一台 Ubuntu 搞定两网段互通!手把手教你 iptables 的 SNAT 和 DNAT 实战
【Linux网络实战】VMware虚拟机环境下 iptables SNAT 与 DNAT 防火墙实验全解析 前言在 Linux 网络运维中防火墙Netfilter/Iptables是核心组件。很多初学者对SNAT源地址转换和DNAT目的地址转换的概念感到模糊。本文将通过 VMware 虚拟机搭建三台 Linux 主机Rocky Linux、Ubuntu、OpenEuler手把手带你完成 SNAT 和 DNAT 的配置与验证彻底搞懂 NAT 的原理。实验核心SNAT解决内网主机访问外网的问题隐藏内网 IP。DNAT解决外网或不同网段访问内网服务的问题端口映射。️ 实验环境与网络规划1. 虚拟机网络设置关键在 VMware 中我们需要用到两种网络模式NAT 模式用于模拟“外网/公网”环境网段10.0.0.0/24。仅主机模式Host-Only用于模拟“内网/私网”环境网段192.168.8.0/24。关闭 VMware 虚拟网络编辑器里的 DHCP 服务所有 IP 地址全部手动配置防止冲突。2. 主机角色分配主机名网卡模式IP 地址角色说明Rocky10NAT10.0.0.12模拟外部客户端Ubuntu24NAT 仅主机10.0.0.13192.168.8.13充当防火墙/NAT网关双网卡OpenEuler仅主机192.168.8.14模拟内网 Web 服务器特别提示三台虚拟机的防火墙firewalld / ufw必须全部提前关闭。# Rocky/OpenEuler 关闭防火墙systemctl disable--nowfirewalld# Ubuntu 关闭防火墙ufw disable#防止后续出现问题Rocky/OpenEuler 最好关闭安全增强Linux将SELINUX内容修改为disabledvim/etc/selinux/configSELINUXdisabled3. 核心环境配置准备步骤1OpenEuler 安装 Nginx 并测试#安装nginxweb软件同时安装一个抓包工具后面会用[rootopeneuler ~]# yum install nginx tcpdump vim -y#定制nginx的web页面[rootopeneuler ~]# echo openeuler web page from 192.168.8.14 /usr/share/nginx/html/index.html#启动nginx服务[rootopeneuler ~]# systemctl start nginx#测试效果[rootopeneuler ~]# curl localhost# 预期输出openeuler web page from 192.168.8.142Ubuntu 开启路由转发至关重要Ubuntu 作为网关必须开启数据包转发功能。#防火墙主机保证当前主机支持数据包转发的能力rootubuntu24:~# sysctl -w net.ipv4.ip_forward1# 验证是否生效rootubuntu24:~# sysctl -a | grep ip_forward3Rocky 删除默认网关# Rocky 主机先删除默认路由让其只能访问本网段[rootrocky10 ~]# ip route del default#修改10.0.0.12 主机的默认网关指向 10.0.0.13[rootrocky10 ~]# ip route add default via 10.0.0.13 dev ens160 # 网关指向 Ubuntu 实验一SNAT 源地址转换实践内网出外网1. 现象展示问题此时 Rocky10.0.0.12如果想要访问内网 OpenEuler 的 Web 服务192.168.8.14会失败因为 10.0.0.12 没有去往 192.168.8.0 网段的路由且防火墙不会自动做地址转换。[rootrocky10 ~]# ping 192.168.8.14# 结果卡住无法连通丢包。2. 解决方案配置 SNAT 规则在 Ubuntu 防火墙主机上执行以下命令rootubuntu24:~# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -d 10.0.0.0/24 -j SNAT --to-source 192.168.8.13命令解释-t nat指定操作 NAT 表。POSTROUTING数据包即将离开网卡时处理。-s 10.0.0.0/24匹配源 IP 为 10.0.0.0 网段的数据包。! -d 10.0.0.0/24匹配目的 IP 不是10.0.0.0 网段的数据包避免内部互访时的非必要转换。-j SNAT --to-source 192.168.8.13将源 IP 统一替换为网关的外网口 IP192.168.8.13。3. 验证效果抓包分析再次在 Rocky 上 ping OpenEuler同时我们在 OpenEuler 的网卡上抓包。# 在 OpenEuler 上抓包[rootopeneuler ~]# tcpdump -n icmp# 预期输出发现发出的 Ping 请求源 IP 变成了 192.168.8.13而不是原来的 10.0.0.12实验结论SNAT 成功隐藏了 Rocky 的真实 IP实现了 10.0.0.0/24 内网访问 192.168.8.0/24 外网的功能。 实验二DNAT 目的地址转换实践外网进内网/端口映射1. 准备工作我们需要删除 Rocky 主机的默认路由改为由 Ubuntu 转发。为了模拟 DNAT 的典型场景把 Ubuntu 的 80 和 8080 端口作为“公网入口”将流量送往内网真实的 OpenEuler 的 80 端口。# 在 OpenEuler 上添加出口路由[rootopeneuler ~]# ip route add default via 192.168.8.13# 确保 Ubuntu 主机本身没有占用 80 端口rootubuntu24:~# netstat -tnupl | grep 802. 解决方案配置 DNAT 规则在 Ubuntu 上配置端口转发#定制两条防火墙规则rootubuntu24:~# iptables -t nat -A PREROUTING -d 10.0.0.13 -p tcp --dport 80 -j DNAT --to-destination 192.168.8.14:80rootubuntu24:~# iptables -t nat -A PREROUTING -d 10.0.0.13 -p tcp --dport 8080 -j DNAT --to-destination 192.168.8.14:80命令解释PREROUTING数据包进入网卡时路由决策前处理。-d 10.0.0.13 -p tcp --dport 80匹配目的 IP 是 10.0.0.13且目的端口是 80 的 TCP 数据包。-j DNAT --to-destination 192.168.8.14:80将目的 IP 改为内网真实服务器 IP192.168.8.14同时端口改为 80。3. 验证效果访问测试在 Rocky 主机上访问 Ubuntu 的 IP#测试两个端口[rootrocky10 ~]# curl 10.0.0.13:80# 预期输出openeuler web page from 192.168.8.14[rootrocky10 ~]# curl 10.0.0.13:8080# 预期输出openeuler web page from 192.168.8.14实验结论虽然我们请求的是 Ubuntu10.0.0.13但防火墙通过 DNAT 规则将请求悄悄地转发给了后方的 OpenEuler192.168.8.14。这正是云服务器“端口映射”和“负载均衡”最基础的原型。 总结SNAT 与 DNAT 核心区别特性SNAT (源地址转换)DNAT (目的地址转换)动作修改数据包的源 IP修改数据包的目的 IP挂载点POSTROUTING链出站前修改PREROUTING链入站时修改场景内网机器访问互联网共享上网互联网用户访问内网服务器端口映射路由影响数据包返回时自动解 NAT无需额外配置数据包返回时需保证网关路由表正确 避坑指南与温馨提示不生效检查sysctl -w net.ipv4.ip_forward1是否执行这是 NAT 成功的前提。VMware 乱码如果 ping 不通务必检查 VMware 虚拟机的网卡设置确保 Ubuntu 开启了“NAT”和“仅主机”两个网卡。抓包调试如果遇到问题使用tcpdump -i ens160 -n在 Ubuntu 的 NAT 网卡和仅主机网卡分别抓包观察数据包入口和出口是否都有变化这是排查绝招。 附件注本文提供的实验拓扑图及命令均已在 VMware 环境验证建议各位小伙伴在搭建时先完成基础网络互通确保同网段能 ping 通再进行 NAT 实验这样排错会更轻松。最后感谢并欢迎各位小伙伴的指正

相关新闻