WordPressのセキュリティ対策として管理画面にアクセス制限を設定

wordpress-access-control-top

WordPressを利用していて管理画面に制限を掛けたいと思ったことはありませんか。
”wp-admin”から始まるWordPress用管理画面は、制限を掛けずに公開することで不特定多数からの攻撃を受ける可能性が高くなります。ウェブサーバーのログを見ると分かりますが、wp-adminへの不正アクセスを試みているログは大量に記録されています。
またサイトがWordPressを運用していることが容易に分かってしまいます。それを避けるためにも、WordPressの管理画面はなるべくアクセスを制限することをオススメします。

WordPressの管理画面にアクセス制限を設定する方法は

  1. .htaccessファイルを利用した、基本認証(管理画面にアクセスするためにIDとパスワードを入力する)
  2. 多要素認証を利用するプラグインを利用して、ログインにワンタイムパスワードを設定する
  3. ウェブサーバー側の機能で、特定のIPアドレスからのみ接続を許可するように設定する

などありますが、今回の記事では”3. ウェブサーバー側の機能で、特定のIPアドレスからのみ接続を許可するように設定する方法”を紹介します。代表的なオープンソースのウェブサーバーであるapache(以下、httpdと記載します。)とnginxの両方で設定を行います。

1. IPによる制限を設定する環境

今回の記事でIPアドレスによるWordPress管理画面へのアクセス制限を設定する環境は、httpdを利用してウェブサーバーの構築手順を紹介した以前の記事(上から構築順に並んでいます。)

>「CentOS 7 への Apacheインストール。最短でウェブサーバーを構築して.....」

>「常時SSL化待ったなし!CentOS 7 と Apacheに Let’s Encryptで信頼性の高い...」

>「CentOS 7のウェブサーバーにphp 7.2を導入する。phpの入門にも最適な環境の構築」

>「CentOSのサーバーへWordPressをインストール。WordPressを理解するには.....」

>「WordPressの高速化に。ApacheのeventMPMとphp-fpmを利用して.....」

>「WordPressサーバーの高速化(効果大)OPcacheとAPCuでWordPressの速度を5....」

で作成した環境と、nginxによるウェブサーバーの構築手順を紹介した記事(こちらも、上から構築順に並んでいます。)

>「CentOS 7へのnginxのインストール。最短でバーチャルホストまでを利用する」

>「CentOS 7のnginxでPHP7を利用する。最短でPHP7系の環境を構築する手順」

>「CentOS 7のnginxでSSLを設定。Let’s Encryptで安全なウェブサイトを構築する」

>「nginx環境へWordPressをインストールする時の注意点。パーマリンクの設定に気を付ける」

>「centosにインストールしたnginxでPHPの処理速度をアップ、OPcacheと...」

>「centosのnginxでHTTP/2通信を設定する。HTTP通信の効率化でサイト表示速度を向上」

で作成したnginxの環境になります。
各々の環境は記事の中で紹介していますが、確認の意味で再度纏めておきます。基本的な環境は以下の通りです。

サーバーとネットワークの環境(共通)

  • OSのバージョンはCentOSで最新のバージョン7.5を利用しています。(2016年7月現在)
  • サーバーはインターネットへ接続されており、グローバルIPアドレスが一つ、割り当てられています。
  • ファイアウォールとしてfirewalldを設定しています。

httpd(apache)の環境

  • httpdはhttpd-2.4.6を利用しています。
  • phpとphp-fpmの7.2系がインストールされて、テスト用のWordPressサイトが表示されています。
  • ドメイン名はwww.testdom.comを設定しています。
  • phpアクセラレータとしてOPcacheとAPCuがインストールされています。
  • Let's Encrypytを利用してHTTPS通信の機能を有効化しています。

nginxの環境

  • nginxはnginx1.15.0を利用しています。
  • nginxは基本的な設定が完了して、バーチャルホストが二つ設定されています。
  • バーチャルホストは”www.testdom.com”になります。
  • phpとphp-fpmの7.2系がインストールされて、テスト用のWordPressサイトが表示されています。
  • phpアクセラレータとしてOPcacheとAPCuがインストールされています。
  • Let's Encrypytを利用してHTTPS通信の機能を有効化しています。

