FAIL2BAN & UFW
FAIL2BAN INSTALLATION#
# Debian/Ubuntu sudo apt install fail2ban # CentOS/RHEL sudo yum install epel-release && sudo yum install fail2ban # Start and enable sudo systemctl enable --now fail2ban
CONFIGURATION FILES#
/etc/fail2ban/jail.conf # Default config (don't edit) /etc/fail2ban/jail.local # Local overrides (create this) /etc/fail2ban/jail.d/ # Drop-in configs /etc/fail2ban/filter.d/ # Filter definitions /etc/fail2ban/action.d/ # Action definitions /var/log/fail2ban.log # Fail2ban log
BASIC CONFIGURATION#
# /etc/fail2ban/jail.local [DEFAULT] bantime = 3600 # Ban for 1 hour findtime = 600 # Look back 10 minutes maxretry = 5 # 5 attempts before ban ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24 # Email notifications destemail = admin@example.com sender = fail2ban@example.com mta = sendmail action = %(action_mwl)s
COMMON JAILS#
# SSH [sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 # Apache [apache-auth] enabled = true port = http,https filter = apache-auth logpath = /var/log/apache2/*error.log # Nginx [nginx-http-auth] enabled = true port = http,https filter = nginx-http-auth logpath = /var/log/nginx/error.log # Postfix [postfix] enabled = true port = smtp,465,submission filter = postfix logpath = /var/log/mail.log # WordPress [wordpress] enabled = true port = http,https filter = wordpress logpath = /var/log/apache2/access.log maxretry = 3
FAIL2BAN-CLIENT COMMANDS#
fail2ban-client status # Show all jails fail2ban-client status sshd # Show sshd jail status fail2ban-client set sshd banip 1.2.3.4 # Manually ban IP fail2ban-client set sshd unbanip 1.2.3.4 # Unban IP fail2ban-client reload # Reload configuration fail2ban-client restart # Restart service fail2ban-client get sshd bantime # Get ban time fail2ban-client set sshd bantime 7200 # Set ban time fail2ban-client get sshd maxretry # Get max retry fail2ban-client banned # List all banned IPs
CUSTOM FILTER#
# /etc/fail2ban/filter.d/myapp.conf
[Definition]
failregex = ^<HOST> - - \[.*\] "POST /login HTTP/.*" 401
^Authentication failure from <HOST>
ignoreregex =
# Test filter
fail2ban-regex /var/log/myapp.log /etc/fail2ban/filter.d/myapp.conf
# Use in jail
[myapp]
enabled = true
filter = myapp
logpath = /var/log/myapp.log
maxretry = 5
bantime = 3600
CUSTOM ACTION#
# /etc/fail2ban/action.d/slack-notify.conf
[Definition]
actionstart =
actionstop =
actionban = curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Banned <ip> from <name>"}' \
https://hooks.slack.com/services/YOUR/WEBHOOK/URL
actionunban =
PROGRESSIVE BANNING#
# /etc/fail2ban/jail.local [recidive] enabled = true logpath = /var/log/fail2ban.log banaction = %(banaction_allports)s bantime = 604800 # 1 week for repeat offenders findtime = 86400 # 1 day window maxretry = 3 # Banned 3 times = recidive ========================================
UFW (UNCOMPLICATED FIREWALL)#
UFW BASICS#
sudo ufw enable # Enable firewall sudo ufw disable # Disable firewall sudo ufw status # Show status sudo ufw status verbose # Detailed status sudo ufw status numbered # Show rules with numbers sudo ufw reset # Reset all rules sudo ufw reload # Reload rules
DEFAULT POLICIES#
sudo ufw default deny incoming # Block all incoming sudo ufw default allow outgoing # Allow all outgoing sudo ufw default deny routed # Block forwarded traffic
ALLOW RULES#
sudo ufw allow 22 # Allow SSH sudo ufw allow 80/tcp # Allow HTTP sudo ufw allow 443/tcp # Allow HTTPS sudo ufw allow 22/tcp # Allow SSH (TCP only) sudo ufw allow 53/udp # Allow DNS (UDP) sudo ufw allow 6000:6007/tcp # Allow port range sudo ufw allow from 192.168.1.0/24 # Allow subnet sudo ufw allow from 192.168.1.100 to any port 22 # Allow specific IP to SSH sudo ufw allow from 10.0.0.0/8 to any port 3306 # Allow internal MySQL
DENY RULES#
sudo ufw deny 23 # Deny telnet sudo ufw deny from 1.2.3.4 # Deny specific IP sudo ufw deny from 1.2.3.0/24 # Deny subnet sudo ufw deny in on eth0 to any port 80 # Deny on interface
LIMIT (RATE LIMITING)#
sudo ufw limit 22/tcp # Rate limit SSH (6 conn/30sec) sudo ufw limit 22/tcp comment 'SSH rate limit'
DELETE RULES#
sudo ufw status numbered # Show numbers first sudo ufw delete 3 # Delete rule #3 sudo ufw delete allow 80/tcp # Delete by specification
APPLICATION PROFILES#
sudo ufw app list # List available profiles sudo ufw app info 'OpenSSH' # Show profile info sudo ufw allow 'OpenSSH' # Allow by profile sudo ufw allow 'Nginx Full' # Allow Nginx HTTP+HTTPS sudo ufw allow 'Apache Full' # Allow Apache HTTP+HTTPS
LOGGING#
sudo ufw logging on # Enable logging sudo ufw logging medium # Set log level # Levels: off, low, medium, high, full # Logs go to /var/log/ufw.log
UFW + FAIL2BAN INTEGRATION#
# Fail2ban uses UFW as action # /etc/fail2ban/jail.local [DEFAULT] banaction = ufw # Or create action # /etc/fail2ban/action.d/ufw.conf [Definition] actionban = ufw insert 1 deny from <ip> to any actionunban = ufw delete deny from <ip> to any
ADVANCED UFW#
# Allow forwarding (for VPN/NAT) # Edit /etc/default/ufw DEFAULT_FORWARD_POLICY="ACCEPT" # Add NAT rules in /etc/ufw/before.rules *nat :POSTROUTING ACCEPT [0:0] -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE COMMIT # Allow specific interface sudo ufw allow in on eth1 to any port 80
TROUBLESHOOTING#
# Check iptables rules behind UFW sudo iptables -L -n -v # Check fail2ban status sudo fail2ban-client status sudo tail -f /var/log/fail2ban.log # Check if fail2ban is banning sudo fail2ban-client status sshd | grep "Banned IP" # Check UFW rules in iptables sudo iptables -L ufw-user-input -n -v
FAIL2BAN & UFW CHEATSHEET
==========================
Source: https://cheatsheet.johlem.net
FAIL2BAN INSTALLATION
---------------------
# Debian/Ubuntu
sudo apt install fail2ban
# CentOS/RHEL
sudo yum install epel-release && sudo yum install fail2ban
# Start and enable
sudo systemctl enable --now fail2ban
CONFIGURATION FILES
-------------------
/etc/fail2ban/jail.conf # Default config (don't edit)
/etc/fail2ban/jail.local # Local overrides (create this)
/etc/fail2ban/jail.d/ # Drop-in configs
/etc/fail2ban/filter.d/ # Filter definitions
/etc/fail2ban/action.d/ # Action definitions
/var/log/fail2ban.log # Fail2ban log
BASIC CONFIGURATION
-------------------
# /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600 # Ban for 1 hour
findtime = 600 # Look back 10 minutes
maxretry = 5 # 5 attempts before ban
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
# Email notifications
destemail = admin@example.com
sender = fail2ban@example.com
mta = sendmail
action = %(action_mwl)s
COMMON JAILS
-------------
# SSH
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
# Apache
[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/*error.log
# Nginx
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
# Postfix
[postfix]
enabled = true
port = smtp,465,submission
filter = postfix
logpath = /var/log/mail.log
# WordPress
[wordpress]
enabled = true
port = http,https
filter = wordpress
logpath = /var/log/apache2/access.log
maxretry = 3
FAIL2BAN-CLIENT COMMANDS
-------------------------
fail2ban-client status # Show all jails
fail2ban-client status sshd # Show sshd jail status
fail2ban-client set sshd banip 1.2.3.4 # Manually ban IP
fail2ban-client set sshd unbanip 1.2.3.4 # Unban IP
fail2ban-client reload # Reload configuration
fail2ban-client restart # Restart service
fail2ban-client get sshd bantime # Get ban time
fail2ban-client set sshd bantime 7200 # Set ban time
fail2ban-client get sshd maxretry # Get max retry
fail2ban-client banned # List all banned IPs
CUSTOM FILTER
-------------
# /etc/fail2ban/filter.d/myapp.conf
[Definition]
failregex = ^<HOST> - - \[.*\] "POST /login HTTP/.*" 401
^Authentication failure from <HOST>
ignoreregex =
# Test filter
fail2ban-regex /var/log/myapp.log /etc/fail2ban/filter.d/myapp.conf
# Use in jail
[myapp]
enabled = true
filter = myapp
logpath = /var/log/myapp.log
maxretry = 5
bantime = 3600
CUSTOM ACTION
--------------
# /etc/fail2ban/action.d/slack-notify.conf
[Definition]
actionstart =
actionstop =
actionban = curl -X POST -H 'Content-type: application/json' \
--data '{"text":"Banned <ip> from <name>"}' \
https://hooks.slack.com/services/YOUR/WEBHOOK/URL
actionunban =
PROGRESSIVE BANNING
--------------------
# /etc/fail2ban/jail.local
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime = 604800 # 1 week for repeat offenders
findtime = 86400 # 1 day window
maxretry = 3 # Banned 3 times = recidive
========================================
UFW (UNCOMPLICATED FIREWALL)
========================================
UFW BASICS
----------
sudo ufw enable # Enable firewall
sudo ufw disable # Disable firewall
sudo ufw status # Show status
sudo ufw status verbose # Detailed status
sudo ufw status numbered # Show rules with numbers
sudo ufw reset # Reset all rules
sudo ufw reload # Reload rules
DEFAULT POLICIES
----------------
sudo ufw default deny incoming # Block all incoming
sudo ufw default allow outgoing # Allow all outgoing
sudo ufw default deny routed # Block forwarded traffic
ALLOW RULES
-----------
sudo ufw allow 22 # Allow SSH
sudo ufw allow 80/tcp # Allow HTTP
sudo ufw allow 443/tcp # Allow HTTPS
sudo ufw allow 22/tcp # Allow SSH (TCP only)
sudo ufw allow 53/udp # Allow DNS (UDP)
sudo ufw allow 6000:6007/tcp # Allow port range
sudo ufw allow from 192.168.1.0/24 # Allow subnet
sudo ufw allow from 192.168.1.100 to any port 22 # Allow specific IP to SSH
sudo ufw allow from 10.0.0.0/8 to any port 3306 # Allow internal MySQL
DENY RULES
-----------
sudo ufw deny 23 # Deny telnet
sudo ufw deny from 1.2.3.4 # Deny specific IP
sudo ufw deny from 1.2.3.0/24 # Deny subnet
sudo ufw deny in on eth0 to any port 80 # Deny on interface
LIMIT (RATE LIMITING)
---------------------
sudo ufw limit 22/tcp # Rate limit SSH (6 conn/30sec)
sudo ufw limit 22/tcp comment 'SSH rate limit'
DELETE RULES
-------------
sudo ufw status numbered # Show numbers first
sudo ufw delete 3 # Delete rule #3
sudo ufw delete allow 80/tcp # Delete by specification
APPLICATION PROFILES
--------------------
sudo ufw app list # List available profiles
sudo ufw app info 'OpenSSH' # Show profile info
sudo ufw allow 'OpenSSH' # Allow by profile
sudo ufw allow 'Nginx Full' # Allow Nginx HTTP+HTTPS
sudo ufw allow 'Apache Full' # Allow Apache HTTP+HTTPS
LOGGING
-------
sudo ufw logging on # Enable logging
sudo ufw logging medium # Set log level
# Levels: off, low, medium, high, full
# Logs go to /var/log/ufw.log
UFW + FAIL2BAN INTEGRATION
----------------------------
# Fail2ban uses UFW as action
# /etc/fail2ban/jail.local
[DEFAULT]
banaction = ufw
# Or create action
# /etc/fail2ban/action.d/ufw.conf
[Definition]
actionban = ufw insert 1 deny from <ip> to any
actionunban = ufw delete deny from <ip> to any
ADVANCED UFW
-------------
# Allow forwarding (for VPN/NAT)
# Edit /etc/default/ufw
DEFAULT_FORWARD_POLICY="ACCEPT"
# Add NAT rules in /etc/ufw/before.rules
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
# Allow specific interface
sudo ufw allow in on eth1 to any port 80
TROUBLESHOOTING
---------------
# Check iptables rules behind UFW
sudo iptables -L -n -v
# Check fail2ban status
sudo fail2ban-client status
sudo tail -f /var/log/fail2ban.log
# Check if fail2ban is banning
sudo fail2ban-client status sshd | grep "Banned IP"
# Check UFW rules in iptables
sudo iptables -L ufw-user-input -n -v
Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.