この疑問に回答します。
ウェブサーバー1台で稼働させている場合は、こんな面倒臭い方法で判断する必要は無いんですけど、サイトの規模が大きくなると、SSLアクセラレーターと複数サーバーを利用してサイトを構築します。このような構成になると、X-Forwarded ヘッダーを利用する機会が出てきます。X-Forwarded ヘッダーでリダイレクトさせる手順をまとめます。
システム構成について
サイトの規模が大きくなると、SSLアクセラレーターと複数サーバーを利用して負荷分散させたサイトを構築します。暗号通信のHTTPSは、SSLアクセラレーターで暗号処理・復号処理をオフロードさせます。
HTTPSの場合
- HTTPS通信によるアクセス
- SSLアクセラレーターが暗号/複合
- X-Forwarded ヘッダーを付加
- HTTP通信でバックエンドのサーバーへアクセス
HTTPS通信の場合は、SSLアクセラレーターが暗号を解読し、同時に X-Forwarded ヘッダー に値をセットし、バックエンドのサーバーにHTTP通信させます。
これで、HTTP通信の場合は「X-Forwarded ヘッダー:無し」、HTTPS通信の場合は「X-Forwarded ヘッダー:有り(https)」の環境を作り出します。
これでバックエンドサーバーが、HTTP・HTTPSのどちらでアクセスが来たか判断できるようになります。
X-Forwarded ヘッダー値について
X-Forwarded ヘッダーにセットする値は、「https」である必要はありません。解りやすい値でかまいません。世の中では、「https」を入れることがスタンダードになっています。
そもそも、ヘッダー名の「X-Forwarded」も同様です。誰かが決めたものが、知らない間にスタンダードになっています。
Apache:X-Forwarded ヘッダーでHTTPSにリダイレクト
.htaccessファイルによる設定方法
.htaccess は手軽でよいのですが、.htaccessによる制御は、なるべく避ける必要があります。Apache 設定ファイルを変更出来ない場合に、.htaccess ファイルを利用するようにします。
Directory ディレクティブで、.htaccess を有効にします。
<Directory "/var/www/html"> ~~ RewriteEngine On ← .htaccess の有効化 AllowOverride All ← .htaccess の有効化 ~~ </Directory>
設定を変更したら、Apacheサービスを再起動するかリロードを実施してください。
.htaccess ファイルを編集します。
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto}!=https ← X-Forwarded パラメーター値を判断
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
これで、X-Forwarded ヘッダーのパラメーター値で判断し、リダイレクトします。
X-Forwarded ヘッダーは、SSLアクセラレーターにて付与しています。そもそもHTTPでアクセスしてきた場合は、X-Forwarded ヘッダーがありません。この状況を利用して判断します。
X-Forwarded ヘッダーが「https」で無い場合、httpsにリダイレクトさせる条件をいれます。これで、HTTPはHTTPSにリダイレクトが実施されます。
Apache:conf 設定ファイルによる設定方法
設定ファイルの VirtualHost ディレクティブに書き換えルールを追加します。
<VirtualHost *:80>
~~
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto}!=https ← X-Forwarded パラメーター値を判断
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
~~
</VirtualHost>
これで、X-Forwarded ヘッダーのパラメーター値で判断し、リダイレクトします。
X-Forwarded ヘッダーは、SSLアクセラレーターにて付与しています。そもそもHTTPでアクセスしてきた場合は、X-Forwarded ヘッダーがありません。この状況を利用して判断します。
X-Forwarded ヘッダーが「https」で無い場合、httpsにリダイレクトさせる条件をいれます。これで、HTTPはHTTPSにリダイレクトが実施されます。
設定を変更したら、Apacheサービスを再起動するかリロードを実施してください。
Nginx:X-Forwarded ヘッダーでHTTPSにリダイレクト
書き換えルールを追加します。
server {
listen 80;
server_name _;
if ($http_x_forwarded_proto != 'https'){ ← X-Forwarded パラメーター値を判断
return 301 https://$host$request_uri;
}
}
これで、X-Forwarded ヘッダーのパラメーター値で判断し、リダイレクトします。
X-Forwarded ヘッダーは、SSLアクセラレーターにて付与しています。そもそもHTTPでアクセスしてきた場合は、X-Forwarded ヘッダーがありません。この状況を利用して判断します。
X-Forwarded ヘッダーが「https」で無い場合、httpsにリダイレクトさせる条件をいれます。これで、HTTPはHTTPSにリダイレクトが実施されます。
設定を変更したら、Nginxサービスを再起動するかリロードを実施してください。
IIS サーバー:X-Forwarded ヘッダーでHTTPSにリダイレクト
書き換えルールを追加します。
<rewrite>
<rules>
<rule name="Rewrite HTTP to HTTPS" stopProcessing="true">
<match url="^(.*)$"/>
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_X_FORWARDED_PROTO}" pattern!="^https$"/> ← X-Forwarded パラメーター値を判断
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"/>
</rule>
</rules>
</rewrite>
これで、X-Forwarded ヘッダーのパラメーター値で判断し、リダイレクトします。
X-Forwarded ヘッダーは、SSLアクセラレーターにて付与しています。そもそもHTTPでアクセスしてきた場合は、X-Forwarded ヘッダーがありません。この状況を利用して判断します。
X-Forwarded ヘッダーが「https」で無い場合、httpsにリダイレクトさせる条件をいれます。これで、HTTPはHTTPSにリダイレクトが実施されます。
設定を変更したら、IISサービスを再起動するかリロードを実施してください。
以上、「X-Forwarded ヘッダーを見て、HTTPトラフィックをHTTPSにリダイレクトする」という記事でした。
コメント
“RewriteCond %{HTTP:X-Forwarded-Proto} != https”
の記述にある比較は “!=https” のように空白を消さないと
エラーになるような気がします
ご指摘ありがとうございます。動作確認は未実施ですが、可能性があるなら修正させて頂きます。