User Tools

Site Tools


computing:fail2ban

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
computing:fail2ban [2026/03/22 12:42] oemb1905computing:fail2ban [2026/03/22 21:31] (current) oemb1905
Line 11: Line 11:
 ------------------------------------------- -------------------------------------------
  
-This tutorial is designed to help you install fail2ban and get a basic set of configurations in place.+This tutorial is designed to help you install fail2ban and get a basic set of configurations in place. My logic is as follows: 
 + 
 +//My defaults give a very small 1 hour punishment for first time offense of 3 violations of any jail. Repeat offenders, however, get immediate life-bans. So, the default is very tolerant and the extreme is essentially for life punishment. Using this framework, you override individual services with ''maxretry = xx'' to fit that service's tolerance level. For example, email and web services get a value of 5-10, while ssh might get 1-3. For floods, bot attacks, etc., you will also need to adjust ''findtime = yy'' to fit the interval.// 
 + 
 +You will need to change this recipe to fit your needs. At the same time, there are certain aspects in this tutorial, that are just "always best to do" kind of things, so hopefully you recognize those! Be careful, and don't f2b yourself out of your instance too many times ;)
  
   sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local   sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Line 40: Line 44:
   logpath = %(sshd_log)s   logpath = %(sshd_log)s
   backend = %(sshd_backend)s   backend = %(sshd_backend)s
-  maxretry = 1+  maxretry = 3
  
 The repeat offender, or recidivist jail, is listed under ''[recidive]'' and I give it particular attention. In a tightly controlled environment, if someone has banged once on ssh invalidly and does it again, they have no reason to bang again indefinitely. Again, in larger environments, it might not be possible to enforce maxretry = 1. The repeat offender, or recidivist jail, is listed under ''[recidive]'' and I give it particular attention. In a tightly controlled environment, if someone has banged once on ssh invalidly and does it again, they have no reason to bang again indefinitely. Again, in larger environments, it might not be possible to enforce maxretry = 1.
  
   [recidive]   [recidive]
-  enabled            = true +  enabled   = true 
-  logpath            = /var/log/fail2ban.log +  logpath   = /var/log/fail2ban.log 
-  banaction          = iptables-multiport[blocktype=DROP] +  banaction = iptables-allports[blocktype=DROP] 
-  banaction_allports = iptables-allports[blocktype=DROP] +  bantime   = 100y 
-  bantime            = 100y +  maxretry  = 1
-  maxretry           = 1+
      
 Here's an example of keeping postfix more tolerant, so that you don't get false positives on more common services while users are setting up stuff or accessing public facing resources: Here's an example of keeping postfix more tolerant, so that you don't get false positives on more common services while users are setting up stuff or accessing public facing resources:
Line 113: Line 116:
 Script, ''fail2ban-stats.sh'', which queries all jails for historical and current bans: Script, ''fail2ban-stats.sh'', which queries all jails for historical and current bans:
  
-<code bash>+<code> 
 +sudo cat > /usr/local/bin/fail2ban-stats.sh << 'EOF'
 #!/bin/bash #!/bin/bash
 # /usr/local/bin/fail2ban-stats.sh # /usr/local/bin/fail2ban-stats.sh
Line 131: Line 135:
   fi   fi
  
-  # Safer extraction without variable-length lookbehind 
   banned=$(echo "$stats" | awk '/Currently banned:/ {print $NF}' || echo 0)   banned=$(echo "$stats" | awk '/Currently banned:/ {print $NF}' || echo 0)
   failed=$(echo "$stats" | awk '/Total failed:/ {print $NF}' || echo 0)   failed=$(echo "$stats" | awk '/Total failed:/ {print $NF}' || echo 0)
   tbanned=$(echo "$stats" | awk '/Total banned:/ {print $NF}' || echo 0)   tbanned=$(echo "$stats" | awk '/Total banned:/ {print $NF}' || echo 0)
-  actions=$(echo "$stats" | awk '/Actions executed:/ {print $NF}' || echo 0)  # or "Actions taken" if your version says that+  actions=$(echo "$stats" | awk '/Actions executed:/ {print $NF}' || echo 0)  
  
   printf "%-30s | %10s | %12s | %12s | %12s\n" "$jail" "$banned" "$failed" "$tbanned" "$actions"   printf "%-30s | %10s | %12s | %12s | %12s\n" "$jail" "$banned" "$failed" "$tbanned" "$actions"
 done done
 +EOF
 +
 +sudo chmod 750 /usr/local/bin/fail2ban-stats.sh
 </code> </code>
  
 A small script that I wrote before I knew how to write systemd units that checks and restarts the service: A small script that I wrote before I knew how to write systemd units that checks and restarts the service:
  
