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

May 7, 2025 - 07:44
 0
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:

  1. Create a filter file:
sudo nano /etc/fail2ban/filter.d/myapp.conf
  1. Define the regex pattern to match log entries:
[Definition]
failregex = ^.* authentication failure for .* from $
            ^.* Failed login from $
ignoreregex =
  1. 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

  1. Test Before Deploying: Configure your firewall on a test system before applying to production.

  2. Regular Audits: Periodically review your rules and banned IPs.

  3. Update Frequently: Keep UFW and fail2ban updated with security patches.

  4. Layered Security: Remember that firewalls are just one layer of your security strategy.

  5. Backup Configurations: Keep backups of working configurations.

  6. 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