在 Ubuntu 16.04 上使用 iptables 进行 NAT 不起作用

在 Ubuntu 16.04 上使用 iptables 进行 NAT 不起作用

我曾经使用 Ubuntu 14.04 trusty 作为我们的 NAT 服务器(基于 Google Cloud Platform 构建),但最近我尝试使用 Ubuntu 16.04 xenial。

我的配置和我在 14.04 中做的完全一样,但是不起作用作为 NAT 服务器。唯一的区别是操作系统和库的版本。

配置相当简单,Google的文档中有描述:

  1. 允许 IP 转发sudo sysctl -w net.ipv4.ip_forward=1
  2. 配置 iptablessudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

https://cloud.google.com/compute/docs/networking#natgateway

就是这样。在 Ubuntu 14.04 中,它可以工作。在 Ubuntu 16.04 中,它不工作。

有人能帮我正确配置它吗?我不知道我遗漏了什么,也不知道应该检查哪一点。

提前致谢!


以下是附加信息

在 Ubuntu 14.04 中

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"
$
$ sudo dpkg -l iptables
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name             Version       Architecture  Description
+++-================-=============-=============-=====================================
ii  iptables         1.4.21-1ubunt amd64         administration tools for packet filte
$
$ sudo iptables -v -x -n -L
Chain INPUT (policy ACCEPT 5898 packets, 944634 bytes)
    pkts      bytes target     prot opt in     out     source               destination
    5898   944634 sshguard   all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 40 packets, 3444 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 5658 packets, 526971 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain sshguard (1 references)
    pkts      bytes target     prot opt in     out     source               destination
$
$ sudo iptables -t nat -v -x -n -L
Chain PREROUTING (policy ACCEPT 18 packets, 3471 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 14 packets, 3231 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 797 packets, 48528 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination
     801    48768 MASQUERADE  all  --  *      eth0    0.0.0.0/0            0.0.0.0/0
$
$ ifconfig
eth0      Link encap:Ethernet  HWaddr 12:34:56:78:90:ab
          inet addr:10.146.0.3  Bcast:10.146.0.3  Mask:255.255.255.255
          inet6 addr: fe80::4001:aff:fe92:3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
          RX packets:6379 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6099 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1080290 (1.0 MB)  TX bytes:644140 (644.1 KB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
$
$ sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

在 Ubuntu 16.04 中

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS"
$
$ sudo dpkg -l iptables
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name             Version       Architecture  Description
+++-================-=============-=============-=====================================
ii  iptables         1.6.0-2ubuntu amd64         administration tools for packet filte
$
$ sudo iptables -L -v -x -n
Chain INPUT (policy ACCEPT 474 packets, 44440 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination
      16      960 ACCEPT     all  --  *      ens4    0.0.0.0/0            0.0.0.0/0
       0        0 ACCEPT     all  --  ens4   *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED

Chain OUTPUT (policy ACCEPT 355 packets, 38412 bytes)
    pkts      bytes target     prot opt in     out     source               destination
$
$ sudo iptables -t nat -v -x -n -L
Chain PREROUTING (policy ACCEPT 9 packets, 3013 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain INPUT (policy ACCEPT 6 packets, 2833 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 756 packets, 46153 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 759 packets, 46333 bytes)
    pkts      bytes target     prot opt in     out     source               destination
       0        0 MASQUERADE  all  --  *      ens4    0.0.0.0/0            0.0.0.0/0
$
$ sudo ifconfig
ens4      Link encap:Ethernet  HWaddr 12:34:56:78:90:ab
          inet addr:10.146.0.4  Bcast:10.146.0.4  Mask:255.255.255.255
          inet6 addr: fe80::4001:aff:fe92:4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1460  Metric:1
          RX packets:6274 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6064 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1043141 (1.0 MB)  TX bytes:641746 (641.7 KB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
$
$ sudo sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

答案1

我认为这与 systemd-networkd 更改有关。我最近试图在 Ubuntu 16.04 上完成类似的事情,偶然发现一个网页解释说必须在接口本身上启用转发。我目前无法找到这个网页,我不知道这是什么时候更改的。

因此这将启用转发,但除此之外,还必须在接口上启用它

sudo sysctl -w net.ipv4.ip_forward=1

要查看转发是否启用,请运行以下命令:

sysctl -a | grep forwarding

要在 eth0 上启用转发,请运行以下命令:

sudo sysctl net.ipv4.conf.eth0.forwarding=1

我记得我读到过,在接口上启用转发会将 net.ipv4.ip_forward 设置为 1,因此第一步可能没有必要。如果是这样,再次在接口上禁用转发不会将 net.ipv4.ip_forward 恢复为 0。至少我记得是这样。

答案2

确保已将防火墙设置为允许转发流量。切换到 Ubuntu 16 后,防火墙可能会预先配置为隐式拒绝数据包转发策略

sudo iptables -A FORWARD -o eth0 -j ACCEPT
sudo iptables -A FORWARD -m state \
--state ESTABLISHED,RELATED -i eth0 -j ACCEPT

还要确保已添加 NAT 规则以在重启后运行。将相同的规则添加到 /etc/rc.local

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

相关内容