さくらのレンタルサーバでHTTPS(SNI SSL)な独自ドメインのWordpressサイトを構築する際の注意点

# 2017/7/23 追記
さくらインターネットが、WordPress常時SSL化プラグインの提供を開始しました。さくらのレンタルサーバでHTTPSな独自ドメインのWordpressサイトを構築する場合は、こちらのプラグインを使用することをおすすめします。
https://help.sakura.ad.jp/hc/ja/articles/115000047641

# はじめに
さくらのレンタルサーバ（共有サーバ）でHTTPS(SNI SSL)な独自ドメインのWordpressサイトを構築する際の注意点についてまとめました。

まず、2015/2/4より、共有サーバでの独自SSL(SNI SSL)が利用可能となりました。

* [「さくらのレンタルサーバ」独自SSL機能拡充（SNI SSL提供開始）のお知らせ](http://www.sakura.ad.jp/news/sakurainfo/newsentry.php?id=1018)
* [独自SSL IPアドレスベース／SNI SSL(ネームベース)](http://www.sakura.ad.jp/function/security/original-ssl.html)

SNI（ネームベース）のSSLであるため、SNIに非対応の古い環境（ガラケー、Windows XP等）では正常に動作しませんが、これまでVPSや専用サーバ、上位プラン等でしか利用できなかった独自SSLが安価な共有サーバでも利用できるようになり、手軽にWebサイトのHTTPS化が行えるようになりました。

しかし、共有サーバで提供されるHTTPS接続は一般的な（VPSや専用サーバ等でApacheをインストールして運用する）HTTPSサイトとは異なるため、いくつか注意点があります。

# さくらのレンタルサーバのHTTPS接続の仕様

さくらのレンタルサーバのHTTPS(SNI SSL)は、プロクシとして動作している（TCP/80のリバースプロクシとして動作している）仕様となっています。

## 参考
[SSL利用時の注意点（さくらのサポート情報）](https://help.sakura.ad.jp/app/answers/detail/a_id/2325)より引用

>「さくらのレンタルサーバ」にて提供しているウェブサーバApacheは、 80番ポートを使用する(HTTP)ものと、 443番ポートを使用する(HTTPS)ものとの 2種類に分けられます。 また、後者についてはプロクシとして動作します。 一般的に、前者は「http://」、後者は「https://」という形式でアクセスしますが、 同じディレクトリへのアクセスであっても、その際に呼び出されるウェブサーバ が異なると、 CGIプログラムやウェブサーバが.htaccessなどのファイルを読み込む際、挙動に違いが生じます。
>
> 例えば、HTTPとしてアクセスした場合はお手元のコンピュータが、 HTTPSとしてアクセスした場合は サーバそのものがアクセス元となります。 このため、SSLのみのアクセス許可(HTTPアクセスの制限)や、mod_rewriteによるURLの書き換えはできません。

# リバースプロキシによる影響

前述の通り、さくらのレンタルサーバはリバースプロキシによるHTTPS接続となっています。

その影響として、VPSや専用サーバ上でApache等のWebサーバを立ち上げた場合（プロクシ等を経由せず直接サーバとHTTPSで接続可能な状態）のように、**.htaccessでRewriteCond %{HTTPS}を用いたHTTPS接続の判定や、PHPで$_SERVER['HTTPS']を用いたHTTPS接続の判定が行えません。**（リバースプロキシ経由の接続となり、実行されたファイルからはHTTPで接続されたものと見えるため）

また、実行ファイルから見たURL(URI)は、**https://www.example.com/〜** ではなく、**http://www.example.com/〜** となりますので、例えばPHPの$_SERVER['REQUEST_URI']で現在のURLを取得するようなシステムは正常に動作せず、遷移後のURLがHTTPSではなく、HTTPになってしまう（URLが勝手にHTTPになるように見える）等の問題が発生します。

# Wordpressにおける影響

WordpressをHTTPSで運用する場合、通常は（VPSや専用サーバ等では）WP_HOMEおよびWP_SITEURLの値をデータベースまたはwp-config.phpいずれの変更だけでHTTPSでのサイト公開が行えますが、さくらのレンタルサーバにおいてはこの設定だけでは「**https→httpに勝手にリダイレクトされる**」問題が生じます。

原因は前述の通りとなりますが、これに対処するため.htaccessとwp-config.phpに対する設定変更が必要となります。詳細は下記の通りとなります。

# 対応手順
※環境ごとの設定は適宜変更してください。

まず、Wordpress設置時に追加する（パーマリンク設定時に生成される）.htaccessの先頭に、以下の設定を追加します。

```apache:.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Sakura-Forwarded-For} ^$
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
</IfModule>
```

次に、wp-config.phpの先頭に以下の内容を追加します。

```php:wp-config.php
if( isset($_SERVER['HTTP_X_SAKURA_FORWARDED_FOR']) ) {
    $_SERVER['HTTPS'] = 'on';
    $_ENV['HTTPS'] = 'on';
    $_SERVER['HTTP_HOST'] = 'www.example.com';
    $_SERVER['SERVER_NAME'] = 'www.example.com';
    $_ENV['HTTP_HOST'] = 'www.example.com';
    $_ENV['SERVER_NAME'] = 'www.example.com';
}
```


# 設定例
```apache:.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Sakura-Forwarded-For} ^$
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
</IfModule>


# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
```

```php:wp-config.php
<?php
/**
 * The base configurations of the WordPress.
 *
 * このファイルは、MySQL、テーブル接頭辞、秘密鍵、言語、ABSPATH の設定を含みます。
 * より詳しい情報は {@link http://wpdocs.sourceforge.jp/wp-config.php_%E3%81%AE%E7%B7%A8%E9%9B%86 
 * wp-config.php の編集} を参照してください。MySQL の設定情報はホスティング先より入手できます。
 *
 * このファイルはインストール時に wp-config.php 作成ウィザードが利用します。
 * ウィザードを介さず、このファイルを "wp-config.php" という名前でコピーして直接編集し値を
 * 入力してもかまいません。
 *
 * @package WordPress
 */

// 注意: 
// Windows の "メモ帳" でこのファイルを編集しないでください !
// 問題なく使えるテキストエディタ
// (http://wpdocs.sourceforge.jp/Codex:%E8%AB%87%E8%A9%B1%E5%AE%A4 参照)
// を使用し、必ず UTF-8 の BOM なし (UTF-8N) で保存してください。

// プロクシでIPが入るとSSLアクセス状態をセットする
if( isset($_SERVER['HTTP_X_SAKURA_FORWARDED_FOR']) ) {
    $_SERVER['HTTPS'] = 'on';
    $_ENV['HTTPS'] = 'on';
    $_SERVER['HTTP_HOST'] = 'www.example.com';
    $_SERVER['SERVER_NAME'] = 'www.example.com';
    $_ENV['HTTP_HOST'] = 'www.example.com';
    $_ENV['SERVER_NAME'] = 'www.example.com';
}

// ** MySQL 設定 - こちらの情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define('DB_NAME', 'DB名');

/** MySQL データベースのユーザー名 */
define('DB_USER', 'DBユーザー名');

/** MySQL データベースのパスワード */
define('DB_PASSWORD', 'DBパスワード');

/** MySQL のホスト名 */
define('DB_HOST', 'DBサーバ');

/** データベースのテーブルを作成する際のデータベースのキャラクターセット */
define('DB_CHARSET', 'utf8');

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define('DB_COLLATE', '');

/**#@+
 * 認証用ユニークキー
 *
 * それぞれを異なるユニーク (一意) な文字列に変更してください。
 * {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org の秘密鍵サービス} で自動生成することもできます。
 * 後でいつでも変更して、既存のすべての cookie を無効にできます。これにより、すべてのユーザーを強制的に再ログインさせることになります。
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

/**#@-*/

/**
 * WordPress データベーステーブルの接頭辞
 *
 * それぞれにユニーク (一意) な接頭辞を与えることで一つのデータベースに複数の WordPress を
 * インストールすることができます。半角英数字と下線のみを使用してください。
 */
$table_prefix  = 'wp_prefix';

/**
 * ローカル言語 - このパッケージでは初期値として 'ja' (日本語 UTF-8) が設定されています。
 *
 * WordPress のローカル言語を設定します。設定した言語に対応する MO ファイルが
 * wp-content/languages にインストールされている必要があります。例えば de_DE.mo を
 * wp-content/languages にインストールし WPLANG を 'de_DE' に設定することでドイツ語がサポートされます。
 */
define('WPLANG', 'ja');

/**
 * 開発者へ: WordPress デバッグモード
 *
 * この値を true にすると、開発中に注意 (notice) を表示します。
 * テーマおよびプラグインの開発者には、その開発環境においてこの WP_DEBUG を使用することを強く推奨します。
 */
define('WP_DEBUG', false);

/* 編集が必要なのはここまでです ! WordPress でブログをお楽しみください。 */

/** Absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
	define('ABSPATH', dirname(__FILE__) . '/');

/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');

```
# 参考
* [SSL利用時の注意点（さくらのサポート情報）](https://help.sakura.ad.jp/app/answers/detail/a_id/2325)
* [さくらレンタルサーバーの共有SSLを使う](http://wsf.mot.or.jp/yujakudo/website-admin/shared-ssl/use-shared-ssl-of-sakura/)
* [さくらでHTTPSにするSSL SNIの設定の仕方](https://www.haluka.org/blog/2353/)
*[https→httpに勝手にリダイレクトされてしまいます](https://ja.forums.wordpress.org/topic/151032)