Apacheのリバースプロキシという機能を使いdockerの任意のポートに転送する。
それだけではなく、Certbot + Let’s encryptを使ってクライアントとの間の通信はSSL化する。
環境
- Ubuntu 20.04.2 LTS (AWS EC2)
- Apache/2.4.41
Apacheモジュールのインストール
Apacheのプロキシ機能と、httpでのプロキシ機能を有効化するため、以下のコマンドを実行する
sudo a2enmod proxy
sudo a2enmod proxy_http
Apacheでヘッダーを編集する機能を有効化するため、以下コマンドを実行する
sudo a2enmod headers
URLを都度置き換える機能を有効化するため、以下コマンドを実行する
sudo a2enmod rewrite
設定を反映させるため以下コマンドを実行
sudo systemctl restart apache2
certbotをインストールする
過去の記事を参照してほしい
https://kajindowsxp.com/certbot-ssl/
certbotを使ってSSL証明書を設定する
certbotを利用するには80番ポートが利用できないといけないので、ファイヤウォールなどの設定はしておくこと。
ここからは、websocket.anti-crowded.comというアドレスを例にしていくので、適宜読み替えてほしい。以下コマンドを実行する
sudo certbot certonly --apache -d websocket.anti-crowded.com
正しく取得できると、
Certificate is saved at: /etc/letsencrypt/live/websocket.anti-crowded.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/websocket.anti-crowded.com/privkey.pem
のよう表示されるのでメモしておく。
apache2.confを書き換える
先程/etc/apache2/apache2.confに以下を追記する。
<VirtualHost *:80>
ServerName websocket.anti-crowded.com
AddDefaultCharset UTF-8
RewriteEngine on
RewriteCond %{SERVER_NAME} =websocket.anti-crowded.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName websocket.anti-crowded.com
AddDefaultCharset UTF-8
<Proxy *>
Require all granted
</Proxy>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:49160/ keepalive=On
ProxyPassReverse / http://localhost:49160/
RequestHeader set X-Forwarded-Proto "https"
SSLCertificateFile /etc/letsencrypt/live/websocket.anti-crowded.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/websocket.anti-crowded.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
ここではバーチャルホストを設定してルーティングしている。
バーチャルホストとは、アクセスされたドメインによって転送先を設定できる機能。
ServerNameにドメイン名を設定することで動作を定義できる。
websocket.anti-crowded.comの80番ポートにアクセスしたときには、URLをhttps://から始まるものに変更することでSSL化された通信へリダイレクトしている
RewriteEngine on
RewriteCond %{SERVER_NAME} =websocket.anti-crowded.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
websocket.anti-crowded.comの443ポートにアクセスした時(つまりSSL通信だった場合)は、リバースプロキシをONにすることで、http://localhost:49160/に転送を行っている。
ポート番号を変更したい場合は49160を変更すればいいことになる。
<Proxy *>
Require all granted
</Proxy>
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:49160/ keepalive=On
ProxyPassReverse / http://localhost:49160/
RequestHeader set X-Forwarded-Proto "https"
また、Certbotを使って取得した、Let’s encryptの証明書をここで読み込んでいる。
SSLCertificateFile /etc/letsencrypt/live/websocket.anti-crowded.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/websocket.anti-crowded.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
再起動&動作確認
設定が終わったらApacheを再起動
sudo service apache2 restart
refused to connect. が表示される場合
SSLエンジンが有効になっていない場合がある。以下コマンドを実行
sudo a2enmod ssl
sudo a2ensite default-ssl
sudo service apache2 restart
まとめ
今回、リバースプロキシを用いることでDocker側で設定をせずに、VPSのApacheの設定でポートのルーティングを行うことができた。
自分の通っている大学では、80番と443番以外のポートアクセスが禁止されているため、POST通信とWebsocket通信を利用したデータのやりとりができなかった。
この方法を使えば、SSL化された通信で安全にかつ大学のポート制限を回避してデータの送受信ができる。