以前apacheのGeoIPモジュールを使用して海外からのアクセスを拒否する設定をしていました。
GeoIPを使用してWebサーバのアクセスを国内だけに制限する
今回はNginxで拒否する方法を考えてみました。
1.国別のIPアドレスリストを取得
国別のIPv4アドレスリストを加工して公開してくださっている方がいるので、これを利用します。
― 世界の国別 IPv4 アドレス割り当てリスト ―
http://nami.jp/ipv4bycc/
このサイトから、CIDR表記版のgzipファイルをダウンロードします。
# wget http://nami.jp/ipv4bycc/cidr.txt.gz # gunzip cidr.txt.gz
このファイルには、CIDR表記のIPアドレスと、そのIPアドレスが割り当てられている国名コードが記載されています。
AD 85.94.160.0/19 AD 91.187.64.0/19 AD 109.111.96.0/19 AD 185.4.52.0/22 AD 185.33.0.0/22 AD 185.87.36.0/22 AD 185.87.40.0/21 AD 185.106.124.0/22 AD 185.121.12.0/22 AD 194.158.64.0/19 ...
2.Nginxのアクセス元IPアドレス許可ルールを作成
今回は日本国内からのアクセスは許可し、海外からのアクセスは拒否する設定とします。
まず、deny allで全拒否します。
# deny all;
次に先程ダウンロードした国別のIPv4アドレスリストから
sedコマンドで日本のIPアドレス行をピックアップ&加工して
Nginxの仕様に合わせた許可IPアドレスリストファイル /etc/nginx/allow.conf を作成します。
# sed -n 's/^JP\t\(.*\)/allow \1;/p' cidr.txt > /etc/nginx/allow.conf
ちなみにapacheだとこんな感じ。
# echo "Order allow,deny" > .htaccess # echo "Allow from all" >> .htaccess # sed -n 's/^JP\t/Allow from /p' cidr.txt >> .htaccess
3.NginxのConfigに組み込み
Nginxで、拒否IPアドレスリストファイル /etc/nginx/allow.conf をincludeします。
Nginxは基本的に上から順に適用されるので、includeする箇所としては、
グローバル設定の /etc/nginx/nginx.conf で、conf.d/*.conf を読み込む前としてしまいます。
# vi /etc/nginx/nginx.conf http { ... include /etc/nginx/allow.conf; include /etc/nginx/conf.d/*.conf; }
Nginxをreloadして反映させます。
# /etc/init.d/nginx configtest # /etc/init.d/nginx reload
設定後は、日本国内から問題なくアクセスできることと
Nginxのエラーログに該当のIPアドレスからのアクセス拒否が記録されていることを確認します。
Nginxのエラーログには、アクセス拒否は下記のように、’access forbidden by rule’と記録されます。
2017/01/25 23:23:54 [error] 8317#8317: *980 access forbidden by rule, client: 114.40.25.38, server: localhost, request: "GET /pic01.jpg HTTP/1.1", host: "133.130.88.106"
ちなみにスクリプトにするとこんな感じ。
[root@vps ~]# cat /home/harada/script/nginx.sh #!/bin/bash cd /usr/local/src/ wget http://nami.jp/ipv4bycc/cidr.txt.gz gunzip cidr.txt.gz echo 'deny all;' > /etc/nginx/conf.d/allow.conf sed -n 's/^JP\t\(.*\)/allow \1;/p' cidr.txt >> /etc/nginx/conf.d/allow.conf /etc/rc.d/init.d/nginx reload rm -f cidr.txt exit
日本以外にも許可したい国があれば、国名コードを適宜変えてやれば応用は効くので
結構便利で楽ちんです。