同(异)主机 Linux NAT 最佳实践


目录

    • 说明
    • 实验
    • 实验1
      • [确认 172 段能访问 web 服务](#确认 172 段能访问 web 服务)
      • [确认 192 段无法直接访问 web 服务](#确认 192 段无法直接访问 web 服务)
      • [启用 IP 转发](#启用 IP 转发)
      • [设置 DNAT](#设置 DNAT)
      • 验证
    • 实验2
      • [确认 172 段能访问 web 服务](#确认 172 段能访问 web 服务)
      • [确认 192 段无法直接访问 web 服务](#确认 192 段无法直接访问 web 服务)
      • [启用 IP 转发](#启用 IP 转发)
      • [设置 DNAT + SNAT](#设置 DNAT + SNAT)
      • 验证
    • FAQ

说明

在很多人看来,NAT 无非就是解决"内网 => 公网"的通信问题,这种说法当然是没有问题的,但在企业级生产环境中,它一定就是"公网"吗?在华为《基于私网NAT网关和云专线的混合云SNAT》的最佳实践中,实现了通过私网 NAT 将VPC中的云主机私网地址转换成IDC信任的私网地址进行通信,就实现了内网与内网之间的通信。

所以千万不要刻板的认为 NAT 就是解决"内网 => 公网"的通信问题,你要看你站在什么角度去看?只有当你真正理解 NAT 了,你就明白了。所以说,理论固然重要,但不要片面地认为理论就必然是正确的,实践才是检验真理的唯一标准。

本次我将实现同主机与不同主机的不通网段之间通信问题,要求:只能使用 NAT,不允许使用反向代理,因为本次主角是 NAT。

实验

实验1:同台机器

主机:192.168.56.120

  • ens33:192.168.56.120/24

  • ens36:172.16.11.70/24

  • web测试页面(监听主机端口):172.16.11.70:80

***注:**web 80 服务只能 172 段的用户才能访问。

实现当用户访问 http://192.168.56.120:8080/ 时最终访问的是 http://172.16.11.70:80/

实验2:不同台机器

主机1:192.168.56.121

  • ens33:192.168.56.121/24
  • ens36:172.16.11.129/24

主机2:172.16.11.70

  • ens36:172.16.11.70/24

  • web测试页面(监听主机端口):172.16.11.70:80

***注:**web 80 服务只能 172 段的用户才能访问。

实现当用户访问 http://192.168.56.121:8080/ 时最终访问的是 http://172.16.11.70:80/

实验1

确认 172 段能访问 web 服务

http://172.16.11.70/

确认 192 段无法直接访问 web 服务

http://192.168.56.120/

http://192.168.56.120:8080/

启用 IP 转发

在目标主机 192.168.56.120 进行操作。

sh 复制代码
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

设置 DNAT

在目标主机 192.168.56.120 进行操作。

sh 复制代码
# 对Linux服务器添加本条规则后数据包到达服务器的解释
# 一、正向入站流量(客户端 → 本机)
# 1.客户端发包:
#   源:192.168.56.1:1111,目标:192.168.56.120:8080
# 2.数据包从 ens33 进入本机,匹配 PREROUTING DNAT 规则:
#   仅修改目标地址,源 IP 保持不变:
#   转换后数据包:源192.168.56.1:1111,目标172.16.11.70:80
# 3.内核重新路由判断:目标172.16.11.70是本机另一网卡 IP,直接递交给本机 80 端口服务,不会转发到外部设备。
# 二、反向回包流量(本机服务 → 客户端)
# 1.本机172.16.11.70:80程序生成应答包:
#   源:172.16.11.70:80,目标:192.168.56.1:1111
# 2.数据包本机出站,进入 nat 表 POSTROUTING,内核查询 conntrack 连接跟踪表,自动反向还原 DNAT:
#   应答包源 IP 自动改回原始对外地址 192.168.56.120:8080
# 3.从 ens33 网卡发出,送达客户端:
#   客户端收到包:源192.168.56.120:8080,目标192.168.56.1:1111
iptables -t nat -A PREROUTING -i ens33 -d 192.168.56.120 -p tcp --dport 8080 -j DNAT --to-destination 172.16.11.70:80

# 保存配置
service iptables save

不需要设置 SNAT(源地址转换),因为目标172.16.11.70就是本机网卡,流量不经过 POSTROUTING,单条 DNAT 够用,因为 DNAT 后目的 IP 就改为了 172.16.11.70,而该 IP 正好就是本机 IP,因此就直接通信了。

当然,如果后续你把 web 服务迁移到同网段(172)另一台独立服务器,只靠这条 DNAT 会访问失败,必须额外添加 MASQUERADE 源伪装规则,因为 172.16.11.70 这个目的 IP 没有在当前主机上,需要继续通过 MASQUERADE 规则来指定从某个网卡(这个网卡要能与 172.16.11.70 正常通信)继续请求 172.16.11.70。

验证

http://192.168.56.120:8080/

实验2

确认 172 段能访问 web 服务

http://172.16.11.70/

确认 192 段无法直接访问 web 服务

http://192.168.56.121/

http://192.168.56.121:8080/

启用 IP 转发

在目标主机 192.168.56.121 进行操作。

sh 复制代码
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

设置 DNAT + SNAT

在目标主机 192.168.56.121 进行操作。

sh 复制代码
# 设置iptables策略
# 一、正向流量:客户端 → 本机网关 → 远端 172.16.11.70
# 客户端:192.168.56.1:1111
# 1.客户端发包
#   源:192.168.56.1:1111,目标:192.168.56.121:8080
# 2.数据包进入ens33,匹配 PREROUTING DNAT 规则
#   仅改写目标地址,源 IP 不变:
#   转换后包:192.168.56.1:1111 → 172.16.11.70:80
# 3.内核路由判断:目标172.16.11.70需要从ens36网卡转发出去
# 4.数据包进入 POSTROUTING 链,匹配 MASQUERADE 规则
#   改写源 IP为网关ens36的 IP(172.16.11.129):
#   最终发往远端的包:172.16.11.129:随机端口 → 172.16.11.70:80
# 5.首包完成 DNAT+MASQUERADE 转换,内核写入 conntrack 连接跟踪表,保存双向四元组映射。
# 6.数据包通过ens36送达远端服务器172.16.11.70
# 二、反向回包:远端 172.16.11.70 → 本机网关 → 客户端
# 1.远端服务器回包
#   源:172.16.11.70:80,目标:172.16.11.129:随机端口
# 2.数据包进入本机ens36网卡,匹配 conntrack 记录自动反向 SNAT:
#   目标 IP 还原为原始客户端192.168.56.1:1111
#   此时数据包:172.16.11.70:80 → 192.168.56.1:1111
# 3.数据包路由到ens33网卡,再次查表执行反向 DNAT:
#   源 IP 改写为对外暴露地址192.168.56.121:8080
# 4.从ens33网卡发出,客户端收到完整应答:
#   192.168.56.121:8080 → 192.168.56.1:1111

iptables -t nat -A PREROUTING -i ens33 -d 192.168.56.121 -p tcp --dport 8080 -j DNAT --to-destination 172.16.11.70:80
iptables -t nat -A POSTROUTING -d 172.16.11.70 -p tcp --dport 80 -j SNAT --to-source 172.16.11.129
# 或(亲测,这两条规则都行)
# iptables -t nat -A POSTROUTING -o ens36 -d 172.16.11.70 -p tcp --dport 80 -j MASQUERADE

# 保存配置
service iptables save

这里为什么必须加 MASQUERADE?

如果不做源地址伪装,数据包源 IP 还是客户端192.168.56.1

远端172.16.11.70没有192.168.56.0/24网段路由,回包无法送达客户端,连接直接断开。

伪装成同网段网关 IP 后,远端服务器回包只会发给网关172.16.11.100,回程流量能正常经过本机做反向 NAT 还原。

验证

FAQ

保存防火墙策略报错

现象:

sh 复制代码
[root@base ~]# service iptables save
The service command supports only basic LSB actions (start, stop, restart, try-restart, reload, force-reload, status). For other actions, please try to use systemctl.

解决:

sh 复制代码
# 安装iptables-services
yum install -y iptables-services

# 保存配置
service iptables save

SNAT 和 MASQUERADE 区别

ens36 的 IP 地址为 172.16.11.129

sh 复制代码
iptables -t nat -A POSTROUTING -d 172.16.11.70 -p tcp --dport 80 -j SNAT --to-source 172.16.11.129
iptables -t nat -A POSTROUTING -o ens36 -d 172.16.11.70 -p tcp --dport 80 -j MASQUERADE
底层共性

二者都属于源地址转换,都在 nat 表 POSTROUTING 链执行,作用都是修改数据包源 IP,用来解决回程路由问题。

核心区别
对比项 SNAT MASQUERADE
源地址 手动指定 自动使用出口网卡 IP
IP 是否固定 固定 动态获取
性能 略高 略低(每次查询接口 IP)
网卡 IP 改变 不会自动更新 自动更新
推荐场景 服务器固定 IP DHCP、PPPoE、拨号网络

IP 来源方式(最关键)

SNAT --to-source x.x.x.x

  • 源 IP 是你手动硬编码写死的固定 IP;

  • 不自动读取网卡地址,和出口网卡无绑定关系。

    例子中:--to-source 172.16.11.70 表示无论从哪张网卡出去,源 IP 一律强制改成 172.16.11.70

MASQUERADE

  • 自动读取匹配 -o 出口网卡 当前生效 IP作为新源;

  • 必须配合 -o 网卡 参数使用,内核通过网卡动态获取 IP。

    例子中:-o ens36 表示自动拿 ens36 的 IP(172.16.11.129)做源地址。

DHCP 动态 IP 适配能力

  • SNAT:网卡 IP 租期变更、IP 变化后,规则直接失效,必须手动改 IP 重写规则;
  • MASQUERADE:网卡 IP 动态变化无需改规则,每次发包自动读取网卡最新 IP。

性能差异

  • SNAT:性能更高,直接使用写死的 IP,无需查询网卡信息;
  • MASQUERADE:每次数据包都要读取网卡 IP 信息,开销略高。

参数依赖

  • SNAT:不强制要求 -o 出口网卡,只靠 IP / 端口匹配流量;
  • MASQUERADE:必须带 -o 网卡,否则无法获取伪装 IP,规则失效。

NAT 形态是什么?

说了这么多,NAT 形态是什么?一个后台服务?

我们从"VMware、路由器、Linux "三个维度来说。

VMware 自带 NAT

  1. 对应进程 Windows:vmnat.exe,仅 NAT 网络模式 启用;桥接模式完全不用这套 NAT。
  2. 作用:给虚拟机分配独立私有子网,虚拟机借用宿主机 IP 上网(MASQUERADE)。
  3. 限制:局域网设备无法主动访问虚拟机端口,需要手动配置 VMware 端口转发;
  4. 和你虚拟机内 iptables 无关,是宿主机软件单独实现的虚拟网关。

家用 / 硬件路由器 NAT

  1. 出厂内置 NAT 转发引擎,高端机型带硬件加速,开机自动生效;
  2. 两大核心能力:
    • SNAT / 伪装:内网设备共用 1 个公网 IP 上网;
    • 虚拟服务器 / 端口转发(DNAT):外网访问公网端口映射到内网机器;
  3. 底层原理和 Linux 一致:依靠连接跟踪表双向还原 IP。

Linux 系统 NAT

  1. 无独立后台 NAT 服务,依靠内核 Netfilter 框架,iptables/nftables 只是配置工具;
  2. 必须开启 ip_forward=1 跨网卡转发才生效;
  3. nat 表两条核心链分工:
    • PREROUTING:DNAT,改目标 IP / 端口(外网 8080 转发内网机器 80);
    • POSTROUTING:SNAT / MASQUERADE,改源 IP,解决后端回程路由;
  4. 辅助工具:firewalld 封装可视化 NAT 配置;rinetd/haproxy 是用户态代理,非内核 NAT,性能更差。
相关推荐
星释11 小时前
鸿蒙智能体开发实战:23.常见问题
服务器·华为·ai·harmonyos·鸿蒙·智能体
天空'之城11 小时前
Linux 系统编程 22:五种 IO 模型全解
linux
小张成长计划..12 小时前
【Linux】10:冯·诺依曼体系结构和操作系统
linux·运维·服务器
赛博三把手13 小时前
Claude Fable 5 API 调用完整指南:官方、AWS、OpenRouter 与中转平台对比(2026 最新)
网络·云计算·aws
悦儿遥遥雨115 小时前
PXE + Kickstart 无人值守批量部署系统
linux·javascript·nginx
m0_5648768416 小时前
没有公网IP的情况下,怎么进行远程连接两个电脑
服务器·tcp/ip·负载均衡
Imagine Miracle16 小时前
【WSL】让WSL2后台持久运行不自动关闭的解决方案
linux·windows·wsl
兔C16 小时前
Linux 命令行入门学习资料 day_2
linux·运维·服务器
eggcode17 小时前
Linux命令基础与操作技巧
linux