📑 Daftar Isi
- Pendahuluan
- Gejala — Apa yang Terjadi?
- Gejala 1: LiteSpeed Brute Force Throttle
- Gejala 2: Apache "Too Many Open Files"
- Gejala 3: Massive wp-login.php Brute Force
- Root Cause — Apa yang Salah?
- 1. Brute Force: Tidak Ada Proteksi di Depan WordPress Login
- 2. File Descriptor Exhaustion: Terlalu Banyak Request Simultan
- 3. Kombinasi Kedua Masalah
- Step-by-Step Solution — HTTP Basic Auth untuk wp-login.php
- Langkah 1: Buat File htpasswd
- Langkah 2: Edit pre_virtualhost_global.conf
- Langkah 3: Test Config & Restart Apache
- Langkah 4: Verifikasi Proteksi Aktif
- Langkah 5: Fix File Descriptor Exhaustion
- Pro Tips & Warnings
- FAQ
- Q: Apakah HTTP Basic Auth bisa di-crack?
- Q: Bagaimana jika saya lupa password htpasswd?
- Q: Apakah HTTP Basic Auth mempengaruhi performa server?
- Q: Kenapa harus di pre_virtualhost_global.conf, bukan di .htaccess?
- Kesimpulan
Pendahuluan
Jam 3:38 siang. Saya sedang duduk santai di ruang NOC, menyeruput kopi hangat, ketika monitoring Telegram bunyi: “Warning — Brute force detected, throttle active”. Saya cek log LiteSpeed — ada 2 IP yang kena throttle. Tapi itu belum seberapa. Ketika saya buka error log Apache, saya malah menemui sesuatu yang lebih parah: “Too many open files: could not open transfer log file”.
Masalahnya tidak berhenti di situ. Saya lari ke server dan menjalankan command grep untuk mengecek aktivitas login WordPress di jam terakhir. Hasilnya? Lebih dari 5.000 percobaan login wp-login.php dalam satu jam — dari satu IP saja. Dan ini baru satu server.
Itu bukan manusia. Itu bot. Ribuan request login otomatis yang mencoba brute force akun admin WordPress Anda. Dan jika Anda tidak punya proteksi tambahan, suatu hari bot akan berhasil — karena password yang “kuat” sekalipun bisa di-crack jika punya waktu cukup.
Cerita ini adalah tentang bagaimana saya menghentikan serangan brute force yang masif ini, memperbaiki file descriptor exhaustion yang menyebabkan error log macet, dan membangun HTTP Basic Auth sebagai benteng pertahanan pertama sebelum WordPress login.
Gejala — Apa yang Terjadi?
Ada tiga gejala yang muncul bersamaan di server hari itu:
Gejala 1: LiteSpeed Brute Force Throttle
Log LiteSpeed menunjukkan beberapa IP yang sudah terdeteksi melakukan brute force dan di-throttle otomatis:
[root@mr-x ruak3711]# tail -f /usr/local/apache/logs/error_log
2026-07-20 15:32:38.263607 [WARN] [3402173] [T0] [10.0.0.1:40442#APVH_client-a.com:443] Brute force detected for IP [10.0.0.1], throttle.
2026-07-20 15:32:38.869189 [WARN] [3402173] [T0] [10.0.0.2:62269#APVH_site-lama-client.com:443] Brute force detected for IP [10.0.0.2], throttle.
LiteSpeed memang punya fitur brute force protection bawaan. Tapi masalahnya: throttle hanya memperlambat request, bukan memblokir. Bot tetap bisa mencoba — lebih lambat, tapi tetap mencoba. Dan ketika ada ribuan bot dari IP berbeda, throttle tidak cukup.
Gejala 2: Apache “Too Many Open Files”
Error log Apache menunjukkan masalah yang berbeda — file descriptor exhaustion:
[Mon Jul 20 15:32:46.712781 2026] [log_config:error] [pid 3486344:tid 3486344] (24)Too many open files: AH00649: could not open transfer log file /etc/apache2/logs/domlogs/client-b.com.
AH00015: Unable to open logs
[Mon Jul 20 15:32:50.986574 2026] [log_config:error] [pid 3486614:tid 3486614] (24)Too many open files: AH00649: could not open transfer log file /etc/apache2/logs/domlogs/client-b.com.
AH00015: Unable to open logs
[Mon Jul 20 15:33:08.009242 2026] [log_config:error] [pid 3490205:tid 3490205] (24)Too many open files: AH00649: could not open transfer log file /etc/apache2/logs/domlogs/portal-news-client.com.
AH00015: Unable to open logs
[Mon Jul 20 15:36:00.576506 2026] [log_config:error] [pid 3521150:tid 3521150] (24)Too many open files: AH00649: could not open transfer log file /etc/apache2/logs/domlogs/portal-news-client.com.
AH00015: Unable to open logs
Error (24)Too many open files artinya Apache sudah mencapai batas maksimum file descriptor yang diizinkan sistem operasi. Ketika ini terjadi, Apache tidak bisa membuka file log baru — dan dalam kasus terburuk, tidak bisa melayani request sama sekali.
Domain yang terdampak: client-b.com, portal-news-client.com. Artinya website-website ini tidak bisa diakses atau setidaknya logging-nya terganggu.
Gejala 3: Massive wp-login.php Brute Force
Ini yang paling menakutkan. Ketika saya grep aktivitas login WordPress dalam satu jam terakhir:
[root@brantas ruak3711]# grep -r 'POST /wp-login.php' /usr/local/apache/logs/domlogs/ | grep -E "$(date +'%d/%b/%Y:%H:')|$(date -d '1 hour ago' +'%d/%b/%Y:%H:')" | awk '{print $1}' | cut -d: -f2 | sort | uniq -c | sort -nr | head -n 5
5046 10.0.0.2
4734 10.0.0.3
4652 10.0.0.4
4642 10.0.0.5
4166 10.0.0.6
Perhatikan angkanya: 5.046 percobaan login dalam satu jam dari satu IP. Itu artinya rata-rata 84 login attempts per menit, atau hampir 1.5 per detik. Dan itu baru 5 IP teratas — kemungkinan besar ada puluhan atau ratusan IP lain yang juga melakukan hal sama.
Total percobaan login dari 5 IP ini saja: 23.240 attempts dalam satu jam. Jika ada 100 IP yang melakukan hal yang sama, itu 464.800 percobaan login per jam. Dengan rate seperti ini, brute force akan berhasil menemukan password yang lemah dalam hitungan jam.
Root Cause — Apa yang Salah?
1. Brute Force: Tidak Ada Proteksi di Depan WordPress Login
WordPress login (wp-login.php) adalah pintu masuk utama ke dashboard WordPress. Tanpa proteksi tambahan, siapa pun bisa mengakses halaman ini dan mencoba login sebanyak mungkin. LiteSpeed memang punya throttle, tapi throttle hanya memperlambat — tidak memblokir. Dan ketika serangan datang dari banyak IP (distributed brute force), throttle menjadi tidak efektif.
2. File Descriptor Exhaustion: Terlalu Banyak Request Simultan
Ketika brute force menyerang server dengan ribuan request per menit, Apache harus membuka banyak koneksi sekaligus. Setiap koneksi membutuhkan file descriptor (untuk socket, log file, dll). Jika jumlah request melebihi batas ulimit -n yang dikonfigurasi untuk Apache, sistem operasi menolak membuka file baru — dan muncullah error Too many open files.
Ini bukan hanya masalah logging. Jika Apache tidak bisa membuka file log, ia juga mungkin tidak bisa membuka file konfigurasi, certificate SSL, atau bahkan melayani request HTTP. Dalam kasus terburuk, seluruh website di server bisa down.
3. Kombinasi Kedua Masalah
Brute force yang masif → ribuan koneksi simultan → file descriptor habis → Apache tidak bisa buka file log → error beruntun → website down. Ini adalah chain reaction yang dimulai dari satu titik: ketiadaan proteksi di depan wp-login.php.
Step-by-Step Solution — HTTP Basic Auth untuk wp-login.php
Mengubah pre_virtualhost_global.conf adalah tindakan berisiko tinggi. Jika config salah, semua website di server bisa down. Sebelum melanjutkan:
- Backup config yang ada —
cp pre_virtualhost_global.conf pre_virtualhost_global.conf.bak - Test config sebelum restart — selalu jalankan
apachectl configtestsebelum restart - Pastikan Anda punya akses console/terminal — jika config salah, website down dan Anda tidak bisa akses via browser
- Gunakan HTTPS — HTTP Basic Auth mengirim username/password dalam base64 (bukan enkripsi). Tanpa HTTPS, credentials bisa di-intercept
- Catat password htpasswd Anda — jika lupa, Anda terkunci dari wp-login.php
Langkah 1: Buat File htpasswd
File htpasswd berisi username dan password untuk HTTP Basic Auth. Buat file ini di lokasi yang aman (di luar document root):
# Buat file htpasswd dengan username admin
htpasswd -cb /home/wp-admin-attack-htpasswd-file admin123
# Masukkan password saat diminta
Contoh isi file htpasswd (ter-encrypt):
admin123:$apr1$xxxx$x.xxxxxxxxxxxxxxxxxxxx
Penting: Jangan letakkan file htpasswd di document root (misal /home/user/public_html/). Jika file ini bisa diakses publik, attacker bisa membaca username-nya (meskipun password-nya ter-encrypt).
Langkah 2: Edit pre_virtualhost_global.conf
File ini berada di /usr/local/apache/conf/includes/pre_virtualhost_global.conf. Tambahkan blok berikut di akhir file:
#BEGIN BLOCK-xmlrpc
<Files "xmlrpc.php">
Require all denied
Require ip 122.248.245.244/32
Require ip 54.217.201.243/32
Require ip 54.232.116.4/32
Require ip 192.0.80.0/20
Require ip 192.0.96.0/20
Require ip 192.0.112.0/20
Require ip 195.234.108.0/22
Require ip 192.0.64.0/18
</Files>
#END BLOCK-xmlrpc
#BEGIN BLOCK-WP-ADMIN-ATTACK
#
<Files wp-login.php>
AuthType basic
AuthName "Untuk membuktikan bahwa Anda bukan robot, silakan memasukkan username dan katasandi sebagai berikut:"
AuthBasicProvider file
AuthUserFile /home/wp-admin-attack-htpasswd-file
Require valid-user
ErrorDocument 401 "Authentication required"
</Files>
#
# END BLOCK-WP-ADMIN-ATTACK
Penjelasan blok ini:
<Files wp-login.php>— aturan ini hanya berlaku untuk filewp-login.php, tidak untuk file lain di WordPressAuthType basic— menggunakan HTTP Basic Authentication (browser akan menampilkan popup login)AuthBasicProvider file— credential diambil dari file htpasswdRequire valid-user— hanya user yang terdaftar di htpasswd yang boleh mengaksesErrorDocument 401— pesan yang muncul jika autentikasi gagal- Blok xmlrpc — hanya mengizinkan IP tertentu untuk mengakses xmlrpc.php (WordPress.com, Jetpack, dll)
Langkah 3: Test Config & Restart Apache
Jangan langsung restart. Test dulu apakah config valid:
# Test apakah config valid
apachectl configtest
# Output yang diharapkan: Syntax OK
Jika output Syntax OK, restart Apache:
# Restart Apache ( graceful agar tidak drop koneksi aktif)
apachectl graceful
# atau
systemctl restart httpd
Jika configtest mengembalikan error, JANGAN restart. Perbaiki error-nya terlebih dahulu. Jika Anda restart dengan config yang salah, semua website di server akan down sampai config diperbaiki.
Langkah 4: Verifikasi Proteksi Aktif
Buka browser dan akses https://domain-anda.com/wp-login.php. Anda seharusnya melihat popup login HTTP Basic Auth sebelum halaman WordPress login muncul:
- Masukkan username dan password htpasswd yang sudah dibuat
- Jika benar, halaman WordPress login akan muncul seperti biasa
- Jika salah atau cancel, Anda akan melihat pesan “Authentication required”
Sekarang coba akses wp-login.php tanpa credentials — Anda akan ditolak. Bot brute force juga akan ditolak, karena mereka tidak tahu username dan password HTTP Basic Auth Anda.
Langkah 5: Fix File Descriptor Exhaustion
Sementara proteksi wp-login.php menghentikan brute force, Anda juga perlu fix masalah Too many open files. Cek batas saat ini:
# Cek batas file descriptor untuk Apache
cat /proc/$(pgrep -f "apache2|httpd" | head -1)/limits | grep "Max open files"
Jika Max open files terlalu rendah (misal 1024 atau 4096), tingkatkan:
# Edit limits.conf
nano /etc/security/limits.conf
# Tambahkan di akhir file:
apache hard nofile 65535
apache soft nofile 32768
* hard nofile 65535
* soft nofile 32768
Jika menggunakan systemd, edit juga service file Apache:
# Edit systemd service
systemctl edit httpd
# Tambahkan:
[Service]
LimitNOFILE=65535
Setelah itu, restart Apache:
systemctl daemon-reexec
systemctl restart httpd
Pro Tips & Warnings
- Gunakan HTTPS selalu — HTTP Basic Auth mengirim credentials dalam base64 (bukan enkripsi). Tanpa HTTPS, attacker bisa membaca username dan password Anda dari network traffic. Pastikan SSL aktif di server
- Jangan gunakan password lemah di htpasswd — jika attacker tahu Anda menggunakan HTTP Basic Auth, mereka akan mencoba brute force htpasswd juga. Gunakan password minimal 16 karakter dengan kombinasi huruf, angka, dan simbol
- Batasi IP untuk xmlrpc.php — blok xmlrpc di atas hanya mengizinkan IP WordPress.com dan Jetpack. Jika Anda tidak menggunakan Jetpack, bisa blok semua:
Require all denied - Monitor error log secara berkala — jangan tunggu sampai error muncul sendiri. Jalankan
tail -f error_logminimal sekali sehari untuk mengetahui masalah sejak dini - Gunakan Fail2Ban sebagai lapisan tambahan — HTTP Basic Auth melindungi wp-login.php, tapi Fail2Ban bisa memblokir IP secara permanen setelah beberapa percobaan gagal
- Backup config sebelum edit — selalu backup
pre_virtualhost_global.confsebelum mengubah apapun
FAQ
Q: Apakah HTTP Basic Auth bisa di-crack?
HTTP Basic Auth mengirim username dan password dalam encoding base64 (bukan enkripsi). Jika ada attacker yang bisa memonitor traffic (man-in-the-middle), mereka bisa membaca credentials tersebut. Itulah kenapa HTTPS wajib digunakan — HTTPS mengenkripsi seluruh traffic, termasuk credentials HTTP Basic Auth. Tanpa HTTPS, HTTP Basic Auth hanya melindungi dari bot yang tidak bisa decode base64 (kebanyakan bot memang tidak bisa, tapi attacker manusia bisa).
Q: Bagaimana jika saya lupa password htpasswd?
Jika Anda lupa password, Anda bisa membuat ulang file htpasswd dengan username yang sama:
# Buat ulang file htpasswd (akan menghapus yang lama)
htpasswd -cb /home/wp-admin-attack-htpasswd-file admin123
# Masukkan password baru saat diminta
Setelah itu, restart Apache (apachectl graceful) agar config ter-load ulang. Tidak perlu restart server — cukup restart service Apache.
Q: Apakah HTTP Basic Auth mempengaruhi performa server?
Tidak signifikan. HTTP Basic Auth hanya melakukan satu pengecekan tambahan: membaca file htpasswd dan membandingkan hash password. Proses ini membutuhkan waktu mikro-detik — jauh lebih cepat dari satu request database WordPress. Performa server tidak akan terpengaruh oleh HTTP Basic Auth.
Q: Kenapa harus di pre_virtualhost_global.conf, bukan di .htaccess?
Karena <Files> directive tidak bisa digunakan di .htaccess — hanya bisa di file konfigurasi Apache utama. Selain itu, pre_virtualhost_global.conf berlaku untuk semua virtual host di server, jadi semua website akan terlindungi secara seragam. Jika Anda hanya ingin melindungi satu website, gunakan .htaccess di document root website tersebut.
Kesimpulan
Serangan brute force WordPress adalah ancaman nyata yang terjadi setiap hari di ribuan server di seluruh dunia. Dari log yang saya analisis, satu IP bisa melakukan 5.000+ percobaan login dalam satu jam — dan itu baru satu dari puluhan IP yang menyerang secara bersamaan.
Solusi HTTP Basic Auth yang saya implementasikan adalah benteng pertama yang sangat efektif. Bot brute force tidak bisa melewati HTTP Basic Auth, karena mereka tidak tahu username dan password yang Anda konfigurasi. Mereka hanya akan melihat pesan “Authentication required” dan berhenti mencoba.
Tapi(HTTP Basic Auth bukan satu-satunya lapisan pertahanan yang Anda butuhkan. Anda juga perlu: Fail2Ban untuk memblokir IP secara permanen, limit login attempts di WordPress, dan yang paling penting — password yang kuat. Kombinasi dari semua lapisan pertahanan ini akan membuat server Anda jauh lebih aman dari serangan brute force.
Author: NOC Engineer — ditulis berdasarkan pengalaman menangani brute force 5.000+ attempts per jam di server production.