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 を組み合わせます。
Nginx のベーシック認証の設定の流れ。htpasswd でパスワードファイルを作る、location に auth_basic を書く、admin-ajax.php を除外する、nginx -t と reload で反映して curl で確認する

ベーシック認証とは

ベーシック認証(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 の復元を先に行います。

関連記事

参考: 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 の併用・確認コマンドを追加)。この記事はワードプレス博士(ライトセンド株式会社)が運営しています。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