正文
修改 /etc/sysctl.conf 找到如下内容并去掉井号, 允许 IPv4 转发
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
手动开启 IPv4 转发
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -p
sudo su -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
之后我们再一步一步配置 iptables 防火墙
# 关闭 UbuntuServer 自带的防火墙
sudo ufw disable
# 设置默认允许所有INPUT和FORWARD包
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
# 清空当前生效的防火墙规则。iptables -Z 重置流量计数器
sudo iptables -F
sudo iptables -t nat -F
sudo iptables -t nat -F POSTROUTING
sudo iptables -Z
如何开启 NAT 转发
第一条规则: 允许转发初始网络包
sudo iptables -A FORWARD -s 10.10.10.0/24 -m conntrack --ctstate NEW -j ACCEPT
第二条规则允许转发已经建立连接后的网络包: 允许任何地址到任何地址的确认包和关联包通过。一定要加这一条,至于为什么,参见附录注1。
sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# 或
sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
防火墙规则: 允许转发来自 10.10.10.x 的外网访问请求, 另外, 当数据包离开路由器出口时即 POSTROUTING 阶段进行 SNAT 地址转换
除了上述第1,2两条规则之外, 还要修改改FORWARD链表, 将允许访问的ip添加至FORWARD链,允许特定IP访问外网。
(比如我只想让10.1.1.9这一台机器访问internet, 那么就配置iptables -A FORWARD -s 10.1.1.9 -j ACCEPT
;如果要管理N台主机可否上外网, 同时使用ipset和iptables比重复写 N 条 iptables 规则更加明智)
下列命令将允许转发来自IP 地址 10.10.10.x 的所有客户端报文到任何终点
sudo iptables -A FORWARD -s 10.10.10.0/24 -j ACCEPT
因为是让内网上网,因此对于网关主机而言应该在POSTROUTING阶段进行IP报头转换(数据包离开WAN口之前应该要把源地址变为网关的 WAN 口 IP 地址)
- 网关的 WAN 出口网卡是 eno1, 这里可以通过 MASQUERADE 伪装 IP 地址或通过 SNAT 明确指定 IP 地址
- 网关的 LAN 口 IP 为10.10.10.1 子网掩码 255.255.255.0
MASQUERADE方式:从服务器的网卡eno1 上自动获取当前 IP 地址来做 SNAT
sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o eno1 -j MASQUERADE
另一种静态 SNAT 映射方式必须明确的指定出口的静态 IP 地址, 例如 192.168.0.40
sudo iptables -t nat -A POSTROUTING -s 10.10.10.51 -j SNAT --to 192.168.0.40
附录
注1:
aa<span id="note1">注1</span>
现有通信的双方A和B
但是A如果去主动连接B,由于B是在公网,所以会连接成功,通信也就会建立。
附录2: 参考文档
-
《通过iptables实现端口转发和内网共享上网》 作者张天成
http://wwdhks.blog.51cto.com/839773/1154032
http://xstarcd.github.io/wiki/Linux/iptables_forward_internetshare.html