自宅サーバー構築譚：LDAPサーバー OpenLDAP

# 能書き

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築の続き。

CentOS方面の話ですが、現在、OpenLDAPは非推奨になっているようです。

参考文献：[9.2. OPENLDAP - 9. LDAP サーバー - II. ID と認証ストア - システムレベルの認証ガイド - Product Documentation for Red Hat Enterprise Linux 7](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system-level_authentication_guide/openldap)

代わりに 389 Directory Server （通称 389-ds）というソフトが標準となるようです。理由は明示されてませんが、OpenLDAPは重いからじゃないかという意見も。調査によっては動作が4倍以上遅いとかいう数字も見かけました。

しかし Ubuntu で 389-ds をインストールしようとすると、依存パッケージが山程出てきてちょっと不気味。良く見ると Apache まで入ってるように見えました。見間違いでしょうか？しかしこれで使う気が失せました。

と言う訳で Ubuntu に OpenLDAP をインストールします。

それにしても LDAP という規格は参考文献が少なくて苦労しました。ネットで幾ら調べても、ごく大雑把な概念説明と、こうやったら上手くいきましたというノウハウしか出てこなくて。その間を埋める知識がわかりません。仕方が無いので本を買いました。それも2007年の本、新品ではなくて古本屋での購入です。関係者の皆様スミマセン。

どうやら LDAP も、近々着手予定の Kerberos も、エンタープライズでの利用が一般的なせいかあんまり記事がありませんな。誰か中級者向け記事を書いてください（切実）

本記事もノウハウ寄りになります。理論は参考書を購入して勉強して下さい。古～い規格なので、十数年前の古～い参考書も現役で役に立ちます。

