おことわり
こちらのイベントのLT準備の思考整理用に慌てて作成した記事なので、めちゃめちゃ汚いです。申し訳ありません。
ご質問や、こここうした方が良いのでは?というご意見などは随時受け付けておりますので、是非コメントまで。
構成図
やったこと
- さくらのVPSを契約
- リバースプロキシとWebアプリを1個動かすだけなので最小スペック(メモリ1G/ストレージ50GB/100Mbps)を月額990円で契約
- 本当はWebARENA Indigoでストレージだけ20GBの同スペックVPSが349円(349円!?!?)で提供されてるのでこっちを使いたいが、プリペイド系クレジットカードとかデビッド弾く設定だったので断念(NTTPCさん...この歳までクレカ作ってない僕にも救いはありませんか...?)
- Cloudflareでドメインを取得
- Proxyさせたときにアクセス元IPを拾う方法をまだ調べていないので、当座DNSOnlyモードでリバースプロキシのグローバルIPへ飛ばさせている(要改善)
- VPS上で作成したFlaskアプリケーションをCloudflareTunnel経由で公開
- FlaskでTrustMasterアプリケーションを作成
- ブラウザからawsのグローバルIPチェックにリクエストを送信し、グローバルIPを取得
- 取得したグローバルIPをFlaskにGETで通知
- 受け取ったFlaskはその内容をwhitelistに追記する
- Flaskへのアクセスはコンテナ内に留めて、同じスタックのnginxから、かつ特定ドメインでのアクセス時のみアクセス許可する(後述するBedrockリバースプロキシ用のnginxとは処理が別)
- WireGuardで自宅サーバーへのVPNを構築
- nginxでUDPリバースプロキシを構築
- nginxでUDPのプロキシを通すには専用のオプションを付けてビルドしないと行けないため、まずはそのコンテナ構築
- 構築したUDP対応のnginxでwhitelistの内容に沿ったIPフィルタリングを行う
TrustMasterはCloudflareTunnel経由でVPS上のFlaskへ接続させ、nginx(BedrockServerへのアクセス)はCloudflareのDNS設定経由で直接接続させている。
bedrock用のドメインはDNSOnlyモードで公開しているためVPSのIPは秘匿出来ないことになるが、本来そのためのVPS。一応CloudflareTunnelがUDPに対応してくれるか、自分がCloudflareDNSのProxiedモードをちゃんと調べてアクセス元IPをnginxから拾えるように実装すればVPSも自宅サーバーも完全にIPを秘匿出来るようになる。(ちょっと安全過ぎる)
既知の問題
- nginxでconfigを動的に読み込むためには有償版のnginx plusを使わないといけないらしい
新しくユーザーが追加される度にnginx restartが必要となる。このシステム経由でログインしてるユーザーは、別のユーザーが新規にwhitelistの登録操作(に伴うnginx -s reload)したときに切断される - PCからだとめっちゃラグい
何故かiOS版とか今回検証用に購入したAndroid版とかからだと全然遅延を感じずに遊べるのに、PCから遊ぶとラグい。(チェスト開いたりエリトラ中のロケット花火が実行されるまで1~2秒くらいかかるという典型的な遅延状態)それぞれ同じ回線から接続しても同様の事象が再現するので、クライアント依存っぽい。
参考資料
nginx UDP対応版のビルド
nginx UDPの構成
WireGuard構築