docker
hapi
+
+
+
actix
micronaut
+
+
+
spring
htmx
fiber
+
groovy
+
+
macos
stimulus
+
jenkins
+
+
zig
//
sql
+
+
+
+
+
+
+
+
+
riot
ember
+
+
express
htmx
linux
pytest
+
gulp
+
julia
keras
vb
0x
+
oauth
puppet
netlify
parcel
marko
+
rb
sinatra
lisp
django
pycharm
vue
postgres
dns
//
+
pip
+
+
dns
+
+
alpine
+
ray
mysql
+
actix
+
+
webstorm
bitbucket
+
+
rails
Back to Blog
Managing System Security with firewalld in AlmaLinux
AlmaLinux firewalld Security

Managing System Security with firewalld in AlmaLinux

Published Jul 19, 2025

Master firewalld firewall management in AlmaLinux. Learn zones, services, rich rules, and advanced configurations for comprehensive network security and traffic control

21 min read
0 views
Table of Contents

Introduction

Firewalld provides a dynamically managed firewall with support for network zones that define trust levels for network connections and interfaces. As the default firewall management tool in AlmaLinux, firewalld offers a more flexible and feature-rich alternative to traditional iptables, with runtime and permanent configuration options, rich language rules, and D-Bus interface support. This comprehensive guide explores every aspect of firewalld, from basic concepts to advanced configurations.

Understanding firewalld Architecture

Core Concepts

Firewalld operates on several fundamental concepts:

  1. Zones: Trust levels for network connections
  2. Services: Predefined or custom port/protocol combinations
  3. Ports: Individual port openings
  4. Rich Rules: Complex firewall rules with detailed conditions
  5. Direct Rules: Direct interface to iptables/ip6tables
  6. Interfaces: Network interfaces bound to zones
  7. Sources: IP addresses/networks bound to zones

firewalld vs iptables

# Key differences:
# 1. Dynamic updates without breaking connections
# 2. Zone-based configuration
# 3. Runtime and permanent configurations
# 4. D-Bus interface
# 5. Rich rule support
# 6. Easier service management

# Check if firewalld is active
sudo systemctl status firewalld

# Ensure iptables service is not running
sudo systemctl status iptables

Installation and Basic Setup

Installing firewalld

# Install firewalld
sudo dnf install -y firewalld firewall-config

# Enable and start firewalld
sudo systemctl enable --now firewalld

# Verify installation
sudo firewall-cmd --version
firewall-cmd --state

# Check if firewalld is running
sudo systemctl is-active firewalld

Initial Configuration

# Set default zone
sudo firewall-cmd --set-default-zone=public

# Get firewall status
sudo firewall-cmd --state

# List all zones
sudo firewall-cmd --get-zones

# Get active zones
sudo firewall-cmd --get-active-zones

# Get default zone
sudo firewall-cmd --get-default-zone

Understanding Zones

Predefined Zones

# List available zones with descriptions
sudo firewall-cmd --list-all-zones

# Common zones:
# - drop: Drops all incoming packets, no reply
# - block: Rejects incoming connections with icmp-host-prohibited
# - public: For public areas, only selected connections accepted
# - external: For external networks with masquerading enabled
# - dmz: For DMZ computers with limited access
# - work: For work areas, trust other computers
# - home: For home areas, trust other computers
# - internal: For internal networks, trust other computers
# - trusted: All network connections accepted

Zone Configuration

# View specific zone configuration
sudo firewall-cmd --zone=public --list-all

# Set default zone
sudo firewall-cmd --set-default-zone=work

# Assign interface to zone
sudo firewall-cmd --zone=internal --add-interface=eth1
sudo firewall-cmd --zone=internal --add-interface=eth1 --permanent

# Remove interface from zone
sudo firewall-cmd --zone=internal --remove-interface=eth1 --permanent

# Change interface zone
sudo firewall-cmd --zone=public --change-interface=eth0 --permanent

# Query interface zone
sudo firewall-cmd --get-zone-of-interface=eth0

Creating Custom Zones

# Create new zone
sudo firewall-cmd --permanent --new-zone=customzone

# Reload to activate new zone
sudo firewall-cmd --reload

