私的サーバー構築日誌：LDAPサーバー OpenLDAP over TLS とログ確認

# 能書き

[私的サーバー構築日誌：仕切り直し](https://qiita.com/katz_engineer/items/1f21de2bd9072c260ae6)からの自宅サーバー構築の続きです。[以前](https://qiita.com/katz_engineer/items/0e2c299f943a7b13e2c4)も構築しました、その焼き直しになりますが、今回は手順など大幅に変更してお送りします。

それで、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 20.04 の頃の話ですけど、389-dsをインストールしようとすると依存パッケージが山程出てきてちょっと不気味。良く見るとApacheまで入ってるように見えました。見間違いでしょうか？しかしこれで使う気が失せました。

と言う訳で、OpenLDAPのサーバーをDockerコンテナで立ち上げます。手順は探せば日本語の記事も見つかりました。

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

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

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

# 目標

- OpenLDAPサーバーをDockerコンテナで立てる。そしてログ確認。
- LDAP over TLS を設定。そしてクライアントマシン代わりにLXDコンテナからアクセス。
- 便利なGUIツールは使いません。これは私のコダワリです。

# 参考文献

## LDAPサーバーとDockerコンテナ

- [docker-composeでGUI管理できるLDAPサーバをサクッと立てる - Qiita](https://qiita.com/luhoriuchi/items/bf29f886a78a3500e759)

## 基本的なインストールと設定

- [自宅サーバー構築譚：LDAPサーバー OpenLDAP・インストールとログ出力 - Qiita](https://qiita.com/katz_engineer/items/0e2c299f943a7b13e2c4)
- [自宅サーバー構築譚：LDAPサーバー OpenLDAP over TLS - Qiita](https://qiita.com/katz_engineer/items/c7445176881900120d03)
- [自宅サーバー構築譚：LDAPサーバー OpenLDAP - Qiita](https://qiita.com/katz_engineer/items/729645f6bca28f4a3708)
- [私的サーバー構築日誌：オレオレ認証局が認証する証明書 - Qiita](https://qiita.com/katz_engineer/items/fe954644fa570093ca3a) … 通信暗号化の鍵の作成手順です。
- [自宅サーバー構築譚：LXDでcloud-initによる初期設定の自動化 - Qiita](https://qiita.com/katz_engineer/items/7ac5cadce3bdde9c76dc) … ちょっとイタズラで、cloud-initでクライアントとなるコンテナを設定してみます。
- [LDAP検索ツール ldapsearch の覚書 - Qiita](https://qiita.com/slotport/items/31259f218e4dcec381d4#fn-pass) … ```ldapsearch```コマンドの引数の覚え書きです。助かります。

## ログ

- [Dockert調査　~ログ編~ - Qiita](https://qiita.com/HommaHomma/items/f943fa3397bc3f386057)
- [OpenLDAP のログの見方、確認、解析方法 - 【図解】ネットワーク/サーバ/セキュリティの基礎から応用まで](https://milestone-of-se.nesuke.com/l7protocol/ldap/openldap-log/)
- [私的サーバー構築日誌：rsyslogとlogrotateとlogger - Qiita](https://qiita.com/katz_engineer/items/7a1c16b086a832d9ca8b) … rsyslogの使い方を調べましたが、今回は結局使いませんでした。しかし鍵作成などで参照します。

## LDAP 一般論

- [OpenLDAPで社内サービスのユーザ情報を一元管理する - Qiita](https://qiita.com/jca02266/items/bf00acf88fde8bc29775) … LDAP 利用における実践的内容の紹介です。参考になります。

# Dockerコンテナ

## 準備

場所は[前回検討した通り](https://qiita.com/katz_engineer/items/24b7732cd13606c78ce2#docker%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AE%E7%BD%AE%E3%81%8D%E5%A0%B4%E6%89%80)です。Dockerコンテナの場所は、[管理者アカウント](https://qiita.com/katz_engineer/items/667aefcab488cc4a1caf#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90)の```$HOME/docker-slapd```ディレクトリとします。

```console:ホスト側
cd
mkdir docker-slapd
cd docker-slapd
mkdir -p data/certs
mkdir data/config
mkdir data/db
mkdir data/ldif
```

```docker-compose.yml```ファイルは下記のようにします。各環境変数などの値は、環境に合わせて適当に変えて下さい。特に```admin_password```や```readonly_password```など。

```console:ホスト側
cat <<___ >docker-compose.yml
version: '3.8'
services:
  slapd:
    image: osixia/openldap:latest
    container_name: slapd
    restart: unless-stopped
    hostname: primary.home
    ports:
      - 636:636
    environment:
      LDAP_ORGANISATION: "Example Home."
      LDAP_DOMAIN: "home"
      LDAP_ADMIN_PASSWORD: "admin_password"
      LDAP_READONLY_USER: "true"
      LDAP_READONLY_USER_USERNAME: "readonly"
      LDAP_READONLY_USER_PASSWORD: "readonly_password"
      LDAP_TLS_VERIFY_CLIENT: "never"
      LDAP_TLS_CRT_FILENAME: "primary.home.crt"
      LDAP_TLS_KEY_FILENAME: "primary.home.key"
      LDAP_TLS_CA_CRT_FILENAME: "demoCA.crt"
    volumes:
      - ./data/db:/var/lib/ldap
      - ./data/config:/etc/ldap/slapd.d
      - ./data/certs:/container/service/slapd/assets/certs
      - ./data/ldif:/root/ldif
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
___
```

## 通信暗号化の為の鍵

[以前、rsyslogの通信暗号化で鍵を作りました](https://qiita.com/katz_engineer/items/7a1c16b086a832d9ca8b#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E9%8D%B5%E3%81%AE%E9%85%8D%E7%BD%AE)。今回はこれを流用します。

認証局：

- 秘密鍵 ```/home/cert/demoCA/pki/private/ca.key```
- 公開鍵 ```/home/cert/demoCA/pki/ca.crt```

サーバーマシンprimary.homeの証明書：

- 秘密鍵 ```/home/cert/demoCA/pki/private/primary.home.key```
- 公開鍵 ```/home/cert/demoCA/pki/issued/primary.home.crt```

参照する鍵とその置き場所は、上述の```docker-compose.yml```の記述通りです。

- 認証局の公開鍵 ```ca.crt```
- 証明書の公開鍵 ```primary.home.crt```
- 証明書の秘密鍵 ```primary.home.key```
- 置き場所 ```$HOME/data/certs```

鍵を置き場所にコピーするには、下記手順にします。これも[以前のrsyslogの記事の通り](https://qiita.com/katz_engineer/items/7a1c16b086a832d9ca8b#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E9%8D%B5%E3%81%AE%E9%85%8D%E7%BD%AE)です。

```console:ホスト側
sudo -u cert cp -p /home/cert/demoCA/pki/ca.crt /tmp/demoCA.crt
```

```console:ホスト側
sudo -u cert cp -p /home/cert/demoCA/pki/issued/primary.home.crt /tmp
```

```console:ホスト側
sudo -u cert cp -p /home/cert/demoCA/pki/private/primary.home.key /tmp
```

```console:ホスト側
sudo mv /tmp/demoCA.crt /tmp/primary.home.crt /tmp/primary.home.key ~/docker-slapd/data/certs
```

## 起動

```console:ホスト側
cd
cd docker-slapd
docker compose up -d
```

```~/data/ldif```だけは自動では権限が設定されないようです。他は大丈夫の模様。

```console:ホスト側
sudo chown root:root data/ldif
```

# LXDコンテナ

## オレオレ認証局を信頼

信頼対象のオレオレ認証局、その公開鍵を用意します。

```console:ホスト側
sudo -u cert cp -p /home/cert/demoCA/pki/ca.crt /tmp/demoCA.crt
```

```console:ホスト側
sudo chown root: /tmp/demoCA.crt
```

```console:ホスト側
sudo chmod 644 /tmp/demoCA.crt
```

クライアントマシン代わりのLXDコンテナです。

```console:ホスト側
lxc init images:ubuntu/jammy/cloud ldap-client --device eth0,ipv4.address=192.168.0.2
```

オレオレ認証局の公開鍵をLXDコンテナに仕込みます。

```console:ホスト側
lxc file push /tmp/demoCA.crt ldap-client/usr/share/ca-certificates/demoCA/demoCA.crt -p
sudo rm /tmp/demoCA.crt
```

[LXDコンテナの初期化手順を設定](https://qiita.com/katz_engineer/items/7ac5cadce3bdde9c76dc)。

```console:ホスト側
lxc config set ldap-client cloud-init.user-data="$(cat <<___
#cloud-config
timezone: Asia/Tokyo
locale: ja_JP.utf8
package_upgrade: true
packages:
  - ldap-utils
runcmd:
  - echo demoCA/demoCA.crt >>/etc/ca-certificates.conf
  - [update-ca-certificates]
___
)"
```

起動。

```console:ホスト側
lxc start ldap-client
```

LXDコンテナの初期化が終わるのを待ちます。

```console:ホスト側
lxc exec ldap-client -- cloud-init status --wait
```

初期化が終わったら、証明書（というか認証局）を信頼した事を確認します。

```console:ホスト側
lxc exec ldap-client -- ls -l /etc/ssl/certs/ | grep demoCA
```

## LDAP動作確認

下記コマンドを実行してみます。

```console:ホスト側
lxc exec ldap-client -- ldapsearch -x -LLL -H ldaps://primary.home -b dc=home -D cn=readonly,dc=home -W
```

パスワード入力後、ちょっとだけ表示されます。

```console:ホスト側
$ lxc exec ldap-client -- ldapsearch -x -LLL -H ldaps://primary.home -b dc=home -D cn=readonly,dc=home -W
Enter LDAP Password:
dn: dc=home
objectClass: top
objectClass: dcObject
objectClass: organization
o: Example Home.
dc: home

dn: cn=readonly,dc=home
cn: readonly
objectClass: simpleSecurityObject
objectClass: organizationalRole
userPassword:: e1NTSEF9bUtFWmZoRlM4emQ3SGNuMi90a2JEZ3A0alZjdDYreWk=
description: LDAP read only user

```

Dockerコンテナ側のログを確認してみます。

```console:ホスト側
docker logs slapd 2>&1 | grep -A 100 "ACCEPT from IP="
```

LXDコンテナからの問合せが届いていれば、こんな感じになるでしょう。

```console:ホスト側
$ docker logs slapd 2>&1 | grep -A 100 "ACCEPT from IP="
654a0147 conn=1000 fd=12 ACCEPT from IP=172.20.0.1:36158 (IP=0.0.0.0:636)
654a0147 conn=1000 fd=12 TLS established tls_ssf=256 ssf=256
654a0147 conn=1000 op=0 BIND dn="cn=readonly,dc=home" method=128
654a0147 conn=1000 op=0 BIND dn="cn=readonly,dc=home" mech=SIMPLE ssf=0
654a0147 conn=1000 op=0 RESULT tag=97 err=0 text=
654a0147 conn=1000 op=1 SRCH base="dc=home" scope=2 deref=0 filter="(objectClass=*)"
654a0147 conn=1000 op=1 SEARCH RESULT tag=101 err=0 nentries=2 text=
654a0147 conn=1000 op=2 UNBIND
654a0147 conn=1000 fd=12 closed
```

# 仕舞い

実験に使った、クライアントマシン代わりのLXDコンテナは削除しましょう。

```console:ホスト側
lxc stop ldap-client
lxc rm ldap-client
```

LDAPサーバーをDockerコンテナで立てて、通信路を暗号化し、ログを記録・確認する事に成功しました。きちんとしたドメイン管理への第一歩です。