2026年7月6日
2026年7月6日
htpasswd コマンドの使い方|.htpasswd の生成・追加・削除・確認と Apache Basic 認証(wp-admin の保護)
htpasswd は、Apache の Basic 認証で使うパスワードファイル(ユーザー名とパスワードのハッシュを1行ずつ並べたファイル)を作成・更新するコマンドです。この記事では、htpasswd でユーザーを追加・削除・確認する方法と、Apache 2.4 で Basic 認証をかける設定を説明します。
パスやパッケージ名は2026年10月時点の Ubuntu 24.04 / Debian 12(Apache 2.4 系)を例にし、RHEL 系(AlmaLinux・Rocky Linux)の違いは都度書いています。
htpasswdをインストールする
htpasswd は Apache 本体とは別のパッケージに入っています。
| OS | パッケージ | インストール |
|---|---|---|
| Ubuntu / Debian | apache2-utils |
sudo apt install apache2-utils |
| AlmaLinux / Rocky Linux / RHEL | httpd-tools |
sudo dnf install httpd-tools |
インストールされたかは which htpasswd で確かめます。htpasswd -v はバージョン表示ではなく「パスワードが合っているかの確認」なので、インストール確認には使えません。Apache 自体のバージョンは次で確認します。
# Ubuntu / Debian
apache2 -v
# RHEL 系
httpd -v
パスワードファイルを作る・ユーザーを追加する
パスワードファイルは、Web から見えない場所(DocumentRoot の外)に置きます。ここでは /etc/apache2/.htpasswd を使います(RHEL 系なら /etc/httpd/.htpasswd など)。
# 新規作成して最初のユーザーを登録(-c はファイルを作り直す)
sudo htpasswd -c -B /etc/apache2/.htpasswd alice
# 2人目以降は -c を付けない
sudo htpasswd -B /etc/apache2/.htpasswd bob
-c は既存のファイルがあっても作り直すため、2人目以降に付けると先に登録したユーザーが消えます。
主なオプションは次のとおりです(Apache 2.4 の公式マニュアルより)。
| オプション | 意味 |
|---|---|
-c |
ファイルを新規作成する(既存のファイルは上書きされる) |
-B |
bcrypt でハッシュ化する。何も指定しないときの既定は Apache 独自の MD5($apr1$) |
-C 数値 |
bcrypt のコスト(4〜17、既定5)。-B と一緒に使う |
-b |
パスワードをコマンドラインで渡す。シェルの履歴やプロセス一覧に残る |
-i |
パスワードを標準入力から読む(スクリプト向け) |
-n |
ファイルを更新せず、結果を画面に出す |
-D |
指定したユーザーを削除する |
-v |
入力したパスワードが登録済みのものと一致するか確認する(2.4.5 以降) |
新しく作るなら -B(bcrypt)を使うのがよいでしょう。スクリプトで登録する場合は、履歴に残る -b より -i を使います。
# 変数 PASS に入れたパスワードを標準入力で渡す
printf '%s\n' "$PASS" | sudo htpasswd -i -B /etc/apache2/.htpasswd carol
パスワードの変更・削除・確認
# パスワードの変更(既存ユーザーに対して追加と同じコマンドを実行)
sudo htpasswd -B /etc/apache2/.htpasswd bob
# ユーザーの削除
sudo htpasswd -D /etc/apache2/.htpasswd alice
# パスワードが合っているか確認(入力を求められる)
sudo htpasswd -v /etc/apache2/.htpasswd bob
# 登録されているユーザー名の一覧
sudo cut -d: -f1 /etc/apache2/.htpasswd
ファイルの中身は ユーザー名:ハッシュ の行です。bcrypt なら $2y$、MD5 なら $apr1$ で始まります。
ファイルの権限は、Apache の実行ユーザーが読めて、他のユーザーからは読めないようにします。
# Ubuntu / Debian(Apache は www-data で動く)
sudo chown root:www-data /etc/apache2/.htpasswd
sudo chmod 640 /etc/apache2/.htpasswd
# RHEL 系(Apache は apache で動く)
# sudo chown root:apache /etc/httpd/.htpasswd
# sudo chmod 640 /etc/httpd/.htpasswd
ApacheでBasic認証をかける
設定ファイルに書く場合
サーバーの設定を編集できるなら、バーチャルホストの設定に書くのが分かりやすく、.htaccess を毎回読む処理も省けます。
<Directory /var/www/html/admin>
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Directory>
特定のユーザーだけ許可するときは Require user alice bob と書きます。
.htaccessに書く場合
共用サーバーなどで .htaccess を使う場合は、保護したいディレクトリの .htaccess に同じ4行を書きます。AuthUserFile は / から始まるフルパスで指定します(相対パスは ServerRoot からの位置と解釈されます)。
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
認証の設定を .htaccess で使うには、そのディレクトリに AllowOverride AuthConfig(または All)が許可されている必要があります。許可されていないと、.htaccess の認証設定は使えません(AllowOverride None なら読まれず、許可されていない種類の指示を書くと 500 エラーになります)。
IPアドレスとの組み合わせ(Apache 2.4の書き方)
社内のネットワークからは認証なし、それ以外からはパスワードを求める、という条件は <RequireAny> で書きます。
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /etc/apache2/.htpasswd
<RequireAny>
Require ip 192.0.2.0/24
Require valid-user
</RequireAny>
Apache 2.2 の Order / Allow / Satisfy Any は、Apache 2.4 では互換用の mod_access_compat が有効なときしか動かず、新しい Require と混ぜると意図どおりに動かないことがあります。2.4 では Require だけで書きます。
設定を反映する
# 構文チェック
sudo apache2ctl configtest
# 反映
sudo systemctl reload apache2
RHEL 系では sudo apachectl configtest と sudo systemctl reload httpd です。.htaccess の変更は再読み込みなしで反映されます。
Basic 認証のモジュール(mod_auth_basic・mod_authn_file・mod_authz_user)は Ubuntu の標準構成で有効です。無効にしている場合は sudo apache2ctl -M | grep auth で確認し、sudo a2enmod auth_basic などで有効にします。
動作を確認する
# 認証なしでアクセス → 401 になること
curl -sI https://example.com/admin/
# 認証付きでアクセス(パスワードは入力を求められる)
curl -sI -u alice https://example.com/admin/
認証なしでは 401 Unauthorized と WWW-Authenticate: Basic realm="Restricted Area" が返り、正しいユーザーとパスワードなら本来のステータス(200 など)が返ります。
うまくいかないときは、Apache のエラーログ(Ubuntu は /var/log/apache2/error.log、RHEL 系は /var/log/httpd/error_log)を見ます。
| ログのメッセージ(抜粋) | 意味 |
|---|---|
AH01617: user alice: authentication failure for "/admin/": Password Mismatch |
パスワードが違う |
AH01618: user alice not found: /admin/ |
そのユーザーがファイルに無い(別のファイルを見ている可能性も) |
AH01620: Could not open password file: /etc/apache2/.htpasswd |
ファイルが無い、またはパスや権限が違う |
AH01615: need AuthName: /admin/ |
AuthName が書かれていない |
WordPressのwp-adminをBasic認証で守る
WordPress の管理画面に Basic 認証を重ねると、ログイン画面への総当たり攻撃を手前で止められます。ただし wp-admin/admin-ajax.php はサイトの表側(テーマやプラグインの非同期処理)からも呼ばれるため、ここまで認証をかけると訪問者の画面で機能が動かなくなります。admin-ajax.php だけは認証の対象から外します。
# /etc/apache2/sites-available/example.conf のバーチャルホスト内
<Directory /var/www/html/wp-admin>
AuthType Basic
AuthName "WordPress Admin"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
# admin-ajax.php は認証なしで通す(Apache 2.4 の書き方)
<Files "admin-ajax.php">
Require all granted
</Files>
</Directory>
# ログイン画面(ドキュメントルート直下)も保護する
<Files "wp-login.php">
AuthType Basic
AuthName "WordPress Admin"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</Files>
<Files> の設定は <Directory> より後に適用され、既定では後から適用された Require が前のものを置き換えます。このため admin-ajax.php だけが認証なしになります。.htaccess で行う場合は、wp-admin/.htaccess に <Directory> の中身(<Files "admin-ajax.php"> を含む)を書き、ログイン画面の <Files "wp-login.php"> はドキュメントルートの .htaccess に書きます。
確認は次のように行います。
# 認証なしで 401 になること
curl -sI https://example.com/wp-login.php
# admin-ajax.php は 401 にならないこと(WordPress の応答として 400 などが返る)
curl -sI https://example.com/wp-admin/admin-ajax.php
注意点
- Basic 認証は、ユーザー名とパスワードを Base64 で符号化して送るだけで、暗号化はしません。HTTPS のサイトでだけ使います。
- パスワードファイルを
DocumentRootの下に置くと、設定によってはダウンロードされるおそれがあります。外に置くのが安全です。 - Basic 認証をかけたディレクトリは、外部の監視サービスや決済サービスからの通知(Webhook)も通らなくなります。そうした URL があるディレクトリにはかけないか、上の
admin-ajax.phpと同じ方法で除外します。