IMG_1073

必要があってリバースプロキシを立てました。
こんな滅多にやらないこと絶対に忘れそうだったので、メモりました。  

したいこと

同じグローバルIPアドレスで、複数(今回は3台)のWebサーバを運用する、これがやりたかった。
それを実現する方法として、リバースプロキシを立てて、その後ろにWebサーバを配置、このプロキシでドメインごとにサーバを振り分ける。(微妙に表現に誤りがあるけど気にしない)


環境

本当は、新しく出たMac miniとかMac Proで全部やりたかったけど、そんなお金ないので今回は某オークションで安く出回っている業務用デスクトップパソコンを複数使用。
これにWindowsを入れ、その上に仮想マシンとかWSLを入れてUbuntu上でApacheを動作させる。
(そう、パソコンを複数並べなくてもMac ProかハイスペMac miniが用意できれば、全部仮想Ubuntuマシンにして1つのMacで動かせてめちゃコンパクトだったわけで・・・)
WSLてなんぞって人は、「Windows Subsystem for Linux」でググってください。

というわけで、用意した環境は、
1. WSL on C2Q@2.4GHz、RAM 8GB(Ubuntu18.04、Webサーバ)
2. VM on Core i3@3.3GHz 2コア割り当て、RAM 4GB割り当て(Ubuntu16.04、Webサーバ)
3. WSL on Core i3@3.3GHz、RAM 8GB(Ubuntu18.04、Webサーバ)
4. WSL on Core i3@3.3GHz、RAM 8GB(Ubuntu18.04、プロキシ)
の4環境。
2. と3.は物理的には同じパソコン、3. のRAMは2.のVMに最大4GB持っていかれるので、他のマシンに比べると非力。

ドメインはそれぞれ、
1. aaa.example.jp
2. bbb.example.jp
3. ccc.example.jp
とします。

LANのIPアドレスは今回、
1. 192.168.10.3
2. 192.168.10.4
3. 192.168.10.5
4. 192.168.10.2
とし、ルータ側で192.168.10.2に対して80番と443番ポートへのアクセスが流れるように設定。


ドメインについて

すべてのドメインには、CNAMEでDDNSのようなものを指定してあります。
値は全部同じです。
DDNSのようなものに関しては、この記事を参照。


Webサーバ側の設定

特別な設定はありません。
リバースプロキシをかまさないときと同じように設定。
SSL対応させる場合はそれもしてOK。

* 11/23/2018 追記
WSLを使ってサーバを立てる場合、Windowsファイアウォールの設定を変更して、「受信の規制」でTCPポート80番(https対応した場合は443番も)に穴を開けておく必要があります。


リバースプロキシ側の設定

SSL対応してない方(http)の設定です。
以下の設定を000-default.confに、サーバの数だけ書きます。
コメントが入ってるところは、コメントに沿って各サーバに合う適当なものに書き換えます。
<VirtualHost *:80>
  ProxyPreserveHost On
  ServerName aaa.example.jp    # Webサーバのドメイン 
  ProxyPass / http://192.168.10.3:80/ retry=0     # 対象のWebサーバのLAN IPアドレスとそのポート
  ProxyPassReverse / http://192.168.10.3:80/ retry=0    # 対象のWebサーバのLAN IPアドレスとそのポート

  ErrorLog ${APACHE_LOG_DIR}/aaa.example.jp_error.log    # 対象サーバのアクセスエラーログ
  CustomLog ${APACHE_LOG_DIR}/aaa.example.jp_access.log combined    # 対象サーバのアクセスエラーログ
</VirtualHost>

SSL対応してる方(https)の設定はこちら。
以下の設定をdefault-ssl.confの、
 <IfModule mod_ssl.c>
内に、サーバの数だけ書きます。
コメントが入ってるところは、コメントに沿って各サーバに合う適当なものに書き換えます。
<VirtualHost *:443>
  ProxyPreserveHost On
  ServerName aaa.example.jp:443

  SSLProxyEngine on
  ProxyPass / https://192.168.10.3:443/ retry=0    # 対象のWebサーバのLAN IPアドレスとそのポート
  ProxyPassReverse / https://192.168.10.3:443/ retry=0    # 対象のWebサーバのLAN IPアドレスとそのポート

  ErrorLog ${APACHE_LOG_DIR}/aaa.example.jp_error.log    # 対象サーバのアクセスエラーログ
  CustomLog ${APACHE_LOG_DIR}/aaa.example.jp_access.log combined    # 対象サーバのアクセスエラーログ

  SSLEngine on
  # aaa.example.jpのSSL証明書を参照できるように設定(Let's Encrypt仕様)
  SSLCertificateFile	/etc/letsencrypt/live/aaa.example.jp/cert.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/aaa.example.jp/privkey.pem
  SSLCertificateChainFile /etc/letsencrypt/live/aaa.example.jp/chain.pem

  <FilesMatch "\.(cgi|shtml|phtml|php)$">
    SSLOptions +StdEnvVars
  </FilesMatch>
  <Directory /usr/lib/cgi-bin>
    SSLOptions +StdEnvVars
  </Directory>
</VirtualHost>

これで、LAN内にWebサーバをIPアドレスがあるだけ立て放題になりました。
どうもレンタルWebサーバは、このリバースプロキシを応用して作られてるらしいです。

* 11/23/2018 追記
WSLを使ってサーバを立てる場合、Windowsファイアウォールの設定を変更して、「受信の規制」でTCPポート80番(https対応した場合は443番も)に穴を開けておく必要があります。


さいごに

WSLでサーバ立てるの、MSは推奨してないです。
でもめっちゃ安定して動くので(PHPも今の所まともに動いている)、ガン無視して使っちゃってます。
このWSLが結構使えることに気づいたとき、初めて勉学用にWIndowsネイティブマシンを用意するのもいいかもしれないと心をよぎったのはなかったことにします。
足元に置いたサーバマシン、(仮想マシンが動いてるせいで)1台だけぬくぬくな子がいて、冬は極楽、夏は地獄と化すこととなりました・・・