$ run as a normal user# run as root (or with sudo)
Exam objectives in this chapter
- Limit network access with firewalld and firewall-cmd
- Set firewall rules with firewall-cmd and firewalld
Understand Linux firewalling
The kernel part is netfilter. Tools write rules into it: first iptables, now nftables. On RHEL you normally do not write nftables rules yourself — firewalld does it for you with zones and services.
| Tool | Role on RHEL 10 |
|---|---|
| netfilter | Kernel framework that filters packets |
nftables (nft) | Rule engine and low-level tool (firewalld backend) |
| iptables | Old tool; replaced by nftables |
firewalld (firewall-cmd) | The service and tool you use |
Watch out
Do not mix your own nft or iptables rules with firewalld; firewalld may overwrite them at reload.
Understand zones
A zone is a trust level with its own rules. Every network interface (or source address) belongs to one zone. Traffic is checked by the rules of that zone.
| Zone | Default behaviour |
|---|---|
public | Default on RHEL: only selected services (ssh, cockpit, dhcpv6-client) |
drop | Drop everything incoming, no answer |
block | Reject incoming with an ICMP message |
external, dmz, work, home, internal | Different preset services |
trusted | Allow everything |
firewall-cmd --get-default-zone
firewall-cmd --get-active-zones
firewall-cmd --get-zones
firewall-cmd --list-all
firewall-cmd --list-all --zone=internalUnderstand services
A firewalld service is a name for one or more ports (and helpers). http = 80/tcp, ssh = 22/tcp, nfs = 2049/tcp … Using names keeps rules readable.
firewall-cmd --get-services | tr ' ' '\n' | grep -E '^(http|https|ssh|nfs|samba)$'
firewall-cmd --info-service=http
ls /usr/lib/firewalld/services/ | headYou can define your own service in /etc/firewalld/services/NAME.xml.
Open services and ports
Add a service or port to the zone. Without --permanent it is lost at reload or reboot; with --permanent it is not active until a reload.
- Open a service and a port permanently, then reload.
firewall-cmd --add-service=http --permanent firewall-cmd --add-port=8443/tcp --permanent firewall-cmd --reload - Check.
firewall-cmd --list-services firewall-cmd --list-ports - Close them again.
firewall-cmd --remove-service=http --permanent firewall-cmd --remove-port=8443/tcp --permanent firewall-cmd --reload
| Way | Effect |
|---|---|
without --permanent | Active now, gone after reload/reboot |
--permanent + --reload | Saved and active |
--runtime-to-permanent | Save all current runtime rules |
Exam tip
Use --permanent and --reload for every firewall task, and check with firewall-cmd --list-all. Test from another machine.
Work with zones and sources
Change the default zone, move an interface to another zone, or give a source network its own zone.
firewall-cmd --set-default-zone=public
firewall-cmd --zone=internal --change-interface=enp2s0 --permanent
firewall-cmd --zone=trusted --add-source=192.168.122.0/24 --permanent
firewall-cmd --reload
firewall-cmd --get-active-zonesNote
NetworkManager can store the zone of a connection: nmcli con mod enp2s0 connection.zone internal.
Use rich rules and forwarding
Rich rules allow more detail: a service only for one network, logging, rejecting one IP. Port forwarding sends traffic to another port or host.
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.122.0/24" service name="mysql" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" drop'
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
firewall-cmd --reload
firewall-cmd --list-rich-rulesAt work
Open only what you need, and limit admin services (ssh, cockpit, databases) to admin networks with rich rules or a separate zone.
Test the firewall
Check the rules on the server, then test from outside.
firewall-cmd --list-all
firewall-cmd --query-service=http
yes
curl -I http://server1
nc -zv server1 8443
firewall-cmd --set-log-denied=all
journalctl -k | grep -i 'filter_IN_public_REJECT'Remember the main points
The most important facts of this chapter, in short.
- firewalld manages the firewall (nftables underneath); the tool is
firewall-cmd. - Zones set trust levels; every interface or source belongs to one zone; the default zone is
public. - Open a service (
--add-service=http) or a port (--add-port=8080/tcp). - Changes without
--permanentare lost at reload or reboot; with--permanentthey wait until--reload. Do both, or use--runtime-to-permanent. firewall-cmd --list-allshows the active zone;--get-serviceslists known services.- Rich rules allow more detail, for example one source network for one service.
- Test from another host with
curl,ncornmap.
Learn the key terms
The words of this chapter in simple English.
| Term | Meaning |
|---|---|
| firewalld | The firewall service of RHEL. |
| Zone | A set of rules with one trust level. |
| Default zone | The zone for interfaces that have no other zone. |
| Service | A name for one or more ports, like ssh or http. |
| Runtime config | The rules that are active now. |
| Permanent config | The rules saved on disk for the next start. |
| Rich rule | A detailed rule with source, service, port and action. |
| nftables | The kernel firewall that firewalld uses. |
Check what you learned
Think about the answer first, then open it.
1How do you open the https service now and for good?
2How do you open port 2022/tcp for good?
firewall-cmd --permanent --add-port=2022/tcp, then --reload.
3How do you see all rules of the active zone?
4How do you see which zone is the default?
5How do you put interface enp2s0 in the zone internal?
firewall-cmd --permanent --zone=internal --change-interface=enp2s0, then --reload (or set the zone in the NetworkManager profile).
6How do you allow SSH only from 192.168.122.0/24?
A rich rule: firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=192.168.122.0/24 service name=ssh accept' and remove the normal ssh service.
7You added a rule without --permanent. What happens at reboot?
It is gone.
8Which file holds the ports of a known service?
The service XML file in /usr/lib/firewalld/services/ (your own in /etc/firewalld/services/).