What you will read?
- 1 Verify and start FirewallD
- 2 Understand runtime vs permanent
- 3 Inspect zones and active zone
- 4 Assign interfaces and set default zone
- 5 Allow common services safely
- 6 Open specific ports or ranges
- 7 Restrict by source IP
- 8 Add rate limits and logging
- 9 Enable masquerading (NAT)
- 10 Configure port forwarding
- 11 Create a custom service
- 12 Manage ICMP (ping) rules
- 13 Blocklists and immediate drops
- 14 Audit, test, and persist
- 15 Troubleshoot conflicts and order
FirewallD in Red Hat/RHEL is a key layer for securing networks and services. With zone-based rules, you can precisely manage access, open or block ports, and enable NAT or logging. The following steps provide a practical explanation of configuring FirewallD in a professional way.
Verify and start FirewallD
Confirm the package is installed, enable the service, and check status to ensure rules will apply.
rpm -q firewalld || sudo dnf install -y firewalld sudo systemctl enable --now firewalld sudo systemctl status firewalld --no-pager
● firewalld.service - firewalld - dynamic firewall daemon Active: active (running)
Understand runtime vs permanent
FirewallD keeps a runtime config (immediate) and a permanent config (survives reboot). Combine both for reliable changes.
# add runtime change sudo firewall-cmd --add-service=ssh # add permanent change sudo firewall-cmd --permanent --add-service=ssh # apply permanent changes to runtime sudo firewall-cmd --reload # or copy runtime to permanent sudo firewall-cmd --runtime-to-permanent
Inspect zones and active zone
Zones group rules by trust level and network interfaces. Identify the active zone and defaults.
sudo firewall-cmd --get-active-zones sudo firewall-cmd --get-zones sudo firewall-cmd --get-default-zone sudo firewall-cmd --list-all
Assign interfaces and set default zone
Bind your NICs to the appropriate zone. Adjust the default for new interfaces.
# replace eth0 with your interface sudo firewall-cmd --zone=public --change-interface=eth0 sudo firewall-cmd --permanent --zone=public --change-interface=eth0 # set default zone sudo firewall-cmd --set-default-zone=public sudo firewall-cmd --get-default-zone
Allow common services safely
Services are predefined groups of ports/protocols. Prefer services over raw ports when available.
sudo firewall-cmd --get-services | tr ' ' '\n' | head sudo firewall-cmd --zone=public --permanent --add-service=http sudo firewall-cmd --zone=public --permanent --add-service=https sudo firewall-cmd --reload sudo firewall-cmd --zone=public --list-services
Open specific ports or ranges
When no service exists, open exact TCP/UDP ports or ranges.
# single port sudo firewall-cmd --zone=public --permanent --add-port=8080/tcp # port range sudo firewall-cmd --zone=public --permanent --add-port=30000-30100/tcp sudo firewall-cmd --reload sudo firewall-cmd --zone=public --list-ports
Restrict by source IP
Limit access to trusted addresses or networks using sources or rich rules.
# allow 203.0.113.10 to reach 22/tcp sudo firewall-cmd --zone=public --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10" port protocol="tcp" port="22" accept' # allow a CIDR and drop others for a port sudo firewall-cmd --zone=public --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" port protocol="tcp" port="5432" accept' sudo firewall-cmd --zone=public --permanent --add-rich-rule='rule family="ipv4" port protocol="tcp" port="5432" drop' sudo firewall-cmd --reload
Add rate limits and logging
Throttle abusive connections and log denies for auditing.
# limit SSH: 10 connections per minute per source sudo firewall-cmd --zone=public --permanent --add-rich-rule='rule service name="ssh" limit value="10/m" accept' # log denied packets sudo firewall-cmd --set-log-denied=all # check sudo firewall-cmd --get-log-denied
Enable masquerading (NAT)
Masquerading hides internal IPs on egress. Required for many forwarding scenarios.
sudo firewall-cmd --zone=public --permanent --add-masquerade sudo firewall-cmd --reload sudo firewall-cmd --zone=public --query-masquerade
Configure port forwarding
Forward external traffic to an internal host. Combine with masquerade when doing NAT.
# forward external 8080/tcp to 10.0.0.10:80 sudo firewall-cmd --zone=public --permanent --add-forward-port=port=8080:proto=tcp:toaddr=10.0.0.10:toport=80 sudo firewall-cmd --reload sudo firewall-cmd --zone=public --list-forward-ports
Create a custom service
Package your app’s ports into a reusable service definition and keep rule sets clean.
sudo firewall-cmd --permanent --new-service=myapp sudo firewall-cmd --permanent --service=myapp --set-short="MyApp Service" sudo firewall-cmd --permanent --service=myapp --set-description="MyApp ports" sudo firewall-cmd --permanent --service=myapp --add-port=9000/tcp sudo firewall-cmd --permanent --service=myapp --add-port=9001/udp sudo firewall-cmd --reload sudo firewall-cmd --zone=public --permanent --add-service=myapp sudo firewall-cmd --reload
Manage ICMP (ping) rules
Control ping and other ICMP types for security hardening.
# block echo-request (ping) in public zone sudo firewall-cmd --zone=public --permanent --add-icmp-block=echo-request sudo firewall-cmd --reload sudo firewall-cmd --zone=public --list-icmp-blocks # allow again sudo firewall-cmd --zone=public --permanent --remove-icmp-block=echo-request sudo firewall-cmd --reload
Blocklists and immediate drops
Drop traffic from hostile sources early with rich rules.
sudo firewall-cmd --zone=public --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.66" drop' sudo firewall-cmd --reload
Audit, test, and persist
Review the effective policy, test connectivity, and ensure changes survive reboots.
sudo firewall-cmd --list-all sudo firewall-cmd --zone=public --list-services sudo firewall-cmd --zone=public --list-ports sudo firewall-cmd --zone=public --list-rich-rules # simple tests (from a client) nc -vz your.server.ip 22 curl -I http://your.server.ip:8080 # persist runtime changes if any sudo firewall-cmd --runtime-to-permanent
Troubleshoot conflicts and order
Resolve overlaps between services, ports, and rich rules. Remember evaluation order: drop rules can override accepts.
# show priorities (rich rules evaluated top-down) sudo firewall-cmd --zone=public --list-rich-rules # check system services opening ports (SELinux/daemons) sudo ss -tulpn sudo sealert -a /var/log/audit/audit.log 2>/dev/null | head -n 50
By carefully configuring zones, services, ports, and rich rules in FirewallD, you can maintain a secure and standardized RHEL server environment. For additional resources, guidance, server options, and support, you can use dropvps.




