配置 DNAT 和 SNAT 的核心是使用 iptables 的 nat 表,并确保内核已开启 IP 转发。
📌 前提:开启 IP 转发
NAT 涉及数据包在不同网络间转发,因此必须先启用内核的 ip_forward 功能。
bash
# 临时生效
sudo sysctl -w net.ipv4.ip_forward=1
# 永久生效(推荐)
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
🔄 SNAT(源地址转换):让内网访问外网
SNAT 用于修改数据包的源 IP 地址 。典型场景是让私有内网(如 192.168.1.0/24)通过网关(服务器)的公网 IP 访问互联网。
规则需要添加到 POSTROUTING 链(数据包发出前最后一步处理)。
假设:
- 内网网段:
192.168.1.0/24 - 网关公网接口:
eth1 - 网关公网 IP:
203.0.113.1
bash
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to-source 203.0.113.1
参数解释:
-t nat:指定使用 nat 表。-A POSTROUTING:在 POSTROUTING 链追加规则。-s 192.168.1.0/24:匹配来自该内网网段的流量。-o eth1:匹配从eth1接口发出的流量。-j SNAT:执行源地址转换。--to-source 203.0.113.1:将源 IP 改为公网 IP203.0.113.1。
替代方案: 如果公网 IP 是动态获取的(如 DHCP),建议使用 MASQUERADE,它会自动使用接口当前的 IP 地址,更省事。
bash
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE
🔀 DNAT(目的地址转换):将外网请求转发到内网服务器
DNAT 用于修改数据包的目的 IP 地址,常被称为"端口转发"。典型场景是将公网 IP 的 80 端口请求转发给内网的 Web 服务器。
规则需要添加到 PREROUTING 链(数据包到达后、路由决策前处理)。
假设:
- 网关公网接口:
eth1 - 公网 IP:
203.0.113.1 - 内网 Web 服务器:
192.168.1.10
bash
# 将访问公网 80 端口的流量转发到内网 Web 服务器
sudo iptables -t nat -A PREROUTING -d 203.0.113.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80
参数解释:
-A PREROUTING:在 PREROUTING 链追加规则。-d 203.0.113.1:匹配目标是公网 IP 的流量。-p tcp --dport 80:匹配 TCP 协议的 80 端口。-j DNAT:执行目的地址转换。--to-destination 192.168.1.10:80:将目的地址改为192.168.1.10,端口改为80。
注意 :DNAT 只负责修改地址,并不自动放行流量 。你还需要在
FORWARD链中添加规则,允许转发到内网服务器的流量。
💾 保存规则(防止重启丢失)
iptables 规则默认是临时的,重启后会丢失。可以使用 iptables-persistent 工具来保存。
bash
# Debian/Ubuntu
sudo apt install iptables-persistent
sudo netfilter-persistent save
# CentOS/RHEL 可使用 service iptables save
🔍 查看与调试
bash
# 查看 nat 表的所有规则,带行号
sudo iptables -t nat -L -n -v --line-numbers
# 查看当前活动的 NAT 连接(需安装 conntrack)
sudo conntrack -L