Monday, October 28, 2013

What Is FirewallD and How It Works (firewall-cmd)

Hello everyone,
Today, I would like to talk about new implemented firewall in Fedora (18 and above, I guess) which is called FirewallD or Dynamic Firewall. FirewallD is more powerful and flexible compared to old static firewall. In static firewall, you list a set of rules and then firewall reads them by restarting your firewall, however, in new FirewallD you apply modified rules without restarting firewall. In fact, FirewallD does not use netfilter rules in the traditional sense. In other words, you cannot use the iptables command to add firewall rules for the Firewalld daemon. They conflict with each other. And, of course you can use the old iptables firewall, however, you have to first disable FirewallD which is not a good idea in my opinion.

You can use either firewall-config tool (GUI version) or firewall-cmd command (command line version) to set up your firewall. Systemd manages FirewallD by using firewalld.service unit file. If you don't know what are systemd and unit files, take a look at these links:  and
Let's take a look at inside firewalld.service Figure 1. I tried to put all explanations inside Figure 1.

                                                                               Figure 1

By the way, D-Bus is a free and open-source inter-process communication system, allowing multiple, concurrently-running computer programs (processes) to communicate with one another.

FirewallD uses zones. A network zone defines the level of trust for network connections. Most zones are mutable, but there are also immutable zones. Immutable zones are not customizable and there is no way to overload them. These are the different zones:

Zone                                    Description
drop (immutable)                 Deny all incoming connections, outgoing ones are accepted.
block (immutable)                Deny all incoming connections, with ICMP host prohibited messages issued.
trusted (immutable)              Allow all network connections
public                                  Public areas, do not trust other computers
external                               For computers with masquerading enabled, protecting a local network
dmz                                     For computers publicly accessible with restricted access. 
work                                    For trusted work areas
home                                   For trusted home network connections
internal                                For internal network, restrict incoming connections

Default zone is defined in /etc/firewalld/firewalld.conf. Figure 2.
Location of default and fallback zone files (in xml format) are in /usr/lib/firewalld/zones Figure 2.
Zone configurations are located in /etc/firewalld/zones.

                                                                              Figure 2


firewall-cmd is a command line to set your firewall with so many options. There are two options to save your changes. One is Permanent and the other one is runtime. Runtime changes are deleted after reload or restart. Permanent option will be there even after reload/restart/reboot.

Now, let's try few examples (Figure 3):

firewall-cmd --get-zones --> List your zones
firewall-cmd --get-services --> List all supported zones under the current zone
firewall-cmd --get-icmptype --> List icmp types
firewall-cmd --get-default-zone --> List default zone
firewall-cmd --set-default-zone=zone --> To set your default zone
firewall-cmd --get-active-zones --> Print currently active zones
firewall-cmd --get-zone-of-interface=interface --> Print the name of the zone the interface is bound to or no zone.
firewall-cmd --list-all-zones --> List everything added for or enabled in all zones.

                                                                              Figure 3

firewall-cmd --zone=public --list-all  --> List everything added for or enabled in public zone
firewall-cmd --zone=public --query-interface=ens33
firewall-cmd --zone=dmz --query-interface=ens33
firewall-cmd [--permanent] --add-service postgresql  --> To add services to the zone
firewall-cmd --query-service=postgresql --> To check if the service is enabled for a zone
cat /etc/services | grep postgresql
iptables-save | grep 5432

                                                                          Figure 4

firewall-cmd --remove-service postgresql --> To remove services from the zone
firewall-cmd --zone=dmz --add-port=22/tcp --> To add ssh port 22
firewall-cmd --zone=dmz --query-port=22/tcp --> To query the added port 22
firewall-cmd --zone=dmz --remove-port=22/tcp --> To remove port 22 in dmz zone
firewall-cmd --zone=dmz --add-masquerade --timeout=30 --> Enable IPv4 masquerade for zone. If zone is omitted, default zone will be used. If a timeout is supplied, masquerading will be active for the amount of seconds.

                                                                          Figure 5

If you want to use custom rules, you can use --direct option. The direct options give a more direct access to the firewall.

Direct options should be used only as a last resort when it's not possible to use for example --add-service=service.

firewall-cmd --direct --get-chains ipv4 filter -->  Get all chains added to table filter, in this case, as a space separated list. This option concerns only chains previously added with --direct 

firewall-cmd --direct --get-rules ipv4 filter INPUT  --> Get all rules added to chain INPUT in table filter as a newline separated list of the priority and arguments.

firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT   --> Add a rule with the arguments args to chain INPUT in table filter with priority 0. The priority is used to order rules. Priority 0 means add rule on top of the chain, with a higher priority the rule will be added further down. Rules with the same priority are on the same level and the order of these rules is not fixed and may change. If you want to make sure that a rule will be added after another one, use a low priority for the first and a higher for the following.

firewall-cmd --direct --get-rules ipv4 filter INPUT
firewall-cmd --direct --remove-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j ACCEPT --> to remove rule
firewall-cmd --direct --get-rules ipv4 filter INPUT

                                                                           Figure 6

If you want a comprehensive list of options, please refer to man page. I read Ferdora 19's man page and it's much nicer than before in terms of explanation. And that's all. Hope you enjoyed.
Khosro Taraghi


  1. Great post! I've only scanned it, but I can tell it will be very helpful to me on my fc20 system. Thanks so much!

  2. Fantastic blog!!! This blog helps you to solve your any knid of windows 7 firewall error , its can get instant service provider.go through this link.
    windows firewall error 1068 windows 7
    Aalia lyon

  3. To get your changes to remain between restarts you have to use the --permanent option. I really wish they'd stop chaging the damn options though, one used to be able to do 'firewall-cmd --add --port=xxxx/tcp' and they changed it to 'firewall-cmd --add-port=xxx/tcp'. I had some systems with F18 and others with F20 and I was going crazy for a while until I figured this out. RTFM helps though :)

      .."we are planning the new command line tool firewallctl"...


  4. Bro i learned a lot from your site!!....thanks!!

  5. how do i allow only ips from a certain network to access ssh services?. for example
    i want only to access ssh from public zone


    1. You can use rich language rules:
      ]# firewall-cmd --add-rich-rule 'rule family="ipv4" source address="" forward-port to-addr="" to-port="22" protocol="tcp" port="2222"' --zone public --permanent

      Have sshd running on server port 22 default config. Now you can:
      user @ $ ssh -p2222

  6. Could not get the interfaces to stay to the zones they belong after # systemctl restart firewalld.service. All the interfaces move back to the default zone. In order to get this working correctly need to modify the ifcfg-eth0 file in the /etc/sysconfig/network-scripts/ folder and add ZONE=, then it will be put in correct zone on restart/start otherwise default.

    Another option didnt see mentioned maybe helpful:
    # firewall-cmd --runtime-to-permanent

    When rule executed with --permanent flag before --reload, they will be reverted removed, and rules submitted without --permanent flag will become --permanent

    1. The --runtime-to-permanent option doesn't exist in RHEL 7!

  7. What to do when getting this error:
    bash: firewall-cmd: command not found...

  8. This comment has been removed by the author.

  9. Can you please tell how to save rich rule in any XML file using firewalld like we have iptables-save> in iptables service?

  10. It has been a good tutorial Thanks.
    I am facing one problem i have a FTP server which is accessible from 30 IPs from different part of the world. Earlier i have created a rule to access them EX: -A INPUT -s -p tcp -m tcp --dport 21 -j ACCEPT.

    I don't understand what would be the firewalld command for this rule .

    please help

  11. Excellent post!!! I have learnt many things form here. I have also website where you can visit and pass your pleasure time. In everyone’s life, at some time, our inner fire goes out. It is then burst into flame by an encounter with another human being. We should all be thankful for those people who rekindle the inner spirit. To get more information, visit here……………
    home network setup

  12. Thanks for sharing such a valuable information. Whenever I setup a Linux VPS, the first thing I do is install a Linux firewall . I have noticed an increase in attacks on my servers

  13. Is there a way to find out what ports are associated with a service (from firewall-cmd)??

  14. Hi,
    In RHEL6, we have a "reload" option in iptables to retrieve the changes without breaking the existing connections and to apply the modification done. So how come firewalld is dynamic as compared to iptables(which is being termed as static).