VPNブロックを安く実装する + 良質なVPN検出API

こんにちは、テスト2日前のmf_Miiです。
勉強から逃げていたらここに行き着きました(ｵｲ
本日は、WebアプリやMinecraftサーバーなどを運営する際に必須とも言える**匿名ネットワーク**からのアクセスをブロックする方法を考案してみましたので話してみたいと思います。
尚、学生の浅はかな考えなので間違えなどたくさんあると思います。ご容赦ください。
また、本記事を参考にした方法を試して裁判沙汰とかになっても一切の責任を負いません。

# 基礎中の基礎、VPN, Tor, Proxyを防ぐ目的
なぜWebサービスを運営するのにVPN, Tor, Proxyを防いだほうがいいのか、それはセキュリティを高めるためというのがあります。これらの殆どが、自分のIPアドレスを隠してアクセスするために使われるため、暴れ回られたり、不正アクセスされたときに犯人の特定が非常に難しくなったりします。よって、これらの匿名ネットワークからのアクセスを防いだほうがいいのです。

# 基本的な方法
個人ができる基本的なブロックは
・匿名ネットワークのIPを検出するAPIを利用する
ぐらいしかないかな～と思います。
(企業はそのIPの一覧情報を数十万とかかけて買っているようですが、個人には無理ですね)
## 具体的なサービス
| URL | 検出<br>(VPNGate) | 検出<br>(NordVPN) | 検出<br>(CloudflareWARP) | 無料枠 |
| --- | ------------- | ------------ | -------------------- | ----- |
| https://ip-api.com/ | ○ | ○ | ○ | 45/min |
| https://proxycheck.io/ | ○ | ○ | ○ | 1,000/day |
| https://iphub.info/ | ○ | ○ | ○ | 1,000/day |
| https://isproxyip.com/ | ○　| ○ | ○ | 1,000/day |
| https://iptrooper.net/ | ○ | ○ | ○ | 500/day |
| http://getipintel.net/ | ○ | ○ | ○ | 15/min<br>500/day |
| https://ipqualityscore.com/ | ○ | ○ | ○ | 5,000/mon |
| https://iphunter.info/ | ○ | ○ | ☓ | 1,000/day |
| https://vpnblocker.net/ | ☓ | ○ | ○ | 500/mon |
| https://vpnapi.io/ | ☓ | ○ | ☓ | 1,000/day |
| https://ip.teoh.io/api/vpn/ | ☓ | ○ | ☓ | 1,000/day |
| https://vpn-proxy-detection.ipify.org/ | ☓ | ☓ | ☓ | 1,000 |
| https://ipdata.co/ | ☓ | ☓ | ☓ | 1,500/day |
| https://ipapi.com/ | ☓ | ☓ | ☓ | 1,000/mon |

# 本題: とにかく安価に実装する
さて、上図に検出APIの一覧と検出率を示しましたが、アクセス制限がきつかったり、料金が高かったり...コストカットしたいですよね^^
ということで、できる限り高い検出率でブロックするような構成を組んでみたいと思います。(プログラムを組む必要はあるがね)

## 材料
・Cloudflare
・Nginx
・自分がかける言語の実行環境(Java, js, phpなど)
以上...少ないね

## 1. Torをブロックする
さて、まずはもう本来の目的利用のほうが圧倒的に少ないであろうTorネットワークを遮断します。これは自分のサーバーでやると効率が悪いのでCloudflareの設定でちゃちゃっとやっちゃいます。
Cloudflareの管理画面を開いて[セキュリティ]->[WAF]に移動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721577/c794e7d3-b635-7dd9-d702-e635e3d1d57a.png)
ファイアウォールルールを作成します(`国`が`Tor`のとき、`ブロック`します)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721577/754a3fa2-aaf2-c423-e134-29e16b93d8eb.png)
デプロイして完成です

## 2. VPNとかProxyをブロックする(その1)
では次に、VPNとかProxyをブロックしちゃいましょう
といっても、独自でVPN検出のプログラムを作るのはめちゃめんどいです。
ではどうするかって？簡単です。
**いろんなVPNのサービスのAPIからサーバーリストを取得してブロックすればいい**のです!!
今回はVPNGate, NordVPN, ExpressVPNの3つを実装してみます。プログラム打つ時間はないので説明だけします。
### リストを取得する
#### 2, 1-a. 公式のリストを探す
まず、公式がAPIを出しているか探しましょう。VPNGateの場合は出しているのでこれで終了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/721577/308ed00b-b0e8-5cb3-6489-d2b1c618ce34.png)

#### 2, 1-b. Githubの有志が探したのを見つける
Githubで一覧を取得するプログラムや、独自のクライアントのソースがあげられている可能性があります。ソースコードを見てみましょう。たぶんURLがあるはずです。
余談ですが、探してるうちにこんなもの見つけました。

https://github.com/qdm12/gluetun/wiki

#### 2, 1-c. 公式が提供するブラウザ拡張機能を解析する
ブラウザ拡張機能は大抵の場合、公式がGithubにおいています。Cloneしてプログラムを解析しましょう。
#### 2, 1-d. パケットキャプチャ
無料期間があるはずです。ダウンロードして仮想マシンに入れて、WireShark起動した状態でソフトを起動します。この時、WireSharkでSSL通信を見れるようにしておきましょう。
それっぽい通信を頑張って探してください。
#### 2, 1-e. ゴリ押し
URLを憶測で入力してサーバーリストを探します。
NordVPNの場合、自分はこの方法で初めて見つけました。

### 2, 2. リストをIPのリストに変換する
リストを取得することができました。VPNGateはIPが外向きのIPなのでいいのですが、その他のVPNではレスポンスに記載されているIPアドレス以上にDNSが登録されているので、追加でこれらのDNSレコードのIPを追加しちゃいましょう。
### 2, 3. 完成したIPの一覧をブロッカーに追加する
#### Nginxの場合
Nginxでブロックする場合、以下のような内容のファイルをincludeしてください。
```conf
deny 0.0.0.0;
deny x.x.x.x;
deny y.y.y.y;
...
```
reloadしてあげれば拒否されるようになります

#### Cloudflareの場合
Cloudflareでブロックしたほうがネットワークに負荷がかかりませんよね？じゃあCloudflare WAFのファイアウォールルールをAPIで更新してあげましょう。
てことで、ほい

https://api.cloudflare.com/#firewall-rules-update-individual-firewall-rule

## 3. APIを呼び出す
これまでの方法で特定のVPNをブロックすることができました。しかし、別のサービスを使ったら簡単にアクセスされてしまいます...
なので、一番最初に言ったAPIを呼び出してあげるようにしましょう。
上の方の表は、検出率が高い順、そしてだいたい安い順になっています。ぜひ活用してください。

# おまけ: 不正アクセス禁止法に触れない？
この方法、各VPNサービスのユーザーでもないのにAPIに接続しちゃって不正アクセスになっちゃわないかなと思って調べてみたところ、次のような記事を見つけました。

 https://blog.apar.jp/web/16132/

てことで多分大丈夫です(多分