我有一个非常简单的拓扑。
机器 1:
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:0d:2c:a2 brd ff:ff:ff:ff:ff:ff
inet 193.124.117.195/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe0d:2ca2/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:0d:2c:a5 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.2/24 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe0d:2ca5/64 scope link
valid_lft forever preferred_lft forever
ip r
default via 193.124.117.1 dev eth0
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.2
193.124.117.0/24 dev eth0 proto kernel scope link src 193.124.117.195
机器2:
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:0d:2c:a3 brd ff:ff:ff:ff:ff:ff
inet 176.113.82.77/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe0d:2ca3/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:0d:2c:a4 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.3/24 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe0d:2ca4/64 scope link
valid_lft forever preferred_lft forever
ip r
default via 176.113.82.1 dev eth0
176.113.82.0/24 dev eth0 proto kernel scope link src 176.113.82.77
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.3
Ping 192.168.0.3 -> 192.168.0.2:
ping -c 1 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=1.63 ms
--- 192.168.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.629/1.629/1.629/0.000 ms
Ping 192.168.0.2 -> 192.168.0.3:
ping -c 1 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=2.70 ms
--- 192.168.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.702/2.702/2.702/0.000 ms
接下来。我在 192.168.0.3 机器上安装了 Nginx,但这其实并不重要。我想实现从 192.168.0.2:8888 到 192.168.0.3:80 的端口转发。我检查连接:
wget 192.168.0.3:80
--2023-06-14 19:02:52-- http://192.168.0.3/
Connecting to 192.168.0.3:80... connected.
HTTP request sent, awaiting response... 200 OK
然后我在 192.168.0.2 机器上添加一条规则
iptables -t nat -A PREROUTING -p tcp --dport 8888 -DNAT --to 192.168.0.3:80
并开启转发功能:
echo 1 > /proc/sys/net/ipv4/ip_forward
然后我尝试从第三台机器打开 193.124.117.195:8888 并看到数据包从第一台机器(192.168.0.2)出去:
tcpdump -i eth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
19:18:33.480948 IP 84.252.147.253.6016 > 192.168.0.3.http: Flags [S], seq 2692986583, win 12500, options [mss 1250,nop,wscale 2,sackOK,TS val 3132330242 ecr 0], length 0
19:18:36.480279 IP 84.252.147.253.6016 > 192.168.0.3.http: Flags [S], seq 2692986583, win 12500, options [mss 1250,nop,wscale 2,sackOK,TS val 3132333242 ecr 0], length 0
另外,我还添加了另一条规则来确保数据包朝正确的方向传输:
iptables -t nat -A POSTROUTING -p tcp --dport 80 -d 192.168.0.3 -j ACCEPT
iptables -t nat -nvL POSTROUTING
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2 120 ACCEPT tcp -- * * 0.0.0.0/0 192.168.0.3 tcp dpt:80
因此,据我了解,数据包通过 eth1 到达本地网络,应该到达机器 2。但这里什么也没发生。我尝试监听 192.168.0.3 eth1,只看到 arp 数据包。而且 iptables 没有显示任何数据包。我在哪里犯了错误?192.168.0.3:
tcpdump -i eth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
19:29:13.020569 ARP, Request who-has 192.168.0.3 tell 192.168.0.2, length 28
19:29:13.020600 ARP, Reply 192.168.0.3 is-at 00:15:5d:0d:2c:a4 (oui Unknown), length 28
答案1
我找到了答案:只需添加 MASQUERADE 来掩盖 LAN 数据包的源 ip:
iptables -t nat -A POSTROUTING -p tcp -d 192.168.0.3 --dport 80 -j MASQUERADE