VPS tanpa firewall itu kayak rumah tanpa pintu — siapapun bisa masuk kapan aja. Gue pernah lihat VPS klien yang baru 3 hari online udah kena brute force SSH lebih dari 10.000 kali. Logs-nya penuh sama failed login attempts dari IP China dan Russia. Untungnya mereka udah pake key-based auth, tapi tetep aja ngeri kan? Artikel ini bakal jadi panduan lengkap lo untuk setup firewall di Ubuntu VPS production menggunakan UFW, Fail2Ban, dan rate limiting — semua yang lo butuhkan buat tidur nyenyak.
Kita bakal cover tiga layer pertahanan: UFW sebagai firewall utama, Fail2Ban sebagai brute force protection, dan nginx rate limiting sebagai application layer protection. Kombinasi ketiganya udah teruji di puluhan VPS yang gue manage selama 5 tahun terakhir.
Layer 1: UFW (Uncomplicated Firewall)
UFW itu wrapper simpel untuk iptables yang bikin setup firewall jadi jauh lebih mudah. Lo nggak perlu ngerti syntax iptables yang ribet — UFW handles everything dengan command yang intuitive.
Install UFW terlebih dahulu:
sudo apt update && sudo apt install ufw -y
Setup default policies — deny all incoming, allow all outgoing:
sudo ufw default deny incoming
sudo ufw default allow outgoing
Sekarang allow ports yang lo butuhkan. Untuk web server, lo butuh SSH (22), HTTP (80), dan HTTPS (443):
sudo ufw allow 22/tcp comment "SSH"
sudo ufw allow 80/tcp comment "HTTP"
sudo ufw allow 443/tcp comment "HTTPS"
PENTING: Pastikan SSH di-allow SEBELUM enable UFW. Kalau nggak, lo bisa ke-lock dari VPS sendiri. Gue pernah ngalamin ini — untungnya ada console access dari provider.
Enable UFW:
sudo ufw enable
sudo ufw status verbose
Output-nya harusnya kayak gini:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere # SSH
80/tcp ALLOW IN Anywhere # HTTP
443/tcp ALLOW IN Anywhere # HTTPS
Advanced UFW Rules untuk Production
Beyond basic ports, lo perlu rules yang lebih spesifik. Misalnya, restrict SSH cuma dari IP tertentu:
sudo ufw allow from 103.xxx.xxx.xxx to any port 22 proto tcp comment "Office SSH"
Allow PostgreSQL cuma dari localhost (untuk aplikasi yang jalan di server yang sama):
sudo ufw allow from 127.0.0.1 to any port 5432 proto tcp comment "Local PostgreSQL"
Dan block semua traffic dari suspicious countries. Gue biasanya block ranges dari negara yang nggak relevan sama bisnis klien:
# Block specific ranges (contoh)
sudo ufw deny from 185.220.0.0/16 comment "Known bad range"
Rate limiting di UFW level juga bisa dilakukan untuk SSH protection tambahan:
sudo ufw limit 22/tcp comment "SSH rate limit"
Command limit akan block IP yang melakukan lebih dari 6 connection attempts dalam 30 detik. Ini defense layer pertama sebelum Fail2Ban.
Layer 2: Fail2Ban — Brute Force Protection
Fail2Ban itu monitor log files dan ban IP yang melakukan repeated failed login attempts. Ini sangat powerful karena bisa auto-block attacker tanpa intervensi manual.
Install Fail2Ban:
sudo apt install fail2ban -y
Buat custom configuration (jangan edit jail.conf langsung — itu akan ke-overwrite saat update):
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
Edit section [DEFAULT]:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
banaction = ufw
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
Penjelasan parameter: - bantime: Durasi ban dalam detik (86400 = 24 jam untuk SSH) - findtime: Window waktu untuk menghitung failed attempts - maxretry: Jumlah maksimal failed attempts sebelum ban - banaction: UFW integration — langsung block via firewall
Restart Fail2Ban dan cek statusnya:
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Output yang diharapkan:
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 47
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 12
`- Banned IP list: 185.220.101.xx
Custom Fail2Ban Filter untuk Web Application
Selain SSH, lo juga bisa protect web application dari brute force login. Bikin custom filter untuk nginx:
sudo nano /etc/fail2ban/filter.d/nginx-auth.conf
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*"/(login|admin|wp-login).*" (401|403)
ignoreregex =
Dan tambahin jail di jail.local:
[nginx-auth]
enabled = true
port = http,https
filter = nginx-auth
logpath = /var/log/nginx/access.log
maxretry = 5
bantime = 7200
Sekarang setiap IP yang gagal login di web app lebih dari 5 kali dalam 10 menit bakal di-ban selama 2 jam. Ini sangat efektif melawan credential stuffing attacks.
Layer 3: Nginx Rate Limiting
Rate limiting di nginx level melindungi dari DDoS aplikasi dan API abuse. Ini defense layer terakhir sebelum request sampai ke aplikasi lo.
Edit nginx configuration. Definisikan rate limit zone di http block (biasanya di /etc/nginx/nginx.conf):
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=3r/m;
Penjelasan: - $binary_remote_addr: Client IP dalam binary format (hemat memory) - zone=api:10m: Shared memory zone 10MB untuk tracking - rate=10r/s: Max 10 requests per detik per IP untuk API - rate=3r/m: Max 3 requests per menit untuk login (sangat ketat)
Apply rate limit ke location blocks:
server {
listen 80;
server_name api.toolkuy.com;
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:8080;
}
location /api/v1/auth {
limit_req zone=login burst=3 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:8080;
}
}
Parameter burst=20 mengizinkan burst traffic hingga 20 requests. nodelay berarti burst ditangani langsung, nggak ditahan. limit_req_status 429 mengembalikan HTTP 429 (Too Many Requests) saat limit tercapai.
Monitoring dan Maintenance
Setup firewall nggak cukup — lo juga perlu monitoring. Buat script sederhana untuk check status semua layer:
#!/bin/bash
echo "=== UFW Status ==="
sudo ufw status | head -20
echo ""
echo "=== Fail2Ban Status ==="
sudo fail2ban-client status sshd
echo ""
echo "=== Recent SSH Failures ==="
sudo journalctl -u sshd --since "1 hour ago" | grep -i "failed" | tail -5
echo ""
echo "=== Top Offenders ==="
sudo awk '/Failed password/ {print $11}' /var/log/auth.log | sort | uniq -c | sort -rn | head -10
Jalankan script ini setiap pagi atau setup cron job untuk automated alerting. Kalau lo pake Telegram bot (kayak OpenCrabs), lo bisa auto-send report ke Telegram setiap hari.
Best Practices Tambahan
Beberapa best practices tambahan dari pengalaman gue manage lebih dari 50 VPS production:
Gunakan SSH key-based authentication dan disable password login. Edit /etc/ssh/sshd_config: set PasswordAuthentication no dan PermitRootLogin prohibit-password.
Setup automatic security updates dengan unattended-upgrades. Lo nggak mau manually patching setiap CVE yang keluar. Jalankan sudo apt install unattended-upgrades -y dan sudo dpkg-reconfigure -plow unattended-upgrades.
Gunakan log rotation yang proper. Pastikan logs nggak consume semua disk space. Log yang penuh bisa bikin service crash.
Backup UFW rules secara berkala dengan sudo ufw export rules > /backup/ufw-rules.txt. Kalau VPS crash, lo bisa restore rules dalam hitungan detik.
Kesimpulan
Tiga layer pertahanan ini — UFW, Fail2Ban, dan nginx rate limiting — kalau dikombinasikan dengan benar, bisa melindungi VPS dari 95% attacks yang biasa menargetkan web server. Investasi waktu setup ini cuma sekitar 2-3 jam, tapi manfaatnya jangka panjang banget. Lo nggak mau jadi developer yang baru sadar pentingnya firewall setelah VPS-nya kena compromourse kan? Setup sekarang, tidur nyenyak malam ini.
Automated Alerting dengan Telegram Bot
Selain monitoring, lo juga perlu alerting system yang bikin lo tau kalau ada masalah tanpa harus cek server terus-menerus. Cara paling gampang adalah bikin simple Telegram bot yang kirim alert ke group atau personal chat lo. Lo bisa pake Python dengan library python-telegram-bot atau langsung pakai curl ke Telegram Bot API.
Script alerting sederhana bisa check beberapa kondisi: disk space usage, memory usage, CPU load, dan failed login attempts. Kalau salah satu threshold tercapai, bot langsung kirim pesan ke Telegram lo. Lo juga bisa nambahin auto-remediation untuk kasus yang simple — misalnya automatic restart kalau service nggak merespon.
Penting juga untuk setup log aggregation. Dengan UFW, Fail2Ban, dan nginx yang semuanya punya logs, lo butuh cara untuk search dan analyze logs secara centralized. Lo bisa pake Loki + Grafana untuk log aggregation yang powerful tapi resource-friendly. Atau kalau VPS lo cukup powerful, ELK stack (Elasticsearch, Logstash, Kibana) bisa jadi pilihan yang lebih feature-rich.
Backup verification juga sering dilupakan. Banyak admin yang setup backup tapi nggak pernah test restore-nya. Lo harus test restore minimal sebulan sekali — bikin cron job yang restore backup ke staging environment dan verify data integrity-nya. Percuma punya backup kalau pas dibutuhkan, isinya corrupt atau nggak compatible.
Terakhir, document everything. Semua rules, configs, dan procedures harus terdokumentasi dengan baik. Kalau lo sakit atau unavailable, orang lain harus bisa handle server lo tanpa masalah. Bikin runbook untuk setiap kemungkinan scenario — dari server down sampai security breach response procedure. Investasi waktu di dokumentasi ini bakal save lo banyak masalah di kemudian hari.
Incident Response: Apa yang Harus Dilakukan Saat Attack
Meskipun udah setup firewall dengan benar, tetap ada kemungkinan lo menghadapi situasi di mana server diserang. Yang penting adalah lo punya incident response plan yang jelas. Langkah pertama: jangan panik. Serangan itu sudah diprediksi dan firewall lo udah designed untuk handle ini.
Langkah kedua: identifikasi attack vector. Cek logs untuk menentukan jenis serangan — apakah brute force SSH, DDoS, atau application-level attack. Dengan logs yang proper, lo bisa trace setiap attempt dan block IP yang suspicious. UFW logs bisa lo cek dengan sudo journalctl -u ufw atau langsung dari /var/log/ufw.log.
Langkah ketiga: block dan remediate. Tambahkan IP yang menyerang ke blocklist secara manual kalau perlu, meskipun Fail2Ban harusnya udah handle ini otomatis. Kalau attack targeting aplikasi web, aktifkan mode maintenance sementara sambil lo fix vulnerability yang dieksploit. Pastikan juga untuk update semua dependencies ke versi terbaru sebelum bring back online.
Langkah keempat: post-incident review. Setelah attack berhasil ditangani, lakukan review untuk improve defense lo. Apakah ada rules yang terlewat? Apakah response time lo cukup cepat? Apakah logging lo cukup detail untuk investigasi lebih lanjut? Dokumentasikan semua findings dan update runbook berdasarkan lessons learned. Setiap attack itu learning opportunity — lo harus lebih kuat setelah menghadapinya dibanding sebelumnya.
💬 Komentar (0)
Belum ada komentar. Jadilah yang pertama! 💬