Skip to content

Instantly share code, notes, and snippets.

@kimus
Created March 2, 2014 22:46
Show Gist options
  • Save kimus/9315140 to your computer and use it in GitHub Desktop.
Save kimus/9315140 to your computer and use it in GitHub Desktop.
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
@duffyduck00
Copy link

duffyduck00 commented Dec 3, 2021

almost everything is working fine - i am using a vpn connection .. i just changed the line
-A POSTROUTING -s 192.168.137.0/24 -o eth0 -j MASQUERADE to -A POSTROUTING -s 192.168.137.0/24 -o tun0 -j MASQUERADE
so if the vpn connection is lost, no traffic will reach internet ... thats how i would like it.

the only thing what is not working till now, is dns through 192.168.137.1 (which is the ip address to the local network). i have to enter dns address 1.1.1.1 at all my clients - but i want to use dns address 192.168.137.1 at all my clients.
i tried portforwarding for port 53

-A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to-destination 192.168.137.1

... but it doesnt work.

any ideas how to make this work ?

@duffyduck00
Copy link

duffyduck00 commented Jan 24, 2022

everything is workine fine now ... after i installed dhcp server on my router pc

@h6w
Copy link

h6w commented Jan 25, 2022

Instead of forwarding ports in before.rules, UFW now supports forwarding itself.

e.g. the command above

-A PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to-destination 192.168.137.1

can instead be done along with other ufw commands on the command line

ufw route add in on eth0 to 192.168.137.1 port 53 proto udp

Or even, add an application file in /etc/ufw/applications.d/dns which contains:

[DNS]
title=DNS Server
description=Standard DNS Server
ports=53/udp

and then go:

ufw route add in on eth0 to 192.168.137.1 app DNS

The real advantage to this is that ufw status will show you (almost) everything that's going on, and not hide things away in before.rules!

Status: active

To                         Action      From
--                         ------      ----
192.168.137.1             ALLOW FWD   DNS on eth0

@nettoinfo
Copy link

nettoinfo commented Nov 11, 2022

Portuguese:
Pessoal, muito bom esse tutorial, parabéns!
Eu quero redirecionar a porta 443 para 8443, porque o Tomcat não trabalha com portas menores que 1024....
No FirewallD seria assim: /sbin/iptables -A PREROUTING -t nat -i ens160 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443
No UFW, como eu faria isso?

English (I'm sorry! - Thank you, Google Translator)
Guys, this tutorial is very good, congratulations!
I want to redirect port 443 to 8443, because Tomcat doesn't work with ports smaller than 1024....
In FirewallD it would look like this: /sbin/iptables -A PREROUTING -t nat -i ens160 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443
No UFW, how would I do that?

-------------------------------------------------- How resolve
Edit /etc/ufw/before.rules and add this:

*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
-A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
COMMIT

@aceqbaceq
Copy link

hello, thanks for the vauable info.
however i want to underline that if you enable NAT as desribed above you get a problem. when you restart uwf via

systemctl restart ufw

or

ufw reload

you notice that your iptables nat rules start to clone like that

iptables-save

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [66:3560]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
**-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE**
COMMIT

ufw reload

iptables-save

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [66:3560]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
**-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE
-A POSTROUTING -s 10.10.10.0/24 -o eth0 -j MASQUERADE**

COMMIT

etc.

i have found the reason of such behavior = https://bugs.launchpad.net/ufw/+bug/364558
so i ve taken the solution

# cat /etc/default/ufw | grep MANAG
MANAGE_BUILTINS=yes

Hope it helps !

@yoyosbg
Copy link

yoyosbg commented Apr 13, 2023

Not straight forward at all!
I expect use simple "ufw deny 3306" for NAT, after some configuration.

@ktechmidas
Copy link

@yoyosbg some ancient code of mine still works I think :)

https://github.com/Monotoko/iptables-nat-helper

@yoyosbg
Copy link

yoyosbg commented May 5, 2023

@yoyosbg some ancient code of mine still works I think :)

https://github.com/Monotoko/iptables-nat-helper

thanks

@friki67
Copy link

friki67 commented May 22, 2023

Hello! I'm trying to set up a VPN gateway (using LXD containers). I'm using ufw for killswitch service. Almost all is working except for port forwarding.


             ┌─────────────────────────┐                  ┌──────────────────────────┐
             │   SECOND CONTAINER      │                  │   OVPN CLIENT CONTAINER  │
             │                         │                  │                          │                ┌─────────────┐
             │     192.168.1.3         │       LAN        │       192.168.1.2        │    VPN TUNNEL  │             │
             │  gw:192.168.1.2     eth0├──────────────────┤eth0                 tun0 ├────────────────┤  VPN NODE   │
             │                         │                  │                          │                │             │
             │ HTTP test server in     │                  │                          │                └──┬──────────┘
             │        8107 port        │                  │                          │                   │
             └─────────────────────────┘                  └──────────────────────────┘                   │
                                                                                                      xxxxxxxxxxxx
                                                                                                   xxxx          xxx
                                                                                                xxx                x
                                                                                                 xx    INTERNET    x
                                                                                                   xxx           xxx
                                                                                                     xxxx    xxxx
                                                                                                        xxxxx

In my VPN gateway I have:

ufw rules

192.168.1.0/24                ALLOW       Anywhere

192.168.1.0/24                ALLOW OUT   Anywhere
Anywhere                      ALLOW OUT   Anywhere on tun0
<myvpnremoteip> 1194/tcp      ALLOW OUT   Anywhere #vpn remote address

before.rules extract:

*nat
:POSTROUTING ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
-A PREROUTING -i eth0 -p tcp --dport 8701 -j  DNAT --to-destination 192.168.1.3
-A POSTROUTING -s 192.168.1.0/24 -o tun0 -j MASQUERADE
COMMIT

I can access http://192.168.1.3:8701 directly, but I cannot access http://192.168.1.2:8107

So, what am I doing wrong?

@meirg
Copy link

meirg commented Oct 19, 2023

@bluebaroncanada

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

Yes, this is certainly preferable. You can add this at the end of the filter rules in /etc/ufw/before.rules (before the COMMIT)
-A ufw-before-forward -i eth0 -p tcp --dport 22 -j ACCEPT

@phlplowe9
Copy link

Nice simple guide but I spent days struggling to make it work.

The problem is ufw will append all of the rules to the iptables chains every time ufw is reloaded or started/stopped. So you end up with lots of copies of the same thing. Or in my case lots of permutations of slightly different things to test, none of which were applying since they were further down.

you should have a -F before the first -A to flush all of the old rules out first.

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