自宅サーバー構築譚：LXDコンテナにDovecotをインストール / SSSDでLDAPと連携

# 能書き

[自宅サーバー構築譚：基本構想](https://qiita.com/katz_engineer/items/cb592be44daa28a51d9b)に基づく自宅サーバー構築、[Ubuntu22.04LTSインストールその2](https://qiita.com/katz_engineer/items/033471b69143bf76650e)の続きです。

[前回](https://qiita.com/katz_engineer/items/2fdb627714c6967019f5)と[前々回](https://qiita.com/katz_engineer/items/9e8716c8bdf2bb1a54a8)でDovecotの基本的な設定は終わりましたが、今回はSSSDを設定してLDAPユーザーもメールを受信できるようにします。

# 目標

- Dovecotが動いているLXDコンテナにSSSDをインストールしてLDAPと連携させる。
- LDAPで登録したアカウントにメールを送信し、受信を確認する。

# 参考文献

- [自宅サーバー構築譚：LDAPサーバー OpenLDAP・SSSD を利用したログイン・Xubuntu 22.04 LTS - Qiita](https://qiita.com/katz_engineer/items/e51104d04549dcf2842c)
- [自宅サーバー構築譚：LAN内DNSサーバー Unbound・Ubuntu 22.04 - Qiita](https://qiita.com/katz_engineer/items/4e29b954e0290621c1ab#systemd-resolved-%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%92%E5%A4%89%E6%9B%B4)
- [自宅サーバー構築譚：LXD - Qiita](https://qiita.com/katz_engineer/items/74d7b357750e51e9c61c#%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%AB%E6%8E%A5%E7%B6%9A)
- [自宅サーバー構築譚：LXDコンテナにDovecotをインストール / LMTP](https://qiita.com/katz_engineer/items/9e8716c8bdf2bb1a54a8)
- [自宅サーバー構築譚：LXDコンテナにDovecotをインストール / IMAP](https://qiita.com/katz_engineer/items/2fdb627714c6967019f5)

# スナップショット

コンテナdovecot1（IPアドレス192.168.0.4）について、まずは現時点でのスナップショットを撮ります。

まずはコンテナ名とIPアドレスを変数に設定。ここは環境に合わせた値を設定して下さい。

```console:ホスト側
CONTAINER=dovecot1
IPADDRESS=192.168.0.4
```

スナップショット名はbefore_SSSDとします。

```console:ホスト側
SSNAME=before_SSSD
```

コンテナを停止してスナップショットを撮ります。稼働中でも撮れるようですが、変に面倒臭い何かが起こってもイヤなので。

```console:ホスト側
lxc stop $CONTAINER
lxc snapshot $CONTAINER $SSNAME
```

スナップショットの一覧表示。

```console:ホスト側
lxc info $CONTAINER
```

スナップショットの操作が終わったら、起動させましょう。

```console:ホスト側
lxc start $CONTAINER
```

# 名前解決の確認

LXDコンテナのDNSはホストマシンに向いているようです。何も設定しなくても[ホストマシン名`secondary.home`](https://qiita.com/katz_engineer/items/4e29b954e0290621c1ab#%E5%86%85%E5%90%91%E3%81%8Ddns)を解決できます。

```console:コンテナ内
lxc exec $CONTAINER -- ping -c2 secondary.home
```

外の名前も解決できます。例えば`example.com`など。

```console:コンテナ内
lxc exec $CONTAINER -- ping -c2 example.com
```

# SSSD インストールと設定

## インストール

まずはコンテナに入ります。

```console:ホスト側
lxc shell $CONTAINER
```

クライアントマシンに関連パッケージをインストールします。

```console:コンテナ内
apt install -y sssd-ldap
```

`/etc`の差分を確認します。

```console:コンテナ内
svn st /etc
```

今回の`/etc`差分は下記の通り。

```console:コンテナ内
# svn st /etc
?       /etc/apparmor.d/force-complain/usr.sbin.sssd
?       /etc/apparmor.d/local/usr.sbin.sssd
?       /etc/apparmor.d/usr.sbin.sssd
?       /etc/cracklib
?       /etc/cron.daily/cracklib-runtime
?       /etc/default/sssd
M       /etc/group
M       /etc/gshadow
?       /etc/init.d/sssd
M       /etc/ld.so.cache
?       /etc/libnl-3
?       /etc/logcheck/ignore.d.paranoid
?       /etc/logrotate.d/sssd-common
?       /etc/magic
?       /etc/magic.mime
M       /etc/nsswitch.conf
M       /etc/pam.d/common-account
M       /etc/pam.d/common-auth
M       /etc/pam.d/common-password
M       /etc/pam.d/common-session
?       /etc/pam.d/sssd-shadowutils
M       /etc/passwd
?       /etc/rc0.d/K01sssd
?       /etc/rc1.d/K01sssd
?       /etc/rc2.d/S01sssd
?       /etc/rc3.d/S01sssd
?       /etc/rc4.d/S01sssd
?       /etc/rc5.d/S01sssd
?       /etc/rc6.d/K01sssd
?       /etc/security/pwquality.conf
M       /etc/shadow
?       /etc/sssd
?       /etc/systemd/system/multi-user.target.wants/sssd.service
?       /etc/systemd/system/sssd.service.wants
```

これらの検討は、今回もサボります。面倒臭くなりました。このままSubversion登録します。

```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"SSSD install"
```

## 初期設定

コンテナ内のSSSDを初期設定します。
`/etc/sssd/sssd.conf`を作成し、パーミッションを`0600`、所有権を`root:root`にします。
なおLDAPサーバーは`secondary.home`とします。

```console:コンテナ内
cat >/etc/sssd/sssd.conf <<___
[sssd]
config_file_version = 2
domains = home

[domain/home]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://secondary.home
cache_credentials = True
ldap_search_base = dc=home
___
chmod 600 /etc/sssd/sssd.conf
```

```console:コンテナ内
svn add /etc/sssd/sssd.conf
svn ci /etc -m"add SSSD setting"
```

後でコンテナを再起動させるので、この時点での`sssd`の起動は省略します。

ホームディレクトリの自動作成を有効にします。

```console:コンテナ内
pam-auth-update --enable mkhomedir
```

これによって変化する設定がありますので、ここでもSubversion登録しておきます。

```console:コンテナ内
svn ci /etc -m"setting mkhomedir"
```

ここまで出来たら、一度コンテナを抜けます。

```console:コンテナ内
exit
```

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

### 鍵の配置

[以前の鍵作成](https://qiita.com/katz_engineer/items/e51104d04549dcf2842c#%E9%8D%B5%E3%81%AE%E9%85%8D%E7%BD%AE)の通りならば、ホスト側に下記のように認証局と証明書の鍵が配置されています。

認証局：

- 秘密鍵 `/opt/CA/demoCA/pki/private/ca.key`
- 公開鍵 `/opt/CA/demoCA/pki/ca.crt`

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

- 秘密鍵 `/opt/CA/demoCA/pki/private/secondary.home.key`
- 公開鍵 `/opt/CA/demoCA/pki/issued/secondary.home.crt`

[コンテナへは認証局の公開鍵`ca.crt`を送付して信頼します](https://qiita.com/katz_engineer/items/e51104d04549dcf2842c#%E3%82%AA%E3%83%AC%E3%82%AA%E3%83%AC%E8%AA%8D%E8%A8%BC%E5%B1%80%E3%82%92%E4%BF%A1%E9%A0%BC)。

### オレオレ認証局の公開鍵を信頼

[必要な手順を一気に操作します](https://qiita.com/katz_engineer/items/e51104d04549dcf2842c#%E3%82%AA%E3%83%AC%E3%82%AA%E3%83%AC%E8%AA%8D%E8%A8%BC%E5%B1%80%E3%82%92%E4%BF%A1%E9%A0%BC)。

まずはディレクトリを作成。

```console:ホスト側
lxc exec $CONTAINER mkdir /usr/share/ca-certificates/demoCA
```

オレオレ認証局の公開鍵をコンテナ内に送付。

```console:ホスト側
sudo lxc file push /opt/CA/demoCA/pki/ca.crt $CONTAINER/usr/share/ca-certificates/demoCA/demoCA.crt
```

公開鍵を追記して処理します。

```console:ホスト側
lxc exec $CONTAINER -- tee -a /etc/ca-certificates.conf <<< demoCA/demoCA.crt
lxc exec $CONTAINER update-ca-certificates
```

ここでも`/etc`に変化があります。

```console:コンテナ内
lxc exec $CONTAINER svn st /etc | grep "^?" | cut -b9- | xargs -I{} lxc exec $CONTAINER -- find {} -type f -or -type d -or -type l | xargs -t lxc exec $CONTAINER svn add
```

```console:コンテナ内
lxc exec $CONTAINER -- svn ci /etc -m"ssl settings"
```

### コンテナを再起動

ここまで出来たらコンテナを再起動します。

```console:ホスト側
lxc restart $CONTAINER
```

## LDAPユーザーでログイン

コンテナのコンソールに接続して、一度、ログインします。ログインする事によってホームディレクトリも作られます。

[以前の設定](https://qiita.com/katz_engineer/items/693ab241fc6aa8452b0d#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D)の通りならば、LDAPにはユーザー名`taro`が登録されています。

```console:ホスト側
USERID=taro
```

下記のコマンドならば`taro`のパスワード入力は省略できます。

```console:サーバー側
lxc exec $CONTAINER -- login -f $USERID
```

成功すれば下記のように表示され、よく見ると最後に`Creating directory '/home/taro'.`というメッセージが表示されています。

```console:サーバー側
$ lxc exec $CONTAINER -- login -f $USERID
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-71-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

Creating directory '/home/taro'.
```

特にする事も無いので、確認できたら`exit`しましょう。

```console:コンテナ内
exit
```

残念ながら`login`コマンドはコンソールからの入出力しか受け付けないようです。`exit`は手で入力しなければなりません。自動化できませんね。残念。

# LDAPユーザーのメールの確認

## 送信

LDAPユーザー`taro`のホームディレクトリが作成されたら、dovecotでメール配送できる筈です。

[以前の設定](https://qiita.com/katz_engineer/items/9e8716c8bdf2bb1a54a8)の通りならば、ポート番号は24になります。

```console:ホスト側
LMTP_PORT=24
```

メールを送信します。

```console:ホスト側
nc -C 172.16.1.3 $LMTP_PORT <<___
lhlo sender.home
mail from:<test@sender.home>
rcpt to:<$USERID@secondary.home>
data
From: test@sender.home
To: $USERID@secondary.home
Subject: test mail

hello, world
.
quit
___
```

## 着信確認

メールが正しく届いていれば、LDAPユーザー`taro`に対してもIMAPで確認できる筈です。

```console:ホスト側
IMAPS_PORT=993
```

```console:ホスト側
openssl s_client -connect 172.16.1.3:$IMAPS_PORT
```

```console:openssl
1 login taro Ma9H%6jg
2 list "" *
3 select INBOX
4 fetch 1 body[]
5 logout
```

# 仕舞い

これでLDAPユーザーへのメールも取り扱えるようになりました。やったね:thumbsup_tone1: