Quantcast
Channel: 風柳メモ
Viewing all articles
Browse latest Browse all 92

さくらのレンタルサーバ・共有SSLで .htaccess によりSSLのみのアクセス許可を設定する方法

$
0
0

さくらのレンタルサーバで共有SSLを使用する際に、SSLのみのアクセス許可を設定(SSLアクセス強制のため、http://〜 は https://〜 へリダイレクト)するための .htaccess の記述方法を調べてみた。



設定する .htaccess の内容

<IfModule mod_rewrite.c>RewriteEngineOn# --- 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>RewriteEngineOnRewriteBase /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で実行されるルール結果
1http://〜/wordpress/year/month/day//wordpress/year/month/day/(未設定)(未設定)RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L][A] リダイレクト
2https://〜/wordpress/year/month/day//wordpress/year/month/day/'on'RewriteRule . /wordpress/index.php [L][B] リライト
3https://〜/wordpress/year/month/day//wordpress/index.php(未設定)RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L][C] リダイレクト
4https://〜/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}による判別が出来なくなる可能性はある。


Viewing all articles
Browse latest Browse all 92

Trending Articles