NAT using iptables on Ubuntu 16.04 doesn't work

18,523

Solution 1

I believe this has to do with a systemd-networkd change. I was trying to accomplish something similar recently on Ubuntu 16.04, and stumbled across a webpage explaining that forwarding has to be enabled on the interface itself. I am unable to find this webpage at the moment, and I don't know when this was changed.

So this will enable forwarding, but in addition to this, it has to be enabled on the interface

sudo sysctl -w net.ipv4.ip_forward=1

To see if forwarding is enabled or not, run this:

sysctl -a | grep forwarding

To enable forwarding on eth0, run this:

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

I believe I read that enabling forwarding on an interface will set net.ipv4.ip_forward to 1, so the first step might not be necessary. If this is the case, disabling forwarding again on the interface will not revert net.ipv4.ip_forward back to 0. At least that's how I remember it.

Solution 2

Make sure you have set set the firewall to allow forwarding of traffic. It's possible that switching to Ubuntu 16 that the firewall is preconfigured to an implicit deny policy for packet forwarding

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

Also make sure that you have added your NAT rule to run after reboot. Add the same rule to /etc/rc.local

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Share:
18,523

Related videos on Youtube

Shinichi TAMURA
Author by

Shinichi TAMURA

Updated on September 18, 2022

Comments

  • Shinichi TAMURA
    Shinichi TAMURA over 1 year

    I used to use Ubuntu 14.04 trusty for our NAT server (build on Google Cloud Platform), but recently I tried to use the Ubuntu 16.04 xenial.

    I configured perfectly same as I've done in 14.04, but it DOESN'T WORK as NAT server. The only difference is the versions of the OS and libraries.

    The configuration is quite simple, which is described in Google's documentation:

    1. Allow IP forwarding sudo sysctl -w net.ipv4.ip_forward=1 and
    2. Configure the iptables sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

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

    That's it. In Ubuntu 14.04, it worked. In Ubuntu 16.04, it didn't.

    Can someone help me to configure it correctly? I have no idea what I'm missing nor what point I should check.

    Thanks in advance!


    Here're the additional info

    In 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
    

    In 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
    
    • Doug Smythies
      Doug Smythies about 7 years
      The problem with using sudo iptables -t nat -L is that it doesn't show us the all the information, in particular the interface names, but also packet counters. Please replace those outputs with outputs from sudo iptables -t nat -v -x -n -L. Also add the output from sudo iptables -v -x -n -L and ifconfig.
    • Shinichi TAMURA
      Shinichi TAMURA about 7 years
      @DougSmythies Thanks for the advice! I added the information what you recommended, and found that the interface name is no longer eth0 but is ens4, which is unfamiliar to me. I attempted to changed the iptables rule, but that still unavialable.
    • Shinichi TAMURA
      Shinichi TAMURA about 7 years
      I also ACCEPT rule which @hamiheim commented (but replaced eth0 to ens4). Another change I can see now is the absense of sshgurad...does it have something to do with the problem?
    • Doug Smythies
      Doug Smythies about 7 years
      I thought interface name change might be a problem. You do not need those specific FORWARD rules, because the default is ACCEPT anyhow. Beyond that I do not know what is going on because I don't even see a second network interface such that NAT is even required.
  • Shinichi TAMURA
    Shinichi TAMURA about 7 years
    Thank you for the advice! But adding the ACCEPT rule has no effect on the result...