刚接触Linux网络配置时,看到满屏的iptables规则是不是头皮发麻?尤其是SNAT和DNAT这两个长得像双胞胎的术语,手册里的解释总是绕来绕去。今天我们就用快递收发、酒店前台这些生活场景,把这两个核心概念揉碎了讲明白。
想象你住在一个封闭小区(内网),所有住户的门牌号都是192.168开头的私有号码。某天你想给外面的朋友(公网)寄快递,但快递公司规定:只接收公网地址的包裹。这时候小区物业(网关)站出来说:"把包裹给我,我帮你换成小区对外的统一地址(公网IP)再寄出"——这就是NAT(网络地址转换)的日常版。
NAT的三大刚需场景:
小知识:全球IPv4地址在2019年就已全部分配完毕,NAT技术让互联网多撑了20年
继续用快递类比,SNAT(Source NAT)就是物业的寄件人代填服务。当你的包裹经过网关时,物业会把寄件人地址从"192.168.1.10"改成"小区统一公网地址",这样回邮时快递会先到物业,再由物业转交给你。
经典SNAT命令拆解:
bash复制iptables -t nat -A POSTROUTING \
-s 192.168.1.0/24 \ # 来自内网网段
-o eth0 \ # 从外网网卡发出
-j SNAT \ # 执行SNAT操作
--to-source 203.0.113.1 # 替换为这个公网IP
参数避坑指南:
-t nat:指定nat表(默认filter表不处理地址转换)POSTROUTING:在路由决策之后修改源地址(重要!)-o eth0:必须指定出口网卡,否则可能影响内网通信动态IP用户可以用这个简化版:
bash复制iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
DNAT(Destination NAT)则像酒店的前台分拣服务。当外人给酒店总机(公网IP)打电话时,前台根据分机号把电话转接到具体房间(内网服务器)。对应到网络场景,就是把访问公网IP:80的请求,转发到内网服务器的192.168.1.100:80。
端口转发经典示例:
bash复制iptables -t nat -A PREROUTING \
-d 203.0.113.1 \ # 目标为公网IP
-p tcp --dport 80 \ # 访问80端口
-j DNAT \ # 执行DNAT操作
--to-destination 192.168.1.100:8080 # 转到内网服务器的8080端口
关键区别点:
PREROUTING链处理(路由决策前修改目标地址)现象1:内网能上网但外网无法访问内网服务
sysctl net.ipv4.ip_forward 是否为1现象2:NAT规则不生效
bash复制iptables -t nat -L -n -v # 查看规则命中计数器
tcpdump -i eth0 port 80 # 抓包观察流量走向
规则持久化技巧:
bash复制# 保存当前规则
iptables-save > /etc/iptables.rules
# 开机自动加载
echo "iptables-restore < /etc/iptables.rules" >> /etc/rc.local
chmod +x /etc/rc.local
假设我们要实现:
完整配置步骤:
开启IP转发:
bash复制echo 1 > /proc/sys/net/ipv4/ip_forward
配置SNAT:
bash复制iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
配置DNAT:
bash复制iptables -t nat -A PREROUTING \
-d 203.0.113.1 -p tcp --dport 5000 \
-j DNAT --to-destination 192.168.1.100:22
允许转发流量:
bash复制iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
测试时发现外网连接超时?可能是忘了放行5000端口:
bash复制iptables -A INPUT -p tcp --dport 5000 -j ACCEPT