この環境を前提にWordPress管理画面へのIPアドレス制限を設定していきます。
許可するIPアドレス(WordPressの管理画面へアクセスできるIPアドレス)は111.8.21.167/32として設定を行います。

2. httpdを利用している場合の設定手順

本章ではウェブサーバーとしてhttpdを利用している環境での設定手順を紹介します。主な作業としては設定ファイルの変更と、httpdサービスの再起動になります。

2-1. httpd.confの変更

httpdの設定は/etc/httpd/conf以下にあるhttpd.confで行います。
httpd.confの編集前に、既存のファイルをバックアップしておきます。具体的には以下の手順でコピーを行います。(以前の記事で作成したbkupファイルとバッティングしないようにbkup2としてバックアップします。日付などを拡張子としても良いかと思います。(例:httpd.conf.181129など))

# cd /etc/httpd/conf
# cp -p httpd.conf httpd.conf.bkup2

httpd.confファイルのバックアップ後、エディタで設定ファイルを開いて変更を行います。本環境ではOSの標準的なエディタである、viエディタを利用しています。

# vi httpd.conf

変更点はhttpd.confにDirectoryディレクティブを追記します。
httpd.confの120行目付近にDirectoryディレクティブがありますので、その下に設定を追加します。
WordPressの管理機能が含まれている”wp-admin”ディレクトリのパスが”/home/www/html/wp-admin”の場合になります。もしパスが異なる場合は、運用している環境に合わせて読み替えて下さい。
120行目辺りにあるDirectoryディレクティブが以下にになります。

#
# Relax access to content within /var/www.
#
<Directory "/home/www/html">
AllowOverride None
# Allow open access:
Require all granted

この部分に以下の設定を追加します。記載するIPアドレスについては許可するIPアドレスに読み替えて下さい。
ディレクトリに対して、アクセス制限を掛ける設定になります。
wp-adminは基本的には全てアクセス制限を掛けますが、ファイル”admin-ajax.php”ファイルについてはWordPressが利用するファイルになりますので、アクセス制限から除外します。
アクセス制限からの除外は”Files”ディレクティブで設定しています。

<Directory "/home/www/html/wp-admin">
# Allow acces to wp-admin/admin-ajax.php

Order allow,deny
Allow from all
Satisfy any

order deny,allow
deny from all
allow from 111.8.21.167 <=実際のIPアドレスに変更する。

追記後の設定箇所は以下のようになります。

#
# Relax access to content within /var/www.
#
<Directory "/home/www/html">
AllowOverride None
# Allow open access:
Require all granted

<Directory "/home/www/html/wp-admin">
# Allow acces to wp-admin/admin-ajax.php

Order allow,deny
Allow from all
Satisfy any

order deny,allow
deny from all
allow from 111.8.21.167

設定ファイルを確認して、間違いが無ければ、ファイルを保存します。これで設定ファイルの編集は完了です。

2-2. httpdの設定ファイル確認

設定変更を行ったファイルに間違いがないかを確認します。設定ファイルの確認はhttpdに”-t”オプションを付けて実行します。

# httpd -t
Syntax OK

上記のように”Syntax OK”と表示されれば。設定ファイルには問題ありません。これで設定ファイルの確認は完了です。

2-3. 設定ファイルの反映(httpdの再起動)

httpd.confファイルの変更が完了しましたので、変更した設定を反映するためにhttpdを再起動します。systemctlコマンドを以下のように実行します。

# systemctl restart httpd

エラーメッセージが表示されなければ、再起動は完了しています。
再起動後にhttpdのステータスを確認します。

$ systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since 火 2018-04-03 10:55:49 JST; 10s ago
Docs: man:httpd(8)
man:Apachectl(8)
Process: 1656 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)
Main PID: 1660 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
tq1660 /usr/sbin/httpd -DFOREGROUND
tq1662 /usr/sbin/httpd -DFOREGROUND
tq1663 /usr/sbin/httpd -DFOREGROUND
tq1664 /usr/sbin/httpd -DFOREGROUND
tq1665 /usr/sbin/httpd -DFOREGROUND
mq1666 /usr/sbin/httpd -DFOREGROUND