参考文献：[OpenLDAP Server - Ubuntu Server](https://ubuntu.com/server/docs/service-ldap) … 今時はブラウザが自動翻訳してくれたりします。英語の文献でも怖くありません。良い時代になりましたな。
参考文献：[OpenLDAP : LDAP サーバーの設定 - Server World](https://www.server-world.info/query?os=Ubuntu_20.04&p=openldap)
参考文献：[Ubuntu 20.04 LTS にOpenLDAPサーバーを構築したい - Qiita](https://qiita.com/cffnpwr/items/be903005e291d0ece514)

# インストール

## スナップショット

[スナップショットだいじ。超だいじ。](https://qiita.com/katz_engineer/items/f3bd2f7af2ba49db156c#%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)

```console
zfs snapshot tank/main/ubuntu@$(date +%Y%m%d_%H%M%S)_before_OpenLDAP
```

## インストール

```console
apt install -y slapd ldap-utils
```

インストール中に LDAP 管理者のパスワードを求められました。管理者パスワードなので root 並にしっかりした物にしましょう。

```console
┌─────────────────────────┤ Configuring slapd ├─────────────────────────┐
│ Please enter the password for the admin entry in your LDAP directory. │
│                                                                       │
│ Administrator password:                                               │
│                                                                       │
│ _____________________________________________________________________ │
│                                                                       │
│                                 <Ok>                                  │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘
```

同じパスワードをもう一回入力します。

```console
┌─────────────────────────────────────┤ Configuring slapd ├────────────────────────────────────────────┐
│ Please enter the password for your LDAP directory again to verify that you hanve typed it correctly. │
│                                                                                                      │
│ Confirm password:                                                                                    │
│                                                                                                      │
│ ____________________________________________________________________________________________________ │
│                                                                                                      │
│                                             <Ok>                                                     │
│                                                                                                      │
└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
```

これで最後までインストールが完了します。

インストール直後の ```/etc``` をバージョン管理します。まずは確認。

```console
svn st /etc
```

こう表示されました。

```console
# svn st /etc
?       /etc/apparmor.d/local/usr.sbin/slapd
?       /etc/apparmor.d/usr.sbin.slapd
?       /etc/default/slapd
M       /etc/group
M       /etc/gshadow
?       /etc/hosts.allow
?       /etc/hosts.deny
?       /etc.init.d/slapd
M       /etc/ld.so.cache
?       /etc/ldap/sasl2
?       /etc/ldap/schema
?       /etc/ldap/slapd.d
M       /etc/passwd
?       /etc/perl
?       /etc/rc0.d/K01slapd
?       /etc/rc1.d/K01slapd
?       /etc/rc2.d/K01slapd
?       /etc/rc3.d/K01slapd
?       /etc/rc4.d/K01slapd
?       /etc/rc5.d/K01slapd
?       /etc/rc6.d/K01slapd
M       /etc/shadow
?       /etc/ufw/applications.d/slapd
M       /etc/zfs/zpool.cache
```

目新しいのは ```/etc/hosts.allow``` ```/etc/hosts.deny``` でしょうか。なぜ今更出てきたのかと思ったら、OpenLDAP は TCPWrapper によるアクセス制御が可能らしい。

と言う訳で確認できた事にして```svn commit```します。

```console
svn st /etc | grep "^?" | cut -b9- | xargs -I{} find {} -type f -or -type d -or -type l | xargs -t svn add
svn ci /etc -m"installed OpenLDAP"
```

参考文献：[TCP Wrapperを用いたアクセス制限 - 考えておこう！ OpenLDAPのセキュリティ設定 - OpenLDAPで始めるディレクトリサーバ構築（4） - @IT](https://atmarkit.itmedia.co.jp/ait/articles/0901/21/news123.html)

それから DIT サフィックス(dc)を設定します。インストール直後に設定されているのは nodomain ですので、[Unbound を立てた時に決めた家庭内ドメイン](https://qiita.com/katz_engineer/items/241c3667cae2e742d54f#%E5%AE%B6%E5%BA%AD%E5%86%85%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3)へと変更します。
我が家の場合は home ですな。

また、同時に組織単位(ou)も登録します。というかこのコマンドを実行すると組織単位の設定も要求されます。
下記の参考文献に則って、ここでは infra を作成します。

参考文献：[LDAPディレクトリの構成、ACLについて - CentOS7でOpenldap構築 - 1.Openldapの仕組み - Qiita](https://qiita.com/y-araki-qiita/items/0c954c3ae25d4ed9dbb8#ldap%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%81%AE%E6%A7%8B%E6%88%90acl%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

```console
dpkg-reconfigure slapd
```

設定できたら```svn commit```しましょう。

```console
svn st /etc
svn ci /etc -m"OpenLDAP initial setting"
```

## ファイルディスクリプタ上限値の設定

家庭向け小規模システムなので、このチューニングは実施しません。[メインの参考文献](https://ubuntu.com/server/docs/service-ldap)にも書かれていませんし。
関連する参考文献の提示だけにしておきます。

参考文献：[ファイルディスクリプタ上限値の設定 - LDAPサーバ構築 - CentOS7でOpenldap構築 - 2.LDAPサーバ構築手順](https://qiita.com/y-araki-qiita/items/6b2dcbf1a39a969d8024#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%87%E3%82%A3%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%82%BF%E4%B8%8A%E9%99%90%E5%80%A4%E3%81%AE%E8%A8%AD%E5%AE%9A)
参考文献：[Linux ファイル・ディスクリプタ制限のチューニング - Oji-Cloud](https://oji-cloud.net/2022/03/16/post-6951/)
参考文献：[5.4 運用時に必要なシステム資源(Linux) - 第5章 チューニング - Interstage HTTP Server 2.2 運用ガイド](https://software.fujitsu.com/jp/manual/manualfiles/m170006/b1ws1309/01z200/index.html)

# インストール後のチェック

私は誰でしょう。

```console
ldapwhoami -x
```

この結果は anonymous と表示されます。匿名ユーザーです。

この匿名ユーザがアクセス可能な範囲で、home ドメインに登録されている情報を表示してみます。

```console
ldapsearch -x -LLL -H ldap:/// -b dc=home
```

実行結果は下記のようになります。

```console
dn: dc=home
objectClass: top
objectClass: dcObject
objectClass: organization
o: infra
dc: home

dn: cn=admin,dc=home
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
```

```slapcat``` というコマンドもあります。が、私もまだ勉強不足で、コマンドの違いはわかりません。

```console
slapcat
```

取り敢えず結果は下記のようになり、もっと細かい情報まで表示されました。

```console
dn: dc=home
objectClass: top
objectClass: dcObject
objectClass: organization
o: infra
dc: home
structuralObjectClass: organization
entryUUID: 68b754a4-49cf-103c-8b6a-c959e410f364
creatorsName: cn=admin,dc=home
createTimestamp: 20220406082924Z
entryCSN: 20220406082924.154097Z#000000#000#000000
modifiersName: cn=admin,dc=home
modifyTimestamp: 20220406082924Z

dn: cn=admin,dc=home
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e1NTSEF9ekcwNmk4Ny9OZjdEL3RGUlhDcHRWV5hxaVZiaGo0b4c=
structuralObjectClass: organizationalRole
entryUUID: 68b80e6c-49cf-103c-8b6b-c959e410f364
creatorsName: cn=admin,dc=home
createTimestamp: 20220406082924Z
entryCSN: 20220406082924.158993Z#000000#000#000000
modifiersName: cn=admin,dc=home
modifyTimestamp: 20220406082924Z
```

SASL 接続で、インストール時に設定したユーザ admin.home でパイントする事も出来るようです。当然パスワード入力を求められますが。

```console
ldapwhoami -Y EXTERNAL -H ldapi:/// -Q -D cn=admin,dc=home -W
```

結果はこうなります。

```console
Enter LDAP Password:
dn:gidNumber0+uidNumber=0,cn=peercred,cn=external,cn=auth
```

これ以上の詳細は私も良く分かりません。色々と勉強が進んだらまた少し書き足すかも知れませんが、今はこの辺で勘弁して下さい。

# データベースの変更と入力

## 管理者パスワード変更

admin.home のパスワードは下記コマンドで変更できます（```cn=config```の rootDN とは別）

```console
ldappasswd -x -D cn=admin,dc=home -W -S
```

## ユーザー登録の準備

ldif ファイルは```/opt/ldap/ldif```ディレクトリを作成して、そこに保管する事にしました。

こういうのは```/root/ldif```ディレクトリにする事例が多いようですが、何でも root に情報を集めてしまうのもどうかと考えました。

ひとまず root として```/opt/ldap/ldif```を作成します。ディレクトリのアクセス権限は後日見直す事にします。

```console
mkdir -p /opt/ldap/ldif
```

## 標準スキーマ追加

基本となる組織単位を登録します。

```console
cat >/opt/ldap/ldif/base.ldif <<___
dn: ou=people,dc=home
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=home
objectClass: organizationalUnit
ou: groups 
___
```

```console
ldapadd -x -D cn=admin,dc=home -W -f /opt/ldap/ldif/base.ldif
```

## 一般ユーザー登録

例えばアカウント名を taro、姓を familyname、パスワードを適当に生成した8文字 Ma9H%6jg とする場合。
更に uid と gid を決めます。

参考文献：[OpenLDAP : ユーザーアカウントを追加する - Server World](https://www.server-world.info/query?os=Ubuntu_20.04&p=openldap&f=2)

```console
ACCOUNT=taro
SURNAME=familyname
PASSWORD=Ma9H%6jg
USERID=2000
GROUPID=2000
cat >/opt/ldap/ldif/user_$ACCOUNT.ldif <<___
dn: uid=$ACCOUNT,ou=people,dc=home
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: $ACCOUNT
cn: $ACCOUNT
sn: $SURNAME
userPassword: $(slappasswd -T <(echo -n $PASSWORD))
loginShell: /bin/bash
uidNumber: $USERID
gidNumber: $GROUPID
homeDirectory: /home/$ACCOUNT

dn: cn=$ACCOUNT,ou=groups,dc=home
objectClass: posixGroup
cn: $ACCOUNT
gidNumber: $GROUPID
memberUid: $ACCOUNT

___
```

```console
ldapadd -x -D cn=admin,dc=home -W -f /opt/ldap/ldif/user_$ACCOUNT.ldif
```

ユーザーとグループが追加された事を確認します。

```console
cat <(ldapsearch -x -LLL -H ldap:/// -b uid=$ACCOUNT,ou=people,dc=home) <(ldapsearch -x -LLL -H ldap:/// -b cn=$ACCOUNT,ou=groups,dc=home) | diff -s -U0 /opt/ldap/ldif/user_$ACCOUNT.ldif -
```

## 一般ユーザーの変更

例えば taro のログインシェルを```/bin/sh```に、ホームディレクトリを```/home/everyone```に変更したい場合。

```console
cat >/opt/ldap/ldif/user_taro_01.ldif <<___
dn: uid=taro,ou=people,dc=home
changetype: modify
replace: loginShell
loginShell: /bin/sh
-
replace: homeDirectory
homeDirectory: /home/everyone
___
```

```console
ldapmodify -x -D cn=admin,dc=home -W -f user_taro_01.ldif
```

確認。

```console
ldapsearch -x -LLL -H ldap:/// -b uid=taro,ou=people,dc=home
```

## 一般ユーザーの削除

お世話になった taro を削除しましょう。

```console
ldapdelete -x -D cn=admin,dc=home -W uid=taro,ou=people,dc=home
```

```ldapmodify```コマンドで削除する方法もあるようですが、そちらは必要ならば調べて下さい。

# 仕舞い

今回 LDAP を勉強してわかりました。 LDAP というのはデータベースです。

いや当たり前なんですけども、つまり、信頼性を確保する為に運用までキチンと計画して実施する事が肝要です。具体的にはログやバックアップや復元や、更には多重化やらスケーリングやらですな。

その点で色々と足りてない感は否めません。そういった運用の充実はいずれゆっくり着手する事にします。今回は零細システムにおけるアカウント管理に限定するという事で、この辺で許して下さい。

ともあれ、きちんとしたドメイン管理へ第一歩を踏み出しました。やったね:thumbsup_tone1: