NAT using iptables on Ubuntu 16.04 doesn't work
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
Related videos on Youtube
Shinichi TAMURA
Updated on September 18, 2022Comments
-
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:
- Allow IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
and - 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 about 7 yearsThe 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 fromsudo iptables -t nat -v -x -n -L
. Also add the output fromsudo iptables -v -x -n -L
andifconfig
. -
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 isens4
, which is unfamiliar to me. I attempted to changed the iptables rule, but that still unavialable. -
Shinichi TAMURA about 7 yearsI also
ACCEPT
rule which @hamiheim commented (but replacedeth0
toens4
). Another change I can see now is the absense ofsshgurad
...does it have something to do with the problem? -
Doug Smythies about 7 yearsI 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.
- Allow IP forwarding
-
Shinichi TAMURA about 7 yearsThank you for the advice! But adding the
ACCEPT
rule has no effect on the result...