WordPressの特定のファイルに対してNginxでIPを規制する方法


投稿日:2015年5月9日
  • 8
  • 0



ログに流れるスパマーとのイタチごっこも疲れた方に

nginxip

あまりの普及率にスパマーからも大人気のWordPress。

数あるスパム行為の中でも特に問題なのがwp-login.phpxmlrpc.phpに対して繰り返されるブルートフォース攻撃です。Basic認証を導入するのが一般的な対策ですが、予約投稿が機能しなくなったり、二重にログインするというのも煩わしいものです。

手間のかからない対策をということで、当サイトではSwatchで当該ファイルへの連続したアクセスをフィルタリングしています。

興味のある方は「Swatchでログを監視して、攻撃に合わせた対策を自動で実行する方法」をご覧ください。

これはこれで有効に機能しているのですが、念の為にと導入した「狂骨(Crazy Bone)」というプラグインでログイン履歴を見ると、散発的ながらブルートフォース攻撃が行われています。

nginxip01

規制にかからないように、何種類ものIPを組み合わせて、ゆっくりとしたペースで攻撃しています。(速いペースのものは接続拒否している証拠でもあります)
当サイトではパスワードを強固なものにしているので、この程度の総当たり攻撃では1000年続けても破られることはありません。またペースも遅いのでリソースの消費も無視して良い程度です。

まず安心して良い状況と言えますが、ログイン情報に自分以外のIPが列挙されるというのも精神衛生上よくありません。ログを見てみると、どれか特定の国というわけでもなく、様々な国から来ているので国単位での規制も難しいようです。

そこでタイトルにある通りWordPressの特定のファイルを対象に、NginxでIPによる規制をかけることになりました。


NginxでIPによる規制をかける方法

前置きが長くなりましたが、方法は至って簡単です。
まずはNginxのディレクティブについて簡単に解説します。

Nginxのディレクティブについて

Nginxのlocationディレクティブの書式は以下のようになっています。

location プレフィックス URIのパス {
    [locationコンテキスト]
}

プレフィックスの種類と意味

プレフィックス 意味
なし 前方一致
^~ 前方一致。一致したら、正規表現の条件を評価しない。
= 完全一致。パスが等しい場合。
~ 正規表現(大文字・小文字を区別する)
~* 正規表現(大文字・小文字を区別しない)

プレフィックスごとの優先順位は「完全一致 > 前方一致 > 正規表現 > なし」となっており、それぞれ「最長一致 > 部分一致」となってます。

詳しく知りたい方は「こちらのサイト」で詳しく解説されています。

今回は正規表現で部分一致した場合にIPを規制します。

具体的にはWordPressを動かしているserverディレクティブに以下の記述を追加するだけです。

バックエンドサーバ側ではないので注意。

また、正規表現で一致した項目に関する設定はそこで終了するので順序に気をつけてください。serverディレクティブのlocationに関する設定の先頭に追加すれば安心です。

Nginxの設定の優先順位については「Nginx で location の判定方法と優先順位を調べる」で詳しく解説されています。
# admin-ajax.phpを使うプラグインがあるので例外に登録
location ~ wp-login\.php$|xmlrpc\.php$|wp-admin/((?!admin-ajax\.php).)*$ {
    allow 0.0.0.0/16; # 自分の固定IPや、ISPのIPアドレス
    allow 153.122.40.105; # サーバ自体のIP
    allow 127.0.0.1;
    deny all;
    proxy_pass http://backend;
}

正規表現なのでドットはバックスラッシュでエンティティ処理。また「.php」という名前が途中に入ることは考えにくいですが、文末を示す「$(ドルマーク)」を指定しています。

同じようにxmlrpc.phpwp-adminについての処理を「|(パイプ)」で繋げています。

追記:admin-ajax.phpを利用するプラグインがあるので(WordPress Popular Postsなど)例外として許可する設定に変更しました。またWordPress Popular Postsは一度しかカウントしないtokenを発行するので、リバースプロキシやキャッシュ系プラグインが有効な場合は設定画面でAjaxify widgetを有効にする必要があります。

コンテキストには「allow <IPアドレス>」といった書式でホワイトリスト形式でIPを追加します。
ログインするIPが固定なら固定IPアドレス。もしくはISP(インターネットサービスプロバイダー)に割り振られたIPの範囲を指定。サンプルにあるようにサブネットマスクも使えるので指定は簡単です。

ISPに割り振られたIPの範囲を知りたい場合は以前の投稿で紹介した「JPNIC WHOIS Gateway」などを利用してください。

続けてサーバのIPアドレスローカルIPアドレスを追加。

最後の「proxy_pass http://backend」は、別の場所で定義したバックエンドサーバを指定しています。
普通にphp-fpmで実行するだけなら以下のように直接書いても問題ありません。

fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index  index.php;
fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
include        fastcgi_params;

後はnginxを再起動すれば、設定が有効になります。
記載したIP以外でアクセスすると403エラーになります。試しに自分の固定IPアドレスをコメントアウトしてテストしてみてください。


現在のページを共有する



現在のページに関連する記事

WordPressの特定のファイルに対してNginxでIPを規制する方法 WordPress Popular Postsでページビューがカウントされない場合に試す4つのこと
WordPressの特定のファイルに対してNginxでIPを規制する方法 ロリポップ!から「不正なアクセスを検知いたしました」というメールが届いた
WordPressの特定のファイルに対してNginxでIPを規制する方法 whoisが暴走してCPU利用率が100%になった場合の対処法
WordPressの特定のファイルに対してNginxでIPを規制する方法 Swatchでログを監視して、攻撃に合わせた対策を自動で実行する方法
WordPressの特定のファイルに対してNginxでIPを規制する方法 ロリポップ!で起きている大規模な改ざんからWordPressサイトを守る方法
WordPressの特定のファイルに対してNginxでIPを規制する方法 Nginxで502 Bad Gatewayの原因が「upstream sent too big header~」の場合の対処法
WordPressの特定のファイルに対してNginxでIPを規制する方法 Nginxとリバースプロキシ、php-fpmとOPcacheのインストールと設定

おすすめの記事

PukiWikiで5段階評価を付けるプラグインを作成しました

PukiWikiで5段階評価を付けるプラグインを作成しました

Question2AnswerへreCAPTCHAを導入する方法

Question2AnswerへreCAPTCHAを導入する方法

Google Feed APIの代替手段としてjQueryだけでRSSを表示する方法

Google Feed APIの代替手段としてjQueryだけでRSSを表示する方法

そのサイト、WordPressじゃなくてWixで十分じゃない?

そのサイト、WordPressじゃなくてWixで十分じゃない?

UWSCでPhotoshopの作業を自動化する方法

UWSCでPhotoshopの作業を自動化する方法

5段階評価プラグインを通して学ぶPukiWikiのプラグインを作成する方法

5段階評価プラグインを通して学ぶPukiWikiのプラグインを作成す…

誤って削除したGoogle Chromeのブックマークを復元する方法

誤って削除したGoogle Chromeのブックマークを復元する方法

公式ドキュメントよりも詳しいTinyMCEの使い方(基本編)

公式ドキュメントよりも詳しいTinyMCEの使い方(基本編)


コメントを残す

コメントは認証制のため、すぐには反映されません。

プログラミングに関する質問は「日本語でプログラミングの悩みを解決するQ&Aサイト sukegra」をご利用ください。