Firewalls are an important part of configuring basic security for your server.
Firewalls are network appliances that monitor and filter traffic to and from your instance and decides what traffic is allowed to reach your server, and what traffic should be dropped.
At its core, firewalld acts as a front end for managing iptables/nftables, which actually do the heavy lifting of filtering packets.
Install firewalld on CentOS 7
Before we get started, lets ensure we have firewalld installed by issuing the following command:
# yum install firewalld
Follow the prompts as needed to ensure you’ve got the latest version of firewalld installed before proceeding.
Now that firewalld is installed, let’s better explain a few concepts. Firewalld uses zones to manage various rules that dictate how strict or relaxed traffic should be, based
on what network or interface you’re using. This is mostly useful with dynamic networks or shifting interfaces, in other words, less important for servers as networks and interfaces are more static.
With that being said, there are some predefined zones we should be made aware of, ordered by most strict to most relaxed:
- Drop – Ensures all incoming connections are immediately dropped without reply. Outgoing connections are possible and if made, bilateral traffic is allowed to pass.
- Block – Similar to drop, but rejected connections are sent a reply message of icmp-host-prohibited or icmp6-adm-prohibited.
- Public – For public, untrusted networks.
- External – For use on external networks with masquerading enabled, especially for routers.
- DMZ – For computers in your demilitarized zone. A DMZ is defined as publicly accessible, but with limited access to your internal network.
- Work – For use in work areas. You mostly trust the other computers on this network not to harm your computer.
- Home – For use in home areas.
- Internal – For use on internal networks.
- Trusted – All network connections are accepted.
A common issue we see is when a reboot occurs – expected or not – and suddenly your website stops loading or you’re unable to access it. This is often due to a problem with rule permanence. Changes made through firewall-cmd change the active firewall session only, and will not persist through a reboot. “Live session only” changes of this kind are for live testing of your rules before creating a disruptive change, that could end up locking you our of your server!
You can make rule changes permanent by using the the –permanent flag with firewall-cmd commands.
The service firewalld can also be configured using XML, however we’ll be focusing on the use of firewall-cmd. Once you’ve got firewalld installed, lets go ahead and enable it to start by default:
# systemctl enable firewalld
Next, lets perform a reboot:
# shutdown -r now
Log back in to your server. Check whether the firewalld daemon is running with the following:
# firewall-cmd --state
If the status is ‘running’, you’re good to go. Next, let’s review our default zone:
# firewall-cmd --get-default-zone
This should return ‘public’. Now let’s take a look at what zones are active:
# firewall-cmd --get-active-zones public interfaces: eth0 eth1
Taken what we’ve learned so far, let’s break down what this response indicates. First, we have an active zone, public. If more than one zone was active, they would also be listed here. Interfaces listed are where the active zone is being applied. Here we see the public zone is active on both eth0 and eth1.
You can specify which interface the rule applies to with the following:
# firewall-cmd --zone=home --change-interface=eth0
So now lets explore the rules for our zone:
# firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 eth1 sources: services: dhcpv6-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Again, because we only have one active zone, as is the default setting, we see the public zone listed with its associated rules. What we’ll want to take note of here, is the services section. This section details what services and traffic are being defined by that zone.
What we see here is SSH service and DHCP services are permitted, thus port 22 and 53 are open.
To explore other zones without applying them, you can issue the following command:
# firewall-cmd --zone=$zone --list-all
Where $zone is one of the zones we covered earlier.
Adding and Removing Services
To allow traffic for specific services, we can add them to an existing zone. To get a list of available services, run the following:
# firewall-cmd --get-services
This will return the services included in a fresh CentOS 7 install:
RH-Satellite-6 amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius redis rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
So lets say we’re running a web server, we’d likely be interested in opening up port 80 so that people can reach our site.
# firewall-cmd --zone=public --add-service=http success
Let’s not forget that these changes are not permanent! If after we add these rules and ensure everything is as expected; we can add the –permanent flag to the end of this to ensure it services a restart.
This should cover most beginner use cases, if you have a custom port you want to open, or a service that is not listed in our –get-services command, you can open that port by adding the port, with the protocol defined after a forward slash:
# firewall-cmd --zone=public --add-port=1776/tcp --permanent