Creating a Lightweight Linux Firewall with UFW and fail2ban
As a system administrator or developer, securing your Linux server is non-negotiable. In this guide, we'll set up a robust yet lightweight firewall solution combining two powerful tools: UFW (Uncomplicated Firewall) and fail2ban. This combination provides an excellent security foundation without consuming excessive system resources. Why UFW and fail2ban? UFW (Uncomplicated Firewall) lives up to its name by simplifying iptables configuration while providing comprehensive firewall functionality. fail2ban monitors log files and temporarily bans IPs that show malicious behavior, such as repeated failed login attempts. Together, they create a powerful security layer that: Controls which services are accessible Blocks brute force attacks Prevents various network-based threats Uses minimal system resources Part 1: Setting Up UFW Installation UFW comes pre-installed on many distributions, but if you need to install it: # Ubuntu/Debian sudo apt update sudo apt install ufw # CentOS/RHEL sudo dnf install epel-release sudo dnf install ufw # Arch Linux sudo pacman -S ufw Basic Configuration Let's start with a secure baseline configuration: # Reset UFW to default settings (optional) sudo ufw reset # Set default policies sudo ufw default deny incoming sudo ufw default allow outgoing Allow Essential Services Now we'll open ports for services we want to expose: # Allow SSH (important to prevent lockout!) sudo ufw allow ssh # Example: Allow web server ports sudo ufw allow 80/tcp sudo ufw allow 443/tcp # Example: Allow specific port range sudo ufw allow 8000:8100/tcp Working with Service Names UFW can use service names instead of port numbers: # These are equivalent sudo ufw allow 22/tcp sudo ufw allow ssh You can see available service names in /etc/services. IP-Specific Rules You can restrict services to specific IP addresses: # Allow SSH only from a specific IP sudo ufw allow from 192.168.1.100 to any port 22 # Allow access from a subnet sudo ufw allow from 192.168.1.0/24 to any port 3306 Enabling UFW Once configured, enable the firewall: sudo ufw enable UFW will prompt that this may disrupt SSH connections. Type "y" to confirm. Managing UFW Some useful commands: # Check status and rules sudo ufw status verbose # Delete a rule (by number) sudo ufw status numbered sudo ufw delete 2 # Delete a rule (by specification) sudo ufw delete allow 80/tcp # Disable UFW sudo ufw disable Part 2: Setting Up fail2ban Installation # Ubuntu/Debian sudo apt install fail2ban # CentOS/RHEL sudo dnf install epel-release sudo dnf install fail2ban # Arch Linux sudo pacman -S fail2ban Configuration Create a local configuration file to override defaults: sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo nano /etc/fail2ban/jail.local Basic settings in jail.local: [DEFAULT] # Ban duration (in seconds) bantime = 10m # Time frame for detection (in seconds) findtime = 10m # Number of failures before ban maxretry = 5 # Email notifications (optional) destemail = your@email.com sender = fail2ban@example.com mta = sendmail # Action to take action = %(action_mwl)s Creating a Jail for SSH While fail2ban includes many predefined jails, we'll customize the SSH jail: sudo nano /etc/fail2ban/jail.d/sshd.local Add the following: [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 1h Starting fail2ban # Start and enable at boot sudo systemctl start fail2ban sudo systemctl enable fail2ban # Check status sudo fail2ban-client status sudo fail2ban-client status sshd Part 3: Advanced Configuration Rate Limiting with UFW You can use UFW's rate limiting to protect against DoS attacks: # Limit SSH connection attempts sudo ufw limit ssh # This allows 6 connections in 30 seconds per IP Custom fail2ban Filters Create custom filters for specific applications: Create a filter file: sudo nano /etc/fail2ban/filter.d/myapp.conf Define the regex pattern to match log entries: [Definition] failregex = ^.* authentication failure for .* from $ ^.* Failed login from $ ignoreregex = Create a jail for your custom filter: sudo nano /etc/fail2ban/jail.d/myapp.conf [myapp] enabled = true port = 8080 filter = myapp logpath = /var/log/myapp/auth.log maxretry = 5 bantime = 30m Whitelisting IPs To prevent accidentally locking yourself out: In UFW: # Always allow your IP sudo ufw allow from 192.168.1.100 In fail2ban: Edit /etc/fail2ban/jail.local: [DEFAULT] # IPs that should never be banned ignoreip = 127.0.0.1/8 ::1 192.168.1.100 Part 4: Monitoring and Maintenance Checking Banned I

As a system administrator or developer, securing your Linux server is non-negotiable. In this guide, we'll set up a robust yet lightweight firewall solution combining two powerful tools: UFW (Uncomplicated Firewall) and fail2ban. This combination provides an excellent security foundation without consuming excessive system resources.
Why UFW and fail2ban?
UFW (Uncomplicated Firewall) lives up to its name by simplifying iptables configuration while providing comprehensive firewall functionality.
fail2ban monitors log files and temporarily bans IPs that show malicious behavior, such as repeated failed login attempts.
Together, they create a powerful security layer that:
- Controls which services are accessible
- Blocks brute force attacks
- Prevents various network-based threats
- Uses minimal system resources
Part 1: Setting Up UFW
Installation
UFW comes pre-installed on many distributions, but if you need to install it:
# Ubuntu/Debian
sudo apt update
sudo apt install ufw
# CentOS/RHEL
sudo dnf install epel-release
sudo dnf install ufw
# Arch Linux
sudo pacman -S ufw
Basic Configuration
Let's start with a secure baseline configuration:
# Reset UFW to default settings (optional)
sudo ufw reset
# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing
Allow Essential Services
Now we'll open ports for services we want to expose:
# Allow SSH (important to prevent lockout!)
sudo ufw allow ssh
# Example: Allow web server ports
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Example: Allow specific port range
sudo ufw allow 8000:8100/tcp
Working with Service Names
UFW can use service names instead of port numbers:
# These are equivalent
sudo ufw allow 22/tcp
sudo ufw allow ssh
You can see available service names in /etc/services
.
IP-Specific Rules
You can restrict services to specific IP addresses:
# Allow SSH only from a specific IP
sudo ufw allow from 192.168.1.100 to any port 22
# Allow access from a subnet
sudo ufw allow from 192.168.1.0/24 to any port 3306
Enabling UFW
Once configured, enable the firewall:
sudo ufw enable
UFW will prompt that this may disrupt SSH connections. Type "y" to confirm.
Managing UFW
Some useful commands:
# Check status and rules
sudo ufw status verbose
# Delete a rule (by number)
sudo ufw status numbered
sudo ufw delete 2
# Delete a rule (by specification)
sudo ufw delete allow 80/tcp
# Disable UFW
sudo ufw disable
Part 2: Setting Up fail2ban
Installation
# Ubuntu/Debian
sudo apt install fail2ban
# CentOS/RHEL
sudo dnf install epel-release
sudo dnf install fail2ban
# Arch Linux
sudo pacman -S fail2ban
Configuration
Create a local configuration file to override defaults:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Basic settings in jail.local
:
[DEFAULT]
# Ban duration (in seconds)
bantime = 10m
# Time frame for detection (in seconds)
findtime = 10m
# Number of failures before ban
maxretry = 5
# Email notifications (optional)
destemail = your@email.com
sender = fail2ban@example.com
mta = sendmail
# Action to take
action = %(action_mwl)s
Creating a Jail for SSH
While fail2ban includes many predefined jails, we'll customize the SSH jail:
sudo nano /etc/fail2ban/jail.d/sshd.local
Add the following:
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 1h
Starting fail2ban
# Start and enable at boot
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# Check status
sudo fail2ban-client status
sudo fail2ban-client status sshd
Part 3: Advanced Configuration
Rate Limiting with UFW
You can use UFW's rate limiting to protect against DoS attacks:
# Limit SSH connection attempts
sudo ufw limit ssh
# This allows 6 connections in 30 seconds per IP
Custom fail2ban Filters
Create custom filters for specific applications:
- Create a filter file:
sudo nano /etc/fail2ban/filter.d/myapp.conf
- Define the regex pattern to match log entries:
[Definition]
failregex = ^.* authentication failure for .* from $
^.* Failed login from $
ignoreregex =
- Create a jail for your custom filter:
sudo nano /etc/fail2ban/jail.d/myapp.conf
[myapp]
enabled = true
port = 8080
filter = myapp
logpath = /var/log/myapp/auth.log
maxretry = 5
bantime = 30m
Whitelisting IPs
To prevent accidentally locking yourself out:
In UFW:
# Always allow your IP
sudo ufw allow from 192.168.1.100
In fail2ban:
Edit /etc/fail2ban/jail.local
:
[DEFAULT]
# IPs that should never be banned
ignoreip = 127.0.0.1/8 ::1 192.168.1.100
Part 4: Monitoring and Maintenance
Checking Banned IPs
# List all currently banned IPs
sudo fail2ban-client status sshd
Manually Banning/Unbanning
# Ban an IP
sudo fail2ban-client set sshd banip 192.168.1.200
# Unban an IP
sudo fail2ban-client set sshd unbanip 192.168.1.200
Log Monitoring
Monitor fail2ban actions:
sudo tail -f /var/log/fail2ban.log
Review UFW logs:
sudo grep UFW /var/log/syslog
Part 5: Best Practices
Test Before Deploying: Configure your firewall on a test system before applying to production.
Regular Audits: Periodically review your rules and banned IPs.
Update Frequently: Keep UFW and fail2ban updated with security patches.
Layered Security: Remember that firewalls are just one layer of your security strategy.
Backup Configurations: Keep backups of working configurations.
Emergency Access: Have a plan for regaining access if you're accidentally locked out.
Part 6: Troubleshooting
Common Issues
"Connection refused" after enabling UFW
Check if you've allowed the necessary ports:
sudo ufw status
fail2ban not banning IPs
Verify the log path in your jail configuration matches the actual log file location.
Locked out of SSH
If you're locked out, you'll need physical or console access to the server. Then:
# Disable UFW
sudo ufw disable
# Unban your IP in fail2ban
sudo fail2ban-client set sshd unbanip YOUR_IP
Conclusion
By combining UFW and fail2ban, you've created a lightweight yet powerful firewall solution for your Linux server. UFW provides straightforward port and service control, while fail2ban adds dynamic protection against brute force attacks.
This setup requires minimal system resources while significantly improving your server's security posture. Remember that security is an ongoing process - regularly review logs and adjust your configuration as needed.
What other security tools do you use alongside UFW and fail2ban? Let me know in the comments!
This article was published on May 7, 2025