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: 2
# numEntries: 1
この問い合わせの結果 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
# PERL5LIB="${PERL5LIB}:/etc/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
You might notice that we extend the PERL5LIB variable. This is due to Debian bug report #982666.
As you might have also noticed, we deliberately ignore migration of the /etc/aliases file, since the standard schema as provided by Debian does not include the structures that this script uses to describe email aliases. Should we want to integrate this data into the directory, the /etc/ldap/schema/misc.schema file should be added to the standard schema.
ldapadd コマンドの -c オプションの利用について触れておきます。このオプションはエラーが起きた場合に処理を停止しないように要求するものです。このオプションを使うことが必要です。なぜなら、/etc/services を変換する際に、無視しても問題ない数個のエラーが起きることが多いからです。

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

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

11.7.3.1. NSS の設定

The NSS system (Name Service Switch, see sidebar GOING FURTHER NSS とシステムデータベース」) is a modular system designed to define or fetch information for system directories. Using LDAP as a source of data for NSS requires installing the libnss-ldapd package.
The /etc/nsswitch.conf file then needs to be modified, so as to configure NSS to use the freshly-installed ldap module.

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

# /etc/nsswitch.conf
#
# 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 データベースに向けて認証を要求することが可能になります。
The LDAP module for PAM is provided by the libpam-ldapd package. Installing this package asks a few questions very similar to those in libnss-ldapd; some configuration parameters (such as the URI for the LDAP server) are even actually shared with the libnss-ldapd package.
Installing libpam-ldapd automatically adapts the default PAM configuration defined in the /etc/pam.d/common-auth, /etc/pam.d/common-password and /etc/pam.d/common-account files. This mechanism uses the dedicated pam-auth-update tool (provided by the libpam-runtime package). This tool can also be run by the administrator should they wish to enable or disable PAM modules.

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
# mv pki/issued/ldap.falcot.com.crt /etc/ssl/certs/ldap.falcot.com.pem
# chown root.root /etc/ssl/certs/ldap.falcot.com.pem
# chmod 0644 /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: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ldap.falcot.com.key
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ldap.falcot.com.pem
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"
# systemctl restart slapd.service
# ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config -s base | grep TLS
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
olcTLSCertificateFile: /etc/ssl/certs/ldap.falcot.com.pem
olcTLSCertificateKeyFile: /etc/ssl/certs/ldap.falcot.com.key
暗号化を有効化するための最後の作業が /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.d 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. クライアントの設定
On the client side, the configuration for the libpam-ldapd and libnss-ldapd modules needs to be modified to use an ldaps:// URI.
LDAP clients also need to be able to authenticate the server. In an X.509 public key infrastructure, public certificates are signed by the key of a certificate authority (CA). With easy-rsa, the Falcot administrators have created their own CA and they now need to configure the system to trust the signatures of Falcot's CA. This can be done by putting the CA certificate in /usr/local/share/ca-certificates and running 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 Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

#BASE   dc=example,dc=com
#URI    ldap://ldap.example.com ldap://ldap-provider.example.com:666

#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never

# TLS certificates (needed for GnuTLS)
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt