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
ufw reset deletes all rules. Note down your current configuration before running it.
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