1つのグローバルIPアドレスで2つのHTTPSサイトを公開する(2)

  • 投稿日:
  • by
  • カテゴリ:
去年の年末に書いた記事のアップデートです。
どんなサイトもHTTPS化が必須みたいな流れがやってきたので、年末にMovableType 7に移行するタイミングでLet's Encryptを使ってこのブログをHTTPS化したわけですが、不慣れな構成変更だったこともあり、ルーターに入ったHTTPS要求をリバースプロキシ専用のバーチャルマシンにインストールしたARRを介して各サイトをホストしたVMに振り分けるという極めて無駄な構成になっていたのを最近直しました。
できなければおかしいと思っていたので、実際できるにきまってます。

arr.jpg 実現方法は元々想定していた構成の通りで、TCP:443へのリクエストをルーターからこのブログを公開しているVMWareのマシンに流し込みます。
IISにARR 3.0とURL Rewrite 2.1をインストールし、ブログ用ともう1つのHTTPSサイト用のWebサイトを計2個作る。
ARRはEnable ProxyのチェックボックスをONにするだけで、それ以外は何も設定しない。(Use URL Rewrite to inspect incoming requestsもチェックしないでおく。)

aaaaaaa.jpg

どちらのサイトも、バインディングの設定でポート443にバインドし、外部からアクセスされるホスト名のFQDNが複数ある場合は、以下のようにそれぞれ登録して証明書を選択する。(たとえば、Default Web Siteはwww.mydomain.com:443にバインドするなど)
自分の環境ではDigicertのワイルドカード証明書を使っているので、どちらのホスト(www.mydomain.comとmail.mydomain.comなど)も同じ証明書を割り当てている。また、Let's Encryptのように3カ月ごとに更新されるような証明書ではないので、リクエストを転送する先のサーバーにインストールした証明書をエクスポートしてARRのサーバーにインポートしている。年に1回のコピーなら耐えられるので。
ここで、Server Name Indication (SNI)を使うことで、SSLのハンドシェイク時にクライアントに対してホスト名が要求されるので、HTTPでホストヘッダーを使ってリクエスト内部の複数のサーバーに振り分ける動作をHTTPSで実現できるようになる。この表記が、日本語のIISマネージャでは「サーバー名表示を要求する」という謎の文言になっているので混乱するかもしれない。

sni.jpg
これによって、それぞれのサイト(liefwith34.ddo.jpとwww.mydomain.com)へのリクエストはSNIによって振り分けられるわけだけど、ARRをインストールしているサーバーでホストしているこのブログはいいとして、別のサーバーに実体があるwww.contoso.comはURL Rewriteで転送する必要がある。

やることとしては、インターネットから来た*.mydomain.netへのアクセスを、URL Rewriteを使って内部のホスト名server01.mydomain.comに書き換えるというもの。内部ホストの名前解決はHOSTSを使う。(ルーターのDNS機能のカスタムレコードの追加みたいなもでもよし)
URL Rewriteは各サイトの設定だから、それぞれのサイトはバインドの設定でlifewith34.ddo.jpの場合とwww.mydomain.com/mail.mydomain.comで既に分かれているわけで、スラッシュ以降{R:0}はそのまま、サーバー名だけをwww.mydomain.comやmail.mydomain.comからserver01.mydomain.netに書き換えるだけ。

この規則のアクションに書いた{R:0}というのは、インターネットからのリクエストがhttps://www.mydomain.com/category/content.htmlだとすると、"category/content.html"のこと(パターンテストで確認できるけど、R:0というのはスラッシュ以降の全ての文字のこと)。なので、ホストのFQDNだけをローカルのサーバー名に書き換えて、その後ろに{R:0}をまるごとくっつけている。
以下の画面では条件にサーバー変数{HTTP_HOST}を指定しているけど、これは実際には不要。サイトが1つしか無くて、そのサイトのURL書き換えで複数のサーバーにリクエストを振り分けるなら{HTTP_HOST}の条件は必要。かつ、書き換え規則が複数必要になる。

mars-2019-05-17-16-41-52.jpg

と、長々と書いたけど、1つのグローバルIPアドレスで2つのHTTPSサイトを公開することができるようになった。いや、元々できてたんだけど、必要最低限のサーバー台数で実現できるようになったというのが正しいか。
ただ、これだってIPv4でインターネットに公開するせいでこうなっているわけで、IPv6でそれぞれの仮想マシンが直接インターネットに公開できるようなら必要無い知識のような気はする。DNSだってダイナミックである必要はないだろうし。