LFCS 107 ๐ง Firewalld โ Zones and Rules
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
| Command | Effect |
|---|---|
firewall-cmd --zone=public --add-service=http | Runtime only |
firewall-cmd --zone=public --add-service=http --permanent | Persistent |
firewall-cmd --zone=public --remove-service=http --permanent | Remove persistent |
firewall-cmd --zone=public --list-services | List allowed services |
Port Commands
| Command | Effect |
|---|---|
firewall-cmd --zone=public --add-port=8080/tcp | Runtime only |
firewall-cmd --zone=public --add-port=8080/tcp --permanent | Persistent |
firewall-cmd --zone=public --remove-port=8080/tcp --permanent | Remove persistent |
firewall-cmd --zone=public --list-ports | List raw ports |
Rich Rule Commands
| Command | Effect |
|---|---|
--add-rich-rule='rule ...' | Add rich rule |
--remove-rich-rule='rule ...' | Remove rich rule |
--list-rich-rules | List rich rules in zone |
Reload Commands
| Command | Effect |
|---|---|
firewall-cmd --reload | Apply permanent rules, keep connections |
firewall-cmd --complete-reload | Apply 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
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Rule lost after reload | Added without --permanent | Add --permanent and reload |
Rule not active after --permanent | No reload executed | firewall-cmd --reload |
| Service added to wrong zone | --zone omitted | Specify --zone explicitly |
| Rich rule rejected | Syntax error | Verify quoting and keyword order |
| Cannot connect after change | Service removed or zone changed | Use 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
| Item | Value |
|---|---|
| Add service (runtime) | --add-service=<svc> |
| Add service (permanent) | --add-service=<svc> --permanent |
| Apply permanent | firewall-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 dropping | firewall-cmd --reload |
| Reload dropping connections | firewall-cmd --complete-reload |
Key takeaways:
- The
--permanentflag is mandatory for persistence. A rule added without it is lost on reload or reboot. The exam tests this distinction explicitly . --reloadpreserves connections;--complete-reloaddrops 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
--zonetargets 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.
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!