Implement network security policies with iptables and firewalld for enterprise infrastructure protection

Intermediate 45 min Apr 29, 2026 64 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure enterprise-grade network security with iptables and firewalld, implementing zone-based policies, advanced rules, and comprehensive logging for production infrastructure protection.

Prerequisites

  • Root or sudo access
  • Basic understanding of networking concepts
  • Active network interface

What this solves

Enterprise networks require robust security policies to protect against threats, control traffic flow, and maintain compliance standards. This tutorial shows you how to implement comprehensive network security using both iptables (the traditional Linux firewall) and firewalld (the modern zone-based firewall manager) to create layered defense mechanisms for your infrastructure.

Step-by-step installation

Update system packages

Start by updating your system to ensure you have the latest security patches and package versions.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install iptables and firewalld

Install both firewall systems. Most distributions include iptables by default, but we'll ensure both tools are available.

sudo apt install -y iptables iptables-persistent firewalld
sudo dnf install -y iptables-services firewalld

Configure firewalld as primary firewall

Enable firewalld and ensure it starts automatically. Firewalld will manage iptables rules dynamically.

sudo systemctl stop ufw 2>/dev/null || true
sudo systemctl disable ufw 2>/dev/null || true
sudo systemctl enable --now firewalld
sudo systemctl status firewalld

Configure zone-based security policies

Review default zones

Firewalld uses zones to define trust levels for network connections. Review available zones and their current configuration.

sudo firewall-cmd --get-zones
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all

Create custom enterprise zones

Create specific zones for different network segments in your enterprise infrastructure.

sudo firewall-cmd --permanent --new-zone=dmz-servers
sudo firewall-cmd --permanent --new-zone=internal-services
sudo firewall-cmd --permanent --new-zone=management
sudo firewall-cmd --reload

Configure DMZ zone for web servers

Set up the DMZ zone for publicly accessible services with restricted access.

sudo firewall-cmd --permanent --zone=dmz-servers --set-description="DMZ zone for public-facing servers"
sudo firewall-cmd --permanent --zone=dmz-servers --add-service=http
sudo firewall-cmd --permanent --zone=dmz-servers --add-service=https
sudo firewall-cmd --permanent --zone=dmz-servers --add-service=ssh
sudo firewall-cmd --permanent --zone=dmz-servers --add-port=8080/tcp
sudo firewall-cmd --permanent --zone=dmz-servers --set-target=default

Configure internal services zone

Create a zone for internal services that should only be accessible from trusted networks.

sudo firewall-cmd --permanent --zone=internal-services --set-description="Internal services zone"
sudo firewall-cmd --permanent --zone=internal-services --add-source=10.0.0.0/8
sudo firewall-cmd --permanent --zone=internal-services --add-source=172.16.0.0/12
sudo firewall-cmd --permanent --zone=internal-services --add-source=192.168.0.0/16
sudo firewall-cmd --permanent --zone=internal-services --add-service=mysql
sudo firewall-cmd --permanent --zone=internal-services --add-service=postgresql
sudo firewall-cmd --permanent --zone=internal-services --add-port=6379/tcp
sudo firewall-cmd --permanent --zone=internal-services --add-port=9200/tcp

Configure management zone

Set up a highly restricted zone for management interfaces and administrative access.

sudo firewall-cmd --permanent --zone=management --set-description="Management and monitoring zone"
sudo firewall-cmd --permanent --zone=management --add-source=203.0.113.0/24
sudo firewall-cmd --permanent --zone=management --add-service=ssh
sudo firewall-cmd --permanent --zone=management --add-port=3000/tcp
sudo firewall-cmd --permanent --zone=management --add-port=9090/tcp
sudo firewall-cmd --permanent --zone=management --add-port=9093/tcp
sudo firewall-cmd --permanent --zone=management --set-target=DROP

Implement advanced firewall rules

Create rate limiting rules

Implement connection rate limiting to prevent DDoS attacks and brute force attempts.

sudo firewall-cmd --permanent --zone=dmz-servers --add-rich-rule='rule service name="ssh" accept limit value="5/m"'
sudo firewall-cmd --permanent --zone=dmz-servers --add-rich-rule='rule service name="http" accept limit value="100/s"'
sudo firewall-cmd --permanent --zone=dmz-servers --add-rich-rule='rule service name="https" accept limit value="100/s"'

Configure geo-blocking rules

Block traffic from specific countries or regions using IP ranges. This example blocks a range often associated with attacks.

sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" reject'
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" accept'

Implement port knocking

Create a simple port knocking mechanism for enhanced SSH security.

sudo firewall-cmd --permanent --zone=public --remove-service=ssh
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule port port="12345" protocol="tcp" accept'
sudo firewall-cmd --permanent --add-service=ssh --zone=trusted

Configure application-specific rules

Create custom rules for specific applications and protocols commonly used in enterprise environments.

sudo firewall-cmd --permanent --zone=internal-services --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="5432" accept'
sudo firewall-cmd --permanent --zone=internal-services --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="mysql" accept'
sudo firewall-cmd --permanent --zone=dmz-servers --add-rich-rule='rule family="ipv4" forward-port port="80" protocol="tcp" to-port="8080" to-addr="192.168.1.100"'

Configure comprehensive logging

Enable firewalld logging

Configure detailed logging for security monitoring and compliance requirements.

sudo firewall-cmd --set-log-denied=all
sudo firewall-cmd --permanent --set-log-denied=all

Configure rsyslog for firewall logs

Set up centralized logging to collect and organize firewall events.

# Firewall logging configuration
:msg,contains,"FINAL_REJECT:" /var/log/firewall-reject.log
:msg,contains,"FINAL_ACCEPT:" /var/log/firewall-accept.log
:msg,contains,"FINAL_DROP:" /var/log/firewall-drop.log
& stop

Configure log rotation

Set up automatic log rotation to prevent disk space issues while maintaining audit trails.

/var/log/firewall-*.log {
    daily
    missingok
    rotate 365
    compress
    delaycompress
    notifempty
    create 640 root adm
    postrotate
        /bin/systemctl reload rsyslog > /dev/null 2>&1 || true
    endscript
}

Enable detailed iptables logging

Configure custom iptables chains for granular logging of specific traffic patterns.

sudo iptables -N LOG_CHAIN
sudo iptables -A LOG_CHAIN -j LOG --log-prefix="IPTABLES-CUSTOM: " --log-level 4
sudo iptables -A LOG_CHAIN -j ACCEPT
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 22 -j LOG_CHAIN

Implement monitoring and alerting

Create firewall status monitoring script

Build a monitoring script to track firewall health and rule effectiveness.

#!/bin/bash

Firewall monitoring script

LOG_FILE="/var/log/firewall-monitor.log" DATE=$(date '+%Y-%m-%d %H:%M:%S') echo "[$DATE] Starting firewall health check" >> $LOG_FILE

Check firewalld status

if systemctl is-active --quiet firewalld; then echo "[$DATE] Firewalld: ACTIVE" >> $LOG_FILE else echo "[$DATE] Firewalld: INACTIVE - ALERT" >> $LOG_FILE logger -p daemon.err "Firewall monitoring: firewalld is not active" fi

Count rejected connections in last hour

REJECT_COUNT=$(grep "$(date -d '1 hour ago' '+%b %d %H'):" /var/log/firewall-reject.log 2>/dev/null | wc -l) echo "[$DATE] Rejected connections last hour: $REJECT_COUNT" >> $LOG_FILE if [ $REJECT_COUNT -gt 1000 ]; then logger -p daemon.warning "High number of rejected connections: $REJECT_COUNT" fi

Check for configuration changes

CONFIG_HASH=$(sudo firewall-cmd --list-all-zones | sha256sum | cut -d' ' -f1) echo "[$DATE] Configuration hash: $CONFIG_HASH" >> $LOG_FILE

Set up automated monitoring

Schedule regular monitoring and make the script executable.

sudo chmod +x /opt/firewall-monitor.sh
sudo chown root:root /opt/firewall-monitor.sh
echo "/15    * /opt/firewall-monitor.sh" | sudo crontab -

Configure fail2ban integration

Integrate fail2ban with your firewall configuration for automatic threat response. For comprehensive fail2ban setup, see our fail2ban configuration guide.

sudo apt install -y fail2ban
sudo dnf install -y fail2ban

Configure fail2ban for firewalld

Set up fail2ban to work with firewalld for automated IP blocking.

[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
banaction = firewallcmd-ipset

[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 3

[nginx-req-limit]
enabled = true
filter = nginx-req-limit
action = firewallcmd-ipset[name=ReqLimit, port=http, protocol=tcp]
logpath = /var/log/nginx/error.log
findtime = 600
bantime = 7200
maxretry = 10

Apply all configurations

Reload all firewall rules and start monitoring services.

sudo firewall-cmd --reload
sudo systemctl restart rsyslog
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

Verify your setup

Test your firewall configuration and verify all components are working correctly.

# Check firewalld status and zones
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all-zones

Verify logging is working

sudo tail -f /var/log/firewall-reject.log &

Try to connect to a blocked port from another machine

You should see entries in the log

Check fail2ban status

sudo fail2ban-client status sudo fail2ban-client status sshd

Test monitoring script

sudo /opt/firewall-monitor.sh cat /var/log/firewall-monitor.log

Verify iptables rules generated by firewalld

sudo iptables -L -n -v sudo iptables -t nat -L -n -v

Advanced security hardening

Configure connection tracking

Enable advanced connection tracking for better security and performance.

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" forward-port port="80" protocol="tcp" to-port="8080" to-addr="192.168.1.100"'
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="http" accept limit value="50/s"'

Implement network segmentation

Create rules for proper network segmentation between different zones.

sudo firewall-cmd --permanent --zone=internal-services --add-rich-rule='rule family="ipv4" source address="192.168.100.0/24" destination address="192.168.200.0/24" accept'
sudo firewall-cmd --permanent --zone=dmz-servers --add-rich-rule='rule family="ipv4" source address="192.168.100.0/24" destination address="10.0.0.0/8" reject'

Configure IPv6 security

Ensure IPv6 traffic is properly controlled alongside IPv4 rules.

sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv6" source address="2001:db8::/32" service name="ssh" accept'
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv6" source address="::/0" service name="dhcpv6-client" accept'

Performance optimization

Optimize rule ordering

Order firewall rules for optimal performance, placing most common rules first.

# View current rule priorities
sudo firewall-cmd --list-rich-rules --zone=public

Add high-priority rules with specific priorities

sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule priority="100" family="ipv4" source address="192.168.1.0/24" accept' sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule priority="200" service name="ssh" accept limit value="5/m"'

Configure connection limits

Set appropriate connection limits to prevent resource exhaustion.

# Network security and performance tuning
net.netfilter.nf_conntrack_max = 262144
net.netfilter.nf_conntrack_tcp_timeout_established = 7200
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_generic_timeout = 600

Apply system optimizations

Load the network optimizations and verify they're applied.

sudo sysctl -p /etc/sysctl.d/99-network-security.conf
sudo sysctl net.netfilter.nf_conntrack_max

Backup and restore procedures

Create firewall backup script

Implement automated backup of firewall configurations for disaster recovery.

#!/bin/bash

BACKUP_DIR="/opt/firewall-backups"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="$BACKUP_DIR/firewall-backup-$DATE.tar.gz"

mkdir -p $BACKUP_DIR

Export firewalld configuration

sudo firewall-cmd --list-all-zones > $BACKUP_DIR/zones-$DATE.txt sudo cp -r /etc/firewalld $BACKUP_DIR/firewalld-$DATE

Export iptables rules

sudo iptables-save > $BACKUP_DIR/iptables-$DATE.rules sudo ip6tables-save > $BACKUP_DIR/ip6tables-$DATE.rules

Create compressed backup

cd $BACKUP_DIR sudo tar -czf $BACKUP_FILE zones-$DATE.txt firewalld-$DATE iptables-$DATE.rules ip6tables-$DATE.rules

Clean up temporary files

sudo rm -rf zones-$DATE.txt firewalld-$DATE iptables-$DATE.rules ip6tables-$DATE.rules

Keep only last 30 backups

find $BACKUP_DIR -name "firewall-backup-*.tar.gz" -type f -mtime +30 -delete echo "Backup created: $BACKUP_FILE"

Schedule automated backups

Set up daily backups of your firewall configuration.

sudo chmod +x /opt/firewall-backup.sh
sudo mkdir -p /opt/firewall-backups
echo "0 2   * /opt/firewall-backup.sh" | sudo crontab -

Integration with monitoring systems

Configure Prometheus metrics export

Set up metrics collection for integration with monitoring systems like those covered in our Prometheus and Grafana monitoring guide.

#!/bin/bash

Export firewall metrics for Prometheus

METRICS_FILE="/var/lib/prometheus/node-exporter/firewall.prom" mkdir -p $(dirname $METRICS_FILE)

Count active connections

ACTIVE_CONNECTIONS=$(ss -ant | grep ESTABLISHED | wc -l) echo "firewall_active_connections $ACTIVE_CONNECTIONS" > $METRICS_FILE

Count firewall rules

FIREWALL_RULES=$(sudo firewall-cmd --list-all-zones | grep -c "services:\|ports:\|rich rules:") echo "firewall_total_rules $FIREWALL_RULES" >> $METRICS_FILE

Count blocked IPs from fail2ban

BLOCKED_IPS=$(sudo fail2ban-client status sshd 2>/dev/null | grep "Currently banned:" | awk '{print $NF}' || echo 0) echo "firewall_blocked_ips $BLOCKED_IPS" >> $METRICS_FILE

Enable metrics collection

Schedule metrics collection for monitoring integration.

sudo chmod +x /opt/firewall-metrics.sh
echo "    * /opt/firewall-metrics.sh" | sudo crontab -

Common issues

SymptomCauseFix
Services not accessibleFirewall blocking required portssudo firewall-cmd --list-all and add missing services/ports
Firewalld won't startConflicting with iptables servicesudo systemctl stop iptables && sudo systemctl disable iptables
Rules not persistingMissing --permanent flagRe-add rules with --permanent and run firewall-cmd --reload
High CPU usageToo many connection tracking entriesIncrease net.netfilter.nf_conntrack_max in sysctl
Logs not appearingrsyslog not configured properlyCheck /etc/rsyslog.d/10-firewall.conf and restart rsyslog
Zone assignment issuesInterface not assigned to correct zonesudo firewall-cmd --change-interface=eth0 --zone=dmz-servers
Rich rules not workingSyntax errors in rule definitionValidate syntax with firewall-cmd --check-config
Never disable your firewall completely to troubleshoot connectivity issues. Instead, temporarily allow all traffic with firewall-cmd --set-default-zone=trusted, test your application, then return to proper security with firewall-cmd --set-default-zone=public and configure specific rules.

Next steps

Running this in production?

Want this handled for you? Setting up enterprise firewall policies once is manageable. Keeping them updated, monitored, and compliant across environments while responding to security incidents is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle infrastructure security hardening for businesses that depend on uptime. From initial setup to ongoing operations.