4月 03 10:55:49 www systemd[1]: Starting The Apache HTTP Server...
4月 03 10:55:49 www systemd[1]: Started The Apache HTTP Server

正常にhttpdが起動していることが上記から確認できます。これで設定したIP以外からはwp-adminへアクセスできません。

2-4. httpdアクセス制限の動作確認

ここまででhttpdのアクセス制限設定が完了しましたので、動作テストを行います。本記事ではブラウザのchromeを利用して確認を行います。
ブラウザからwww.testdom.comのWordPress管理画面へアクセスします。
WordPressの管理画面へアクセスするURLはドメイン名に”/wp-admin”を付与したものになります。www.testdom.comの場合は以下のようになります。

https://www.testdom.com/wp-admin

設定が正常に行われている場合、以下のようにwp-adminに対してアクセス権限が無いというメッセージが表示されます。

wp-admin-setting-2-4-1

また、許可されたIPアドレスからアクセスすると、WordPressの管理画面が表示されます。

wp-admin-setting-2-4-2

これで正常に設定が行われていることが確認できました。

3. nginxを利用している場合の設定手順

本章ではウェブサーバーとしてnginxを利用している環境での設定手順を紹介します。作業としては設定ファイルの変更と、nginxサービスの再起動になります。
nginxの環境ではバーチャルホストして二つのドメインが設定されていますが、本記事では”www.testdom.com”のみ設定を行います。必要に応じて、他のバーチャルホストでも設定を行って下さい。

3-1. www.testdom.com.conf設定ファイルのバックアップ

IPアドレスによる制限の設定はバーチャルホスト用設定ファイルであるwww.testdom.com.confに行います。先ずはこのファイルをバックアップします。以下の手順でコピーを行います。
以前の記事で作成したconf.orgファイルと重複を回避するために、conf.org5としてファイルをバックアップしています。日付などを付けても良いかと思います。(例:www.testdom.com.conf.181129など)

# cp -p /etc/nginx/sites-available/www.testdom.com.conf /etc/nginx/sites-available/www.testdom.com.conf.org5

コピーされたバックアップファイルが存在することを確認します。

$ ls /etc/nginx/sites-available/
default.conf www.testdom.com.conf www.testdom.com.conf.org www.testdom.com.conf.org2 www.testdom.com.conf.org3 www.testdom.com.conf.org4 www.testdom.com.conf.org5

コピーしたファイル”www.testdom.com.conf.org5”があることが確認できました。

3-2. www.testdom.com.conf 設定ファイルの編集

ファイルのバックアップが完了しましたので”www.testdom.com.conf”を編集していきます。変更前の設定ファイルの内容は以下のようになります。

server {
listen 80;
server_name testdom.com www.testdom.com;
rewrite ^ https://$server_name$request_uri? permanent;
}

server {
listen 443 ssl;
server_name testdom.com www.testdom.com;
access_log /var/log/nginx/www.testdom.com-access.log main;
error_log /var/log/nginx/www.testdom.com-error.log;
root /home/www/www.testdom.com;

ssl_certificate /etc/letsencrypt/live/www.testdom.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.testdom.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location / {
index index.html index.htm index.php;
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
set $do_not_cache 0;

if ($request_method = POST) {
set $do_not_cache 1;
}
if ($query_string != "") {
set $do_not_cache 1;
}
if ($http_cookie ~* "comment_author|WordPress_[a-f0-9]+|wp-postpass|WordPress_no_cache|WordPress_logged_in") {
set $do_not_cache 1;
}
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
set $do_not_cache 1;
}
fastcgi_cache testdom;
fastcgi_cache_valid 200 60m;
fastcgi_no_cache $do_not_cache;
fastcgi_cache_bypass $do_not_cache;
add_header X-F-Cache $upstream_cache_status;
}
}

このファイルに以下の記載を追加します。
追加場所は

