Product SiteDocumentation Site

11.7. LDAP ディレクトリ

OpenLDAP は LDAP プロトコルの実装です。言い換えれば、OpenLDAP はディレクトリを保存するために設計された特製データベースです。OpenLDAP が最もよく使われる用途は、LDAP サーバを使ってユーザアカウントと関連するパーミッションの中央管理を行う場合です。さらに、LDAP データベースは簡単に複製できるので、複数の同期された LDAP サーバをセットアップすることが可能になります。ネットワークとユーザの数が急速に多くなった場合でも、複数のサーバ間で負荷のバランスをとることが可能です。
LDAP データは階層的に構造化されています。LDAP データの構造は「スキーマ」によって定義され、スキーマはデータベースに保存できるオブジェクトの種類をその属性リストと一緒に説明するものです。データベース内の特定のオブジェクトを参照するために使われる構文はデータ構造に依存し、構文の複雑さはデータ構造の複雑さに対応します。

11.7.1. インストール

OpenLDAP サーバは slapd パッケージに含まれます。LDAP サーバと情報をやり取りするためのコマンドラインツールは ldap-utils パッケージに含まれます。
Installing slapd usually asks only for the administrator's password and the resulting database is unlikely to suit your needs. Fortunately a simple dpkg-reconfigure slapd will let you reconfigure the LDAP database with more details:
  • OpenLDAP サーバの設定を省略しますか? LDAP サービスを設定するので当然「いいえ」を選びます。
  • DNS ドメイン名。「falcot.com」と入力します。
  • 組織名。「Falcot Corp」と入力します。
  • 管理者のパスワードを入力します。
  • 利用するデータベースバックエンド。「MDB」を選びます。
  • slapd をパージした時にデータベースを削除しますか? 間違ってデータベースを失う危険性を増やすのは得策ではありませんから「いいえ」を選びます。
  • 古いデータベースを移動しますか? この質問はデータベースが既に存在するにも関わらず設定を行おうとした場合に表示されます。たとえば最初のインストールの直後に dpkg-reconfigure slapd を実行する場合など、空っぽのデータベースから設定を再開したい場合、「はい」を選びます。
以下の問い合わせによって実例を示す通り、最低限のデータベースが設定されています。
$ ldapsearch -x -b dc=falcot,dc=com
# extended LDIF
#
# LDAPv3
# base <dc=falcot,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# falcot.com
dn: dc=falcot,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Falcot Corp
dc: falcot

# admin, falcot.com
dn: cn=admin,dc=falcot,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2
この問い合わせの結果 2 種類のオブジェクトが返されました。具体的に言えば、組織自身と管理ユーザが返されました。

11.7.2. ディレクトリへの書き込み

空っぽのデータベースは全く役に立たないので、すべての存在するディレクトリをデータベースに投入することにします。ここで存在するディレクトリとはユーザ、グループ、サービス、ホスト名データベースなどを指します。
migrationtools パッケージには、標準的な Unix ディレクトリ (/etc/passwd/etc/group/etc/services/etc/hosts など) からのデータを展開するための一連のスクリプトが含まれます。スクリプトを使ってデータを変換し、LDAP データベースに投入します。
migrationtools パッケージをインストールしたら、必ず /etc/migrationtools/migrate_common.ph を編集してください。つまり、IGNORE_UID_BELOWIGNORE_GID_BELOW オプションを編集して (コメント解除するだけで十分です)、DEFAULT_MAIL_DOMAINDEFAULT_BASE を更新する必要があります。
実際の移行操作は以下の通り migrate_all_online.sh コマンドを使って行います。
# cd /usr/share/migrationtools
# LDAPADD="/usr/bin/ldapadd -c" ETC_ALIASES=/dev/null ./migrate_all_online.sh
migrate_all_online.sh から LDAP データベースに移行するデータの種類に関する数個の質問を尋ねられます。表 11.1 には Falcot の使用例で使った回答がまとめられています。

表 11.1 migrate_all_online.sh スクリプトからの質問に対する回答

