Torからのアクセスをnginxでブロックする
はじめに
Torは、プライバシー保護という観点で自身は決して悪いものだとは思っていません。サービスを運用する上で個人の特定ができない事で起こりうる問題の予防のためにこのような対応の選択をせざるを得ないというだけで、Torそのものを否定したいわけではない事だけ始めに書いておきます。
本題
Torは、ざっくり言うと複数のサーバーを経由することで秘匿性を実現しています。一番最後に経由したノードからインターネットに接続し、接続先へ通信します。一番最後に経由したノードはTor出口ノードと呼ばれています。接続先のサーバーのログに残るIPアドレスはこの出口ノードのIPアドレスであるので、現在出口ノードになっているサーバーのIPアドレスさえ分かればそれらをnginxでブロックするのは容易です。
Torの出口ノードはtorprojectで管理されているので、このエンドポイントをcurlで叩いてIPを取得、nginxのdenyディレクティブにIPを追加するようなファイルを動的に生成するスクリプトをcronで定期的に実行させれば、出口ノードに変動があったとしてもなるべくリアルタイムに更新させることができます。
以下で、動的にIPを取得し、block_tor_ip.confに追加、nginxをリロードさせます。
#!/bin/bash result=`curl -s https://check.torproject.org/torbulkexitlist?ip=1.1.1.1` if [ $? -ne 0 ]; then echo "Cannot get address." exit 1 fi echo "${result}" | sed '/^#/ !s/^/deny /g; s/$/;/g' >> block_tor_ip.conf nginx -t nginx -s reload
ファイルは以下のように生成され、/etc/nginx/conf.d/*.confはデフォルトでincludeされるので、リロードされれば適用されます。 実際は、数百行ありますが、長いので割愛してます。
$ head conf.d/block_tor_ip.conf deny 54.37.16.241; deny 46.182.106.190; deny 109.70.100.32; deny 51.15.43.205; deny 51.75.64.23; deny 185.205.210.245; deny 94.32.66.48; deny 82.221.128.191; deny 109.70.100.35;
検証
AWSでインスタンスを立てて、試しに上記のスクリプトを動作させTorからアクセスしてみます。 nginxをstartさせると、デフォルト画面がレンダリングされます。
スクリプトを発火させ、denyのIPが追加されているnginxを起動します。
Tor起動し、アクセスすると
403を返し、ブロックされました。
最後に
本番環境で運用するならば、locationディレクティブを使って特定のURLの時だけ(例えば、決済画面とかユーザーの問合せ画面とか)denyを適用させるとかもありかなと思いました。