用iptables做端口转发最灵活但必须配齐四步:开启ip_forward、添加prerouting dnat规则、放行forward链、配置postrouting masquerade;firewalld更简便但需手动启用masquerade且依赖zone配置。

要在 Linux 上用防火墙把内网服务安全地暴露给外网,核心不是“开放端口”,而是“可控转发”——关键在路径可控、回包可溯、权限最小。firewalld 和 iptables 都能实现,但 firewalld 更适合 CentOS/RHEL/Fedora 系统,配置简洁;iptables 通用性更强,规则更底层、更灵活。
必须先打开内核 IP 转发
这是所有转发功能的开关,没它,数据包进不来就直接丢弃:
- 临时启用:echo 1 > /proc/sys/net/ipv4/ip_forward
- 永久生效:编辑 /etc/sysctl.conf,确保含 net.ipv4.ip_forward = 1,然后运行 sysctl -p
- 验证是否成功:cat /proc/sys/net/ipv4/ip_forward 输出为 1 才算生效
firewalld 端口转发四步到位
firewalld 的 --add-forward-port 命令看似简单,但缺一不可:
- 绑定正确 zone:确认公网接口在 public 区域(firewall-cmd --get-active-zones),否则规则不生效;如需调整,运行 firewall-cmd --permanent --zone=public --change-interface=ens33
- 开启区域级 IP 伪装:执行 firewall-cmd --permanent --zone=public --add-masquerade,否则内网服务回包源地址是私网 IP,外网客户端收不到响应
-
添加转发规则:例如将外网 4433 转到内网 192.168.10.5:22222:
firewall-cmd --permanent --zone=public --add-forward-port=port=4433:proto=tcp:toport=22222:toaddr=192.168.10.5 -
放行外网入口端口:仅转发还不够,得让流量进来:
firewall-cmd --permanent --add-port=4433/tcp,最后别忘 firewall-cmd --reload
iptables 端口转发必须配齐四链
iptables 更底层,每一步都影响通断,漏掉任意一环都会静默失败(比如连接超时或 Connection refused):
-
PREROUTING 做 DNAT:改目标地址和端口
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80 -
FORWARD 链放行转发:默认策略常为 DROP,必须显式允许
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT -
POSTROUTING 做 MASQUERADE:让内网服务回包源 IP 变成本机,保证路径闭环
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE -
保存规则防重启丢失:
Ubuntu/Debian:iptables-save > /etc/iptables/rules.v4
CentOS:service iptables save 或使用 firewall-cmd --runtime-to-permanent
安全加固不能省
暴露即风险,转发只是通道,控制权仍在你手里:
- 内网目标机器自身的防火墙(如其 firewalld 或 ufw)也必须放行对应隐藏端口(如 22222/tcp)
- 如只允许特定 IP 访问,firewalld 用富规则替代简单转发:
firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.25" port port="4433" protocol="tcp" forward-port port="22222" to-port="22222" to-addr="192.168.10.5"' - 避免使用 127.0.0.1 或 localhost 作为 toaddr;若转发到本机非标准端口(如本地 8081),则省略 toaddr,只写 toport=8081
- 测试时建议先关闭 SELinux(setenforce 0)排除干扰,确认转发正常后再按需配置策略