location ~ \.php$ {

の上辺りにしています。

httpdの場合と同じようにadmin-ajax.php以外のファイルにアクセス制限を設定します。
allowに記載したIPアドレスは環境に合わせたものに変更します。
fastCGIキャッシュを利用している場合、127.0.0.1からの許可を追加する必要があります。

location ~* /wp-login\.php|/wp-admin/((?!admin-ajax\.php).)*$ {
allow 111.8.21.167;
allow 127.0.0.1;
deny all;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

編集が終わった後の設定ファイルは以下のようになります。

server {
listen 80;
server_name testdom.com www.testdom.com;
rewrite ^ https://$server_name$request_uri? permanent;
}

server {
client_max_body_size 20M;
listen 443 ssl http2;
server_name testdom.com www.testdom.com;
access_log /var/log/nginx/www.testdom.com-access.log main;
error_log /var/log/nginx/www.testdom.com-error.log;
root /home/www/html;

ssl_certificate /etc/letsencrypt/live/www.testdom.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.testdom.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php?$args;
}

location ~* /wp-login\.php|/wp-admin/((?!admin-ajax\.php).)*$ {
allow 111.8.21.167;
allow 127.0.0.1;
deny all;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
set $do_not_cache 0;

if ($request_method = POST) {
set $do_not_cache 1;
}
if ($query_string != "") {
set $do_not_cache 1;
}
if ($http_cookie ~* "comment_author|WordPress_[a-f0-9]+|wp-postpass|WordPress_no_cache|WordPress_logged_in") {
set $do_not_cache 1;
}
if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
set $do_not_cache 1;
}
fastcgi_cache testdom;
fastcgi_cache_valid 200 60m;
fastcgi_no_cache $do_not_cache;
fastcgi_cache_bypass $do_not_cache;
add_header X-F-Cache $upstream_cache_status;
}
}

これで設定ファイルの変更は完了です。変更したファイルを保存します。

3-3. 設定ファイルの確認

設定ファイルの作成と配置が完了したら、間違いがないかを確認します。nginxコマンドに”-t”オプションを付けて実行することで設定ファイルをチェックできます。設定変更後には実行することをお勧めします。
以下のように実行します。

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

上記のように、”test is successful”と表示されていればファイルには問題ありません。

3-4. 設定の有効化(nginxの場合)

設定ファイルの変更を行った場合には、ファイル再読み込みとして、nginxの再起動が必要になります。systemctlコマンドでnginxを再起動します。

# systemctl restart nginx

エラーが出力されなければ、正常に再起動は完了しています。これでIPアドレスでのアクセス制限は設定完了です。

3-5. nginxでのIPアドレス制限、動作確認

「項目3. 設定の有効化(nginxの場合)」でwp-adminディレクトリに対するIPアドレスの制限設定が完了しています。
本章では実際にブラウザでサイトへ接続して、アクセス制限が設定されていることを確認していきます。
ブラウザからwww.testdom.comのwp-adminへアクセスします。
WordPressの管理画面へアクセスするURLはドメイン名に”/wp-admin”を付与したものになります。www.testdom.comの場合は以下のようになります。

https://www.testdom.com/wp-admin

設定が正常に行われている場合、以下のようにwp-adminに対してアクセス権限が無いというメッセージが表示されます。

wp-admin-setting-3-5

また、許可されたIPアドレスからアクセスすると、WordPressの管理画面が表示されます。

wp-admin-setting-2-4-2

これで正常に設定が行われていることが確認できました。

4. まとめ

WordPressは現在、世界中で一番利用されているCMS(コンテンツマネジメントシステム:ウェブサイトを管理するためのシステム)になります。
利用されている環境が多いと、必然的にクラッカーのターゲットになりやすくなります。弊社でもクラックされたWordPressを幾つも見てきました。その殆どは古いバージョンのWordPressを利用していることや、同じく古いプラグインを利用している環境でしたが、管理画面への攻撃もかなり多く見られます。
セキュリティは保険のようなもので、より多く担保しておいて損はありません。もし固定IPアドレスを利用している環境があれば、本設定は有効なセキュリティ対策になると思います。是非、設定してみて下さい。

  • この記事を書いた人
rem-profile-photo

レムシステム

レムシステムはPC・サーバー・ネットワークでの業務効率化を主な業務としている会社です。全国に対応しています。

-Apache, Nginx