多くのブログやホームページのプラットフォームに利用されているWordPressですが、人気ゆえに多くのウイルスやMalware、DDos攻撃の的となっています。
誰でも簡単にインストールできる反面、適切なセキュリティを施している方は少ないのではないかと思います。特にAmazon AWSやMicrosoft Azureなど、OSから自分で入れていくタイプのクラウドサービスを利用していると、自由にカスタマイズできる反面、ユーザーが意識してセキュリティ対策をしないと、裸で公衆の面前に立っているような状態になっている可能性もあります。
今回はすぐにできるセキュリティ対策のポイントを16個紹介します。
AWSやAzureのようにSSHでログインして動き回れるようなホスティングではなく、FTPとphpMyAdmin経由でのDB操作のみ許可されている場合は、適宜必要なものだけピックアップして実施してみてください。それぞれの施策に依存関係はないので、どこから始めても、何個実施してもOKです。
1.Cookieの暗号化
サイト訪問者 のコンピュータに保存されるcookieの中身を暗号化する
wp-config.phpの中身です。デフォルトだと下記のように記載されているので、これを書き換えます。
[crayon]
define('AUTH_KEY', 'put your unique phrase here');
define('SECURE_AUTH_KEY', 'put your unique phrase here');
define('LOGGED_IN_KEY', 'put your unique phrase here');
define('NONCE_KEY', 'put your unique phrase here');
define('AUTH_SALT', 'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT', 'put your unique phrase here');
define('NONCE_SALT', 'put your unique phrase here');
[/crayon]
下記のURLをブラウザで閲覧すると、ランダムなキーが生成されるので上記の箇所を上書きしてください。
https://api.wordpress.org/secret-key/1.1/salt/
平文でcookieに保存されていたパスワードが暗号化されるため、盗まれても利用不可
2.データベースのprefixを変更
データベースのprefixをデフォルトの"WP_"からカスタマイズしたものに変える
こちらのサイトがわかりやすくまとまっています。
http://viral-community.com/wordpress/wordpress-table-prefix-1305/
上記サイトがクローズしてしまった時のために私が行った手順を書いておきます。
やることは3つです。
1. wp-config.phpのprefixを wp_ から お好きなものに変更(例: wp_sitename_)
wp-config.php内で下記のラインを探し、'wp_'を変更します。
[crayon]
$table_prefix = 'wp_';
[/crayon]
次項以降の説明の都合上、仮に下記のように変更します。
[crayon]
$table_prefix = 'wp_sitename_';
[/crayon]
2.DBのテーブル名を更新
MySQLにログインし、テーブル名一覧を取得し、下記のようにクエリーを作成します。
ALTER TABLE (元のtable名) RENAME TO (変更後のtable名);
例:ALTER TABLE wp_commentmeta RENAME TO wp_sitename_commentmeta;
プラグインを入れている場合は、デフォルト以外のテーブルもできている可能性があるので、全てのテーブルで名前を変更します。
SSHでログインしてコマンドラインから実行してもよいですが、phpMyAdminやMySQL workbenchを使うとよりわかりやすいと思います。
TIPS
Webserverにnginxを利用している方は下記の手順で簡単にphpMyAdminが利用できます。
nginxのコンフィグファイルで下記の箇所を探します。
[crayon]
#include /etc/nginx/phpmyadmin;
location ~* /(phpmyadmin|myadmin|pma) {
access_log off;
log_not_found off;
return 404;
[/crayon]
これを下記のように変更します。
[crayon]
include /etc/nginx/phpmyadmin;
#location ~* /(phpmyadmin|myadmin|pma) {
# access_log off;
# log_not_found off;
# return 404;
[/crayon]
3.optionsとusermetaテーブル内でテーブル名を指定している箇所を1の内容で更新
下記のクエリーを発行します。
SELECT * FROM `wp_sitename_options` WHERE `option_name` LIKE '%wp_%'
option_nameに'wp_'が指定されている箇所があるレコードがヒットするので、ひとつづつ'wp_sitename_'に変更していきます。
同様にusermetaテーブルも下記クエリーを発行します。
SELECT * FROM `wp_sitename_usermeta` WHERE `meta_key` LIKE '%wp_%'
meta_keyに'wp_'が指定されている箇所があるレコードがヒットするので、ひとつづつ'wp_sitename_'に変更していきます。
不正アクセスがあってもDB内のデータを改ざんされにくい。テーブル名を推測されにくい。
3.WP,プラグインのアップデート
WordPress本体、プラグインを最新のものにアップデートする。2年以上更新されていないプラグインは代替プラグインを探す。
WordPress管理画面から更新をします。WP本体、プラグインの更新によりサイトが動作しなくなることもあるので、事前にバックアップを取ったほうがよいです。プラグインの更新もひとつづつ行ったほうが、問題発生時の切り分けが簡単になるのでお勧めです。
古いWordPressやプラグインのセキュリティホールをついた不正行為を防ぐ
4.管理ページからプログラムを編集不可
WordPressの管理ページからプログラムをEditできる機能を停止します。
wp-config.phpの最後尾に下記の一行をいれます。
[crayon]
define( 'DISALLOW_FILE_EDIT', true );
[/crayon]
管理ページへ不正アクセスされてもソースコードの改ざんができない
5.テーマとプラグインを導入・変更不可
WordPressの管理ページからプラグインをインストールする機能を停止します。
wp-config.phpの最後尾に下記の一行をいれます。
[crayon]
define( 'DISALLOW_FILE_MODS', true );
[/crayon]
管理ページに不正アクセスされてもテーマとプラグインのアップデートができない
6.ファイル単位でパーミッションを設定する
※sudo権限があるユーザーで実行してください。
1.ドキュメントルート以下のパーミッションを755か750にします。
例:chmod 755 -R /var/www/html
2.ファイルのパーミッションを644にする
例:find /var/www/html/ -type f -exec chmod 644 {} \;
3.wp-config.phpのパーミッションを600にする
例:chmod 600 wp-config.php
サーバに不正ログインされてもファイルを編集ができない
7.エラーメッセージに物理パスを表示しない
テーマとプラグインが原因でエラーが起きても、エラーメッセージに物理パスを表示しない
wp-config.phpに下記の最後尾に下記をいれる
[crayon]
error_reporting(0);
@ini_set(‘display_errors’, 0);
[/crayon]
ディレクトリ構成を開示しないため、ディレクトリやファイル改ざんのあたりをつけられない
8.設定ファイルはブラウザ経由でアクセス不可
wp-config.phpにブラウザ経由でアクセスさせない
Apacheの場合
ドキュメントルートの.htaccessに下記を追加します。
[crayon]
order allow,deny
deny from all
[/crayon]
nginxの場合
コンフィグファイルに下記を追加します。
[crayon]
location = /wp-config.php {
deny all;
access_log off;
log_not_found off;
}
[/crayon]
ブラウザ経由で設定ファイルの閲覧ができない
9.コアファイルはブラウザ経由でアクセス不可
ブラウザで直接参照されることがない(内部includeでしか使われない)WordPressのコアファイルはブラウザ経由でアクセス不可にする
Apacheの場合
ドキュメントルートの.htaccessに下記を追加します。
[crayon]
# Block the include-only files
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
[/crayon]
nginxの場合
コンフィグファイルに下記を追加します。
[crayon]
location = /wp-includes/ {
deny all;
}
[/crayon]
正常にサイトが閲覧できればこのままでよいですが、もし見れない箇所などが出た場合は、上記を入れた後に、下記のようにディレクトリ単位でallow設定をいれてください。にしてみてください。
[crayon]
location = /wp-includes/css {
allow all;
}
[/crayon]
ブラウザ経由でアクセスする必要のないファイルは直接アクセスできない
10. .htaccessへブラウザからアクセス不可
ブラウザ経由のアクセスをコントロールする.htaccessファイル自体へブラウザからアクセス不可にする
Apacheの場合
ドキュメントルートの.htaccessに下記を追加します。
[crayon]
order allow,deny
deny from all
[/crayon]
nginxの場合
コンフィグファイルに下記を追加します。
[crayon]
location = /.htaccess {
deny all;
access_log off;
log_not_found off;
}
[/crayon]
ブラウザ経由で.htaccessに直接アクセスできない
11.XML-RPCは使用不可にする
Apacheの場合
ドキュメントルートの.htaccessに下記を追加します。
[crayon]
order allow,deny
deny from all
[/crayon]
nginxの場合
コンフィグファイルに下記を追加します。
[crayon]
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
[/crayon]
下記二つのプラグインをインストールします。
リモートログインによるDDoSアタックができない
12.管理ページへのログインの試行回数を制限する
管理ページへのログイン試行回数を制限する
下記のプラグインをインストールする
管理ページへの総当り不正ログインができない
13.WordPressのバージョンナンバーを表示しない
生成されたHTMLにWordPressのバージョンナンバーを表示しない
利用中のthemeの下にあるfunction.phpの最後尾に下記を入れる。
[crayon]
remove_action('wp_head', 'wp_generator');
[/crayon]
特定のバージョンをターゲットにした攻撃ができない
14.管理ページへのログイン履歴をとる
管理ページのログイン毎にログをとり、不正利用があった際に調査のよりどころとする
下記のプラグインをインストールする。
不正アクセスがあった場合にトラックできる
15.監視ツールをいれる
ウイルス、マルウェア、ハッキングを毎日チェックするプラグインを導入する
下記のプラグインをインストールする
無償版・有償版があり、有償版にするとより強固なセキュリティチェックと、スケジュールによる自動実行が可能。
1サイト年間40ドル弱。複数サイト契約によるボリュームディスカウントあり。
不正ファイルやアクセスがあった場合にすぐに検知できる
16.自動でsnapshotをとる
※この対応はAmazon AWSを利用している場合のみです。他のホスティングを利用している場合は、適切な方法で定期的にバックアップを取っておきましょう。
インスタンスにsnapshotをとるスクリプトを仕込み、cronで定期的に実行する
こちらのサイトがわかりやすくまとまっています。
https://blog.supersonico.info/?p=1312
マニュアル復旧不可能な改ざんが行われた場合、バックアップからリストアできる
特に更新をしていないのに、突然Snapshotが取れなくなることがあります。
スクリプトを直接たたくと、下記のようなエラーがでます。
A client error (AuthFailure) occurred when calling the DescribeInstances operation: AWS was not able to validate the provided access credentials
ログインができないといっています。AIMでユーザーを作るとcredential(Access key, Secret Access Key)と呼ばれる認証キーをもらえるのですが、特に変えてないし、うーん。。 となった人、おそらくサーバ時間が実時間と大きくかけ離れていることが理由です。
まずntpdがインストールされているか確認しましょう。なければ下記のコマンドでインストール。(centOSを利用)
[crayon]
yum install ntp ntpdate ntp-doc
[/crayon]
スタートさせます。
[crayon]
service ntpd start
[/crayon]
再起動時も上がってくるようにします。
[crayon]
chkconfig ntpd on
[/crayon]
これでもう一度スクリプトをたたくとエラーは消えます。
番外編:定期的なWPとプラグインの更新
WordPressでセキュリティホールになりやすいのはWPのコアファイル、テーマそれからプラグインです。これらをこまめにチェックし、極力最新の状態をキープするようにしましょう
番外編2:UploadsフォルダのPermission
マルウェアやバックドアに狙われやすいディレクトリの一つにUploadsディレクトリがあります。
パスでいうとwp-content/uploadsです。
ここに不正なphpファイルが置かれるケースが良くあります。
イメージファイルをアップロードするという用途の都合上、書き込み権限をつける必要があり、ファイルが置かれること自体を止めることができません。そこで、仮にphpファイルを置かれたとしても実行できないようにしよう というのがこの施策です。
やることは.htaccessでPHPを実行不可にする というだけです。
wp-content/uploads以下に.htaccessを作成し、下記のとおり記載します。
[crayon]
# Kill PHP Execution
deny from all
[/crayon]
当ページはWORDPRESS SECURITY: THE ULTIMATE GUIDEを参考に自身で調査実施した内容を掲載しています