Files
ubuntu-post-install/CADDY-FAIL2BAN-SETUP.md
T
Claude 7cf82d5d28 Add no-keycloak and CrowdSec script variants; restore originals
Provide three tiers of the install script for both 24.04 and 26.04:

- Originals (ubuntu-post-install-24.04.sh / -26.04.sh): restored to their
  true original state, with Keycloak intact, as a fallback baseline. (This
  reverts the in-place Keycloak removal from the previous commit; the cleanup
  now lives in the -no-keycloak variants instead.)
- -no-keycloak.sh: Keycloak fully removed, Authelia as the SSO/2FA option.
- -crowdsec.sh: builds on -no-keycloak and replaces fail2ban entirely with
  CrowdSec (SSH via auth.log/sshd collection, Caddy via caddy collection + log
  acquisition, firewall bouncer for enforcement, plus geo-blocking and
  community IP-reputation blocklists).

Add SCRIPT-VARIANTS.md documenting the three tiers and how the Authelia /
fail2ban / CrowdSec security layers differ.

All variants pass 'bash -n'.

https://claude.ai/code/session_017eA2qqq9jfF2tNtpUYL8vK
2026-06-03 11:34:43 +00:00

8.0 KiB

Caddy with Fail2ban Setup Guide

This guide helps you integrate new services with an existing Caddy reverse proxy and set up fail2ban protection.

Quick Start

For servers with Caddy already installed:

# Run the automated helper script
./caddy-setup-helper.sh

This script will:

  • Detect your Caddy installation
  • Locate and backup your Caddyfile
  • Check for fail2ban configuration
  • Provide examples for adding new services

Manual Setup

1. Backup Your Caddyfile

IMPORTANT: Always backup before making changes!

# Find your Caddyfile location
CADDYFILE=~/docker/caddy/Caddyfile  # Adjust path as needed

# Create backup directory
mkdir -p $(dirname "$CADDYFILE")/backups

# Backup with timestamp
cp "$CADDYFILE" "$(dirname "$CADDYFILE")/backups/Caddyfile.backup.$(date +%Y%m%d_%H%M%S)"

2. Add New Services to Caddy

Add these blocks to your Caddyfile:

ActualBudget (Personal Finance)

budget.yourdomain.com {
    log {
        output file /var/log/caddy/actualbudget-access.log
        format json
        level INFO
    }

    reverse_proxy localhost:5006

    # Security headers
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
        X-XSS-Protection "1; mode=block"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}

Keycloak (Identity & Access Management)

auth.yourdomain.com {
    log {
        output file /var/log/caddy/keycloak-access.log
        format json
        level INFO
    }

    reverse_proxy localhost:8180

    # Security headers
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Frame-Options "SAMEORIGIN"
        X-Content-Type-Options "nosniff"
        X-XSS-Protection "1; mode=block"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}

3. Reload Caddy Configuration

After editing the Caddyfile:

# Format the Caddyfile (optional but recommended)
docker exec -w /etc/caddy caddy caddy fmt --overwrite

# Reload Caddy configuration
docker exec -w /etc/caddy caddy caddy reload

If you get errors, check Caddy logs:

docker logs caddy

4. Restore from Backup (if needed)

If something goes wrong:

# Find your backup
ls -lah ~/docker/caddy/backups/

# Restore the backup
cp ~/docker/caddy/backups/Caddyfile.backup.YYYYMMDD_HHMMSS ~/docker/caddy/Caddyfile

# Reload Caddy
docker exec -w /etc/caddy caddy caddy reload
docker exec -w /etc/caddy caddy caddy fmt --overwrite

Fail2ban Configuration

Prerequisites

  1. Enable JSON logging in Caddy (shown in examples above)
  2. Install fail2ban on the host:
    sudo apt update
    sudo apt install fail2ban -y
    

Installation Steps

Step 1: Install Fail2ban Filter

# Copy the filter configuration
sudo cp fail2ban-caddy-filter.conf /etc/fail2ban/filter.d/caddy-auth.conf

Or create it manually:

sudo tee /etc/fail2ban/filter.d/caddy-auth.conf > /dev/null <<'EOF'
[Definition]
failregex = ^.*"remote_ip":"<HOST>".*"status":(?:401|403|429).*$
            ^.*"remote_addr":"<HOST>.*"status":(?:401|403|429).*$
ignoreregex = ^.*"remote_ip":"(?:127\.0\.0\.1|::1)".*$
datepattern = "ts":%%s
EOF

Step 2: Install Fail2ban Jail

# Copy the jail configuration
sudo cp fail2ban-caddy-jail.conf /etc/fail2ban/jail.d/caddy.conf

Or create it manually:

sudo tee /etc/fail2ban/jail.d/caddy.conf > /dev/null <<'EOF'
[caddy-auth]
enabled = true
port = http,https
filter = caddy-auth
logpath = /var/log/caddy/access.log
          /var/log/caddy/*-access.log
maxretry = 5
findtime = 600
bantime = 3600
action = iptables-multiport[name=CaddyAuth, port="http,https", protocol=tcp]
backend = auto
EOF

Step 3: Create Log Directory

# Create log directory if using Docker Caddy
sudo mkdir -p /var/log/caddy
sudo chmod 755 /var/log/caddy

# If Caddy runs as specific user:
# sudo chown caddy:caddy /var/log/caddy

Step 4: Update Caddy Docker Compose

Add log volume to your Caddy docker-compose.yml:

services:
  caddy:
    image: caddy:latest
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./data:/data
      - ./config:/config
      - /var/log/caddy:/var/log/caddy  # Add this line

Then restart Caddy:

cd ~/docker/caddy
docker compose down
docker compose up -d

Step 5: Restart Fail2ban

sudo systemctl restart fail2ban
sudo systemctl status fail2ban

Testing Fail2ban

# Check if jail is running
sudo fail2ban-client status caddy-auth

# Test the filter against your logs
sudo fail2ban-regex /var/log/caddy/access.log /etc/fail2ban/filter.d/caddy-auth.conf

# View banned IPs
sudo fail2ban-client get caddy-auth banip

# Manually ban/unban an IP (for testing)
sudo fail2ban-client set caddy-auth banip 1.2.3.4
sudo fail2ban-client set caddy-auth unbanip 1.2.3.4

Troubleshooting

Fail2ban not detecting attacks

  1. Check log format:

    tail -f /var/log/caddy/access.log
    

    Ensure it's JSON format with remote_ip or remote_addr field.

  2. Test filter manually:

    sudo fail2ban-regex /var/log/caddy/access.log /etc/fail2ban/filter.d/caddy-auth.conf --print-all-matched
    
  3. Check fail2ban logs:

    sudo tail -f /var/log/fail2ban.log
    

Caddy configuration errors

  1. Validate Caddyfile:

    docker exec caddy caddy validate --config /etc/caddy/Caddyfile
    
  2. Check Caddy logs:

    docker logs caddy --tail 50
    

Advanced Configuration

Aggressive Fail2ban Settings

For tighter security:

[caddy-auth]
maxretry = 3       # Ban after 3 attempts (instead of 5)
findtime = 300     # Within 5 minutes (instead of 10)
bantime = 86400    # Ban for 24 hours (instead of 1)

Ban Time Increment

Ban repeat offenders for longer:

[caddy-auth]
bantime.increment = true
bantime.factor = 24
bantime.maxtime = 604800  # Maximum 1 week ban

Email Notifications

Get notified when IPs are banned:

[caddy-auth]
action = iptables-multiport[name=CaddyAuth, port="http,https", protocol=tcp]
         sendmail-whois[name=CaddyAuth, dest=admin@yourdomain.com]

Per-Service Jails

Create separate jails for different services:

[caddy-actualbudget]
enabled = true
port = http,https
filter = caddy-auth
logpath = /var/log/caddy/actualbudget-access.log
maxretry = 3
bantime = 7200

[caddy-keycloak]
enabled = true
port = http,https
filter = caddy-auth
logpath = /var/log/caddy/keycloak-access.log
maxretry = 5
bantime = 3600

Best Practices

  1. Always backup before changes
  2. Test configuration before reloading (caddy validate)
  3. Monitor fail2ban logs initially to tune settings
  4. Use strong passwords for admin interfaces
  5. Keep services updated (docker compose pull && docker compose up -d)
  6. Regular backups of configuration and data
  7. Use HTTPS via Caddy for all services
  8. Implement rate limiting in Caddy for API endpoints

Quick Reference

Common Commands

# Caddy
docker exec -w /etc/caddy caddy caddy reload
docker exec -w /etc/caddy caddy caddy fmt --overwrite
docker exec caddy caddy validate --config /etc/caddy/Caddyfile
docker logs caddy --tail 50

# Fail2ban
sudo systemctl restart fail2ban
sudo fail2ban-client status caddy-auth
sudo fail2ban-client set caddy-auth unbanip 1.2.3.4
sudo tail -f /var/log/fail2ban.log

# Backup
cp ~/docker/caddy/Caddyfile ~/docker/caddy/Caddyfile.backup

Service Ports

  • ActualBudget: 5006
  • Keycloak: 8180
  • Caddy: 80 (HTTP), 443 (HTTPS)

Support

For issues: