【网络】iptables MASQUERADE作用
文章目录
- 概述
- 1. 设置了 MASQUERADE/SNAT (正常情况)
- 2. 没有设置 MASQUERADE/SNAT
概述
sudo iptables -t nat -A POSTROUTING -j MASQUERADE 的核心作用
这条命令的作用是:在所有从本机转发出去的数据包离开本机之前,自动将其源IP地址修改为本机出口网的IP地址。
针对您的场景分析 (Client -> Server1 -> Server2)
我们用这个具体场景来解释,假设:
Client IP: 192.168.1.100
(一个私有IP)
Server1 IP:
-
内网卡 (eth1):
192.168.1.1
(Client的网关) -
外网卡 (eth0):
111.11.1.42
(公网IP)
Server2 IP: 8.8.8.8
(一个公网IP)
1. 设置了 MASQUERADE/SNAT (正常情况)
1、Client 发送包:
-
数据包: 源IP:
192.168.1.100
(client) | 目标IP:8.8.8.8
(server2) -
Client根据自己的路由表,将这个包发给它的网关
192.168.1.1
(Server1)。
2、Server1 收到并路由:
-
数据包从
eth1
进入 Server1。 -
Server1 的内核根据路由表,判断这个包要去往互联网,应该从
eth0
接口发出。 -
在数据包从
eth0
发出之前 (POSTROUTING 链),MASQUERADE
规则生效。
3、MASQUERADE 执行SNAT:
-
规则将数据包的源IP从
192.168.1.100
(client) 修改为 Server1 的外网IP111.11.1.42
(server1)。 -
修改后的数据包: 源IP: 111.11.1.42 (server1) | 目标IP: 8.8.8.8 (server2)
-
这个新包被发送到互联网,最终到达 Server2。
4、Server2 回复:
-
Server2 收到包后,它认为是在和 111.11.1.42 (server1)通信。
-
它构造回复包: 源IP: 8.8.8.8 (server2) | 目标IP: 111.11.1.42 (server1)
5、回复包回到 Server1:
-
这个回复包通过互联网路由,顺利到达 Server1 (111.11.1.42)。
-
Server1 的内核知道这个连接(因为它有连接跟踪
conntrack
的记录),记得这个来自8.8.8.8
发给111.11.1.42
的回复,其实是属于当初那个从192.168.1.100
发往8.8.8.8
的请求。 -
内核在 PREROUTING 链执行 DNAT,将回复包的目标IP从
111.11.1.42
(server1)修改回192.168.1.100
(client)。
6、Server1 转发回 Client:
-
修改后的回复包: 源IP:
8.8.8.8
| 目标IP:192.168.1.100
-
Server1 根据路由表,将这个包从 eth1 接口发出,最终到达 Client。
结论: 通信成功。Server2 始终不知道 Client 192.168.1.100 的存在,它只和 Server1 通信。
2. 没有设置 MASQUERADE/SNAT
1、Client 发送包:
-
数据包: 源IP: 192.168.1.100 | 目标IP: 8.8.8.8
-
包到达 Server1。
2、Server1 收到并路由:
-
数据包从
eth1
进入 Server1。 -
内核路由判断它应该从
eth0
发出。 -
因为没有 SNAT 规则,数据包原封不动地从
eth0
发出。 -
发出的数据包: 源IP:
192.168.1.100
(client) | 目标IP:8.8.8.8
3、Server2 收到包:
-
Server2 收到这个包,看到源IP是
192.168.1.100
(client) 。 -
它很高兴地处理这个请求,然后构造回复包。
4、Server2 尝试回复:
-
回复包: 源IP: 8.8.8.8 | 目标IP: 192.168.1.100
-
问题来了!
192.168.1.100
是一个私有IP地址,在公共互联网上是不可路由的。这个回复包根本到不了Client
。 -
更可能的情况是,互联网上的路由器在看到目标地址是私有IP时,会直接丢弃这个包。回复包甚至都无法到达 Server1。
5、即使回复包奇迹般到达 Server1:
-
假设我们在一个实验环境中,回复包被送回了 Server1。
-
Server1 内核看到这个包:目标IP: 192.168.1.100。
-
它检查自己的连接跟踪表(
conntrack
),但找不到任何记录(因为出去的包没做SNAT
,无法建立完整的连接跟踪)。 -
最终,Server1 不知道这个包是给谁的。如果它开启了IP转发,它可能会尝试将其转发到 192.168.1.100,但整个过程非常脆弱且不符合标准。