Firewalls on Linux: ufw and nftables

Every Linux server should have a firewall. Even on a “private” cloud, ports left open are ports getting scanned. Linux’s kernel has a built-in firewall (called netfilter); the user-space tools to control it are iptables (legacy), nftables (modern), and friendly wrappers like ufw and firewalld.

The simple case: ufw (Uncomplicated Firewall)

ufw is the default firewall tool on Ubuntu and a popular choice on Debian. It hides nftables/iptables behind one-liner commands.

# Install (Ubuntu has it preinstalled)
sudo apt install ufw

# Set sane defaults: deny incoming, allow outgoing
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow specific services
sudo ufw allow ssh                # port 22
sudo ufw allow http               # port 80
sudo ufw allow https              # port 443
sudo ufw allow 8080/tcp
sudo ufw allow 53/udp

# Allow from a specific IP only
sudo ufw allow from 198.51.100.5 to any port 22

# Allow a range
sudo ufw allow 60000:61000/udp

# Deny something explicitly
sudo ufw deny 23                  # block telnet

# Enable the firewall (this drops everything not allowed)
sudo ufw enable

# Status
sudo ufw status verbose
sudo ufw status numbered          # lists rules with numbers (for delete)

# Delete a rule by number
sudo ufw delete 3

# Reset all rules
sudo ufw reset

Critical: open SSH BEFORE enabling

If you SSH in and run ufw enable without first allowing SSH, you’ll lock yourself out. Always:

sudo ufw allow ssh
sudo ufw enable

The capable case: nftables

nftables is the modern netfilter user-space tool. Replaces iptables. More expressive syntax, less duplication.

Config lives in /etc/nftables.conf. A minimal good config:

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        iif lo accept                                    # localhost
        ct state established,related accept              # ongoing connections
        ct state invalid drop

        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        tcp dport ssh accept                              # SSH
        tcp dport { http, https } accept                  # web
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Apply and enable:

sudo nft -f /etc/nftables.conf
sudo systemctl enable --now nftables

# View current ruleset
sudo nft list ruleset

The legacy case: iptables

iptables is being phased out but still works on most distros. Quick reference:

# Show rules
sudo iptables -L -v -n

# Allow SSH from a specific IP
sudo iptables -A INPUT -p tcp -s 198.51.100.5 --dport 22 -j ACCEPT

# Drop everything else not explicitly allowed
sudo iptables -P INPUT DROP

# Save (distro-specific)
sudo apt install iptables-persistent       # then it auto-saves on reboot
sudo iptables-save > /etc/iptables/rules.v4

The “almost-only” rules you need on a typical server

  • Allow SSH (preferably restricted to your IP or VPN).
  • Allow ports your services use (80/443 for web, custom ports for apps).
  • Allow loopback (127.0.0.1).
  • Allow established/related connections.
  • Drop everything else.

Test from the outside

Don’t trust your firewall config until you test it from another machine:

# From another host
nmap -p 22,80,443 myserver.com
nc -zv myserver.com 80                # connect, then close
curl -I http://myserver.com/

fail2ban: dynamic blocking

A firewall blocks ports. fail2ban blocks IPs based on suspicious behavior in your logs (failed SSH attempts, etc.):

sudo apt install fail2ban
sudo systemctl enable --now fail2ban

# See banned IPs
sudo fail2ban-client status sshd

Common mistakes

  • Enabling a firewall without allowing SSH first — instant lockout.
  • Allowing 0.0.0.0/0 when you meant a specific IP — exposes to the entire internet.
  • Forgetting that cloud providers ALSO have firewalls (security groups). You may need to allow at both layers.
  • Not testing rules from outside — looks fine on the server, blocked from the internet.

What to learn next

That covers the networking section. Next: shell programming — turning your one-liners into reusable scripts.

Similar Posts

Leave a Reply

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