リバースプロキシ環境でWordPress管理画面をhttps強制にする
|わかりにくいので説明しておくと画像は風呂です(フロキシ)。
ゆえあって、こういう構成でWordPressを立てているわけですよ。
といってもわざわざDocker使っていること以外は、
- フロントエンドに nginx が立っている
- バックエンドに nginx + WordPress が立っていて、
フロントエンドがリバースプロキシ参照している
ということで、新婚の奥様がよく構築されているような事例ですね。
環境はCentOS 6.5 + WordPress 3.9 です。
しかーし、ここで以下のような要件が出てきたらどうしましょうか。
- /wp-login.php, /wp-admin/.* はSSLアクセスを強制したい
(ログイン画面、管理画面)
で、ちょっとハマったのでメモ。
端的に言うと正解は以下のとおり:
まず、フロントエンド側 nginx の該当 server コンテキスト内に、
proxy_set_header X-Forwarded-Proto $scheme;
と追記する。
そののちバックエンド側WordPressの
ドキュメントルート/wp-config.php
に(config.phpじゃないよ!)、
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
&& $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") {
$_SERVER['HTTPS'] = 'on';
}
define('FORCE_SSL_ADMIN', true);
を追加する。
ハマりどころ:
- フロントエンドにクライアントがhttp/httpsどちらでアクセスしてきたか
バックエンドに伝える方法がない。
そのため X-Forwareded-Proto で受け渡す必要がある - nginx の proxy_set_header とか proxy_pass は
if ディレクティブや 正規表現を使った {} ブロック内では
使用できない(ナンデ?!ナンデ ニンジャ?!) - バックエンドのWordPressシステムは
X-Forwareded-Proto を自動では読まないため、
$_SERVER[‘HTTPS’] に反映してやる必要がある - WordPressの FORCE_SSL_ADMIN は $_SERVER[‘HTTPS’] しか見ない。
なお、これが true なら FORCE_SSL_LOGIN を設定する必要はなし
死んだ…。
追記
ちなみに、このように管理画面でSSLを強制すると、
WordPressの一部動作に不具合が出ます。
といってもふつうの操作をしているぶんには問題がなくて、
具体的には「自サイトURLがhttpであることを前提にしてい
るプラグインなど」がうまく動かない。
たとえば、JetPack(!)のパブリサイズ共有はTwitter認証
ができなくなります…(どこにバグがあるのか丸わかりである)。
とほほ…。