How to Install Firewalld on Arch Linux

This guide explains how to install Firewalld on Arch Linux and configure zone-based firewall rules for securing your system. Firewalld provides dynamic firewall management through zones that define trust levels for network connections and interfaces. A laptop connecting to home WiFi, a coffee shop network, and a corporate VPN can automatically apply different security rules to each connection without manual reconfiguration. Developed by Red Hat and used as the default firewall on Fedora and RHEL-based distributions, Firewalld offers a more intuitive approach than raw nftables rules while supporting runtime changes without restarting services.

This guide covers understanding zone-based security concepts, configuring default zones and services, creating custom port rules, implementing rich rules for advanced filtering, managing permanent versus runtime configurations, and completely removing Firewalld when switching to alternative solutions. By the end, you will have a fully configured zone-based firewall protecting your Arch Linux system.

Firewalld uses nftables as its backend on Arch Linux and operates within its own namespace, allowing other applications like Docker or libvirt to maintain separate firewall rules. For configuration details beyond this guide, see the Arch Wiki Firewalld page.

Install Firewalld via Pacman

Arch Linux ships without a firewall by default, leaving incoming connections unfiltered. Firewalld is available in the official extra repository. Before installation, update your system to ensure package compatibility:

sudo pacman -Syu

Install Firewalld:

sudo pacman -S firewalld

Verify the installation by checking the Firewalld version:

firewall-cmd --version

Expected output:

2.4.0

Firewalld is now installed. The package includes firewall-cmd for command-line management, firewall-offline-cmd for configuration when the daemon is not running, and firewall-config for graphical management (requires the gtk3 optional dependency).

Enable and Start Firewalld

Enable the Firewalld service to start automatically at boot and start it immediately:

sudo systemctl enable --now firewalld.service

Verify the service is running:

systemctl status firewalld.service

Expected output showing Firewalld is active:

● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; preset: disabled)
     Active: active (running) since Fri 2026-01-31 12:00:00 UTC; 5s ago
       Docs: man:firewalld(1)
   Main PID: 1234 (firewalld)
      Tasks: 2 (limit: 4915)
     Memory: 32.1M
        CPU: 412ms
     CGroup: /system.slice/firewalld.service
             └─1234 /usr/bin/python /usr/bin/firewalld --nofork --nopid

Confirm the firewall is active:

firewall-cmd --state

Expected output:

running

Do not run Firewalld simultaneously with other firewall managers like UFW or direct iptables/nftables services. Multiple firewall managers create conflicting rules and unpredictable behavior.

Understand Firewalld Zones

Firewalld organizes network traffic management through zones, which are named sets of rules that define the trust level for network connections. When a connection is established, Firewalld assigns it to a zone based on the source address or network interface, then applies that zone’s rules.

List all available zones:

firewall-cmd --get-zones

Expected output:

block dmz drop external home internal public trusted work

Each zone serves a specific security purpose:

ZoneDefault BehaviorUse Case
publicRejects incoming except allowed servicesUntrusted networks (default zone)
homeTrusts other computers on the networkHome networks with trusted devices
workTrusts coworkers and network devicesCorporate networks
internalSimilar to home, for internal networksInternal segments behind NAT
dmzLimited access for DMZ serversPublicly accessible servers
externalMasquerading enabled for routersExternal-facing router interfaces
trustedAccepts all network connectionsFully trusted networks only
dropDrops all incoming without replyMaximum stealth, no protocol responses
blockRejects all incoming with ICMP messageBlocking with host unreachable notification

The difference between drop and block affects how blocked clients perceive your server. With drop, connection attempts time out silently, making it harder for attackers to confirm the host exists. With block, clients immediately receive an ICMP host unreachable message, providing faster feedback for legitimate users who may have misconfigured their connection.

Check the default zone:

firewall-cmd --get-default-zone

Expected output:

public

The public zone is the default and appropriate for most server deployments. New interfaces without explicit zone assignments automatically use the default zone.

View Current Firewall Configuration

Before making changes, review the current firewall state. View all settings for the default zone:

firewall-cmd --list-all

Expected output showing the default public zone configuration:

public (active)
  target: default
  ingress-priority: 0
  egress-priority: 0
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  forward: yes
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

The output shows that the public zone is active with ssh and dhcpv6-client services enabled by default. This means SSH connections are already permitted, preventing lockouts when enabling the firewall on remote servers.

To view active zones and their assigned interfaces:

firewall-cmd --get-active-zones

To view settings for a specific zone:

firewall-cmd --info-zone=home

To list all zones with their complete configuration:

firewall-cmd --list-all-zones

Configure Services

