Help us understand the problem. What is going on with this article?

【mod_proxy】Dynmapをhttpsで見る

やりたいこと

タイトル通り、Dynmapをhttpsで見たい。

前提

DynmapはMinecraftのサーバプラグインで、ゲームの内部状況をブラウザから確認できるようになる、人気のプラグインです。

【Dynmap】Overview
image.png

普通に実装するなら、ポート周りはこんな感じになります。
server-image.png

ソフトウェア ポート番号 通信プロトコル
Apache 80, 443 http, https
Minecraft server 25565 独自プロトコル
Dynmap 8123 http

大雑把な図ですが、おおよそこのような関係になります。ポート番号はデフォルト値です。

問題はDynmapです。Dynmapは内部にスタンドアローンなWebサーバを内蔵していますが、Apacheとの競合を防ぐため、8123番ポートを利用します。そのため、サーバは80, 443, 25565の他に8123番ポートも開放しなければなりません。

他のポートは開放する他ありませんが、Dynmapのポートは開放したくありません。
もっといえば、httpsで通信したいです。

さて、どうしましょう。

リバースプロキシ(Reverse Proxy)を使う

リバースプロキシを使うことで解決できます。
リバースプロキシとは、外部ネットワークの接続に対し、何らかの処理を行い、内部サーバに引き渡す、いわば中継機能を果たす機器のことです。

とても分かりやすい図があったので、お借りしました。

image.png
【ITSakura】プロキシサーバとリバースプロキシサーバの違い

リバースプロキシが外部の受付役となっていることが分かりますね。今回、ハード的にサーバは1つですが、やることは同じです。
Apacheに対するリクエストはApacheに、Dynmapに対するリクエストはDynmapにそれぞれ内部で振り分けることで、開放ポートを減らすことができます。

リバースプロキシ適用

リバースプロキシを使った図が以下になります。(8123番ポートはイメージです)
reverse-proxy

リバースプロキシはApacheに備わっている機能なので、リバースプロキシはApache内部にあります。
リバースプロキシが受け取ったリクエストのうち、Dynmapに関するものだけ8123番ポートに向けて、リクエストを送ります。
Dynmapの応答はリバースプロキシを通じて、外部に送信されます。

このように、リバースプロキシを使うと内部サーバを隠蔽し、無用なポート開放を防ぐことができます。

リバースプロキシの実装

Apacheであれば、mod_proxyを使って簡単に実装できます。
今回はhttpsの通信に対して実装するので、VirtualHostを使います。(https化はすでにされているものとします)

ssl.conf
...
# スラッシュ補完(後述)
<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/dynmaphttps://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で通信するためにも、リバースプロキシを使ってみてはいかがでしょうか。

参考リンク

kiyocy24
しがない大学院生やってます。 趣味でWebサーバやマイクラサーバを立てて、サーバ周りをいろいろいじってます。
dena_coltd
    Delight and Impact the World
https://dena.com/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした