Skip to content
Search RunEntLinux

Searches general documentation on RunEntLinux. Each distribution has its own documentation search.

    Browse this documentation

    Firewall (firewalld)

    firewalld is the default dynamic firewall management tool on CentOS / AlmaLinux / Rocky Linux. It provides zone-based firewall management and supports modifying rules at runtime without restarting the service.

    Zones are the core concept of firewalld. Each zone defines a set of trust levels and corresponding firewall rules, and network interfaces are assigned to different zones.

    Commonly used built-in zones:

    ZoneDescription
    publicDefault zone. Suitable for public network environments; only selected inbound connections are allowed
    trustedAllows all inbound traffic
    homeSuitable for home networks; trusts other devices on the network
    workSuitable for work networks
    internalSuitable for internal networks
    dmzSuitable for servers in a DMZ; only specific inbound connections are allowed
    externalSuitable for external networks with NAT masquerading enabled
    blockRejects all inbound connections and returns an ICMP rejection message
    dropDrops all inbound packets without returning any response
    View firewalld running status
    sudo systemctl status firewalld
    Start and enable at boot
    sudo systemctl enable --now firewalld
    Check if firewalld is running
    sudo firewall-cmd --state
    View the default zone
    sudo firewall-cmd --get-default-zone
    View all active zones and their bound interfaces
    sudo firewall-cmd --get-active-zones
    View the complete rules for the current zone
    sudo firewall-cmd --list-all
    View rules for a specific zone
    sudo firewall-cmd --zone=public --list-all
    List all available zones
    sudo firewall-cmd --get-zones
    List all predefined services
    sudo firewall-cmd --get-services
    View the detailed definition of a service (e.g., http)
    sudo firewall-cmd --info-service=http

    firewalld rules come in two types:

    • Runtime rules: Take effect immediately but are lost after restarting firewalld or the system
    • Permanent rules: Written to configuration files and persist after a restart, but do not take effect immediately
    Add a permanent rule and apply it immediately
    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --reload

    You can also add both runtime and permanent rules simultaneously (no reload needed):

    Apply both runtime and permanent rules at once
    sudo firewall-cmd --add-service=http
    sudo firewall-cmd --permanent --add-service=http
    Allow HTTP service (permanent)
    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --reload
    Allow both HTTP and HTTPS
    sudo firewall-cmd --permanent --add-service=http --add-service=https
    sudo firewall-cmd --reload
    Remove HTTP service allowance (permanent)
    sudo firewall-cmd --permanent --remove-service=http
    sudo firewall-cmd --reload
    List services allowed in the current zone
    sudo firewall-cmd --list-services
    Allow TCP port 8080
    sudo firewall-cmd --permanent --add-port=8080/tcp
    sudo firewall-cmd --reload
    Allow a UDP port
    sudo firewall-cmd --permanent --add-port=53/udp
    sudo firewall-cmd --reload
    Allow a port range
    sudo firewall-cmd --permanent --add-port=3000-3100/tcp
    sudo firewall-cmd --reload
    Remove a port allowance
    sudo firewall-cmd --permanent --remove-port=8080/tcp
    sudo firewall-cmd --reload
    List currently allowed ports
    sudo firewall-cmd --list-ports
    Change the default zone to internal
    sudo firewall-cmd --set-default-zone=internal
    Assign ens33 to the internal zone
    sudo firewall-cmd --permanent --zone=internal --change-interface=ens33
    sudo firewall-cmd --reload
    Allow MySQL service in the internal zone
    sudo firewall-cmd --permanent --zone=internal --add-service=mysql
    sudo firewall-cmd --reload

    Rich rules provide more granular firewall control, allowing you to flexibly set rules based on source addresses, destination addresses, ports, and other conditions.

    The basic structure of a rich rule:

    rule family="ipv4" source address="source_address" service name="service_name" accept/reject/drop

    Allowing a Specific IP to Access a Service

    Section titled “Allowing a Specific IP to Access a Service”
    Allow only the 192.168.1.0/24 subnet to access SSH
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
    sudo firewall-cmd --reload
    Drop all connections from 10.0.0.100
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.100" drop'
    sudo firewall-cmd --reload

    Allowing a Specific IP to Access a Given Port

    Section titled “Allowing a Specific IP to Access a Given Port”
    Allow 172.16.0.0/16 to access TCP port 3306
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="172.16.0.0/16" port port="3306" protocol="tcp" accept'
    sudo firewall-cmd --reload
    Log and drop connections from a specific IP
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.200" log prefix="BLOCKED: " level="warning" drop'
    sudo firewall-cmd --reload
    List all current rich rules
    sudo firewall-cmd --list-rich-rules
    Delete a specific rich rule
    sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="10.0.0.100" drop'
    sudo firewall-cmd --reload
    Typical web server configuration: allow HTTP, HTTPS, and SSH
    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --permanent --add-service=https
    sudo firewall-cmd --permanent --add-service=ssh
    sudo firewall-cmd --reload

    Database Server (restricting access sources)

    Section titled “Database Server (restricting access sources)”
    Allow only the application server subnet to access MySQL
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.10.0/24" service name="mysql" accept'
    sudo firewall-cmd --reload
    Node.js application running on port 3000
    sudo firewall-cmd --permanent --add-port=3000/tcp
    sudo firewall-cmd --reload
    Forward external port 80 to internal port 8080
    sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
    sudo firewall-cmd --reload
    Forward traffic to another host
    sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=80:toaddr=192.168.1.50
    sudo firewall-cmd --permanent --add-masquerade
    sudo firewall-cmd --reload
    Enable IP masquerading
    sudo firewall-cmd --permanent --add-masquerade
    sudo firewall-cmd --reload
    View all rules across all zones
    sudo firewall-cmd --list-all-zones

    Viewing Underlying nftables/iptables Rules

    Section titled “Viewing Underlying nftables/iptables Rules”
    View the nftables rules generated by firewalld
    sudo nft list ruleset

    Since EL 8 the firewalld default backend is already nftables (FirewallBackend=nftables); only EL 7 and earlier used iptables. On EL 8/9/10 inspect rules with nft list ruleset or firewall-cmd --list-all; iptables -L on EL8+ shows the nft compatibility layer (iptables-nft), which is not evidence of an “iptables backend”.

    EL 7 only: the iptables backend (historical)
    sudo iptables -L -n -v
    View firewalld-related logs
    sudo journalctl -u firewalld --no-pager -n 30
    Enable panic mode (block all traffic)
    sudo firewall-cmd --panic-on
    Disable panic mode
    sudo firewall-cmd --panic-off
    Check whether panic mode is active
    sudo firewall-cmd --query-panic

    Backing Up the Current Firewall Configuration

    Section titled “Backing Up the Current Firewall Configuration”
    Back up the firewalld configuration directory
    sudo cp -r /etc/firewalld /etc/firewalld.backup.$(date +%Y%m%d)
    Restore backed-up configuration
    sudo cp -r /etc/firewalld.backup.20260324/* /etc/firewalld/
    sudo firewall-cmd --reload