Master Linux Security Hardening: Advanced firewalld Rules & SELinux Context Management
This guide walks you through practical Linux hardening techniques, covering firewalld's zone‑based and rich‑rule configurations, IPSET management, SELinux context fundamentals, custom policy creation, automation scripts, monitoring, common pitfalls, performance tips, and validation methods to build a multi‑layered defense.
Why Harden Linux Servers?
More than 80% of security incidents stem from misconfigurations; relying solely on basic iptables rules leaves systems vulnerable. The article shares a production‑tested hardening plan that combines firewalld and SELinux for comprehensive protection.
firewalld Advanced Rules
Core Concepts
firewalld is a dynamic firewall manager built around zones rather than static iptables chains.
# View active zones
firewall-cmd --get-active-zones
# Show default zone
firewall-cmd --get-default-zoneScenario 1 – Web Server Hardening
Expose HTTPS to the public while restricting management ports to a trusted subnet.
# Create custom zones
firewall-cmd --permanent --new-zone=webserver
firewall-cmd --permanent --new-zone=management
# Configure web zone
firewall-cmd --permanent --zone=webserver --add-service=https
firewall-cmd --permanent --zone=webserver --add-port=80/tcp
# Management zone – allow only 192.168.1.0/24
firewall-cmd --permanent --zone=management --add-source=192.168.1.0/24
firewall-cmd --permanent --zone=management --add-port=22/tcp
firewall-cmd --permanent --zone=management --add-port=3306/tcp
# Apply changes
firewall-cmd --reloadScenario 2 – Rich Rules
Rich rules handle complex policies such as rate‑limiting SSH and logging FTP rejections.
# Limit SSH connections to 3 per minute
firewall-cmd --permanent --add-rich-rule='\
rule service name="ssh" \
accept limit value="3/m"'
# Open port 8080 for a specific IP range during a time window
firewall-cmd --permanent --add-rich-rule='\
rule family="ipv4" \
source address="10.0.0.0/8" \
port protocol="tcp" port="8080" \
accept'
# Log and reject FTP attempts
firewall-cmd --permanent --add-rich-rule='\
rule service name="ftp" \
log prefix="FTP-REJECT: " level="warning" \
reject'IPSET for Large IP Collections
IPSET provides efficient storage and lookup for blacklists.
# Create an IP set named blacklist
firewall-cmd --permanent --new-ipset=blacklist --type=hash:ip
# Add malicious IPs
firewall-cmd --permanent --ipset=blacklist --add-entry=1.2.3.4
firewall-cmd --permanent --ipset=blacklist --add-entry=5.6.7.8
# Drop traffic from the set
firewall-cmd --permanent --add-rich-rule='\
rule source ipset="blacklist" \
drop'SELinux Context Management
How SELinux Works
SELinux enforces Mandatory Access Control (MAC); every process and file carries a security context label.
# Show file context
ls -Z /etc/passwd
# Example output: -rw-r--r--. root root system_u:object_r:passwd_file_t:s0 /etc/passwd
# Show process contexts for httpd
ps -eZ | grep httpdScenario 3 – Fixing Apache Home‑Directory Access
Common issue: Apache cannot serve files in user home directories.
# Check SELinux status
sestatus
# List SELinux booleans related to httpd
getsebool -a | grep httpd
# Allow Apache to read user homes
setsebool -P httpd_enable_homedirs on
# Set correct file context
semanage fcontext -a -t httpd_exec_t "/var/www/html/myapp(/.*)?"
restorecon -Rv /var/www/html/myapp/Scenario 4 – Custom Application Policy
Create a dedicated SELinux module for a self‑developed binary.
# Generate a policy template
sepolicy generate --init /usr/local/bin/myapp
# Compile and install the module
make -f /usr/share/selinux/devel/Makefile myapp.pp
semodule -i myapp.pp
# Assign the proper file type
semanage fcontext -a -t myapp_exec_t "/usr/local/bin/myapp"
restorecon /usr/local/bin/myappTroubleshooting Tips
# View recent AVC denials
ausearch -m AVC -ts recent
# Explain why denials occurred
ausearch -m AVC -ts recent | audit2why
# Generate a permissive rule (use with caution)
ausearch -m AVC -ts recent | audit2allow -M mypolicy
semodule -i mypolicy.ppProduction‑Ready Best Practices
1. Layered Defense Strategy
# Network layer – drop everything by default
firewall-cmd --set-default-zone=drop
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --permanent --zone=public --add-rich-rule='\
rule family="ipv4" \
source address="!192.168.0.0/16" \
service name="ssh" \
limit value="2/m" \
accept'
# Application layer – SELinux booleans
setsebool -P httpd_can_network_connect off
setsebool -P httpd_can_network_connect_db on2. Automated Deployment Script
#!/bin/bash
# security_harden.sh – one‑click hardening
configure_firewall() {
systemctl enable firewalld
systemctl start firewalld
firewall-cmd --set-default-zone=drop
firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --reload
echo "✅ Firewalld configured"
}
configure_selinux() {
setenforce 1
sed -i 's/SELINUX=disabled/SELINUX=enforcing/' /etc/selinux/config
setsebool -P allow_execheap off
setsebool -P allow_execstack off
echo "✅ SELinux configured"
}
configure_firewall
configure_selinux3. Monitoring & Alerting
# Create monitoring script
cat > /usr/local/bin/security_monitor.sh <<'EOF'
#!/bin/bash
# Count SELinux AVC denials today
DENIALS=$(ausearch -m AVC -ts today | wc -l)
if [ $DENIALS -gt 10 ]; then
echo "⚠️ SELinux denials exceed threshold: $DENIALS"
ausearch -m AVC -ts today | tail -5
fi
# Verify firewalld service
if ! systemctl is-active firewalld >/dev/null; then
echo "🚨 firewalld service not running!"
fi
EOF
chmod +x /usr/local/bin/security_monitor.sh
# Run every 2 hours via cron
echo "0 */2 * * * /usr/local/bin/security_monitor.sh" | crontab -Common Pitfalls
Zone Mis‑binding
# Wrong: adding service without confirming the interface’s zone
firewall-cmd --zone=public --add-service=http
# Correct: check active zones then bind interface
firewall-cmd --get-active-zones
firewall-cmd --zone=public --change-interface=eth0
firewall-cmd --zone=public --add-service=httpSELinux Context Reset
# Wrong: temporary chcon change
chcon -t httpd_exec_t /var/www/myapp
# Correct: permanent policy update
semanage fcontext -a -t httpd_exec_t /var/www/myapp
restorecon /var/www/myappPerformance Optimizations
Rule Order – place frequently matched rules first.
Use IPSET – improves lookup speed for large blacklists.
SELinux Caching – persist boolean settings with setsebool -P.
Validation
After deployment, run security scans to confirm the hardening effect.
# Nmap quick scan
nmap -sS -O target_ip
# Lynis system audit
lynis audit systemConclusion
By combining advanced firewalld rules with fine‑grained SELinux context management, a multi‑layered defense is achieved that blocks the majority of common attacks. The presented solution has been verified in production environments, but continuous review and updates remain essential for lasting security.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
