When you install Firewalld on Fedora Linux, you gain a powerful dynamic firewall manager that protects your system from network threats while giving you precise control over incoming and outgoing traffic. Unlike static firewalls that require a full restart for every change, Firewalld lets you adjust rules on the fly without interrupting active connections.
This guide shows you how to verify the installation, enable the daemon, manage zones and services, implement advanced policies, and troubleshoot the issues that appear on Fedora desktops and servers.
What Is Firewalld?
Think of Firewalld as a security guard for your network connections. It sits between your Fedora system and the internet, deciding which traffic gets through and which gets blocked. Instead of managing individual iptables rules manually, Firewalld provides a friendlier command-line interface and organizes rules into zones based on trust levels.
Firewalld ships pre-installed on most Fedora installations and offers several key capabilities:
- Dynamic Management: Firewalld allows users to make real-time changes to the firewall settings without restarting the service.
- Zone-based Management: Users can group network interfaces into different zones, each with specific firewall rules, allowing for varied levels of trust.
- Rich Language Rules: This feature offers detailed control over firewall settings, accommodating complex rules and exceptions for different networking needs.
- Service-specific Configurations: Firewalld lets users set specific firewall rules for individual services or applications, adding another layer of customization.
- IPv6 Support: With compatibility for IPv6, Firewalld ensures your system remains secure as the internet transitions to the next generation of IP addresses.
On desktop systems, Firewalld controls incoming and outgoing traffic for safer browsing and reduced malware risk. For servers exposed to the internet, Firewalld’s zone-based management and service-specific configurations become essential for blocking unauthorized access while keeping legitimate services running. Whether you’re securing a development workstation or hardening a production server, Firewalld gives you the flexibility to adapt firewall rules to different network environments without compromising uptime.
Check If Firewalld Is Installed
Before installing Firewalld, verify whether it already exists on your system. Most Fedora installations include Firewalld by default, so checking first avoids unnecessary reinstallation. Run the following command to check the installed version:
Open the terminal with Ctrl+Alt+T or by searching for Terminal from the GNOME Activities overview. Fedora manages software through the DNF package manager, which plays a role similar to Windows Update, and the commands in this guide use sudo to grant temporary administrator privileges.
sudo firewall-cmd --version
When you run this command, the output displays the firewall version if it’s installed. If Firewalld is absent, you’ll see an error message like “command not found,” indicating you need to install it.
Install Firewalld on Fedora
If Firewalld isn’t on your system, install it using the DNF package manager. Execute this command:
sudo dnf install firewalld
DNF downloads the package from Fedora’s repositories along with any required dependencies, then installs everything automatically. The installation typically completes in under a minute on modern systems.
Enable and Start Firewalld
After installation, configure Firewalld to start automatically whenever your system boots and bring it online right away so current sessions stay protected. Use systemctl to enable and start the service in a single command:
systemctl controls background services on Linux the same way the Services console works on Windows, so the command below both enables Firewalld for every boot and starts it immediately.
sudo systemctl enable --now firewalld
The --now flag starts Firewalld immediately while also creating the boot-time symlink. You should see confirmation that the service is enabled and running.
Verify Firewalld Status
Confirm that Firewalld is running correctly by checking its service status. This verification step ensures the installation and enablement succeeded before you start configuring rules:
sudo systemctl status firewalld
The output shows whether Firewalld is active and running. Look for “active (running)” in green text, which confirms the service is operational. If you see “inactive (dead)” or any errors, revisit the installation and enablement steps to troubleshoot.
Firewalld Command Basics
Before diving into specific firewall rules, understanding how Firewalld commands work helps you avoid mistakes and build confidence. The firewall-cmd tool follows a consistent pattern that becomes intuitive once you grasp the basics.
Firewalld requires administrative privileges on Fedora. All examples use
sudo; drop it only if you are already working inside a root shell or have custom polkit rules.
Firewalld Command Syntax
Every Firewalld command follows this structure:
firewall-cmd [options] command
Breaking down each component:
- firewall-cmd: The command-line client that communicates with the Firewalld daemon
- options: Modifiers that control where and how changes apply:
--zone=nametargets a specific firewall zone instead of the default--permanentsaves changes to configuration files so they survive reboots--reloadapplies permanent changes immediately without dropping connections
- command: The action to perform, such as
--add-service,--list-all, or--add-port
Use the quick-reference table below to see how the most important firewall-cmd options map to real-world administration tasks.
Identify the default zone: Shows which zone handles new interfaces so you know where rules land by default.
sudo firewall-cmd --get-default-zone
Target a specific zone: Add the --zone=name option to scope the command to that zone instead of the default.
sudo firewall-cmd --zone=public --list-all
Make a change persistent: Append --permanent and reload so the rule survives reboots.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
Test a change temporarily: Skip --permanent so the rule only affects the runtime configuration.
sudo firewall-cmd --add-service=http
Save all runtime rules: Copy the current runtime configuration into permanent storage in one step.
sudo firewall-cmd --runtime-to-permanent
Temporary vs Permanent Rules
By default, Firewalld changes take effect immediately but disappear after a reboot. To make rules permanent, add the
--permanentflag to your command, then runsudo firewall-cmd --reloadto apply them to the running configuration. This two-step approach lets you test rules safely before committing them.
At its simplest, checking your active firewall zone requires just:
sudo firewall-cmd --get-default-zone
This returns the name of your default zone (typically “public” on fresh installations) without making any changes. Once you understand this foundation, the following commands follow the same logical pattern.
Basic Firewalld Commands
The following commands cover the most common Firewalld tasks you’ll use regularly. Each example shows the exact syntax you need, along with context for when you’d use it in real scenarios.
How Firewalld Zones Work
Firewalld organizes network interfaces into zones, each representing a different trust level. For example, your home network might use the “home” zone with relaxed rules, while a public Wi-Fi connection uses the stricter “public” zone. Network interfaces automatically get assigned to zones based on your configuration, letting you apply different security policies to different connections simultaneously.
Display All Zones
View all available zones and their complete configurations with this command:
sudo firewall-cmd --list-all-zones
The output displays every zone (public, home, work, etc.) along with their allowed services, ports, and interfaces. This comprehensive view helps when diagnosing connectivity issues or planning zone assignments.
Get the Default Zone
Check which zone handles network traffic by default:
sudo firewall-cmd --get-default-zone
This returns a single word like “public” or “home,” indicating which zone applies to new network interfaces automatically.
Set a Default Zone
Change the default zone to match your environment’s trust level. Replace zone_name with your preferred zone:
sudo firewall-cmd --set-default-zone=zone_name
For example, on a home workstation, you might set --set-default-zone=home to enable more permissive rules for local network services.
List Services in a Zone
See which services are allowed through a specific zone’s firewall. Replace zone_name with the zone you want to inspect:
sudo firewall-cmd --zone=zone_name --list-services
The output shows service names like “ssh,” “http,” or “https” that are currently permitted. This is useful when troubleshooting why a service isn’t accessible.
Add a Service to a Zone
Allow a service through the firewall by adding it to a zone. Replace zone_name and service_name with your specific values:
sudo firewall-cmd --zone=zone_name --add-service=service_name
For example, if you’re setting up an Apache web server on Fedora, you’d run sudo firewall-cmd --zone=public --add-service=http --permanent to allow web traffic. Remember to add --permanent and reload for the change to persist.
Remove a Service from a Zone
Block a service by removing it from a zone’s allowed list. Replace zone_name and service_name accordingly:
sudo firewall-cmd --zone=zone_name --remove-service=service_name
This immediately blocks the service in the running configuration. Add --permanent and reload if you want the block to survive reboots.
Reload Firewalld Configuration
Apply permanent configuration changes without dropping existing connections:
sudo firewall-cmd --reload
Unlike restarting the firewall service, reloading preserves active network connections while loading updated rules from disk. This is critical for production servers where you can’t afford dropped SSH sessions.
List All Rules in a Zone
Get a complete overview of everything configured in a zone, including services, ports, rich rules, and more. Replace zone_name with the zone to inspect:
sudo firewall-cmd --zone=zone_name --list-all
This comprehensive output displays the zone’s target policy, interfaces, allowed services, open ports, and any advanced rich rules. It’s your go-to command for auditing zone configurations.
Add a Port to a Zone
Open a specific port for traffic when no predefined service exists for your application. Replace zone_name, port_number, and protocol with your values:
sudo firewall-cmd --zone=zone_name --add-port=port_number/protocol
For instance, to allow custom application traffic on TCP port 8080, you’d run sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent. Always specify either tcp or udp based on your application’s requirements.
Remove a Port from a Zone
Close a previously opened port when you no longer need it. Replace zone_name, port_number, and protocol with your specific details:
sudo firewall-cmd --zone=zone_name --remove-port=port_number/protocol
This closes the port immediately in the running config. Add --permanent and reload to make the closure permanent across reboots.
Firewall Zones Reference Guide
Firewalld organizes network security into nine predefined zones, each representing a different trust level. Understanding which zone fits your network environment helps you apply appropriate security policies without over-restricting legitimate traffic or leaving vulnerabilities open.
Zone Trust Levels Explained
Zones range from “drop” (zero trust, maximum security) to “trusted” (full trust, no restrictions). Here’s how each zone behaves and when to use it:
Drop Zone
The strictest zone available, offering maximum security by making your system invisible to attackers:
- Trust Level: Zero trust, maximum security
- Default Behavior: Silently drops all incoming packets without any reply; only outgoing connections work
- Best Used For: Hostile public Wi-Fi at airports or hotels where you suspect network monitoring and want zero incoming traffic
Block Zone
Similar to drop zone but actively rejects connections with ICMP messages:
- Trust Level: Zero trust, maximum security
- Default Behavior: Sends ICMP rejection messages (host-prohibited for IPv4, admin-prohibited for IPv6) back to the sender instead of silently dropping packets
- Best Used For: Untrusted networks where you want to discourage connection attempts while remaining RFC-compliant with rejection messages
Public Zone (Default)
The default zone for most Fedora installations, balancing security with essential access:
- Trust Level: Low trust, assumes untrusted network
- Default Behavior: Only allows services you explicitly enable; SSH (port 22) and DHCP client traffic permitted by default
- Best Used For: Laptops, workstations, or servers on untrusted networks like coffee shops, coworking spaces, or cloud providers where neighbor instances share the same network segment
External Zone
Designed for routers and gateways that bridge two networks:
- Trust Level: Low trust for external-facing interfaces
- Default Behavior: Masquerading (NAT) enabled by default; assumes your system connects an untrusted external network (internet) to a trusted internal network (LAN)
- Best Used For: Configuring a Fedora system as a home router, VPN gateway, or network appliance that routes traffic between networks while hiding internal addresses
DMZ Zone
Created for demilitarized zone servers that face the public but need isolation from internal systems:
- Trust Level: Low trust with strict service limitations
- Default Behavior: Only selected services reach DMZ hosts, reducing damage if one gets compromised; blocks direct access to internal infrastructure
- Best Used For: Web servers, mail servers, or any public-facing service that shouldn’t directly touch your internal network; for example, assign your Apache server’s interface to the DMZ zone while keeping database servers on the internal zone
Work Zone
Provides moderate trust for office networks where collaboration matters:
- Trust Level: Medium trust, balances security with productivity
- Default Behavior: Generally trusts coworkers’ machines while maintaining basic protection against accidents or compromised workstations; common services like file sharing and printers receive easier access
- Best Used For: Corporate environments where network segmentation exists but colleague collaboration requires more open policies than public networks
Home Zone
Similar trust level to work zone but tailored for residential environments:
- Trust Level: Medium trust, prioritizes convenience
- Default Behavior: Assumes you trust other devices (family members’ phones, smart TVs, IoT devices) with slightly relaxed rules; services like Samba file sharing, mDNS for network discovery, and DHCP client traffic typically allowed
- Best Used For: Home network interfaces where convenience matters more than strict security, though you should still manually configure which services to expose
Internal Zone
Designed for trusted internal networks behind your firewall perimeter:
- Trust Level: High trust for protected internal networks
- Default Behavior: Similar to home zone but intended for business internal networks where you have high confidence in endpoint security
- Best Used For: Internal management interfaces, backup networks, or server-to-server communication channels that never touch the internet directly
Trusted Zone
Accepts all network traffic without restrictions, effectively disabling the firewall:
- Trust Level: Full trust, no restrictions
- Default Behavior: Accepts all traffic without filtering; firewall is effectively disabled for that interface
- Best Used For: VPN tunnels, encrypted WireGuard interfaces, or direct connections between trusted systems where another layer already handles security; never assign internet-facing interfaces to this zone unless you fully understand the security implications
Choosing the Right Zone
When deciding which zone to use, consider three factors: the network’s trust level, the services you need to expose, and the consequences of a breach. A laptop moving between coffee shop Wi-Fi (public zone) and home network (home zone) should switch zones accordingly. Servers typically stay in one zone (public for most cloud servers, DMZ for web servers, internal for databases) based on their role. Therefore, assign interfaces to zones that match the network environment, not the hardware’s physical location.
Advanced Firewalld Configuration
Beyond basic service and port management, Firewalld supports advanced scenarios like custom zones, IP blocking, and rich rules. These capabilities become essential when securing production servers or managing complex network environments.
Create Custom Services for Reusable Rules
When you need to expose the same application across multiple zones or hosts, create a custom service definition instead of juggling raw port numbers. Service XML files live under /etc/firewalld/services/ and persist across package updates.
sudo tee /etc/firewalld/services/nodeapp.xml <<'EOF'
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>nodeapp</short>
<description>Node.js dashboard on TCP port 3000</description>
<port protocol="tcp" port="3000"/>
</service>
EOF
sudo firewall-cmd --permanent --add-service=nodeapp --zone=public
sudo firewall-cmd --reload
Edit the XML to match your application name, description, and port list. Once loaded, you can grant the service to any zone with --add-service=nodeapp just like the built-in definitions.
Creating Custom Zones for Specific Networks
Custom zones let you apply different security policies to different network segments. For example, build a “dmz” zone for public-facing servers or a “trusted” zone for management interfaces. After creating a zone, assign services and move the relevant network interface into it:
sudo firewall-cmd --permanent --new-zone=your_zone
sudo firewall-cmd --permanent --zone=your_zone --add-service=http
sudo firewall-cmd --permanent --zone=your_zone --add-interface=eth1
sudo firewall-cmd --reload
Repeat the --add-service and --add-interface steps for every protocol and interface you want governed by this new trust level.
Deleting Unused Zones
Remove custom zones you no longer need to keep your configuration clean. Replace your_zone with the zone name:
sudo firewall-cmd --permanent --delete-zone=your_zone
sudo firewall-cmd --reload
You cannot delete built-in zones like “public” or “home,” only custom zones you’ve created. Make sure no interfaces are assigned to the zone before deleting it.
Log and Block Suspicious IP Addresses
When you identify suspicious traffic from a specific IP address, create a rich rule that both logs and blocks the packets. This pairs nicely with Fail2ban on Fedora for automated intrusion prevention. Replace your_zone and ip_address with your values:
sudo firewall-cmd --permanent --zone=your_zone --add-rich-rule='rule family="ipv4" source address="ip_address" log prefix="firewalld-block" level="info" drop'
sudo firewall-cmd --reload
The log prefix appears inside journalctl -u firewalld, making it easy to verify the block while confirming that packets never reach user-space daemons.
Ban Host Ranges with Ipsets
Rich rules can also reference ipsets, which excel at blocking large address lists without slowing packet processing. Use them when you need to ban VPN ranges or disposable botnet networks.
sudo firewall-cmd --permanent --new-ipset=blocked_vpn --type=hash:net
sudo firewall-cmd --permanent --ipset=blocked_vpn --add-entry=203.0.113.0/24
sudo firewall-cmd --permanent --zone=your_zone --add-rich-rule='rule source ipset=blocked_vpn drop'
sudo firewall-cmd --reload
Add or remove --ipset entries as threats evolve, then reload to apply them instantly across every zone that references the ipset.
Troubleshooting Firewalld Issues
Even with proper configuration, firewall issues can block legitimate traffic or fail to apply rules correctly. The following troubleshooting steps address the most common problems administrators encounter when managing Firewalld on Fedora systems.
Service Won’t Start After Rule Changes
When Firewalld fails to start after adding custom rules, the most common cause is syntax errors in rich rules or direct interface commands. First, check the service status for error details:
sudo systemctl status firewalld
Look for lines indicating which rule failed to parse. If you recently added a rich rule, validate its syntax by testing it without the --permanent flag first. To recover from a broken permanent configuration, temporarily rename the zone file causing issues:
sudo mv /etc/firewalld/zones/public.xml /etc/firewalld/zones/public.xml.backup
sudo firewall-cmd --reload
This forces Firewalld to reload the default zone configuration from /usr/lib/firewalld/zones/, letting you start fresh and reapply rules one at a time.
Port Shows Open But Service Unreachable
When sudo firewall-cmd --list-ports shows a port as open but connections still fail, the issue often lies outside Firewalld. First, verify the application is actually listening on that port:
sudo ss -tlnp | grep :8080
If nothing appears, your application isn’t bound to the port. Next, check if you opened the port in the correct zone. Many users add ports to the default zone while their interface belongs to a different zone:
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=actual_zone --list-ports
Additionally, confirm you made the rule permanent and reloaded. Runtime-only rules disappear after a firewall reload or system reboot. Always add --permanent and run sudo firewall-cmd --reload afterward.
Rules Disappeared After Reboot
If your firewall rules vanish after rebooting, you forgot the --permanent flag when adding them. Firewalld maintains two separate configurations: runtime (immediate but temporary) and permanent (survives reboots). To check what’s actually saved:
sudo firewall-cmd --permanent --list-all --zone=public
Compare this output to the runtime configuration (sudo firewall-cmd --list-all --zone=public). Missing rules in the permanent output explain why they disappeared. To save current runtime rules permanently:
sudo firewall-cmd --runtime-to-permanent
This command copies all active runtime rules into permanent storage in one step, avoiding the need to re-add each rule with --permanent.
Firewalld Conflicts with Docker or Libvirt
Docker and libvirt both manipulate iptables directly, occasionally conflicting with Firewalld’s zone-based management. If containers or virtual machines lose network connectivity after enabling Firewalld, the services are fighting over netfilter rules. For Docker, ensure you’re running a recent version (20.10+) that properly integrates with Firewalld. Restart Docker after Firewalld starts:
sudo systemctl restart firewalld
sudo systemctl restart docker
For libvirt, add the libvirt zone to Firewalld and assign virtual bridge interfaces to it. This prevents Firewalld from blocking virtualization traffic while maintaining security boundaries.
sudo firewall-cmd --permanent --zone=libvirt --change-interface=virbr0
sudo firewall-cmd --permanent --zone=libvirt --add-masquerade
sudo firewall-cmd --reload
Zone Assignment Doesn’t Stick
When interfaces keep reverting to the wrong zone after reconnecting, NetworkManager is overriding Firewalld’s assignment. NetworkManager stores zone information in connection profiles, taking precedence over Firewalld’s configuration. To permanently assign a zone to a connection:
sudo nmcli connection modify "Wired connection 1" connection.zone home
sudo nmcli connection up "Wired connection 1"
Replace “Wired connection 1” with your actual connection name (find it with nmcli connection show). This embeds the zone into the NetworkManager profile, ensuring it persists across reconnections.
Rich Rules Not Working as Expected
Rich rules process in the order they appear in the zone file, but Firewalld applies zone-level deny rules before allow rules. If your rich rule seems ignored, check rule ordering with:
sudo firewall-cmd --list-rich-rules --zone=public
Additionally, verify your rich rule syntax carefully. A missing quote or incorrect family (ipv4 vs ipv6) causes silent failures. Test rich rules in runtime mode first before making them permanent, allowing quick rollback if they don’t behave as expected.
Panic Mode Accidentally Enabled
Panic mode immediately drops all network traffic, cutting off remote SSH connections. If you suspect panic mode is active (usually after fat-fingering a command), check from the console:
sudo firewall-cmd --query-panic
Disable it immediately to restore connectivity:
sudo firewall-cmd --panic-off
Panic mode is strictly a runtime feature and doesn’t persist across reboots, so restarting the system also clears it. However, you’ll lose remote access until the system comes back up.
Quick Reference: Common Firewalld Tasks
This quick-reference section highlights the most frequently used Firewalld commands. Bookmark it for fast lookups when managing firewall rules on Fedora systems.
Check firewall status: Returns whether the daemon is running.
sudo firewall-cmd --state
List all zones: Displays every built-in and custom zone name.
sudo firewall-cmd --get-zones
Get the default zone: Confirms which zone new interfaces join.
sudo firewall-cmd --get-default-zone
List active zones: Shows which zones currently have interfaces assigned.
sudo firewall-cmd --get-active-zones
View zone details: Lists services, ports, targets, and rich rules for a zone.
sudo firewall-cmd --list-all --zone=public
Add a service temporarily: Grants access until the next reload or reboot.
sudo firewall-cmd --add-service=http
Add a service permanently: Keeps the service open across reboots.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload
Remove a service: Close the service using the same flags you used to open it.
sudo firewall-cmd --remove-service=http --permanent
sudo firewall-cmd --reload
Open a port temporarily: Helpful for quick tests or short maintenance windows.
sudo firewall-cmd --add-port=8080/tcp
Open a port permanently: Keeps the port available after reboots.
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
Close a port: Removes a previously opened port from the zone.
sudo firewall-cmd --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload
Save runtime rules: Copies every active runtime rule into the permanent configuration.
sudo firewall-cmd --runtime-to-permanent
Reload firewall rules: Applies permanent configuration changes without dropping connections.
sudo firewall-cmd --reload
Block an IP address: Use a rich rule to reject traffic, then reload.
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="1.2.3.4" reject'
sudo firewall-cmd --reload
Enable masquerading (NAT): Required when the system routes traffic between networks.
sudo firewall-cmd --add-masquerade --permanent
sudo firewall-cmd --reload
Change the default zone: Immediately affects any new network connection.
sudo firewall-cmd --set-default-zone=home
Assign an interface to a zone: Persistently map a NetworkManager connection profile to a zone.
sudo nmcli connection modify eth0 connection.zone home
sudo nmcli connection up eth0
Emergency block all traffic: Panic mode drops every packet immediately.
sudo firewall-cmd --panic-on
Disable panic mode: Restores normal firewall operation.
sudo firewall-cmd --panic-off
Conclusion
Firewalld provides comprehensive network security for Fedora systems through zone-based management, dynamic rule updates, and rich language configurations. By understanding the fundamentals of firewall-cmd syntax, managing zones and services, and applying permanent vs temporary rules, you can confidently secure both desktop and server environments without sacrificing accessibility or uptime.