#!/bin/sh

# Ensure the script is run as root
if [ "$(id -u)" -ne 0 ]; then
  echo "Error: This script must be run as root." >&2
  exit 1
fi

echo "--- 1. Installing Fail2ban, Rsyslog, and Iptables ---"
apk update
# iptables is required for Fail2ban's default banning actions
apk add fail2ban rsyslog iptables

echo "--- 2. Ripping out BusyBox Syslog and configuring Rsyslog ---"
# Stop and remove the default Alpine logger
rc-service syslog stop 2>/dev/null
rc-update del syslog boot 2>/dev/null

# Enable Rsyslog
rc-update add rsyslog boot

# Force Rsyslog to use the traditional date format (must be at the absolute top of the config)
sed -i '/\$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat/d' /etc/rsyslog.conf
echo '$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat' > /tmp/rsyslog-new.conf
cat /etc/rsyslog.conf >> /tmp/rsyslog-new.conf
mv /tmp/rsyslog-new.conf /etc/rsyslog.conf

# Start Rsyslog
rc-service rsyslog restart

echo "--- 3. Creating Custom SSHD Filter ---"
mkdir -p /etc/fail2ban/filter.d
# This regex ignores Alpine/rsyslog prefix bloat and hunts directly for OpenSSH 9.8+ session failures
cat << 'EOF' > /etc/fail2ban/filter.d/sshd-nuclear.conf
[Definition]
failregex = ^.*(?:sshd|sshd-session)(?:\[\d+\])?: (?:Failed password for|Invalid user) .*? from <HOST>.*$
ignoreregex = 
EOF

echo "--- 4. Configuring jail.local ---"
cat << 'EOF' > /etc/fail2ban/jail.local
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
port    = ssh
filter  = sshd-nuclear
logpath = /var/log/messages
# Force polling to prevent silent failures on Alpine
backend = polling
EOF

echo "--- 5. Enabling and Starting Fail2ban ---"
rc-update add fail2ban default
rc-service fail2ban restart

echo ""
echo "Fail2ban install complete. Check Fail2ban is now actively monitoring /var/log/messages."