コンテンツにスキップ

PAMを通したLDAP認証

nginx で PAM 認証モジュールを使うと、HTTP Basic 認証のユーザー名とパスワードを PAM に渡し、PAM 側で LDAP 認証を行える。


nginxがLDAPを直接見るわけではない

Section titled “nginxがLDAPを直接見るわけではない”

この構成では、nginx が LDAP プロトコルを直接話すわけではない。

browser
-> HTTPS + Basic Authentication
-> nginx
-> ngx_http_auth_pam_module
-> PAM service: /etc/pam.d/nginx
-> libpam-ldapd
-> nslcd
-> LDAP Bind
-> OpenLDAP slapd

nginx は HTTP の入口である。認証処理は PAM に委ねる。PAM は /etc/pam.d/nginx の設定に従い、libpam-ldapd を通して nslcd に問い合わせる。nslcd が LDAP サーバーと通信する。


コンポーネント 役割
ngx_http_auth_pam_module nginx から PAM 認証を呼び出す
PAM 認証方式を組み合わせる枠組み
/etc/pam.d/nginx nginx 用の PAM サービス定義
libpam-ldapd PAM から LDAP 認証を使うモジュール
nslcd LDAP サーバーへの問い合わせを行うデーモン
OpenLDAP ユーザー情報とパスワード検証の情報源

PAM と LDAP の基本は NSSとPAMによるLinuxログイン を参照する。


nginx の PAM 認証モジュールは、HTTP Basic 認証としてクライアントに認証を要求する。

1. clientが保護されたURLへアクセスする
2. nginxが401 Unauthorizedを返す
3. clientがBasic認証のユーザー名とパスワードを送る
4. nginx auth PAM moduleがPAMへ渡す
5. PAMがLDAP認証を行う
6. 成功すればnginxがリクエスト処理を続ける

Basic 認証は認証情報を送る仕組みであり、暗号化の仕組みではない。必ず HTTPS と組み合わせる。


nginx 側では、どの PAM サービスを使うかを指定する。

location /admin/ {
auth_pam "LDAP Login";
auth_pam_service_name nginx;
}

この場合、PAM は /etc/pam.d/nginx を読む。auth_pam_service_name nginx_restricted; とすれば、/etc/pam.d/nginx_restricted を使う。

保護する URL ごとに PAM サービス名を分けると、許可ユーザーや認証条件を分けられる。


LDAP 認証に成功することと、その URL へアクセスしてよいことは同じではない。

認証: あなたは誰か
認可: その人がこのURLへアクセスしてよいか

全 LDAP ユーザーにアクセスを許可してよいなら、PAM LDAP 認証だけで足りる。特定ユーザーだけに絞る場合は、pam_listfile.so などで許可リストを追加する。


  • nginx worker は通常 www-data で動くため、PAM モジュール側がroot権限や特定の実行条件を前提にしていると失敗することがある。
  • pam_unix.so が必ず失敗するとは限らない。PAM実装や特権ヘルパー、PAMサービス定義によって動作が変わる。ただしLDAP認証が目的なら、ローカルパスワード認証を混在させず libpam-ldapd / nslcd 側に寄せる方が切り分けやすい。
  • LDAP への Simple Bind は StartTLS または ldaps:// で保護する。
  • nginx の Basic 認証は HTTPS で保護する。

同一ホストの閉じたネットワークで要件指定がなければLDAP側TLSを省略する場合があるが、通常運用ではSimple BindをTLSで保護する。libnginx-mod-http-auth-pam を導入できない場合の限定的な代替は Python auth_request LDAP認証 を参照する。