Note: Fail2ban should be installed and configured AFTER the initial vibebin run so that Caddy and SSHPiper are already in place.
sudo apt update && sudo apt install -y fail2ban python3-systemdCreate the following configuration files:
/etc/fail2ban/filter.d/caddy-flood.conf
[Definition]
# Matches every single request from an IP regardless of success/failure
failregex = ^.*"remote_ip":"<HOST>".*$
ignoreregex =
datepattern = LongEpoch/etc/fail2ban/filter.d/caddy-auth.conf
[Definition]
# Matches the Unix epoch timestamp in Caddy's JSON logs.
datepattern = LongEpoch
# Multiple failregex lines are treated as OR.
failregex =
# Matches common authentication failures.
^.*"remote_ip":\s*"<HOST>".*"status":\s*(401|403).*$
# Matches scanners probing for common vulnerabilities/files
^.*"remote_ip":\s*"<HOST>".*"uri":\s*".*(?:/\.git|/\.env|/wp-admin|/wp-login\.php|/xmlrpc\.php).*".*$
# Matches common malicious user agents.
^.*"remote_ip":\s*"<HOST>".*"User-Agent":\s*\[\s*"(?i:sqlmap|nmap|nikto|wpscan|masscan)".*].*$
ignoreregex =/etc/fail2ban/filter.d/sshpiper.conf
[Definition]
# Matches logs from the sshpiperd service in journalctl
journalmatch = _SYSTEMD_UNIT=sshpiperd.service
# Regex for the "cannot create upstream" error format
# Captures the IP address before the colon and port number
failregex = ^.*level=error msg="cannot create upstream for <HOST>:\d+.*$
ignoreregex =/etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 10.128.31.0/24 fd42:ace5:c1f4:81db::/64
# If not using UFW firewall then comment this out
banaction = ufw
banaction_allports = ufw
[caddy-flood]
enabled = true
port = http,https
filter = caddy-flood
logpath = /var/log/caddy/access.log
findtime = 10s
maxretry = 200
bantime = 12h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 52w
[caddy-auth]
enabled = true
port = http,https
filter = caddy-auth
logpath = /var/log/caddy/access.log
findtime = 5m
maxretry = 3
bantime = 12h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 52w
[sshpiperd]
enabled = true
port = 2222
filter = sshpiper
backend = systemd
maxretry = 3
findtime = 10m
bantime = 12h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 52wNote: Adjust the
ignoreipvalues to match your Incus bridge network. You can find your network ranges with:incus network show incusbr0 | grep -E 'ipv4.address|ipv6.address'
# Create the Caddy access log file if it doesn't exist yet
# (It may not be created until after the first container is created in Vibebin)
sudo touch /var/log/caddy/access.log
sudo systemctl restart fail2ban# Check fail2ban status
sudo fail2ban-client status
# Check specific jail status
sudo fail2ban-client status sshd # Host SSH (default jail)
sudo fail2ban-client status caddy-flood # Caddy flood protection
sudo fail2ban-client status caddy-auth # Caddy auth failure protection
sudo fail2ban-client status sshpiperd # SSHPiper protection
# View banned IPs
sudo fail2ban-client get sshd banned
sudo fail2ban-client get caddy-flood banned
sudo fail2ban-client get caddy-auth banned
sudo fail2ban-client get sshpiperd banned# Unban from specific jail
sudo fail2ban-client set caddy-flood unbanip <IP_ADDRESS>
sudo fail2ban-client set caddy-auth unbanip <IP_ADDRESS>
sudo fail2ban-client set sshpiperd unbanip <IP_ADDRESS># Test caddy filters against log file
sudo fail2ban-regex /var/log/caddy/access.log /etc/fail2ban/filter.d/caddy-flood.conf
sudo fail2ban-regex /var/log/caddy/access.log /etc/fail2ban/filter.d/caddy-auth.conf
# Test sshpiper filter against journald
sudo fail2ban-regex systemd-journal /etc/fail2ban/filter.d/sshpiper.confsudo tail -f /var/log/fail2ban.log