| |

LFCS 107 ๐Ÿง Firewalld โ€” Zones and Rules

โฑ๏ธ Estimated read: 10 min | |

The previous chapter established the conceptual model: zones as trust boundaries, services as named port sets, and the runtime-versus-permanent split. This chapter moves from theory to configuration. The LFCS exam tests the specific commands that create, modify, and verify zone rules, and it tests the traps that cause a working configuration to fail after a reload. The most consequential trap is the --permanent flag: a rule added without it is active immediately but vanishes on the next reload. The second trap is the --reload versus --complete-reload distinction: the first preserves existing connections, the second drops them. The exam expects precision on both.

Key point: Rules added without --permanent are runtime-only. Rules added with --permanent are written to disk but require firewall-cmd --reload to take effect. The --reload command applies permanent rules without disrupting existing connections; --complete-reload applies them and drops all active connections.


Why zone rule configuration requires precision

The runtime-permanent trap. A candidate adds firewall-cmd --add-service=http, verifies it works, and moves on. The rule is active. The exam then asks what happens after a reboot or a firewall-cmd --reload. The rule is gone, because it was never written to the permanent configuration . The exam tests this distinction explicitly: the --permanent flag is not optional if the rule must survive.

The reload-versus-restart trap. Restarting firewalld with systemctl restart firewalld drops all established connections and applies the permanent configuration. firewall-cmd --reload applies the permanent configuration without dropping connections . The exam may present a scenario where an administrator needs to apply new rules on a live server without kicking off active SSH sessions. The correct answer is --reload, not restart.

The zone-targeting problem. Every firewall-cmd command operates on a zone. If the --zone flag is omitted, the command targets the default zone. On a fresh installation, the default zone is public. If an interface is assigned to a different zone, the command may not affect the traffic that the administrator intended to control . The --get-active-zones command reveals which zones are active and which interfaces are bound to them.

The rich rule problem. Simple services and ports cover most scenarios, but the exam tests --add-rich-rule for source-IP restrictions and rate limiting. A rich rule that allows SSH only from a specific subnet is a common exam scenario . The syntax is specific: rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept. A single character error in the rule string causes the command to fail or the rule to be ignored.

The trade-off. firewall-cmd is forgiving in the runtime configuration. A rule that is added incorrectly can be removed or the runtime can be reloaded to discard it. The permanent configuration is less forgiving: a malformed rule is written to an XML file and fails to load on reload. The safe workflow is to test in runtime, verify, then save to permanent with --runtime-to-permanent or add with --permanent and reload.


a. Adding and removing services in a zone

The --add-service and --remove-service commands modify the allowed services in a zone. The zone is specified with --zone or defaults to the default zone. The --permanent flag controls persistence.

# Add HTTP to the public zone (runtime only)
sudo firewall-cmd --zone=public --add-service=http

# Add HTTP and HTTPS permanently
sudo firewall-cmd --zone=public --add-service=http --add-service=https --permanent

# Reload to apply the permanent changes
sudo firewall-cmd --reload

# Remove a service
sudo firewall-cmd --zone=public --remove-service=http --permanent

The --list-services command shows the services currently allowed in the zone. Without --permanent, it shows the runtime configuration. With --permanent, it shows the saved configuration. The --list-all command shows the complete zone configuration, including services, ports, interfaces, and sources .

A service definition may include multiple ports and protocols. The ssh service, for example, opens TCP port 22. The http service opens TCP port 80. The --get-services command lists every service definition available on the system, which is useful when the correct service name for a protocol is unclear.


b. Adding and removing ports in a zone

When a service definition does not exist, a raw port can be opened with --add-port. The port is specified as <port>/<protocol>, where the protocol is tcp, udp, sctp, or dccp .

# Open TCP port 8080 in the public zone (runtime only)
sudo firewall-cmd --zone=public --add-port=8080/tcp

# Open UDP port range 60000-61000 permanently
sudo firewall-cmd --zone=public --add-port=60000-61000/udp --permanent

# Remove a port
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent

The --list-ports command shows the raw ports that have been explicitly opened. It does not list ports that are opened by service definitions. The --list-all command is the complete view; it shows both services and ports .

The recommendation is to use services when a definition exists. A service name is self-documenting; a raw port number requires the administrator to remember why it was opened. The exam may ask for the command to allow HTTPS traffic without specifying the port number. The correct answer is --add-service=https, not --add-port=443/tcp.


c. Rich rules for source restrictions and rate limiting

Rich rules extend firewall-cmd with conditions that services and ports cannot express. The two exam-relevant scenarios are source-IP restrictions and rate limiting.

# Allow SSH only from the 192.168.50.0/24 subnet
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.50.0/24" service name="ssh" accept' --permanent
sudo firewall-cmd --reload

# Rate limit SSH: 4 connections per minute
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" service name="ssh" limit value="4/m" accept' --permanent

The rich rule syntax follows a fixed order: rule, optional family, optional source address or destination address, the match condition (service name or port port protocol), optional log or limit, and the action (accept, reject, or drop) . The rule is enclosed in single quotes. A single missing quote or misspelled keyword causes the command to fail.

The --list-rich-rules command shows the rich rules in the zone. The --remove-rich-rule command removes a specific rule, which must be specified with the exact same string used to add it.

Rich rules can also be prioritized. The priority attribute determines the order of evaluation. Lower numbers are evaluated first. A rule with priority="-10" is evaluated before rules with the default priority of 0 . This is used to place a drop rule for a specific source before an accept rule for a service.


Complete Example Session

# ============================================
# PART 1: CHECK THE DEFAULT ZONE
# ============================================

firewall-cmd --get-default-zone
# Output: public
# ============================================
# PART 2: ADD A SERVICE AT RUNTIME
# ============================================

sudo firewall-cmd --zone=public --add-service=http
# Output: success
# Active immediately, lost on reload.
# ============================================
# PART 3: RELOAD AND OBSERVE THE LOSS
# ============================================

sudo firewall-cmd --reload
firewall-cmd --zone=public --list-services
# Output: ssh dhcpv6-client
# http is gone.
# ============================================
# PART 4: ADD A SERVICE PERMANENTLY
# ============================================

sudo firewall-cmd --zone=public --add-service=http --permanent
# Output: success
# Written to disk, not yet active.
# ============================================
# PART 5: RELOAD TO APPLY
# ============================================

sudo firewall-cmd --reload
firewall-cmd --zone=public --list-services
# Output: ssh dhcpv6-client http
# ============================================
# PART 6: OPEN A RAW PORT
# ============================================

sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
firewall-cmd --zone=public --list-ports
# Output: 8080/tcp
# ============================================
# PART 7: ADD A SOURCE-RESTRICTED RICH RULE
# ============================================

sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="ssh" accept' --permanent
sudo firewall-cmd --reload
firewall-cmd --zone=public --list-rich-rules
# Output: rule family="ipv4" source address="10.0.0.0/8" service name="ssh" accept
# ============================================
# PART 8: ADD A RATE-LIMITING RULE
# ============================================

sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" service name="ssh" limit value="4/m" accept' --permanent
sudo firewall-cmd --reload
# ============================================
# PART 9: VERIFY THE COMPLETE ZONE
# ============================================

firewall-cmd --zone=public --list-all
# Shows services, ports, rich rules, and active interfaces.

The nine parts trace the configuration workflow: default zone, runtime service, reload loss, permanent service, reload apply, raw port, source-restricted rich rule, rate-limiting rich rule, and complete verification.


Quick Reference

Service Commands

CommandEffect
firewall-cmd --zone=public --add-service=httpRuntime only
firewall-cmd --zone=public --add-service=http --permanentPersistent
firewall-cmd --zone=public --remove-service=http --permanentRemove persistent
firewall-cmd --zone=public --list-servicesList allowed services

Port Commands

CommandEffect
firewall-cmd --zone=public --add-port=8080/tcpRuntime only
firewall-cmd --zone=public --add-port=8080/tcp --permanentPersistent
firewall-cmd --zone=public --remove-port=8080/tcp --permanentRemove persistent
firewall-cmd --zone=public --list-portsList raw ports

Rich Rule Commands

CommandEffect
--add-rich-rule='rule ...'Add rich rule
--remove-rich-rule='rule ...'Remove rich rule
--list-rich-rulesList rich rules in zone

Reload Commands

CommandEffect
firewall-cmd --reloadApply permanent rules, keep connections
firewall-cmd --complete-reloadApply permanent rules, drop connections

Best Practices

โœ… Do This:

sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --reload
<!-- Add permanent, then reload to apply -->           # โœ…
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="ssh" accept' --permanent
<!-- Use rich rule for source restriction -->         # โœ…
sudo firewall-cmd --runtime-to-permanent
<!-- Save tested runtime rules -->                    # โœ…

โŒ Don’t Do This:

firewall-cmd --add-service=http
# Then reload
<!-- Runtime rule is lost -->                        # โŒ
# Use --add-port for a service that has a definition
<!-- Use --add-service instead -->                    # โŒ
# Assume rich rule syntax is forgiving
<!-- A single quote error breaks the rule -->         # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Rule lost after reloadAdded without --permanentAdd --permanent and reload
Rule not active after --permanentNo reload executedfirewall-cmd --reload
Service added to wrong zone--zone omittedSpecify --zone explicitly
Rich rule rejectedSyntax errorVerify quoting and keyword order
Cannot connect after changeService removed or zone changedUse console; --panic-off if needed

Real-World Examples

1. Add Service Permanently

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

2. Reload

sudo firewall-cmd --reload

3. Open Port

sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent

4. Remove Service

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

5. Source-Restricted SSH

sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="ssh" accept' --permanent

6. Rate-Limited SSH

sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" service name="ssh" limit value="4/m" accept' --permanent

7. List Rich Rules

firewall-cmd --zone=public --list-rich-rules

8. List All in Zone

firewall-cmd --zone=public --list-all

9. Save Runtime

sudo firewall-cmd --runtime-to-permanent

10. Complete Reload

sudo firewall-cmd --complete-reload

Visual

Runtime vs Permanent Rule Flow

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  firewall-cmd --add-service=http             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  RUNTIME CONFIGURATION                       โ”‚
โ”‚  Active now. Lost on reload.                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ”‚ --reload
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  RUNTIME DISCARDED                           โ”‚
โ”‚  Permanent config loaded.                    โ”‚
โ”‚  http is gone.                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  firewall-cmd --add-service=http --permanent โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  PERMANENT CONFIGURATION                     โ”‚
โ”‚  Written to disk. Not active yet.            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ”‚ --reload
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  RUNTIME UPDATED                             โ”‚
โ”‚  http is active and persistent.              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Rich Rule Evaluation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Incoming packet on public zone              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Rich rules evaluated by priority            โ”‚
โ”‚  โ”œโ”€โ”€ priority=-10: drop 203.0.113.0/24       โ”‚
โ”‚  โ””โ”€โ”€ priority=0: accept ssh from 10.0.0.0/8  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  First matching rule wins                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Summary

ItemValue
Add service (runtime)--add-service=<svc>
Add service (permanent)--add-service=<svc> --permanent
Apply permanentfirewall-cmd --reload
Open port--add-port=<port>/<proto>
Rich rule (source)--add-rich-rule='rule family="ipv4" source address="..." service name="..." accept'
Rich rule (rate limit)limit value="N/m"
List rich rules--list-rich-rules
Reload without droppingfirewall-cmd --reload
Reload dropping connectionsfirewall-cmd --complete-reload

Key takeaways:

  • The --permanent flag is mandatory for persistence. A rule added without it is lost on reload or reboot. The exam tests this distinction explicitly .
  • --reload preserves connections; --complete-reload drops them. The first is the correct command for applying new rules on a live server. The second is for a hard reset .
  • Services are preferred over raw ports. A service definition is self-documenting and covers all required ports and protocols. The exam may ask for HTTPS access without specifying port 443; the correct answer is --add-service=https .
  • Rich rules handle source restrictions and rate limiting. The syntax is specific and order-sensitive. A single quote error breaks the rule .
  • The zone must be specified when it is not the default. Omitting --zone targets the default zone, which may not be the zone the interface is assigned to.

Remember: The exam tests the reload cycle, not just the command. A rule that is added and never reloaded is not persistent. A rule that is added permanently and never reloaded is not active. The correct workflow is: add with --permanent, then --reload, then verify with --list-all. The runtime configuration is for testing; the permanent configuration is for production.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!