# Configure custom zone
sudo firewall-cmd --zone=customzone --add-service=ssh --permanent
sudo firewall-cmd --zone=customzone --add-service=http --permanent
sudo firewall-cmd --zone=customzone --add-port=8080/tcp --permanent

# Set target for zone
sudo firewall-cmd --zone=customzone --set-target=default --permanent

# Delete custom zone
sudo firewall-cmd --permanent --delete-zone=customzone

Service Management

Working with Services

# List all available services
sudo firewall-cmd --get-services

# List services in current zone
sudo firewall-cmd --list-services

# List services in specific zone
sudo firewall-cmd --zone=public --list-services

# Add service to zone
sudo firewall-cmd --zone=public --add-service=http
sudo firewall-cmd --zone=public --add-service=http --permanent

# Add multiple services
sudo firewall-cmd --zone=public --add-service={http,https,ssh} --permanent

# Remove service
sudo firewall-cmd --zone=public --remove-service=telnet --permanent

# Query if service is enabled
sudo firewall-cmd --zone=public --query-service=http

Creating Custom Services

# Create custom service file
sudo cat > /etc/firewalld/services/myapp.xml << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>MyApp</short>
  <description>My Custom Application Service</description>
  <port protocol="tcp" port="8888"/>
  <port protocol="tcp" port="8889"/>
  <port protocol="udp" port="8890"/>
</service>
EOF

# Reload firewalld
sudo firewall-cmd --reload

# Use custom service
sudo firewall-cmd --add-service=myapp --permanent
sudo firewall-cmd --reload

# List service info
sudo firewall-cmd --info-service=myapp

Service Definition Examples

<!-- Web application service -->
<service>
  <short>WebApp</short>
  <description>Custom Web Application</description>
  <port protocol="tcp" port="3000"/>
  <port protocol="tcp" port="3001"/>
  <module name="nf_conntrack_http"/>
</service>

<!-- Database cluster service -->
<service>
  <short>DBCluster</short>
  <description>Database Cluster Service</description>
  <port protocol="tcp" port="3306"/>
  <port protocol="tcp" port="4444"/>
  <port protocol="tcp" port="4567"/>
  <port protocol="tcp" port="4568"/>
</service>

Port Management

Basic Port Operations

# List open ports
sudo firewall-cmd --list-ports
sudo firewall-cmd --zone=public --list-ports

# Add port
sudo firewall-cmd --add-port=8080/tcp
sudo firewall-cmd --add-port=8080/tcp --permanent

# Add port range
sudo firewall-cmd --add-port=5000-5010/tcp --permanent

# Add multiple ports
sudo firewall-cmd --add-port={8080/tcp,8081/tcp,9090/udp} --permanent

# Remove port
sudo firewall-cmd --remove-port=8080/tcp --permanent

# Query port
sudo firewall-cmd --query-port=8080/tcp

Port Forwarding

# Enable masquerading (required for port forwarding)
sudo firewall-cmd --add-masquerade --permanent

# Add port forward
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 --permanent

# Forward to different host
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080 --permanent

# List port forwards
sudo firewall-cmd --list-forward-ports

# Remove port forward
sudo firewall-cmd --remove-forward-port=port=80:proto=tcp:toport=8080 --permanent

Rich Rules

Rich Rule Syntax

# Rich rule format:
# rule [family="<ipv4|ipv6>"]
#      [source address="<address>[/<mask>]" [invert="True"]]
#      [destination address="<address>[/<mask>]" [invert="True"]]
#      [service name="<service>"]
#      [port port="<port value>" protocol="<tcp|udp>"]
#      [protocol value="<protocol>"]
#      [icmp-block name="<icmptype>"]
#      [masquerade]
#      [forward-port port="<port>" protocol="<tcp|udp>" [to-port="<port>"] [to-addr="<address>"]]
#      [log [prefix="<prefix>"] [level="<level>"]]
#      [audit]
#      [accept|reject|drop]

Rich Rule Examples

# Allow specific IP to access service
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept' --permanent

# Allow subnet to access port
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept' --permanent

# Rate limiting
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="ssh" limit value="5/m" accept' --permanent

