{"id":167772,"date":"2026-05-20T14:06:34","date_gmt":"2026-05-20T11:06:34","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=167772"},"modified":"2026-05-20T22:22:49","modified_gmt":"2026-05-20T19:22:49","slug":"configure-firewalld-fedora","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/configure-firewalld-fedora\/","title":{"rendered":"Configure firewalld on Fedora 44 \/ 43 \/ 42: Zones, Services, Rich Rules"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">firewalld is the default firewall on Fedora, Server and Workstation alike. It abstracts nftables (and iptables on older releases) behind a zone model that maps cleanly onto the way real networks work: one interface or source belongs to one zone, and each zone has its own list of allowed services, ports, rich rules, and forwarding policy. Once you understand zones, services, and rich rules, every other firewalld setting is a footnote.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide walks the practical firewalld workflow on Fedora: confirming the service is running, picking the right default zone, opening services and ports, writing rich rules for source filtering and rate limiting, and using the firewall-config GUI for a faster visual audit. Every command was executed on a real Fedora install; the output you see in the screenshots is what your terminal will show.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Tested <strong>May 2026<\/strong> on Fedora 44 (kernel 7.0.9-202.fc44, firewalld 2.4.0, nftables 1.1.4). Package availability and firewall-cmd syntax parity verified on Fedora 43 (firewalld 2.3.2) and Fedora 42 (firewalld 2.3.2).<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"1080\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-fedora-44-firewall-config-services.png\" alt=\"firewall-config GUI with zones list and services tab on Fedora 44\" class=\"wp-image-167751\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-fedora-44-firewall-config-services.png 1920w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-fedora-44-firewall-config-services-300x169.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-fedora-44-firewall-config-services-1024x576.png 1024w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-fedora-44-firewall-config-services-768x432.png 768w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-fedora-44-firewall-config-services-1536x864.png 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Confirm firewalld is running<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fedora installs and enables firewalld by default. Verify in one shot:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>firewall-cmd --version\nsudo systemctl is-active firewalld\nsudo firewall-cmd --state<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The output of the commands is shown above.<\/p>\n\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"920\" height=\"800\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-status-fedora-44.png\" alt=\"firewalld 2.4 systemctl status default zone get-zones on Fedora 44\" class=\"wp-image-167752\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-status-fedora-44.png 920w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-status-fedora-44-300x261.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-status-fedora-44-768x668.png 768w\" sizes=\"auto, (max-width: 920px) 100vw, 920px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If the service is masked or missing, install and enable it:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo dnf install -y firewalld\nsudo systemctl unmask firewalld\nsudo systemctl enable --now firewalld<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you previously ran iptables-services or nftables.service directly, disable them. firewalld is the single source of truth on Fedora and conflicts with manually loaded rules.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Zones: the firewalld model in one paragraph<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A zone is a named profile that defines what the firewall does with traffic arriving on an interface or from a source address. Recent Fedora releases ship fifteen built-in zones. The ones you actually use:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>public<\/strong>: default on most Fedora systems. Allows ssh, dhcpv6-client, mdns. Everything else is dropped.<\/li>\n<li><strong>FedoraServer<\/strong>: default on Fedora Server. Same as public minus mdns, plus cockpit.<\/li>\n<li><strong>FedoraWorkstation<\/strong>: default on Fedora Workstation. Adds samba-client and KDE Connect range to public.<\/li>\n<li><strong>trusted<\/strong>: allows everything. Useful for a private VLAN, dangerous on a real interface.<\/li>\n<li><strong>drop<\/strong>: drops every inbound packet without a reply. Use during incident response.<\/li>\n<li><strong>block<\/strong>: rejects inbound (sends ICMP unreachable) instead of dropping silently.<\/li>\n<li><strong>internal<\/strong>, <strong>home<\/strong>, <strong>work<\/strong>: pre-defined &#8220;less restrictive than public&#8221; profiles for LAN-trusted contexts.<\/li>\n<li><strong>dmz<\/strong>: only inbound SSH is allowed; suitable for an exposed bastion.<\/li>\n<li><strong>external<\/strong>: masquerading is on. Use this on the outbound interface of a router.<\/li>\n<li><strong>libvirt<\/strong> and <strong>libvirt-routed<\/strong>: managed automatically by libvirt for the default virtual network.<\/li>\n<li><strong>nm-shared<\/strong>: created automatically by NetworkManager when sharing a connection.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Get the current state with three commands:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --get-default-zone\nsudo firewall-cmd --get-active-zones\nsudo firewall-cmd --get-zones<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On a fresh Workstation install you will see <code>public<\/code> as the default with <code>eth0<\/code> (or whatever NIC name NetworkManager assigned) bound to it. To change the default zone for unbound interfaces:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --set-default-zone=FedoraWorkstation<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To bind a specific interface to a different zone permanently:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --zone=internal --change-interface=eth1\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Open services and ports<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A firewalld service is a named bundle of ports and protocols. List the services your distro ships with:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --get-services | tr ' ' '\\n' | head -20<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Recent Fedora releases ship definitions for nearly 200 services. Use them whenever they exist: they survive port changes upstream and the names are self-documenting in audits. To open HTTP, HTTPS, and Cockpit in the default zone:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --add-service=http\nsudo firewall-cmd --permanent --add-service=https\nsudo firewall-cmd --permanent --add-service=cockpit\nsudo firewall-cmd --reload\nsudo firewall-cmd --list-services<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The output of the commands is shown above.<\/p>\n\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"920\" height=\"800\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-zones-services-fedora-44.png\" alt=\"firewall-cmd list-all add-service add-port reload on Fedora 44\" class=\"wp-image-167753\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-zones-services-fedora-44.png 920w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-zones-services-fedora-44-300x261.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-zones-services-fedora-44-768x668.png 768w\" sizes=\"auto, (max-width: 920px) 100vw, 920px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For a service that does not have a definition (custom app on port 8080, etc.) add the raw port:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --add-port=8080\/tcp\nsudo firewall-cmd --permanent --add-port=51820\/udp\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The golden rule: every persistent change uses <code>--permanent<\/code> and is followed by <code>--reload<\/code>. Without <code>--permanent<\/code> the rule is only in the runtime config and disappears on the next restart. The two configurations are intentional: it lets you experiment without writing changes to disk.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Define a custom service<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you frequently open the same set of ports across machines, write a service file once. Save the following as <code>\/etc\/firewalld\/services\/myapp.xml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;service&gt;\n  &lt;short&gt;myapp&lt;\/short&gt;\n  &lt;description&gt;Custom app on tcp\/8080 and udp\/8081&lt;\/description&gt;\n  &lt;port protocol=\"tcp\" port=\"8080\"\/&gt;\n  &lt;port protocol=\"udp\" port=\"8081\"\/&gt;\n&lt;\/service&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then reload and use it like any built-in service:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --reload\nsudo firewall-cmd --permanent --add-service=myapp\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Rich rules: source filtering, rate limits, and logging<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Rich rules are firewalld&#8217;s expressive layer. They can combine source address, destination, service or port, action, log, and audit, in one rule. The pattern looks dense at first but reads cleanly once you parse it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Restrict SSH to one subnet, and rate-limit-and-log every other SSH attempt:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --zone=public --add-rich-rule=\\\n'rule family=\"ipv4\" source address=\"192.168.1.0\/24\" service name=\"ssh\" accept'\n\nsudo firewall-cmd --permanent --zone=public --add-rich-rule=\\\n'rule family=\"ipv4\" service name=\"ssh\" log prefix=\"ssh-deny\" level=\"warning\" limit value=\"10\/m\" drop'\n\nsudo firewall-cmd --reload\nsudo firewall-cmd --zone=public --list-rich-rules<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The output of the commands is shown above.<\/p>\n\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"920\" height=\"800\" src=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-rich-rules-fedora-44.png\" alt=\"firewall-cmd rich rules accept ssh from subnet log drop other on Fedora 44\" class=\"wp-image-167754\" title=\"\" srcset=\"https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-rich-rules-fedora-44.png 920w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-rich-rules-fedora-44-300x261.png 300w, https:\/\/computingforgeeks.com\/wp-content\/uploads\/2026\/05\/wm-firewalld-rich-rules-fedora-44-768x668.png 768w\" sizes=\"auto, (max-width: 920px) 100vw, 920px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The log entries land in <code>\/var\/log\/messages<\/code> on Fedora, with the prefix you set, so a quick <code>sudo journalctl -k -g ssh-deny<\/code> shows attempted breakins.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Block an entire country code by combining a CIDR list with rich rules. For example, drop everything from a specific malicious \/24:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --zone=public --add-rich-rule=\\\n'rule family=\"ipv4\" source address=\"203.0.113.0\/24\" drop'\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">For larger sets, IP sets via <code>--new-ipset<\/code> are dramatically faster than dozens of rich rules. Modern firewalld on Fedora supports both nftables-native and legacy ipset back ends.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">firewall-config: the GUI for visual audits<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">firewall-config is the desktop counterpart to firewall-cmd. It shows every zone, every service binding, and every rich rule in one window, and is by far the fastest way to review a complicated configuration. Install it on a Workstation:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo dnf install -y firewall-config\nfirewall-config<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The header tabs separate Runtime from Permanent. Switch to <strong>Permanent<\/strong> first, edit, then <strong>Options: Reload Firewalld<\/strong> to apply. Otherwise your changes only land in runtime and disappear on next restart, mirroring the CLI semantics.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use the GUI for two things in particular:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Rich rule visualization<\/strong>. Each rich rule renders as a row with source, service, action, log columns. Far easier than parsing the XML by hand.<\/li>\n<li><strong>Service definitions<\/strong>. The Services tab lists every service Fedora ships and lets you edit ports without writing XML.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Common Fedora hardening patterns<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Three short recipes that cover most servers:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Web server on a public network<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Run the commands below.<\/p>\n\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --set-default-zone=FedoraServer\nsudo firewall-cmd --permanent --zone=FedoraServer --add-service=http\nsudo firewall-cmd --permanent --zone=FedoraServer --add-service=https\nsudo firewall-cmd --permanent --zone=FedoraServer --remove-service=cockpit\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Internal app server (only management subnet allowed)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Run the commands below.<\/p>\n\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --new-zone=mgmt\nsudo firewall-cmd --permanent --zone=mgmt --add-source=10.10.0.0\/24\nsudo firewall-cmd --permanent --zone=mgmt --add-service=ssh\nsudo firewall-cmd --permanent --zone=mgmt --add-service=cockpit\nsudo firewall-cmd --permanent --set-default-zone=drop\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Anything from outside <code>10.10.0.0\/24<\/code> hits the default <code>drop<\/code> zone and gets silently dropped.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Linux gateway with masquerading<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Run the commands below.<\/p>\n\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --permanent --zone=external --change-interface=eth0\nsudo firewall-cmd --permanent --zone=internal --change-interface=eth1\nsudo firewall-cmd --permanent --zone=external --add-masquerade\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>external<\/code> zone has masquerading enabled by default in its template, so a separate <code>--add-masquerade<\/code> only matters when you want to enable it on a non-external zone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Panic mode and emergencies<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you suspect a compromise and want to immediately stop accepting any traffic:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo firewall-cmd --panic-on\nsudo firewall-cmd --query-panic\nsudo firewall-cmd --panic-off<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Panic mode drops every packet in and out of the host (including DNS) until you turn it off. If you panic-on over SSH you will lose your session, so use it only from the console or from another machine that already has an established connection.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Inspect the underlying nftables<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">firewalld is a high-level layer over nftables. If you want to see what the kernel actually has loaded:<\/p>\n\n\n\n<pre class=\"wp-block-code code\"><code>sudo nft list ruleset | head -50\nsudo nft list table inet firewalld | head -30<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That is the source of truth. Never edit those rules directly: firewalld will overwrite them on the next reload. Use this view to verify that your high-level firewall-cmd changes resulted in the rules you expected, and to debug &#8220;I added a rule but the port is still closed&#8221; situations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Where to go next<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This guide is part of the Fedora 44 Workstation series. The <a href=\"https:\/\/computingforgeeks.com\/post-install-fedora-44-workstation\/\">post-install checklist<\/a> chains firewalld together with SELinux, fail2ban, and DNS over TLS for a hardened baseline. For non-Fedora hosts the same patterns translate one to one to Rocky Linux 10 and AlmaLinux 10: see <a href=\"https:\/\/computingforgeeks.com\/getting-started-with-firewalld-rhel-centos\/\">Configure Firewalld on Rocky Linux 10 \/ AlmaLinux 10 \/ RHEL 10<\/a> for the RHEL family equivalents.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>firewalld is the default firewall on Fedora, Server and Workstation alike. It abstracts nftables (and iptables on older releases) behind a zone model that maps cleanly onto the way real networks work: one interface or source belongs to one zone, and each zone has its own list of allowed services, ports, rich rules, and forwarding &#8230; <a title=\"Configure firewalld on Fedora 44 \/ 43 \/ 42: Zones, Services, Rich Rules\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/configure-firewalld-fedora\/\" aria-label=\"Read more about Configure firewalld on Fedora 44 \/ 43 \/ 42: Zones, Services, Rich Rules\">Read more<\/a><\/p>\n","protected":false},"author":21,"featured_media":167740,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29,299,47,50],"tags":[681,203,144,35849,39858],"cfg_series":[39847],"class_list":["post-167772","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-fedora","category-how-to","category-linux","category-linux-tutorials","tag-fedora","tag-firewall","tag-firewalld","tag-linux-security","tag-nftables","cfg_series-fedora-44-workstation"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/167772","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=167772"}],"version-history":[{"count":4,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/167772\/revisions"}],"predecessor-version":[{"id":167785,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/167772\/revisions\/167785"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/167740"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=167772"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=167772"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=167772"},{"taxonomy":"cfg_series","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/cfg_series?post=167772"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}