How to Install Firewalld on Debian

Firewalld provides dynamic firewall management with support for IPv4, IPv6, and Ethernet bridges. Unlike static firewall systems that require service restarts after rule changes, Firewalld allows you to modify rules on the fly without disrupting active connections. This makes it particularly useful for managing web servers, protecting SSH access, configuring NAT gateways, and controlling network traffic on multi-interface systems. By the end of this guide, you will have Firewalld installed and running on Debian, with the knowledge to configure zones, manage services, and troubleshoot common issues.

This installation uses Debian’s default repositories and works identically across Debian 13 (Trixie), Debian 12 (Bookworm), and Debian 11 (Bullseye). Package versions vary by release (2.x on Debian 13, 1.x on Debian 12, 0.9.x on Debian 11), but all commands and zone configurations function the same way.

Install Firewalld on Debian

Update the Package Index

Before installing any new software, first refresh your package database to ensure you get the latest available version:

sudo apt update

As a result, APT retrieves the current package information from all configured repositories, ensuring the installation pulls the most recent firewalld version.

Install the Firewalld Package

With the package index updated, you can now install Firewalld using the APT package manager:

sudo apt install firewalld -y

The -y flag automatically confirms the installation prompt, which is useful for scripted deployments but means you won’t see the package list before installation proceeds.

Verify the Installation

After installation completes, verify that Firewalld installed correctly by checking its version:

firewall-cmd --version

Expected output:

2.3.1

Once you see a version number, Firewalld is installed and accessible from your terminal. Your output may show a different version depending on your Debian release.

Enable and Start Firewalld

If you are connected via SSH, ensure SSH access is permitted before enabling the firewall. By default, Firewalld’s public zone allows SSH, but if you change zones or modify rules, you risk losing remote access. Consider adding sudo firewall-cmd --add-service=ssh --permanent before enabling if you are unsure.

Next, start Firewalld and configure it to launch automatically at boot:

sudo systemctl enable --now firewalld

The --now flag combines enable and start into a single command. Verify the service is running:

sudo systemctl status firewalld

Expected output:

● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/lib/systemd/system/firewalld.service; enabled; preset: enabled)
     Active: active (running) since Sat 2025-12-14 12:00:00 UTC; 5s ago
       Docs: man:firewalld(1)
   Main PID: 1234 (firewalld)
      Tasks: 2 (limit: 4647)
     Memory: 28.5M
        CPU: 432ms
     CGroup: /system.slice/firewalld.service
             └─1234 /usr/bin/python3 /usr/sbin/firewalld --nofork --nopid

The active (running) status confirms that Firewalld is operational and protecting your system.

Understanding Firewalld Zones

Firewalld organizes network traffic rules into zones, which represent different levels of trust for network connections. In particular, each zone contains a predefined set of rules that control which services and ports are accessible. When a network interface connects, Firewalld applies the rules from the zone assigned to that interface.

Common Predefined Zones

Firewalld includes several predefined zones, each designed for specific network environments:

ZoneTrust LevelUse Case
dropNoneDrops all incoming packets silently; outgoing connections allowed
blockNoneRejects incoming packets with ICMP response; outgoing allowed
publicLowPublic networks like cafes or airports (default zone)
externalLowSystems acting as NAT gateways or routers
dmzLowServers in a demilitarized zone with limited access
workMediumOffice environments with partially trusted devices
homeHighHome networks where most devices are trusted
internalHighInternal network segments behind a gateway
trustedFullAccepts all incoming connections (use with caution)

In most cases, the public zone provides appropriate defaults for Debian servers exposed to the internet, blocking all incoming connections except those explicitly permitted.

View Active Zones and Interfaces

To see which zones are currently active and which network interfaces belong to each zone, run:

sudo firewall-cmd --get-active-zones

Expected output:

public
  interfaces: eth0 enp0s3

In this example, the public zone is active with the eth0 and enp0s3 interfaces assigned to it. Your interface names will vary depending on your system configuration.

