PAM経由LDAP認証の設定
nginx の
auth_pamで HTTP Basic 認証を要求し、PAM からlibpam-ldapd/nslcdを通して LDAP 認証する。
| 項目 | 例 |
|---|---|
| OS | Debian 13.x(Ubuntu系でも概ね同様) |
| 公開URL | https://app.example.com/admin/ |
| ドキュメントルート | /var/www/app.example.com |
| nginxユーザー | www-data |
| LDAPサーバー | ldap://ldap.example.com/ |
| Base DN | dc=example,dc=com |
| LDAPユーザー | uid=ldapuser,ou=people,dc=example,dc=com |
| PAMサービス | /etc/pam.d/nginx |
LDAP サーバー側には、認証に使うユーザーが存在している前提とする。LDAP ユーザー作成や nslcd の基本は Linuxユーザー認証の設定 を参照する。
証明書は HTTP/HTTPSとリダイレクトの設定 と同じく、fullchain.pem とroot所有・600の privkey.pem を使用する。証明書のSANには実際の server_name を含める。
1. 必要なパッケージを入れる
Section titled “1. 必要なパッケージを入れる”sudo apt updatesudo apt install nginx libnginx-mod-http-auth-pam nslcd libpam-ldapd ldap-utils役割は次のとおり。
| パッケージ | 役割 |
|---|---|
libnginx-mod-http-auth-pam |
nginx から PAM 認証を呼び出す |
libpam-ldapd |
PAM から LDAP 認証を使う |
nslcd |
LDAP への問い合わせを行うデーモン |
ldap-utils |
ldapsearch などの確認コマンド |
Debian / Ubuntu 系では、パッケージの導入により nginx の動的モジュールが読み込まれる構成になる。モジュール読み込み設定を確認するには、nginx -T で load_module 行を見る。
sudo nginx -T | grep -E 'load_module.*auth_pam|auth_pam_module'load_module modules/ngx_http_auth_pam_module.so; のような行が表示されれば、nginx が PAM 認証モジュールを読み込む設定になっている。
2. nslcdを設定する
Section titled “2. nslcdを設定する”/etc/nslcd.conf に LDAP サーバーと検索ベースを設定する。LDAP 接続を TLS で保護するかに応じて、次のどちらか一方を使う。
TLSを使わない最小構成
Section titled “TLSを使わない最小構成”同一ホストまたは閉じた隔離ネットワークで使用する TLS なしの最小構成。
uid nslcdgid nslcd
uri ldap://ldap.example.com/base dc=example,dc=com
ssl off
filter passwd (objectClass=posixAccount)filter group (objectClass=posixGroup)この構成ではLDAP Simple Bindの認証情報が暗号化されない。閉じた隔離ネットワークでのみ使用する。
StartTLSを使う構成
Section titled “StartTLSを使う構成”LDAP サーバー側で StartTLS を構成し、発行元 Root CA を nginx サーバーへ配布してから使用する。LDAP URI のホスト名はサーバー証明書の SAN と一致させる。
Root CA証明書を ca.crt としてコピー済みの場合の例。
sudo install -o root -g root -m 644 ca.crt \ /usr/local/share/ca-certificates/skills-root-ca.crtsudo update-ca-certificatesuid nslcdgid nslcd
uri ldap://ldap.example.com/base dc=example,dc=com
ssl start_tlstls_reqcert demandtls_cacertfile /etc/ssl/certs/ca-certificates.crt
filter passwd (objectClass=posixAccount)filter group (objectClass=posixGroup)匿名検索を許可しない場合は、検索用の読み取り専用 DN を用意し、binddn と bindpw を設定する。
binddn cn=readonly,dc=example,dc=combindpw read-only-passwordbindpw を書く場合は、ファイル権限に注意する。
sudo chown root:nslcd /etc/nslcd.confsudo chmod 640 /etc/nslcd.conf設定を反映する。
sudo systemctl restart nslcd3. LDAP疎通を確認する
Section titled “3. LDAP疎通を確認する”LDAP サーバーに到達できるか確認する。TLSを使わない構成では次のように確認する。
ldapsearch -x -H ldap://ldap.example.com/ \ -b "dc=example,dc=com" \ "(uid=ldapuser)"StartTLSを使う構成では -ZZ を付け、TLS開始に失敗した場合も処理を継続させない。
ldapsearch -x -ZZ -H ldap://ldap.example.com/ \ -b "dc=example,dc=com" \ "(uid=ldapuser)"NSS も LDAP を見る構成にしている場合は、Linux ユーザーとして解決できるか確認する。
getent passwd ldapuserid ldapuserこの確認は切り分けに使う。nginx の Basic 認証そのものは PAM サービス経由で判定されるが、LDAP ユーザーやグループが想定どおり引けるかを見るには getent が分かりやすい。
4. nginx用PAMサービスを作る
Section titled “4. nginx用PAMサービスを作る”/etc/pam.d/nginx を作成する。
auth required pam_ldap.soaccount required pam_ldap.soこの PAM サービスは、nginx から渡されたユーザー名とパスワードを LDAP 認証へ渡す。
特定ユーザーだけに絞る場合は、pam_listfile.so を先に置く。
auth required pam_listfile.so onerr=fail item=user sense=allow file=/etc/nginx/allowed_ldap_usersauth required pam_ldap.soaccount required pam_ldap.so許可ユーザーリストを作る。
printf '%s\n' ldapuser | sudo tee /etc/nginx/allowed_ldap_userssudo chown root:www-data /etc/nginx/allowed_ldap_userssudo chmod 640 /etc/nginx/allowed_ldap_users5. nginxで保護するlocationを設定する
Section titled “5. nginxで保護するlocationを設定する”静的サイトの /admin/ 配下に PAM 認証をかける例。
確認用ファイルを作成する。
sudo mkdir -p /var/www/app.example.com/adminprintf '%s\n' 'for LDAP users' | \ sudo tee /var/www/app.example.com/admin/index.htmlserver { listen 80; listen [::]:80; server_name app.example.com;
return 301 https://$host$request_uri;}
server { listen 443 ssl; listen [::]:443 ssl; server_name app.example.com;
ssl_certificate /etc/nginx/tls/app.example.com/fullchain.pem; ssl_certificate_key /etc/nginx/tls/app.example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3;
root /var/www/app.example.com; index index.html;
location / { try_files $uri $uri/ =404; }
location /admin/ { auth_pam "LDAP Login"; auth_pam_service_name nginx;
try_files $uri $uri/ =404; }}この例では、/admin/ は /var/www/app.example.com/admin/ 配下のファイルに対応する。
auth_pam_service_name nginx; は /etc/pam.d/nginx を使うという意味である。nginx_restricted を使う場合は、auth_pam_service_name nginx_restricted; に変更する。
6. 設定を反映する
Section titled “6. 設定を反映する”Debian / Ubuntu 系では、sites-available に設定ファイルを作っただけでは nginx に読み込まれない。sites-enabled へシンボリックリンクを作り、サイトを有効化する。
sudo ln -s /etc/nginx/sites-available/app.example.com.conf \ /etc/nginx/sites-enabled/app.example.com.confsudo nginx -tsudo systemctl reload nginxnginx が auth_pam を知らないというエラーを出す場合は、libnginx-mod-http-auth-pam が入っているか、モジュール読み込み設定が有効かを確認する。あわせて、作成した site 設定が nginx に読み込まれているかも確認する。
dpkg -l libnginx-mod-http-auth-pamsudo nginx -T | grep -E 'load_module.*auth_pam|auth_pam_module|auth_pam'load_module の行は PAM 認証モジュールの読み込み確認である。auth_pam と auth_pam_service_name の行は、sites-enabled 経由で自分の location 設定が読み込まれていることの確認である。
7. 動作確認する
Section titled “7. 動作確認する”認証なしでアクセスし、401 Unauthorized が返ることを確認する。
curl -I https://app.example.com/admin/LDAP ユーザーでアクセスする。
curl -u ldapuser https://app.example.com/admin/成功の目安は、LDAP ユーザーのパスワードで認証が通り、保護された静的コンテンツが返ることである。
失敗時は nginx、PAM、nslcd の順に見る。
sudo tail -f /var/log/nginx/error.logjournalctl -u nginxjournalctl -u nslcdよくある失敗
Section titled “よくある失敗”| 症状 | 主な確認箇所 |
|---|---|
unknown directive "auth_pam" |
libnginx-mod-http-auth-pam が入っているか、モジュールが読み込まれているか |
| 常に 401 になる | /etc/pam.d/nginx、LDAP パスワード、nslcd の接続設定 |
| LDAP検索はできるが認証できない | Bind DN、ユーザー DN の検索、TLS、LDAP 側 ACL |
| HTTPでは動くが危険 | Basic 認証を HTTP のまま使っている。HTTPS 化する |
pam_unix.so で失敗する |
nginxの実行ユーザー、PAMサービス定義、PAM実装や特権ヘルパーの利用条件を確認する。LDAP認証が目的なら pam_ldap.so へ寄せる |
- nslcd.conf(5) — Debian 13
ssl、tls_reqcert、tls_cacertfileなど、nslcdのLDAP/TLS接続設定。