Server Initial Security Hardening Script
Security Hardening
Source: 16idc
A complete server security hardening script — non-root user, SSH lockdown, UFW firewall, Fail2Ban, and auto-updates.
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