質問回答
X.500 命名コンテキストdc=falcot,dc=com
LDAP サーバのホスト名localhost
管理者の識別名cn=admin,dc=falcot,dc=com
認証情報の紐付けLDAP データベース管理用パスワード
DUAConfigProfile を作成no
上の例では ETC_ALIASES=/dev/null を指定することで意図的に /etc/aliases ファイルの移行を行いませんでした。なぜなら、Debian の提供する標準的なスキーマには、このスクリプトが電子メールアドレスを表現するために使う構造が含まれないからです。このデータをディレクトリに統合したい場合、標準的なスキーマに /etc/ldap/schema/misc.schema ファイルを追加するべきです。
ldapadd コマンドの -c オプションの利用について触れておきます。このオプションはエラーが起きた場合に処理を停止しないように要求するものです。このオプションを使うことが必要です。なぜなら、/etc/services を変換する際に、無視しても問題ない数個のエラーが起きることが多いからです。

11.7.3. LDAP を用いたアカウントの管理

これで LDAP データベースにいくつかの実用的な情報が含まれるようになりましたので、このデータを使うように設定します。この節では、さまざまなシステムディレクトリが LDAP データベースを使うように Linux システムを設定する方法に注目します。

11.7.3.1. NSS の設定

NSS システム (Name Service Switch、補注GOING FURTHER NSS とシステムデータベース」を参照してください) はシステムディレクトリの情報を定義したり取得したりするために設計されたモジュール式システムです。NSS 用のデータ参照元として LDAP を使うには、libnss-ldap パッケージをインストールする必要があります。libnss-ldap パッケージのインストール中に数個の質問が行われます。ここで使った回答は表 11.2 にまとめられています。

表 11.2 libnss-ldap パッケージの設定

質問回答
LDAP サーバの Uniform Resource Identifier ldapi://ldap.falcot.com
検索ベースの識別名dc=falcot,dc=com
使用する LDAP バージョン3
LDAP 管理用アカウントcn=admin,dc=falcot,dc=com
LDAP 管理用パスワードLDAP データベース管理用パスワード
Allow LDAP admin account behave like local root? yes
LDAP データベースはログインを必要としますか?no
The /etc/nsswitch.conf file then needs to be modified, so as to configure NSS to use the freshly-installed ldap module. You can use the example provided in /usr/share/doc/libnss-ldap/examples/nsswitch.ldap or edit your existing configuration.

例 11.23 /etc/nsswitch.conf ファイル

#ident $Id: nsswitch.ldap,v 2.4 2003/10/02 02:36:25 lukeh Exp $
#
# An example file that could be copied over to /etc/nsswitch.conf; it
# uses LDAP conjunction with files.
#
# "hosts:" and "services:" in this file are used only if the
# /etc/netconfig file has a "-" for nametoaddr_libs of "inet" transports.

# the following lines obviate the "+" entry in /etc/passwd and /etc/group.
passwd:                files ldap
shadow:                files ldap
group:                files ldap

# consult DNS first, we will need it to resolve the LDAP host. (If we
# can't resolve it, we're in infinite recursion, because libldap calls
# gethostbyname(). Careful!)
hosts:                dns ldap

# LDAP is nominally authoritative for the following maps.
services:   ldap [NOTFOUND=return] files
networks:   ldap [NOTFOUND=return] files
protocols:  ldap [NOTFOUND=return] files
rpc:        ldap [NOTFOUND=return] files
ethers:     ldap [NOTFOUND=return] files

# no support for netmasks, bootparams, publickey yet.
netmasks:   files
bootparams: files
publickey:  files
automount:  files

# I'm pretty sure nsswitch.conf is consulted directly by sendmail,
# here, so we can't do much here. Instead, use bbense's LDAP
# rules ofr sendmail.
aliases:    files
sendmailvars:   files

# Note: there is no support for netgroups on Solaris (yet)
netgroup:   ldap [NOTFOUND=return] files


通常 ldap モジュールは他のモジュールよりも前に書き込みます。こうすることで、問い合わせの際に ldap モジュールが優先して使われます。注目すべき除外例が hosts サービスです。なぜなら、LDAP サーバに接続するには (ldap.falcot.com の名前解決を行うためには) 先に DNS を調べる必要があるからです。hosts サービスで最初 ldap モジュールを使うようにすると、LDAP サーバにホスト名を問い合わせることになります。しかし、名前解決を担当している LDAP サーバに接続するには LDAP サーバの名前解決が必要なので、無限ループすることになります。
LDAP サーバからの応答を正式な回答として取り扱う場合 (そして特殊な状況が起きない限り files モジュールの使うローカルファイルからの応答を無視する場合)、以下の構文を使ってサービスを設定します。
service: ldap [NOTFOUND=return] files.
LDAP サービスを利用して問い合わせたエントリが LDAP データベースに存在しない場合、問い合わせに対する応答は「not existing」になるでしょう。これは問い合わせたエントリがローカルファイルに存在するか否かに依存しません。しかし LDAP サービスが利用できない場合に限り、ローカルファイルにエントリを問い合わせます。

11.7.3.2. PAM の設定

この節では、PAM 設定 (補注BEHIND THE SCENES /etc/environment/etc/default/localeを参照してください) を説明します。ここで説明した PAM 設定を使うことで、アプリケーションは LDAP データベースに向けて認証を要求することが可能になります。
PAM 用の LDAP モジュールは libpam-ldap パッケージに含まれます。libpam-ldap パッケージをインストールする際に、libnss-ldap をインストールした際にされた質問と良く似た数個の質問を尋ねられます。いくつかの設定パラメータ (LDAP サーバの URI など) は libnss-ldap パッケージと共有されます。ここで使った回答は表 11.3 にまとめられています。

表 11.3 libpam-ldap の設定

質問回答
LDAP 管理アカウントがローカルの root のように振る舞うことを許しますか?はい。こうすることで、通常の passwd コマンドから LDAP データベースに保存されているパスワードを変更することが可能になります。
LDAP データベースはログインを必要としますか?no
LDAP 管理用アカウントcn=admin,dc=falcot,dc=com
LDAP 管理用パスワードLDAP 管理用パスワード
パスワードに使うローカル暗号化アルゴリズムcrypt
libpam-ldap をインストールすると自動的に /etc/pam.d/common-auth/etc/pam.d/common-password/etc/pam.d/common-account ファイルで定義されたデフォルトの PAM 設定が適用されます。このメカニズムは専用の pam-auth-update ツール (libpam-runtime パッケージから提供される) を使います。pam-auth-update ツールは PAM モジュールを有効化または無効化したい管理者によって実行される場合もあります。

11.7.3.3. 安全な LDAP データ交換

デフォルトで、LDAP プロトコルはネットワークを平文で通信します。従って、(暗号化された) パスワードがネットワーク上をそのまま流れます。暗号化されたパスワードをネットワークから抽出することが可能ですから、パスワードは辞書型攻撃に弱いということになります。暗号化層を追加することで、このような危険性を避けることが可能です。この節のテーマは暗号化層を有効化することです。
11.7.3.3.1. サーバの設定
The first step is to create a key pair (comprising a public key and a private key) for the LDAP server. The Falcot administrators reuse easy-rsa to generate it (see 第 10.2.2 節「公開鍵基盤、easy-rsa). Running ./easyrsa build-server-full ldap.falcot.com nopass will ask you about the “common name”. The answer to that question must be the fully-qualified hostname for the LDAP server; in our case, ldap.falcot.com.
This command creates a certificate in the pki/issued/ldap.falcot.com.crt file; the corresponding private key is stored in pki/private/ldap.falcot.com.key.
さらに、これらの鍵を標準的な場所にインストールし、openldap ユーザ権限で実行されている LDAP サーバが秘密鍵を読み込み可能であることを保証しなければいけません。これを行うために以下の通り実行します。
# adduser openldap ssl-cert
Adding user `openldap' to group `ssl-cert' ...
Adding user openldap to group ssl-cert
Done.
# mv pki/private/ldap.falcot.com.key /etc/ssl/private/ldap.falcot.com.key
# chown root:ssl-cert /etc/ssl/private/ldap.falcot.com.key
# chmod 0640 /etc/ssl/private/ldap.falcot.com.key
# ./eassyrsa gen-dh

Note: using Easy-RSA configuration from: ./vars

Using SSL: openssl OpenSSL 1.1.1c  28 May 2019
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
........................................................+..........................................................................+...............................................................................+............
[...]
DH parameters of size 2048 created at /home/roland/pki/dh.pem

