![iptables 在 POSTROUTING 之后丢弃数据包](https://linux22.com/image/651222/iptables%20%E5%9C%A8%20POSTROUTING%20%E4%B9%8B%E5%90%8E%E4%B8%A2%E5%BC%83%E6%95%B0%E6%8D%AE%E5%8C%85.png)
我有一个恶意软件分析环境,可以使用 InetSim 拦截到任意域和互联网服务的流量。我有一个沙盒,其 DNS 服务器设置为 InetSim 实例,InetSim 将使用其自己的 IP 地址回答任何 DNS 查询。
这种设置对于回调域名的恶意软件很有效,但如果它尝试直接连接硬编码的 IP 地址,我的恶意软件环境就会错过它。我正尝试使用 iptables 重定向任何出站流量后退到同一子网上的 InetSim 实例,但数据包似乎在网关机器的某处被丢弃。
网络上有三台机器
- 网关(Ubuntu 14.04LTS,运行 VirtualBox,主机专用接口 vboxnet0 为 192.168.54.1)
- InetSim(VirtualBox VM、Remnux(Debian)Linux Distro、192.168.54.2 上 eth0 上的 VBox 主机专用接口)
- 沙盒(VirtualBox VM、WinXPSP2、VBox 主机专用接口,地址为 192.168.54.102)
我通常会遵循netfilter NAT 文档,我的 iptables 规则如下所示。规则基本上是,
- 出站流量(不针对 192.168.54.0/24 子网)被发送到 192.168.54.1 的网关
- PREROUTING 将目标地址更改为 192.168.54.2 的 InetSim 实例
- POSTROUTING 将源地址更改为网关 192.168.54.1
iptable 规则
$ sudo iptables -v -t nat -L
Chain PREROUTING (policy ACCEPT 17465 packets, 1818K bytes)
pkts bytes target prot opt in out source destination
24 1763 LOG all -- vboxnet0 any anywhere !192.168.54.0/24 LOG level debug prefix "[PREROUTE OUTBOUND]"
41 2824 DNAT all -- vboxnet0 any anywhere !192.168.54.0/24 to:192.168.54.2
Chain INPUT (policy ACCEPT 14623 packets, 1341K bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 74 packets, 4809 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 73 packets, 4749 bytes)
pkts bytes target prot opt in out source destination
17 984 LOG all -- any any 192.168.54.0/24 192.168.54.2 LOG level debug prefix "[POSTROUTE Inetsim]"
41 2513 SNAT all -- any any 192.168.54.0/24 192.168.54.2 to:192.168.54.1
从数据包计数可以看出,规则正在捕获流量。奇怪的是,当我在网关机器和 InetSim 机器上运行 tcpdump 时,我看到了网关捕获的重写数据包,但没有看到 InetSim 机器捕获的重写数据包。
网关捕获
15:11:28.747298 ARP, Request who-has 192.168.54.1 tell 192.168.54.102, length 46
15:11:28.747305 ARP, Reply 192.168.54.1 is-at 0a:00:27:00:00:00, length 28
15:11:28.747471 IP 192.168.54.102.1041 > 2.3.4.5.80: Flags [S], seq 2061217349, win 65535, options [mss 1460,nop,nop,sackOK], length 0
15:11:28.747513 IP 192.168.54.1.1041 > 192.168.54.2.80: Flags [S], seq 2061217349, win 65535, options [mss 1460,nop,nop,sackOK], length 0
...SYN Repeated 2 more times...
15:11:33.748132 ARP, Request who-has 192.168.54.2 tell 192.168.54.1, length 28
15:11:33.748483 ARP, Reply 192.168.54.2 is-at 08:00:27:c7:4f:7c, length 28
InetSim 捕获
10:11:28.649243 ARP, Request who-has 192.168.54.1 tell 192.168.54.102, length 46
10:11:28.649253 ARP, Reply 192.168.54.1 is-at 0a:00:27:00:00:00, length 46
10:11:28.649363 IP 192.168.54.102.1041 > 2.3.4.5.80: Flags [S], seq 2061217349, win 65535, options [mss 1460,nop,nop,sackOK], length 0
...SYN Repeated 2 more times...
10:11:33.650248 ARP, Request who-has 192.168.54.2 tell 192.168.54.1, length 46
10:11:33.650266 ARP, Reply 192.168.54.2 is-at 08:00:27:c7:4f:7c, length 28
我已经启用跟踪,这些是中的条目/var/log/syslog
:
kernel: [22504.635493] TRACE: raw:PREROUTING:policy:2 IN=vboxnet0 OUT= MAC=0a:00:27:00:00:00:08:00:27:0b:26:95:08:00 SRC=192.168.54.102 DST=2.3.4.5 LEN=48 TOS=0x00 PREC=0x00 TTL=128 ID=141 DF PROTO=TCP SPT=1046 DPT=80 SEQ=3347741723 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B401010402)
kernel: [22504.635504] TRACE: nat:PREROUTING:rule:1 IN=vboxnet0 OUT= MAC=0a:00:27:00:00:00:08:00:27:0b:26:95:08:00 SRC=192.168.54.102 DST=2.3.4.5 LEN=48 TOS=0x00 PREC=0x00 TTL=128 ID=141 DF PROTO=TCP SPT=1046 DPT=80 SEQ=3347741723 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B401010402)
kernel: [22504.635508] [PREROUTE OUTBOUND]IN=vboxnet0 OUT= MAC=0a:00:27:00:00:00:08:00:27:0b:26:95:08:00 SRC=192.168.54.102 DST=2.3.4.5 LEN=48 TOS=0x00 PREC=0x00 TTL=128 ID=141 DF PROTO=TCP SPT=1046 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0
kernel: [22504.635512] TRACE: nat:PREROUTING:rule:2 IN=vboxnet0 OUT= MAC=0a:00:27:00:00:00:08:00:27:0b:26:95:08:00 SRC=192.168.54.102 DST=2.3.4.5 LEN=48 TOS=0x00 PREC=0x00 TTL=128 ID=141 DF PROTO=TCP SPT=1046 DPT=80 SEQ=3347741723 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B401010402)
kernel: [22504.635532] TRACE: filter:FORWARD:policy:1 IN=vboxnet0 OUT=vboxnet0 MAC=0a:00:27:00:00:00:08:00:27:0b:26:95:08:00 SRC=192.168.54.102 DST=192.168.54.2 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=141 DF PROTO=TCP SPT=1046 DPT=80 SEQ=3347741723 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B401010402)
kernel: [22504.635536] TRACE: nat:POSTROUTING:rule:1 IN= OUT=vboxnet0 SRC=192.168.54.102 DST=192.168.54.2 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=141 DF PROTO=TCP SPT=1046 DPT=80 SEQ=3347741723 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B401010402)
kernel: [22504.635538] [POSTROUTE Inetsim]IN= OUT=vboxnet0 SRC=192.168.54.102 DST=192.168.54.2 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=141 DF PROTO=TCP SPT=1046 DPT=80 WINDOW=65535 RES=0x00 SYN URGP=0
kernel: [22504.635541] TRACE: nat:POSTROUTING:rule:2 IN= OUT=vboxnet0 SRC=192.168.54.102 DST=192.168.54.2 LEN=48 TOS=0x00 PREC=0x00 TTL=127 ID=141 DF PROTO=TCP SPT=1046 DPT=80 SEQ=3347741723 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT (020405B401010402)
所有其他流量和连接都按预期工作,但网关中发生了一些事情。是的,ip_forward 已启用。我知道 tcpdump 位于路由过程的中间,不一定能捕获线路上的内容,因此看起来数据包在 PREROUTING 和 POSTROUTING 表之间的某个地方被丢弃了。任何帮助都将不胜感激。
答案1
这里的问题似乎与 VirtualBox 如何模拟网络接口和/或网络堆栈有关。我能够使用相同的 iptables 规则启动另一个 VBox Guest,将其配置为专用网关,并能够成功将流量重定向到任意 IP 到我的本地 InetSim 实例。
答案2
要排除您的设置的故障,请将其拆开并单独测试每个部分。
我有一个防火墙服务器(10.3.1.5),因此我添加了将数据包发送到 1.2.3.4 到内部盒子 10.3.1.140(mil102)的命令:
iptables -t nat -A PREROUTING -i eth0 -d 1.2.3.4 -j LOG
iptables -t nat -A PREROUTING -i eth0 -d 1.2.3.4 -j DNAT --to 10.3.1.140
这应该与您的起点相同,现在从内部机器 10.3.1.129 (hp) 我可以 ping 1.2.3.4。防火墙上的日志显示了数据包:
Feb 3 15:42:54 firewall kernel: [7052380.506166] IN=eth0 OUT= MAC=00:0c:29:64:b1:4a:00:22:64:f7:b4:b8:08:00 SRC=10.3.1.129 DST=1.2.3.4 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=27456 DF PROTO=ICMP TYPE=8 CODE=0 ID=922 SEQ=1
使用 tcpdump 仅显示 ICMP 数据包(tcpdump 'icmp[icmptype] = icmp-echo 或 icmp[icmptype] = icmp-echoreply')我看到 mil102(10.3.1.140)上的数据包:
16:42:55.161125 IP hp > mil102: ICMP echo request, id 922, seq 1, length 64
16:42:55.161185 IP mil102 > hp: ICMP echo reply, id 922, seq 1, length 64
您应该能够仅使用 nat 表中的 PREROUTING 行来达到这一点 - 在尝试 POSTROUTING 规则之前验证它是否正常工作。
然后我添加了 POSTROUTING 规则:
iptables -t nat -I POSTROUTING 1 -d 10.3.1.140 -s 10.3.1.0/24 -j LOG
iptables -t nat -I POSTROUTING 2 -d 10.3.1.140 -s 10.3.1.0/24 -j SNAT --to 10.3.1.5
这会将来自本地网络到 10.3.1.140(mil102)的数据包更改为看起来像是来自 10.3.1.5(防火墙)。
日志文件现在显示 ping 正在进行:
Feb 3 15:40:33 firewall kernel: [7052239.848022] IN=eth0 OUT= MAC=00:0c:29:64:b1:4a:00:22:64:f7:b4:b8:08:00 SRC=10.3.1.129 DST=1.2.3.4 LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=21950 DF PROTO=ICMP TYPE=8 CODE=0 ID=32310 SEQ=1
Feb 3 15:40:33 firewall kernel: [7052239.848081] IN= OUT=eth0 SRC=10.3.1.129 DST=10.3.1.140 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=21950 DF PROTO=ICMP TYPE=8 CODE=0 ID=32310 SEQ=1
我的目标机器 mil102 (10.3.1.140) 现在显示 ping 的来源是防火墙 (10.3.1.5):
16:40:35.639037 IP firewall > mil102: ICMP echo request, id 32310, seq 2, length 64
16:40:35.639110 IP mil102 > firewall: ICMP echo reply, id 32310, seq 2, length 64
关于我的设置有几点说明 - eth0 是防火墙上的内部接口,eth1 是外部接口。hp 和 mil102 都只有一个接口 eth0。
我现有的 nat 表有一些路由,这就是我使用插入命令的原因。这是我的原始 nat 表的样子:
Chain PREROUTING (policy ACCEPT 37 packets, 2362 bytes)
pkts bytes target prot opt in out source destination
1444 73980 DNAT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:81 to:10.3.1.129:81
Chain INPUT (policy ACCEPT 18 packets, 1222 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6 packets, 420 bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
5 420 ACCEPT all -- * eth1 0.0.0.0/0 172.20.20.0/24
116M 7439M MASQUERADE all -- * eth1 0.0.0.0/0 0.0.0.0/0
请忽略日志上的时间戳——我在测试完所有内容后才收集示例的数据。
如果这不起作用,最好的建议是简化设置,直到达到预期的工作状态,然后增加复杂性,直到突破或达到目标。