Iptables之nat配置

Iptables之nat配置

核心概念先明确

  • SNAT(Source NAT):修改数据包的源 IP,用于内网主机通过网关服务器访问外网(解决内网 IP 无法直接路由的问题)。

  • DNAT(Destination NAT):修改数据包的目标 IP / 端口,用于将外网请求映射到内网服务器(如发布内网服务到公网)。

  • 前提条件:网关服务器需开启 IP 转发功能(必须先配置,否则 NAT 不生效)。

基础准备:开启 IP 转发(所有场景必做)

1. 临时开启(重启失效,用于测试)

echo 1 > /proc/sys/net/ipv4/ip_forward

2. 永久开启(重启生效,生产环境推荐)

编辑内核参数配置文件:

/etc/sysctl.conf
net.ipv4.ip_forward = 1

生效配置:

sysctl -p

场景 1:SNAT 配置(内网主机通过网关访问外网)

环境假设

  • 网关服务器有两块网卡:

    • 内网网卡:eth1,IP:192.168.1.2(内网网段:192.168.1.0/24

    • 外网网卡:eth0,IP:203.0.113.10(公网 IP,可访问互联网)

  • 内网主机:192.168.1.100(重要:网关指向 192.168.1.2

需求

内网主机(192.168.1.100)通过网关服务器的公网 IP(203.0.113.10)访问外网,外网返回的数据通过网关转发回内网主机。

配置命令(SNAT 两种常用方式)

方式 1:固定公网 IP 场景(网关有静态公网 IP)

# 配置 SNAT:内网网段 192.168.1.0/24 的流量,源 IP 替换为网关外网 IP(203.0.113.10)

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 203.0.113.10

方式 2:动态公网 IP 场景(网关拨号上网,IP 不固定)

MASQUERADE 替代 SNAT,自动适配公网 IP 变化:

# 动态伪装内网 IP,适用于 ADSL 拨号、DHCP 获取公网 IP 的场景

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

关键参数说明

参数 作用
-t nat 指定操作 nat 表(SNAT/DNAT 均在 nat 表中配置)
-A POSTROUTING 在 POSTROUTING 链添加规则(数据包路由后、发送前修改源 IP)
-s 192.168.1.0/24 匹配内网网段(仅对该网段的流量生效)
-o eth0 指定出站网卡(即网关的外网网卡)
--to-source 203.0.113.10 替换后的源 IP(网关公网 IP)

验证方法

  1. 内网主机(192.168.1.100)执行 ping 测试:
ping 223.5.5.5  #  ping 阿里云 DNS,测试外网连通性
  1. 网关服务器查看 nat 表规则:
iptables -t nat -L POSTROUTING -n  # 查看 SNAT 规则是否存在
  1. 外网服务器查看访问日志(如 Web 服务器),会显示访问源 IP 为网关公网 IP(203.0.113.10)。

场景 2:DNAT 配置(外网访问内网服务,端口映射)

环境假设

  • 网关服务器:外网网卡 eth0(IP:203.0.113.10),内网网卡 eth1(IP:192.168.1.1)

  • 内网服务器:192.168.1.200(提供 Web 服务,端口 80;SSH 服务,端口 22)

  • 需求:

  1. 外网用户访问网关公网 IP 的 80 端口 → 转发到内网 192.168.1.200:80(Web 服务)

  2. 外网用户访问网关公网 IP 的 2222 端口 → 转发到内网 192.168.1.200:22(SSH 服务,避免直接暴露 22 端口)

配置命令(DNAT 端口映射)

1. Web 服务映射(80 端口)

# DNAT:外网访问 203.0.113.10:80 → 转发到内网 192.168.1.200:80

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.200:80

2. SSH 服务映射(2222 端口映射到 22 端口)

# DNAT:外网访问 203.0.113.10:2222 → 转发到内网 192.168.1.200:22

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.200:22

3. 可选:放行对应端口的入站流量(避免被默认策略拦截)

若网关 INPUT 链默认策略为 DROP,需放行映射的端口:

# 放行外网访问 80 端口

iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT

# 放行外网访问 2222 端口

iptables -A INPUT -i eth0 -p tcp --dport 2222 -j ACCEPT

# 放行已建立的连接(确保返回数据能通过)

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

关键参数说明

参数 作用
-A PREROUTING 在 PREROUTING 链添加规则(数据包路由前修改目标 IP / 端口)
-i eth0 指定入站网卡(即网关的外网网卡,仅匹配外网请求)
--dport 80 匹配外网请求的目标端口(网关公网 IP 的端口)
--to-destination 192.168.1.200:80 转发后的内网服务器 IP 和端口

验证方法

  1. 外网主机测试 Web 服务:
curl http://203.0.113.10  # 应返回内网 192.168.1.200 的 Web 页面
  1. 外网主机测试 SSH 服务:
ssh -p 2222 用户名@203.0.113.10  # 应连接到内网 192.168.1.200 的 SSH
  1. 网关查看 DNAT 规则和连接状态:
iptables -t nat -L PREROUTING -n  # 查看 DNAT 规则

netstat -an | grep :80            # 查看 80 端口连接(应显示内网服务器的连接)

重要操作:保存 NAT 规则(避免重启失效)

CentOS/RHEL 系统

# 保存规则到配置文件

iptables-save > /etc/sysconfig/iptables

# 开机自启 iptables

systemctl enable iptables && systemctl restart iptables

Ubuntu/Debian 系统

# 安装规则持久化工具

apt-get install -y iptables-persistent

# 保存规则(自动写入 /etc/iptables/rules.v4)

netfilter-persistent save

常见问题与注意事项

  1. NAT 不生效?
  • 检查 IP 转发是否开启:cat /proc/sys/net/ipv4/ip_forward(返回 1 才正确)。

  • 检查规则顺序:PREROUTING 链规则在前,POSTROUTING 链在后;入站放行规则需匹配映射端口。

  • 检查网卡名称:确认 -i(入站)、-o(出站)网卡名称正确(用 ip addr 查看)。

  1. 外网能访问映射服务,但内网访问公网 IP 无法访问?
  • 原因:内网主机访问网关公网 IP 时,DNAT 生效但返回路径未经过 SNAT,需添加 “内网访问公网 IP 映射” 规则:
iptables -t nat -A PREROUTING -s 192.168.1.0/24 -d 203.0.113.10 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.200:80
  1. 云服务器配置 DNAT 无效?
  • 云服务器(阿里云、腾讯云等)的公网 IP 是厂商提供的 “弹性 IP”,需先在云控制台配置 “端口转发” 或 “安全组”,开放对应端口,否则外网流量无法到达服务器。
  1. 批量删除 NAT 规则?
# 清空 nat 表的 PREROUTING 链(DNAT 规则)

iptables -t nat -F PREROUTING

# 清空 nat 表的 POSTROUTING 链(SNAT 规则)

iptables -t nat -F POSTROUTING