Lucky Wirasakti
5 min read

Ngamanin VPS Biar Nggak Gampang Dibobol

#Security#DevOps#Linux#Self-Hosting

Beberapa post terakhir gue isinya nge-deploy terus: Caddy + 9Router, Dokploy, sampai asisten AI di Telegram. Semua itu naroh service yang kebuka ke internet. Masalahnya, begitu IP VPS lo ketauan, bot scanner langsung dateng 24 jam nyoba-nyoba login. Coba aja ssh ke server baru terus jalanin lastb, isinya ribuan percobaan login dari IP yang nggak lo kenal.

Jadi sebelum nambah service lagi, mending kunci dulu pintunya. Di post ini gue bakal bikin user non-root, pindah ke login pakai SSH key doang, pasang firewall ufw, dan tambahin fail2ban. Nggak ribet, tapi ngangkat keamanan server dari "telanjang" ke "lumayan tenang" dalam belasan menit.

Asumsinya VPS-nya Ubuntu/Debian dan lo masih login sebagai root lewat password. Kalau provider lo udah ngasih SSH key dari awal, tinggal skip bagian yang relevan.

Bikin user biasa dulu

Login sebagai root buat operasi sehari-hari itu berisiko: satu salah ketik bisa fatal, dan tiap bot di luar sana tau persis username root ada di semua server. Jadi langkah pertama, bikin user biasa yang punya hak sudo.

Masuk dulu ke VPS:

ssh root@ip-vps-lo

Bikin user baru, terus masukin ke grup sudo:

adduser lucky
usermod -aG sudo lucky

Perintah adduser bakal minta password dan beberapa info opsional (tinggal Enter aja). Sekarang tes dulu user-nya bisa pakai sudo:

su - lucky
sudo whoami   # harusnya keluar "root"

Kalau keluar root, berarti user-nya udah sah jadi admin. Jangan tutup dulu sesi root yang sekarang — biarin kebuka sebagai jaring pengaman sampai login user baru kita pastiin jalan.

Pindah ke login pakai SSH key

Password bisa ditebak, key nggak. Ini bagian paling penting. Kerjain dari laptop lo, bukan dari server.

Kalau belum punya key, generate dulu:

ssh-keygen -t ed25519 -C "lucky@laptop"

Tekan Enter buat lokasi default (~/.ssh/id_ed25519), dan isi passphrase biar key-nya tetep aman kalau laptop ilang. Habis itu, salin public key ke server:

ssh-copy-id lucky@ip-vps-lo

Sekarang coba login pakai user baru dari terminal lain:

ssh lucky@ip-vps-lo

Kalau langsung masuk tanpa diminta password, berarti key-nya udah kepasang. Ini momen yang harus dipastiin sebelum lanjut, karena langkah berikutnya bakal matiin login pakai password sepenuhnya.

Matiin login root & password

Setelah yakin bisa masuk pakai key, saatnya nutup dua jalan masuk yang paling sering dibobol: login root langsung dan login pakai password. Edit config SSH:

sudo nano /etc/ssh/sshd_config

Cari dan ubah (atau tambahin) tiga baris ini:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes

Di Ubuntu versi baru, kadang setting password-nya kesimpen di file terpisah dalam /etc/ssh/sshd_config.d/. Cek cepet biar nggak ketiban:

sudo grep -r PasswordAuthentication /etc/ssh/sshd_config.d/

Kalau ada baris PasswordAuthentication yes di situ, ubah jadi no juga — kalau nggak, dia bakal nge-override config utama. Terus reload SSH:

sudo systemctl restart ssh

Jangan logout dulu! Buka terminal baru dan coba ssh lucky@ip-vps-lo sekali lagi. Kalau masih bisa masuk, aman. Sesi lama tadi baru boleh ditutup. Aturan ini wajib tiap kali ngutak-atik SSH: selalu sisain satu sesi aktif sebagai cadangan kalau-kalau config-nya bikin lo kekunci di luar.

Pasang firewall pakai ufw

Sekarang batesin port yang kebuka. Defaultnya semua port bisa diakses, padahal yang lo butuh paling cuma SSH, HTTP, dan HTTPS. ufw (Uncomplicated Firewall) bikin ini gampang.

sudo apt update && sudo apt install ufw -y

Set aturan dasarnya: tolak semua koneksi masuk, izinin semua keluar, terus buka port yang emang dipakai:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Port 80 dan 443 buat Caddy/Traefik ngurus web traffic. Begitu aturannya kelar, baru aktifin:

sudo ufw enable
sudo ufw status verbose

Pastiin sudo ufw allow OpenSSH udah kejalanin sebelum ufw enable. Kalau kelupaan, lo bakal langsung ketendang dari sesi SSH dan kekunci di luar server. Ini kesalahan klasik yang bikin orang panik manggil support provider.

Satu catatan buat yang pakai Docker: Docker suka nge-bypass ufw dengan nulis aturan iptables-nya sendiri, jadi port container bisa kebuka walau ufw keliatan nutup. Kalau lo mapping port container ke host, ikat ke 127.0.0.1 (misalnya 127.0.0.1:3000:3000) dan biarin reverse proxy yang ngadepin publik, bukan port container langsung.

Tahan brute-force pakai fail2ban

ufw nutup port yang nggak dipakai, tapi port SSH kan tetep harus kebuka. Di sinilah fail2ban masuk: dia mantau log, dan kalau ada IP yang gagal login berkali-kali, IP-nya di-ban sementara.

sudo apt install fail2ban -y

Jangan edit file bawaannya langsung — bikin file override biar nggak ketimpa pas update:

sudo nano /etc/fail2ban/jail.local

Isi dengan:

[sshd]
enabled = true
maxretry = 3
findtime = 10m
bantime = 1h

Artinya: 3 kali gagal login dalam 10 menit, IP-nya di-ban 1 jam. Restart servicenya:

sudo systemctl restart fail2ban

Mau lihat hasil kerjanya? Cek status jail SSH:

sudo fail2ban-client status sshd

Di server yang udah jalan beberapa jam, biasanya udah ada beberapa IP nyangkut di daftar banned — itu bot yang tadinya nyoba-nyoba dan sekarang nyerah.

Auto-update buat patch keamanan

Bagian terakhir yang sering kelupaan: nge-patch celah keamanan. Daripada inget-inget update manual, nyalain unattended-upgrades biar patch keamanan kepasang otomatis.

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure --priority=low unattended-upgrades

Pilih Yes pas ditanya. Mulai sekarang, update keamanan bakal kepasang sendiri di background tanpa lo harus mikirin.

Penutup

Segini aja udah ngubah VPS dari target empuk jadi server yang lumayan tenang: nggak ada login root langsung, password udah nggak kepake, cuma key yang bisa masuk, firewall cuma ngebuka port yang dipakai, dan bot brute-force langsung di-ban sama fail2ban. Sisanya cuma soal disiplin — jangan asal chmod 777, jangan jalanin service sebagai root kalau nggak perlu, dan rutin cek sudo lastb sama status fail2ban.

Pintu udah dikunci. Lanjutannya nanti gue mau bahas mantau semua service ini biar tau pas ada yang mati — tapi itu cerita buat post berikutnya. Selamat ngamanin server.