WordPressのリバースプロキシ対策を行うプラグイン

をかもとさんのかねてからのオススメでついにこのサイトもNginx + リバースプロキシで構築しなおしました。

結果的には約1,000倍以上高速になりましたよ。

構築化に関する詳しいハウツーはもったいつけて省略しますが、結果だけ自慢させて頂きます。笑

以下は、同じサーバー内からこのブログにapacheベンチを実施した結果です。

ab -n 100 -c 20 https://firegoby.jp/
  • 1秒あたりの処理 – 6,368.62リクエスト
  • 1リクエストあたりの時間 – 0.157ミリ秒

コンテンツをリバースプロキシで静的にキャッシュしているので、超高速になっているのがお分かりいただけると思います。

ちなみに、サーバーは月額980円の「さくらのVPS 512」です。^^

詳しいデータをちゃんと保存してないのですが、Apache上でリバースプロキシなしで運用していた際は、秒間 4リクエスト前後だったので、信じがたいことに1,000倍以上高速になりました。

ただし、ネットワーク越しではネットワークがボトルネックになってしまい、それほど早くなるわけではありません。

しかしメモリやCPUなどのリソースは劇的に節約できるようになりましたので、エコになったことは確かです。^^

やや自慢が長くなりましたが(笑)、本題はここからです。

リバースプロキシを導入する際の問題点

このように劇的な高速が期待できるリバースプロキシですが、いいことだけではありません。

リバースプロキシは、WordPressが出力するコンテンツを静的なHTMLファイルとしてサーバー内にキャッシュしますので以下のような問題に直面します。

今回は特にWordPressで考慮すべき問題についてのみご説明します。

1)管理画面の問題

もしリバースプロキシが wp-admin/ 以下のディレクトリをキャッシュしてしまうと使いものになりません。
wp-admin/ 以下をキャッシュしないように設定する必要があります。

ただし、WordPressはデフォルトで管理画面以下ではno-cacheヘッダを送信していますので、通常の設定ではリバースプロキシはキャッシュしません。

2)Adminバーの問題

管理画面だけでなくサイト側でもAdminバーを出力しますので、これもキャッシュされてはいけません。
クッキーの有無を判別してキャッシュを使用しない設定を加える必要があります。

Adminバーはコンテンツの中に直接埋めこまれて出力されますので、この設定は必ず必要です。

3)コメントフォームの問題

WordPressでは、コメントを投稿した際に投稿者の名前やメールアドレス、URLをクッキーで取得して、コンテンツの中に埋め込んだ状態で出力します。

したがって、キャッシュの有効期限をまたがってコメントを投稿されると、投稿者の情報が埋め込まれたままキャッシュされることがあり、個人情報の漏洩につながります。

WordPress + リバースプロキシについて触れられたネット上のブログ記事では、この対策として、コメント投稿者のクッキーの有無を判別して、クッキーがあるユーザーにはキャッシュを使用しない設定を加えています。

しかし、この場合コメント投稿者には常にキャッシュが使用されないという問題が発生します。

4)パスワード保護されたコンテンツの問題

パスワード保護されたコンテンツも同様にパスワードが入力されてコンテンツが表示された状態でキャッシュされる可能性があります。

キャッシュの有効期限が10分の場合、そのページを開いた状態で10分待ち、そのあとでパスワードを入力してコンテンツが表示された際に、他のだれからもアクセスがなければ、コンテンツが表示された状態でキャッシュが生成されます。

この場合も同じくクッキーの有無を判別してキャッシュを使用しない設定を加える必要があります。

これらを解決するプラグイン

上述した4つの問題のうち、コメントフォームとパスワード保護がかかった投稿に関する問題については、サーバーの設定でも回避できますが、以下のような問題が残ります。

  1. サーバーの設定で回避するにはクッキーのキーで判別する必要があり、WordPress本体のアップデート等でクッキーのキーが変わった場合のことを想像すると気持ち悪い。(クッキーのキーが変わることはないと思いますが、もしものときは個人情報の漏洩につながりますので…。)
  2. クッキーで判別しても、コメント投稿者の情報はコメント欄があるすべての記事で挿入されるので、コメント投稿者にはそれらすべてのページでキャッシュが利用されない。

以上の問題を回避するために私なりに以下のような方法で解決できるのではないかと考えました。

  • パスワード保護がかかったページでは、自動的にno-cacheヘッダを送出して、リバースプロキシ側で特別な設定がなくてもキャッシュされないようにする。
  • コメントフォームでは、フォームのHTML内に直接投稿者の情報を埋め込むのではなく、AJAXでJSONからデータを取得するようにし、JSONを出力する際にはno-cacheヘッダを送出する。

というわけで以上の処理を行うプラグインを作りました。

nginx-champuru.zip

このプラグインを使用するとパスワード保護されたページとJSON以外のサイト側のページは普通にキャッシュできますし、設定も若干減りますので幸せになれるのではないかと思うのですがどうでしょう?

まだβテスト中なので、お試しになる場合はオウンリスクでお願いします。

ソースはGitHunbで公開しています。

miya0001/nginx-champuru – GitHub

あと、リバースプロキシを使用していない環境では、メリットゼロです。インストールしないで下さい。

しばらく様子を見て公式ディレクトリにも登録しますので、フィードバックをたくさんいただけると嬉しいです。

余裕があればnginx_cache_purgeを使用して、保存するたびに必要なページのキャッシュをクリアする機能も実装しようかなと思っていますが、nginx cache purgeをnginxに組み込むにはソースのコンパイルとかRPMの再構築が必要で、ほとんど需要がなさそうな気がしますので、どうしようかな?ってかんじです。

リバースプロキシはプラグインとも相性があるのでよく注意して導入しましょう。

同じサーバー内の別のサイトで、キャッシュが生成されなくてめちゃくちゃハマったのですが、MobilePressプラグインは常にno-cacheヘッダを出してしまう仕様なので、リバースプロキシを導入しても、このプラグインを使用すると意味ねーじゃんってことになりますのでご注意を。

このようにリバースプロキシはプラグインとも相性がありますので、よくわからない人は使わないほうが無難かもしれないです。

特にコミュニティサイトとかソーシャルサイトみたいなことをやる場合には、個人情報の漏洩とかにつながるリスクがあるので、ヒャッホー早くなったぜなんて話に安易に飛びついたらダメですよ。^^