さくらのレンタルサーバーで、常時SSLにするための.htaccessの設定


このエントリー、「さくらのレンタルサーバーで、サブディレクトリだけ常時SSLにするときの注意」というタイトルでした。その表題通りの困った事象があってまとめてみたのですが、さくらのヘルプに公式な情報がでており、そちらを設定すれば問題なく動作しました。

WordPressを利用せずサイトを作成/公開されている場合 ~SNI SSLを利用~
SetEnvIf REDIRECT_HTTPS (.*) HTTPS=$1 
<IfModule mod_rewrite.c>
RewriteEngine on 
RewriteCond %{ENV:HTTPS} !on 
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 
</IfModule>

a-blog cmsでテストしてみたところ、.htaccessの末尾に次のように設定することで、ルートディレクトリに設定しても、サブディレクトリに設定しても、問題なく動作しています。

SetEnvIf REDIRECT_HTTPS (.*) HTTPS=$1 
RewriteCond %{ENV:HTTPS} !on 
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

常時SSLのリダイレクトがおかしい。

さくらのレンタルサーバーで、サブディレクトリだけ常時SSL対応をするという事例がありました。
当該サブディレクトリに.htaccessを設定し、リダイレクトで、http://にアクセスがあった場合、https://にリダイレクトする設定を行い、一見うまく行ったように見えたのですが、奇妙な事象が起こりました。
条件としては次のような状態です(例です)。

  1. サイトルートはhttp://www.example.com/
  2. 常時SSL化したいのはhttps://www.example.com/path/to/ssl/
  3. http://www.example.com/path/to/ssl/hoge.htmlにアクセスしたら、https://www.example.com/path/to/ssl/hoge.htmlにリダイレクトしたい

上記3のようにファイル名を指定してアクセスするとちゃんとSSL化された同じページにリダイレクトされるのですが、.htaccessファイルを置いたディレクトリのディレクトリインデックス(http://www.example.com/path/to/ssl/)にアクセスすると、https://www.example.com/と、SSL状態のサイトルートにリダイレクトされてしまいました。

今回は、http://www.example.com/path/to/ssl/にa-blog cmsをインストールしており、その環境で確認したのですが、a-blog cmsをインストールしていない素の状態でも、同様の現象が起こりました。
いずれの場合も、.htaccessに次のような設定をしていました。

さくらのレンタルサーバーで常時SSL/TLSを設定する
RewriteCond %{ENV:HTTPS} !^on$
RewriteCond %{HTTP:X-Sakura-Forwarded-For} ^$
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R,L]

常時SSL化する際の.htaccessの書き方

ずいぶんあっちゃこっちゃしたのですが、結論としては、最後の行を

RewriteRule ^(.*)$ https://%{HTTP_HOST}/path/to/ssl/$1 [R,L]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

のいずれかに設定すれば期待通りの動作になりました。
前者の場合、$1には本来、アクセスしたURLのパスが入るはずなのですが、このhtaccessを置いたディレクトリのディレクトリインデックスのみ、なぜかそうならないようで…どういう理屈なんだろう。
通常は、サイトルートからSSL化するはずなので問題はないと思いますし、さくらのレンタルサーバー以外の環境ではおこらない事象なはずです。

以上のような状況があるかもしれないことを踏まえて、さくらのレンタルサーバーで常時SSL化する際の.htaccessのリダイレクト設定は、以下が安全であると思われます。

RewriteCond %{ENV:HTTPS} !^on$
RewriteCond %{HTTP:X-Sakura-Forwarded-For} ^$
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]