Ubuntu 24.04 LTS as Firewall Router in Azure Notes

by Sep 12, 2025IT Tips0 comments

Latest version of these notes available here: https://github.com/toggenation/ubuntu-fw

README.md

Using Ubuntu in Azure as a Firewall, Router, VPN

  1. create vnet Dual IPv4 / IPv6 with multiple subnets (WAN, LAN, DEV etc)
  2. Add burstable with .5GB ram x 2 vms
  3. firewall: Add a WAN nic with Dual IPv4 / IPv6
  4. firewall: AllowAny NSG for WAN NIC
  5. firewall: Add a LAN nic with Dual IPv4 / IPv6
  6. firewall: enable Forwarding on LAN NIC
  7. web: Add LAN NIC with ipv6/4
  8. azureuser with key from me
  9. Route table with default routes pointing at LAN interface on Firewall
  10. Install etckeeper

Create Route Table

IPv4 route to: 0.0.0.0/0 via: IPV4_ADDRESS_OF_FIREALL_LAN_INTERFACE
IPv6 route to: ::/0 via: IPV6_ADDRESS_OF_FIREALL_LAN_INTERFACE

Associate Route Table with subnets "behind" firewall (e.g. LAN, DEV etc)

Update VMs

apt-get update # Killed triggered
sudo lsblk

Add swap options 1

sudo swapon --show sudo fallocate -l 1G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab sudo swapon --show

Add swap options 1

sudo swapon --show sudo fallocate -l 1G /mnt/swapfile sudo chmod 600 /mnt/swapfile sudo mkswap /mnt/swapfile echo '/mnt/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab sudo swapon -a sudo swapon --show

Add swap option 2 - ephemeral storage

https://learn.microsoft.com/en-us/troubleshoot/azure/virtual-machines/linux/create-swap-file-linux-vm

#!/bin/sh # /var/lib/cloud/scripts/per-boot/swap.sh # Percent of space on the ephemeral disk to dedicate to swap. Here 30% is being used. Modify as appropriate. PCT=0.3 # Location of the swap file. Modify as appropriate based on the location of the ephemeral disk. LOCATION=/mnt if [ ! -f ${LOCATION}/swapfile ] then # Get size of the ephemeral disk and multiply it by the percent of space to allocate size=$(/bin/df -m --output=target,avail | /usr/bin/awk -v percent="$PCT" -v pattern=${LOCATION} '$0 ~ pattern {SIZE=int($2*percent);print SIZE}') echo "$size MB of space allocated to swap file" # Create an empty file first and set correct permissions /bin/dd if=/dev/zero of=${LOCATION}/swapfile bs=1M count=$size /bin/chmod 0600 ${LOCATION}/swapfile # Make the file available to use as swap /sbin/mkswap ${LOCATION}/swapfile fi # Enable swap /sbin/swapon ${LOCATION}/swapfile /sbin/swapon -a # Display current swap status /sbin/swapon -s
chmod +x /var/lib/cloud/scripts/per-boot/swap.sh

After enabling swap install etckeeper

sudo apt-get install etckeeper

Enable forwarding - 2 options to do that

  1. edit /etc/ufw/sysctl.conf or,
  2. edit /etc/sysctl.conf
# /etc/ufw/sysctl.conf # Uncomment this to allow this host to route packets between interfaces net/ipv4/ip_forward=1 net/ipv6/conf/default/forwarding=1 net/ipv6/conf/all/forwarding=1
# /etc/sysctl.conf net.ipv4.ip_forward=1 # the same for ipv6 # reload settings
# check setting sysctl -p sysctl -a | grep forward ufw reload

Modify /etc/defaults/ufw can be done by hand or CLI

# edit /etc/defaults/ufw by hand DEFAULT_FORWARD_POLICY="ACCEPT" # or via cli ACCEPT = allow, DROP = deny sudo ufw default deny forward sudo ufw default allow forward

View via CLI

sudo ufw reload cat /etc/default/ufw | grep FOR

Modify /etc/ufw/before.rules

Where to add the rules https://documentation.ubuntu.com/server/how-to/security/firewalls/#add-the-configuration

"Add the following to the top of the file, just after the header comments:"

# /etc/ufw/before.rules # NAT *nat -F :POSTROUTING ACCEPT [0:0] # add rules :PREROUTING ACCEPT [0:0] # port forward http,https to nginx server -A PREROUTING -p tcp -i eth0 -m multiport --dports 443,80 -j DNAT --to-destination 10.0.0.51 # port forward ssh on port 7022 to nginx server -A PREROUTING -p tcp -i eth0 --dport 7022 -j DNAT --to-destination 10.0.0.51:22 -A POSTROUTING -s 10.0.0.51/24 -o enp1s0 -j MASQUERADE COMMIT

Modify /etc/ufw/before6.rules

# /etc/ufw/before6.rules # NAT *nat -F :POSTROUTING ACCEPT [0:0] # add rules :PREROUTING ACCEPT [0:0] # port forward http,https to nginx server -A PREROUTING -p tcp -i eth0 -m multiport --dports 443,80 -j DNAT --to-destination fd00:cd2:3b3c:1::4 # port forward ssh on port 7022 to nginx server -A PREROUTING -p tcp -i eth0 --dport 7022 -j DNAT --to-destination fd00:cd2:3b3c:1::4 -A POSTROUTING -s fd00:cd2:3b3c:1::/64 -o eth0 -j MASQUERADE COMMIT

Test SSH to firewall and web server VM

# test vm ssh -l azureuser IPV6_ADDRESS_PUBLIC_IP -p 7322 ssh -l azureuser IPV4_ADDRESS_PUBLIC_IP -p 7322 # firewall ssh -l azureuser IPV6_ADDRESS_PUBLIC_IP ssh -l azureuser IPV4_ADDRESS_PUBLIC_IP

UFW enable OpenVPN

sudo ufw allow 1194/udp
sudo ufw route allow in on eth0 out on eth1 from 210.185.79.208 to 10.45.1.5 port 80 # allow ssh from internal to firewall sudo ufw allow from 10.45.1.0/24 to 10.45.1.4 port 22 sudo ufw route allow in on eth1 out on eth0 from 10.45.1.0/24 to 0.0.0.0/0 # change default policy sudo ufw route allow in on eth0 out on eth1 from 210.185.79.208 to 10.45.1.5 port 22 sudo ufw route allow in on eth0 out on eth1 from 1.2.3.4 to 10.45.1.5 port 80
sudo ufw status numbered Status: active To Action From -- ------ ---- [ 1] 10.45.0.4 22/tcp ALLOW IN 210.185.79.208 [ 2] 1194/udp ALLOW IN Anywhere [ 3] 10.45.0.4 80/tcp ALLOW IN 210.185.79.208 [ 4] 10.45.0.4 443/tcp ALLOW IN 210.185.79.208 [ 5] 10.45.1.5 80/tcp ALLOW IN 4.200.137.158 [ 6] 10.45.1.5 443/tcp ALLOW IN 4.200.137.158 [ 7] 10.45.1.5 22/tcp ALLOW IN 4.200.137.158 [ 8] fd00:2d9e:b4ea::4 22/tcp ALLOW IN 2603:1010:202:3::9 [ 9] fd00:2d9e:b4ea:1::5 80/tcp ALLOW IN 2603:1010:202:3::9 [10] fd00:2d9e:b4ea:1::5 443/tcp ALLOW IN 2603:1010:202:3::9 [11] 1194/udp (v6) ALLOW IN Anywhere (v6)

Logging

sudo ufw logging on tail -f /var/log/ufw.log

How to view UFW commands used to create a rules

Examples of commands to allow different types of traffic

sudo ufw show added Added user rules (see 'ufw status' for running firewall): # allow OpenVPN from anywhere on IPv6 and IPv4 udp only ufw allow 1194/udp # or to add OpenVPN 1194 on both udp/tcp use ufw allow openvpn # Allow SSH to firewall from one host IP # Where 10.45.0.4 is the firewall WAN interface private IP ufw allow from 210.185.79.208 to 10.45.0.4 port 22 proto tcp # Allow forwarding of traffic from Azure LAN Subnet to anywhere sudo ufw route allow in on eth1 out on eth0 from 10.82.1.0/24 # Allow LAN Subnet hosts to SSH to the firewall LAN Interface # Where 10.45.1.0/24 is the LAN subnet and 10.45.1.4 is the Firewalls LAN Address ufw allow from 10.45.1.0/24 to 10.45.1.4 port 22 # Allow anything from a specific host to be forward to the web server on port 80 ufw route allow in on eth0 out on eth1 from 210.185.79.208 to 10.45.1.5 port 80 # Allow anything from a specific host to be forward to the web server on port 22 ufw route allow in on eth0 out on eth1 from 210.185.79.208 to 10.45.1.5 port 22 sudo ufw route allow in on eth0 out on eth1 from any to fd00:6fcf:3e46:1::5 port 80 proto tcp # Allow the OpenVPN Client Subnet to beforwarded to the internet ufw route allow in on tun0 out on eth0 from 10.52.0.0/24 # Allow forward from internet to web server on port 80 ufw route allow in on eth0 out on eth1 to 10.82.1.5 port 80 proto tcp # allow specific host to connect to port 22/tcp on eth0 ufw allow in on eth0 from 123.243.170.175 port 22 proto tcp # allow route from IPv6 VPN Subnet to internet ufw route allow in on tun0 out on eth0 from fdaf:7a2e:a079:52::/64 # allow forwarding from IPv6 LAN Subnet to Internet ufw route allow in on eth1 out on eth0 from fd00:2d9e:b4ea:1::/64 # Allow IPv6 from a host to port 22 on firewall sudo ufw allow in on eth0 from 2603:1010:200::32c to fd00:cd2:3b3c::4 port 22 proto tcp
# 10.82.1.4 ufw allow in on eth0 from 52.147.37.48 to 10.82.0.4 port 22 proto tcp ufw route allow in on eth0 out on eth1 to 10.82.1.4 port 80 proto tcp ufw route allow in on eth1 out on eth0 from 10.82.1.0/24 ufw route allow in on eth0 out on eth1 to 10.82.1.5 port 443 proto tcp ufw route allow in on eth0 out on eth1 to fd00:6fcf:3e46:1::5 port 80 proto tcp ufw route allow in on eth0 out on eth1 to fd00:6fcf:3e46:1::5 port 443 proto tcp ufw route allow in on eth0 out on eth1 to fd00:6fcf:3e46:1::5 port 22 proto tcp ufw route allow in on eth1 out on eth0 from fd00:6fcf:3e46:1::/64

Add a third subnet

Associate route-table to subnet

Update firewall netplan to have a route for both IPv4 and IPv6

sudo /etc/netplan/50-cloud-init.yaml
# /etc/netplan/50-cloud-init.yaml eth1: match: macaddress: "00:22:48:e4:34:96" driver: "hv_netvsc" dhcp4: true dhcp4-overrides: use-dns: false route-metric: 200 dhcp6: true dhcp6-overrides: use-dns: false route-metric: 200 set-name: "eth1" # add this to eth1 routes: - to: 10.82.2.0/24 via: 10.82.1.1 - to: fd00:e808:aa83:2::/64 scope: link
ip -6 route #output fd00:e808:aa83::/64 dev eth0 proto ra metric 100 pref medium fd00:e808:aa83:1::/64 dev eth1 proto ra metric 200 pref medium fd00:e808:aa83:2::/64 dev eth1 proto static metric 1024 pref medium fe80::/64 dev eth0 proto kernel metric 256 pref medium fe80::/64 dev eth1 proto kernel metric 256 pref medium default via fe80::1234:5678:9abc dev eth0 proto ra metric 100 expires 8997sec pref medium default via fe80::1234:5678:9abc dev eth1 proto ra metric 200 expires 8997sec pref medium

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.