WordPress がブルートフォースアタックされていたのでいくつか対策しました

2014/04/06

知人の WordPress が不正アクセスされたようだったので明日は我が身だなあと思い、Crazy Bone(狂骨)を入れてログを見てみたら、6 時間弱で 780 件ちょいぐらいログイン総当たり攻撃(ブルートフォースアタック)がきてました。

Crazy Bone はログイン履歴などを見れる WordPress のプラグインです。ブルートフォースアタック受けているかどうか確かめるために入れてみたのですが、便利! 不正ログインされてないか一目瞭然。

wp-numb-loginerror
不正ログインを試みた履歴(クリックで拡大)

Admin とか admin をユーザー名にしてのアタックが多いなあという印象。admin 系のユーザー名使っておらず、Google 2 段階認証も使っていた(「Google 2 段階認証アプリ | Numb.」参照)のでログインされることはなく無事なようでした。

どんな方法が不正ログインを防ぐのに有効か

下記、調べてみた範囲で、メリット・デメリットなども簡単にまとめました。違うだろオラァみたいな内容があったらコメント等で教えてください。

  • IP 制限(サーバー側で設定)
    ……IP で弾くので WordPress のログイン画面に bot は到達できず、ログインを試行されにくくサーバー負荷はかかりにくい。強固な反面、特定の場所からしか更新できないことになる。
  • Bacic 認証(サーバー側で設定)
    ……Basic 認証で弾くので WordPress のログイン画面に bot は到達できず、ログインを試行されにくくサーバー負荷はかかりにくい。
  • Google 2 段階認証(WordPress プラグインを利用)
    WordPress › Google Authenticator « WordPress Plugins
    ……Google 2 段階認証を利用する。ワンタイムパスワードを利用するのでログイン難易度高だが、ログイン試行自体は防げないのでサーバー負荷は減らない。仕方ないとはいえ毎回 OTP 入れるのはちょっと面倒。
  • メールまたは SMS で 2 段階認証(WordPress プラグインを利用)
    WordPress で二段階認証を可能にするプラグイン「魍魎」 | dogmap.jp / WordPress › Spirits and Goblins « WordPress Plugins
    ……メールか SMS にワンタイムパスワードを送って 2 段階認証する。その他は Google 2 段階認証と同じだが、こちらは Crazy Bone と一緒に使える(後述)。
  • 一定回数ログイン失敗で一定時間ログイン不可にする(WordPress プラグインを利用)
    WordPress › Limit Login Attempts « WordPress Plugins
    ……ログイン難易度は別に変わらないが、一定回数失敗すると弾かれるため多少サーバー負荷は良いのかも。

他にも管理画面 SSL とかもありますが今回は飛ばします。

WordPress+サーバー側で設定

今までは Google 2 段階認証を使ってログインの難易度をあげていましたが、bot にログインを試行されるたびに WordPress は起動してしまうわけで、ログインされなくてもサーバーには負荷がかかってしまいます。そこで今回、Basic 認証もかけることにしました。

上記記事がとても参考になりました。ありがとうございます。

EC2+網元(Nginx)で Basic 認証を設定

私は Apache ではなく Nginx なので、.htaccess ではなく /etc/nginx/conf.d/default.conf を編集しました。

まず、下記のようにして .htpasswd を作成。

htpasswd -c /etc/nginx/conf.d/.htpasswd [ユーザー名]

パスワードの入力を求められるので、入力してエンター。再度確認のため入力を求められるので同じ内容を入力してエンター。

その後、/etc/nginx/conf.d/default.conf を開いて編集。下記内容を追記。

server {
    # (略)
    location ~* /wp-login\.php|/wp-admin/(^admin-ajax\.php) {
        if ($request_filename ~ .*\.php) {
            break;
            proxy_pass http://backend;
        }
        include /etc/nginx/expires;

        # IPアドレスで制限する場合は以下の通り
        allow 123.45.67.89;
        deny all;

        # Basic認証のメッセージ
        auth_basic "Please enter your ID and password";
        # .htpasswd ファイルのパス
        auth_basic_user_file /etc/nginx/conf.d/.htpasswd;

    }
    # (略)
}

WordPressの管理画面に制限をかける(ver3.5.1) | Gatespace’s Blog から引用。

編集・保存したら、次のようにして nginx を再起動。

systemctl restart nginx

Basic 認証などサーバー側の設定で弾くことができれば WordPress がログイン試行される回数が減りますので WordPress が起動する回数も減って、結果的にサーバー負荷も減り良いかんじになる……ことを期待。

Google 2 段階認証がエラーを出してログインできない

単純にサーバーと時間がずれてる場合

Google 2 段階認証はサーバーとの時間がずれてるとワンタイムパスワードの有効時間がシビアでうまく入れなかったするので、その場合は管理画面の「ユーザー」>「あなたのプロフィール」の Google Authenticator Settings という項目内「Relaxed mode」にチェックをつけておくと良いです(ワンタイムパスワードの有効時間が延びます)。

Crazy Bone との相性の場合

Crazy Bone と Google 2 段階認証の相性が悪いようで両方有効にするとうまくログインできなくなりました。こっちのケースの場合、仕方ないので CrazyBone を諦める or Google 2 段階認証を諦める、どっちかになるかなーと思います。

私は今回、Google 2 段階認証を止めて様子見することに。Basic 認証を設定してからログイン画面に到達してる bot が全然いないので、止めてみて、ログを見ながら考えようかなと。とりあえず Limit Login Attempts を入れて、万が一 Basic 認証を抜けてログイン画面にきてもログインを何度か失敗すれば弾かれる形に。当面これでやってみます。

2 段階認証をメールか SMS で行う Spirits and Goblins(魍魎)は Crazy Bone と一緒に使っても問題ないので、まだしつこくアタックしてくる bot がいるようだったらそちらを検討しようかなと思います。

まとめ

ブルートフォースアタック流行ってるなー、へー、ぐらいに思ってましたが Crazy Bone 入れて「うおお……」となりました。セキュリティには気を付けているつもりではありましたが、実際にログを見ると怖いなーと思いますね。やっぱり来るモノなんだなあ。

これだけ来るならサーバー負荷もかかると思いますが、今までそこに気が回っていなかったです。とりあえず Crazy Bone でログイン履歴やアタックの形跡があるかを見てみるのはお勧めです。