Fail2Ban Magic: Keeping Your Django Server Safe

By Saurav Sharma

Imagine your Django server is a cozy castle. Brave knights (your users) come and go, but naughty robots (bad bots) sometimes knock repeatedly on secret doors (login pages) trying to sneak in. We need Fail2Ban, a friendly guard dog, to watch the castle logs and chase away any robot that knocks too many times!


1. What Is Fail2Ban?


2. Why Use Fail2Ban with Django?

  1. Protect the Admin Tower
    The /admin/ page is a treasure room. Don’t let robots guess passwords!
  2. Guard the Login Gate
    Your API login endpoint (/auth/login/) needs extra eyes.
  3. Stop Crawler Floods
    Bots triggering hundreds of 404 pages can overwhelm the castle.
  4. Layered Security
    Compliments your Django settings.py security (SSL redirect, HSTS, X-Frame-Options).

3. Setting Up Fail2Ban Step-by-Step

Step 3.1: Install Your Guard

sudo apt update
sudo apt install -y ufw fail2ban

Step 3.2: Configure the Drawbridge (UFW)

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH            # Let knights in via SSH
sudo ufw allow 'Nginx Full'       # Let visitors reach your website (HTTP/HTTPS)
sudo ufw enable

Step 3.3: Create the Jail Configuration

Create /etc/fail2ban/jail.local and add:

[DEFAULT]
bantime  = 3600        # Ban duration: 1 hour
findtime = 600         # Look back: 10 minutes
maxretry = 5           # After 5 bad tries, ban

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/auth.log

[django-login]
enabled  = true
port     = http,https
filter   = django-login
logpath  = /var/log/nginx/access.log

Step 3.4: Write Your Magic Spell (Filter)

Create /etc/fail2ban/filter.d/django-login.conf:

[Definition]
# Spot HTTP 401 responses on /auth/login/
failregex = ^<HOST> -.*POST /auth/login/.*" 401
ignoreregex =

This tells Fail2Ban: “Whenever you see a 401 Unauthorized on a login POST, count it!”

Step 3.5: Start the Guard Dog

sudo systemctl restart fail2ban

4. Testing Your Guard

  1. Check All Jails
    sudo fail2ban-client status
    
  2. Inspect the Django-Login Jail
    sudo fail2ban-client status django-login
    
  3. Simulate Robot Knocks
    for i in {1..6}; do
      curl -s -o /dev/null -w "%{http_code}" \
        -X POST https://your-domain.com/auth/login/ \
        -H "Content-Type: application/json" \
        -d '{"username":"bad","password":"bad"}'
    done
    
    After 5 “bad” tries, your IP should appear in the banned list!

5. Extra Security Tips


6. You Did It!

🎉 You now have a trusty Fail2Ban guard watching your Django castle. No more pesky robots breaking in! Keep learning, keep coding, and enjoy your safe server.

First published on blog.sorv.dev.