WordPressのセキュリティ対策(2020年9月版)
昨年に引き続きまたWordpressの移転作業を行ったところ、Wordpressのバージョンアップに伴ってか、セキュリティ対策方法を若干変えないといけない部分がでてきたので解説します。
※注意! Wordpressのサイトヘルスチェックをクリアできていなかったので、2020年0月17日に赤字部分を追記しました。
IP Geo Blockを使う
まずはWordpressのプラグインの IP Geo Blockを導入して、有効化します(あとで削除してもいいです)。このプラグインは、Wordpressの各種ファイルのうち、外部からアクセスされてはマズいファイルを監視してくれ、また国ごとのアクセス制限ができます。
Wordpressの管理画面→「プラグイン」→「新規追加」→「IP Geo Block」で検索すると簡単に見つかります。
有効化したあと、以下のように設定します。
- 「あなたのIPアドレス/国コード」
- 「マッチング規則」
- 「国コードのホワイトリスト」
- 「国コードに優先する……」
自分の住んでいる場所もしくはサーバのある場所の国コードをセットします(自動でセットされます)。私の場合はベトナムです。
「ホワイトリスト」にします。
必要な国を2桁で入力します。私の場合、居住地のベトナム(VN)、サーバのある香港(HK)、別サーバのあるシンガポール(SG)、プロキシやVPNで使うことのある日本(JP)、よくいく隣国のカンボジア(KH)を入れておきました。2桁の国コードはここから検索できます。
国コードを無視してホワイトリストにいれるIPアドレスを指定します。国別IPアドレスは誤判定もありえますし、確実に許可できるIPアドレスを指定しておきます。
それから、「バックエンドの設定」で必要に応じて「国コードでの遮断」をしておきます。「フロントエンドの設定」は何もしません。フロントエンドに国コードでの遮断を行うと、コンテンツの閲覧自体がホワイトリスト国以外からはできなくなります。
設定を更新してしばらくすると、この「ログ」タブに攻撃とブロックの履歴が出てきます。
もちろんこれだけでも防御になりますが、私的には不十分なので次の章にてBasic/Digest認証で必要ファイルをサーバレベルで防御します。今回、このGeo IP Blockは主にBasic/Digest認証での防御の確認に使うことにします。
/wp-admin 全体にBasic/Digest認証をかけてはいけない
以前は、{DocumentRoot}/wp-admin/ ディレクトリ全体にBasic/Digest認証をかけてしまってよかったのですが、いまはよろしくないようで、admin-ajax.phpというファイルを除外してやらなければいけません。
{DocumentRoot}/wp-admin/.htaccessを以下の内容で設定します。
※赤字部分は2020年9月17日追記。サイトヘルスチェックをクリアするため、ローカルIPアドレスからの接続を許可します。
AuthUserFile /var/www/.htaccess_pass_wordpress
AuthGroupFile /dev/null
AuthName “Secure Zone”
AuthType Digest
require valid-user
require ip xxx.xxx.xxx.xxx 127.0.0.1<FilesMatch “(admin-ajax.php)$”>
Satisfy Any
Order allow,deny
Allow from all
Deny from none
</FilesMatch>
Digest認証をかけて、なおかつ admin-ajax.php だけはどこからでもアクセスできる設定です。
そのあと以下のようにDigest認証のパスワードファイルを作っておきます。USERNAMEは適宜置き換えてください。
$ htdigest -c /var/www/.htaccess_pass_wordpress “Secure Zone” USERNASME
Adding password for USERNAME in realm Secure Zone.
Newpassword:
Re-type new password:
これでhttpdを再起動すれば、 {DocumentRoot}/wp-admin/ は、admin-ajax.php を除いてIDパスワードなしではアクセスできなくなります。
ルートディレクトリでBasic/Digest認証をかけるべきファイル
WordPressのルートディレクトリでアクセス制限をするファイル一覧は以下です。
- wp-login.php
- wp-config.php
- xmlrpc.php
- wp-cron.php
管理者や投稿者のログインに使います
データベースなどの設定を記述します
他プラットフォームとの連携に使います。Wordpress ver5以上ではもう無効になっているようなので、本当は防御不要のようですが……。
定時実行(バックアップや予約投稿)を行います
このうち上の3つはフルでアクセス制限をかけてしまってもいいのですが、wp-cron.phpだけは、サーバ内部からのアクセスを許可しておかないと、バックアッププラグインのジョブが動かなかったりしてしまいます。
このため、まず {DocumentRoot}/.htaccess に以下のような記述を追加します。このファイルにはWordpressの動作に必要な記述があるため、かならずバックアップをとってから作業しましょう。なお、パスワードファイルは wp-adminディレクトリのものと使い回しです。
※赤字部分は2020年9月17日追記。サイトヘルスチェックをクリアするため、wp-login.phpは次項の wp-cron.php同様に、ローカルIPアドレスからの接続を許可します。
<Files wp-login.php>
AuthType Digest
AuthUserFile /var/www/.htaccess_pass_wordpress
AuthName “Secure Zone”
require valid-user
require ip xxx.xxx.xxx.xxx 127.0.0.1
</Files><Files wp-config.php>
AuthType Digest
AuthUserFile /var/www/.htaccess_pass_wordpress
AuthName “Secure Zone”
require valid-user
</Files><Files xmlrpc.php>
AuthType Digest
AuthUserFile /var/www/.htaccess_pass_wordpress
AuthName “Secure Zone”
require valid-user
</Files>
wp-cron.phpはサーバ内から自由にアクセスできるようにする
wp-cron.phpだけはただのDigest認証だけではなく、IPアドレスxxx.xxx.xxx.xxx(Wordpressが動いているサーバのグローバルアドレス)と localhost からのフリーアクセスも許可します。前項とおなじく、 {DocumentRoot}/.htaccess に以下を追加します。
<Files wp-cron.php>
AuthType Digest
AuthUserFile /var/www/.htaccess_pass_wordpress
AuthName “Secure Zone”
require valid-user
require ip xxx.xxx.xxx.xxx 127.0.0.1
</Files>
※IPアドレスの区切りはスペース1つです
サーバ外部から以下のようなコマンドを打つと、失敗が返ってくるはずです。
これで必要なファイルに必要なアクセス制限/Digest認証ができました。数時間放置してから IP Geo Blockプラグインのログ画面を再確認しても、攻撃履歴はもう増えていないはずです。これを確認したらIP Geo Blockプラグインは消してしまっても構わないでしょう。