やりたいこと
タイトル通り、Dynmapをhttpsで見たい。
前提
DynmapはMinecraftのサーバプラグインで、ゲームの内部状況をブラウザから確認できるようになる、人気のプラグインです。
ソフトウェア | ポート番号 | 通信プロトコル |
---|---|---|
Apache | 80, 443 | http, https |
Minecraft server | 25565 | 独自プロトコル |
Dynmap | 8123 | http |
大雑把な図ですが、おおよそこのような関係になります。ポート番号はデフォルト値です。
問題はDynmapです。Dynmapは内部にスタンドアローンなWebサーバを内蔵していますが、Apacheとの競合を防ぐため、8123番ポートを利用します。そのため、サーバは80, 443, 25565の他に8123番ポートも開放しなければなりません。
他のポートは開放する他ありませんが、Dynmapのポートは開放したくありません。
もっといえば、httpsで通信したいです。
さて、どうしましょう。
リバースプロキシ(Reverse Proxy)を使う
リバースプロキシを使うことで解決できます。
リバースプロキシとは、外部ネットワークの接続に対し、何らかの処理を行い、内部サーバに引き渡す、いわば中継機能を果たす機器のことです。
とても分かりやすい図があったので、お借りしました。
― 【ITSakura】プロキシサーバとリバースプロキシサーバの違い
リバースプロキシが外部の受付役となっていることが分かりますね。今回、ハード的にサーバは1つですが、やることは同じです。
Apacheに対するリクエストはApacheに、Dynmapに対するリクエストはDynmapにそれぞれ内部で振り分けることで、開放ポートを減らすことができます。
リバースプロキシ適用
リバースプロキシを使った図が以下になります。(8123番ポートはイメージです)
リバースプロキシはApacheに備わっている機能なので、リバースプロキシはApache内部にあります。
リバースプロキシが受け取ったリクエストのうち、Dynmapに関するものだけ8123番ポートに向けて、リクエストを送ります。
Dynmapの応答はリバースプロキシを通じて、外部に送信されます。
このように、リバースプロキシを使うと内部サーバを隠蔽し、無用なポート開放を防ぐことができます。
リバースプロキシの実装
Apacheであれば、mod_proxyを使って簡単に実装できます。
今回はhttpsの通信に対して実装するので、VirtualHost
を使います。(https化はすでにされているものとします)
...
# スラッシュ補完(後述)
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_URI} /dynmap$
RewriteRule /* %{REQUEST_URI}/ [R=301,L]
</IfModule>
# リバースプロキシ
<VirtualHost *:443>
ServerName sample.com:443
<IfModule mod_proxy.c>
ProxyRequests Off
ProxyPass /dynmap http://localhost:8123
</IfModule>
...
</VirtualHost>
ProxyRequests
はフォワードプロキシをオンにするかどうかの記述なので、今回はoffにします。
ProxyPass
の使い方は、
ProxyPass <外部からのリクエスト> <内部サーバ先>
です。非常にシンプルですね。
sample.com:443/dynmap
へのリクエストは内部のlocalhost:8123
に投げるようにしています。
これで、https://sample.com/dynmap
にアクセスすると、Dynmapの画面が表示されます。
これでポートを開放をせず、外部からhttpsを使ってDynmapにアクセスすることができました。
補足:スラッシュ補完
リバースプロキシの前にmod_rewriteモジュールを使ってスラッシュ補完を行っています。
つまり、
https://sample.com/dynmap
をhttps://sample.com/dynmap/
に書き換えるということです。
スラッシュ補完をしないと、真っ白な画面が表示されてしまいます。
一方、https://sample.com/dynmap/
やhttps://sample.com/dynmap/#
であれば、正しく表示されます。
ではなぜ、スラッシュ/
を保管しなければならないのか。
これは推測なのですが、DynmapのWebサーバのルートディレクトリを明示する必要があるのでは?と考えています。
通常、ドメイン名のみでアクセスするとき、ブラウザはスラッシュを補完してサーバにリクエストを投げます。
URLバーがhttps://sample.com
であっても実際はhttps:/sample.com/
としてリクエストを送っているということです。
最後のスラッシュがルートを示しています。
ですが、今回の場合リバースプロキシを経由しているので、スラッシュ補完が行われません。
ディレクトリを一切指定されなかったWebサーバは、困って真っ白な画面を返したのではないでしょうか。
何か詳細あれば、教えていただきたく思います。
Minecraftサーバのポートもリバースプロキシ経由にできないのか?
ごもっともだと思います。
ですが、Minecraftが扱っているプロトコルはゲーム独自のものです。
mod_proxyモジュールでは対応できないプロトコルなので、今回の例のようにはいきません。
ですので、Dynmapのみリバースプロキシを適用することにしました。
まとめ
どうでしたか?
他のマルチサーバをのぞくと、http://xxxxxx:8123
でアクセスしているものがいくつかあったので、記事にしてみました。
ポートを閉じるためにも、httpsで通信するためにも、リバースプロキシを使ってみてはいかがでしょうか。