Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
NAT and FORWARD with Ubuntu’s ufw firewall

UFW

I use Ubuntu’s Uncomplicated firewall because it is available on Ubuntu and it's very simple.

Install UFW

if ufw is not installed by default be sure to install it first.

$ sudo apt-get install ufw

NAT

If you needed ufw to NAT the connections from the external interface to the internal the solution is pretty straight forward. In the file /etc/default/ufw change the parameter DEFAULT_FORWARD_POLICY

DEFAULT_FORWARD_POLICY="ACCEPT"

Also configure /etc/ufw/sysctl.conf to allow ipv4 forwarding (the parameters is commented out by default). Uncomment for ipv6 if you want.

net.ipv4.ip_forward=1
#net/ipv6/conf/default/forwarding=1
#net/ipv6/conf/all/forwarding=1

The final step is to add NAT to ufw’s configuration. Add the following to /etc/ufw/before.rules just before the filter rules.

# NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]

# Forward traffic through eth0 - Change to match you out-interface
-A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

# don't delete the 'COMMIT' line or these nat table rules won't
# be processed
COMMIT

Now enable the changes by restarting ufw.

$ sudo ufw disable && sudo ufw enable

FORWARD

For port forwardind just do something like this.

# NAT table rules
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

# Port Forwardings
-A PREROUTING -i eth0 -p tcp --dport 22 -j DNAT --to-destination 192.168.1.10

# Forward traffic through eth0 - Change to match you out-interface
-A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE

# don't delete the 'COMMIT' line or these nat table rules won't
# be processed
COMMIT

TheFox commented May 23, 2015

When I add the NAT rules to /etc/ufw/before.rules the rule appears twice in iptables:

:> iptables -t nat -L -v
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

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

Chain OUTPUT (policy ACCEPT 0 packets, 0 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         
    0     0 MASQUERADE  all  --  any    eth0    192.168.241.0/24     anywhere            
    0     0 MASQUERADE  all  --  any    eth0    192.168.241.0/24     anywhere       

That's because the nat rules get loaded every time ufw starts - they do not overwrite the old ones, they just get added onto the end.

I solved this by adding a "-F" (flush) as the first rule.

enhans3d commented Jun 3, 2015

Thats not a proper solution... it results in the following:

ERROR: problem running ufw-init
iptables-restore v1.4.21: Cannot use -A with -F

Error occurred at line: 18
Try `iptables-restore -h' or 'iptables-restore --help' for more information.

Problem running '/etc/ufw/before.rules'

Well it worked for me, sorry:

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-F
-A PREROUTING .....
-A POSTROUTING .....
COMMIT

Update: I just realised that you may be doing a -A -F

:thumbs:

vol7ron commented Mar 14, 2016

Thanks for sharing.
Can someone confirm if it's possible to perform port-forwarding without opening the port on the firewall? If, say, you want traffic forwarded from 80 to 3000, ufw requires that you allow 3000, which also allows the web to access $IP:80 and $IP:3000. If you don't want the outside world connecting to 3000, are there specific ways to set up the firewall? Should you restrict the 3000 port to only allow traffic from localhost?

nileshadiyecha commented Jun 15, 2016

I am getting the below issue while I attempt shell command "sudo ufw disable && sudo ufe enable"

ERROR: problem running ufw-init
iptables v1.4.21: can't initialize iptables table `filter': Permission denied (you must be root)
Perhaps iptables or your kernel needs to be upgraded.

borodulin commented Dec 27, 2016

ubuntu 16.04.
It is working after adding this line (after icmp code for FORWARD):

-A ufw-before-forward -i eth0 -o virbr0 -d 192.168.1.0/24 -j ACCEPT

virbr0 - internal interface

daBONDi commented Jan 19, 2017

mhh for me its not working :-(

Tripple Check the files

i'm using Vagrant box ubuntu/xenial64 with a private and public network :-(

its like its not doing nat?
internet <-> router <-> Network Public <-> vagrant private
i can ping all ips in Network Public, but not in the internet or other subnets on the router

so i got double NAT should be normaly no problem :-(

Please correct both lines that list
*nat
as
#Nat

It's meant to be a comment line, but it causes UFW to fail at startup.

irgendwr commented Jul 9, 2017

@joebitcoinorg nope, this selects the table and is not meant to be a comment
(I know the post I'm referring to is a few months old, just wanted to clarify in case someone reads this)

Is there a way to do this without changing the default policy?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment