Copyright (c) 2026 MindMesh Academy. All rights reserved. This content is proprietary and may not be reproduced or distributed without permission.

4.2.1. firewalld: Zones, Rules, and NAT

💡 First Principle: firewalld organizes rules using zones — named security contexts assigned to network interfaces or source addresses. An interface in the public zone gets restrictive rules; an interface in the trusted zone allows all traffic. This zone-based model lets you write rules once per zone and apply them to multiple interfaces.

Zone Management:
firewall-cmd --get-default-zone              # Current default zone
firewall-cmd --get-active-zones              # Zones with assigned interfaces
firewall-cmd --list-all                      # All rules in default zone
firewall-cmd --list-all --zone=public        # Rules for specific zone
firewall-cmd --zone=public --change-interface=eth0  # Assign interface to zone
Service and Port Rules:
# Allow by service name (uses /etc/firewalld/services/ definitions)
firewall-cmd --add-service=http              # Runtime: allow HTTP
firewall-cmd --add-service=https             # Runtime: allow HTTPS
firewall-cmd --permanent --add-service=http  # Permanent: allow HTTP
firewall-cmd --permanent --remove-service=http  # Permanent: remove HTTP

# Allow by port
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --permanent --add-port=3000-3100/tcp   # Port range
firewall-cmd --permanent --remove-port=8080/tcp

# Apply permanent changes immediately
firewall-cmd --reload

# List active rules
firewall-cmd --list-services
firewall-cmd --list-ports
Rich Rules — Fine-Grained Control:
# Allow SSH only from specific subnet
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'

# Drop traffic from a specific IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5" drop'

# Rate-limit connections
firewall-cmd --permanent --add-rich-rule='rule service name="http" limit value="25/m" accept'
NAT with firewalld:
# Enable masquerading (SNAT — share one public IP)
firewall-cmd --permanent --zone=public --add-masquerade

# Port forwarding (DNAT — redirect incoming port)
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.5:toport=80
NAT Types:
TypeAcronymDirectionPurpose
Source NATSNATOutboundChange source IP (masquerade = dynamic SNAT)
Destination NATDNATInboundRedirect to internal host/port (port forwarding)
Port Address TranslationPATBothMultiple internal IPs share one external IP (NAT overload)
MasqueradeOutboundDynamic SNAT using interface's IP
Logging with firewalld:
firewall-cmd --permanent --add-rich-rule='rule service name="ssh" log prefix="SSH-ATTEMPT " level="info" limit value="5/m" accept'

⚠️ Exam Trap (M6): The most common firewalld exam mistake is applying a --permanent change and not reloading. firewall-cmd --permanent --add-service=http writes to the permanent config but the running firewall is unchanged until firewall-cmd --reload. Conversely, firewall-cmd --add-service=http (no --permanent) takes immediate effect but won't survive a reload or reboot.

Reflection Question: You need to allow HTTPS traffic permanently and apply the change immediately without a reboot. Write the minimum number of commands to accomplish this using firewall-cmd.

Alvin Varughese
Written byAlvin Varughese
Founder18 professional certifications