+--------------------------------------------------------+ | 1. HIGH LEVEL: User Interface (The Manager) | | - Examples: firewalld (firewall-cmd), UFW | +--------------------------------------------------------+ | v (Sends configuration rules) +--------------------------------------------------------+ | 2. MIDDLE LEVEL: Command-Line Tools (The Translators) | | - Legacy: iptables, ip6tables, arptables | | - Modern: nft (nftables tool), iptables-nft | +--------------------------------------------------------+ | v (Interacts via Netlink sockets) +--------------------------------------------------------+ | 3. LOW LEVEL: Kernel Subsystem (The Security Guard) | | - Netfilter (Core packet processing engine) | +--------------------------------------------------------+
firewalld.iptables or nft.firewalld is Stoppedfirewalld runs, it sends rules down to Layer 2, which loads them into Layer 3 (Netfilter inside the kernel memory). [1, 2]sudo systemctl stop firewalld, you are only killing the Layer 1 Management Daemon.firewalld, you have to explicitly flush the kernel tables using a middle-level tool (e.g., sudo iptables -F or sudo nft flush ruleset).Operating System | Layer 1 (High) | Layer 2 (Middle) | Layer 3 (Low / Kernel) |
|---|---|---|---|
CentOS 7 | firewalld | Legacy iptables binary | Netfilter (using old iptables structures) |
CentOS 8 / AlmaLinux 8 | firewalld | iptables-nft (A translation tool) | Netfilter (using modern nftables structures) |
AlmaLinux 9 | firewalld | Native nft command | Netfilter (pure modern nftables subsystem) |
iptables-nft Trick in Version 8iptables command doesn't actually touch the old legacy architecture. It uses a modern utility called iptables-nft. This utility takes your old iptables command syntax, translates it under the hood into modern nftables syntax, and pushes it directly into the new kernel subsystem. [1, 2, 3, 4]firewalld) rules.firewalld as their primary Layer 1 manager, the exact same firewall-cmd commands work identically across all four operating systems.sudo firewall-cmd --get-zones
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all
sudo firewall-cmd --zone=public --list-all
sudo firewall-cmd --list-all-zones
firewalld has two states: Runtime (active right now, but resets on reboot) and Permanent (saved to disk, applies after reload/reboot). To make a rule permanent, you must use the --permanent flag, and then run firewall-cmd --reload.sudo firewall-cmd --zone=public --add-port=8080/tcp
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --zone=public --query-port=8080/tcp
sudo firewall-cmd --zone=public --query-service=https
firewalld does not have a direct "edit" command. To update a rule, you change the configuration and then reload the system to apply it.sudo firewall-cmd --reload
sudo firewall-cmd --zone=internal --change-interface=eth0 --permanent
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
sudo firewall-cmd --zone=public --remove-service=https --permanent
firewalld to change its default behavior, as it natively operates on a whitelist approach that blocks everything by default. [1, 2, 3]firewalld).public zone drops or rejects all traffic unless explicitly whitelisted. Changing the target to ACCEPT turns it into an "allow-all" zone. [1, 2, 3, 4]# 1. Change the target permanently sudo firewall-cmd --zone=public --set-target=ACCEPT --permanent # 2. Reload to apply changes sudo firewall-cmd --reload
# 1. Add the full port ranges permanently sudo firewall-cmd --zone=public --add-port=1-65535/tcp --permanent sudo firewall-cmd --zone=public --add-port=1-65535/udp --permanent # 2. Reload to apply changes sudo firewall-cmd --reload
firewalld strictly enforces a whitelist policy out of the box. If a port or service is not explicitly added to the active zone configuration, it is automatically blocked. [1]public.default for the public zone translates under the hood to REJECT (or DROP) for any incoming packet that does not match an allowed exception. [1, 2, 3]sudo firewall-cmd --zone=public --list-all
target: default → This is the rule enforcing the whitelist behavior. It catches all unmatched traffic and blocks it.services: cockpit dhcpv6-client ssh → These are the default factory exceptions. Only administrative traffic for SSH, Cockpit web console, and DHCPv6 are allowed through. Everything else is blocked.ports: → This will be blank by default, showing that no raw port numbers have been whitelisted yet. [1, 2, 3, 4, 5]firewalld comes pre-configured with 9 standard zones.Zone Name | Trust Level | Default Behavior | Best Use Case |
|---|---|---|---|
drop | Lowest | Drops all incoming packets without any response. | High-attack environments. |
block | Very Low | Rejects all incoming packets with an ICMP error message. | Disconnecting untrusted networks. |
public | Low | (Default) Blocks all traffic except explicitly allowed ports/services. | Public Wi-Fi or internet-facing servers. |
external | Low | Blocks traffic; enables NAT masquerading for routers/gateways. | Your WAN interface on a router. |
dmz | Medium-Low | Isolated zone with limited access to your internal network. | Public-facing servers (Web, Mail, DNS). |
work | Medium | Trusts most computers; shields against unrequested traffic. | Office networks where colleagues are nearby. |
home | Medium-High | Trusts most computers; designed for helpful local discovery. | Home networks with trusted family devices. |
internal | Medium-High | Identical to the home zone configuration. | Private side of a corporate local network. |
trusted | Highest | Accepts all network traffic automatically. | Local testing or a totally isolated private link. |
sudo firewall-cmd --delete-zone=public --permanent, the system will return an error stating that it is a built-in zone.sudo firewall-cmd --new-zone=my-secure-zone --permanent sudo firewall-cmd --reload
sudo firewall-cmd --delete-zone=my-secure-zone --permanent sudo firewall-cmd --reload
public to trusted to quickly open everything)?eth0 (connected to the public internet) and eth1 (connected to your private internal network). [1]public zonesudo firewall-cmd --zone=public --add-interface=eth0 --permanent
internal zonesudo firewall-cmd --zone=internal --add-interface=eth1 --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --get-active-zones
eth0 under public and eth1 under internal.)public) set to its native target. Never use the trusted zone for an internet-facing NIC.sudo firewall-cmd --zone=public --add-service=ssh --permanentsudo firewall-cmd --zone=public --add-port=22/tcp --permanentsudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.50" port port="3306" protocol="tcp" accept' --permanent sudo firewall-cmd --reload
--permanent flag first. Test your connection. If something breaks, simply reboot the server (or wait for a timeout) to restore your previous configuration. Once verified, run the command again with --permanent and reload.sudo yum install system-config-firewall-tui sudo system-config-firewall-tui
Tab to check/uncheck common services (SSH, HTTP) and add custom ports.iptables service. Running it on CentOS 7 will frequently conflict with Layer 1 firewalld. It does not exist on CentOS 8 or AlmaLinux 8/9. [1]Cockpit (Web-based Console Wizard)# On CentOS 7 sudo yum install cockpit -y sudo systemctl enable --now cockpit.socket # On CentOS 8 / AlmaLinux 8 & 9 sudo dnf install cockpit -y sudo systemctl enable --now cockpit.socket
https://<YOUR_SERVER_IP>:9090firewalld does not offer a native modern TUI wizard tool. In that exact scenario, administrators rely on interactive shell syntax tricks to act like a wizard.read) into a quick terminal macro to handle rule additions step-by-step:echo "=== Firewalld Rule Wizard ===" read -p "Enter Port Number (e.g., 8080): " port read -p "Enter Protocol (tcp/udp): " proto read -p "Enter Zone (default public): " zone zone=${zone:-public} sudo firewall-cmd --zone=$zone --add-port=$port/$proto --permanent sudo firewall-cmd --reload echo "Successfully added $port/$proto to $zone zone!"
8000-8080), and handles all CRUD operations across CentOS 7/8 and AlmaLinux 8/9.fw-wizard.sh:nano fw-wizard.sh
#!/bin/bash # Ensure the script runs with root/sudo privileges if [ "$EUID" -ne 0 ]; then echo "❌ Error: Please run this script using sudo or as root." exit 1 fi while true; do clear echo "=============================================" echo " 🔥 FIREWALLD INTERACTIVE TUI WIZARD 🔥 " echo "=============================================" echo " 1) [READ] List All Rules & Zones" echo " 2) [CREATE] Add a Port / Port Range" echo " 3) [DELETE] Remove a Port / Port Range" echo " 4) [RELOAD] Apply & Reload Firewall Settings" echo " 5) [EXIT] Exit Wizard" echo "=============================================" read -p "Choose an option [1-5]: " choice case $choice in 1) clear echo "=== ACTIVE ZONES AND CURRENT RULES ===" echo "--------------------------------------" sudo firewall-cmd --list-all-zones | grep -E '^[a-zA-Z0-9]|ports:|services:|interfaces:' echo "--------------------------------------" read -p "Press [Enter] to return to menu..." temp ;; 2) clear echo "=== CREATE: ADD PORT OR RANGE ===" read -p "Enter Target Zone (Default: public): " zone zone=${zone:-public} echo "👉 Format Examples: Single port [8080] | Range [8000-8050]" read -p "Enter Port or Port Range: " port read -p "Enter Protocol (tcp/udp) (Default: tcp): " proto proto=${proto:-tcp} echo "--------------------------------------" echo "Adding $port/$proto to '$zone' zone..." sudo firewall-cmd --zone=$zone --add-port=$port/$proto --permanent if [ $? -eq 0 ]; then echo "✅ Rule added successfully to configuration!" echo "💡 Note: You must select Option 4 (Reload) to activate it." else echo "❌ Failed to add rule. Please verify the port format or zone name." fi read -p "Press [Enter] to return to menu..." temp ;; 3) clear echo "=== DELETE: REMOVE PORT OR RANGE ===" read -p "Enter Target Zone (Default: public): " zone zone=${zone:-public} echo "👉 Format Examples: Single port [8080] | Range [8000-8050]" read -p "Enter Port or Port Range to remove: " port read -p "Enter Protocol (tcp/udp) (Default: tcp): " proto proto=${proto:-tcp} echo "--------------------------------------" echo "Removing $port/$proto from '$zone' zone..." sudo firewall-cmd --zone=$zone --remove-port=$port/$proto --permanent if [ $? -eq 0 ]; then echo "✅ Rule removed successfully from configuration!" echo "💡 Note: You must select Option 4 (Reload) to activate changes." else echo "❌ Failed to remove rule. Ensure the rule exists in that zone." fi read -p "Press [Enter] to return to menu..." temp ;; 4) clear echo "=== RELOADING SYSTEM FIREWALL ===" sudo firewall-cmd --reload if [ $? -eq 0 ]; then echo "🚀 Changes are now LIVE!" else echo "❌ Reload failed." fi read -p "Press [Enter] to return to menu..." temp ;; 5) clear echo "Goodbye! 👋" exit 0 ;; *) echo "❌ Invalid choice. Please pick an option from 1 to 5." sleep 1.5 ;; Museumesac done
chmod +x fw-wizard.sh
sudo:sudo ./fw-wizard.sh
80809000-9100tcp or udp, and the system handles the range orchestration behind the scenes.ssh or http) alongside raw port ranges?