次のページ「CentOS 7にOpenLDAP(2.5.12)をソースファイルからインストールする手順」のつづきである。
ここでは続いて、初期設定のみ行う。
上記の手順で構築したコンテナに接続して初期設定を継続するか、上記の手順で作成したイメージから新しくコンテナを始動させて初期設定を行うこともできる。
◯ 上記の手順で作成したコンテナを継続して設定する場合
・今回の作業に合うような名称に変更しておく
# docker rename ldap_justinstalled_centos7_priv ldap_installed_initialized_centos7_priv
・コンテナを始動する
# docker start ldap_installed_initialized_centos7_priv
・コンテナに接続する
# docker exec -it ldap_installed_initialized_centos7_priv /bin/bash
◯ 上記の手順で作成したイメージからコンテナを始動させる場合
コンテナ名は、既存のものと重ならないようにすること。
# docker run --privileged -d --net MYNETWORK --dns 192.168.1.1 --name ldap_installed_initialized_centos7_priv image_centos7_openldap-ver-2.5.12_202207XX_justinstalled /sbin/init
(以下の設定を行うためには必須)
--privileged 特権でコンテナを動作させる
/sbin/init initを起動する。
(オプション)
--net MYNETWORK 指定したDockerネットワークを利用する。(リモート接続しないなら不要)
--dns 192.168.1.1 コンテナに利用させるリゾルバを指定する。(ホストのものを使うなら不要)
初期設定には、LDAPディレクトリの基本的な考え方が必要である。
■ LDAPに登場するLDAPディレクトリの考え方
これらのLDAPディレクトリはDIT(ディレクトリ情報ツリー)構造を持つ。
DIT内の各位置はエントリと呼ばれる。
エントリは、FATファイルシステムなどでいうところの「ファイル」と「ディレクトリ」に似ている。エントリのうち一部は「ファイル」に相当し情報を保持する役割がある。「ディレクトリ」に相当するエントリは下位のエントリをまとめる役割があり、コンテナと呼ばれる。これらのエントリはDN(ディレクトリやファイルを指定するパスのようなもの)によって指定され他と区別される。
エントリには「ファイル」と「ディレクトリ」の概念だけでは説明できない特徴もある。「ファイル」というものが型なしでシーケンシャルにデータを保存する一方で、エントリは型付きでデータを保存すると考えられる。
すると、エントリはオブジェクト指向プログラミング言語の「参照」に似ている。情報を保持する「ファイル」に相当するエントリは、データ構造などを定義する「LDAPオブジェクトクラス(personなど)」の実体化をポイントしている「参照」と捉えられる。
エントリには「LDAPオブジェクトクラス」が指定され、オブジェクトクラスの属性に対応する属性値としてデータがストアされる。どの属性を持つかはオブジェクトクラスによって違うし、オブジェクトクラスには継承という概念もあり親クラスの属性は引き継がれる。
LDAPサーバーから情報を検索するアプリケーションが求める属性値に応じたオブジェクトクラスがエントリで指定される必要がある。
■ slapdの初期設定
(概要)
LDAPサーバーは、本業のデータ管理用「データディレクトリ」と、自分自身の設定を管理する「設定用ディレクトリ」から成る。
slapd.confファイルによる初期設定で、「データディレクトリ」と、「設定ディレクトリ」について初期設定を行う。(LDAPサーバーの運用後には、LDAPサーバーの設定はLDAPサーバーに統合された「設定用ディレクトリ」の内容変更によって行う。)
さらに後で述べるように、「設定ディレクトリ」の具体化も別に行う必要がある。
(目次)
<1> オリジナル設定ファイルのバックアップ
<2> オリジナル設定ファイルの確認
<3> 初期設定ファイルの編集(オリジナル設定ファイルを基に作成する)
<4> 「設定ディレクトリ(config directory)」の作成
<1> オリジナル設定ファイルのバックアップ
# cp /usr/local/etc/openldap/slapd.conf /usr/local/etc/openldap/slapd.conf.org
<2> オリジナル設定ファイルの確認
オレンジ(suffix項目、rootdn項目)と、黄色(rootpw項目)の各マーカーのところを環境に合わせて、後で述べるように変更する。
# cat /usr/local/etc/openldap/slapd.conf.org
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /usr/local/etc/openldap/schema/core.schema
# Define global ACLs to disable default read access.
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /usr/local/var/run/slapd.pid
argsfile /usr/local/var/run/slapd.args
# Load dynamic backend modules:
# modulepath /usr/local/libexec/openldap
# moduleload back_mdb.la
# moduleload back_ldap.la
# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 63-bit encryption for simple bind
# security ssf=1 update_ssf=112 simple_bind=64
# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#######################################################################
# config database definitions
#######################################################################
database config
# Uncomment the rootpw line to allow binding as the cn=config
# rootdn so that temporary modifications to the configuration can be made
# while slapd is running. They will not persist across a restart.
# rootpw secret
#######################################################################
# MDB database definitions
#######################################################################
database mdb
maxsize 1073741824
suffix "dc=my-domain,dc=com"
rootdn "cn=Manager,dc=my-domain,dc=com"
# Cleartext passwords, especially for the rootdn, should
# be avoid. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged.
rootpw secret
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /usr/local/var/openldap-data
# Indices to maintain
index objectClass eq
#######################################################################
# monitor database definitions
#######################################################################
database monitor
<3> 初期設定ファイルの編集(オリジナル設定ファイルを基に作成する)
下記に挙げる初期設定はLDAPサーバーの運用前に初期投入するものである。
「データディレクトリ」と「設定用ディレクトリ」の利用に必要な初期設定を盛り込んだ内容になっている。
・データディレクトリ管理用パスワードの決定とハッシュデータの作成
これについて、予め、パスワードを決めておき、それのハッシュデータを作成した。
このハッシュは初期設定ファイルに記述する。
# slappasswd
New password: YourPlainPassword
Re-enter new password:
{SSHA}HereLongStringsAsYourEncryptedPassword
・初期設定ファイルの編集
オリジナル設定ファイルの内容をベースにしながら、次のように必要な設定を加えた。
設定内容の解説は下記の通り。
# vi /usr/local/etc/openldap/slapd.conf
include /usr/local/etc/openldap/schema/core.schema
pidfile /usr/local/var/run/slapd.pid
argsfile /usr/local/var/run/slapd.args
database config
rootdn cn=admin,cn=config
access to *
by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
by * break by * none
database mdb
maxsize 1073741824
suffix "dc=example,dc=co,dc=jp"
rootdn "cn=Manager,dc=example,dc=co,dc=jp"
rootpw {SSHA}HereLongStringsAsYourEncryptedPassword
directory /usr/local/var/openldap-data
index objectClass eq
(設定内容の説明)
初期投入する初期設定ファイルでは、「database config」項目でLDAP設定用ディレクトリに関する初期設定を行い、「database mdb」項目でデータディレクトリに関する初期設定を行う。
「database config」項目について:
・ rootdn cn=admin,cn=config
これは「設定ディレクトリ」の特権(管理者)を表すDNである。(後に登場する「データディレクトリ」の管理者と区別すること。)ここで設定するDNは「設定ディレクトリ」DIT内の特定のエントリを指定するものであることから、エントリによって管理者ユーザー名を表すと考えられる。
このように別個の外部ファイルにではなく、エントリでユーザーを定義する点が独特である。(LDAPサーバーが、ファイルシステムに似たLDAPディレクトリという仕組みを持つものでこういうことは自然なのかもしれない。)
設定用ディレクトリのDITの頂上(トップ)にあるエントリは「cn=config」というDNで指定され、その下位にさらにエントリ(cn=admin)が置かれ、この「cn=admin」エントリが設定ディレクトリの管理者ユーザーを定義するということだと考えられる。
ところで、この「設定ディレクトリ」の特権(管理者)は、ネットワーク経由でLDAPサーバーが設定されるときに使用される。実際の使用には別途パスワードの設定も行う必要がある。(この段階では、まだパスワードの設定はしていない。)
通常は、ローカルのLDAPサーバーの設定ディレクトリへのアクセスは、ネットワーク経由でのアクセスでなく「UNIXドメインソケット」経由で行う。そこではアクセス時にこの特権DNを指定することはない。
・ access to *
by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
上で述べた「UNIXドメインソケット」経由での設定ディレクトリへのアクセスを許可している。
「access to *」は、設定ディレクトリの全てのエントリが対象であることに言及。
「manage」は、管理者権限の付与について言及している。
「by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"」は、Linuxのrootユーザーへのその権限の付与を行うよう言及している。
「UNIXドメインソケット」経由での設定ディレクトリへのアクセスを行う具体的なコマンドについては別に扱うことにする。
「database mdb」項目について:
この項目では「データディレクトリ」の初期設定を定義している。
・ maxsize 1073741824
データベースの最大サイズをbyte単位で定める。(約1GBを指定している。)
・ suffix "dc=example,dc=co,dc=jp"
「データディレクトリ」ツリーを識別するDNを定める。ルートディレクトリに名前が付いたようなものである。通常、組織のドメイン名を使う。データディレクトリ内のデータに関するエントリは、このDNで指定されるエントリ(dc=example)の配下に置かれる。したがって、それらのデータに関するエントリを指定するDNは、このDN(dc=example,dc=co,dc=jp)をサフィックスとして含むことになる。httpでデータにアクセスするためのURLの構造に似ている。
・ rootdn "cn=Manager,dc=example,dc=co,dc=jp"
「データディレクトリ」の特権ユーザーを表すエントリを定義している。これは特権DNと呼ばれる。(「設定ディレクトリ」の特権DNとは別に定義されていることに注意する。)
・ rootpw {SSHA}HereLongStringsAsYourEncryptedPassword
特権DNのパスワードのハッシュ値を設定している。(最初にslappasswd で生成したハッシュ値のことである。)
・ directory /usr/local/var/openldap-data
データベースを保存するファイルシステム上のディレクトリの指定
・ index objectClass eq
データ検索の高速化に寄与するのがインデックス(いわゆる索引)というものである。インデックスを作成するため、元にする「属性」を指定する。
ここでは、エントリが持つ「objectClass」という属性の属性値について、等価であるかどうかの判断を高速化を図るためのインデックスが定義されている。
DIT(LDAPディレクトリツリー)にはいろいろなエントリにより構造化される。後で検索の対象となるデータを保持するエントリは「objectClass」属性を持ち、「objectClass」を指示している。「objectClass」はデータを格納する収納棚のようなもので、「objectClass」の種類によってその引き出しの数やラベリングが異なっている。
だから、データ検索には、まずターゲットとする棚である「objectClass」を早く見つけることが大切だと考えられる。そのため、インデックス(索引)が「objectClass」に関してそのように作成されるのだと考えられる。
(ここでは「objectClass」属性に対してのみインデックスを作成しているが、LDAPサーバーを利用するアプリケーションによっては、検索項目の属性についてもインデックスを作成した方が良いのだろうか。)
<4> 「設定ディレクトリ(config directory)」の作成
・必要なディレクトリの準備
# mkdir /usr/local/etc/openldap/slapd.d
# mkdir /usr/local/var/openldap-data
・設定ファイルをもとにして「設定ディレクトリ」を生成
# cd /usr/local/etc/openldap
# slaptest -f slapd.conf -F slapd.d
mdb_db_open: database "dc=example,dc=com" cannot be opened: No such file or directory (2). Restore from backup!
backend_startup_one (type=mdb, suffix="dc=example,dc=com"): bi_db_open failed! (2)
slap_startup failed (test would succeed using the -u switch)
設定ディレクトリの作成に成功すれば次のようにファイルが作られている。
# ls /usr/local/etc/openldap/slapd.d
■ slapdのためのsystemdユニットファイルの作成
ここの設定は、冒頭に挙げたインストール編で既に済ませている。
# vi /lib/systemd/system/slapd.service
[Unit]
Description=OpenLDAP Server
After=syslog.target network.target
[Service]
Type=forking
PIDFile=/usr/local/var/run/slapd.pid
ExecStart=/usr/local/libexec/slapd -h "ldap:/// ldapi:///"
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
■ slapd(OpenLDAP)の起動
# systemctl start rsyslog
# systemctl start slapd
# systemctl status slapd
● slapd.service - OpenLDAP Server
Loaded: loaded (/usr/lib/systemd/system/slapd.service; disabled; vendor preset: disabled)
Active: active (running) since Mon 2022-07-11 07:33:17 JST; 4s ago
Process: 234 ExecStart=/usr/local/libexec/slapd -h ldap:/// ldapi:/// (code=exited, status=0/SUCCESS)
Main PID: 235 (slapd)
CGroup: /docker/b34e14346f76dea9f5b6ee70fd236c4c1718f2107973b5f6688c9852ad5f20e0/system.slice/slapd.service
└─235 /usr/local/libexec/slapd -h ldap:/// ldapi:///
‣ 235 /usr/local/libexec/slapd -h ldap:/// ldapi:///
Jul 11 07:33:07 b34e14346f76 systemd[1]: Starting OpenLDAP Server...
Jul 11 07:33:07 b34e14346f76 slapd[234]: @(#) $OpenLDAP: slapd 2.5.12 (Jul 6 2022 07:01:28) $
root@89192c461c39:/root/Software/OpenLDAP/openldap-2.5.12/servers/slapd
Jul 11 07:33:17 b34e14346f76 systemd[1]: Started OpenLDAP Server.
# cat /usr/local/var/run/slapd.pid
◯ 自動的に起動するように設定しておく。
# systemctl enable slapd
■ 基本となるエントリの作成
ここではOpenLDAPサーバーの「データディレクトリ」に、基本である次の2つのエントリを作成する。
一つ目は、ディレクトリ空間のトップノードにあたるエントリである。
二つ目は、ルートDNのためのエントリである。
それぞれ、slapd.confで指定したデータディレクトリに関する内容(suffix、rootdn)と一致させておく。ここではslapd.confに次のように指定したのだった。
database mdb
maxsize 1073741824
suffix "dc=example,dc=co,dc=jp"
rootdn "cn=Manager,dc=example,dc=co,dc=jp"
rootpw {SSHA}HereLongStringsAsYourEncryptedPassword
directory /usr/local/var/openldap-data
index objectClass eq
これにもとづいて、次のように設定用のldifファイルを作成してOpenLDAPサーバーにコマンドで登録する。
◯ 設定用のldifファイルの作成
まとめて、2つのエントリの情報を含めている。
ファイル名は日付と通し番号をつけ、データディレクトリに関する設定であることと、その内容について簡単なメモを付けた。
こういう設定用ldifファイルは、適当な専用のディレクトリにまとめるようにすると良いと思う。そうすれば、あとでファイル一覧で履歴として見ることができる。
# vi 202207XX-001_DATA_init.ldif
dn: dc=example,dc=co,dc=jp
objectClass: organization
objectClass: dcObject
o: Example Co., Ltd
dc: example
dn: cn=Manager,dc=example,dc=co,dc=jp
objectClass: organizationalRole
cn: Manager
<設定の意味>
ここには私見、推測が含まれています。しかしエントリの設定について理解がしやすくなるので、次のようにエントリとその実体とに分けて考えています。エントリがエントリの実体をポイントしているととらえることと、ldifファイルではその両方をまとめて定めていると考えることが大切だと思います。
ここでは、2つのエントリについて、エントリのディレクトリツリー上での位置とその実体について設定している。
まず、それぞれのエントリが位置するパスを示すDN(区別する名前という意味)を指定している。
dn: dc=example,dc=co,dc=jp
dn: cn=Manager,dc=example,dc=co,dc=jp
このDNの末端(アンダーライン付きの要素)には「dc=example」と「cn=Manager」が指定されていて、これがそれぞれの(エントリの)実体を指し示すと考えられる。
実体をポイントするDN末端の「dc=example」や「cn=Manager」には、(エントリの)実体が保持するオブジェクトクラスの属性とその値と同じ組が使われている。そのため、このDN末端の「dc=example」や「cn=Manager」に合うように、(エントリの)実体としてそれぞれ次のように、オブジェクトクラスとその属性とその値が定義される必要がある。
オブジェクト指向プログラミングでは、このエントリは”参照”に相当すると考えられる。しかし、”参照”は任意の名称をもち階層構造にもなっていない。しかし、エントリはディレクトリツリーという階層構造中の一つであり、その名称は参照先の実体が持つ属性値と同じであるという特徴がある。その意味では、中途半端に参照(エントリ)とその実体が分かれており、文字通りわかりにくさがある。
(一つ目のエントリについての設定)
・dn: dc=example,dc=co,dc=jp
設定するエントリに至るパス(DN)を指定する。
・objectClass: organization
組織名を表す属性(o)を持つクラスである。
同じエントリで「o: Example Co., Ltd」のようにこの属性を設定しておく。
・objectClass: dcObject
ドメイン名を表す属性(dc)を持つクラスである。
今、エントリ「dc=example(,dc=co,dc=jp)」の設定を行っているので、上で述べたように、(エントリの)実体にはdc属性は必須である。そのため、dc属性を提供するこのクラス「objectClass: dcObject」が必要である。(さらに、その属性値も、すぐ下の「dc: example」で説明しているように、エントリとして使われているdc=exampleに一致させる。)
・o: Example Co., Ltd
「objectClass: organization」クラスの属性「o」の設定値である。
・dc: example
「objectClass: dcObject」クラスの属性「dc」の設定値である。
今、エントリ「dc=example(,dc=co,dc=jp)」の設定を行っているので、このdc属性値は「example」としておき、エントリ「dc=example(,dc=co,dc=jp)」と一致させておく。
(二つ目のエントリについての設定)
・dn: cn=Manager,dc=example,dc=co,dc=jp
設定するエントリに至るパス(DN)を指定する。
・objectClass: organizationalRole
役割(ロール)に関する情報を表すオブジェクトクラスで、名称を表す属性(cn)を持つクラスである。
今、エントリ「cn=Manager(,dc=co,dc=jp)」の設定を行っているので、上で述べたように、(エントリの)実体にはcn属性は必須である。また、このエントリはロールに関する情報を扱うため、cn属性を提供し、ロールに関する情報を定めるクラス「objectClass: organizationalRole」が必要である。(さらに、その属性値も、すぐ下で説明しているようにエントリとして使われているcn=Managerに一致させる。)
・cn: Manager
「objectClass: organizationalRole」クラスの属性「cn」の設定値である。
今、エントリ「cn=Manager(,dc=co,dc=jp)」の設定を行っているので、このcn属性値は「Manager」としておき、エントリ「cn=Manager(,dc=co,dc=jp)」と一致させておく。
◯ OpenLDAPサーバーに設定内容を登録する。
OpenLDAPサーバーを動作させておく。
# systemctl start slapd
次のように追加用コマンドで、先程作成した設定ファイルを指定し、含まれる2つのエントリを追加する。尋ねられれるパスワードは、slapd.confでrootpw項目に記述したハッシュに対応するプレインパスワードを指定する。
# ldapadd -x -D "cn=Manager,dc=example,dc=co,dc=jp" -W -f 202207XX-001_DATA_init.ldif
Enter LDAP Password: PlainPassword
adding new entry "dc=example,dc=co,dc=jp"
adding new entry "cn=Manager,dc=example,dc=co,dc=jp"
<オプションの意味>
・ -x
認証にはSASLを使わない。(simple authenticationを使う)
・ -D "cn=Manager,dc=example,dc=co,dc=jp"
認証するためにバインドするべきDNを指定する。
LDAPでは、クライアントの認証にバインドという手続きを用いる。
バインドによって認証されたクライアントはその権限の範囲でアクセスできる。
・ -W
simple authenticationの際に、パスワードの入力をダイアログ形式で行う。(コマンドラインに入れない)
・ -f 202207XX-001_DATA_init.ldif
エントリ変更用ファイルを指定する。(標準入力は使わない)
(エラーが出る場合)
・ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
→ slapdが起動していないので、あらかじめ起動しておく。
・ldapadd: invalid format (line 2) entry: "dc=example,dc=co,dc=jp"
→ 指定されたエントリの記述に誤りがある。(イコール、コロンの使い間違いとか)
以上で、基本的な初期設定は完了した。
必要に応じて、次のようにphpLDAPAdminというWEBベースクライアントもインストールしておく。
【Docker Linux CentOS 7】OpenLDAPのためにWEBベースクライアントphpLDAPAdminを導入する【phpLDAPAdmin 1.2.5】
後は、OpenLDAPの各々の利用目的に応じた設定を行うことになる。
■ ここまで構築してきたコンテナのイメージを作成しておく
◯ イメージの作成
・コンテナを終了した。
[root@89192c461c39 /]# poweroff
・コミットコマンドを実行してイメージを作成した。(Dockerホストにおいて)
# docker commit ldap_installed_initialized_centos7_priv image_centos7_openldap-ver-2.5.12_202207XX_installed_initialized
ldap_
installed_initialized_centos7_priv…ターゲットのコンテナ名称
image_centos7_openldap-ver-2.5.12_202207XX_installed_initialized…作成するイメージにつける名前
・イメージの確認
# docker image list
REPOSITORY TAG IMAGE ID CREATED SIZE
image_centos7_openldap-ver-2.5.12_202207XX_installed_initialized latest a8ab2cfbfe49 10 seconds ago 1.6GB
<参考>
・デージーネット. 入門LDAP/OpenLDAPディレクトリサービス導入・運用ガイド第3版. 秀和システム, 2017, 430p.
・Centralized authentication using OpenLDAP
< https://wiki.gentoo.org/wiki/Centralized_authentication_using_OpenLDAP/en > 2022年2月20
・そろそろLDAPにしてみないか? 第10回 OpenLDAPとACL
< https://gihyo.jp/admin/serial/01/ldap/0010 > 2022年4月6日
・サーバー管理の困った!を○○で解決 LDAPを使ったユーザー管理編
< https://www.nedia.ne.jp/blog/tech/2015/09/08/5570 > 2022年4月7日
・CentOS7 OpenLDAPの設定
< https://www.unix-power.net/networking/post-746 > 2022年2月20
・LDAP の設定と構成 / インデックス
< https://docs.oracle.com/cd/E19455-01/806-7089/6jg0449jq/index.html > 2022年4月7日
・OpenLDAPのindex設定
< https://qiita.com/morih90/items/0398f3dc4591b245a567 > 2022年4月7日
・OpenLDAPによるディレクトリサーバ運用(5) / ビシッと決めるチューニング:しっかり基本編
< https://atmarkit.itmedia.co.jp/ait/articles/1006/21/news102_3.html > 2022年4月7日
・OpenLDAP Manual Pages / ldapadd(1)
< https://www.openldap.org/software//man.cgi?query=ldapadd&sektion=1&apropos=0&manpath=OpenLDAP+2.4-Release > 2022年7月14日
・5.3.98. organizationalRole
< https://access.redhat.com/documentation/ja-jp/red_hat_directory_server/10/html/configuration_command_and_file_reference/organizationalrole > 2022年7月14日