本文翻译自:Setting Up Gateway Using iptables and route on Linux。 网络资源的分享是非常重要的,而建立起一个网关来进行网络分享是一个比较好的解决方案。在 Linux 系统中创建和设置网关非常简单,成本低廉,而且性能可靠。

1 1 Linux 网络设置

假定我们要处理的 Linux 有如下的配置:

  • NIC1: eth0, ip: 192.168.0.1,连接到局域网(LAN)
  • NIC2: eth1, ip: 1.2.3.4, 连接到公网
网络拓扑图

现在我们希望将分享这台机器的网络连接给 LAN 网络上的其他电脑(ip: 192.168.0.0/16)

2 2 设置网关

下面提到的所有操作都需要 root 权限来执行。

3 2.1 操作 IP 路由表

1
2
3
4
ip route add 192.168.0.0/16 dev eth0

# or
# route add -net 192.168.0.0/16 dev eth0

4 2.2 启用 Linux IP 转发(IP Forwarding)

1
2
3
4
sysctl -w net.ipv4.ip.forward=1

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

你也可以直接编辑/etc/sysctl.conf来持久化这一设置:

1
net.ipv4.ip_forward = 1

4.1 2.3 通过 iptables 设置源地址映射(SNAT)

将(其他电脑发送的)包的源地址修改为网关的源地址。iptables 会自动将响应包的目的地址替换成正确的 IP 地址。

1
iptables -t nat -A POSTROUTING ! -d 192.168.0.0/16 -o eth1 -j SNAT --to-source 1.2.3.4

除了使用 SNAT,也可以使用 MASQUERADE:

1
iptables -t nat -A POSTROUTING ! -d 192.168.0.0/16 -o eth1 -j MASQUERADE

注意,对于静态 IP 而言,SNAT 的方式要更好一些。根据 iptables man page:

This target is only valid in the nat table, in the POSTROUTING chain. It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target. Masquerading is equivalent to specifying a mapping to the IP address of the interface the packet is going out, but also has the effect that connections are forgotten when the interface goes down. This is the correct behavior when the next dialup is unlikely to have the same interface address (and hence any established connections are lost anyway).

你还需要确保其他 iptables 不会阻拦对应的连接。如果你有这方面的问题,可以尝试:

1
2
3
iptables -F
iptables -t nat -F
iptables -t nat -A POSTROUTING ! -d 192.168.0.0/16 -o eth1 -j SNAT --to-source 1.2.3.4

上面的代码可以允许所有的接入连接。不过这会存在一些安全性问题。

5 3 客户端配置

客户端配置主要是把网关设置成 192.168.0.1。例如如下命令

1
2
3
4
ip route add default via 192.168.0.1 dev eth0

# or
# route add default gw 192.168.0.1 eth0