2026年5月20日
2026年5月20日
WordPress管理画面をBASIC認証で保護する方法(Apache・Nginx)
BASIC認証は、Webサーバー(Apache・Nginx)がページを返す前にユーザー名とパスワードを求める仕組みです。wp-login.php と /wp-admin/ にかけておくと、WordPressのログインフォームに届く前の段階で、認証情報を持たないアクセスを 401 で止められます。PHPが動く前に止まるので、ログイン画面への総当たり攻撃でサーバーの負荷が上がるのも抑えられます。
この記事では、Debian / Ubuntu の Apache 2.4 と Nginx を例に、設定と確認の手順を説明します(2026年11月時点。設定例は Apache 2.4.69 と Nginx の安定版で動作を確認しています)。
BASIC認証で守れるもの・守れないもの
設定の前に、効果の範囲を確認しておきます。
| 項目 | BASIC認証での扱い |
|---|---|
wp-login.php へのログイン試行 |
認証情報が無ければ 401 で止まる |
/wp-admin/ 以下の管理画面 |
同上 |
xmlrpc.php(XML-RPC) |
対象外。別途無効化や制限が必要 |
REST API(/wp-json/) |
対象外 |
| 通信の暗号化 | しない。認証情報はBase64で送られるだけなので HTTPS が前提 |
xmlrpc.php もユーザー名とパスワードを受け付ける入口なので、使っていなければ XML-RPCを無効化する手順 もあわせて行ってください。
また、会員登録したユーザーやショップの顧客が wp-login.php からログインするサイトでは、その人たちにもBASIC認証の情報を配る必要が出るため向きません。その場合は ログイン試行回数の制限 や IPアドレスによるログイン画面の制限 を検討してください。
手順1:パスワードファイル(htpasswd)を作る
パスワードファイルは htpasswd コマンドで作ります。ドキュメントルート(/var/www/html など)の外に置き、Webから読めないようにします。
# htpasswd コマンドを入れる
sudo apt install apache2-utils # Debian / Ubuntu
# sudo dnf install httpd-tools # RHEL / AlmaLinux / Rocky Linux
# 推測されにくいパスワードを作る(表示された文字列を控える)
openssl rand -base64 24
# 新しくファイルを作って1人目を登録(-c はファイルを作り直すので2回目以降は付けない)
sudo htpasswd -c -B /etc/apache2/.htpasswd-wp wp_guard
# 2人目を追加
sudo htpasswd -B /etc/apache2/.htpasswd-wp second_user
# 登録を削除
sudo htpasswd -D /etc/apache2/.htpasswd-wp second_user
# root が所有し、Webサーバーのグループだけ読めるようにする
sudo chown root:www-data /etc/apache2/.htpasswd-wp
sudo chmod 640 /etc/apache2/.htpasswd-wp
-Bはパスワードを bcrypt で保存するオプションです。付けない場合は Apache 版の MD5(apr1)で保存されます。www-dataは Debian / Ubuntu で Apache と Nginx が動くユーザーです。RHEL系では Apache はapache、Nginx はnginxです。- Nginx で使うファイルは、Nginx の公式ドキュメントが対応形式として明記している apr1 で作れば読み込めます(
-Bを付けずにsudo htpasswd -c /etc/nginx/.htpasswd-wp wp_guard)。bcrypt が使えるかは OS の crypt() 関数の対応しだいです。
手順2:Apacheの設定(.htaccess)
.htaccess で認証を設定するには、そのディレクトリで AllowOverride AuthConfig(または All)が許可されている必要があります。WordPressのパーマリンクが動いていれば、多くの場合 All になっています。
wp-login.php にかける
WordPressのルート(wp-config.php がある場所)の .htaccess に、# BEGIN WordPress より上に追記します。# BEGIN WordPress から # END WordPress の間はWordPressが書き換えるので、そこには書きません。
# BASIC 認証: wp-login.php
<Files "wp-login.php">
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd-wp
Require valid-user
</Files>
/wp-admin/ にかける(admin-ajax.php は外す)
wp-admin ディレクトリの中に新しく .htaccess を作ります。
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd-wp
Require valid-user
# admin-ajax.php はサイトの表側からも呼ばれるので認証の対象から外す
<Files "admin-ajax.php">
Require all granted
</Files>
admin-ajax.php は、ログインしていない訪問者のブラウザーからもプラグインやテーマが呼び出すファイルです。ここに認証をかけると、表側の検索・絞り込み・カート操作などが動かなくなることがあります。Apache 2.4 では、<Files> の中の Require がディレクトリ全体の Require valid-user より後に評価されて置き換わるため、このファイルだけ認証なしで通ります。
古い記事にある Satisfy Any と Allow from all は Apache 2.2 の書き方です。また <Directory> は .htaccess の中には書けません。サーバーの設定ファイル(バーチャルホスト)を編集できる場合は、上と同じ内容を <Directory "/var/www/html/wp-admin"> の中に書いても同じ効果になります。その場合は設定を確かめてから再読み込みします。
sudo apachectl configtest
sudo systemctl reload apache2
.htaccess の変更だけなら再読み込みは要りません。レンタルサーバーで使う場合、AuthUserFile にはサーバー上のフルパス(/ から始まるパス)を書きます。管理パネルにBASIC認証の設定機能があれば、そちらを使うほうが簡単です。
手順3:Nginxの設定
Nginx は .htaccess を読まないので、サイトの server { } ブロックに書きます。PHPの渡し先(fastcgi_pass)は環境に合わせてください(例: Ubuntu 24.04 の php8.3-fpm なら unix:/run/php/php8.3-fpm.sock)。
# server { } の中、既存の location ~ \.php$ と並べて書く
# BASIC 認証: wp-login.php
location = /wp-login.php {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd-wp;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
# BASIC 認証: /wp-admin/ 以下
location ^~ /wp-admin/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd-wp;
# admin-ajax.php は認証なしで通す
location = /wp-admin/admin-ajax.php {
auth_basic off;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
# /wp-admin/ 内の PHP を実行する(これが無いと PHP がそのまま返される)
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}
location ^~ /wp-admin/ は、一致すると正規表現の location(サーバー全体の location ~ \.php$)を調べなくなります。そのため、/wp-admin/ の中にもPHP用の location を入れ子で書く必要があります。これを忘れると、管理画面のPHPファイルが実行されずにソースのまま返されるおそれがあります。
sudo nginx -t && sudo systemctl reload nginx
Nginx の設定全体の作り方は NginxでWordPressを動かす設定 も参考にしてください。
手順4:動作を確かめる
コマンドラインから応答のステータスを確認します。-u にユーザー名だけを渡すと、パスワードは対話で聞かれるので履歴に残りません。
# 認証なし → 401 になればよい
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-login.php
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-admin/
# 認証あり → 200 になればよい
curl -s -o /dev/null -w "%{http_code}\n" -u wp_guard https://example.com/wp-login.php
# admin-ajax.php は 401 にならなければよい(action を付けない呼び出しは 400 が返る)
curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-admin/admin-ajax.php
最後にブラウザーで管理画面にログインし、表側のフォームや検索など admin-ajax.php を使う機能が動くことも確かめます。
運用上の注意
- AuthName(auth_basic の文字列)はそろえる: ブラウザーは同じサイトの同じ領域名(realm)なら一度入力した認証情報を使い回すので、
wp-login.phpと/wp-admin/で同じ名前にしておくと入力が1回で済みます。 - admin-post.php: プラグインによっては、ログインしていない訪問者のフォーム送信先に
/wp-admin/admin-post.phpを使います(admin_post_nopriv_フック)。表側のフォームが送信できなくなった場合は、admin-ajax.phpと同じように除外します。 - パスワードリセットと新規ユーザー: 再設定メールのリンク(
wp-login.php?action=rp)もBASIC認証の対象になります。管理者以外がログインする場合は認証情報を伝えるか、管理者が WP-CLI のwp user updateでパスワードを変更します。 - ファイルの置き場所:
.htpasswd-wpをドキュメントルートの中に置くと、設定しだいでWebから取得されるおそれがあります。外に置いてください。 - ログイン画面の保護は他の対策と組み合わせる: BASIC認証のパスワードが漏れれば効果はなくなります。WordPress側の強いパスワードや二段階認証、総当たり攻撃への対策 も続けてください。