管理画面での SSL 通信

管理画面へのアクセスを簡単にかつ強制的に SSL 接続にするにはサイトの wp-config.php ファイルに FORCE_SSL_ADMIN 定数を定義します。この定数をプラグインファイル内に定義しても十分ではありません。wp-config.php ファイルで定義する必要があります。なおここではサーバーの SSL 構成や、サイトの前でセキュアサーバー用に構成された (バーチャル) ホストはこの定数を true に設定しても正しく動作するものとします。

注意: FORCE_SSL_LOGIN は Version 4.0 で廃止されました。FORCE_SSL_ADMIN を使用してください。

SSL によるログインと管理画面へのアクセスを強制する

すべてのログイン、およびすべての管理画面へのアクセスを SSL を通して行うには FORCE_SSL_ADMIN 定数を true に設定します。

  define('FORCE_SSL_ADMIN', true);

リバースプロキシの使用

SSL を提供するリバースプロキシにより WordPress がホストされ、自身は SSL なしでホストされる場合、このオプションを設定すると当初すべてのリクエストが無限リダイレクトループに陥ります。これを避けるには HTTP_X_FORWARDED_PROTO ヘッダーを認識するように WordPress を構成してください。ここでリバースプロキシは適切に構成されており、ヘッダーを設定するものとします。

define('FORCE_SSL_ADMIN', true);
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' ) {
       $_SERVER['HTTPS']='on';
}

追加情報

この記事の後半では古いバージョンの WordPress を使っている場合 (使うべきではありませんが)、または SSL 設定が異なる場合、たとえば SSL 証明書が異なるドメイン用のものである場合等の構成を説明します。

https プロトコルを使用したセキュアな接続上で wp-admin 全体を動作させたいとします。このとき大きく以下の手順で設定します。

  1. 同一 URL (ブログ URL) で、セキュア (SSL 通信) とセキュアでない2つのバーチャルホストを設定する。
  2. セキュアなバーチャルホストでは、wp-admin 以外のすべてのトラフィックをセキュアでないサイトへ転送する Rewrite ルールを設定する。
  3. セキュアでないバーチャルホストでは、wp-admin のすべてのトラフィックをセキュアなバーチャルホストへ転送する Rewrite ルールを設定する。
  4. プラグイン経由で wp-admin 内のリンク用のフィルタを定義する。一度有効化されると、管理画面へのリンクは https を使用するように書き換えられ、cookie は暗号化した接続でのみ動作するように編集される。

以下のガイドでは WordPress 1.5 と httpd.conf (.htaccess ではなく) の Rewrite ルールを使用した mod_rewrite 稼働の Apache を使用します。他のホスティングのケースでも簡単に修正して適用できます。

バーチャルホスト

セキュアでないサイトに追加して、セキュアサーバー用に設定された (バーチャル) ホストが必要です。この例ではセキュアなバーチャルホストがセキュアでないホストと同じ DocumentRoot を使用します。仮に wpadmin.mysite.com のような異なる名前を使用する場合は DocumentRoot を wpadmin ディレクトリにリンクしてください。

セキュアなバーチャルホストの設定については、利用しているISPに問い合わせてください。管理者権限を持つ場合には自分で設定することもできます。注意: 異なる SSL サーバーの識別に名前ベースのバーチャルホストは使用できません。参照: http://httpd.apache.org/docs-2.0/ssl/ssl_faq.html#vhosts2

セキュアでないホストの Rewrite ルール

セキュアでないホストの .htaccess または httpd.conf のバーチャルホスト部分に次の Rewrite ルールを追加します。http://mysite.com/wp-admin/ や http://mysite.com/wp-login.php を表示する際に自動でセキュアなホストに転送されます。

メインの WordPress 系 Rewrite ブロックの上に追加する必要があります。

  RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)\ HTTP/ [NC]
  RewriteCond %{HTTPS} !=on [NC]
  RewriteRule ^/?(wp-admin/|wp-login\.php) https://mysite.com%{REQUEST_URI}%{QUERY_STRING} [R=301,QSA,L]

パーマリンクの Rewrite ルールを使用している場合、この行は RewriteRule ^.*$ - [S=40] の前に設定する必要があります。

上のコードで重要な点は「THE_REQUEST」の使用です。これにより実際の http リクエストのみが書き換えられ、include や fopen のようなローカルでのダイレクトなファイル要求は書き換えられないことが保証されます。

セキュアなホストの Rewrite ルール (オプション)

以下の Rewrite ルールはオプションです。このルールによりセキュアな接続上のパブリックなサイトへのアクセスは無効化されます。以下のプラグインを使用してサイトのパブリックな部分にログインしたままにしたければ、このルールを追加しないでください。暗号化されていない接続上でプラグインが cookie を無効化します。

セキュアなバーチャルホストでは .htaccess ファイル内、またはバーチャルホストの宣言内で2つの Rewrite ルールを定義する必要があります (Rewrite の詳細については「パーマリンクの使い方」を参照してください)。

   RewriteRule !^/wp-admin/(.*) - [C]
   RewriteRule ^/(.*) http://www.mysite.com/$1 [QSA,L]

最初のルールは次の2番目のルールの対象から wp-admin ディレクトリを除外します。2番目のルールはセキュアサイトへのアクセスをセキュアでないサイトへのアクセスに変換します。閲覧者が意識することはなく快適さが保たれます。

WordPress URIを設定する

ある種のプラグインの動作のため、または何らかの理由によりオプションに WordPress URI を設定し https プロトコルを反映するには https://mysite.com を設定します。ブログのアドレスは変わりません。

構成例 (一部)

注意: 以下の構成は WordPress 2.8 以上と 100% 互換ではありません。これは WordPress 2.8 が wp-includes フォルダーからファイルを使用するためです。はじめの Rewrite ルールによるリダイレクトからセキュリティの警告が出る場合があります。詳細情報については https://core.trac.wordpress.org/ticket/10079 を参照してください。

<VirtualHost nnn.nnn.nnn.nnn:443>
        ServerName www.mysite.com

        SSLEngine On
        SSLCertificateFile    /etc/apache2/ssl/thissite.crt
        SSLCertificateKeyFile /etc/apache2/ssl/thissite.pem
        SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown

        DocumentRoot /var/www/mysite

        <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteRule !^/wp-(admin|includes)/(.*) - [C]
                RewriteRule ^/(.*) http://www.mysite.com/$1 [QSA,L]
        </IfModule>
        ...
</VirtualHost>

# セキュアでないサイト

<VirtualHost *>
        ServerName www.mysite.com

        DocumentRoot /var/www/ii/mysite

        <Directory /var/www/ii/mysite >
                <IfModule mod_rewrite.c>
                        RewriteEngine On
                        RewriteBase /
                        RewriteCond %{REQUEST_FILENAME} -f [OR]
                        RewriteCond %{REQUEST_FILENAME} -d
                        RewriteRule ^wp-admin/(.*) https://www.mysite.com/wp-admin/$1 [C]
                        RewriteRule ^.*$ - [S=40]
                        RewriteRule ^feed/(feed|rdf|rss|rss2|atom)/?$ /index.php?&feed=$1 [QSA,L]
                        ...
                </IfModule>
         </Directory>
         ...
</VirtualHost>

ユーザーログインとユーザー登録の Rewrite

ユーザーログインとユーザー登録にも SSL を使用することは良い考えです。次の更新版 Rewrite ルールを検討してください。

セキュアでないホスト
RewriteRule ^/wp-(admin|login|register)(.*) https://www.mysite.com/wp-$1$2 [C]
セキュアなホスト
RewriteRule !^/wp-(admin|login|register)(.*) - [C]

443番または80番ポートで動作するサイトの Rewrite

# WordPress 開始
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

# 443番ポート等で動作するサイト (http over ssl)
RewriteCond %{SERVER_PORT}  !^80$
RewriteRule !^wp-(admin|login|register)(.*) - [C]
RewriteRule ^(.*)$ http://%{SERVER_NAME}/$1 [L]

# 80番ポートで動作するサイト (http)
RewriteCond %{SERVER_PORT}  ^80$
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^wp-(admin|login|register)(.*) https://%{SERVER_NAME}:10001/wp-$1$2 [L]

RewriteCond %{SERVER_PORT}  ^80$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>

まとめ

この方法は WordPress に 内在するセキュリティリスク を修正しません。また、内部ユーザーからの攻撃やセキュアな接続を脅かすその他のリスクからも WordPress を保護しません。

それでも悪意あるユーザーによる cookie や認証ヘッダの取得、および管理者を偽装した wp-admin へのアクセスを非常に難しくします。またコンテンツが盗み見される可能性を減らします。ドラフト文書を保持する法律関連のブログなど厳格な保護が必要なサイトでは重要です。

検証

筆者のサーバーログで確認したところ GET リクエストと POST リクエストの両方が SSL を使用し、セキュアでないホスト上のすべての wp-admin へのトラフィックがセキュアなホストに転送されました。

サンプルの投稿ログ:

[Thu Apr 28 09:34:33 2005] 
Subsequent (No.5) HTTPS request received for child 6 (server foo.com:443) xx.xxx.xxx.xxx - - [28/Apr/2005:09:34:33 -0500] "POST /wp-admin/post.php HTTP/1.1" 302 - "https://foo.com/wp-admin/post.php?acti on=edit&post=71" "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.7) Gecko/20050414 Firefox/1.0.3"

実際には追加のテスト、可能であればパケットスニファーや本格的なネットワーク解析ツールを使用した確認が必要です。

制限

筆者の考えでは (検証はしていません) ユーザーが cookie を保存するか、フォームのフィールドベースでなく、何らかの外部の認証の仕組みを使用してブラウザにパスワードを保管し、http://www.mysite.com/wp-admin/ にアクセスすると、パケットは平文で流れ、cookie または認証ヘッダを横取りされるのではないかと思います。したがって最大のセキュリティを確保するには、ユーザーは明示的に https ホストを使用するか、常に新しいセッションの最初でログインする必要があります。

関連

この記事は役に立ちましたか ? どうすればさらに改善できますか ?