# mv pki/dh.pem /etc/ssl/certs/ldap.falcot.com.pem
slapd デーモンにこれらの鍵を暗号化に使うように伝えることも必要です。LDAP サーバの設定は動的に管理されます。つまり、設定は cn=config オブジェクト階層に対する通常の LDAP 操作によって更新され、サーバは設定を永続的なものにするために /etc/ldap/slapd.d をリアルタイムで更新します。このため、設定を更新するには ldapmodify ツールを使ってください。

例 11.24 暗号化用の slapd の設定

# cat >ssl.ldif <<END
dn: cn=config
changetype: modify
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap.falcot.com.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap.falcot.com.key
-
END
# ldapmodify -Y EXTERNAL -H ldapi:/// -f ssl.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
暗号化を有効化するための最後の作業が /etc/default/slapd ファイル内の SLAPD_SERVICES 変数を変更することです。ここでは慎重を期して、安全対策されていない LDAP を無効化しています。

例 11.25 /etc/default/slapd ファイル

# Default location of the slapd.conf file or slapd.d cn=config directory. If
# empty, use the compiled-in default (/etc/ldap/slapd.d with a fallback to
# /etc/ldap/slapd.conf).
SLAPD_CONF=

# System account to run the slapd server under. If empty the server
# will run as root.
SLAPD_USER="openldap"

# System group to run the slapd server under. If empty the server will
# run in the primary group of its user.
SLAPD_GROUP="openldap"

# Path to the pid file of the slapd server. If not set the init.d script
# will try to figure it out from $SLAPD_CONF (/etc/ldap/slapd.conf by
# default)
SLAPD_PIDFILE=

# slapd normally serves ldap only on all TCP-ports 389. slapd can also
# service requests on TCP-port 636 (ldaps) and requests via unix
# sockets.
# Example usage:
# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
SLAPD_SERVICES="ldaps:/// ldapi:///"

# If SLAPD_NO_START is set, the init script will not start or restart
# slapd (but stop will still work).  Uncomment this if you are
# starting slapd via some other means or if you don't want slapd normally
# started at boot.
#SLAPD_NO_START=1

# If SLAPD_SENTINEL_FILE is set to path to a file and that file exists,
# the init script will not start or restart slapd (but stop will still
# work).  Use this for temporarily disabling startup of slapd (when doing
# maintenance, for example, or through a configuration management system)
# when you don't want to edit a configuration file.
SLAPD_SENTINEL_FILE=/etc/ldap/noslapd

# For Kerberos authentication (via SASL), slapd by default uses the system
# keytab file (/etc/krb5.keytab).  To use a different keytab file,
# uncomment this line and change the path.
#export KRB5_KTNAME=/etc/krb5.keytab

# Additional options to pass to slapd
SLAPD_OPTIONS=""

11.7.3.3.2. クライアントの設定
クライアント側では libpam-ldaplibnss-ldap モジュールの設定を修正し、ldaps:// URI を使うように設定する作業が必要です。
LDAP クライアントはサーバから認証を受ける必要があります。X.509 公開鍵基盤において、公開証明書は認証局 (CA) の鍵で署名されます。easy-rsa を使うことで、Falcot の管理者は自分自身の CA を作成しました。さらに管理者は Falcot の CA の署名を信頼するようにシステムを設定する必要があります。これを行うには、CA 証明書を /usr/local/share/ca-certificates に配置して update-ca-certificates を実行します。
# cp pki/ca.crt /usr/local/share/ca-certificates/falcot.crt
# update-ca-certificates
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....

Adding debian:falcot.pem
done.
done.
最後に重要なことですが、さまざまなコマンドラインツールで使われるデフォルトの LDAP URI とデフォルトのベース識別名は /etc/ldap/ldap.conf を編集すれば変更することが可能です。こうすることで、入力する量を激減させることが可能です。

例 11.26 /etc/ldap/ldap.conf ファイル

#
# LDAP のデフォルト設定
#

# 詳細は ldap.conf(5) を参照してください。全ユーザに対して
# このファイルの読み込みを許可し、書き込みを禁止してください。

BASE   dc=falcot,dc=com
URI    ldaps://ldap.falcot.com

#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never

# TLS 証明書 (これは GnuTLS を使う場合に必要です)
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt