はじめに
WordpressのVPSへの移行に伴って、ついでに国外IPアドレスからのアクセスを拒否することにした。(wp-login.php
へのブルートフォースアタックがまじうざい)この時、wordpressが以下のようなdockerコンテナの多段構成の下で動いているので、中心のnginxコンテナでIPアドレスフィルタリングをすることにした。
nginx-proxy <--(front bridge)--> nginx <--(wordpress用back bridge)--> wordpress
※ただし、nginx-proxyにnginxからパラメータ渡せばそっちでフィルタリングできる気もする。
設定状況はすべて以下の記事に準じているので、先にそっちに目を通してほしい。
参考:さくらのレンタルサーバからConoHa VPSのdocker環境へWordpressを引っ越しメモ
allowip.conf
の作成
国内からのアクセスのみを許すための、nginx設定ファイルallowip.conf
を作成する。まずは、https://ipv4.fetus.jp/ さんより日本のIPアドレスリストを手に入れる。
$ cd /tmp
$ wget https://ipv4.fetus.jp/jp.txt
それを加工して許可するIPアドレスプールの設定ファイルを作成する。nginxのルールだと、ホワイトリスト形式は、allow→deny all。形式は、allow 192.168.0.1/24;
という感じ。
$ sed -e "/^#\|^$/d" jp.txt| sed -e "s/^/allow /" -e "s/$/;/" > allowip.conf
$ echo "denly all;" >> allowip.conf
最後に、nginxのconf.dへ放り込む。
$ cp allowip.conf ~/apps/wordpress/setting/nginx/conf.d/
default.conf
の編集
リバースプロキシ越しだと、nginxから内部のプライベートIPアドレスが見えている。そのため、実際のクライアントアドレスは見ることができない。httpヘッダに転送されてきたクライアントの実IPアドレスが乗っているので、nginxでプライベートアドレスをその実IPアドレスに書き換えてしまう(remote_addrの書き換え)。
具体的にはnginx/conf.d/default.conf
の以下の4点をチェックする
-
set_real_ip_from
(serverディレクティブ) -
real_ip_header
(serverディレクティブ) -
proxy_set_header X-Real-IP
(locationディレクティブ) -
proxy_set_header X-Forwarded-For
(locationディレクティブ)
実際の設定ファイルは以下のような状態。
(前略)
server {
listen 20092;
server_name <your_domain>;
(中略)
set_real_ip_from 172.18.0.0/16; # ここ
real_ip_header X-Forwarded-For; # ここ
location / {
try_files $uri @proxy;
}
location @proxy {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; # ここ
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # ここ
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_pass http://wordpress:80;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
error_page 500 501 502 503 504 /500.html;
}
nginxの再起動
最後にnginxを再起動。(以下の例ではまるごと再起動している)
$ docker-compose restart
まとめ
ZenmateなどのVPNサービスを利用して国外からのアクセスが弾かれていることを確認してみよう。docker logsで見ると以下のようなログが吐き出されていて、ruleによりfobiddenなため、http 403を返しているのがわかる。
$ docker logs wordpress-proxy
[error] 5#5: *31 access forbidden by rule, client: *.*.*.*, server: *.*, request: "GET /favicon.ico HTTP/1.1", host: "*.*", referrer: "*.*"
"GET /favicon.ico HTTP/1.1" 403 (後略)
なお、IPアドレスの国別割当は割と動的らしいので、適宜アップデートしてやると良い。