How to Install Firewalld on Arch Linux

Install Firewalld on Arch Linux with pacman. Covers zones, services, ports, rich rules, port forwarding, and troubleshooting.

Last updatedAuthorJoshua JamesRead time11 minGuide typeArch Linux

Arch Linux does not enable a firewall service by default, so installing Firewalld on Arch Linux is a practical way to add zone-based filtering without writing raw nftables rules by hand. The zone model works well on laptops, servers, and virtualization hosts because each interface or source network can carry a different trust level.

Firewalld is available from Arch’s Extra repository and uses nftables as the default backend. Runtime changes let you test access rules immediately, while permanent changes keep the rules after reloads and reboots.

Install Firewalld on Arch Linux

The official Arch firewalld package provides the daemon and command-line tools. Use Firewalld when you want zones, runtime testing, rich rules, and integration with tools such as NetworkManager. Use UFW on Arch Linux instead when you prefer a simpler flat rule model for a single-interface host.

Update Arch Linux Before Installing Firewalld

Refresh package databases and apply pending system updates before installing a firewall service:

sudo pacman -Syu

These commands use sudo for tasks that need root privileges. If your user is not in the sudoers file yet, run the commands as root or follow the guide on how to add and manage sudo users on Arch Linux.

Install Firewalld with Pacman

Install Firewalld from the official repository:

sudo pacman -S firewalld

Verify the Firewalld Package and Command

Confirm the package is installed and that firewall-cmd is the command provided by the Arch package:

pacman -Q firewalld
command -v firewall-cmd
pacman -Qo /usr/bin/firewall-cmd

Relevant output includes the installed package, command path, and owning package. The exact package release changes as Arch rolls forward:

firewalld 2.4.1-1
/usr/bin/firewall-cmd
/usr/bin/firewall-cmd is owned by firewalld 2.4.1-1

The package installs firewall-cmd for live management and firewall-offline-cmd for offline configuration. The graphical tool is packaged separately as firewall-config and has its own install step.

The management commands use sudo firewall-cmd for both rule changes and daemon queries. Minimal Arch installs may not run a polkit agent, and unprivileged D-Bus queries can return authorization errors even when the daemon is healthy.

Enable and Start Firewalld on Arch Linux

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

sudo systemctl enable --now firewalld.service

Verify the service is enabled for boot and active now:

systemctl is-enabled firewalld.service
systemctl is-active firewalld.service
sudo firewall-cmd --state

A working service returns:

enabled
active
running

Do not run Firewalld at the same time as UFW or a separate hand-managed iptables.service or nftables.service. Pick one firewall manager so rule ownership stays predictable.

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. The Arch Wiki Firewalld page is the best upstream reference for Arch-specific notes beyond this workflow.

List all available zones:

sudo 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:

sudo 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:

sudo firewall-cmd --list-all

Example output for a host using the default public zone looks similar to this:

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 interface name depends on your system, but the default public zone includes the ssh and dhcpv6-client services. This means inbound SSH is already permitted in the default zone, which helps prevent lockouts when enabling the firewall on remote servers.

To view active zones and their assigned interfaces:

sudo firewall-cmd --get-active-zones

To view settings for a specific zone:

sudo firewall-cmd --info-zone=home

To list all zones with their complete configuration:

sudo 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:

sudo 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:

sudo 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. This example removes the http service added earlier:

sudo firewall-cmd --permanent --remove-service=http
sudo firewall-cmd --reload

Verify the service was removed:

sudo firewall-cmd --list-services

If http no longer appears in the service list, the rule has been removed from the active zone.

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:

sudo firewall-cmd --list-ports

After opening 8080/tcp and 51820/udp, the list should include both entries:

8080/tcp 51820/udp

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. Check your real interface names before copying interface examples:

ip -brief link

Use the interface names from your own output in the following commands.

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:

sudo 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:

sudo 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:

sudo 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:

sudo 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 sudo firewall-cmd --list-forward-ports and copy the complete rule.

Manage Runtime and Permanent Configuration

Firewalld maintains two configuration states: runtime, which is active immediately but temporary, and permanent, which is saved for reloads and reboots. The official firewall-cmd documentation uses this split throughout the command interface, so treat runtime changes as your test area.

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 its default configuration and remove custom zones, services, and rules:

sudo firewall-cmd --reset-to-defaults

Using --reset-to-defaults removes customizations, including any SSH rule you changed manually. If connected remotely, keep a console or provider recovery session available 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 --check-config
sudo firewall-cmd --reload