Check the Default Zone

The default zone applies to any interface not explicitly assigned to another zone. To view the current default:

sudo firewall-cmd --get-default-zone

Expected output:

public

Manage Firewalld Services and Ports

Firewalld uses predefined services (like ssh, http, https) to simplify rule management. As a result, you can allow or deny traffic by service name instead of remembering port numbers. This section covers the essential commands for managing network access.

List Services in a Zone

To see which services are currently permitted in a specific zone:

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

Expected output:

dhcpv6-client ssh

By default, the public zone allows both DHCP client traffic and SSH connections.

Add a Service to a Zone

To allow a service through the firewall, use the --add-service option. For example, to permit HTTP traffic:

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

The --permanent flag saves the rule to the persistent configuration, ensuring it survives reboots. However, permanent changes don’t take effect immediately. To apply them, reload the configuration:

sudo firewall-cmd --reload

Alternatively, add the rule without --permanent to apply it immediately (but lose it on reboot), then add the permanent version separately:

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

Remove a Service from a Zone

To remove a previously added service:

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

Add a Specific Port

For applications that don’t have predefined service definitions, you can open specific ports directly. For example, to allow TCP connections on port 8080:

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

Then verify the port was added:

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

Expected output:

8080/tcp

Change the Default Zone

To change the default zone for new interfaces:

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

Replace home with your desired zone name. Unlike service changes, this takes effect immediately and persists across reboots.

Advanced Firewalld Configuration

Beyond basic service management, Firewalld supports advanced features like custom services, zone creation, IP masquerading, and port forwarding. These capabilities are essential for configuring NAT gateways, load balancers, and complex network topologies.

Create a Custom Service

If you run an application on a non-standard port that isn’t covered by predefined services, you can define your own. First, create the service:

sudo firewall-cmd --permanent --new-service=myapp

Next, configure the service with a description and port:

sudo firewall-cmd --permanent --service=myapp --set-short="My Custom Application"
sudo firewall-cmd --permanent --service=myapp --add-port=9000/tcp

Once the service is defined, reload Firewalld and add it to a zone:

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

Create a Custom Zone

Similarly, for complex network environments you may need zones beyond the predefined options:

sudo firewall-cmd --permanent --new-zone=customzone
sudo firewall-cmd --reload

Then assign interfaces and services to your custom zone as needed.

Enable IP Masquerading

Masquerading (NAT) allows systems behind a gateway to access external networks using the gateway’s IP address. This is essential for routing traffic from private networks:

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

Afterward, verify masquerading is enabled:

sudo firewall-cmd --zone=public --query-masquerade

Expected output:

yes

Configure Port Forwarding

Port forwarding redirects incoming traffic from one port to another. For example, to forward external port 8080 to internal port 80:

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

As shown above, this configuration accepts connections on port 8080 and forwards them to port 80 on the same host. To forward to a different host, add :toaddr=192.168.1.100 to the command.

Create Rich Rules for Granular Control

Rich rules provide fine-grained control over traffic that predefined services and ports cannot express. They allow you to specify source addresses, destination ports, protocols, and actions in a single rule. This is particularly useful for restricting access to specific IP addresses or networks.

For instance, to allow SSH access only from a specific IP address:

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

Alternatively, to block all traffic from a specific subnet:

sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" reject' --permanent
sudo firewall-cmd --reload

Additionally, you can view all active rich rules for a zone:

sudo firewall-cmd --zone=public --list-rich-rules

To remove a rich rule, use the same syntax with --remove-rich-rule instead of --add-rich-rule. Rich rules are evaluated in order, so more specific rules should be added before general ones when order matters.

Troubleshoot Firewalld Issues

When firewall rules don’t behave as expected, systematic troubleshooting helps identify the root cause. Firewalld provides several diagnostic tools to help you investigate and resolve issues.

Check Service Status

If Firewalld commands fail or rules aren’t applying, first verify the service is running:

sudo systemctl status firewalld

