IPアドレスから国や都市を判別する (GeoIP)

# GeoLite2
IP アドレスから国や都市を特定するための DB が MaxMind 社によって作られている。
製品版の **GeoIP2** と、オープンソース版の **GeoLite2** がある。

## Apacheモジュール
### GeoIP Legacy Apache Module
**mod_geoip2** は旧フォーマットしか読み込まないので、最新の **mod_maxminddb** を利用する必要がある模様。

> このモジュールは古いGeoIPフォーマット(dat)のためのものです。GeoIP2で利用されるMaxMind DBフォーマット(mmdb)を読み込むには、mod_maxminddbを参照してください。 [^1]

古い内容でも構わなければyumでepelリポジトリからインストール可能な模様。Apache 2.4は未対応。2015年6月時点で2015年4月14日更新のdatデータがインストールされる。

```bash
$ yum install mod_geoip --enablerepo=epel
```
```bash
$ yum list installed | grep -i geo
GeoIP.x86_64         1.6.5-1.el6        @epel
GeoIP-GeoLite-data.noarch
GeoIP-GeoLite-data-extra.noarch
geoipupdate.x86_64   2.2.1-2.el6        @epel
mod_geoip.x86_64     1.2.10-1.el6       @epel
```
```bash
$ ls -l /usr/share/GeoIP
合計 48696
lrwxrwxrwx. 1 root root       18  6月 18 00:00 2015 GeoIP.dat -> GeoLiteCountry.dat
lrwxrwxrwx. 1 root root       16  6月 18 00:00 2015 GeoIPASNum.dat -> GeoLiteASNum.dat
-rw-r--r--. 1 root root  4554540  4月 14 04:52 2015 GeoIPASNumv6.dat
lrwxrwxrwx. 1 root root       15  6月 18 00:00 2015 GeoIPCity.dat -> GeoLiteCity.dat
lrwxrwxrwx. 1 root root       17  6月 18 00:00 2015 GeoIPCityv6.dat -> GeoLiteCityv6.dat
-rw-r--r--. 1 root root  1420577  4月 14 04:52 2015 GeoIPv6.dat
-rw-r--r--. 1 root root  3865875  4月 14 04:52 2015 GeoLiteASNum.dat
lrwxrwxrwx. 1 root root       16  6月 18 00:00 2015 GeoLiteASNumv6.dat -> GeoIPASNumv6.dat
-rw-r--r--. 1 root root 19296245  4月 14 04:52 2015 GeoLiteCity.dat
-rw-r--r--. 1 root root 19945238  4月 14 04:52 2015 GeoLiteCityv6.dat
-rw-r--r--. 1 root root   775648  4月 14 04:52 2015 GeoLiteCountry.dat
```

[^1]: http://dev.maxmind.com/geoip/legacy/mod_geoip2/

### MaxMind DB Apache Module

> このモジュールは Apache 2.2 以上で libmaxminddb ライブラリを使って MaxMind DB ファイルを参照することが出来ます。 [^2]

[^2]: https://github.com/maxmind/mod_maxminddb/blob/master/README.md

#### システム要件
> このモジュールは Ubuntu でいう apache2-dev のような "dev" パッケージに相当するものを含む Apache 2.2 または 2.4 をインストールする必要があります。$PATH には apxs または apxs2 がある必要があります。
> また libmaxminddb C ライブラリをインストールする必要があります。

#### インストール

##### libmaxminddb [^3]
[^3]: https://github.com/maxmind/libmaxminddb

```bash
yum install epel-release
yum install libmaxminddb*
#sh -c "echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf"
#ldconfig
ldconfig -p | grep libmaxminddb
        libmaxminddb.so.0 (libc6,x86-64) => /lib64/libmaxminddb.so.0
        libmaxminddb.so (libc6,x86-64) => /lib64/libmaxminddb.so
```

##### mod_maxminddb
GitHubから[最新のmod_maxminddbのtarball](https://github.com/maxmind/mod_maxminddb/releases)をダウンロードしてインストールする。

```bash
yum install httpd-devel gcc make
curl -LO https://github.com/maxmind/mod_maxminddb/releases/download/1.0.1/mod_maxminddb-1.0.1.tar.gz
tar vzxf mod_maxminddb-1.0.1.tar.gz
cd mod_maxminddb-1.0.1
./configure
make install
ldd /usr/lib64/httpd/modules/mod_maxminddb.so
        linux-vdso.so.1 =>  (0x00007fffbc99c000)
        libmaxminddb.so.0 => /usr/local/lib/libmaxminddb.so.0 (0x00007fc21ad2d000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fc21a993000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fc21a70f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fc21b134000)
cd ..
rm -fr mod_maxminddb-1.0.1.tar.gz mod_maxminddb-1.0.1
```
### DBデータの取得
```bash
mkdir /usr/local/share/GeoIP
cd /usr/local/share/GeoIP
curl -LO http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
curl -LO http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
gunzip GeoLite2-Country.mmdb.gz
gunzip GeoLite2-City.mmdb.gz
ls -lah /usr/local/share/GeoIP/GeoLite2-*
-rw-r--r--. 1 root root  63M  7月  5 21:31 GeoLite2-City.mmdb
-rw-r--r--. 1 root root 2.2M  7月  5 21:29 GeoLite2-Country.mmdb
```

### 国別の処理の設定
```bash
cat << _EOF_ > /etc/httpd/conf.d/maxminddb.conf
```
```apache
<IfModule mod_maxminddb.c>
    MaxMindDBEnable On
    MaxMindDBFile DB /usr/local/share/GeoIP/GeoLite2-Country.mmdb
    MaxMindDBEnv MM_COUNTRY_CODE DB/country/iso_code
</IfModule>

<IfModule mod_maxminddb.c>
    SetEnvIf MM_COUNTRY_CODE ^(RU|DE|FR) BlockCountry
    Deny from env=BlockCountry
#    Require expr %{ENV:MM_COUNTRY_CODE} !~ ^(RU|DE|FR) # Apache 2.4 用、未検証
</IfModule>
```
```bash
_EOF_
```
ロードバランサーを経由している場合は以下を追加することで対応できる。

```apache
<IfModule remoteip_module>
    RemoteIPHeader          X-Forwarded-For
    RemoteIPProxiesHeader   X-Forwarded-By
</IfModule>
```
### Apacheの再起動
Apacheを再起動して設定を適用。

```bash
cat /etc/httpd/conf/httpd.conf | grep max
LoadModule maxminddb_module   /usr/lib64/httpd/modules/mod_maxminddb.so
```
```bash
httpd -t
Syntax OK
```
```bash
service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [  OK  ]
```

モジュールが読み込まれているのを確認。

```bash
httpd -M | grep max
 maxminddb_module (shared)
```

ちゃんと環境変数が取れているかの確認用テストコード。プロキシーを通して確認。

```html+php:test.php
<html>
<head>
<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>
<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>
```

### 自動アップデート
http://dev.maxmind.com/geoip/geoipupdate/
自動アップデートプログラムが用意されているらしい。

# Apache 関連記事
* [Apacheセキュリティ設定](http://qiita.com/bezeklik/items/1c4145652661cf5b2271)
* [Apache HTTP Server のサポート期限](http://qiita.com/bezeklik/items/7e2c02c3eabd2a416231)
* [Apache のログをコマンドラインで集計する](http://qiita.com/bezeklik/items/f5c292c4360cde140bef)
* [Apache の情報をコマンドラインで取得する](http://qiita.com/bezeklik/items/7bbfcbcfeb05c1d57fec)
* [IPアドレスから国や都市を判別する (GeoIP)](http://qiita.com/bezeklik/items/927e1c52c8c0aefb1f06)
* [Apache チューニング スクリプト](http://qiita.com/bezeklik/items/85f4001a2517be5fe4c0)

# 参照情報