# Log and drop
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" log prefix="DROPPED: " level="info" drop' --permanent

# Time-based rule (requires firewalld 0.6.0+)
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept limit value="10/m"' --permanent

# Block specific country (requires ipset)
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source ipset="blocked_countries" drop' --permanent

# Port forwarding with rich rule
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" forward-port port="80" protocol="tcp" to-port="8080"' --permanent

# Complex rule with logging
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.100.0/24" destination address="192.168.200.0/24" port port="445" protocol="tcp" log prefix="SMB_ACCESS: " level="info" accept' --permanent

Managing Rich Rules

# List rich rules
sudo firewall-cmd --list-rich-rules
sudo firewall-cmd --zone=public --list-rich-rules

# Remove rich rule
sudo firewall-cmd --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept' --permanent

# Query rich rule
sudo firewall-cmd --query-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept'

IP Sets and Address Management

Working with IP Sets

# Create IP set
sudo firewall-cmd --permanent --new-ipset=blacklist --type=hash:ip
sudo firewall-cmd --permanent --new-ipset=whitelist --type=hash:net

# Add entries to IP set
sudo firewall-cmd --permanent --ipset=blacklist --add-entry=192.168.1.100
sudo firewall-cmd --permanent --ipset=blacklist --add-entry=10.0.0.0/8

# Add from file
sudo firewall-cmd --permanent --ipset=blacklist --add-entries-from-file=/etc/firewalld/ipsets/blacklist.txt

# List IP sets
sudo firewall-cmd --get-ipsets
sudo firewall-cmd --info-ipset=blacklist

# Use IP set in rich rule
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source ipset="blacklist" drop' --permanent

# Remove entry
sudo firewall-cmd --permanent --ipset=blacklist --remove-entry=192.168.1.100

# Delete IP set
sudo firewall-cmd --permanent --delete-ipset=blacklist

Source Management

# Add source to zone
sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
sudo firewall-cmd --zone=drop --add-source=10.0.0.100 --permanent

# List sources
sudo firewall-cmd --zone=trusted --list-sources

# Remove source
sudo firewall-cmd --zone=trusted --remove-source=192.168.1.0/24 --permanent

# Query source
sudo firewall-cmd --zone=trusted --query-source=192.168.1.0/24

Masquerading and NAT

Configure Masquerading

# Enable masquerading
sudo firewall-cmd --add-masquerade --permanent
sudo firewall-cmd --zone=external --add-masquerade --permanent

# Query masquerading
sudo firewall-cmd --query-masquerade
sudo firewall-cmd --zone=external --query-masquerade

# Remove masquerading
sudo firewall-cmd --remove-masquerade --permanent

# Rich rule with masquerade
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" masquerade' --permanent

NAT Configuration

# Source NAT
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" destination address="0.0.0.0/0" masquerade' --permanent

# Destination NAT
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080 --permanent

# Complex NAT rule
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" destination address="203.0.113.0/24" forward-port port="443" protocol="tcp" to-addr="192.168.1.200" to-port="8443"' --permanent

ICMP Types and Blocking

ICMP Management

# List ICMP types
sudo firewall-cmd --get-icmptypes

# Block ICMP type
sudo firewall-cmd --add-icmp-block=echo-request --permanent
sudo firewall-cmd --zone=public --add-icmp-block=echo-reply --permanent

# Block multiple ICMP types
sudo firewall-cmd --add-icmp-block={echo-request,echo-reply,timestamp-request} --permanent

# Remove ICMP block
sudo firewall-cmd --remove-icmp-block=echo-request --permanent

# Query ICMP block
sudo firewall-cmd --query-icmp-block=echo-request

# Invert ICMP blocks (block all except specified)
sudo firewall-cmd --add-icmp-block-inversion --permanent
sudo firewall-cmd --add-icmp-block=echo-reply --permanent

Custom ICMP Types

<!-- Create custom ICMP type -->
<icmptype>
  <short>Custom ICMP</short>
  <description>Custom ICMP Type Description</description>
  <destination ipv4="yes" ipv6="yes"/>
</icmptype>

Direct Rules

Using Direct Interface

# Add direct rule
sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPT

# Permanent direct rule
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPT

