Blocking IP Addresses with firewalld
Overview
firewalld is a dynamic firewall management tool that provides a flexible and powerful interface for managing network traffic on Linux systems. It serves as a frontend for the netfilter framework and uses iptables as its backend. One of the most common security tasks is blocking specific IP addresses to prevent unauthorized access or mitigate attacks.
Understanding firewalld Architecture
Core Components
firewalld operates on several key concepts that work together to provide comprehensive network security:
Zones: Predefined sets of rules that define the trust level of network connections. Each zone has specific rules about what traffic is allowed or denied.
Services: Predefined configurations for common network services like SSH, HTTP, HTTPS, etc.
Rich Rules: Advanced rule configurations that provide fine-grained control over network traffic.
Direct Rules: Low-level iptables rules that bypass firewalld's zone-based system.
Zone Types
| Zone | Description | Default Behavior | |------|-------------|------------------| | drop | Lowest trust level | Drops all incoming packets without reply | | block | Low trust level | Rejects all incoming connections with icmp-host-prohibited | | public | Default zone | Accepts only selected incoming connections | | external | For external networks | Masquerading enabled, limited incoming connections | | dmz | Demilitarized zone | Limited incoming connections for public services | | work | Work environment | More services accepted than public | | home | Home environment | Most services accepted | | internal | Internal networks | Most services accepted | | trusted | Highest trust level | All network connections accepted |
Installation and Basic Setup
Installing firewalld
On Red Hat-based systems:
`bash
sudo yum install firewalld
`
On Debian-based systems:
`bash
sudo apt-get install firewalld
`
Starting and Enabling firewalld
`bash
Start the firewalld service
sudo systemctl start firewalldEnable firewalld to start at boot
sudo systemctl enable firewalldCheck firewalld status
sudo systemctl status firewalld`Basic Configuration Check
`bash
Check if firewalld is running
sudo firewall-cmd --stateList all zones
sudo firewall-cmd --get-zonesGet default zone
sudo firewall-cmd --get-default-zoneList active zones
sudo firewall-cmd --get-active-zones`Methods for Blocking IP Addresses
Method 1: Using Rich Rules
Rich rules provide the most flexible approach for blocking IP addresses with detailed logging and specific conditions.
#### Blocking a Single IP Address
`bash
Block a specific IP address
sudo firewall-cmd --add-rich-rule="rule family='ipv4' source address='192.168.1.100' reject"Block with permanent configuration
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' reject"Reload firewall to apply permanent changes
sudo firewall-cmd --reload`#### Blocking IP Address with Logging
`bash
Block IP with logging
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' log prefix='BLOCKED IP: ' level='info' reject"Block IP with rate-limited logging
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' log prefix='BLOCKED IP: ' level='info' limit value='5/m' reject"`#### Blocking IP Ranges (CIDR Notation)
`bash
Block an entire subnet
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.0/24' reject"Block a larger network range
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='10.0.0.0/8' reject"`Method 2: Using Drop Zone
The drop zone automatically drops all incoming packets from assigned sources.
`bash
Add IP to drop zone
sudo firewall-cmd --zone=drop --add-source=192.168.1.100Make it permanent
sudo firewall-cmd --permanent --zone=drop --add-source=192.168.1.100Add IP range to drop zone
sudo firewall-cmd --permanent --zone=drop --add-source=192.168.1.0/24Reload configuration
sudo firewall-cmd --reload`Method 3: Using Block Zone
The block zone rejects connections and sends an ICMP reply.
`bash
Add IP to block zone
sudo firewall-cmd --zone=block --add-source=192.168.1.100Make it permanent
sudo firewall-cmd --permanent --zone=block --add-source=192.168.1.100Reload configuration
sudo firewall-cmd --reload`Method 4: Using Direct Rules
Direct rules provide low-level iptables access for complex scenarios.
`bash
Block IP using direct rule
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -s 192.168.1.100 -j DROPBlock IP range using direct rule
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -s 192.168.1.0/24 -j DROPReload configuration
sudo firewall-cmd --reload`Advanced Blocking Techniques
Time-Based Blocking
`bash
Block IP during specific hours (9 AM to 5 PM)
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' time start='09:00' stop='17:00' reject"`Port-Specific Blocking
`bash
Block IP from accessing SSH (port 22)
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port port='22' protocol='tcp' reject"Block IP from accessing HTTP and HTTPS
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port port='80' protocol='tcp' reject" sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port port='443' protocol='tcp' reject"`Protocol-Specific Blocking
`bash
Block all TCP traffic from IP
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' protocol value='tcp' reject"Block all UDP traffic from IP
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' protocol value='udp' reject"`Managing Blocked IP Addresses
Listing Blocked IPs
`bash
List all rich rules
sudo firewall-cmd --list-rich-rulesList sources in drop zone
sudo firewall-cmd --zone=drop --list-sourcesList sources in block zone
sudo firewall-cmd --zone=block --list-sourcesList all direct rules
sudo firewall-cmd --direct --get-all-rules`Removing Blocked IPs
`bash
Remove IP from rich rule
sudo firewall-cmd --permanent --remove-rich-rule="rule family='ipv4' source address='192.168.1.100' reject"Remove IP from drop zone
sudo firewall-cmd --permanent --zone=drop --remove-source=192.168.1.100Remove IP from block zone
sudo firewall-cmd --permanent --zone=block --remove-source=192.168.1.100Remove direct rule
sudo firewall-cmd --permanent --direct --remove-rule ipv4 filter INPUT 0 -s 192.168.1.100 -j DROPReload configuration
sudo firewall-cmd --reload`Command Reference Table
| Command | Description | Example |
|---------|-------------|---------|
| --add-rich-rule | Add a rich rule | firewall-cmd --add-rich-rule="rule family='ipv4' source address='1.2.3.4' reject" |
| --remove-rich-rule | Remove a rich rule | firewall-cmd --remove-rich-rule="rule family='ipv4' source address='1.2.3.4' reject" |
| --list-rich-rules | List all rich rules | firewall-cmd --list-rich-rules |
| --add-source | Add IP to zone | firewall-cmd --zone=drop --add-source=1.2.3.4 |
| --remove-source | Remove IP from zone | firewall-cmd --zone=drop --remove-source=1.2.3.4 |
| --list-sources | List sources in zone | firewall-cmd --zone=drop --list-sources |
| --permanent | Make change permanent | firewall-cmd --permanent --add-source=1.2.3.4 |
| --reload | Reload firewall configuration | firewall-cmd --reload |
| --direct --add-rule | Add direct iptables rule | firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 1.2.3.4 -j DROP |
Bulk IP Blocking
Using a Script for Multiple IPs
Create a script to block multiple IP addresses:
`bash
#!/bin/bash
bulk_block.sh
Array of IP addresses to block
IPS=( "192.168.1.100" "10.0.0.50" "172.16.1.200" "203.0.113.10" )Block each IP using rich rules
for ip in "${IPS[@]}"; do echo "Blocking IP: $ip" sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='$ip' log prefix='BLOCKED-$ip: ' level='info' reject" doneReload firewall
sudo firewall-cmd --reload echo "All IPs blocked successfully"`Blocking from File
`bash
#!/bin/bash
block_from_file.sh
Read IPs from file (one per line)
while IFS= read -r ip; do if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Blocking IP: $ip" sudo firewall-cmd --permanent --zone=drop --add-source="$ip" fi done < blocked_ips.txtsudo firewall-cmd --reload
`
Logging and Monitoring
Configuring Logging
`bash
Enable logging for dropped packets
sudo firewall-cmd --set-log-denied=allView current log setting
sudo firewall-cmd --get-log-deniedSet specific log levels
sudo firewall-cmd --set-log-denied=unicast`Monitoring Blocked Traffic
`bash
View firewall logs
sudo journalctl -u firewalld -fView kernel logs for dropped packets
sudo dmesg | grep -i "dropped"Check iptables logs
sudo tail -f /var/log/messages | grep "BLOCKED"`Performance Considerations
Optimization Strategies
| Strategy | Description | Use Case | |----------|-------------|----------| | Use zones over rich rules | Zones are processed faster | Blocking many IPs | | Limit logging | Excessive logging impacts performance | High-traffic environments | | Use CIDR notation | Block ranges instead of individual IPs | Blocking subnets | | Regular cleanup | Remove outdated rules | Maintenance |
Resource Usage
`bash
Check number of active rules
sudo iptables -L -n | wc -lMonitor firewalld memory usage
ps aux | grep firewalldCheck rule processing time
time sudo firewall-cmd --list-all`Troubleshooting
Common Issues and Solutions
| Issue | Cause | Solution |
|-------|-------|----------|
| Rules not applying | Missing --reload | Run firewall-cmd --reload |
| Can't access service | Blocked legitimate traffic | Check and adjust rules |
| High CPU usage | Too many rules/logging | Optimize rules, reduce logging |
| Rules disappear after reboot | Not made permanent | Use --permanent flag |
Debugging Commands
`bash
Check firewalld configuration
sudo firewall-cmd --list-allVerify iptables rules
sudo iptables -L -n -vCheck for syntax errors
sudo firewall-cmd --check-configView detailed zone information
sudo firewall-cmd --zone=public --list-allTest rule matching
sudo firewall-cmd --query-rich-rule="rule family='ipv4' source address='192.168.1.100' reject"`Security Best Practices
Rule Management
1. Document Changes: Keep records of all blocked IPs and reasons 2. Regular Reviews: Periodically review and clean up rules 3. Testing: Test rules in non-production environments first 4. Backup Configuration: Regular backups of firewall configuration 5. Monitoring: Implement monitoring for blocked traffic patterns
Configuration Backup
`bash
Backup current configuration
sudo cp -r /etc/firewalld /etc/firewalld.backup.$(date +%Y%m%d)Export configuration
sudo firewall-cmd --list-all-zones > firewall_config_backup.txtSave rich rules
sudo firewall-cmd --list-rich-rules > rich_rules_backup.txt`IPv6 Support
Blocking IPv6 Addresses
`bash
Block IPv6 address using rich rule
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv6' source address='2001:db8::1' reject"Block IPv6 range
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv6' source address='2001:db8::/32' reject"Add IPv6 to drop zone
sudo firewall-cmd --permanent --zone=drop --add-source=2001:db8::1`Integration with Fail2Ban
firewalld can work alongside fail2ban for automated IP blocking based on log analysis.
Fail2Ban Configuration
`bash
Install fail2ban
sudo yum install fail2banConfigure fail2ban to use firewalld
Edit /etc/fail2ban/jail.local
[DEFAULT] banaction = firewallcmd-ipset`This comprehensive guide provides the foundation for effectively blocking IP addresses using firewalld, from basic single IP blocks to advanced automated solutions with logging and monitoring capabilities.