この記事をシェアする

2012年の後半ぐらいからレンタルサーバーでWAF(ウェブアプリケーションファイアウォール)を導入するところが増えてきました。
WAF自体は良い物なのですが、CMSとの相性が悪い(CMSの動作が誤検知されてしまい403エラーを返される)ためか、「オフにすべし」といった情報が散見されます。
わざわざ良い物をオフにしてセキュリティのリスクを上げることもないし、せっかくなのでWAFとWordPressを共存させてみたいと思います。

WAF(ウェブアプリケーションファイアウォール)とは

さくらインターネットWAF

WAF(ウェブアプリケーションファイアウォール)は、従来のファイアウォールやIDS、IPSでは防御できなかった攻撃を検知し、ブロックする機能です。

引用「さくらインターネット – WAF(ウェブアプリケーションファイアウォール)」

導入することでWebサーバーに対する不正なアクセスをWAFがブロックしてくれます。静的なコンテンツ(html、画像、css)には効果がありませんが、PHPやCGIを利用している場合には導入しておいた方が良さそうです。

さくらのレンタルサーバー(マネージドサーバー含む)の場合、デフォルトでオフになっており、必要に応じて有効化するようになっています。
これに対し、ロリポップではWAF導入以降に契約した場合、デフォルトでオンになっています。

WAFとCMS

さくらインターネットのページで丁寧に説明されていますが、mod_rewriteを利用していたり、PHP、CGIを使っている場合には動作に影響が出ます。
実際、WordPress日本語フォーラムには(主にロリポップの)WAFが原因と思われる意図しないエラーの投稿が多くあります。

なおWordPressだけでなく全てのCMSで動作に影響が出る可能性があります。

とはいえ「CMSで403になるからWAFを無効にする」というのはセキュリティを自ら下げることになるので共存できる方法を探ります。

WAFとWordPressの共存(さくらのレンタルサーバーの場合)

既にロリポップでの方法を書かれた記事がありますので、これに倣ってさくらのレンタルサーバーでも設定していきます。

※さくらのマネージドサーバーにもWAFは導入されていますが、環境が用意できなかったので割愛します。

その際、運用は以下の様に行うことを前提とします。

  1. ドメインを閲覧用と管理用で分ける。
  2. 閲覧用のドメイン http://example.com
    WAFで防御して運用する
  3. 管理用のドメイン https://example.sakura.ne.jp
    WAFを無効にするがBasic認証をかけ、共有SSLで運用する

手順1. 閲覧用と管理用のドメインを用意

閲覧用のドメインと管理用のドメインとで2つ用意します。
独自ドメインまたはさくらのレンタルサーバーではサブドメインを取得しこれを閲覧用にします。
また共有SSLは契約時に用意されたさくらのドメイン(sakura.ne.jp)=初期ドメインでの利用が推奨されていますので、こちらを管理用にします。

サブドメインで共有SSLを利用すると警告ウィンドウが出る(推奨されていない)
サブドメインで共有SSLを利用すると警告ウィンドウが出る(推奨されていない)

独自ドメインの設定やサブドメイン、共有SSL利用時の注意点についてはさくらのレンタルサーバーの以下のページをご覧ください。

手順2. 共有SSLの設定

サーバコントロールパネルから初期ドメインに共有SSLを設定します。

ログイン後、メニューから「ドメイン設定」を選択します。
ドメイン一覧から初期ドメイン(example.sakura.ne.jp)の「変更」をクリックします。

ドメイン一覧

「共有SSLを利用する」にチェックを入れ送信ボタンを押します。

共有SSLオン

https://example.sakura.ne.jp でアクセスできる様になっていれば完了です。

手順3. WordPressのインストールとダッシュボードをSSL対応にする

データベースを用意し、閲覧用のドメインでWordPressをインストールしておきます(あとから「設定」>「一般」の「WordPress アドレス (URL)」を変更しなくてもよくするため)。

WPインストール

インストールが終わったらそのままダッシュボード(管理画面)にログインします。

メニューの「プラグイン」>「新規追加」で「WordPress HTTPS (SSL)」をインストール(もしくはFTPでアップロード)し、有効化します。

プラグインインストール

有効化するとメニューに「HTTPS」が追加されるので、そこから設定を行いダッシュボード(管理画面)をSSL化します。

HTTPS

  • SSL Hostexample.sakura.ne.jp(共有SSLのホスト)
  • Force SSL Administrationチェック
    ダッシュボードは常にHTTPSでアクセスするようにする。wp-config.php で行う FORCE_SSL_ADMIN と同じです。
    参照)日本語Codex:Administration Over SSL
  • Force SSL Exclusivelyチェック
    「Secure post」にチェックを入れていない投稿や固定ページはHTTPで表示するようにリダイレクトする。
    チェック入れないとサイト全体がSSL化されてしまいます。

入力後は「Save Changes」をクリックして保存します。

保存後、警告やエラーが表示されると思いますが、 https://example.sakura.ne.jp/wp-login.php からログインしなおしてください。
この段階でサイト全体は閲覧用のアドレス、ダッシュボードは管理用の共有SSLのアドレスに適切にリダイレクトされているかどうか確認してください。

手順4. 管理用のドメイン(共有SSL)にはBasic認証をかける

先に書いたとおり、管理用のドメインはWAFは無効にしているので、Basic認証で防御します(Basic認証ではなくIPアドレスによる制限でも可能だと思います)。
自分で書いても良いのですが、今回はサーバコントロールパネルから作ります。

さくらのサーバーコントロールパネルから「ファイルマネージャー」を選択すると、サーバーのファイルを操作できます。
WordPressをインストールしたディレクトリが表示された状態で「表示されたアドレスへの操作」>「アクセス設定」を選びます。

ファイルマネージャー

「パスワード制限」タブで設定します。

  • 有効性「パスワード制限を使用する」をチェック
  • 接続元アクセス制限との併用:IPアドレスによる制限を併用するかどうか。お好みで。
  • パスワードファイル「編集」を押してユーザー名とパスワードを設定します。


詳しくはさくらのヘルプページをご覧ください。

出来上がった .htaccess ファイルはこんな感じです(他にも書いてある可能性があります)

AuthUserFile /home/(ユーザー名)/www/.htpasswd
AuthType Basic
AuthName "Web access"
Require valid-user
Satisfy all
Order deny,allow

このままでは閲覧用のドメインでもBasic認証がかかってしまいますので、.htaccessファイルに手を加え、閲覧用ドメインの場合はBasic認証を要求しないようにします(最後の2行を変えます)。

AuthUserFile /home/(ユーザー名)/www/.htpasswd
AuthType Basic
AuthName "Web access"
Require valid-user
SetEnvIf Host "^example.com$" allow_host
Order deny,allow
deny from all
allow from env=allow_host
Satisfy any

これで管理用のドメインでアクセスした場合のみBasic認証が要求されます。

basic認証

手順5. WAFを有効化する

最後にWAFを有効化します。

さくらのサーバーコントロールパネルから「Webアプリケーションファイアウォール」を選択します。
閲覧用のドメインのみ「利用する」にチェックを入れ「変更」を押します。

WAF画面


これで全ての設定が終わりましたのでテストしてみます。

閲覧用のページを表示し、URL末尾に ?a=<script>alert(1)</script> を追加してみてください。WAFが有効になっているので403エラーになります。

403

次にWordPressにログインし、同じようにURL末尾に ?a=<script>alert(1)</script> を追加してみます。
WAFが無効になっているので特にエラーは起きません。

ダッシュボード

なお、WAFの検知ログはサーバーコントロールパネルの「Webアプリケーションファイアウォール」から確認できます(ただし検知してすぐには反映されない模様)。

ログ

この運用上の気になるところや注意点

1. アップロードされたメディア

メディアをアップロードし、投稿に挿入すると画像のパスは管理用(共有SSL)のURLが使われ、データベースへもそのURLで保存されます。
ですが、プラグイン(WordPress HTTPS)でフィルターフックしてるようで、投稿を表示する時にソース上も閲覧用のURLに置き換えられています。
通常の運用では問題にならないと思いますが、サーバーの移転やドメインの変更などを行う場合は注意する必要があります。

2. admin-ajax.php

以前「WordPressの管理画面に制限をかける(ver3.5.1)」でも書きましたが、/wp-admin/admin-ajax.php をダッシュボード以外で利用しているケースがあります。
「ダッシュボードにBasic認証をかける場合は除外すべし」となっているのですが、今回は .htaccess で閲覧用のドメインの場合はBasic認証を除外していますので、問題無く利用できます。

3. クロスドメイン制約

この例では管理用と閲覧用途で別のドメインにしているため、WordPressにログインしていてもサイト閲覧時には管理バーが表示されません。これは閲覧用のドメインでログインしていないからです。
クロスドメインによる制限として

  • 投稿のプレビューができない(プレビュー用のURLは閲覧用のURLにパラメーターを渡しているだけ)
  • 通常ログインしていれば見られる非公開の投稿を見ることができない
  • 同様に、ユーザー限定コンテンツのような、ログイン状態を判断させるようなサイトには向かない

が挙げられます。

ただし、これはあくまでクロスドメインによる制限なので、(未確認ではありますが)独自ドメイン+SSLであれば大丈夫だと思います(さくらのレンタルサーバーのWAFの場合、独自SSLを設定したドメインへのHTTPSリクエストについては対象外としているため)。


WAFを導入すればセキュリティ対策は完璧!という訳では絶対ありませんが、CMSを運用する際のセキュリティ対策の一助になればと思います。

この記事をシェアする