-<code bash>+<code>
 sudo cat > /usr/local/bin/fail2ban-restart.sh << 'EOF' sudo cat > /usr/local/bin/fail2ban-restart.sh << 'EOF'
-#!/bin/sh +#!/bin/bash
-# Fail2ban auto-restart script - runs from cron or similar +
-# Created: March 2025 / 2026 +
 RESTART="/bin/systemctl restart fail2ban.service" RESTART="/bin/systemctl restart fail2ban.service"
 STATUS="/bin/systemctl status fail2ban.service" STATUS="/bin/systemctl status fail2ban.service"
 SERVICE="fail2ban.service" SERVICE="fail2ban.service"
 LOGFILE="/home/logs/fail2ban.log" LOGFILE="/home/logs/fail2ban.log"
- 
-# Check if service is dead or failed 
 if $STATUS | grep -q -E 'failed|dead|inactive'; then if $STATUS | grep -q -E 'failed|dead|inactive'; then
     echo "[$(date '+%Y-%m-%d %H:%M:%S')] Jonathan, fail2ban failed → restarting" >> "$LOGFILE"     echo "[$(date '+%Y-%m-%d %H:%M:%S')] Jonathan, fail2ban failed → restarting" >> "$LOGFILE"
Line 160: Line 161:
     $RESTART >> "$LOGFILE" 2>&1     $RESTART >> "$LOGFILE" 2>&1
     echo "----------------------------------------" >> "$LOGFILE"     echo "----------------------------------------" >> "$LOGFILE"
-     
     # Send email with the log content     # Send email with the log content
     mail -s "[fail2ban-restart] $(hostname -f) - $(date '+%Y-%m-%d %H:%M:%S')" \     mail -s "[fail2ban-restart] $(hostname -f) - $(date '+%Y-%m-%d %H:%M:%S')" \
Line 169: Line 169:
     exit 0     exit 0
 fi fi
- 
 exit 0 exit 0
 EOF EOF
- 
-# Set permissions and ownership 
 sudo chmod 750 /usr/local/bin/fail2ban-restart.sh sudo chmod 750 /usr/local/bin/fail2ban-restart.sh
 </code> </code>
  
- --- //[[alerts@haacksnetworking.org|oemb1905]] 2026/03/21 21:58//+Here is another script that sends the fail2ban-stats report to an email of one's choosing: 
 + 
 +<code> 
 +sudo cat > /usr/local/bin/fail2ban-report.sh << 'EOF' 
 +#!/bin/bash 
 +DATE=$(date +"%Y%m%d-%H:%M:%S"
 +LOG="/home/logs/fail2ban-report.log" 
 + 
 +# create log (touch is idempotent) 
 +touch "$LOG" 
 + 
 +# generate report 
 +echo "Jonathan, at $(date), your fail2ban stats for $(hostname -f) were as follows:" > "$LOG" 
 +/bin/bash /usr/local/bin/fail2ban-stats.sh >> "$LOG" 
 + 
 +#mail log 
 +mail -s "[$(hostname -f)]-fail2ban-stats-$(date)]" email@haacksnetworking.org < "$LOG" 
 +rm "$LOG" 
 +EOF 
 + 
 +mkdir -p /home/logs 
 +sudo chmod 750 /usr/local/bin/fail2ban-report.sh 
 +</code> 
 + 
 +Run it hourly: 
 + 
 +  0 * * * * /usr/bin/flock --nonblock /tmp/f2b-report.lock /bin/bash /usr/local/bin/fail2ban-report.sh > /dev/null 2>&
 + 
 +Create a custom jail for postfix floods, for example: 
 + 
 +<code> 
 +cat << 'EOF' >> /etc/fail2ban/jail.local 
 + 
 +[postfix-flood-attack] 
 +enabled  = true 
 +maxretry = 1 
 +filter   = postfix-flood-attack 
 +action   = iptables-multiport[name=postfix, port="http,https,smtp,submission,pop3,pop3s,imap,imaps,sieve", protocol=tcp] 
 +logpath  = /var/log/mail.log 
 + 
 +EOF 
 + 
 +# 2. Create the filter definition 
 +cat << 'EOF' > /etc/fail2ban/filter.d/postfix-flood-attack.conf 
 +[Definition] 
 +failregex = lost connection after AUTH from (.*)\[<HOST>\] 
 +ignoreregex = 
 +EOF 
 + 
 +# Set permissions and reload the jail 
 +chmod 750 /etc/fail2ban/jail.local /etc/fail2ban/filter.d/postfix-flood-attack.conf 
 +systemctl restart fail2ban.service 
 +</code> 
 + 
 + --- //[[alerts@haacksnetworking.org|oemb1905]] 2026/03/22 20:44//
computing/fail2ban.1774183335.txt.gz · Last modified: by oemb1905