#!/bin/bash set -e echo "=== Step 1: Add SSH authorized keys ===" mkdir -p /root/.ssh chmod 700 /root/.ssh cat > /root/.ssh/authorized_keys << 'EOF' ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICvQUpzuHN/+4xIS5dZSUY1Me7c17EhHRJdP5TkrfD39 claude@macbook ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG4TEk5EWIwLM3+/pU/H5qxZQlNUvIcxj72bYhYOZeQZ james@server ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGIhEtv7t3njNoG+mnKElR+rasMArdc8DnHON22lreT7 james@james ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK+9hJSfMkbe68VPbkRmaW/sFFmd3+QBmisJYLY+S6Cj james@forge ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5hDM45kOB8jxk+M4Kk9in9bpwZ90sSZsPBMbzJRkbF johan@thinkpad-x1 EOF chmod 600 /root/.ssh/authorized_keys echo "Keys written: $(wc -l < /root/.ssh/authorized_keys) keys" echo "" echo "=== Step 2: Harden sshd_config ===" cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S) apply_setting() { local key="$1" local value="$2" if grep -qE "^#?[[:space:]]*${key}[[:space:]]" /etc/ssh/sshd_config; then sed -i "s|^#\?[[:space:]]*${key}[[:space:]].*|${key} ${value}|" /etc/ssh/sshd_config else echo "${key} ${value}" >> /etc/ssh/sshd_config fi } apply_setting "PermitRootLogin" "yes" apply_setting "PasswordAuthentication" "yes" apply_setting "PubkeyAuthentication" "yes" apply_setting "MaxAuthTries" "3" apply_setting "LoginGraceTime" "30" apply_setting "X11Forwarding" "no" apply_setting "AllowTcpForwarding" "no" apply_setting "ClientAliveInterval" "300" apply_setting "ClientAliveCountMax" "2" grep -q "^Protocol" /etc/ssh/sshd_config || echo "# Protocol 2 (default in OpenSSH 7+, cannot be set explicitly)" >> /etc/ssh/sshd_config sshd -t && echo "sshd config syntax OK" || echo "ERROR: sshd config syntax FAILED" systemctl reload ssh || systemctl reload sshd || true echo "sshd reloaded" echo "" echo "=== Step 3: Update packages ===" apt-get update -q DEBIAN_FRONTEND=noninteractive apt-get upgrade -y -q 2>&1 | tail -5 echo "" echo "=== Step 4: Install packages ===" DEBIAN_FRONTEND=noninteractive apt-get install -y -q ufw fail2ban unattended-upgrades git 2>&1 | tail -5 echo "" echo "=== Step 5: Configure UFW ===" ufw --force reset ufw default deny incoming ufw default allow outgoing ufw allow 22/tcp comment 'SSH' ufw allow 80/tcp comment 'HTTP' ufw allow 443/tcp comment 'HTTPS vault1984' ufw --force enable echo "UFW enabled" echo "" echo "=== Step 6: Configure fail2ban ===" cat > /etc/fail2ban/jail.local << 'EOF' [DEFAULT] bantime = 3600 findtime = 600 maxretry = 5 [sshd] enabled = true port = ssh logpath = %(sshd_log)s backend = %(sshd_backend)s EOF systemctl enable fail2ban systemctl restart fail2ban echo "fail2ban configured and started" echo "" echo "=== Step 7: Unattended upgrades ===" cat > /etc/apt/apt.conf.d/20auto-upgrades << 'EOF' APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; APT::Periodic::AutocleanInterval "7"; EOF echo "Unattended upgrades enabled" echo "" echo "=== Step 8: Timezone UTC ===" timedatectl set-timezone UTC timedatectl | grep "Time zone" echo "" echo "=== Verification ===" echo "--- UFW status ---" ufw status verbose echo "" echo "--- fail2ban status ---" fail2ban-client status sshd 2>/dev/null || systemctl status fail2ban --no-pager | head -10 echo "" echo "--- SSH key fingerprints ---" ssh-keygen -l -f /root/.ssh/authorized_keys echo "" echo "--- sshd active settings ---" grep -E "^(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|MaxAuthTries|LoginGraceTime|X11Forwarding|AllowTcpForwarding|ClientAlive)" /etc/ssh/sshd_config echo "" echo "=== ALL DONE ==="