Blog » Linux » How to Use firewalld in Linux: Manage Zones and Rules the Right Way
› how-to-use-firewalld-in-linux Linux terminal showing firewalld commands with zone diagram and security shield

How to Use firewalld in Linux: Manage Zones and Rules the Right Way

Table of Contents

If you manage a Linux server running RHEL, Rocky Linux, or Fedora, knowing how to use firewalld in Linux is non-negotiable. It’s the default firewall tool on these distros, and once you understand its zone-based model, managing network security becomes surprisingly straightforward. I’m going to walk you through everything from installation to rich rules, with real examples from my own server setups.

I still remember the first time I deployed a Rocky Linux box for a web project. I had Nginx configured perfectly, the DNS was pointing right, and yet nothing loaded. I spent a solid 20 minutes blaming Nginx before realizing I never opened port 80 in firewalld. That day taught me: always check the firewall first.

What Is firewalld and Why Does It Matter

firewalld is a dynamic firewall management tool that acts as a frontend for nftables and the Linux netfilter framework. Instead of writing raw iptables rules by hand, firewalld gives you a cleaner interface built around zones and services. It manages rules without requiring a full service restart, which is a huge deal on production servers.

The key advantage? firewalld separates runtime configuration from permanent configuration. You can test a rule live, confirm it works, then make it permanent. No more locking yourself out of your own server because of a bad rule you can’t undo. Refer to the firewalld official concepts documentation for deeper architectural details.

firewalld vs iptables vs UFW: Which Should You Use

This comes down to your distro and use case:

RackNerd Mobile Leaderboard Banner

Get a VPS from as low as $11/year! WOW!

  • firewalld: Default on RHEL, Rocky Linux, AlmaLinux, CentOS, and Fedora. Zone-based, dynamic, great for servers with multiple network interfaces.
  • iptables: The raw, low-level tool. Still works everywhere, but writing rules manually is tedious and error-prone.
  • UFW (Uncomplicated Firewall): The Debian/Ubuntu default. Simpler syntax, but lacks the zone model that makes firewalld powerful for complex setups.

If you’re on a RHEL-family distro, use firewalld. It’s already there and it’s what the ecosystem expects.

What Distros Use firewalld by Default

firewalld ships as the default firewall manager on RHEL 7+, Rocky Linux, AlmaLinux, CentOS Stream, and Fedora. That covers the vast majority of enterprise Linux deployments. The Red Hat Enterprise Linux firewall documentation is the authoritative upstream reference if you want the full picture.

Installing and Starting firewalld

Install firewalld on RHEL/CentOS/Rocky/Fedora

On most RHEL-family systems, firewalld is already installed. If it’s missing for some reason:

sudo dnf install firewalld

Install firewalld on Ubuntu/Debian (Optional)

If you’re coming from Ubuntu or Debian and want to try firewalld instead of UFW:

sudo ufw disable
sudo apt install firewalld

Make sure you disable UFW first. Running both simultaneously is a recipe for confusing rule conflicts.

Enable and Check the firewalld Service

Use systemctl to enable and start firewalld:

sudo systemctl enable --now firewalld
sudo firewall-cmd --state

The --state command should return running. If it doesn’t, check for conflicts with iptables or other firewall services.

Understanding firewalld Zones: The Core Concept

Zones are the mental model you need to internalize. A zone defines the trust level for a network connection. Every network interface gets assigned to a zone, and that zone determines what traffic is allowed through.

Think of zones like rooms in a building. The “public” zone is the lobby where anyone can enter but only through specific doors. The “trusted” zone is the back office where everything is allowed. The “drop” zone is a brick wall with no doors at all.

The Default Zones and Their Trust Levels

firewalld comes with 9 predefined zones, from most restrictive to most permissive:

Key Zones to Know

  • drop: Silently drops all incoming connections. No rejection notice. Maximum paranoia.
  • public: The default zone. Only explicitly allowed services get through.
  • dmz: For servers exposed to the internet but isolated from your internal network.
  • internal: For LAN or homelab networks where you trust devices more.
  • trusted: Allows all incoming connections. Use with extreme caution.

Checking and Changing Your Active Zone

# See which zones are currently active
sudo firewall-cmd --get-active-zones

# List all available zones
sudo firewall-cmd --get-zones

# See all rules in the default zone
sudo firewall-cmd --list-all

# Change the default zone
sudo firewall-cmd --set-default-zone=internal

# Assign a specific interface to a zone
sudo firewall-cmd --zone=public --change-interface=eth0 --permanent

In my homelab, I keep my primary interface in the public zone and my LAN-facing interface in internal. It keeps things clean and predictable.

Adding Services and Opening Ports

Working with Predefined Services

firewalld ships with 80+ predefined service definitions. These bundle the correct port and protocol so you don’t have to memorize port numbers.

# List all available services
sudo firewall-cmd --get-services

# Add HTTP to the public zone
sudo firewall-cmd --zone=public --add-service=http

# Add HTTPS
sudo firewall-cmd --zone=public --add-service=https

