Sob*_*yan 0 networking linux nat iptables
我的目标是有一些 iptables 规则来通过 iptables 规则观察网络流量。然而,iptables 似乎并没有按照我的预期工作。作为请求响应的数据包似乎不遵守 NAT 表规则。
首先,我创建了一些记录syslog
匹配数据包的规则。这是我的NAT
餐桌规则:
# iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -d 10.0.0.1/32 -j LOG --log-prefix "+++ nat, preroute +++"
-A OUTPUT -d 10.0.0.2/32 -j LOG --log-prefix "+++ nat, output +++"
-A POSTROUTING -d 10.0.0.2/32 -j LOG --log-prefix "+++ nat, postrouting ++++"
Run Code Online (Sandbox Code Playgroud)
这些是我的filter
餐桌规则:
# iptables -t filter -S
-P INPUT ACCEPT
-P FORWARD DROP
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER
-A INPUT -d 10.0.0.1/32 -j LOG --log-prefix "+++ filter, input +++"
-A OUTPUT -d 10.0.0.2/32 -j LOG --log-prefix "++++ filter, output ++++"
Run Code Online (Sandbox Code Playgroud)
raw
,mangle
表格security
很清楚:
# iptables -t raw -S
-P PREROUTING ACCEPT
-P OUTPUT ACCEPT
# iptables -t mangle -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
# iptables -t security -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
Run Code Online (Sandbox Code Playgroud)
为了测试我的规则,我使用以下脚本创建了一个网络命名空间。它创建一个网络命名空间以及一对 veth 接口,其中一个对等体连接到网络命名空间:
#!/bin/bash
set -ex
ip netns add net1
ip link add veth1 type veth peer veth2 netns net1
ip link set veth1 up
ip netns exec net1 ip link set veth2 up
ip netns exec net1 ip link set lo up
ip addr add 10.0.0.1/24 dev veth1
ip netns exec net1 ip addr add 10.0.0.2/24 dev veth2
Run Code Online (Sandbox Code Playgroud)
然后我使用命名空间veth
中的接口ping 我的本地主机net1
:
# ip netns exec net1 ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.085 ms
Run Code Online (Sandbox Code Playgroud)
根据此图片(此博客的一部分),我预计会看到以下消息登录syslog
:
+++ nat, preroute +++ -> for first packet destined to 10.0.0.1
+++ filter, input +++ -> for first packet destined to 10.0.0.1
+++ nat, output +++ -> for first response packet destined to 10.0.0.2
+++ nat, postrouting ++++ -> for first response packet destined to 10.0.0.2
Run Code Online (Sandbox Code Playgroud)
但是,syslog
日志有所不同:
May 1 10:46:35 safdarian-Legion-5-15ITH6 kernel: [ 4165.810315] +++ nat, preroute +++IN=veth1 OUT= MAC=1a:31:55:32:60:0d:2e:bb:08:2b:8b:5e:08:00 SRC=10.0.0.2 DST=10.0.0.1 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=10280 DF PROTO=ICMP TYPE=8 CODE=0 ID=37055 SEQ=1
May 1 10:46:35 safdarian-Legion-5-15ITH6 kernel: [ 4165.810327] +++ filter, input +++IN=veth1 OUT= MAC=1a:31:55:32:60:0d:2e:bb:08:2b:8b:5e:08:00 SRC=10.0.0.2 DST=10.0.0.1 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=10280 DF PROTO=ICMP TYPE=8 CODE=0 ID=37055 SEQ=1
May 1 10:46:35 safdarian-Legion-5-15ITH6 kernel: [ 4165.810341] ++++ filter, output ++++IN= OUT=veth1 SRC=10.0.0.1 DST=10.0.0.2 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27366 PROTO=ICMP TYPE=0 CODE=0 ID=37055 SEQ=1
May 1 10:46:36 safdarian-Legion-5-15ITH6 kernel: [ 4166.813517] +++ filter, input +++IN=veth1 OUT= MAC=1a:31:55:32:60:0d:2e:bb:08:2b:8b:5e:08:00 SRC=10.0.0.2 DST=10.0.0.1 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=10332 DF PROTO=ICMP TYPE=8 CODE=0 ID=37055 SEQ=2
May 1 10:46:36 safdarian-Legion-5-15ITH6 kernel: [ 4166.813538] ++++ filter, output ++++IN= OUT=veth1 SRC=10.0.0.1 DST=10.0.0.2 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27433 PROTO=ICMP TYPE=0 CODE=0 ID=37055 SEQ=2
May 1 10:46:37 safdarian-Legion-5-15ITH6 kernel: [ 4167.837538] +++ filter, input +++IN=veth1 OUT= MAC=1a:31:55:32:60:0d:2e:bb:08:2b:8b:5e:08:00 SRC=10.0.0.2 DST=10.0.0.1 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=10508 DF PROTO=ICMP TYPE=8 CODE=0 ID=37055 SEQ=3
May 1 10:46:37 safdarian-Legion-5-15ITH6 kernel: [ 4167.837558] ++++ filter, output ++++IN= OUT=veth1 SRC=10.0.0.1 DST=10.0.0.2 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27527 PROTO=ICMP TYPE=0 CODE=0 ID=37055 SEQ=3
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下这是为什么吗?
iptables NAT 是有状态的,并且是按流而不是按数据包进行的。
\n仅流的第一个数据包(即属于未知流的数据包)通过“nat”表 \xe2\x80\x93 发送,所有后续数据包都会绕过它,因为它们会被自动应用的 conntrack 1 子系统识别相同的翻译,或回复的反向翻译。
\n因此,匹配的“Echo Reply”数据包-d 10.0.0.2/32
永远不会命中“POSTROUTING”链(或“PREROUTING”链2),因为它被识别为属于现有的ICMP流并自动跳过整个“nat”表。
(“流”直接映射到 TCP 或 SCTP 中的连接,但对于无连接 L4 协议(如 UDP 或 ICMP),它们是隐式建立的,具有某种超时;例如,同一 src:sport\xe2 之间的所有 UDP 数据包\x87\x86dst:dport 是同一流的一部分,直到过期。)
\n可以使用conntrack -L
查看流表;请注意它如何具有两组 src/dst 对,即原始对和“回复”对。(例如,如果您要在预路由中应用出站 DNAT,则入站回复数据包将与“回复”字段匹配,并相应地自动进行 SNAT。)
1--state ESTABLISHED
这与 iptables 过滤规则或 nftables 规则中常见的实现完全相同的 conntrack ct state
。
2您的规则(具有这些特定-d
匹配)看起来像是在假设 PREROUTING 仅适用于出站数据包而 POSTROUTING 仅适用于入站数据包的情况下编写的。事实并非如此 \xe2\x80\x93 所有数据包都会遍历两条链。
归档时间: |
|
查看次数: |
1523 次 |
最近记录: |