How to Use the Ubuntu ufw Command for Advanced Port Forwarding and NAT

The Power and Simplicity of UFW

When securing an Ubuntu server, the underlying kernel technology responsible for packet filtering is iptables (or more recently, nftables). While incredibly powerful, the syntax for these raw tools is notoriously complex and difficult for junior administrators to read. To solve this, Ubuntu introduced UFW (Uncomplicated Firewall).

UFW is an interface designed to simplify the process of configuring a firewall. While it is widely known for basic tasks—like running ufw allow ssh—it is also capable of handling advanced routing scenarios, such as Port Forwarding and Network Address Translation (NAT), which are essential when using an Ubuntu server as a gateway or a Docker host.

Step 1: Enabling IP Forwarding in the Kernel

By default, the Linux kernel will drop any packets that are not explicitly destined for its own IP address. If you want Ubuntu to act as a router (forwarding packets from one network interface to another, or from an external port to an internal IP), you must enable IP Forwarding.

Open the sysctl configuration file:

sudo nano /etc/sysctl.conf

Uncomment or add the following line:

net.ipv4.ip_forward=1

Apply the change immediately without rebooting:

sudo sysctl -p

Step 2: Configuring UFW Default Forwarding Policy

By default, UFW is configured to drop all forwarded packets. We must change this default policy in the UFW configuration file to allow traffic to pass through the routing engine.

Open the UFW configuration file:

sudo nano /etc/default/ufw

Find the DEFAULT_FORWARD_POLICY directive and change it from "DROP" to "ACCEPT":

DEFAULT_FORWARD_POLICY="ACCEPT"

Step 3: Implementing Port Forwarding (Pre-Routing)

Port forwarding requires modifying the iptables NAT table. UFW allows you to inject raw iptables rules by editing its before.rules file. This file contains rules that are evaluated before any standard UFW rules you create via the command line.

Assume your Ubuntu server has a public IP on the eth0 interface. You want to forward all incoming traffic on port 8080 to an internal web server at 10.0.0.5 on port 80.

Open the before rules file:

sudo nano /etc/ufw/before.rules

At the very top of the file (before the *filter section), add the NAT configuration:

*nat
:PREROUTING ACCEPT [0:0]

# Forward port 8080 to internal IP 10.0.0.5:80
-A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:80

COMMIT

Step 4: Implementing Outbound NAT / IP Masquerading

If your internal server (10.0.0.5) needs to respond to the request or access the internet, its private IP address cannot be routed over the public internet. You must configure Masquerading (Source NAT). This tells the Ubuntu gateway to replace the internal server’s source IP with its own public IP before sending the packet out.

In the same /etc/ufw/before.rules file, modify the *nat block you just created to include the POSTROUTING rule:

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

# Forward port 8080 to internal IP 10.0.0.5:80
-A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.5:80

# Masquerade traffic leaving the eth0 interface
-A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

COMMIT

Step 5: Allowing the Traffic Through the Firewall

Even though you have configured the NAT translation, the actual packets must still pass through the standard UFW filter. You must explicitly tell UFW to allow traffic to reach the internal server.

Run the following command to allow the forwarded port:

sudo ufw route allow in on eth0 out on eth1 to 10.0.0.5 port 80

(Assuming eth1 is the interface connected to the internal 10.0.0.0/24 network).

Finally, reload UFW to apply all changes:

sudo ufw reload

Conclusion

While UFW is celebrated for its simplicity in handling basic port blocking, its ability to cleanly integrate raw iptables NAT rules makes it a surprisingly powerful tool. By modifying the before.rules file and enabling kernel IP forwarding, administrators can transform a standard Ubuntu server into a fully functional, highly secure NAT router and port-forwarding gateway.

RELATED POSTS

  • How to Disable the Ping (ICMP) Response in Linux using sysctl
  • How to Install and Configure the Zabbix Network Monitoring System on Debian
  • How to Install and Configure the Postfix Mail Server on Ubuntu
  • How to Install and Configure the Proxmox Backup Server (PBS) Client on Debian
  • How to Run Linux GUI Apps Natively on Windows 11 using WSL
  • Get the best tech tips delivered straight to your inbox.

    Join thousands of readers mastering Apple, Google, Microsoft, and Linux.