Opening Ports Directly

If your application uses a non-standard port that doesn’t match a predefined service:

# Open port 8080 for TCP traffic
sudo firewall-cmd --zone=public --add-port=8080/tcp

# Open a UDP port
sudo firewall-cmd --zone=public --add-port=51820/udp

The Critical Difference: Runtime vs Permanent

This is where most beginners get tripped up. I’ve seen it in forums countless times, and I’ve made this mistake myself.

Runtime vs Permanent: The Rule

  • Without --permanent: Rule is active immediately but disappears on reload or reboot.
  • With --permanent: Rule is saved to disk but is NOT active until you reload.
  • To activate permanent rules: Run sudo firewall-cmd --reload

The smart workflow: test your rule without --permanent first. Verify it works. Then add it again with --permanent and reload. If you mess up the runtime rule, a simple reload reverts everything back to the permanent config.

# Test first (runtime only)
sudo firewall-cmd --zone=public --add-service=http

# Verify it works, then make permanent
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --reload

Real-World firewalld Examples

Generic “open port 80” examples only get you so far. Here are scenarios I’ve actually dealt with on production and homelab servers.

Setting Up a Web Server (HTTP and HTTPS)

If you’re setting up Nginx or Apache, you need ports 80 and 443 open:

sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload

# Verify
sudo firewall-cmd --list-all

Allowing SSH on a Non-Standard Port

Moving SSH off port 22 is a common hardening step. Pair this with a secure SSH configuration and SSH key authentication for real defense-in-depth.

# Allow SSH on port 2222
sudo firewall-cmd --zone=public --add-port=2222/tcp --permanent

# Remove the default SSH service (port 22)
sudo firewall-cmd --zone=public --remove-service=ssh --permanent

sudo firewall-cmd --reload

Opening a Database Port for a Specific IP (Rich Rules)

Rich rules are where firewalld’s real power shows up. You can restrict access by source IP, which is essential for database servers.

# Allow MySQL (3306) only from a specific application server
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.1.50" port port="3306" protocol="tcp" accept' --permanent

# Block all traffic from a suspicious IP
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.5" drop' --permanent

sudo firewall-cmd --reload

I used this exact pattern last year when isolating a PostgreSQL instance so only my app tier could reach it. Rich rules make firewalld competitive with much more complex tools.

Masquerading and Port Forwarding

Enable IP Masquerading (NAT)

If your server acts as a gateway, runs containers, or serves as a WireGuard VPN server, you need masquerading (NAT). Before enabling it, make sure IP forwarding is turned on via sysctl for kernel-level network parameters.

# Enable masquerading on the external zone
sudo firewall-cmd --zone=external --add-masquerade --permanent
sudo firewall-cmd --reload

Forward Ports with firewalld

Port forwarding redirects incoming traffic from one port to another. Useful for routing web traffic to an application server running on a high port:

# Forward port 80 to 8080
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
sudo firewall-cmd --reload

Verifying and Troubleshooting firewalld Rules

Check What firewalld Is Actually Allowing

Always verify after making changes. Trust, but verify.

# Show everything in the active zone
sudo firewall-cmd --list-all

# Show all zones and their rules
sudo firewall-cmd --list-all-zones

# Check firewalld logs for errors
sudo journalctl -u firewalld

From outside the server, use nmap to test your firewall rules and confirm ports are open or closed as expected. On the server itself, use the ss command or listening ports check to confirm services are actually running before blaming the firewall.

# Confirm a service is listening on the expected port
ss -tlnp | grep :80

Common firewalld Mistakes and Fixes

Top 3 Mistakes I See (And Have Made)

  1. Adding --permanent but forgetting --reload: The rule is saved but never activates. You stare at --list-all wondering why it’s not working.
  2. Adding rules to the wrong zone: Your interface is assigned to public, but you added the rule to internal. Check --get-active-zones first.
  3. Running firewalld and iptables simultaneously: They conflict at the kernel level. Pick one. If you’re using firewalld, make sure iptables-services is stopped and disabled.

If things are truly broken, you can also check which ports are open at the system level, or step back and troubleshoot Linux network issues more broadly.

Wrapping Up: firewalld Is Worth Learning Well

If you’re running RHEL, Rocky Linux, or Fedora, firewalld isn’t optional. It’s the tool your distro expects you to use. The zone-based model clicks fast once you start applying it to real scenarios. Test rules at runtime, commit them permanently, and always verify with --list-all.

Pair firewalld with fail2ban for automated intrusion prevention, and you’ve got a solid security foundation for any server.

Want to keep hardening your Linux setup? Check out our guides on secure SSH configuration and setting up a WireGuard VPN server for the natural next steps after firewall configuration.

author avatar
Alexa Velinxs
I'm Alexa Velinxs, a cryptocurrency trading expert passionate about demystifying digital assets for both beginners and seasoned investors. Through my writing, I share actionable strategies, market insights, and practical tips to help you navigate the crypto landscape with confidence. Let's explore the future of finance together.
Related Posts