コンテンツにスキップ

PAM認証の設定

ApacheのHTTP Basic認証で受け取ったユーザー名とパスワードを、既存のPAMサービスへ渡して認証する。


項目 値
OS Debian 13.x
サイト名 www.example.com
ドキュメントルート /var/www/html
認証対象 /var/www/html/private
PAMサービス名 apache2
PAM設定 /etc/pam.d/apache2

HTTPSサイトの設定が完了し、https://www.example.com/へ接続できることを前提とする。

この手順を開始する前に、HTTP用VirtualHostで/var/www/html/privateをSSLRequireSSLにより403 Forbiddenで拒否するか、HTTPからHTTPSへのリダイレクトを設定する。

PAMの処理グループとLDAP連携はNSSとPAMによるLinuxログインを参照する。


1. PAMサービスを作成して確認する

Section titled “1. PAMサービスを作成して確認する”

/etc/pam.d/apache2を作成し、Debianの共通認証・アカウント管理スタックを使用する。

Terminal window
cat <<'EOF' | sudo tee /etc/pam.d/apache2
@include common-auth
@include common-account
EOF

common-authはユーザー名とパスワードの認証、common-accountはアカウントの有効期限や利用可否の確認を行う。ローカルユーザー、LDAP、SSSDなどのどの認証先を使うかは、共通PAMスタックの設定によって決まる。

PAM設定ファイルを読み取れることを確認する。

Terminal window
sudo test -r /etc/pam.d/apache2
echo $?

0ならファイルを読み取れる。AuthPAMService apache2は、このapache2というPAMサービス名を参照する。

pamtesterを利用できる環境では、Apacheへ組み込む前の任意確認としてPAMサービスを単体テストできる。

Terminal window
sudo apt install pamtester
sudo pamtester apache2 ldapuser authenticate acct_mgmt

authenticateはPAMのauth、acct_mgmtはaccountに相当する処理を順に確認する。pamtesterは確認用ツールであり、ApacheのPAM認証そのものには不要である。


2. PAM認証モジュールをインストールする

Section titled “2. PAM認証モジュールをインストールする”
Terminal window
sudo apt update
sudo apt install libapache2-mod-authnz-pam

必要なモジュールを有効化する。

Terminal window
sudo a2enmod auth_basic authz_user authnz_pam

確認する。

Terminal window
sudo apache2ctl -M | grep -E 'auth_basic|authz_user|authnz_pam'

auth_basic_module、authz_user_module、authnz_pam_moduleが表示されることを確認する。


3. 認証対象のコンテンツを作成する

Section titled “3. 認証対象のコンテンツを作成する”
Terminal window
sudo install -d -o root -g root -m 755 /var/www/html/private
Terminal window
cat <<'EOF' | sudo tee /var/www/html/private/index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Private Area</title>
</head>
<body>
<h1>Private Area</h1>
</body>
</html>
EOF

4. HTTPS用VirtualHostへPAM認証を設定する

Section titled “4. HTTPS用VirtualHostへPAM認証を設定する”

/etc/apache2/sites-available/www.example.com.confの<VirtualHost *:443>へ、/var/www/html/private用のDirectoryセクションを追加する。

/etc/apache2/sites-available/www.example.com.conf
<VirtualHost *:443>
ServerName www.example.com
DocumentRoot /var/www/html
SSLEngine On
SSLCertificateFile /etc/apache2/tls/www.example.com/fullchain.pem
SSLCertificateKeyFile /etc/apache2/tls/www.example.com/privkey.pem
<Directory /var/www/html>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/html/private>
AuthType Basic
AuthName "Private Area"
AuthBasicProvider PAM
AuthPAMService apache2
Require valid-user
</Directory>
ErrorLog ${APACHE_LOG_DIR}/www.example.com-ssl-error.log
CustomLog ${APACHE_LOG_DIR}/www.example.com-ssl-access.log combined
</VirtualHost>

より長いパスを指定した<Directory /var/www/html/private>が親ディレクトリの後に処理される。認可設定は既定のAuthMerging Offにより、このセクションのRequire valid-userが親のRequire all grantedを置き換える。統合順序はVirtualHostと設定セクションを参照する。

この手順では、Basic認証の検証先にPAMを選び、/etc/pam.d/apache2のauthとaccountを通過したユーザーを許可する。mod_authnz_pamが両処理を実行するため、Require pam-account apache2は追加せず、Require valid-userを使う。各認証ディレクティブの役割は認証と認可を参照する。


Terminal window
sudo apache2ctl configtest
sudo systemctl reload apache2

configtestがSyntax OKになることを確認する。


資格情報を送らずにアクセスする。

Terminal window
curl -I https://www.example.com/private/

期待する結果は401 UnauthorizedとBasic認証のchallengeである。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Private Area"

誤ったパスワードで確認する。

Terminal window
curl -I -u ldapuser:wrong-password \
https://www.example.com/private/

期待する結果は401 Unauthorizedである。

正しいユーザー名とパスワードで確認する。

Terminal window
curl -I -u ldapuser \
https://www.example.com/private/

curl -u ldapuserはパスワードを対話入力する。認証とaccount検査に成功すると200 OKが返る。


Apache側のエラーを確認する。

Terminal window
sudo tail -f /var/log/apache2/www.example.com-ssl-error.log

サービス全体のログを確認する。

Terminal window
journalctl -u apache2

PAM側の認証結果を確認する。

Terminal window
sudo tail -f /var/log/auth.log

ApacheがAuthPAMServiceを認識しない場合はauthnz_pam_module、PAMサービスが見つからない場合は/etc/pam.d/apache2、ユーザーの認証やaccount検査に失敗する場合はPAMスタックと認証バックエンドを確認する。