CentOS 6.6 - mod_geoipでWebサーバに対するアクセスを国別で制限してみた。
例えば、VPSなどでWebサイトを運営していて海外からのアクセスが鬱陶しい場合はありませんか??
Webサイトが国内向けで、広告収入など気にしない場合に海外からのアクセスはサーバのリソースを無駄に消費するだけだと思います。
アクセスは国内からだけ!中国とロシアからだけはアクセスさせたくない!などの要望を簡単に叶えてくれるのが mod_geoipです。(apache、nginxどちらでも使えます)
本投稿では、mod_geoipのインストール方法とApacheの設定方法を紹介します。
はじめに
作業環境
- カゴヤ・クラウド/VPS type A
- CentOS 6.6
- Apache 2.2.15
Yumリポジトリを追加
Yumのリポジトリ「EPEL」を追加します。
# yum install epel-release
Webサーバを構築
Apacheをインストール
Apacheをインストールします。
# yum install httpd
VirtualHostの追加
Webサーバには、IPアドレスでアクセスできるようVirtualHostの設定を追加します。
# vim /etc/httpd/conf.d/virtualhost.conf
NameVirtualHost *:80 <virtualhost *:80> DocumentRoot /var/www/html ServerName <WebサーバのIPアドレス> ErrorLog logs/<WebサーバのIPアドレス>-error_log CustomLog logs/<WebサーバのIPアドレス>-access_log common </virtualhost>
テストページを作成
テストページは、先ほどVirtualHostで指定したドキュメントルートに「index.html」を作成します。
# echo "mod_geoip testpage" > /var/www/html/index.html
Webサーバの起動と自動起動設定に追加
Webサーバを起動します。
# service httpd start
サーバ起動にWebサーバも起動するよう自動起動設定に追加します。
# chkconfig httpd on
テストページを確認
WebサーバのIPアドレスにアクセスし、テストページが表示されるか確認します。
ブラウザでのアクセスが面倒なので、コマンドで確認します。
# curl -s http://<サーバIPアドレス>/ mod_geoip testpage
テストページが表示されていることを確認できました。
mod_geoipをインストールする
mod_geoipをインストール
Yumリポジトリの「EPEL」指定して、mod_geoipをインストールします。
# yum install mod_geoip
mod_geoipの初期設定
mod_geoipをインストールすると、「/etc/httpd/conf.d/geoip.conf」が自動生成されるので設定を追加します。
# vim /etc/httpd/conf.d/geoip.conf
LoadModule geoip_module modules/mod_geoip.so <IfModule mod_geoip.c> GeoIPEnable On GeoIPDBFile /usr/share/GeoIP/GeoIP.dat Standard </IfModule> ##日本からのアクセスを拒否する <DirectoryMatch /> SetEnvIf GEOIP_COUNTRY_CODE JP BlockCountry Order allow,deny Allow from all Deny from env=BlockCountry </DirectoryMatch>
動作テストで分かりやすいように日本からアクセスを拒否するよう設定します。
Apacheを再起動
Apacheを再起動すれば、mod_geoipがモジュールとして読み込まれます。
# service httpd restart
無事、再起動が終われば、mod_geoipの準備完了です。
動作確認
「geoip.conf」に日本からのアクセスのみ、拒否するよう設定したので正しく動作しているか確認します。
テストページにアクセス
WebサーバのIPアドレスにアクセスして、テストページが表示されるか確認します。
# curl -s http://<サーバIPアドレス>/ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>403 Forbidden</title> </head><body> <h1>Forbidden</h1> <p>You don't have permission to access / on this server.</p> <p>Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.</p> <hr> <address>Apache/2.2.15 (CentOS) Server at <WebサーバIPアドレス>/ Port 80</address> </body></html>
403エラーが表示されているので、設定通りに動作していることがわかります。
GeoIPとGeoLiteのデータベースを更新
mod_geoipが参照しているデータベースは、月に1回(たしか2日)更新されます。
データベースの定期更新は必須です。もし、更新を忘れると意図しないアクセスを拒否や許可する可能性があります。
データベースを更新
基本的なデータベースは、「geoipupdate」コマンドで更新できます。
※geoipupdateコマンドでは、「GeoLiteCountry.dat」「GeoLiteCity.dat」「GeoLiteASNum.dat」が更新できます。
# geoipupdate
その他データベースを追加
「geoiplookup」コマンドを更に便利にするのデータベースを追加します。
※「-f」オプションは、エラーを無視することができます。
# curl -f http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz | zcat > /usr/share/GeoIP/GeoIPv6.dat # curl -f http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz | zcat > /usr/share/GeoIP/GeoIPCityv6.dat # curl -f http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz | zcat > /usr/share/GeoIP/GeoIPASNum.dat
加えて、シンボリックリンクを作成を行います。 1度行えば、それ以降は必要ありません。
# cd /usr/share/GeoIP/ # ln -s GeoLiteCity.dat GeoIPCity.dat # ln -s GeoLiteCountry.dat GeoIPCountry.dat
データベース更新自動化スクリプト
データベースの定期更新が面倒な方は、シェルスクリプトをCRONで実行することをお勧めします。
CRONの準備
カゴヤ・クラウド/VPSでは、crontabがインストールされていません。そのため、crontabをインストールします。
# yum install -y crontabs
サーバ起動時にCRONが自動起動するよう設定します。
# service crond start # chkconfig crond on
データベース定期更新シェルスクリプト
こんな感じでいいかな・・・
# vim /etc/cron.weekly/geoip_database_update.sh
#!/bin/sh GEOIP_URL01="http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz" GEOIP_URL02="http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz" ####GeoIPデータベースの場所####################################### GEOIP_FILE_IPv6="/usr/share/GeoIP/GeoIPv6.dat" GEOIP_FILE_IPv6_NEW="/usr/share/GeoIP/GeoIPv6.dat.NEW" GEOIP_FILE_LiteCity_IPv6="/usr/share/GeoIP/GeoIPCityv6.dat" GEOIP_FILE_LiteCity_IPv6_NEW="/usr/share/GeoIP/GeoIPCityv6.dat.NEW" ################################################################## /usr/bin/geoipupdate curl -f $GEOIP_URL01 | zcat > $GEOIP_FILE_IPv6_NEW 1>/dev/null 2>/dev/null if [ $ -eq 1 ]; then exit 1 fi curl -f $GEOIP_URL02 | zcat > $GEOIP_FILE_LiteCity_IPv6_NEW 1>/dev/null 2>/dev/null if [ $ -eq 1 ]; then exit 1 fi ##「-s」オプションは、ダウンロードファイルが0KB以上であることを確認している if [ -s $GEOIP_FILE_IPv6_NEW ]; then mv -f $GEOIP_FILE_IPv6_NEW $GEOIP_FILE_IPv6 fi if [ -s $GEOIP_FILE_LiteCity_IPv6_NEW ]; then mv -f $GEOIP_FILE_LiteCity_IPv6_NEW $GEOIP_FILE_LiteCity_IPv6 fi exit 0
/etc/cron.weekly 直下に設置することで、週1回データベースが更新されます。
また、シェルスクリプトには実行権限を与える必要があります。
# chmod +x /etc/cron.weekly/geoip_database_update.sh
アクセス制限のサンプル
mod_geoipで可能なアクセス制限の記述方法を紹介します。
日本からのみ、アクセスを許可する設定
<DirectoryMatch / > SetEnvIf GEOIP_COUNTRY_CODE JP AllowCountry Order deny,allow Deny from all Allow from env=AllowCountry </DirectoryMatch>
国と大陸からのアクセスを許可する設定
日本・アメリカ・北アメリカ・南アメリカ・オセアニア・ヨーロッパからアクセスを許可する設定
<DirectoryMatch / > SetEnvIf GEOIP_COUNTRY_CODE US AllowCountry SetEnvIf GEOIP_COUNTRY_CODE JP AllowCountry SetEnvIf GEOIP_CONTINENT_CODE SA AllowContinent SetEnvIf GEOIP_CONTINENT_CODE EU AllowContinent SetEnvIf GEOIP_CONTINENT_CODE NA AllowContinent SetEnvIf GEOIP_CONTINENT_CODE OC AllowContinent Order deny,allow Deny from all Allow from env=AllowCountry Allow from env=AllowContinent </DirectoryMatch>
GEOIP_CONTINENT_CODEで選択できる大陸一覧
AF - アフリカ
AS - アジア
EU - ヨーロッパ
NA - 北米
OC - オセアニア
SA - 南アメリカ
中国とロシアからのアクセスを拒否する設定
<DirectoryMatch /> SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry Order allow,deny Allow from all Deny from env=BlockCountry </DirectoryMatch>