プライム・ストラテジー「KUSANAGI」開発チームの石川です。
KUSANAGIで運用しているウェブサイトをロードバランサーの配下に配置して運用する方法があります。
例えば AWS であれば Elastic Load Balancing 、 Azure であれば Load Balancer が該当します。
ロードバランサーを使う理由
ロードバランサーを介して KUSANAGI を運用する場合にはメリットがあります。
- 直接KUSANAGIのウェブサイトをインターネットに露出させる必要がない。
- ウェブサイトを運用するKUSANAGIにグローバルIPアドレスを付与しないことで、アクセスを制限してセキュリティを向上できます。
- SaaS型のWAFなどを組み合わせることで、よりウェブサイトの安全性を高めることができます。
- ロードバランサーで負荷分散を行える。
- 複数台のKUSANAGIで同じウェブサイトを運用して、アクセスの負荷を複数台に分散させることができます。
- その際にアップデート等で運用を停止するVMだけをロードバランサーから外すことで、ウェブサイトの運用を止めずにアップデート等が行えます。
ロードバランサーを使う場合の注意点
ただし、ロードバランサーの配下に KUSANAGI を配置する場合には注意が必要な点があります。
- TLS接続のターミネーションをロードバランサーで行うため、HTTPSのアクセスであってもロードバランサーからKUSANAGIへのアクセスは全てHTTPになります。
kusanagi ssl --https redirect
のようにHTTPアクセスをHTTPSへリダイレクトする設定を行っていると、無限リダイレクトとなる場合があります。- WordPressの管理画面などTLS接続を必須としてる場合にログインできなくなる場合があります。
- ロードバランサーがKUSANAGIから見た直接の最後のIPアドレスとなります。
- アクセスログに出力されるIPアドレスがロードバランサーのものとなります。
- IPアドレスを元にウェブサイトのアクセス制限を行っている場合に、正しく判別ができない場合があります。
以下では、この注意点を踏まえた設定方法を説明します。
ロードバランサー配下のKUSANAGIでの設定変更
前提条件
まず、前提条件としてロードバランサーとKUASNAGIのVMの間のネットワーク (仮想ネットワーク) はインターネットからは隔離されたネットワークである必要があります。
ロードバランサーにサーバ証明書を設定してTLS接続をターミネーションしている場合、ロードバランサーとKUSANAGIの間はHTTPによる非暗号化の通信となります。そのため、この間の通信がインターネットに漏れないようにすることが重要です。
もしもインターネット経由でロードバランシングをする場合は、TLS接続のオーバーヘッドが増えてしまいますが、ロードバランサーとKUSANAGIの間もHTTPS接続としてください、
ハートビート (Heart Beat) 用の設定ファイルをWebサーバに設定する
ロードバランサーは配下にいるウェブサーバの死活を監視するために、定期的にアクセスを行います。
これをハートビート (Heart Beat) と呼びます。
KUSANAGI 9ではバーチャルホストを利用することで、1台のVMで複数のFQDNを運用できるようにしています。
この際、どのプロファイルを表示するかは指定されたFQDN (HTTPヘッダの HOST
) を参照します。
ハートビートはIPアドレスでアクセスされることが多いです。
このようにFQDNがない場合は、KUSANAGI 9ではアルファベット順で一番最初のプロファイルが選択されます。
例えば、以下のように3つのプロファイルが存在する場合、IPアドレスでアクセスすると1番目の column.prime-strategy.co.jp のサイトが表示されます。
- column.prime-strategy.co.jp
- kusanagi.tokyo
- www.prime-strategy.co.jp
さて、WordPressのサイトは動的にコンテンツを生成するため、多少の負荷が発生します。
また、死活を監視するハートビートのためだけにフルのコンテンツを表示する必要はありません。
そこで、死活監視用には単純に HTTP でレスポンスコード 200 を返すような設定を加えた方が負荷を軽減できます。
Nginxの場合には以下のような設定ファイルを _default.conf
のように、アルファベット順でプロファイル名よりも前にくる名前で作成し、 /etc/opt/kusanagi/nginx/conf.d
に配置します。
## default HTTP
server {
listen 80 default_server;
location / {
return 200;
break;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /opt/kusanagi/share/nginx/html;
}
}
Apache httpdの場合は以下のような設定ファイルを _default.conf
として作成し、 /etc/opt/kusanagi/httpd/conf.d
に配置します。
## default HTTP
<VirtualHost _default_:80>
DocumentRoot /var/opt/kusanagi/www/html/
</VirtualHost>
いずれの場合も kusanagi nginx
や kusanagi httpd
でリスタートを忘れないでください。
ロードバランサーとKUSANAGIの間をHTTP通信で通信できるようにする
HTTP接続を許可する設定を行う
KUSANAGIではHTTP接続を許容する設定を行います。
以下のコマンドを実行して、HTTPSリダイレクトする設定を解除します。
kusanagi ssl --https noredirect
サーバー証明書の取得と変更
ロードバランサーに設定する元となるサーバー証明書がKUSANAGIにある場合は取り出しておきます。
また、Let’s Encryptのサーバー証明書を利用していた場合、ロードバランサーの配下にKUSANAGIを配置してしまうと証明書の更新が行えなくなってしまいます。
正確にはKUSANAGIとしてサーバー証明書の更新を行うことはできますが、その更新された証明書をロードバランサーに配置することを別に行う必要があります。
ロードバランサーを使用する場合は、Let’s Encryptではなく一般的なサーバー証明書を利用するようにしてください。
WordPressの設定変更
WordPressの管理画面を含め、ウェブサイトのアドレスが https://
で登録されている場合、HTTPで接続された場合にWordPressがHTTPSにリダイレクトを行います。
これにより、HTTPからHTTPSへの無限リダイレクトが発生してしまう場合があります。
WordPress側ではHTTP経由できたとしても、ロードバランサーへのアクセスがHTTPSだった場合には あたかもHTTPSでアクセスされたように 振る舞うように設定を行います。
具体的にはWordPressの wp-config.php
に以下を加えます。
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
$_SERVER['HTTPS'] = 'on';
}
これは、HTTPヘッダの X_FORWARDED_PROTO
に https
が設定されている場合には、アクセスされたプロトコルに関わらず HTTPS として処理するものです。
Azure や AWS のロードバランサーでは、HTTPSで接続された際には自動的に X_FORWARDED_PROTO
に https
を設定するため、これを利用しています。
ここまでで、HTTPSでサイトが見られることを確認してください。
また、アクセスログはHTTP経由であるために、ssl_access.log ではなく access.log に出力されていることも確認してください。
ロードバランサーにアクセスしたIPアドレスをKUSANAGIで認識させる
ロードバランサーでは、アクセスした元のIPアドレスをHTTPヘッダの X-FORWARDED-FOR
に設定します。
これを利用して、KUSANAGIのウェブサーバでアクセス元のIPアドレスを X-FORWARDED-FOR
から復元します。
Nginxでは、各プロファイルのCMSごとの設定ファイルがあるので、それを編集します。
例えば、WordPress用にプロビジョンしたプロファイルでは /etc/opt/kusanagi/nginx/conf.d/プロファイル.wp.inc
となります。
先頭に以下を追加します。
set_real_ip_from ロードバランサーの内部から見たIPアドレス、または、IPアドレスブロック;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Apache httpdではプロファイル毎に設定ファイルがあるので /etc/opt/kusanagi/httpd/conf.d/プロファイル.conf
を編集します。<VirtualHost *:80>
の次の行に入れるとよいでしょう。
<IfModule mod_remoteip.c>
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy ロードバランサーの内部から見たIPアドレス、または、IPアドレスブロック
</IfModule>
なお、ロードバランサーの内部から見たIPアドレス、または、IPアドレスブロックはできるだけ限定するようにしてください。
いずれの場合も kusanagi nginx
や kusanagi httpd
でリスタートを忘れないでください。
まとめ
今回はロードバランサー配下のように、KUSANAGIが直接HTTPSでリクエスト受けられない場合に、HTTPS経由の接続であることをKUSANAGIで認識させる方法を説明しました。
KUSANAGIはデフォルトで高いセキュリティを実現できるように設計されてはいますが、ロードバランサーやWAFを配置することで、よりKUSANAGIの安全性を強固にすることができます。
AzureやAWSなどロードバランサーを利用できるクラウドを使用している場合は、KUSANAGIをロードバランサーの配下に設定することを検討してみてください。