One-Command Security Hardening

#!/bin/bash
# server-security.sh — Run on fresh Ubuntu 22.04/24.04
set -euo pipefail

# === Configuration ===
NEW_USER="deploy"
SSH_PORT="22"  # Change to non-standard for security

# === 1. System Update ===
apt update && apt upgrade -y && apt autoremove -y

# === 2. Create Non-Root User ===
if ! id "$NEW_USER" &>/dev/null; then
    useradd -m -s /bin/bash "$NEW_USER"
    usermod -aG sudo "$NEW_USER"
    # Copy root SSH keys to new user
    mkdir -p /home/$NEW_USER/.ssh
    cp ~/.ssh/authorized_keys /home/$NEW_USER/.ssh/ 2>/dev/null || true
    chown -R $NEW_USER:$NEW_USER /home/$NEW_USER/.ssh
    chmod 700 /home/$NEW_USER/.ssh && chmod 600 /home/$NEW_USER/.ssh/authorized_keys
fi

# === 3. Harden SSH ===
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?Port.*/Port '"$SSH_PORT"'/' /etc/ssh/sshd_config
sed -i 's/^#\?MaxAuthTries.*/MaxAuthTries 3/' /etc/ssh/sshd_config
sed -i 's/^#\?ClientAliveInterval.*/ClientAliveInterval 300/' /etc/ssh/sshd_config
sed -i 's/^#\?ClientAliveCountMax.*/ClientAliveCountMax 2/' /etc/ssh/sshd_config
systemctl restart sshd

# === 4. Configure UFW Firewall ===
ufw default deny incoming
ufw default allow outgoing
ufw allow $SSH_PORT/tcp comment 'SSH'
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
ufw --force enable

# === 5. Install & Configure Fail2Ban ===
apt install fail2ban -y
cat > /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
port = $SSH_PORT
maxretry = 3
bantime = 3600
findtime = 600
EOF
systemctl enable --now fail2ban

# === 6. Auto-Security-Updates ===
apt install unattended-upgrades -y
cat > /etc/apt/apt.conf.d/20auto-upgrades << 'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
EOF

# === 7. Harden Kernel Parameters ===
cat >> /etc/sysctl.conf << 'EOF'
# IP Spoofing protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Ignore ICMP redirects
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# Ignore send redirects
net.ipv4.conf.all.send_redirects = 0
# Disable source packet routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
EOF
sysctl -p

echo "=== Security hardening complete! ==="
echo "User: $NEW_USER | SSH port: $SSH_PORT"
echo "Test new SSH session before closing this one."

What Each Section Does

Step Purpose
System update Latest security patches
Non-root user Principle of least privilege
SSH hardening No root login, key-only auth, rate limiting
UFW firewall Default deny, only allow SSH/HTTP/HTTPS
Fail2Ban Brute force protection, 3-attempt ban
Auto-upgrades Unattended security updates
Kernel params IP spoofing & redirect protection

Verification Commands

# Check SSH config
sshd -T | grep -E "(permitrootlogin|passwordauthentication|port)"

# Check firewall status
ufw status verbose

# Check Fail2Ban status
fail2ban-client status sshd

# Check listening ports
ss -tlnp

# Check for unauthorized users
last -10