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
@dsossna
Copy link

dsossna commented Sep 4, 2024

@casesolved-co-uk
No I need nat, because my Pi is behind a wlan access point that routes the traffik to the internet. I can not establish static routes back to the vlan networks. If I try to ping the wlan access points IP iget the answer time fault. This is a typical error if the reverse route is not available.
You are wright that normaly the icmp has no problem with a local connected subnet. But if I ping from a computer at a vlan subnet the router has to nat this because the router in front do not know the subnet

computer ----pi vlan port----Pi wlan port-----GLI Net router with nat to the Internet

@casesolved-co-uk
Copy link

casesolved-co-uk commented Sep 4, 2024

@dsossna
Then there are two ways to solve it:

  1. Add routes to your internet router so that it knows about all your other networks and the pi gateway and ignore internal NAT (recommended). I would try to put all your networks on the same larger subnet (e.g. 10.0.0.0/8) and subnet these onto your vlans (10.0.1.0/24) so your router only has to NAT a single network.
  2. NAT overload IPs on your pi (which is what you are attempting). However, having double nested NAT isn't necessary or recommended and is prone to issues like you're seeing

@dsossna
Copy link

dsossna commented Sep 4, 2024

@casesolved-co-uk
Yes I know that doble nat ios not nassasary, but this is an shool network where I have no internet, only with my GLI Spitz Wlan Hotspot I have Internet with gsm modem in the router. I installed the Pi as a router for the local practise networks for my students. I am using linux as a nat router for a long time and so I do not understand why this constallation is not working. When I am in other places there are subnets with firewall and routing, so I know how to translate the traffic. I normaly use this vommand for nat. iptables -t nat -A POSTROUTING -o enp0sx -j MASQUERADE and this is working fine. Now my wlan network card name is very long in bookworm, but this could not be the reason

@dsossna
Copy link

dsossna commented Sep 5, 2024

I solved the problem. It was a mistake in the Name of the wlan interface

@coding-linux
Copy link

my ufw router configuration:

#eth0=WAN (wired WAN)
#eth1=LAN (wired LAN)
#wlan0=LAN (wifi LAN)

sudo apt update
sudo apt dist-upgrade
sudo apt install nano iptables dnsmasq ufw


sudo nano /etc/network/interfaces:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.1.10
netmask 255.255.255.0
broadcast 192.168.1.255

auto eth1
iface eth1 inet static
address 192.168.10.1
netmask 255.255.255.0
broadcast 192.168.10.255


sudo nano /etc/dnsmasq.conf

interface=eth1
listen-address=192.168.10.1
bind-interfaces
domain-needed
bogus-priv
dhcp-range=192.168.10.50,192.168.10.80,24h


sudo nano /etc/sysctl.conf:

net.ipv4.ip_forward=1

or for ufw only:

sudo nano /etc/ufw/sysctl.conf:

net.ipv4.ip_forward=1


sudo nano /etc/default/ufw:

#Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if
#you change this you will most likely want to adjust your rules.
DEFAULT_INPUT_POLICY="DROP"

#Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if
#you change this you will most likely want to adjust your rules.
DEFAULT_OUTPUT_POLICY="ACCEPT"

#Set the default forward policy to ACCEPT, DROP or REJECT. Please note that
#if you change this you will most likely want to adjust your rules
DEFAULT_FORWARD_POLICY="ACCEPT"


sudo nano /etc/ufw/before.rules:

#rules.before
#Rules that should be run before the ufw command line added rules. Custom
#rules should be added to one of these chains:
#ufw-before-input
#ufw-before-output
#ufw-before-forward

#Don't delete these required lines, otherwise there will be errors
#NAT table rules
*nat
:POSTROUTING ACCEPT [0:0]

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

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

*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
#End required lines

#allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

#quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP

#ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j DROP

#ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT

#allow dhcp client to work

-A ufw-before-input -i eth1 -p udp --dport 67 -j ACCEPT
-A ufw-before-input -i eth1 -p udp --dport 68 -j ACCEPT

-A ufw-before-input -i eth1 -p udp --dport 53 -j ACCEPT
-A ufw-before-input -i eth1 -p tcp --dport 53 -j ACCEPT

-A ufw-before-input -i eth1 -p tcp --dport 22 -j ACCEPT
-A ufw-before-input -p tcp --dport 22 -j DROP

#ufw-not-local
-A ufw-before-input -j ufw-not-local

#if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN

#if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN

#if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN

#all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP

#allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
#is uncommented)
-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j DROP

#allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
#is uncommented)
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j DROP

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


sudo ufw disable
sudo ufw enable

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