Services in Firewalld are predefined port and protocol combinations that correspond to common applications. Using services instead of raw port numbers makes rules more readable and maintainable.

List Available Services

View all predefined services:

firewall-cmd --get-services

This displays hundreds of predefined services including http, https, ssh, mysql, postgresql, dns, and many others.

View details about a specific service:

firewall-cmd --info-service=http

Expected output:

http
  ports: 80/tcp
  protocols: 
  source-ports: 
  modules: 
  destination: 
  includes: 
  helpers:

Add Services to a Zone

Add a service to the default zone (runtime only):

sudo firewall-cmd --add-service=http

Expected output:

success

This change is temporary and will not persist after a firewall reload or system reboot. To make the change permanent, add the --permanent flag:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

When using --permanent, changes apply to the saved configuration but not the running firewall. Reload to apply permanent changes to the runtime:

sudo firewall-cmd --reload

To add a service to a specific zone:

sudo firewall-cmd --permanent --zone=internal --add-service=samba

Remove Services from a Zone

Remove a service using the --remove-service option:

sudo firewall-cmd --permanent --remove-service=dhcpv6-client
sudo firewall-cmd --reload

Verify the service was removed:

firewall-cmd --list-services

Configure Ports

When no predefined service matches your application, open ports directly.

Open Individual Ports

Open a TCP port permanently:

sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

Open a UDP port:

sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --reload

List currently open ports:

firewall-cmd --list-ports

Open Port Ranges

Open a range of ports for applications that require multiple consecutive ports:

sudo firewall-cmd --permanent --add-port=6000-6010/tcp
sudo firewall-cmd --reload

Close Ports

Remove an open port:

sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload

Manage Zone Assignments

Different network interfaces can be assigned to different zones, applying separate security policies to each.

Change the Default Zone

Change the default zone for new connections:

sudo firewall-cmd --set-default-zone=home

Expected output:

success

Changing the default zone is always permanent. No --permanent flag or reload is required.

Assign an Interface to a Zone

Move an interface to a different zone:

sudo firewall-cmd --permanent --zone=internal --change-interface=eth1
sudo firewall-cmd --reload

Check which zone an interface belongs to:

firewall-cmd --get-zone-of-interface=eth1

Assign Zones with NetworkManager

If your system uses NetworkManager, assign zones to connection profiles for automatic zone switching when connecting to different networks. List connection profiles:

nmcli connection show

Assign a connection to a zone:

nmcli connection modify "Home WiFi" connection.zone home

Replace Home WiFi with your actual connection profile name. When you connect to this network, Firewalld automatically applies the home zone’s rules.

Create Rich Rules

Rich rules provide fine-grained control over traffic filtering when basic service and port rules are insufficient. They support filtering by source address, destination port, protocol, logging, and rate limiting within a single rule. Use rich rules to restrict services to specific IP ranges, implement connection logging for security monitoring, or create temporary access rules.

Allow Access from Specific IP Addresses

Allow a specific IP to access a service:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept'
sudo firewall-cmd --reload

Allow a subnet to access a specific port:

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

Block Specific IP Addresses

Drop all traffic from a specific IP address:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" drop'
sudo firewall-cmd --reload

To reject (send ICMP unreachable) instead of silently dropping:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" reject'
sudo firewall-cmd --reload

Log and Rate Limit Connections

Create a rule that logs and limits SSH connections from any source:

sudo firewall-cmd --permanent --add-rich-rule='rule service name="ssh" log prefix="SSH_CONN: " level="info" limit value="5/m" accept'
sudo firewall-cmd --reload

This logs SSH connections with a prefix, limited to 5 log entries per minute to prevent log flooding.

View and Remove Rich Rules

List all rich rules in the current zone:

firewall-cmd --list-rich-rules

Remove a rich rule by specifying the complete rule:

sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="203.0.113.50" drop'
sudo firewall-cmd --reload

Configure Port Forwarding

Firewalld supports port forwarding for NAT scenarios where external traffic needs routing to internal servers.

Enable Masquerading

Port forwarding requires masquerading (source NAT) to be enabled on the zone. Masquerading rewrites the source IP address of forwarded packets to the firewall’s external IP, making it appear as though traffic originates from the firewall rather than the internal server. This allows internal hosts without public IPs to communicate with external networks.

sudo firewall-cmd --permanent --zone=public --add-masquerade
sudo firewall-cmd --reload

Verify masquerading is enabled:

firewall-cmd --query-masquerade

Forward Ports to Internal Hosts

Forward external port 8080 to an internal server’s port 80:

sudo firewall-cmd --permanent --zone=public --add-forward-port=port=8080:proto=tcp:toport=80:toaddr=192.168.1.10
sudo firewall-cmd --reload

Forward to a different port on the same host:

sudo firewall-cmd --permanent --add-forward-port=port=2222:proto=tcp:toport=22
sudo firewall-cmd --reload

List port forwarding rules:

firewall-cmd --list-forward-ports

Remove Port Forwarding

Removing a port forwarding rule requires specifying the complete original rule. Unlike services or ports, you cannot remove a forward by specifying only the port and protocol:

sudo firewall-cmd --permanent --remove-forward-port=port=8080:proto=tcp:toport=80:toaddr=192.168.1.10
sudo firewall-cmd --reload

If you forget the exact forwarding specification, list current forwards first with firewall-cmd --list-forward-ports and copy the complete rule.

Manage Runtime and Permanent Configuration

Firewalld maintains two configuration states: runtime (active but temporary) and permanent (saved but inactive until reload). Understanding this separation helps you test changes safely before committing them.

Test Changes Before Making Permanent

Add a rule without --permanent to test it:

sudo firewall-cmd --add-service=http

This change is active immediately but will not survive a reload or reboot. If the rule works correctly, make it permanent:

sudo firewall-cmd --runtime-to-permanent

This saves the entire current runtime configuration as permanent.

Use Temporary Rules with Timeouts

Add a rule that automatically expires after a specified duration:

sudo firewall-cmd --add-service=vnc-server --timeout=1h

This opens VNC access for one hour, then automatically removes the rule. Timeout values support seconds (default), minutes (m), or hours (h):

sudo firewall-cmd --add-port=5900/tcp --timeout=30m

Timeouts only work with runtime rules. You cannot combine --timeout with --permanent.

Reload and Reset

Reload the firewall to apply permanent changes:

sudo firewall-cmd --reload

To completely reload the firewall and lose all runtime state information:

sudo firewall-cmd --complete-reload

To reset Firewalld to default configuration, removing all custom zones, services, and rules:

sudo firewall-cmd --reset-to-defaults

Using --reset-to-defaults removes all customizations including SSH rules. If connected remotely, ensure you have console access before running this command.

Create Custom Services

Custom services simplify firewall management for applications that use multiple ports or non-standard configurations. Instead of opening individual ports and remembering which ports belong to which application, you create a named service definition that groups all required ports together. This makes rules more readable and easier to manage across multiple zones.

Service definitions are stored in /usr/lib/firewalld/services/ (system defaults, do not edit) and /etc/firewalld/services/ (custom services). Create a custom service file:

sudo nano /etc/firewalld/services/myapp.xml

Add the service definition:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>MyApp</short>
  <description>My custom application service</description>
  <port protocol="tcp" port="9000"/>
  <port protocol="tcp" port="9001"/>
</service>

Reload Firewalld to recognize the new service:

sudo firewall-cmd --reload

Verify the service is available:

firewall-cmd --info-service=myapp

Use the custom service like any predefined service:

sudo firewall-cmd --permanent --add-service=myapp
sudo firewall-cmd --reload

Configure Log Denied Packets

Firewalld can log packets that are dropped or rejected, useful for troubleshooting connection issues and monitoring potential attacks.

Check current log denied setting:

firewall-cmd --get-log-denied

Expected output:

off

Enable logging of denied packets:

sudo firewall-cmd --set-log-denied=all

Available log levels: all (logs all denied packets), unicast (only direct traffic to this host), broadcast (only broadcast traffic), multicast (only multicast traffic), or off. For most troubleshooting, unicast filters out noisy broadcast traffic while capturing relevant denied connections.

View denied packets in the system journal:

journalctl -k | grep -i reject

Monitor denied packets in real-time:

journalctl -kf | grep -i reject

Enable denied packet logging only temporarily for troubleshooting. Heavy traffic to blocked ports can generate excessive log entries and fill disk space.

Use the Graphical Interface

For desktop users, firewall-config provides a graphical interface for managing Firewalld. The utility is included with the Firewalld package but requires GTK3.

Install the optional GTK3 dependency:

sudo pacman -S gtk3

Launch the graphical configuration tool:

firewall-config

The interface allows you to configure zones, services, ports, and rich rules visually. Changes made in firewall-config can be applied to runtime only or saved permanently using the Configuration dropdown at the top of the window.

Troubleshoot Common Issues

Firewalld Service Will Not Start

If Firewalld fails to start, check the journal for errors:

journalctl -xeu firewalld.service

Common causes include conflicting firewall services or corrupted configuration files. Check for and disable conflicting services:

sudo systemctl disable --now iptables.service nftables.service ufw.service 2>/dev/null

If configuration files are corrupted, reset to defaults:

sudo rm -rf /etc/firewalld/*
sudo firewall-cmd --reload

Rules Not Taking Effect

If rules are not working, verify the firewall is running:

firewall-cmd --state

If you added rules with --permanent, ensure you reloaded:

sudo firewall-cmd --reload

Verify the rule is in the correct zone. Check which zone your interface uses:

firewall-cmd --get-active-zones

Then verify the rule exists in that zone:

firewall-cmd --zone=public --list-all

Firewalld and Docker

Docker manages its own iptables/nftables rules independently of Firewalld. With Firewalld’s nftables backend, both systems operate in separate namespaces and can coexist. However, Docker container ports published with -p flags bypass Firewalld zone rules because Docker inserts its NAT rules at a higher netfilter priority.

This means a container with -p 8080:80 is accessible from external networks regardless of your Firewalld configuration. To control Docker container access, either:

  • Bind published ports to localhost only (-p 127.0.0.1:8080:80) and use a reverse proxy with Firewalld rules
  • Use Docker networks and manage inter-container communication through Docker’s own networking
  • Configure Docker to integrate with Firewalld by adding { "iptables": false } to /etc/docker/daemon.json and manually managing container network rules

IPv6 Connectivity Issues

Firewalld implements an IPv6 reverse path filter that verifies incoming packets have a valid return route. On systems with multiple interfaces connected to the same network (such as laptops with both wired and wireless active), this strict filtering can cause intermittent IPv6 connectivity. Symptoms include random connection timeouts, one interface working while another fails, or IPv6 connections succeeding inconsistently.

If you experience these issues, change the reverse path filter to loose mode, which only checks that a return path exists without validating the specific interface:

sudo nano /etc/firewalld/firewalld.conf

Find and change:

IPv6_rpfilter=loose

Restart Firewalld to apply the change:

sudo systemctl restart firewalld.service

Remove Firewalld from Arch Linux

Remove Firewalld only when switching to a different firewall solution. Disabling the service with sudo systemctl disable --now firewalld.service is sufficient for temporary deactivation.

Stop and disable the service:

sudo systemctl disable --now firewalld.service

Remove the Firewalld package and orphaned dependencies:

sudo pacman -Rns firewalld

Verify removal:

firewall-cmd --version

Expected output:

-bash: firewall-cmd: command not found

Custom configuration files in /etc/firewalld/ may remain as .pacsave backups. Remove them if no longer needed:

The following command permanently deletes all Firewalld configuration files. Only run this if you are certain you no longer need any custom zones, services, or rules.

sudo rm -rf /etc/firewalld/

After removing Firewalld, your system has no active firewall. Configure an alternative solution like UFW or direct nftables rules before exposing the system to untrusted networks.

Frequently Asked Questions

What is the difference between Firewalld and UFW?

Firewalld uses zones to group rules by trust level, making it ideal for systems with multiple network interfaces that need different security policies. UFW uses a simpler flat rule model better suited for single-interface servers. Firewalld also supports runtime changes without reload and has built-in service definitions for hundreds of applications.

Why do my permanent rules not take effect immediately?

When you add rules with --permanent, Firewalld saves them to configuration files but does not apply them to the running firewall. Run firewall-cmd --reload after making permanent changes to apply them. Alternatively, add rules without --permanent to test, then use firewall-cmd --runtime-to-permanent to save working rules.

Does Firewalld on Arch Linux use iptables or nftables?

Firewalld uses nftables as its backend on Arch Linux. It creates rules in a dedicated firewalld table within nftables, allowing other applications like Docker or libvirt to maintain their own firewall rules in separate namespaces without conflicts.

How do I allow SSH after accidentally blocking it?

If you still have console access, run sudo firewall-cmd --add-service=ssh and sudo firewall-cmd --runtime-to-permanent to restore SSH access. The default public zone includes SSH by default, so resetting to defaults with sudo firewall-cmd --reset-to-defaults also restores SSH access.

Can I run Firewalld and UFW at the same time?

No. Running multiple firewall managers creates conflicting rules and unpredictable behavior. Disable and stop one firewall service completely before enabling another. Use either Firewalld or UFW, not both.

Conclusion

Firewalld now protects your Arch Linux system with zone-based security policies, service rules, and logging for security monitoring. The zone model allows different security policies for different network interfaces, while the separation of runtime and permanent configuration enables safe testing before committing changes. As a next step, verify your configuration by running firewall-cmd --list-all after each change session to confirm the expected rules are active. For servers handling sensitive data or exposed to the internet, pair Firewalld with intrusion detection tools like fail2ban to automatically block IP addresses after repeated failed authentication attempts.

Leave a Comment

Let us know you are human: