Firewall Configuration Basics: Getting Started with ufw and firewalld

Firewall Configuration Basics: Getting Started with ufw and firewalld

What Is a Firewall?

A firewall filters network traffic — allowing or blocking connections based on rules. On Linux, the kernel's iptables/nftables handles the actual filtering, while ufw and firewalld are higher-level management tools that make configuration easier.

Default tool by distribution

  • Ubuntu / Debian: ufw (Uncomplicated Firewall)
  • RHEL / CentOS / Fedora: firewalld

How Do ufw and firewalld Differ?

ufw prioritizes simplicity with a straightforward CLI and static rulesets. firewalld uses a zone-based model and supports dynamic rule changes at runtime via D-Bus — no service restart required.

Feature ufw firewalld
Primary distros Ubuntu / Debian RHEL / CentOS
Rule model Static Dynamic (zone-based)
Complexity Simple Flexible but complex
Backend iptables / nftables nftables / iptables

ufw Basics

Install and Enable

Ubuntu includes ufw by default. Always allow SSH before enabling — otherwise you'll lock yourself out of remote connections.

$ sudo ufw status
Status: inactive

$ sudo ufw allow 22/tcp
Rules updated
Rules updated (v6)

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Allow SSH (port 22) before running ufw enable. If you enable the firewall first without allowing SSH, you will be locked out of remote connections.

Allowing and Blocking Ports

# Allow by port number
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp

# Allow by service name (from /etc/services)
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow https

# Block a port
$ sudo ufw deny 23/tcp

# Allow from a specific IP range
$ sudo ufw allow from 192.168.1.0/24

# Allow a specific IP to a specific port
$ sudo ufw allow from 192.168.1.100 to any port 3306

Default Policies

# Block all incoming by default (recommended)
$ sudo ufw default deny incoming

# Allow all outgoing by default
$ sudo ufw default allow outgoing

Viewing and Deleting Rules

# Show rules with numbers
$ sudo ufw status numbered
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] 80/tcp                     ALLOW IN    Anywhere
[ 3] 443/tcp                    ALLOW IN    Anywhere
# Delete by rule number
$ sudo ufw delete 3

# Delete by rule spec
$ sudo ufw delete allow 443/tcp

Disabling and Resetting ufw

# Disable temporarily (rules preserved)
$ sudo ufw disable

# Reset all rules
$ sudo ufw reset

firewalld Basics

Install and Start

On RHEL-based systems firewalld is typically pre-installed.

# RHEL / CentOS
$ sudo yum install firewalld

# Fedora
$ sudo dnf install firewalld

$ sudo systemctl start firewalld
$ sudo systemctl enable firewalld

Understanding Zones

firewalld assigns rules to zones. Each network interface belongs to one zone, and that zone's rules apply to all traffic on that interface.

# List available zones
$ firewall-cmd --get-zones
block dmz drop external home internal public trusted work

# Show the default zone
$ firewall-cmd --get-default-zone
public

# Show which zones are active and their interfaces
$ firewall-cmd --get-active-zones

Allowing and Removing Ports

# Show current rules
$ firewall-cmd --list-all

# Allow a port temporarily (lost on reboot)
$ sudo firewall-cmd --add-port=80/tcp

# Allow a port permanently
$ sudo firewall-cmd --add-port=80/tcp --permanent
$ sudo firewall-cmd --reload

# Allow by service name
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service=https --permanent
$ sudo firewall-cmd --reload

# Remove a port
$ sudo firewall-cmd --remove-port=80/tcp --permanent
$ sudo firewall-cmd --reload

--permanent writes to config files so settings survive reboots. Without it, changes only apply to the current session. Run --reload to apply permanent changes immediately without a full restart.

List Available Service Names

$ firewall-cmd --get-services

Adding Source IPs to a Zone

# Trust a specific subnet
$ sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
$ sudo firewall-cmd --reload

What Are the Common Configuration Patterns?

Web Server (HTTP / HTTPS + SSH)

Using ufw:

$ sudo ufw default deny incoming
$ sudo ufw default allow outgoing
$ sudo ufw allow ssh
$ sudo ufw allow http
$ sudo ufw allow https
$ sudo ufw enable

Using firewalld:

$ sudo firewall-cmd --set-default-zone=public
$ sudo firewall-cmd --add-service=ssh --permanent
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service=https --permanent
$ sudo firewall-cmd --reload

Database Server (Allow MySQL from a Specific IP Only)

Using ufw:

$ sudo ufw allow from 192.168.1.10 to any port 3306 proto tcp

Using firewalld:

$ sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.10" port port="3306" protocol="tcp" accept' --permanent
$ sudo firewall-cmd --reload

What to Do When Settings Don't Take Effect?

If connections fail after making changes, check in this order:

# ufw: verify the firewall is active
$ sudo ufw status
Status: active

# firewalld: verify the service is running
$ sudo systemctl status firewalld

# Confirm the port is actually listening
$ ss -tlnp | grep :80

Cloud environments (AWS / GCP / Azure)

Cloud security groups and network ACLs operate upstream of the OS firewall. Even if you open a port in ufw/firewalld, the cloud-level rules may still block it. Always check both layers when troubleshooting connectivity.

# Enable and tail ufw logs
$ sudo ufw logging on
$ sudo tail -f /var/log/ufw.log

# View firewalld logs via journalctl
$ sudo journalctl -u firewalld -f

Next Reading