About us Guides Projects Contacts
Админка
please wait

Firewalld is the modern dynamic firewall daemon for Linux that replaces iptables as the default firewall management tool. It provides an easier, zone-based approach to firewall configuration with runtime and permanent rule management. This guide covers configuring production server firewalls from a senior developer's perspective.

Why Firewalld

Firewalld offers significant advantages over raw iptables:

  1. Dynamic Rules: Apply changes without restarting the firewall
  2. Zone-Based: Group interfaces and sources into security zones
  3. D-Bus Interface: Programmatic access for applications
  4. Rich Rules: Human-readable syntax for complex rules
  5. Service Definitions: Predefined rules for common services

Installation

CentOS/RHEL/Fedora

# Usually preinstalled, but if needed:
sudo dnf install firewalld
# Start and enable.
sudo systemctl start firewalld
sudo systemctl enable firewalld
# Check status.
sudo firewall-cmd --state

Ubuntu/Debian

sudo apt install firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld

Understanding Zones

Firewalld uses zones to define trust levels for network connections:

ZoneDescriptionDefault Services
dropDrop all incoming, no replyNone
blockReject all incoming with messageNone
publicUntrusted networks (default)ssh, dhcpv6-client
externalFor routers with NAT masqueradingssh
dmzPublicly accessible serversssh
workWork environmentssh, dhcpv6-client
homeHome environmentssh, mdns, dhcpv6-client
internalInternal networksSame as home
trustedAll connections acceptedAll

View Zone Information

# List all zones.
sudo firewall-cmd --get-zones
# Get the default zone.
sudo firewall-cmd --get-default-zone
# Get active zones.
sudo firewall-cmd --get-active-zones
# List everything in a zone.
sudo firewall-cmd --zone=public --list-all
# List all zones with details.
sudo firewall-cmd --list-all-zones

Set Default Zone

# Change the default zone.
sudo firewall-cmd --set-default-zone=home
# Assign an interface to a zone.
sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
sudo firewall-cmd --reload

Managing Services

List and Enable Services

# List available services.
sudo firewall-cmd --get-services
# List services in a zone.
sudo firewall-cmd --zone=public --list-services
# Add service (runtime only).
sudo firewall-cmd --zone=public --add-service=http
# Add service permanently.
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload
# Remove service.
sudo firewall-cmd --zone=public --remove-service=http --permanent
sudo firewall-cmd --reload

Common Services

# Web server.
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# Database.
sudo firewall-cmd --permanent --add-service=mysql
sudo firewall-cmd --permanent --add-service=postgresql
# Mail.
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --permanent --add-service=imap
sudo firewall-cmd --permanent --add-service=imaps
# Apply all.
sudo firewall-cmd --reload

Managing Ports

Open Specific Ports

# Open port (runtime).
sudo firewall-cmd --zone=public --add-port=8080/tcp
# Open port permanently.
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
# Open port range.
sudo firewall-cmd --zone=public --add-port=5000-5100/tcp --permanent
# List open ports.
sudo firewall-cmd --zone=public --list-ports
# Remove port.
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload

UDP Ports

# DNS.
sudo firewall-cmd --permanent --add-port=53/udp
# VPN.
sudo firewall-cmd --permanent --add-port=1194/udp
# Apply.
sudo firewall-cmd --reload

Rich Rules

Rich rules provide fine-grained control:

Allow from Specific IP

# Allow all from IP.
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" accept' --permanent
# Allow a specific port from IP.
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="3306" accept' --permanent
# Allow from subnet.
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="22" accept' --permanent

Block Specific IP

# Drop all from IP.
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.50" drop' --permanent
# Reject (sends response).
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.50" reject' --permanent

Rate Limiting

# Limit SSH connections (prevent brute force).
sudo firewall-cmd --zone=public --add-rich-rule='rule service name="ssh" limit value="3/m" accept' --permanent

Logging

# Log dropped packets.
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" log prefix="Dropped: " level="info" drop' --permanent

List Rich Rules

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

Securing SSH

Best practice: Restrict SSH to trusted IPs only.

# Create a trusted zone for SSH.
sudo firewall-cmd --zone=trusted --add-service=ssh --permanent
# Add trusted IPs.
sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
sudo firewall-cmd --zone=trusted --add-source=10.20.30.40 --permanent
# Remove SSH from the public zone.
sudo firewall-cmd --zone=public --remove-service=ssh --permanent
# Apply.
sudo firewall-cmd --reload

Port Forwarding

Forward to Another Port

# Forward port 80 to 8080.
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
# Forward to another IP.
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10:toport=8080 --permanent
# Enable masquerading (required for forwarding to other hosts).
sudo firewall-cmd --zone=public --add-masquerade --permanent
sudo firewall-cmd --reload

Custom Service Definitions

Create Custom Service

# Create 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</description>
<port protocol="tcp" port="3000"/>
<port protocol="tcp" port="3001"/>
</service>
EOF
# Reload to recognize the new service.
sudo firewall-cmd --reload
# Use the service.
sudo firewall-cmd --zone=public --add-service=myapp --permanent
sudo firewall-cmd --reload

Production Server Example

Complete setup for a typical web server:

##!/bin/bash
# Secure web server firewall configuration.
# Set the default zone.
firewall-cmd --set-default-zone=public
# Remove unnecessary services.
firewall-cmd --zone=public --remove-service=dhcpv6-client --permanent
# Web services.
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --zone=public --add-service=https --permanent
# SSH from trusted IPs only.
firewall-cmd --zone=trusted --add-service=ssh --permanent
firewall-cmd --zone=trusted --add-source=10.0.0.0/8 --permanent
firewall-cmd --zone=public --remove-service=ssh --permanent
# Application ports (internal only).
firewall-cmd --zone=internal --add-port=3000/tcp --permanent # Node.js
firewall-cmd --zone=internal --add-port=6379/tcp --permanent # Redis
firewall-cmd --zone=internal --add-source=10.0.1.0/24 --permanent
# Rate-limit public web traffic.
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" service name="http" limit value="25/s" accept' --permanent
# Log dropped packets (for debugging).
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" log prefix="DROPPED: " level="warning" limit value="5/m"' --permanent
# Apply all changes.
firewall-cmd --reload
# Verify.
firewall-cmd --list-all-zones

Runtime vs Permanent

# Runtime only (lost after restart).
sudo firewall-cmd --add-service=http
# Permanent (persists after restart).
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload
# Make runtime rules permanent.
sudo firewall-cmd --runtime-to-permanent
# Reload permanent rules (discard runtime changes).
sudo firewall-cmd --reload
# Complete restart.
sudo firewall-cmd --complete-reload

Reset to Defaults

# Remove custom zone files.
sudo rm /etc/firewalld/zones/*
# Reload defaults.
sudo firewall-cmd --complete-reload

Troubleshooting

Check Logs

# View firewalld logs.
sudo journalctl -u firewalld
# View dropped packets (if logging enabled).
sudo journalctl -k | grep DROPPED

Test Connectivity

# From another machine.
nc -zv server-ip 80
nmap -p 22,80,443 server-ip

Key Takeaways

  1. Use zones: Match network trust levels to zones
  2. Permanent + reload: Always use --permanent and --reload
  3. Restrict SSH: Move SSH to trusted zone with specific sources
  4. Rich rules for precision: IP-based filtering and rate limiting
  5. Service definitions: Create reusable service files for applications
  6. Log carefully: Enable logging for dropped packets during debugging

Firewalld provides a robust, manageable firewall that balances security with usability—essential for any production Linux server.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive