[AWS] AWS 上の WordPress が HTTPS で正常に表示されない場合の対処

Amazon Web Service Elastic Load Balancing に起因する事例。

症状

  • HTTPS でアクセスしているが JavaScript や CSS が HTTP で呼ばれており、表示が乱れている。
  • ログインもできない。

当初はサイト URL の設定を疑ったが、これでは解決しません。

対応

サーバ構成図などの情報が得られなかったが、AWS 上で構築されているらしいとの情報あり。
Elastic Load Balancing (以下、ELB)の振る舞いが原因ではないかと推測し、同様の症状を探しました。

具体的にはこちらが見つかりました。
ありがとうございます。

WordPress Codex には、以下の記述がありました。

Websites behind load balancers or reverse proxies that support HTTP_X_FORWARDED_PROTO can be fixed by adding the following code to the wp-config.php file, above the require_once call:

Function Reference/is ssl « WordPress Codex

wp-config.php の冒頭に下記の記述を書き加え、解決しました。

wp-config.php
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS'] = 'on';

PHP のスーパーグローバル変数の値を書き換えています。

何故なのか

ELB の SSL Termination 機能により、アプリ側は HTTPS ではなく HTTP リクエストを受け取っていた。
これにより挙動が変わっていた。

ELB の設定と振る舞いに関しては、こちらが大変参考になりました。
ありがとうございます。

3つの解決策が提案されていました。

アプリケーション

アプリ側で HTTP_X_FORWARDED_PROTO の値が https かどうかチェックする。
PHP の場合は、$_SERVER['HTTP_X_FORWARDED_PROTO']

Web サーバ

Webサーバ(Apache)の設定(httpd.conf)で環境変数をセットする。

SetEnvIf X-Forwarded-Proto https HTTPS=on

ELB

ELBでSSLの処理(SSL Termination)をした後に、再度HTTPS通信にして、EC2にリクエストする。
この場合ELB経由でもEC2のWebサーバはHTTPSで接続される。

補遺