#!/bin/bash
# ============================================================
# VPS Security Hardening Script — InfoKoding.com
# Kompatibel: Ubuntu 20.04+, Debian 11+
# Jalankan: sudo bash vps-hardening.sh [SSH_PORT]
# Contoh  : sudo bash vps-hardening.sh 2222
# ============================================================

set -euo pipefail

RED="\033[0;31m"; GREEN="\033[0;32m"; YELLOW="\033[0;33m"; BLUE="\033[0;34m"; NC="\033[0m"
log()  { echo -e "${GREEN}[INFO]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
err()  { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
section() { echo -e "\n${BLUE}════════════════════════════════════${NC}"; echo -e "${BLUE}  $1${NC}"; echo -e "${BLUE}════════════════════════════════════${NC}"; }

[[ $EUID -ne 0 ]] && err "Script ini harus dijalankan sebagai root. Gunakan: sudo bash $0"

SSH_PORT="${1:-22}"
section "VPS Security Hardening — InfoKoding.com"
log "Menggunakan SSH Port: $SSH_PORT"

# ── 1. Update & Upgrade ──────────────────────────────────────
section "1/7 — Update Sistem"
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get upgrade -y -qq
log "Sistem berhasil diperbarui."

# ── 2. Install Tools Keamanan ────────────────────────────────
section "2/7 — Install Tools Keamanan"
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
    fail2ban ufw unattended-upgrades apt-listchanges auditd curl wget net-tools
log "Tools keamanan berhasil diinstall."

# ── 3. Konfigurasi UFW Firewall ──────────────────────────────
section "3/7 — Konfigurasi UFW Firewall"
ufw --force reset
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
log "UFW firewall aktif. Port yang diizinkan: $SSH_PORT, 80, 443"

# ── 4. Konfigurasi Fail2Ban ──────────────────────────────────
section "4/7 — Konfigurasi Fail2Ban"
cat > /etc/fail2ban/jail.local << EOF
[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 5
backend  = systemd

[sshd]
enabled  = true
port     = $SSH_PORT
maxretry = 3
bantime  = 86400

[nginx-http-auth]
enabled  = true
port     = http,https

[nginx-limit-req]
enabled  = true
port     = http,https
EOF
systemctl enable fail2ban --quiet
systemctl restart fail2ban
log "Fail2Ban aktif. SSH jail: maxretry=3, bantime=24jam."

# ── 5. Kernel Hardening via sysctl ───────────────────────────
section "5/7 — Kernel Hardening (sysctl)"
cat > /etc/sysctl.d/99-hardening.conf << 'SYSCTL'
# IP Spoofing Protection
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable IP Forwarding
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0
# Disable ICMP Redirects (prevent MITM)
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
# SYN Flood Protection
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5
# Disable ICMP Broadcast (Smurf attack)
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Log martian packets
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# ASLR (Address Space Layout Randomization)
kernel.randomize_va_space = 2
fs.suid_dumpable = 0
SYSCTL
sysctl -p /etc/sysctl.d/99-hardening.conf -q
log "Kernel hardening parameters diterapkan."

# ── 6. Unattended Security Updates ───────────────────────────
section "6/7 — Auto Security Updates"
cat > /etc/apt/apt.conf.d/20auto-upgrades << 'APT'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
APT
dpkg-reconfigure -f noninteractive unattended-upgrades -q
log "Auto security updates aktif."

# ── 7. Aktifkan Audit Log ────────────────────────────────────
section "7/7 — Audit Log (auditd)"
systemctl enable auditd --quiet
systemctl start auditd
log "auditd aktif dan berjalan."

# ── RINGKASAN HASIL ──────────────────────────────────────────
section "✅ Hardening Selesai!"
log "Status layanan keamanan:"
for svc in ufw fail2ban auditd; do
    status=$(systemctl is-active "$svc" 2>/dev/null || echo "unknown")
    if [[ "$status" == "active" ]]; then
        echo -e "  ${GREEN}●${NC} $svc: $status"
    else
        echo -e "  ${RED}●${NC} $svc: $status"
    fi
done

echo ""
warn "═══════════════════════════════════════════════════════"
warn "  LANGKAH MANUAL YANG MASIH PERLU DILAKUKAN:"
warn "═══════════════════════════════════════════════════════"
warn "  1. Pastikan SSH key sudah di-upload ke server"
warn "  2. Edit /etc/ssh/sshd_config:"
warn "       Port $SSH_PORT"
warn "       PermitRootLogin no"
warn "       PasswordAuthentication no"
warn "  3. Jalankan: systemctl restart sshd"
warn "  4. Buka terminal BARU untuk test login sebelum"
warn "     menutup session yang sekarang!"
warn "═══════════════════════════════════════════════════════"
echo ""
log "Dokumentasi lengkap: https://infokoding.com/artikel/awas-terjebak-vps-lawas-mudah-jebol-cara-kencengin-keamanan"
