Create a gist now

Instantly share code, notes, and snippets.

Embed
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

This comment has been minimized.

Show comment
Hide comment
@TheFox

TheFox 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       

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       
@asfandtpo

This comment has been minimized.

Show comment
Hide comment
@asfandtpo

asfandtpo Jun 1, 2015

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.

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

This comment has been minimized.

Show comment
Hide comment
@enhans3d

enhans3d 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'

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'

@asfandtpo

This comment has been minimized.

Show comment
Hide comment
@asfandtpo

asfandtpo Jun 3, 2015

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

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

@watsoncj

This comment has been minimized.

Show comment
Hide comment
@watsoncj

watsoncj Nov 26, 2015

:thumbs:

:thumbs:

@vol7ron

This comment has been minimized.

Show comment
Hide comment
@vol7ron

vol7ron 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?

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?

@timss

This comment has been minimized.

Show comment
Hide comment
@timss

timss May 13, 2016

@nileshadiyecha

This comment has been minimized.

Show comment
Hide comment
@nileshadiyecha

nileshadiyecha 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.

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

This comment has been minimized.

Show comment
Hide comment
@borodulin

borodulin 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

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

This comment has been minimized.

Show comment
Hide comment
@daBONDi

daBONDi 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 :-(

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 :-(

@joebitcoinorg

This comment has been minimized.

Show comment
Hide comment
@joebitcoinorg

joebitcoinorg Apr 7, 2017

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.

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

This comment has been minimized.

Show comment
Hide comment
@irgendwr

irgendwr 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)

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)

@bluebaroncanada

This comment has been minimized.

Show comment
Hide comment
@bluebaroncanada

bluebaroncanada Aug 17, 2017

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

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

@drst0ck

This comment has been minimized.

Show comment
Hide comment
@drst0ck

drst0ck Dec 22, 2017

You are my hero!

drst0ck commented Dec 22, 2017

You are my hero!

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