How to Use the firewalld Firewall on a CentOS Cloud Server?

11-01-2024 03:07:24

Firewalld is a dynamic firewall software supporting both IPv4 and IPv6, operable on operating systems based on RHEL 7 (Red Hat Enterprise Linux). It represents an upgrade from the traditional iptables firewall. This article uses CentOS 7 as an example to explain how to use the firewalld firewall, primarily employing the firewall-cmd command.

First, we need to confirm whether firewalld is successfully installed. Use the following command to check the status of firewalld:

$ systemctl status firewalld
firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2016-03-10 15:07:00 UTC; 1min 30s ago

It is evident that on this cloud server, firewalld has been successfully installed and loaded.

We can also use the firewall-cmd tool to check:

$ firewall-cmd --state
running

Zone Management

Unlike iptables, firewalld introduces a concept called "zones" to define security levels. The use of zones is flexible; we can add different network interfaces to different zones, or add all network interfaces to one zone. Such division allows firewall rules set on a zone to be applicable to all network interfaces under it. For ease of use, firewalld establishes an initial default zone. Common commands related to zones are as follows.

Check the current zone:

$ firewall-cmd --get-zones
block dmz drop external home internal public trusted work

Check the default zone:

$ firewall-cmd --get-default-zone
public

Change the default zone:

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

It's worth noting that the configuration file for firewalld is /etc/firewalld/firewalld.conf. While it's possible to set firewalld by manually editing this file, it's still recommended to use the firewall-cmd command to avoid errors.

Get active zones:

$ firewall-cmd --get-active-zones

Get the zone corresponding to a network interface (for example, eth0):

$  firewall-cmd --get-zone-of-interface=eth0

If the default zone does not meet more detailed requirements, you can also create new zones (for example, zone1):

$ firewall-cmd --permanent --new-zone=zone1

After creation, it needs to be reloaded:

$ firewall-cmd --reload

Add a network interface (for example, eth1) to a specific zone (for example, internal):

$ firewall-cmd --permanent --zone=internal --change-interface=eth1

List all information under a zone, including network interfaces, allowed services, port settings, etc.:

$ firewall-cmd --permanent --zone=public --list-all
public (default)
  interfaces:
  sources:
  services: dhcpv6-client ssh
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:

Service Management

Once the zones are set, services can be added to the zones. Here, a service refers to a combination of protocols and ports.

Check available services:

$ firewall-cmd --get-services
RH-Satellite-6 amanda-client bacula bacula-client dhcp dhcpv6 dhcpv6-client dns freeipa-ldap freeipa-ldaps freeipa-replication ftp high-availability http https imaps ipp ipp-client ipsec iscsi-target kerberos kpasswd ldap ldaps libvirt libvirt-tls mdns mountd ms-wbt mysql nfs ntp openvpn pmcd pmproxy pmwebapi pmwebapis pop3s postgresql proxy-dhcp radius rpc-bind rsyncd samba samba-client smtp ssh telnet tftp tftp-client transmission-client vdsm vnc-server wbem-https

Check services under the default zone:

$ firewall-cmd --list-services
dhcpv6-client ssh

Add a service (for example, HTTP) to a specific zone (for example, public):

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

Reload firewalld:

$ firewall-cmd --reload

Verify if the addition was successful:

$ firewall-cmd --zone=public --list-services
dhcpv6-client http ssh

Remove a service (for example, HTTP) from a specific zone (for example, public):

$ firewall-cmd --permanent --zone=public --remove-service=http

Port Management

Besides defining protocol and port rules through services, individual protocol and port firewall rules can also be set. For instance, to run TCP protocol on port 7777, you can set it like this:

$ firewall-cmd --permanent --zone=public --add-port=7777/tcp

Setting a range of ports is also feasible:

$ firewall-cmd --permanent --zone=public --add-port=7000-8000/tcp

Delete the recently set protocol and port:

$ firewall-cmd --permanent --zone=public --remove-port=7777/tcp

Check the allowed protocols and ports under a zone:

$ firewall-cmd --zone=public --list-ports
7000-8000/tcp

After all settings are complete, firewalld needs to be enabled to start automatically with the system.

$ systemctl enable firewalld

Custom Services

If we need to make some custom settings, such as changing the default SSH port, then custom services need to be added. Services are defined in XML files, with default services stored in the /usr/lib/firewalld/services directory. We can use the tree command to view the files in this directory:

$ tree /usr/lib/firewalld/services
/usr/lib/firewalld/services
├── amanda-client.xml
├── bacula-client.xml
├── bacula.xml
├── dhcpv6-client.xml
├── dhcpv6.xml
├── dhcp.xml
├── dns.xml
├── freeipa-ldaps.xml
├── freeipa-ldap.xml
├── freeipa-replication.xml
├── ftp.xml
├── high-availability.xml
├── https.xml
├── http.xml

The simplest way to create a custom service is to copy a default service XML file and modify it. Custom services are stored in the /etc/firewalld/services directory. For example, to create a custom SSH service, first copy the XML file corresponding to the SSH service.

$ cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-custom.xml

The content of the XML file is as follows:

$ cat /etc/firewalld/services/ssh-custom.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="22"/>
</service>

Suppose we want to change the port number from 22 to 1234, then the content of the short tag and the attributes of the port tag need to be modified. The modified file is as follows:

$ nano /etc/firewalld/services/ssh-custom.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH-Custom</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="1234"/>
</service>

Add the newly created service to the default zone:

$ firewall-cmd --permanent --zone=public --add-service=ssh-custom

Reload firewalld:

$ firewall-cmd --reload

The functionality of firewalld is robust, with many settings. Due to limited knowledge, this article introduces only some basic uses of firewalld. Advanced techniques, such as port forwarding, address masquerading, and d-Bus communication, are left for enthusiastic readers to explore.