Integrate Caddy and fail2ban into main ubuntu-post-install.sh script
Users can now install and configure everything by simply running the main script. Re-running the script allows adding new services to existing installations. NEW SERVICES IN MAIN SCRIPT: CADDY WEB SERVER: - Automatic HTTPS with Let's Encrypt - Reverse proxy for all services - Creates example Caddyfile with ActualBudget and Keycloak configs - Detects existing installations (asks before reconfiguring) - Automatically backs up existing Caddyfile before changes - Pre-configured with /var/log/caddy volume for fail2ban integration - Includes HTTP/3 support FAIL2BAN INTRUSION PREVENTION: - Automated installation via apt - Creates Caddy filter for JSON logs (401, 403, 429 status codes) - Creates Caddy jail with configurable settings - Automatically creates /var/log/caddy directory - Tests configuration before restart - Verifies jail is active after restart - Shows status and useful commands FEATURES: ✅ Detects if services already exist (won't overwrite) ✅ Backs up configurations before changes ✅ Interactive prompts for all settings ✅ Validates configurations before applying ✅ Can be re-run to add services to existing setup ✅ Works alongside existing services ✅ Follows same pattern as ActualBudget/Keycloak WORKFLOW: 1. Run ubuntu-post-install.sh 2. Select services to install (ActualBudget, Keycloak, Caddy, fail2ban, etc.) 3. Script handles everything automatically 4. Re-run anytime to add more services The caddy-setup-helper.sh remains available as a standalone tool for advanced configuration, but the main script is now the primary method.
This commit is contained in:
@@ -3051,6 +3051,274 @@ KC_COMPOSE
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ---- CADDY WEB SERVER ----
|
||||||
|
echo ""
|
||||||
|
echo "┌─────────────────────────────────────────────────────────────────┐"
|
||||||
|
echo "│ CADDY - Modern Web Server & Reverse Proxy │"
|
||||||
|
echo "│ Automatic HTTPS, reverse proxy for all your services │"
|
||||||
|
echo "│ Port: 80 (HTTP), 443 (HTTPS) │"
|
||||||
|
echo "└─────────────────────────────────────────────────────────────────┘"
|
||||||
|
prompt_yn "Install Caddy reverse proxy? (y/n):" "n" INSTALL_CADDY
|
||||||
|
|
||||||
|
if [ "$INSTALL_CADDY" = "y" ] || [ "$INSTALL_CADDY" = "Y" ]; then
|
||||||
|
CADDY_DIR="$DOCKER_DIR/caddy"
|
||||||
|
|
||||||
|
# Check if Caddy is already installed
|
||||||
|
if [ -f "$CADDY_DIR/Caddyfile" ] || [ -f "$CADDY_DIR/docker-compose.yml" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "⚠ Caddy appears to be already installed at $CADDY_DIR"
|
||||||
|
prompt_yn "Do you want to reconfigure it? (y/n):" "n" RECONFIGURE_CADDY
|
||||||
|
if [ "$RECONFIGURE_CADDY" != "y" ] && [ "$RECONFIGURE_CADDY" != "Y" ]; then
|
||||||
|
echo " Skipping Caddy installation"
|
||||||
|
INSTALL_CADDY="n"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$INSTALL_CADDY" = "y" ] || [ "$INSTALL_CADDY" = "Y" ]; then
|
||||||
|
if [ "$DRY_RUN" = true ]; then
|
||||||
|
echo "[DRY-RUN] Would create $CADDY_DIR"
|
||||||
|
else
|
||||||
|
echo "Installing Caddy..."
|
||||||
|
mkdir -p "$CADDY_DIR/data" "$CADDY_DIR/config"
|
||||||
|
|
||||||
|
# Backup existing Caddyfile if it exists
|
||||||
|
if [ -f "$CADDY_DIR/Caddyfile" ]; then
|
||||||
|
mkdir -p "$CADDY_DIR/backups"
|
||||||
|
BACKUP_FILE="$CADDY_DIR/backups/Caddyfile.backup.$(date +%Y%m%d_%H%M%S)"
|
||||||
|
cp "$CADDY_DIR/Caddyfile" "$BACKUP_FILE"
|
||||||
|
echo " ✓ Backed up existing Caddyfile to: $BACKUP_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$CADDY_DIR"
|
||||||
|
|
||||||
|
cat > docker-compose.yml << 'CADDY_COMPOSE'
|
||||||
|
name: caddy
|
||||||
|
|
||||||
|
services:
|
||||||
|
caddy:
|
||||||
|
image: caddy:latest
|
||||||
|
container_name: caddy
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
- "443:443/udp" # HTTP/3
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||||
|
- ./data:/data
|
||||||
|
- ./config:/config
|
||||||
|
- /var/log/caddy:/var/log/caddy
|
||||||
|
environment:
|
||||||
|
- ACME_AGREE=true
|
||||||
|
labels:
|
||||||
|
- "io.podman.annotations.label/fail2ban.enable=true"
|
||||||
|
CADDY_COMPOSE
|
||||||
|
|
||||||
|
# Create Caddyfile if it doesn't exist
|
||||||
|
if [ ! -f "Caddyfile" ]; then
|
||||||
|
cat > Caddyfile << 'CADDYFILE'
|
||||||
|
{
|
||||||
|
# Global options
|
||||||
|
admin off
|
||||||
|
# Email for Let's Encrypt notifications
|
||||||
|
# email admin@yourdomain.com
|
||||||
|
}
|
||||||
|
|
||||||
|
# Example configuration - edit this for your services
|
||||||
|
# Uncomment and modify these examples:
|
||||||
|
|
||||||
|
# ActualBudget
|
||||||
|
# budget.yourdomain.com {
|
||||||
|
# log {
|
||||||
|
# output file /var/log/caddy/actualbudget-access.log
|
||||||
|
# format json
|
||||||
|
# level INFO
|
||||||
|
# }
|
||||||
|
# reverse_proxy localhost:5006
|
||||||
|
# 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
|
||||||
|
# auth.yourdomain.com {
|
||||||
|
# log {
|
||||||
|
# output file /var/log/caddy/keycloak-access.log
|
||||||
|
# format json
|
||||||
|
# level INFO
|
||||||
|
# }
|
||||||
|
# reverse_proxy localhost:8180
|
||||||
|
# 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"
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Add more services here...
|
||||||
|
CADDYFILE
|
||||||
|
echo " ✓ Created example Caddyfile"
|
||||||
|
else
|
||||||
|
echo " ℹ Using existing Caddyfile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " ✓ Caddy configured at $CADDY_DIR"
|
||||||
|
|
||||||
|
prompt_yn "Start Caddy now? (y/n):" "y" START_CADDY
|
||||||
|
if [ "$START_CADDY" = "y" ] || [ "$START_CADDY" = "Y" ]; then
|
||||||
|
docker compose up -d 2>/dev/null && echo " ✓ Caddy started" || echo " ⚠ Failed to start Caddy"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " Configuration file: $CADDY_DIR/Caddyfile"
|
||||||
|
echo " Edit Caddyfile to add your domains and services"
|
||||||
|
echo " Reload config: cd $CADDY_DIR && docker exec -w /etc/caddy caddy caddy reload"
|
||||||
|
echo ""
|
||||||
|
echo " ⚠ IMPORTANT: Edit the Caddyfile to configure your domains!"
|
||||||
|
echo " - Uncomment and modify the example configurations"
|
||||||
|
echo " - Add your domain names"
|
||||||
|
echo " - Configure services you want to expose"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---- FAIL2BAN ----
|
||||||
|
echo ""
|
||||||
|
echo "┌─────────────────────────────────────────────────────────────────┐"
|
||||||
|
echo "│ FAIL2BAN - Intrusion Prevention System │"
|
||||||
|
echo "│ Automatically ban IPs with failed auth attempts │"
|
||||||
|
echo "│ Protects SSH, Caddy, and other services │"
|
||||||
|
echo "└─────────────────────────────────────────────────────────────────┘"
|
||||||
|
prompt_yn "Install and configure fail2ban? (y/n):" "n" INSTALL_FAIL2BAN
|
||||||
|
|
||||||
|
if [ "$INSTALL_FAIL2BAN" = "y" ] || [ "$INSTALL_FAIL2BAN" = "Y" ]; then
|
||||||
|
if [ "$DRY_RUN" = true ]; then
|
||||||
|
echo "[DRY-RUN] Would install fail2ban"
|
||||||
|
else
|
||||||
|
echo "Installing fail2ban..."
|
||||||
|
|
||||||
|
# Check if fail2ban is already installed
|
||||||
|
if command -v fail2ban-client &> /dev/null; then
|
||||||
|
echo " ✓ fail2ban is already installed"
|
||||||
|
else
|
||||||
|
echo " Installing fail2ban package..."
|
||||||
|
if sudo apt update && sudo apt install -y fail2ban; then
|
||||||
|
echo " ✓ fail2ban installed successfully"
|
||||||
|
else
|
||||||
|
echo " ⚠ Failed to install fail2ban"
|
||||||
|
echo " You may need to install it manually: sudo apt install fail2ban"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create log directory for Caddy
|
||||||
|
if [ ! -d "/var/log/caddy" ]; then
|
||||||
|
sudo mkdir -p /var/log/caddy
|
||||||
|
sudo chmod 755 /var/log/caddy
|
||||||
|
echo " ✓ Created /var/log/caddy directory"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if Caddy filter exists
|
||||||
|
FILTER_FILE="/etc/fail2ban/filter.d/caddy-auth.conf"
|
||||||
|
if [ ! -f "$FILTER_FILE" ]; then
|
||||||
|
echo " Creating fail2ban filter for Caddy..."
|
||||||
|
|
||||||
|
FILTER_CONTENT='[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'
|
||||||
|
|
||||||
|
if echo "$FILTER_CONTENT" | sudo tee "$FILTER_FILE" > /dev/null; then
|
||||||
|
echo " ✓ Created Caddy fail2ban filter"
|
||||||
|
else
|
||||||
|
echo " ⚠ Failed to create filter - you may need to create it manually"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " ✓ Caddy fail2ban filter already exists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if Caddy jail exists
|
||||||
|
JAIL_FILE="/etc/fail2ban/jail.d/caddy.conf"
|
||||||
|
if [ ! -f "$JAIL_FILE" ]; then
|
||||||
|
echo " Creating fail2ban jail for Caddy..."
|
||||||
|
echo ""
|
||||||
|
echo " Configure fail2ban settings (press Enter for defaults):"
|
||||||
|
|
||||||
|
prompt_text " Max retries before ban:" "5" F2B_MAXRETRY
|
||||||
|
prompt_text " Find time window (seconds):" "600" F2B_FINDTIME
|
||||||
|
prompt_text " Ban duration (seconds):" "3600" F2B_BANTIME
|
||||||
|
|
||||||
|
JAIL_CONTENT="[caddy-auth]
|
||||||
|
enabled = true
|
||||||
|
port = http,https
|
||||||
|
filter = caddy-auth
|
||||||
|
logpath = /var/log/caddy/access.log
|
||||||
|
/var/log/caddy/*-access.log
|
||||||
|
maxretry = $F2B_MAXRETRY
|
||||||
|
findtime = $F2B_FINDTIME
|
||||||
|
bantime = $F2B_BANTIME
|
||||||
|
action = iptables-multiport[name=CaddyAuth, port=\"http,https\", protocol=tcp]
|
||||||
|
backend = auto"
|
||||||
|
|
||||||
|
if echo "$JAIL_CONTENT" | sudo tee "$JAIL_FILE" > /dev/null; then
|
||||||
|
echo " ✓ Created Caddy fail2ban jail"
|
||||||
|
else
|
||||||
|
echo " ⚠ Failed to create jail - you may need to create it manually"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " ✓ Caddy fail2ban jail already exists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test fail2ban configuration
|
||||||
|
echo ""
|
||||||
|
echo " Testing fail2ban configuration..."
|
||||||
|
if sudo fail2ban-client -t &> /dev/null; then
|
||||||
|
echo " ✓ fail2ban configuration is valid"
|
||||||
|
else
|
||||||
|
echo " ⚠ fail2ban configuration has errors"
|
||||||
|
echo " Check with: sudo fail2ban-client -t"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Restart fail2ban
|
||||||
|
prompt_yn "Restart fail2ban to apply changes? (y/n):" "y" RESTART_F2B
|
||||||
|
if [ "$RESTART_F2B" = "y" ] || [ "$RESTART_F2B" = "Y" ]; then
|
||||||
|
if sudo systemctl restart fail2ban; then
|
||||||
|
echo " ✓ fail2ban restarted successfully"
|
||||||
|
|
||||||
|
# Wait for fail2ban to start
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# Check jail status
|
||||||
|
if sudo fail2ban-client status caddy-auth &> /dev/null; then
|
||||||
|
echo " ✓ caddy-auth jail is active"
|
||||||
|
echo ""
|
||||||
|
sudo fail2ban-client status caddy-auth
|
||||||
|
else
|
||||||
|
echo " ⚠ caddy-auth jail is not active (may need Caddy logs to exist first)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo " ⚠ Failed to restart fail2ban"
|
||||||
|
echo " Check logs: sudo journalctl -u fail2ban -n 50"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo " Useful commands:"
|
||||||
|
echo " Check jail status: sudo fail2ban-client status caddy-auth"
|
||||||
|
echo " View banned IPs: sudo fail2ban-client get caddy-auth banip"
|
||||||
|
echo " Unban IP: sudo fail2ban-client set caddy-auth unbanip 1.2.3.4"
|
||||||
|
echo " View logs: sudo tail -f /var/log/fail2ban.log"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# ---- LYRION MUSIC SERVER ----
|
# ---- LYRION MUSIC SERVER ----
|
||||||
echo ""
|
echo ""
|
||||||
echo "┌─────────────────────────────────────────────────────────────────┐"
|
echo "┌─────────────────────────────────────────────────────────────────┐"
|
||||||
|
|||||||
Reference in New Issue
Block a user