The config check should return:

success

Verify the service is available:

sudo 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:

sudo 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:

sudo journalctl -k | grep -Ei 'reject|drop'

Monitor denied packets in real-time:

sudo journalctl -kf | grep -Ei 'reject|drop'

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

Install the Firewalld Graphical Interface

Desktop users can install firewall-config, the separate Arch package that provides the graphical Firewalld interface:

sudo pacman -S firewall-config

Launch the graphical configuration tool from a desktop session:

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 service errors:

sudo journalctl -xeu firewalld.service

Check whether another firewall service is active before disabling anything:

systemctl is-active iptables.service nftables.service ufw.service

If one of those services returns active, disable that specific firewall manager before starting Firewalld. For example, if nftables.service is active:

sudo systemctl disable --now nftables.service
sudo systemctl restart firewalld.service

If the journal points to a bad Firewalld XML file, check the saved configuration before resetting it:

sudo firewall-cmd --check-config

A clean configuration returns:

success

Rules Not Taking Effect

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

sudo 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:

sudo firewall-cmd --get-active-zones

Then verify the rule exists in that zone:

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

SSH Access Was Blocked

If an SSH rule change blocks remote access, use a local console, hypervisor console, or provider rescue session first. Once you have console access, restore SSH in the active zone and save the working runtime rule:

sudo firewall-cmd --add-service=ssh
sudo firewall-cmd --runtime-to-permanent
sudo firewall-cmd --list-services

The service list should include ssh again:

dhcpv6-client ssh

If OpenSSH itself is missing or stopped, use the separate guide to install OpenSSH on Arch Linux before depending on remote access.

Firewalld and Docker

Docker manages its own packet-filtering rules when it publishes container ports. On a host that also runs Firewalld, a container published with -p 8080:80 can be reachable through Docker’s rules even when the equivalent Firewalld zone does not allow that port.

Use one of these safer patterns when Docker and Firewalld share the same Arch host:

  • Bind published ports to localhost only (-p 127.0.0.1:8080:80) and expose the service through a reverse proxy controlled by Firewalld rules.
  • Keep container-to-container traffic on Docker networks and expose only the host ports that should be public.
  • Review Firewalld’s upstream Docker filtering guidance before changing Docker’s iptables behavior, because disabling Docker-managed rules without replacement policies can break container networking.

If you are still setting up the container runtime, the separate guide to install Docker on Arch Linux covers the package and service side.

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 the IPv6_rpfilter line and set it to loose mode:

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 enough 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

If you installed the graphical interface too, remove both packages together so Pacman can resolve the dependency relationship cleanly:

sudo pacman -Rns firewalld firewall-config

Verify removal with Pacman’s installed-package database:

pacman -Q firewalld || echo "firewalld is not installed"

A removed package returns:

error: package 'firewalld' was not found
firewalld is not installed

Pacman removes package-owned files, but custom zones, services, and policies that you created under /etc/firewalld/ can remain. Remove them only if you no longer need that saved firewall policy:

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 may have no active firewall manager. Configure an alternative solution such as UFW on Arch Linux or a direct nftables ruleset before exposing the system to untrusted networks.

Conclusion

Firewalld is running on Arch Linux with zone-based rules you can test at runtime, save permanently, and inspect with sudo firewall-cmd --list-all. For exposed servers, pair the firewall with Fail2ban on Arch Linux, or use Nmap on Arch Linux from another host to verify which ports are reachable.

Share this guide

Help another Linux user troubleshoot faster

Share this guide with someone troubleshooting Linux systems or saving it for later.

Follow LinuxCapable

Want more LinuxCapable guides in Google?

Add LinuxCapable as a preferred source so Google can show our tutorials more often in Top Stories and mark them as preferred in AI Mode and AI Overviews when relevant.

Add LinuxCapable as a preferred source on Google
Search LinuxCapable

Need another guide?

Search LinuxCapable for package installs, commands, troubleshooting, and follow-up guides related to what you just read.

Found this guide useful?

Support LinuxCapable to keep tutorials free and up to date.

Buy me a coffeeBuy me a coffee
Before commenting, please review our Comments Policy.
Formatting tips for your comment

You can use basic HTML to format your comment. Useful tags currently allowed in published comments:

You type Result
<code>command</code> command
<strong>bold</strong> bold
<em>italic</em> italic
<a href="https://example.com">link</a> link
<blockquote>quote</blockquote> quote block

Add to the discussion

Questions, fixes, command output, and version notes help keep this guide current.

Verify before posting: