如何使用 Iptables 在 Linux 网关中配置端口转发

本文是一篇详细的指南,教你如何利用 iptables 的 NAT、DNAT 和 SNAT 在 Linux 网关上配置端口转发,将外部流量安全地路由到内部私有网络的服务器中。

阅读时长: 5 分钟
共 2400字
作者: luckt

💡 导语:在网络架构中,NAT (网络地址转换) 是一项将数据包重定向到备用地址的强大技术。本文将详细教你如何通过 iptables 在 Linux 网关上进行端口转发配置,让外部请求也能安全、准确地访问到完全处于内网的服务器。

端口转发(Port Forwarding)是指将对特定端口的请求转发到另一个主机、网络或端口的过程。由于它在传输中修改了数据包的目的地,所以被认为是 NAT(网络地址转换)的一种操作。

实现端口转发,主要依赖于两种关键操作:

  • DNAT (Destination NAT):修改入站数据包的“目标地址”。
  • SNAT (Source NAT):修改出站数据包的“源地址”,确保响应的数据包能够正确地原路路由回去。

在这篇教程中,我们将学习如何在一台充当网关的 Linux 机器上使用 iptables 进行端口转发。具体来说,我们会利用 PREROUTINGPOSTROUTING 链中的 DNAT 和 SNAT 规则,把发往网关 80 端口的流量转发给一台只能通过内部私有网络访问的 Web 服务器。


1. 原理核心与准备工作

要使用 iptables 成功实现端口转发,核心需要三部分组件配合:

  1. 内核级别的 IP 转发:通过 sysctl 开启。
  2. filter 表中的 FORWARD 链规则:允许流量通过防火墙。
  3. nat 表中的 DNAT / SNAT 规则:准确地修改目标地址和源地址。

我们在这个教程中的实验环境架构

为了便于理解,我们假设有两台服务器,它们都在同一个私有网络里。

内网 Web 服务器的细节:

  • 公网 IP(不用):203.0.113.1
  • 私网 IP:10.0.0.1
  • 公网网卡:eth0
  • 私网网卡:eth1

网关/防火墙服务器的细节:

  • 公网 IP(流量入口):203.0.113.2
  • 私网 IP:10.0.0.2
  • 公网网卡:eth0
  • 私网网卡:eth1

我们的目标是:当用户访问网关的公网 IP 203.0.113.2:80 时,请求会被转发到 Web 服务器的内网 IP 10.0.0.1:80 上。


2. 设置内网 Web 服务器 (Nginx)

首先登录到你的内网 Web 服务器(10.0.0.1)。

为了验证端口转发是否生效,我们需要安装一个 Nginx,并且严格限制 Nginx 只能监听私网接口

sudo apt update
sudo apt install nginx

安装完成后,打开默认的站点配置文件:

sudo nano /etc/nginx/sites-enabled/default

找到关于 listen 的两行指令,修改为仅监听内网 IP。(本教程只演示 IPv4,如果不需要可以把 IPv6 的 listen 删掉):

server {
    listen 10.0.0.1:80 default_server;
    # ... 其他配置
}

保存并退出。测试语法无误后重启 Nginx:

sudo nginx -t
sudo systemctl restart nginx

这样,你的 Web 服务器就再也不会对外网暴露了,它变得非常安全。


3. 在网关服务器上配置防火墙 (Iptables)

接下来所有的操作都在网关/防火墙服务器10.0.0.2)上进行。

3.1 开启内核级 IP 转发

Linux 系统默认是关闭了数据包转发功能的。你需要手动将它打开。

你想临时测试开启的话,可以运行:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

但要想做到永久生效(重启后依然有效),请编辑 /etc/sysctl.conf 文件:

sudo nano /etc/sysctl.conf

取消 net.ipv4.ip_forward=1 这一行前面的注释(去掉 # 号),保存退出。 然后应用配置:

sudo sysctl -p
# 或者
sudo sysctl --system

3.2 在 FORWARD 链中放行流量

默认的安全防火墙模板通常会将 FORWARD 链的策略设置为 DROP。我们需要加两条规则,允许特定流量流经这台网关。

首先,我们在 FORWARD 链中,允许来自外网卡 eth0、目标为内网卡 eth1 的 80 端口 TCP 新建连接请求(NEW):

sudo iptables -A FORWARD -i eth0 -o eth1 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT

接着,依靠 conntrack (连接追踪),允许那些已经建立起来的、或是相关的双向回传流量(ESTABLISHED, RELATED):

# 从外网卡到内网卡
sudo iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 从内网卡到外网卡
sudo iptables -A FORWARD -i eth1 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

最后,确认一下你的 FORWARD 链的默认策略是不是还是 DROP(拦截一切其余不符合规则的包):

sudo iptables -P FORWARD DROP

这就好比给一堵密不透风的墙开了一扇带有身份验证机制的门。

3.3 配置 NAT 规则正确引导数据包

目前门虽然开了,但别人进来后根本不知道该往哪里走!这步就是配置向导服务(NAT)。

首先是 DNAT(目标地址转换)。当公网用户的请求到达网关的外网卡 eth0 时,我们要在路由判定之前(PREROUTING)就把数据包的目标地址偷梁换柱,改成真正的 Web 服务器内网 IP 10.0.0.1

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

这只完成了一半。此时数据包虽然成功发到了 Web 服务器,但该数据包的“寄件人”依然是公网客户端的原始真实 IP。如果 Web 服务器直接“回复”给这个真实 IP,会导致 TCP 连接无法建立,甚至会被底层的云服务商以反欺诈原因直接丢包。

因此,我们要进行 SNAT(源地址转换)。在数据包即将离开网关内网卡 eth1 奔向 Web 服务器之前(POSTROUTING),我们把它的源地址改成网关自己的内网 IP 10.0.0.2。 于是,Web 服务就只会把响应交还给网关,网关再顺水推舟把响应返回给公网客户端:

sudo iptables -t nat -A POSTROUTING -o eth1 -p tcp --dport 80 -d 10.0.0.1 -j SNAT --to-source 10.0.0.2

提示:SNAT vs MASQUERADE 如果我们的网关私网 IP 是固定的静态 IP(如本例的 10.0.0.2),用 SNAT 性能更好。如果你的网关 IP 是通过 DHCP 动态获取的,那就没有固定 IP 可写,此时只能把最后修改成 -j MASQUERADE

至此,大功告成!找一台外网电脑执行:

curl http://203.0.113.2

你就能看到 Web 服务器内网机器上的 Nginx 初始界面的 HTML 代码了。

3.4 永久保存防火墙规则

一旦你重启服务器 iptables 规则就会清空。为了让刚才的配置硬化固化,你需要保存规则。

在 Ubuntu 等用 iptables-persistent 的系统中:

sudo service netfilter-persistent save

这会使当前所有活动规则写入到 /etc/iptables/rules.v4 当中。


4. 端口转发安全最佳实践指南

为了保障环境的安全可靠,当我们在 Linux 网关上做这种高级路由操作时,一些安全规范要时刻牢记:

  1. 精准限制端口映射:绝对不要开多余的端口,开哪个用哪个。每一个端口转发都在内部网络上撕开了一道口子。
  2. 尽量限制能够发起请求的来源 IP:比如,只有总部办公室的 IP 段 198.51.100.0/24 允许访问,可以在 PREROUTING 时增加 -s 参数:
    sudo iptables -t nat -A PREROUTING -i eth0 -s 198.51.100.0/24 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1
    
  3. 针对 FORWARD 中的废弃包开启日志打点:在你的 DROP 规则之前插入一条 -j LOG,便于后续的入侵检测排查。
  4. 防御 SYN 洪水泛滥或暴力破解:利用 iptables 原生的 limit 模块进行新建请求的限流(例如 --limit 25/second --limit-burst 50)。
  5. 定期审计规则:常使用 iptables -t nat -L -v -niptables -L -v -n 进行查看。

结尾

通过配置以上的规则,你现在已经在这台 Linux 机器上玩转了 Iptables 端口转发的核心理论。你会发现它并没有想象中那么神秘:无非就是内核准许通过、中间开个小门,接着来一手漂亮的前后门“目标-来源”地址掉包计。在这个基础之上,你就可以应对诸多更加复杂的内网代理需求了!

使用 Hugo 构建
主题 StackJimmy 设计