コンテンツにスキップ

LDAP認証の設定

Apache標準のmod_authnz_ldapを使い、LDAP検索でユーザーDNを取得し、そのDNと入力されたパスワードでBindして認証する。


項目 値
OS Debian 13.x
Webサイト www.example.com
認証対象 /var/www/html/private
LDAPサーバー ldap.example.com
LDAPポート TCP 389
Base DN dc=example,dc=com
ユーザー検索ベース ou=people,dc=example,dc=com
ログイン名の属性 uid

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

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

LDAPサーバーにはuid=ldapuser,ou=people,dc=example,dc=comなどのユーザーが存在し、ユーザー自身のDNとパスワードでSimple Bindできるようにする。LDAPサーバーとユーザーの作成はLinuxユーザー認証の設定(TLSなし)を参照する。StartTLSを使う場合はLinuxユーザー認証の設定(StartTLS)も完了させる。

Basic認証、認証プロバイダー、Requireの役割は認証と認可を参照する。Apacheが行うユーザー検索、検索用Bind、ユーザーBindと、AuthLDAPURLを構成する各要素はLDAP認証の仕組みを参照する。


mod_authnz_ldapとmod_ldapはApacheのモジュールとしてDebianのapache2パッケージに含まれる。

Terminal window
sudo a2enmod auth_basic authz_user ldap authnz_ldap

有効なモジュールを確認する。

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

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


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

Section titled “2. 認証対象のコンテンツを作成する”
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>LDAP Private Area</title>
</head>
<body>
<h1>LDAP Private Area</h1>
</body>
</html>
EOF

3. TLSを使用しないLDAP認証を設定する

Section titled “3. TLSを使用しないLDAP認証を設定する”

/etc/apache2/sites-available/www.example.com.confの<VirtualHost *:443>へ、次の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 "LDAP Private Area"
AuthBasicProvider ldap
AuthLDAPURL "ldap://ldap.example.com/ou=people,dc=example,dc=com?uid?sub?(objectClass=posixAccount)" NONE
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>

この完成形ではNONEを選ぶため、ApacheとLDAPサーバーの間のLDAP Simple Bindは暗号化されない。private配下では、より具体的なDirectoryセクションのRequire valid-userが親ディレクトリのRequire all grantedを置き換える。設定セクションの統合はVirtualHostと設定セクションを参照する。


4. StartTLSを使用するLDAP認証を設定する

Section titled “4. StartTLSを使用するLDAP認証を設定する”

LDAPサーバー証明書を発行したCAのRoot CA証明書をApacheサーバーへ配備する。

Terminal window
sudo install -d -o root -g root -m 755 /etc/apache2/ldap
sudo install -o root -g root -m 644 ca.crt \
/etc/apache2/ldap/ca.crt

LDAPTrustedGlobalCertはサーバー全体の設定として使用するため、/etc/apache2/conf-available/ldap-tls.confを作成する。

/etc/apache2/conf-available/ldap-tls.conf
LDAPTrustedGlobalCert CA_BASE64 "/etc/apache2/ldap/ca.crt"
LDAPVerifyServerCert On

LDAPサーバー証明書を発行したCAを信頼し、サーバー証明書を検証する構成にする。LDAPTrustedGlobalCert、CA_BASE64、LDAPVerifyServerCertの役割はLDAP認証の仕組みを参照する。

設定を有効化する。

Terminal window
sudo a2enconf ldap-tls

TLSなし版のDirectoryセクションを、次のStartTLS版へ置き換える。

/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 "LDAP Private Area"
AuthBasicProvider ldap
AuthLDAPURL "ldap://ldap.example.com/ou=people,dc=example,dc=com?uid?sub?(objectClass=posixAccount)" STARTTLS
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>

この完成形ではSTARTTLSを選び、接続先のldap.example.comとLDAPサーバー証明書のSANを一致させる。


この設定は、LDAPサーバーがou=people,dc=example,dc=com配下のuid、objectClass、DNを匿名検索できる場合、その匿名接続でユーザーを検索する。

匿名検索が許可されていない場合は、任意で検索専用のBind DNとパスワードを同じDirectoryセクションへ追加する。

AuthLDAPBindDN "cn=readonly,dc=example,dc=com"
AuthLDAPBindPassword "search-account-password"

この資格情報はユーザー検索だけに使う。Web利用者本人の認証は、検索で得たユーザーDNとWeb利用者が入力したパスワードによるBindで行われる。2種類のBindの違いはLDAP認証の仕組みを参照する。

検索用アカウントには、検索に必要な属性だけを読めるACLを与える。設定ファイルへパスワードを記録する場合は、root以外から読めないようにする。

Terminal window
sudo chown root:root \
/etc/apache2/sites-available/www.example.com.conf
sudo chmod 600 \
/etc/apache2/sites-available/www.example.com.conf

検索用Bindを使わない場合、これらのディレクティブと権限変更は不要である。


Terminal window
sudo apache2ctl configtest
sudo systemctl reload apache2

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


資格情報なしで確認する。

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

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

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="LDAP 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がパスワードを対話入力する。LDAP検索でユーザーが一意に見つかり、そのユーザーDNによるBindが成功すると200 OKが返る。


Apacheのエラーログを確認する。

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

StartTLSで失敗する場合は、LDAPサーバー名の名前解決、CA証明書、証明書チェーン、SAN、時刻を確認する。LDAPVerifyServerCert Offで証明書検証を無効化せず、検証エラーの原因を直す。

認証エラーの詳細が必要な場合は、任意で一時的にログレベルを上げられる。

LogLevel warn authnz_ldap:debug ldap:debug

詳細ログは認証処理の情報量を増やすため、切り分け後は元のログレベルへ戻す。

検索が0件になる場合はBase DN、uid、追加フィルターを確認する。検索が複数件になる場合は、検索範囲またはログイン属性がユーザーを一意に識別できていない。



  • mod_authnz_ldap LDAPの検索・Bind、AuthLDAPURL、LDAP認可。

  • mod_ldap LDAPTrustedGlobalCert、StartTLS、証明書検証、LDAP接続とキャッシュ。