Kenapa request masih bisa sampai ke IP lama
- Klien perlu IP untuk domain. Ia bertanya ke cache lokalnya dulu (browser, OS, atau library di aplikasi). Kalau tidak ada, ia bertanya ke resolver, yaitu server DNS milik ISP, kantor, atau publik, yang juga punya cache sendiri.
- Setelah dapat IP, klien membuka koneksi TCP ke IP itu (SYN, SYN-ACK, ACK).
- Untuk HTTPS, klien mengirim TLS ClientHello yang biasanya berisi SNI (Server Name Indication), yaitu nama domain yang dituju. Server memakai SNI untuk memilih sertifikat.
- Di dalam koneksi itu, klien mengirim request HTTP dengan header
Hostberisi nama domain. Web server memakai header ini untuk memilih virtual host. - Web server mencatat request ke access log. Field IP yang tercatat adalah alamat lawan bicara TCP, bukan hasil lookup DNS apa pun.
/etc/hosts, konfigurasi webhook, setting origin di CDN, script cron di server lain, atau aplikasi mobile yang menyimpan IP. Yang ini tidak akan pernah hilang sendiri, berapa lama pun kamu menunggu.
Scanner dan bot yang menyasar IP. Banyak bot memindai rentang IP tanpa peduli domain. Mereka akan terus datang ke IP lama selama IP itu masih hidup, siapa pun yang memakainya.
Tiga field yang paling banyak memberi petunjuk
curl, python-requests, Go-http-client, atau klien Java. Crawler mesin pencari menyebut namanya sendiri. Perlu diingat, user agent bisa dipalsukan, jadi anggap ini petunjuk, bukan bukti.
Header Host menunjukkan nama apa yang diminta klien. Kalau isinya domain kamu, klien memang berniat ke situs itu dan masih memegang IP lama. Kalau isinya IP mentah, kosong, atau domain yang tidak kamu kenal, besar kemungkinan itu scanner yang tidak tahu dan tidak peduli soal domain.
Masalahnya, format combined bawaan Nginx dan Apache tidak mencatat header Host. Di setup dengan log per domain, seperti domlogs di cPanel, Host tersirat dari nama file log. Request ke IP mentah biasanya justru jatuh ke virtual host default dan tercatat di log lain. Contoh format output log combined dengan beberapa pola yang sering muncul (IP dari blok dokumentasi, bukan kejadian nyata):
TEXT
198.51.100.23 - - [03/Nov/2026:10:15:02 +0800] "GET /produk/kaos HTTP/2.0" 200 18432 "https://contoh.id/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
203.0.113.10 - - [03/Nov/2026:10:15:00 +0800] "POST /api/callback/pembayaran HTTP/1.1" 200 41 "-" "python-requests/2.x"
192.0.2.77 - - [03/Nov/2026:10:15:07 +0800] "GET /.env HTTP/1.1" 404 162 "-" "Mozilla/5.0 zgrab/0.x"Memilah polanya dari log
BASH
LOG=/var/log/nginx/access.log
# 20 IP sumber teratas
awk '{print 1}' "LOG" | sort | uniq -c | sort -rn | head -20
# 20 user agent teratas (asumsi format combined)
awk -F'"' '{print 6}' "LOG" | sort | uniq -c | sort -rn | head -20
# Jumlah request per jam, untuk melihat tren naik atau turun
awk '{print substr(4, 2, 14)}' "LOG" | uniq -c
# Koneksi TCP yang sedang terbuka ke port 443 di server lama
ss -tn state established '( sport = :443 )'
# Reverse DNS dari IP yang mencurigakan
dig -x 203.0.113.10 +short/api/..., /webhook, /callback, /wp-cron.php dari server lain), itu tanda kuat ada klien dengan IP hardcode atau cache DNS di aplikasi. Reverse DNS dari IP-nya sering membantu menebak pemiliknya, misalnya hostname milik payment gateway, layanan monitoring, atau server internal kamu sendiri.
Kalau yang dominan adalah request ke path aneh dengan Host berupa IP, itu scanner. Mereka tidak relevan untuk keputusan mematikan server. Kalau ada yang mengaku crawler mesin pencari, cara memverifikasinya adalah reverse DNS lalu forward DNS ke IP yang sama. Hanya melihat user agent tidak cukup.
Perintah ss memberi gambaran lain: koneksi yang masih terbuka saat ini. Kalau traffic baru sudah sepi tapi masih ada koneksi established dari IP tertentu, kemungkinan besar itu koneksi persistent yang belum ditutup.
Menambahkan Host dan SNI ke log sementara
http, lalu memakainya di server block yang relevan atau di default_server:
NGINX
log_format cutover 'remote_addr [time_local] host="host" sni="ssl_server_name" '
'"request"status ua="http_user_agent" xff="http_x_forwarded_for"';
access_log /var/log/nginx/cutover.log cutover;nginx -t untuk validasi sebelum reload. Di Apache, padanannya adalah LogFormat dengan tambahan %{Host}i dan %{X-Forwarded-For}i. Di LiteSpeed atau control panel, caranya tergantung panel yang dipakai. Field sni membantu membedakan klien HTTPS yang memang menuju domain kamu dari scanner yang tersambung ke IP tanpa nama sama sekali.
Field xff penting untuk satu kasus khusus. Kalau domain berada di belakang CDN atau reverse proxy, semua request akan tercatat dari IP milik CDN, bukan IP pengunjung. Kalau server lama masih menerima traffic dalam jumlah normal dari rentang IP CDN, hampir pasti setting origin di CDN masih menunjuk ke IP lama. Mengubah record DNS publik tidak ada pengaruhnya di sini, karena CDN tidak memakai record itu untuk menemukan origin. Nama header IP asli pengunjung juga berbeda per vendor, jadi cek dokumentasi CDN yang kamu pakai.
Kapan server lama aman dimatikan
- Ganti semua IP hardcode yang ketemu dari log: origin CDN, URL webhook di dashboard pihak ketiga,
/etc/hosts, dan konfigurasi service lain. - Restart service yang mungkin menyimpan cache DNS, supaya mereka melakukan resolve ulang.
- Tunggu sampai request ber-Host domain kamu tinggal sedikit dan tidak muncul lagi dari klien yang sama.
- Hentikan web service di server lama, tapi jangan langsung hapus VPS atau data. Pantau error di server baru dan keluhan dari integrasi.
- Hapus server lama hanya setelah masa tunggu yang kamu anggap cukup, dan setelah ada backup akhir.