# List direct rules
sudo firewall-cmd --direct --get-all-rules

# Remove direct rule
sudo firewall-cmd --direct --remove-rule ipv4 filter INPUT 0 -p tcp --dport 9999 -j ACCEPT

# Add chain
sudo firewall-cmd --permanent --direct --add-chain ipv4 filter CUSTOM_CHAIN

# Direct passthrough
sudo firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Logging Configuration

Enable Logging

# Get log denied setting
sudo firewall-cmd --get-log-denied

# Set log denied
sudo firewall-cmd --set-log-denied=all

# Options: all, unicast, broadcast, multicast, off

# Rich rule with logging
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" log prefix="SSH_ACCESS: " level="info" accept' --permanent

# Log levels: emerg, alert, crit, error, warning, notice, info, debug

Log Analysis

# View firewall logs
sudo journalctl -u firewalld

# Follow firewall logs
sudo journalctl -f -u firewalld

# Filter by log prefix
sudo journalctl -t kernel | grep "DROPPED:"

# Create logging script
cat > /usr/local/bin/firewall-log-analyzer.sh << 'EOF'
#!/bin/bash
# Analyze firewall logs

echo "=== Firewall Log Analysis ==="
echo "Top 10 Blocked IPs:"
journalctl -t kernel | grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn | head -10

echo -e "\nTop 10 Blocked Ports:"
journalctl -t kernel | grep -oP 'DPT=\K[0-9]+' | sort | uniq -c | sort -rn | head -10

echo -e "\nRecent Dropped Packets:"
journalctl -t kernel | grep "DROPPED:" | tail -20
EOF

chmod +x /usr/local/bin/firewall-log-analyzer.sh

Panic Mode and Lockdown

Panic Mode

# Enable panic mode (blocks all traffic)
sudo firewall-cmd --panic-on

# Disable panic mode
sudo firewall-cmd --panic-off

# Query panic mode
sudo firewall-cmd --query-panic

Lockdown Mode

# Enable lockdown
sudo firewall-cmd --lockdown-on

# Disable lockdown
sudo firewall-cmd --lockdown-off

# Query lockdown
sudo firewall-cmd --query-lockdown

# Configure lockdown whitelist
sudo vim /etc/firewalld/lockdown-whitelist.xml
<?xml version="1.0" encoding="utf-8"?>
<whitelist>
  <command name="/usr/bin/python3 /usr/bin/firewall-cmd*"/>
  <user name="root"/>
  <user id="0"/>
</whitelist>

Runtime vs Permanent Configuration

Configuration Management

# Runtime changes (immediate but not persistent)
sudo firewall-cmd --add-service=http

# Permanent changes (persistent but requires reload)
sudo firewall-cmd --add-service=http --permanent

# Apply permanent configuration
sudo firewall-cmd --reload

# Runtime to permanent
sudo firewall-cmd --runtime-to-permanent

# Check configuration differences
sudo firewall-cmd --list-all
sudo firewall-cmd --list-all --permanent

Backup and Restore

# Backup firewall configuration
sudo cp -r /etc/firewalld /etc/firewalld.backup.$(date +%Y%m%d)

# Export zone configuration
sudo firewall-cmd --zone=public --list-all > public-zone.txt

# Create complete backup script
cat > /usr/local/bin/firewall-backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/var/backups/firewalld"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# Backup all configuration
tar -czf $BACKUP_DIR/firewalld_backup_$DATE.tar.gz /etc/firewalld

# Export current rules
firewall-cmd --list-all-zones > $BACKUP_DIR/all_zones_$DATE.txt
firewall-cmd --direct --get-all-rules > $BACKUP_DIR/direct_rules_$DATE.txt
firewall-cmd --get-ipsets > $BACKUP_DIR/ipsets_$DATE.txt

echo "Firewall backup completed: $BACKUP_DIR/firewalld_backup_$DATE.tar.gz"
EOF

chmod +x /usr/local/bin/firewall-backup.sh

Security Best Practices

Zone Security Strategy

# Create DMZ configuration
sudo firewall-cmd --zone=dmz --add-service=http --permanent
sudo firewall-cmd --zone=dmz --add-service=https --permanent
sudo firewall-cmd --zone=dmz --add-interface=eth2 --permanent

