How to Use Firewall Zones on Fedora (Trusted, Public, Home, etc.)

Fedora's firewalld organizes network interfaces into zones with different trust levels, letting you control which traffic is allowed with a single tool.

When the network changes, the rules should too

You connect your Fedora laptop to a coffee shop Wi-Fi network. Your browser loads, but your SSH connection to your home server drops. Or you plug into your home network and suddenly your media server can't reach your desktop. The issue isn't your router. It's firewalld. Fedora manages network security through zones, and if the wrong zone is active on the wrong interface, traffic gets blocked or allowed when it shouldn't be.

How zones control traffic

firewalld doesn't just block or allow traffic globally. It assigns a security profile to each network interface based on where you are. Think of zones like security badges. The trusted zone is a badge that opens every door. The drop zone is a badge that locks you in a room. The public zone lets you through the front door but checks your bag. When you switch networks, firewalld should swap the badge automatically. If it doesn't, or if you have multiple interfaces, traffic rules diverge.

Fedora uses firewalld as the default firewall manager. It sits on top of nftables and provides a dynamic interface. You manage the firewall through firewall-cmd. Don't mix firewall-cmd with raw iptables or nft commands. The configurations conflict and the firewall state becomes unpredictable.

Check the zone before you blame the app. The firewall is usually the culprit when a service works locally but fails remotely.

Check the current zone and active interfaces

Start by seeing what firewalld thinks is happening. You need to know the default zone and which interfaces are assigned to which zones. The default zone applies to new connections that don't have an explicit zone assignment.

# Show the zone that applies to new connections by default
sudo firewall-cmd --get-default-zone
# List all active zones and the interfaces bound to them
sudo firewall-cmd --get-active-zones

If an interface is missing or in the wrong zone, assign it explicitly. This is common with virtual machines or when NetworkManager fails to trigger a zone change.

# Bind the ethernet interface to the home zone permanently
sudo firewall-cmd --permanent --zone=home --add-interface=enp3s0
# Apply the permanent configuration to the running firewall
sudo firewall-cmd --reload

NetworkManager drives zone assignment on desktop systems. When you connect to a Wi-Fi network, NetworkManager sends the connection profile to firewalld. You can set the zone in the connection settings. This ensures the zone changes automatically when you roam. If you manage zones manually via firewall-cmd, you risk conflicts when NetworkManager tries to update the zone on reconnect.

Reload after every permanent change. The runtime config and persistent config diverge instantly if you skip this step.

Allow services and ports in a zone

Zones control services, not just ports. Use services when possible because they handle port changes and IPv6 automatically. Services are safer than raw ports. A service definition includes the port, the protocol, and sometimes helper applications. If the upstream package changes the port number, the service rule updates automatically. A raw port rule stays fixed. If you open 8080/tcp manually and the application moves to 8081, your firewall blocks the traffic. Use services whenever a definition exists.

# Add SSH to the public zone in the permanent config
sudo firewall-cmd --permanent --zone=public --add-service=ssh
# Open a custom TCP port for a specific application
sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp
# Reload to activate the new rules
sudo firewall-cmd --reload

Test changes at runtime before making them permanent. This prevents locking yourself out if you mistype a rule. The runtime configuration lives in memory. It changes immediately and vanishes on reboot. The permanent configuration lives on disk in /etc/firewalld/. It survives reboots but does not affect the running firewall until you reload. This separation exists so you can test changes safely. If you add a rule at runtime and it breaks your connection, a reboot restores the old state. If you make a permanent mistake, you might need to boot into rescue mode to fix it. Always test at runtime first.

# Add a port to the runtime config only for testing
sudo firewall-cmd --zone=home --add-port=5432/tcp
# Verify the service responds, then copy runtime to permanent
sudo firewall-cmd --runtime-to-permanent

You can list all built-in zones available in firewalld to see what options exist. The built-in zones cover 99% of use cases. Creating a custom zone requires copying a service definition or writing XML. Stick to the built-in zones unless you have a specific policy requirement.

# List all built-in zones available in firewalld
sudo firewall-cmd --get-zones

Verify the rules are active

Confirm the rules are active. List the zone contents to see services, ports, and interfaces.

# Show all rules, services, and ports for the public zone
sudo firewall-cmd --zone=public --list-all

Read the output carefully. If the service isn't listed, the firewall is still blocking it.

Common pitfalls and errors

If you run a command without sudo, you get Error: COMMAND_FAILED. firewalld requires root privileges.

Error: COMMAND_FAILED: org.fedoraproject.FirewallD1: invalid_argument

If you see Warning: ALREADY_ENABLED, the service is already open. This isn't an error. It means the rule exists. If you get Error: INVALID_ZONE, you typed a zone name that doesn't exist. Check the list of available zones.

Changing the default zone doesn't move existing interfaces. It only affects new connections. If you set the default to trusted but your interface is pinned to public, the interface stays in public.

Pin interfaces to zones. Relying on the default zone leaves you vulnerable when NetworkManager reassigns interfaces on reboot.

When to use each zone

Use trusted when you are on a private network where every device is under your control and you want zero friction. Use home when you are on a LAN with devices you trust but still want to block unsolicited inbound traffic from the internet. Use work when you are in an office environment and need access to internal services like printers and file shares while restricting external exposure. Use public when you connect to Wi-Fi hotspots, airport networks, or any network where you do not control the other devices. Use drop when you want to silently discard all packets without sending rejection responses, usually for maximum stealth on an unused interface. Use block when you want to reject all incoming traffic with an ICMP error message, which helps with debugging connectivity issues.

Where to go next