我有一个安装,我有主接口( eth0
)的多个接口别名(与私有IP)。
eth0 Link encap:Ethernet HWaddr 0a:ed:01:17:53:b4 inet addr:10.0.1.220 Bcast:10.0.1.255 Mask:255.255.255.0 eth0:0 Link encap:Ethernet HWaddr 0a:ed:01:17:53:b4 inet addr:192.168.1.1 Bcast:0.0.0.0 Mask:255.255.255.0 eth0:1 Link encap:Ethernet HWaddr 0a:ed:01:17:53:b4 inet addr:192.168.1.2 Bcast:0.0.0.0 Mask:255.255.255.0
我将这些别名分别应用于不同的networking整形策略。 为了使绑定到每个私有IP的进程能够与Internet通信,我使用iptables
作为NAT来伪装IP地址到eth0
的IP地址
iptables -t nat -A POSTROUTING -s 192.168.1.1/24 -o eth0 -j MASQUERADE
这很好。 如果我看到stream量离开eth0
,我可以看到源IP已经正确更改。
# Send pings using eth0:0 ping -I 192.168.1.1 www.google.com # Monitor packets sent out of eth0 tcpdump -i eth0 icmp # 21:34:18.664664 IP ip-10-0-1-220.ec2.internal > ord37s08-in-f4.1e100.net: ICMP echo request, id 3957, seq 2, length 64 # 21:34:18.683022 IP ord37s08-in-f4.1e100.net > ip-10-0-1-220.ec2.internal: ICMP echo reply, id 3957, seq 2, length 64 # 21:34:19.666137 IP ip-10-0-1-220.ec2.internal > ord37s08-in-f4.1e100.net: ICMP echo request, id 3957, seq 3, length 64 # 21:34:19.683954 IP ord37s08-in-f4.1e100.net > ip-10-0-1-220.ec2.internal: ICMP echo reply, id 3957, seq 3, length 64 # 21:34:28.774873 IP ip-10-0-1-220.ec2.internal > ord37s08-in-f4.1e100.net: ICMP echo request, id 3962, seq 1, length 64 # 21:34:28.793410 IP ord37s08-in-f4.1e100.net > ip-10-0-1-220.ec2.internal: ICMP echo reply, id 3962, seq 1, length 64
对于stream量整形,我使用了dummynet + ipfw。 当我为每个别名创build必要的stream量调整策略时。
# Apply an outbound bandwidth cap of 1Mbps to eth0:0 ipfw pipe 1 config bw 1Mbit/s ipfw queue 1 config pipe 1 queue 100 ipfw add queue 1 ip from 192.168.1.1 to any
那么由dummynet生成的数据包实际上从来没有被iptables
看到,所以当stream量离开eth0
,它有内部的私有IP,显然是永远不会得到答复的。
# Send pings using eth0:0 ping -I 192.168.1.1 www.google.com # Monitor packets sent out of eth0 tcpdump -i eth0 icmp # 21:34:29.776431 IP 192.168.1.1 > ord37s08-in-f4.1e100.net: ICMP echo request, id 3962, seq 2, length 64 # 21:34:30.784435 IP 192.168.1.1 > ord37s08-in-f4.1e100.net: ICMP echo request, id 3962, seq 3, length 64 # 21:34:31.792440 IP 192.168.1.1 > ord37s08-in-f4.1e100.net: ICMP echo request, id 3962, seq 4, length 64 # 21:34:32.800446 IP 192.168.1.1 > ord37s08-in-f4.1e100.net: ICMP echo request, id 3962, seq 5, length 64
当我看着iptables -t nat -vnL
我可以确认这些数据包从来没有被iptables
看到。
我意识到, ipfw
和iptables
都使用底层netfilter
库来处理数据包,并根据我的阅读,他们都挂钩到POSTROUTING
挂钩。 他们有可能以某种方式竞争吗? 如果是这样,我可以以某种方式对netfilter
的规则进行“重新sorting”,这样dummynet会将数据包重新input到stream中,以便iptables
。 有没有其他的方法来创build这些私人IP的NAT,以便我可以避免这种冲突?
不幸的是, ipfw
的NATfunction似乎在将其移植到Linux时被删除,所以这是不可能的。
更新
在挖掘dummynet代码的时候,好像使用dst_output
( 这里是基于我的读取)应该调用ip_output
,然后执行NF_INET_POST_ROUTING
netfilter钩子,将延迟的数据包重新注入堆栈。
当添加一些TRACE
iptables
规则时,
iptables -A PREROUTING -t raw -p icmp -j TRACE iptables -A OUTPUT -t raw -p icmp -j TRACE
我得到了以下。
没有运行dummynet(但使用接口别名):
[23416.053128] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=37956 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=1 UID=0 GID=0 [23416.053136] TRACE: nat:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=37956 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=1 UID=0 GID=0 [23416.053139] TRACE: filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=37956 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=1 UID=0 GID=0 [23416.053143] TRACE: nat:POSTROUTING:rule:1 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=37956 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=1 UID=0 GID=0 [23416.055612] TRACE: raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=0a:0d:f8:70:35:b4:0a:86:45:e6:5c:49:08:00 SRC=172.217.7.164 DST=10.0.1.255 LEN=84 TOS=0x00 PREC=0x00 TTL=47 ID=0 PROTO=ICMP TYPE=0 CODE=0 ID=12659 SEQ=1 [23416.055628] TRACE: filter:INPUT:policy:1 IN=eth0 OUT= MAC=0a:0d:f8:70:35:b4:0a:86:45:e6:5c:49:08:00 SRC=172.217.7.164 DST=192.168.1.1 LEN=84 TOS=0x00 PREC=0x00 TTL=47 ID=0 PROTO=ICMP TYPE=0 CODE=0 ID=12659 SEQ=1 [23417.054547] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=38092 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=2 UID=0 GID=0 [23417.054557] TRACE: filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=38092 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=2 UID=0 GID=0 [23417.055950] TRACE: raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=0a:0d:f8:70:35:b4:0a:86:45:e6:5c:49:08:00 SRC=172.217.7.164 DST=10.0.1.255 LEN=84 TOS=0x00 PREC=0x00 TTL=47 ID=0 PROTO=ICMP TYPE=0 CODE=0 ID=12659 SEQ=2 [23417.055969] TRACE: filter:INPUT:policy:1 IN=eth0 OUT= MAC=0a:0d:f8:70:35:b4:0a:86:45:e6:5c:49:08:00 SRC=172.217.7.164 DST=192.168.1.1 LEN=84 TOS=0x00 PREC=0x00 TTL=47 ID=0 PROTO=ICMP TYPE=0 CODE=0 ID=12659 SEQ=2 [23418.056141] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=38099 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=3 UID=0 GID=0 [23418.056157] TRACE: filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=172.217.7.164 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=38099 DF PROTO=ICMP TYPE=8 CODE=0 ID=12659 SEQ=3 UID=0 GID=0 [23418.057635] TRACE: raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=0a:0d:f8:70:35:b4:0a:86:45:e6:5c:49:08:00 SRC=172.217.7.164 DST=10.0.1.255 LEN=84 TOS=0x00 PREC=0x00 TTL=47 ID=0 PROTO=ICMP TYPE=0 CODE=0 ID=12659 SEQ=3 [23418.057646] TRACE: filter:INPUT:policy:1 IN=eth0 OUT= MAC=0a:0d:f8:70:35:b4:0a:86:45:e6:5c:49:08:00 SRC=172.217.7.164 DST=192.168.1.1 LEN=84 TOS=0x00 PREC=0x00 TTL=47 ID=0 PROTO=ICMP TYPE=0 CODE=0 ID=12659 SEQ=3
在dummynet运行的情况下(你可以看到POSTROUTING
NAT策略从未被应用。
[23535.355649] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43670 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=1 UID=0 GID=0 [23535.355657] TRACE: nat:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43670 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=1 UID=0 GID=0 [23535.355661] TRACE: filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43670 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=1 UID=0 GID=0 [23536.362312] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43689 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=2 UID=0 GID=0 [23536.362324] TRACE: nat:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43689 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=2 UID=0 GID=0 [23536.362330] TRACE: filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43689 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=2 UID=0 GID=0 [23537.370345] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43819 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=3 UID=0 GID=0 [23537.370379] TRACE: nat:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43819 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=3 UID=0 GID=0 [23537.370385] TRACE: filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=192.168.1.1 DST=216.58.217.132 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=43819 DF PROTO=ICMP TYPE=8 CODE=0 ID=12715 SEQ=3 UID=0 GID=0