# Configure internal zone
sudo firewall-cmd --zone=internal --add-service=ssh --permanent
sudo firewall-cmd --zone=internal --add-service=cockpit --permanent
sudo firewall-cmd --zone=internal --add-source=192.168.1.0/24 --permanent

# Restrict public zone
sudo firewall-cmd --zone=public --remove-service=ssh --permanent
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" service name="ssh" accept' --permanent

Rate Limiting

# SSH rate limiting
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="ssh" limit value="3/m" accept' --permanent

# HTTP rate limiting
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="http" limit value="100/s" accept' --permanent

# Connection limiting
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="80" protocol="tcp" limit value="20/m" accept' --permanent

Security Hardening Script

cat > /usr/local/bin/firewall-harden.sh << 'EOF'
#!/bin/bash
# Firewall hardening script

echo "Applying firewall hardening..."

# Set default zone to drop
firewall-cmd --set-default-zone=drop

# Configure zones
firewall-cmd --zone=drop --set-target=DROP --permanent
firewall-cmd --zone=public --set-target=default --permanent

# Remove unnecessary services
for service in dhcpv6-client mdns samba-client; do
    firewall-cmd --zone=public --remove-service=$service --permanent
done

# Add rate limiting for SSH
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="ssh" limit value="5/m" accept' --permanent

# Block common attack ports
for port in 23 135 137 138 139 445 1433 3389; do
    firewall-cmd --zone=public --add-rich-rule="rule family='ipv4' port port='$port' protocol='tcp' reject" --permanent
done

# Enable logging for dropped packets
firewall-cmd --set-log-denied=all

# Block ICMP timestamp requests
firewall-cmd --zone=public --add-icmp-block=timestamp-request --permanent
firewall-cmd --zone=public --add-icmp-block=timestamp-reply --permanent

# Reload configuration
firewall-cmd --reload

echo "Firewall hardening completed"
EOF

chmod +x /usr/local/bin/firewall-harden.sh

Integration with Services

SELinux Integration

# Check SELinux context for firewalld
ls -Z /usr/sbin/firewalld

# Allow firewalld to modify files
sudo setsebool -P firewalld_can_network_connect on

# Check for SELinux denials
sudo ausearch -m avc -ts recent | grep firewalld

systemd Integration

# Create service-specific firewall rules
cat > /etc/systemd/system/myapp-firewall.service << 'EOF'
[Unit]
Description=Configure firewall for MyApp
After=firewalld.service
Requires=firewalld.service

[Service]
Type=oneshot
ExecStart=/usr/bin/firewall-cmd --zone=public --add-port=8080/tcp
ExecStop=/usr/bin/firewall-cmd --zone=public --remove-port=8080/tcp
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable myapp-firewall.service

Troubleshooting

Common Issues

# Check firewalld status
sudo systemctl status firewalld
sudo firewall-cmd --state

# Verify no conflicts
sudo systemctl status iptables
sudo systemctl status nftables

# Check for errors
sudo journalctl -u firewalld -p err

# Debug mode
sudo firewall-cmd --debug=10

# Verify rules are applied
sudo iptables -L -n -v
sudo ip6tables -L -n -v

# Check direct rules
sudo firewall-cmd --direct --get-all-rules

# Reload with error checking
sudo firewall-cmd --reload --debug=2

Recovery Procedures

# Reset to defaults
sudo rm -rf /etc/firewalld/zones/
sudo rm -rf /etc/firewalld/services/
sudo firewall-cmd --reload

# Emergency access
# Boot with kernel parameter: systemd.unit=emergency.target
# Then:
systemctl stop firewalld
systemctl disable firewalld

# Fix configuration errors
sudo firewall-cmd --check-config

Monitoring and Reporting

Monitoring Script

cat > /usr/local/bin/firewall-monitor.sh << 'EOF'
#!/bin/bash
# Firewall monitoring script

LOGFILE="/var/log/firewall-monitor.log"

echo "=== Firewall Status Report - $(date) ===" | tee -a $LOGFILE

# Check service status
echo -e "\n[Service Status]" | tee -a $LOGFILE
systemctl is-active firewalld | tee -a $LOGFILE

# Active zones
echo -e "\n[Active Zones]" | tee -a $LOGFILE
firewall-cmd --get-active-zones | tee -a $LOGFILE

# Open services and ports
echo -e "\n[Open Services]" | tee -a $LOGFILE
firewall-cmd --list-services | tee -a $LOGFILE

echo -e "\n[Open Ports]" | tee -a $LOGFILE
firewall-cmd --list-ports | tee -a $LOGFILE

# Rich rules
echo -e "\n[Rich Rules]" | tee -a $LOGFILE
firewall-cmd --list-rich-rules | tee -a $LOGFILE

# Recent blocks
echo -e "\n[Recent Blocked Connections]" | tee -a $LOGFILE
journalctl -u firewalld --since "1 hour ago" | grep -i "REJECT\|DROP" | tail -10 | tee -a $LOGFILE

# Connection statistics
echo -e "\n[Connection Statistics]" | tee -a $LOGFILE
ss -s | tee -a $LOGFILE
EOF

chmod +x /usr/local/bin/firewall-monitor.sh

# Add to crontab
echo "0 * * * * /usr/local/bin/firewall-monitor.sh" | crontab -

Performance Optimization

# Optimize rule order
# Place most-used rules first in rich rules

# Use ipsets for large lists
sudo firewall-cmd --permanent --new-ipset=large_list --type=hash:net
sudo firewall-cmd --permanent --ipset=large_list --add-entries-from-file=/etc/firewalld/ipsets/large_list.txt

# Minimize logging overhead
sudo firewall-cmd --set-log-denied=unicast

# Use direct rules for performance-critical paths
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

GUI Management

Using firewall-config

# Install GUI tool
sudo dnf install -y firewall-config

# Launch GUI (requires X11)
firewall-config

# Remote GUI access
ssh -X user@server
firewall-config

Web-based Management

# Cockpit integration
sudo dnf install -y cockpit
sudo systemctl enable --now cockpit.socket
sudo firewall-cmd --add-service=cockpit --permanent
sudo firewall-cmd --reload

# Access at https://server:9090

Automation and Scripting

Ansible Integration

---
- name: Configure firewalld
  hosts: almalinux
  tasks:
    - name: Ensure firewalld is running
      systemd:
        name: firewalld
        state: started
        enabled: yes

    - name: Configure firewalld zones
      firewalld:
        zone: public
        service: "{{ item }}"
        permanent: yes
        state: enabled
      loop:
        - http
        - https
        - ssh

    - name: Add rich rule
      firewalld:
        rich_rule: 'rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
        zone: public
        permanent: yes
        state: enabled

    - name: Reload firewalld
      systemd:
        name: firewalld
        state: reloaded

Automated Configuration Script

#!/bin/bash
# Automated firewall configuration

configure_firewall() {
    local zone=$1
    local services=$2
    local ports=$3
    
    # Add services
    IFS=',' read -ra SERVICE_ARRAY <<< "$services"
    for service in "${SERVICE_ARRAY[@]}"; do
        firewall-cmd --zone=$zone --add-service=$service --permanent
    done
    
    # Add ports
    IFS=',' read -ra PORT_ARRAY <<< "$ports"
    for port in "${PORT_ARRAY[@]}"; do
        firewall-cmd --zone=$zone --add-port=$port --permanent
    done
    
    firewall-cmd --reload
}

# Usage
configure_firewall "public" "http,https,ssh" "8080/tcp,9090/tcp"

Conclusion

Firewalld provides a powerful and flexible firewall management system for AlmaLinux, offering dynamic configuration, zone-based security, and rich rule capabilities. By mastering firewalld’s features—from basic zone management to advanced rich rules and automation—administrators can implement robust network security policies that protect systems while maintaining necessary connectivity.

Key takeaways:

  • Use zones to implement security boundaries
  • Leverage rich rules for complex requirements
  • Implement rate limiting for DDoS protection
  • Regular monitoring and backup of configurations
  • Integrate firewalld with system services and automation tools

With proper configuration and management, firewalld serves as an essential component of a comprehensive security strategy for AlmaLinux systems.