118 lines
3.5 KiB
Bash
118 lines
3.5 KiB
Bash
#!/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 ==="
|