Look for Active: active (running) in the output. If the service shows failed or inactive, check the logs for errors.

Review Firewalld Logs

Firewalld logs events to the system journal. To view recent log entries:

sudo journalctl -u firewalld --no-pager -n 50

The -n 50 flag limits output to the last 50 lines. Look for error messages, configuration warnings, or failed rule applications.

Reload the Configuration

If Firewalld becomes unresponsive or rules aren’t taking effect, reload the configuration:

sudo firewall-cmd --reload

Expected output:

success

As a result, this command re-reads the permanent configuration and applies it without restarting the service. However, runtime-only changes (those made without --permanent) will be lost.

Restart the Firewalld Service

For more persistent issues, restart the entire service:

sudo systemctl restart firewalld

Because a restart fully reinitializes Firewalld from its permanent configuration, this approach can resolve issues caused by corrupted runtime state.

Rules Not Persisting After Reboot

If your firewall rules disappear after a reboot, the rules were likely added without the --permanent flag. To make rules persistent, always include --permanent:

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

Furthermore, you can check the permanent configuration separately from the runtime configuration:

sudo firewall-cmd --zone=public --list-services --permanent

Interface Not in Expected Zone

If traffic isn’t being filtered as expected, verify the interface is assigned to the correct zone:

sudo firewall-cmd --get-active-zones

To move an interface to a different zone:

sudo firewall-cmd --zone=work --change-interface=eth0 --permanent
sudo firewall-cmd --reload

Verify Configuration Files

Firewalld stores its configuration in /etc/firewalld/. If you suspect configuration corruption, you can examine the files directly:

ls -la /etc/firewalld/zones/

In particular, zone-specific configurations are stored as XML files. The main configuration file is:

cat /etc/firewalld/firewalld.conf

View All Active Rules at Once

When troubleshooting, it helps to see everything Firewalld is currently applying. The --list-all flag displays all services, ports, rich rules, and settings for the default zone:

sudo firewall-cmd --list-all

Expected output:

public (active)
  target: default
  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:

Consequently, this output provides a complete snapshot of the active zone configuration. To view rules for a specific zone, add --zone=zonename to the command. For a comprehensive view of all zones with their configurations, use sudo firewall-cmd --list-all-zones.

Remove Firewalld from Debian

If you need to remove Firewalld, whether to switch to a different firewall solution like UFW or nftables, follow these steps. First, stop and disable the service:

sudo systemctl stop firewalld
sudo systemctl disable firewalld

Next, remove the firewalld package and its configuration:

sudo apt remove --purge firewalld -y

Then remove any orphaned dependencies that were installed with Firewalld. This step cleans up supporting packages like nftables, python3-firewall, iptables, and polkitd that are no longer needed:

sudo apt autoremove -y

Finally, refresh the package cache and verify the removal was successful:

sudo apt update
apt-cache policy firewalld

Expected output:

firewalld:
  Installed: (none)
  Candidate: 2.3.1-1
  Version table:
     2.3.1-1 500
        500 http://deb.debian.org/debian trixie/main amd64 Packages

Running apt update before the verification ensures you see accurate removal status rather than stale cached information. Your version numbers will vary depending on your Debian release.

The Installed: (none) line confirms that Firewalld has been removed from your system.

After removing Firewalld, your system will have no active firewall. If you need continued protection, consider installing UFW on Debian as a simpler alternative, or configure nftables directly for finer control. Install your replacement firewall before removing Firewalld to avoid leaving the system unprotected.

Conclusion

You now have Firewalld installed and configured on Debian, with the ability to manage zones, control service access, and troubleshoot common issues. The zone-based approach simplifies network security by applying consistent rules across different network environments, while the --permanent flag ensures your configuration survives reboots. For advanced configurations beyond what this guide covers, the official Firewalld documentation provides comprehensive reference material. To complement your firewall configuration, our guide on enabling SSH on Debian covers secure remote access setup that works well with Firewalld’s default public zone rules.

Leave a Comment