MaxMind DB による IP アドレスでの国の判別

## GeoIP2
https://dev.maxmind.com/
米国マサチューセッツ州に本社を置く MaxMind 社によって提供されている [GeoIP](https://dev.maxmind.com/geoip/) は特定の IP アドレスに関する情報を知ることができるサービス。

## MaxMind DB
[MaxMind DB](https://dev.maxmind.com/maxmind-db/) は高度に最適化された IP アドレスに関する情報を柔軟なデータベース形式で格納するための新しいファイル形式。

[このフォーマットの仕様](https://github.com/maxmind/MaxMind-DB/blob/master/MaxMind-DB-spec.md)は GitHub の [MaxMind-DB](https://github.com/maxmind/MaxMind-DB) にある。 [libmaxminddb](https://github.com/maxmind/libmaxminddb) はこれらのデータベースを読み取るための C ライブラリが含まれている。

GeoIP2 データベースは MaxMind DB形式で利用できる。

## libmaxminddb
https://github.com/maxmind/libmaxminddb
http://maxmind.github.io/libmaxminddb/
libmaxminddb ライブラリは MaxMind DB ファイル (`.mmdb`) を読み込むための C ライブラリを提供する。

rpm パッケージ は EPEL および PUIAS Computational リポジトリで libmaxminddb 1.2.0 がインストールできる。

### インストール
```bash
cd ~
curl -LO https://github.com/maxmind/libmaxminddb/releases/download/1.3.2/libmaxminddb-1.3.2.tar.gz
tar xf libmaxminddb-1.3.2.tar.gz
cd libmaxminddb-1.3.2
./configure
make
make check
sudo make install
sudo sh -c "echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf"
sudo ldconfig
ldconfig -p | grep libmaxminddb
```
```
	libmaxminddb.so.0 (libc6,x86-64) => /usr/local/lib/libmaxminddb.so.0
	libmaxminddb.so (libc6,x86-64) => /usr/local/lib/libmaxminddb.so
```

## mod_maxminddb
https://github.com/maxmind/mod_maxminddb
mod_maxminddb モジュールは Apache 2.2 以降で libmaxminddb ライブラリを使用してMaxMind DB ファイルを問い合わせることができる。

rpm パッケージでインストールできるリポジトリはない模様。

### インストール
```bash
cd ~
curl -LO https://github.com/maxmind/mod_maxminddb/releases/download/1.1.0/mod_maxminddb-1.1.0.tar.gz
tar xf mod_maxminddb-1.1.0.tar.gz
cd mod_maxminddb-1.1.0
./configure
make
make check
sudo make install
cat /etc/httpd/conf/httpd.conf | grep maxmind
```
```
LoadModule maxminddb_module   /usr/lib64/httpd/modules/mod_maxminddb.so
```

### 設定ファイル
```apache:/etc/httpd/conf.d/mod_maxminddb.conf
<IfModule mod_maxminddb.c>
    MaxMindDBEnable On
    MaxMindDBFile   COUNTRY_DB /usr/local/share/GeoIP/GeoLite2-Country.mmdb
    MaxMindDBFile   CITY_DB    /usr/local/share/GeoIP/GeoLite2-City.mmdb
    MaxMindDBEnv    MM_CONTINENT_CODE              COUNTRY_DB/continent/code
#    MaxMindDBEnv    MM_CONTINENT_GEONAME_ID        COUNTRY_DB/continent/geoname_id
    MaxMindDBEnv    MM_CONTINENT_NAME              COUNTRY_DB/continent/names/en
#    MaxMindDBEnv    MM_CONTINENT_NAME_JA           COUNTRY_DB/continent/names/ja
    MaxMindDBEnv    MM_COUNTRY_CODE                COUNTRY_DB/country/iso_code
#    MaxMindDBEnv    MM_COUNTRY_GEONAME_ID          COUNTRY_DB/country/geoname_id
    MaxMindDBEnv    MM_COUNTRY_NAME                COUNTRY_DB/country/names/en
#    MaxMindDBEnv    MM_COUNTRY_NAME_JA             COUNTRY_DB/country/names/ja
#    MaxMindDBEnv    MM_COUNTRY_IS_IN_EU            COUNTRY_DB/country/is_in_european_union
#    MaxMindDBEnv    MM_CITY_NAME                   CITY_DB/city/names/en
#    MaxMindDBEnv    MM_CITY_NAME_JA                CITY_DB/city/names/ja
#    MaxMindDBEnv    MM_CONTINENT_CODE              CITY_DB/continent/code
#    MaxMindDBEnv    MM_CONTINENT_GEONAME_ID        CITY_DB/continent/geoname_id
#    MaxMindDBEnv    MM_CONTINENT_NAME              CITY_DB/continent/names/en
#    MaxMindDBEnv    MM_CONTINENT_NAME_JA           CITY_DB/continent/names/ja
#    MaxMindDBEnv    MM_COUNTRY_CODE                CITY_DB/country/iso_code
#    MaxMindDBEnv    MM_COUNTRY_GEONAME_ID          CITY_DB/country/geoname_id
#    MaxMindDBEnv    MM_COUNTRY_NAME                CITY_DB/country/names/en
#    MaxMindDBEnv    MM_COUNTRY_NAME_JA             CITY_DB/country/names/ja
#    MaxMindDBEnv    MM_COUNTRY_IS_IN_EU            CITY_DB/country/is_in_european_union
#    MaxMindDBEnv    MM_REGISTERED_COUNTRY_ISO_CODE CITY_DB/registered_country/iso_code
#    MaxMindDBEnv    MM_REGISTERED_COUNTRY_NAMES    CITY_DB/registered_country/names/en
#    MaxMindDBEnv    MM_REGISTERED_COUNTRY_NAMES_JA CITY_DB/registered_country/names/ja
#    MaxMindDBEnv    MM_REGISTERED_COUNTRY_IS_IN_EU CITY_DB/country/is_in_european_union
#    MaxMindDBEnv    MM_LOCATION_LATITUDE           CITY_DB/location/latitude
#    MaxMindDBEnv    MM_LOCATION_LONGITUDE          CITY_DB/location/longitude
#    MaxMindDBEnv    MM_LOCATION_TIME_ZONE          CITY_DB/location/time_zone
#    MaxMindDBEnv    MM_POSTAL_CODE                 CITY_DB/postal/code
#    MaxMindDBEnv    MM_SUBDIVISION_1_GEONAME_ID    CITY_DB/subdivisions/0/geoname_id
#    MaxMindDBEnv    MM_SUBDIVISION_1_ISO_CODE      CITY_DB/subdivisions/0/iso_code
#    MaxMindDBEnv    MM_SUBDIVISION_1_NAMES         CITY_DB/subdivisions/0/names/en
#    MaxMindDBEnv    MM_SUBDIVISION_1_NAMES_JA      CITY_DB/subdivisions/0/names/ja
</IfModule>
```

## geoipupdate
https://github.com/maxmind/geoipupdate
https://dev.maxmind.com/geoip/geoipupdate/
GeoIP アップデートプログラムは GeoIP2 および GeoIP レガシーバイナリデータベースの自動アップデートを実行する。 CSV データベースはサポートされていない。

`geoipupdate` コマンドを実行することで `/usr/local/share/GeoIP` 配下に最新の `GeoLite2-Country.mmdb` と `GeoLite2-City.mmdb` をダウンロードできる。

rpm パッケージは Atomic リポジトリで geoipupdate 2.2.2 がインストールできる。

### インストール
```bash
cd ~
curl -LO https://github.com/maxmind/geoipupdate/releases/download/v3.1.0/geoipupdate-3.1.0.tar.gz
tar xf geoipupdate-3.1.0.tar.gz
cd geoipupdate-3.1.0
./configure
make
sudo make install
/usr/local/bin/geoipupdate
ls /usr/local/share/GeoIP
```
```
GeoLite2-City.mmdb  GeoLite2-Country.mmdb
```

### Cron 設定
```:cron
15 14 * * 6 /usr/local/bin/geoipupdate
```


## mod_remoteip
ELB などのロードバランサーを経由している場合は `RemoteIPHeader` に `X-Forwarded-For` を指定することで対応できる。

```apache
<IfModule remoteip_module>
    RemoteIPHeader          X-Forwarded-For
    RemoteIPProxiesHeader   X-Forwarded-By
</IfModule>
```

VirtualHost を利用している場合は `<VirtualHost>` ディレクティブ内に記述しないと反映されないので注意。

```bash
httpd -t
service httpd restart
httpd -M | grep max
```


## 動作テスト

### テストページ
```php:test.php
<html>
<head>
<title>mod_maxminddb</title>
<style>
table { border-collapse: collapse; }
th, td{ border: 1px solid #CCC; padding: 0.3em 0.5em; font-size: 11px; font-family: Helvetica, Arial; }
th { text-align: right; background-color: #EEE; }
</style>
</head>
<body>
<h1>mod_maxminddb</h1>
<table>
<?php foreach ($_SERVER as $key => $value): ?>
<?php if (substr($key, 0, 2) === 'MM'): ?>
<tr><th><?php echo $key; ?></th><td><?php echo $value; ?></td></tr>
<?php endif; ?>
<?php endforeach; ?>
</table>
</body>
</html>
```