2026年10月19日
2026年10月19日
Nginx でベーシック認証を設定する方法|htpasswd の作成・location 単位の保護・WordPress 管理画面への適用
Nginx でベーシック認証を設定するには、パスワードファイルを作り、守りたい location に auth_basic と auth_basic_user_file を書いて nginx -s reload するだけです。WordPress では wp-login.php と /wp-admin/ に掛けて、総当たりのログイン試行を Nginx の段階で止める使い方が多いです。
結論を先にまとめます。
- パスワードファイルは
htpasswd -B(bcrypt)かopenssl passwd -apr1で作ります。公開ディレクトリの外に置き、Nginx の実行ユーザーだけが読めるようにします。 auth_basic "文言"; auth_basic_user_file /etc/nginx/.htpasswd;をserverかlocationに書きます。- WordPress では
/wp-admin/admin-ajax.phpを認証から外さないと、サイト表示側の機能(テーマやプラグインの Ajax)が壊れます。 - ベーシック認証はパスワードを Base64 で送るだけなので、HTTPS でないサイトには掛けないでください。
- 社内の固定 IP からは認証なしで通したいときは
satisfy anyとallow/denyを組み合わせます。
ベーシック認証とは
ベーシック認証(HTTP Basic Authentication)は、ブラウザーがユーザー名とパスワードを Authorization: Basic ヘッダーで送り、サーバーが照合する仕組みです。Nginx では ngx_http_auth_basic_module が担当し、設定は 2 つのディレクティブだけです(公式ドキュメント)。
| ディレクティブ | 役割 | 書ける場所 | |
|---|---|---|---|
| `auth_basic 文字列 \ | off;` | 認証を有効にし、文字列を realm(ダイアログに出る名前)にする。off で上位の設定を打ち消す |
http、server、location、limit_except |
auth_basic_user_file ファイル; |
ユーザー名とパスワードのハッシュを書いたファイル | 同上 |
パスワードファイルの形式は 1 行に ユーザー名:ハッシュ で、ハッシュは crypt() 形式、Apache の apr1(MD5 系)、{SHA} / {SSHA} 形式に対応しています。公式ドキュメントは {SHA} を新しいパスワードには使わないよう明記しているので、htpasswd の bcrypt か apr1 を使います。
手順 1: パスワードファイルを作る
htpasswd は Debian / Ubuntu では apache2-utils、RHEL 系では httpd-tools に入っています。Apache 本体は要りません。
# Debian / Ubuntu
sudo apt install apache2-utils
# RHEL 系(AlmaLinux / Rocky Linux)
sudo dnf install httpd-tools
# 新規作成(-c は最初の 1 回だけ。2 回目以降に付けると上書きされます)
sudo htpasswd -B -c /etc/nginx/.htpasswd admin
# ユーザーを追加
sudo htpasswd -B /etc/nginx/.htpasswd editor
-B は bcrypt でハッシュします。htpasswd を入れたくない場合は openssl でも作れます。
printf "admin:%s\n" "$(openssl passwd -apr1)" | sudo tee -a /etc/nginx/.htpasswd
ファイルの権限は Nginx の実行ユーザー(Debian / Ubuntu は www-data、RHEL 系は nginx)が読めれば足ります。
sudo chown root:www-data /etc/nginx/.htpasswd
sudo chmod 640 /etc/nginx/.htpasswd
ドキュメントルートの下(/var/www/html など)には置かないでください。ブラウザーから取得できる場所に置くと、ハッシュが流出します。
手順 2: location に auth_basic を書く
ディレクトリ全体に掛ける
location /private/ {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
}
サイト全体に掛け、一部だけ外す
公開前のステージングサイトなど、サイト全体を隠したいときは server に書き、Let's Encrypt の認証用パスだけ off で外します。
server {
listen 443 ssl;
server_name staging.example.com;
auth_basic "Staging";
auth_basic_user_file /etc/nginx/.htpasswd;
location ^~ /.well-known/acme-challenge/ {
auth_basic off;
root /var/www/letsencrypt;
}
# 以下、通常の location
}
手順 3: WordPress の管理画面に掛ける
WordPress では、ログイン画面 wp-login.php と管理画面 /wp-admin/ にだけ認証を掛け、サイトの表示には影響させない書き方にします。注意点は /wp-admin/admin-ajax.php です。このファイルはログインしていない閲覧者からも呼ばれる(テーマやプラグインの Ajax、問い合わせフォームなど)ため、認証から外します。
# ログイン画面
location = /wp-login.php {
auth_basic "Login";
auth_basic_user_file /etc/nginx/.htpasswd;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# 管理画面(admin-ajax.php は除外)
location ^~ /wp-admin/admin-ajax.php {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ^~ /wp-admin/ {
auth_basic "Admin";
auth_basic_user_file /etc/nginx/.htpasswd;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
fastcgi_pass の値は環境の PHP-FPM のソケットに合わせます(2026年11月現在の例として PHP 8.3 のパスを書いています)。認証を掛けた location の中で PHP を処理する設定を書かないと、.php が別の location に拾われて認証が掛からないことがあるので、上の例では location の中に PHP の処理を含めています。
既存の location ~ \.php$ がある構成では、location = /wp-login.php のように = で完全一致にすると優先して評価されます。
手順 4: IP 許可と併用する
社内の固定 IP からは認証なしで入り、それ以外はベーシック認証にする構成です。satisfy any は「allow か認証のどちらかを満たせば通す」という意味です。
location = /wp-login.php {
satisfy any;
allow 203.0.113.10;
deny all;
auth_basic "Login";
auth_basic_user_file /etc/nginx/.htpasswd;
# fastcgi の設定は上と同じ
}
Cloudflare などの CDN を通している場合、allow に書くべき IP は閲覧者ではなく CDN の IP になってしまいます。先に set_real_ip_from と real_ip_header で実 IP を復元してください。
手順 5: 反映して確認する
sudo nginx -t
sudo nginx -s reload
# 認証なし → 401 が返る
curl -sI https://example.com/wp-login.php | head -n 1
# 認証あり → 200(または WordPress の 302)
curl -sI -u admin https://example.com/wp-login.php | head -n 1
# admin-ajax.php は認証なしで 200 か 400(WordPress が返す)
curl -sI https://example.com/wp-admin/admin-ajax.php | head -n 1
-u admin でパスワードを対話入力できます。コマンド履歴にパスワードを残さないため、-u admin:パスワード の形は避けます。
WordPress の観点
WordPress のログイン画面への総当たりは、サイトの規模にかかわらず届きます。ベーシック認証を手前に置くと、PHP と MySQL を動かさずに Nginx が 401 を返すので、サーバーの負荷も下がります。一方で、次の点に注意が要ります。
- スマートフォンのアプリや外部サービス(Jetpack、投稿用のクライアント、XML-RPC)から管理機能を使っている場合は、ベーシック認証を通れず動かなくなります。REST API 経由の連携は影響を受けないことが多いですが、
/wp-admin/配下を呼ぶものは止まります。 - 複数人で運用するサイトでは、ベーシック認証のパスワードを共有することになります。個人ごとの認証にはならないので、WordPress 側の 2 要素認証と併用します。
- Apache のサイトでは
.htaccessとhtpasswdで同じことができます(「htpasswd で Apache の Basic 認証パスワードを作成する方法」)。
ログイン画面の保護はほかにも方法があり、国別の制限(「Nginx の GeoIP2 で国別にアクセスを制限する方法」)や、セキュリティプラグインでの試行回数制限(「Wordfence の初期設定」)と組み合わせると、1 つの手段に頼らずに済みます。
よくある質問
Nginx のベーシック認証が効きません(ダイアログが出ない)
.php のリクエストが別の location ~ \.php$ に先に一致していることが多いです。location = /wp-login.php の完全一致にするか、認証を掛けた location の中に PHP の処理を書きます。nginx -T で有効な設定全体を出し、どの location に一致しているかを確認してください。
500 エラーになり、error.log に「user not found」や「open() failed」が出ます
パスワードファイルのパスが違う、または Nginx の実行ユーザーに読み取り権限が無い状態です。ls -l /etc/nginx/.htpasswd で所有者と権限を確認します。SELinux が有効な環境では、ファイルのコンテキストが原因のこともあります。
htpasswd が無い環境ではどうしますか
openssl passwd -apr1 でハッシュを作り、ユーザー名:ハッシュ の形でファイルに追記します。openssl passwd -6(SHA-512 の crypt)も Nginx で使えます。
HTTP のサイトでも使えますか
動きますが、パスワードが Base64 でそのまま流れるため、途中で読まれます。先に HTTPS 化してから掛けてください。HTTP で届いたリクエストは HTTPS へ転送する設定にします。
まとめ
- Nginx のベーシック認証は
htpasswd -Bでファイルを作り、auth_basicとauth_basic_user_fileをlocationに書くだけで有効になります。 - WordPress では
wp-login.phpと/wp-admin/に掛け、admin-ajax.phpは除外します。PHP の処理は認証を掛けたlocationの中に書きます。 - HTTPS が前提です。固定 IP の許可は
satisfy anyで併用し、CDN 経由なら実 IP の復元を先に行います。
関連記事
- htpasswd で Apache の Basic 認証パスワードを作成する方法|wp-admin の保護
- Nginx の GeoIP2 で国別にアクセスを制限する方法
- Wordfence の初期設定
- WordPress の REST API へのアクセスを制限する方法
参考: nginx – Module ngx_http_auth_basic_module、nginx – Module ngx_http_access_module(allow / deny)、nginx – satisfy(ngx_http_core_module)、Apache – htpasswd
更新履歴: 2026-11-09 全面改訂(定型文を Nginx 公式ドキュメントに沿った設定手順に置き換え、WordPress の管理画面への適用例・admin-ajax.php の除外・satisfy any の併用・確認コマンドを追加)。この記事はワードプレス博士(ライトセンド株式会社)が運営しています。