2026年11月12日

2026年11月12日

Batasi Akses per Negara di Nginx dengan GeoIP2 dan GeoLite2

Artikel ini adalah edisi lokal dari artikel asli berbahasa Jepang. Baca artikel asli berbahasa Jepang

Untuk membatasi akses per negara di Nginx, per November 2026 caranya adalah memakai modul GeoIP2 (ngx_http_geoip2_module) dan database GeoLite2 dari MaxMind, memasukkan kode negara ke variabel lewat blok geoip2, lalu menentukan izin atau penolakan dengan map. Cara lama dalam artikel-artikel lawas, yaitu mengunduh file .dat GeoLite dengan wget, tidak lagi berfungsi karena distribusi datanya sudah dihentikan.

Berikut ringkasan kesimpulannya.

  • Modul lama ngx_http_geoip_module (GeoIP Legacy) tidak bisa dipakai untuk pengaturan baru karena MaxMind sudah menghentikan distribusi data format lama. Beralihlah ke GeoIP2 (format .mmdb).
  • GeoLite2 gratis, tetapi memerlukan pendaftaran akun MaxMind dan license key. Pengunduhan dan pembaruannya dilakukan dengan geoipupdate.
  • Di sisi Nginx, buat variabel seperti $geoip2_country_code dengan blok geoip2, tentukan nilai 0 / 1 yang setara dengan allow / deny lewat map, lalu lakukan return 403 di location.
  • Pada situs yang berada di belakang CDN seperti Cloudflare, jika IP asli pengunjung tidak dipulihkan lebih dulu dengan real_ip_header, semua pengunjung akan dianggap berasal dari negara milik CDN.
  • Pembatasan berdasarkan negara hanyalah "alat bantu untuk mengurangi serangan" dan bisa dihindari dengan VPN atau perantara. Yang realistis adalah memakainya hanya untuk halaman login dan area admin, bukan untuk seluruh halaman publik.
Alur pengaturan GeoIP2 di Nginx. Daftar di MaxMind, ambil database dengan geoipupdate, muat modul, tentukan dengan geoip2 dan map, lalu batasi di location

Perbedaan geoip lama dan GeoIP2

Item ngx_http_geoip_module (lama) ngx_http_geoip2_module (GeoIP2)
Format data GeoIP Legacy (.dat) GeoIP2 (.mmdb)
Penyediaan data gratis Berakhir (distribusi dihentikan pada 2019) GeoLite2 (perlu pendaftaran akun dan license key)
Pustaka yang diperlukan libGeoIP libmaxminddb
Cara mendapatkan modul Bawaan Nginx (--with-http_geoip_module) Modul pihak ketiga leev/ngx_http_geoip2_module. Debian / Ubuntu menyediakan paketnya
Variabel Tetap, seperti $geoip_country_code Nama ditentukan sendiri di blok geoip2

Jika konfigurasi Anda yang ada masih memakai geoip_country, pembaruan databasenya sudah berhenti sehingga hasil deteksinya usang. Sebaiknya manfaatkan kesempatan ini untuk beralih ke GeoIP2.

Langkah 1: Daftar ke MaxMind dan buat license key

  1. Buat akun gratis dari halaman GeoLite2 MaxMind.
  2. Setelah login, terbitkan License Key di halaman pengelolaan akun (key hanya ditampilkan saat diterbitkan, jadi catat baik-baik).
  3. Database yang dipakai adalah GeoLite2-Country jika hanya perlu negara, atau GeoLite2-City jika perlu sampai tingkat kota. Untuk pembatasan per negara, Country sudah cukup.

Syarat penggunaan (GeoLite2 End User License Agreement) memuat aturan tentang redistribusi dan penayangan data. Jika hanya dipakai untuk deteksi di server internal, biasanya masih dalam batas wajar, tetapi periksa ketentuannya saat mendaftar.

Langkah 2: Unduh dan perbarui database dengan geoipupdate

GeoLite2 diperbarui secara berkala, jadi gunakan geoipupdate alih-alih mengunduh secara manual (dokumentasi geoipupdate).

# Debian / Ubuntu
sudo apt install geoipupdate

# Keluarga RHEL (AlmaLinux / Rocky Linux) dari EPEL
sudo dnf install geoipupdate

Tulis ID akun dan license key di berkas konfigurasi /etc/GeoIP.conf.

AccountID 123456
LicenseKey key_yang_Anda_terbitkan
EditionIDs GeoLite2-Country
# Lokasi penyimpanan mengikuti bawaan paket (Debian / Ubuntu: /var/lib/GeoIP, lainnya umumnya /usr/share/GeoIP).
# Untuk mengubahnya: DatabaseDirectory /var/lib/GeoIP
sudo geoipupdate -v
ls -l /var/lib/GeoIP/   # berhasil jika ada GeoLite2-Country.mmdb

geoipupdate versi paket sudah dilengkapi pengaturan untuk berjalan berkala lewat timer systemd atau cron (periksa dengan systemctl list-timers | grep geoip). Jika belum ada, tambahkan cron sekitar seminggu sekali.

Langkah 3: Pasang modul GeoIP2 di Nginx

Debian / Ubuntu (Nginx dari apt)

sudo apt install libnginx-mod-http-geoip2
ls /etc/nginx/modules-enabled/   # 50-mod-http-geoip2.conf akan ditempatkan
nginx -t

Nginx dari paket nginx.org atau hasil build dari sumber

Pasang libmaxminddb, lalu build modul dinamis dari sumber dengan versi yang sama seperti Nginx yang sedang berjalan.

sudo apt install libmaxminddb-dev   # keluarga RHEL: libmaxminddb-devel
cd /usr/local/src
git clone https://github.com/leev/ngx_http_geoip2_module
curl -LO https://nginx.org/download/nginx-1.26.3.tar.gz   # sesuaikan versi dengan nginx -v
tar xzf nginx-1.26.3.tar.gz && cd nginx-1.26.3
./configure --with-compat --add-dynamic-module=../ngx_http_geoip2_module
make modules
sudo cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/

Muat modul di bagian paling atas nginx.conf (pada versi paket, baris ini ditempatkan otomatis).

load_module modules/ngx_http_geoip2_module.so;

Langkah 4: Jadikan kode negara variabel dan tentukan izin atau penolakan

Tulis di blok http. Masukkan kode negara ke variabel dengan blok geoip2, lalu lewat map beri nilai 1 untuk negara yang diizinkan dan 0 untuk yang lain.

http {
    geoip2 /var/lib/GeoIP/GeoLite2-Country.mmdb {
        auto_reload 60m;
        $geoip2_country_code country iso_code;
    }

    # Negara yang diizinkan mengakses admin (kode 2 huruf ISO 3166-1)
    map $geoip2_country_code $admin_allowed {
        default 0;
        JP      1;
        ""      1;   # Yang tidak bisa dideteksi (misalnya IP privat) diizinkan. Ubah ke 0 jika ingin menolak
    }
}

auto_reload adalah interval untuk membaca ulang database yang diganti oleh geoipupdate tanpa perlu restart.

Langkah 5: Batasi hanya halaman login dan admin WordPress

Ini contoh yang membatasi per negara hanya wp-login.php dan /wp-admin/, tanpa membatasi halaman publik. Tulis di blok server.

server {
    # ... konfigurasi yang sudah ada ...

    location = /wp-login.php {
        if ($admin_allowed = 0) { return 403; }
        include        fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
    }

    location ^~ /wp-admin/ {
        if ($admin_allowed = 0) { return 403; }
        # Jika admin-ajax.php dipakai plugin eksternal, izinkan di location terpisah
        location ~ \.php$ {
            include        fastcgi_params;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass   unix:/run/php/php8.3-fpm.sock;
        }
    }
}

Kombinasi if dan return adalah bentuk yang aman ditangani Nginx. /wp-admin/admin-ajax.php terkadang dipanggil oleh fungsi halaman publik (misalnya formulir atau infinite scroll) tanpa login, jadi putuskan apakah akan dikecualikan dari pembatasan sesuai fitur situs Anda.

Terapkan dan periksa:

sudo nginx -t && sudo systemctl reload nginx

# Dari negara Anda sendiri: 200 atau 302 dikembalikan
curl -sI https://example.com/wp-login.php | head -1
# Memeriksa hasil deteksi (contoh mencatat kode negara di log)
# log_format geo '$remote_addr $geoip2_country_code "$request" $status';

Untuk memeriksa tampilannya dari luar negeri, akses wp-login.php lewat VPN di lokasi luar negeri atau layanan pemantauan dari luar negeri, lalu pastikan hasilnya 403.

Jika situs berada di belakang CDN (Cloudflare dan sejenisnya)

Lewat CDN, $remote_addr menjadi IP milik CDN sehingga semua pengunjung dianggap berasal dari negara CDN. Pulihkan dulu IP asli pengunjung dengan ngx_http_realip_module (modul realip).

# Contoh Cloudflare. Perbarui daftar IP secara berkala dari IP Ranges resmi Cloudflare
set_real_ip_from 173.245.48.0/20;
# ... daftarkan semua rentang Cloudflare ...
real_ip_header   CF-Connecting-IP;

