さくらのレンタルサーバの仕様が変更になっており、この記事の内容は現状に合わなくなっている可能性が高いです。ご注意ください。
詳細は以下のページをご参照願います。
help.sakura.ad.jp
help.sakura.ad.jp
【WordPress】常時SSL化プラグインの使い方 – さくらのサポート情報
さくらのレンタルサーバで共有SSLを使用する際に、SSLのみのアクセス許可を設定(SSLアクセス強制のため、http://〜 は https://〜 へリダイレクト)するための .htaccess の記述方法を調べてみた。
設定する .htaccess の内容
[2016.07.01修正]
以下の例で、当初は
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]」
のようにしていたが、これだと対象ディレクトリ直下で且つファイル名を指定しない(「/」で終わる)URLの場合( http://~/wordpress/ 等)にはリダイレクトされないため、修正("."→"^")。
<IfModule mod_rewrite.c> RewriteEngine On # --- SSLアクセスでない場合(${ENV:HTTPS} が 'on' でなく、且つ、%{HTTP:X-Sakura-Forwarded-For} が未設定の場合)には # https://%{SERVER_NAME}%{REQUEST_URI} へリダイレクト RewriteCond %{ENV:HTTPS} !^on$ RewriteCond %{HTTP:X-Sakura-Forwarded-For} ^$ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] </IfModule>
なお、WordPress を設置している場合(例として /wordpress/ 下)
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase /wordpress/ # --- SSLアクセスでない場合(%{ENV:HTTPS} が 'on' でなく、且つ、%{HTTP:X-Sakura-Forwarded-For} が未設定の場合)には # https://%{SERVER_NAME}%{REQUEST_URI} へリダイレクト RewriteCond %{ENV:HTTPS} !^on$ RewriteCond %{HTTP:X-Sakura-Forwarded-For} ^$ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /wordpress/index.php [L] </IfModule>
のようにすればよいと思われる。
WordPress の元の .htaccess の RewriteBase 行と最初のRewriteCond 行の間に、SSLアクセス強制用の RewriteCond・RewriteRule を挟み込む。 /wordpress/(二か所)は環境にあわせて書き換えること。
また、wp-config.php の「/* That's all, stop editing! Happy blogging. */(/* 編集が必要なのはここまでです ! WordPress でブログをお楽しみください。 */)」直前に、
if ( isset($_SERVER['HTTP_X_SAKURA_FORWARDED_FOR']) ) {
$_SERVER['HTTPS'] = 'on';
$_ENV['HTTPS'] = 'on';
}
/* That's all, stop editing! Happy blogging. */
という記述を追加しておく。
解説(覚え書き)
さくらのレンタルサーバで共有SSLを使用する場合、以下の点に留意する必要がある。
.htaccess からの参照時
- %{SERVER_PORT} には、SSLかそうでないかによらず '80' が設定される。
このため、%{SERVER_PORT}ではSSL接続かどうかの判別はできない。
「RewriteCond %{SERVER_PORT} ^80$」や「RewriteCond %{SERVER_PORT} !^443$」は常に真となるために、リダイレクトループが発生してしまう。 - SSLアクセス時には通常、 %{ENV:HTTPS} には 'on' が、%{HTTP:X-Sakura-Forwarded-For} にはクライアント(リクエスト元)のIPアドレスが設定される。*1
ただし、SSLアクセスした場合であっても、mod_rewrite.c の RewriteRule によりリライトされるケースでは、リライト後には %{ENV:HTTPS} が未設定となってしまう。
RewriteRuleの[R]フラグによりhttps://〜にリダイレクトされた場合には 'on' が設定される。
上記の .htaccess では、リダイレクトするかどうかの判別に、
RewriteCond %{ENV:HTTPS} !^on$
だけでなく、
RewriteCond %{HTTP:X-Sakura-Forwarded-For} ^$
のような条件(%{HTTP:X-Sakura-Forwarded-For}が未設定)を設定している。
これをせずに %{ENV:HTTPS} のみで判定してしまうと、例えば WordPress を設置したサイト上の http://〜/wordpress/year/month/day/ というページ(URL)にアクセスした場合、
URL | %{REQUEST_URI} | %{ENV:HTTPS} | %{HTTP:X-Sakura-Forwarded-For} | mod_rewrite.cで適用されるルール | 結果 | |
---|---|---|---|---|---|---|
1 | http://〜/wordpress/year/month/day/ | /wordpress/year/month/day/ | (未設定) | (未設定) | RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] | [A] リダイレクト |
2 | https://〜/wordpress/year/month/day/ | /wordpress/year/month/day/ | 'on' | RewriteRule . /wordpress/index.php [L] | [B] リライト | |
3 | https://〜/wordpress/year/month/day/ | /wordpress/index.php | (未設定) | RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L] | [C] リダイレクト | |
4 | https://〜/wordpress/index.php | /wordpress/index.php | 'on' | RewriteRule ^index\.php$ - [L] | [D](このまま) |
のように、意図しないURLの PATH の書き換えが発生してしまう。
このため、[C] (3→4)のリダイレクトを発生させないように、条件を追加している。
むしろ「RewriteCond %{ENV:HTTPS} !^on$」の方は無くても現状では動作する。
PHP からの参照時
- SSLアクセス時には、$_SERVER['HTTP_X_SAKURA_FORWARDED_FOR'] および $_ENV['HTTP_X_SAKURA_FORWARDED_FOR'] にはクライアント(リクエスト元)のIPアドレスが設定される。
- SSLアクセスした場合であっても、mod_rewrite.c の RewriteRule によりリライトされるケースでは、$_SERVER['HTTPS'] と $_ENV['HTTPS'] が設定されない。
RewriteRuleの[R]フラグによりhttps://〜にリダイレクトされた場合には 'on' が設定される。
WordPress 等では、SSL 接続かどうかを $_SERVER['HTTPS'] もしくは $_ENV['HTTPS'] の状態で判別している。
このため、上記のように $_SERVER['HTTP_X_SAKURA_FORWARDED_FOR'] が設定されているかどうかで SSL かどうかを判別し、SSL の場合には $_SERVER['HTTPS'] および $_ENV['HTTPS'] に 'on' を設定するような処理を追加してやる必要がある。
*1:将来的にさくら側で仕様変更が行われると、%{HTTP:X-Sakura-Forwarded-For}による判別が出来なくなる可能性はある。