Skip to content

Nginx1.28.0でGeoIP2を使う

はじめに

ChatGPTに訊きながら作成した手順をメモしておく。

soをビルドする

ビルド準備

必要モジュールをインストール

必要なモジュールをapt installする。対象はChatGPTに言われたまま。

$ sudo apt update
$ sudo apt install -y \
    build-essential \
    git \
    wget \
    libmaxminddb-dev \
    libpcre2-dev \
    zlib1g-dev \
    libssl-dev

作業フォルダを作成

ビルド用の作業ディレクトリを/tmp配下に作成して移動する。

$ cd /tmp
$ mkdir nginx-geoip2-build
$ cd nginx-geoip2-build

Nginxソースを取得

Nginxのソースファイルをwgetでダウンロードし、nginx-1.28.0.tar.gzを展開する。

$ wget https://nginx.org/download/nginx-1.28.0.tar.gz
$ tar xf nginx-1.28.0.tar.gz

GeoIP2をclone

続いて、Githubから本命のGeoIP2のプロジェクトをcloneする。

git clone https://github.com/leev/ngx_http_geoip2_module.git

現在の状態

これでビルドの準備が整った。

$ ll
(中略)
drwxr-xr-x  9 dezikomoe dezikomoe    4096 Jul 13 22:14 nginx-1.28.0/
-rw-r--r--  1 dezikomoe dezikomoe 1280111 Apr 23  2025 nginx-1.28.0.tar.gz
drwxr-xr-x  3 dezikomoe dezikomoe    4096 Jul 13 22:10 ngx_http_geoip2_module/

ビルド実行

Nginxの情報取得

ビルド実行にあたり、nginx -VでNginxの詳細な情報を取得する。

$ nginx -V
nginx version: nginx/1.28.0
built by gcc 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/run/nginx.pid --lock-path=/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_v3_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/home/builder/debuild/nginx-1.28.0/debian/debuild-base/nginx-1.28.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'

./configure

./configureMakefileを生成する。
先程のnginx -Vで出力されたconfigure arguments:の末尾に、--add-dynamic-module=../ngx_http_geoip2_moduleを足すだけ。

$ cd /tmp/nginx-geoip2-build/nginx-1.28.0
$ ./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--lock-path=/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-compat \
--with-file-aio \
--with-threads \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-http_v3_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-cc-opt='-g -O2 -fdebug-prefix-map=/home/builder/debuild/nginx-1.28.0/debian/debuild-base/nginx-1.28.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' \
--with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie' \
--add-dynamic-module=../ngx_http_geoip2_module

Makefileを確認

問題なければMakefileが無事に生成されているはず。どうなったか見てみよう。(トランプ風)

$ ll Makefile
-rw-r--r-- 1 dezikomoe dezikomoe 375 Jul 13 22:14 Makefile

make

Makefileが生成できたので、make modulesでビルドする。

$ make modules

モジュールを確認

objs/の下を確認すると、無事に目的のsoファイルがビルドできていた。

$ ll objs/*.so
-rwxr-xr-x 1 dezikomoe dezikomoe 119160 Jul 13 22:14 objs/ngx_http_geoip2_module.so*
-rwxr-xr-x 1 dezikomoe dezikomoe  93088 Jul 13 22:14 objs/ngx_stream_geoip2_module.so*

Nginxへ配置

生成したsoファイルを/usr/lib/nginx/にコピーしておく。

$ sudo cp objs/ngx_http_geoip2_module.so /usr/lib/nginx/modules/
$ sudo cp objs/ngx_stream_geoip2_module.so /usr/lib/nginx/modules/
$ ll /usr/lib/nginx/modules/*.so
-rwxr-xr-x 1 root root 119160 Jul 13 22:16 /usr/lib/nginx/modules/ngx_http_geoip2_module.so*
-rwxr-xr-x 1 root root  93088 Jul 13 22:16 /usr/lib/nginx/modules/ngx_stream_geoip2_module.so*

作業ディレクトリ削除

これでもう作業用のディレクトリは削除してOK。

$ rm -rf /tmp/nginx-geoip2-build/

mmdbを取得

MaxMindの公式サイトから、データベースのmmdbファイルを取得する。
まずはMaxMindアカウント作成からだ。

MaxMindのアカウントを作成する

GeoLite sign upからサインアップしてアカウントを作成する。メールアドレスがあればOK。
サインアップするとメールが飛んでくるのでパスワードを生成し、後はログインする方式。
ログインするとメールアドレスに対して認証コードが飛んでくるので、それを入力した。

mmdbをダウンロードする

MaxMindにアクセスし、左側のメニュー「GeoIP / GeoLite」から、「Download files」を選ぶ。
「GeoLite ASN」と「GeoLite Country」のmmdbをダウンロードする。
今回は「GeoLite City」は使わない事にした。スクレイピングBotを判定したいだけなので、不必要な個人情報は欲しくない。

mmdbを配置する

tar.gzから取り出したmmdbを好きな場所に置く。
今回はデフォルトの\usr\share\GeoIP\の下に置いた。ディレクトリは既に作成されていた。

$ \usr\share\GeoIP\
$ ll *mmdb
-rw-r--r-- 1 dezikomoe dezikomoe 12100745 Jul 14 17:15 GeoLite2-ASN.mmdb
-rw-r--r-- 1 dezikomoe dezikomoe  8844154 Jul 10 16:13 GeoLite2-Country.mmdb

nginx.conf更新

ビルドしたsoファイルとmmdbをnginx.confの設定に組み込む。

load_moduleを指定

eventsの前にload_moduleディレクティブを書く。

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /run/nginx.pid;

# ビルドしたGeoIP2
load_module modules/ngx_http_geoip2_module.so;

events {
    worker_connections  1024;
}
(後略)

geoip2を指定

httpブロックにgeoip2ディレクティブを書く。

http {
  (中略)
    # GeoIP2の設定
    geoip2 /home/dezikomoe/geoip2/GeoLite2-Country.mmdb {
        auto_reload 1h;
        $geoip_country_code country iso_code;
        $geoip_country_name country names en;
    }
    geoip2 /home/dezikomoe/geoip2/GeoLite2-ASN.mmdb {
        auto_reload 1h;
        $geoip_asn autonomous_system_number;
        $geoip_org autonomous_system_organization;
    }

起動前チェック

お約束の構文チェックを念のため実行してNginxを再起動すればOK。

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl reload nginx

mmdbの自動更新

mmdbは適宜更新が入るので、MaxMindから自動でmmdbを取得し更新する設定を入れておこう。
/etc/GeoIP.confで設定可能なようだ。

GeoIP.conf

見てみると、既に/etc/GeoIP.confが作成されていた。

$ ll /etc/GeoIP.conf
-rw-r--r-- 1 root root 1929 Jul 10  2025 /etc/GeoIP.conf

これをviなどで編集していく。

$ sudo vi /etc/GeoIP.conf

設定内容は以下の通り。
AccountIDは、ログイン時のユーザIDではないので注意。MaxMindにログイン後、「My Account」で確認できる。
LicenseKeyは同じく「My Account」から発行が必要である。発行する際に、丁寧にconfのダウンロードまでできる。

(前略)
AccountID MaxMindのアカウントID
LicenseKey MaxMindのライセンスキー

# Enter the edition IDs of the databases you would like to update.
# Multiple edition IDs are separated by spaces.
EditionIDs GeoLite2-Country GeoLite2-ASN
(後略)

更新実行

geoipupdateを実行して更新する。
ライセンスキー発行後の画面に表示される通り、ライセンスキーが有効になるまで数分のラグがある。

$ sudo geoipupdate

実際に、即座に実行してみたら認証に失敗して焦った。

$ sudo geoipupdate
Error retrieving updates: running the job processor: running job: unexpected HTTP status code: received HTTP status code: 401: {"code":"AUTHORIZATION_INVALID","error":"Your account ID or license key could not be authenticated."}

シェルスクリプトを作ってcrontabに入れておく。

$ cd ~/dezikomoe_sh
$ touch geoipupdate.sh
$ chmod +x geoipupdatesh
$ vi geoipupdate.sh
#!/bin/bash
geoipupdate /home/dezikomoe/dezikomoe_sh/geoipupdate.log 2>&1
$ sudo crontab -e