geoip2 secara bawaan membaca $remote_addr, sehingga deteksi dilakukan dengan IP asli setelah diganti oleh realip. Cloudflare sendiri juga punya kontrol akses per negara (aturan khusus WAF), jadi jika Anda memakai Cloudflare, membatasi di sisi Cloudflare lebih mudah daripada di Nginx. Lihat juga Cara mengatur Cloudflare di WordPress.

Keterbatasan pembatasan per negara

  • Deteksi GeoIP hanyalah perkiraan berdasarkan data registrasi alamat IP, sehingga bisa dihindari lewat VPN, proxy, atau perantara dari cloud luar negeri.
  • Pada jaringan seluler atau jaringan perusahaan, lokasi bisa terdeteksi sebagai negara yang berbeda dari lokasi sebenarnya. Masalah operasional seperti admin yang sedang dinas ke luar negeri terkunci juga bisa terjadi.
  • Karena itu, pembatasan per negara dipakai sebagai alat bantu untuk mengurangi serangan brute force pada login, dikombinasikan dengan autentikasi dua faktor, pembatasan jumlah percobaan login, dan perlindungan wp-admin dengan autentikasi Basic.

Pertanyaan yang sering diajukan

Apa bedanya modul geoip dan modul geoip2 di Nginx?

Modul geoip lama membaca data format GeoIP Legacy (.dat), tetapi MaxMind sudah menghentikan distribusi format ini. Modul geoip2 (ngx_http_geoip2_module) membaca format .mmdb yang berlaku sekarang dan bisa memakai data gratis GeoLite2. Untuk pengaturan baru, pakailah geoip2.

Apakah GeoLite2 gratis? Apakah perlu mendaftar?

Gratis, tetapi perlu mendaftar akun MaxMind dan menerbitkan license key. Pengunduhan dan pembaruan berkala dilakukan dengan geoipupdate. Cara lama yang mengunduh langsung tanpa key tidak berfungsi.

Apakah login ilegal ke WordPress bisa dicegah dengan membatasi per negara?

Cara ini mengurangi percobaan brute force, tetapi tidak bisa dikatakan mencegahnya karena bisa dihindari lewat VPN atau perantara dari server luar negeri. Kombinasikan dengan pembatasan jumlah login, autentikasi dua faktor, autentikasi Basic, dan sebagainya.

Jika memakai Cloudflare, semua pengunjung terdeteksi dari negara yang sama

Itu karena lewat CDN, sumber koneksi menjadi IP milik CDN. Pulihkan IP asli dengan set_real_ip_from dan real_ip_header CF-Connecting-IP sebelum melakukan deteksi. Ada juga cara membatasi per negara dengan WAF Cloudflare.

Apakah dengan GeoLite2-City saya bisa membatasi sampai tingkat kota?

Kode kota dan wilayah juga bisa dimasukkan ke variabel, tetapi akurasi tingkat kota lebih rendah daripada negara, sehingga pengguna sah lebih mudah terkunci akibat salah deteksi. Untuk kontrol akses, sebaiknya batasi sampai tingkat negara saja.

Ringkasan

  • Pembatasan per negara di Nginx saat ini dilakukan dengan GeoIP2 (ngx_http_geoip2_module + GeoLite2 .mmdb), dan datanya diperbarui dengan geoipupdate.
  • Masukkan kode negara ke variabel dengan geoip2, tentukan izin atau penolakan dengan map, lalu lakukan return 403 di location untuk wp-login.php dan /wp-admin/.
  • Jika lewat CDN, pulihkan IP asli lebih dulu, dan gunakan pembatasan per negara sebagai tindakan bantu yang dikombinasikan dengan autentikasi dua faktor dan sejenisnya.

Artikel terkait

Referensi: ngx_http_geoip2_module (GitHub), MaxMind GeoLite2 Free Geolocation Data, MaxMind – Updating Databases (geoipupdate), Nginx ngx_http_realip_module

Riwayat pembaruan: 2026-11-09 revisi menyeluruh (prosedur GeoLite lama yang distribusinya telah dihentikan diganti dengan prosedur GeoIP2 dan geoipupdate, serta ditambahkan contoh pembatasan area admin WordPress dan catatan tentang CDN). Artikel ini dikelola oleh WordPress Hakase (Lightscend Inc.).

Ada pertanyaan tentang WordPress? Penerbit situs ini berada di Jepang dan membalas dalam bahasa Jepang. Kontak (bahasa Jepang)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