389DSでSambaとSSHをLDAP認証する(SSL/TLSなし)

ネットワークスペシャリスト初受験の午後2問1がIPv6で、自室IPv6化エントリでやってきた内容ドンピシャだったわい勝利の舞ヽ(´ー｀)ノ

まぁ午後1が時間全然足りなくってとりあえず埋めただけになっちゃったのでアレ_(:3」∠)_

試験直前にCockpitを使うと簡単に389DSが使えることを知ってしまったので、直前なのに勉強ほったらかしてLDAP認証を入れ始めてしまいました。

直前だからと試験勉強始めたらSSOが楽しそうでKerberos認証を調べてみたらトンでもなくメンドクサそうでLDAPに方針変更したとかそんな(ry

OSはFedora42でSambaのバーションは4.22.0、SELinuxは有効にしています。

途中上手くいってないときにもしかしてSELinuxのせいじゃね？ってGemini先生に言われたけどそんなことはなかった。

# 389DSのインストール

Cockpitを使っているとサービスのメニューで一番上にあるあいつ(389DirectoryServer)です。有効ボタンを押すだけでインストールされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/e49bdd4a-b6cb-438b-8ab7-ee6ec8efcddc.png)

インストールが終わったらF5で画面を更新すると左のメニューのツールの下に389DSのメニューが現れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/c5b1c429-79dc-4d5d-b9a8-216ece182a20.png)

## firewallを設定しておく

インストールが終わったらついでなのでその下の端末のメニューでコンソールを開いてfirewallのポートを開いておきましょう。

```bash
$ firewall-cmd --add-service=ldap --permanent
$ firewall-cmd --add-service=ldaps --permanent
$ firewall-cmd --reload
$ firewall-cmd --list-services 
cockpit dns ldap ldaps samba squid ssh
```

# 初期化

## インスタンスの作成

389DSメニューを選択すると、初めての時はインスタンス(一つのツリーと思ったらいいのかな)の作成ボタンが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/7076d419-9dc1-43a8-aa9d-79f33363a68a.png)

インスタンスの作成ボタンを押すとインスタンスの設定画面になります。パスワードはそこそこの長さを求められます。

ポートはデフォルトの`389がldap`、`636がldaps`なので変える場合はfirewalldの設定も修正します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/f3978582-0a77-4afb-aca4-d0edb8d4339e.png)

なおスクロールするとデータベースの作成チェックボックスがあります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/8df98380-cf30-4e82-a8e2-9808b50853aa.png)

## データベースの作成

DBが無いと何も書き込めません。

サーバインスタンス作成時にチェックボックスがありますがチェックを忘れたときはサフィックスというメニューで後から作れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/c60e88ca-618d-4e01-ba60-7a54bb5170c9.png)

インスタンス作成時にDBの作成チェックボックスを付けるか、データベースメニューのサフィックスの＋ボタンを押すとサフィックスの設定画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/e28466cd-a72f-43f9-9ae7-6c0bb0fd879d.png)

LDAPブラウザを見に行くと初期化せずにDBを作ったのでルートサフィックスエントリがないと言われます。右下の`ルートサフィックスのエントリを作成→`というのがボタンになっているので押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/ff7905af-06e9-4486-a582-971081827cd7.png)

左側のサフィックスツリーにあるエントリをクリックすると右側に詳細が現れます。右側の...を押すとエントリの追加や削除ができます。

![スクリーンショット 2025-04-18 203921.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/511d01cc-939e-4c98-a2b7-5910326eaae5.png)

# Sambaのスキーマを導入する

最近の389DSにはsambaのスキーマが最初から入っていました。

オブジェクトクラスに`sambaSamAccount`があればたぶん入っています。

<details><summary>入っていない場合</summary>

サーバメニューの一般設定の下の方にスキーマディレクトリがあります。ここにSambaのスキーマをコピーして再起動すればいいそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/34db54b4-b494-4409-8879-e27122cbddfb.png)

![スクリーンショット 2025-04-18 204228.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/41da9ad3-d4e6-41d0-b03a-5e8d8523afe4.png)

sambaのスキーマを探して……

```
$ find /usr/share/doc/samba -name "*.ldif"
/usr/share/doc/samba/LDAP/samba-schema-FDS.ldif
/usr/share/doc/samba/LDAP/samba.ldif
```

samba-schema-FDS.ldifが目的のものです(FDS=FedoraDirectoryServer。389DSの旧名)

ファイルの先頭にファイル名を変えてコピーしろとあるのでそうします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/36ef2444-c434-4403-a362-d579aad0e494.png)

```
$ cp /usr/share/doc/samba/LDAP/samba-schema-FDS.ldif <スキーマディレクトリ>/60samba-schema-FDS.ldif


# 389DSを再起動
$ systemctl restart dirsrv@インスタンス名.service
```
</details>

# ユーザーを登録

ユーザー作成時に認証に必要なオブジェクトクラスを追加しておきます。後からオブジェクトクラスを追加することもできるので最初は無くても大丈夫です。

Sambaで必要なオブジェクトクラス
- sambaSamAccount
- posixAccount

sambaSamAccountがSamba用パスワード管理を行うためのオブジェクトクラスです。ログインパスワードとは別のSamba用パスワード(サービスごとに別パスワードを付ける)を管理します。

**SambaはuidNumber/gidNumberベースでリソース管理を行うのでposixAccountが必要です。**

SSHで必要なオブジェクトクラス
- nsAccount

## まずはorganizationalUnitを作成

ルートの下には色々なノードが追加されるので、ユーザーはルート直下ではなくグループ等挟んでわかりやすくしておきます。小さな組織なのでここではUsersというorganizationalUnitにユーザーをまとめていきます。

左側のツリーのdc=homeが選択された状態で右側の...の新規作成を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/b79f4f3b-0ac5-4104-a4b6-1e1cb67a8ae2.png)

必要なのはouだけです。Nextを押していくと値の設定画面になるので鉛筆マークを押して値を入れて✔マークを押して設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/1ed17ff5-f8a9-4c4a-940f-2deea1fc648d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/946c29d4-047a-4c0d-b714-f486d21c41ca.png)

最低限！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/4d6a1e89-1896-4f26-a6e7-c97e6eb2c24d.png)

## ユーザーの追加

左側のツリーでou=Usersを選択し右側の...の新規作成から`新しいカスタムエントリを作成`を実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/48071eb0-3397-4250-b14d-a5fa162f1c83.png)

必要なオブジェクトクラスにチェックを入れておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/ffd59035-bd0f-4c31-b27c-9da2b95dff87.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/45fbda34-2861-45c8-9835-336d463b89b0.png)

属性は後から追加したり自動で追加されたりするので何もせずそのままNextで進めます。

値の設定画面になったらユーザー情報を入力していきます。uidNumber/gidNumberは自動で振ってくれないので自分でちゃんと管理します。

昔の感覚で1000～65535だと思っていたら、64bitOSなら簡単に2^(32-1)-1≒20億まで上げられるそうです。が、デフォルトだとやっぱり最大値が60000とかになってるので注意。

```bash
$ cat /etc/login.defs | grep MAX
...
UID_MAX                 60000
```

最小値も1000未満はOSが使用するので1000以上を使います。Linuxユーザーと同じユーザーなら同じuidNumberを、LinuxにいないユーザーならかぶらないようなuidNumberにしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/051ab41c-29eb-49bb-991b-d09984dea436.png)

sambasidはnetコマンド(sambaを入れたら入ってた)を使って取得します。

```bash
$ sudo net getlocalsid
```

`S-`で始る値がsidなのですがこれをそのまま使うのではなく、他とかぶらないよう後ろにuidNumber等を追加して設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/d5d5f299-f134-4ece-8b15-ee0369dcba89.png)

最低限必要な設定はこれだけなのでこれでユーザーを作ってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/4005af07-12b7-4add-8443-b32da28997db.png)

# Sambaの認証を通過させる

## Sambaに389DSとの連携を設定する

- passdb backend: ldapam:ldap://の後ろにホスト[:port]で指定
- ldap ssl: 今回SSLは使いません
- ldap adomin dn: 389DSの管理者(パスワード設定は後でコマンドで)
- ldap suffix: ツリーのルート
- ldap user suffix: ユーザーを(直接?)含むノード

```/etc/samba/smb.conf
[global]
...
        security = user

#       passdb backend = tdbsam
        passdb backend = ldapsam:ldap://localhost
        ldap ssl = no
        ldap admin dn = cn=Directory Manager
        ldap suffix = dc=home
        ldap user suffix = ou=Users,dc=home
```

変更したら再起動して反映させます。

```bash
$ systemctl restart smb
```

389DSを操作するための管理者パスワードをSambaに設定しておきます。

```bash
$ smbpasswd -W 
Setting stored password for "cn=Directory Manager" in secrets.tdb
New SMB password:
```

ここまででSamba管理用ノードが389DSに追加されていると思いますが、これは編集しないようにしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/0501b5b1-679d-4d06-9d2a-207def4b8278.png)

このノードの中に自動生成された`sambasid`が設定されているので、netコマンドじゃなくてこっちからコピペして使うこともできます。

## NSSとSSSDの設定

Sambaの認証はNSSを経由して行われるということですが、NSSが直接LDAPとやりとりするのではなくLDAPとやりとりするサービスを呼び出す形になってます。

LDAPとやりとりするサービスにはNSLCDやSSSDがありSSSDがメンドクサイという話でしたが最低限ならそう面倒でも無さそうだし認証キャッシュ付きでLDAPサーバにも優しいとのことでSSSDにしました。

```
$ dnf install sssd
```

設定ファイルのデフォルトが無いので0から自分で作ります。

- services: Samba用にnss,pamを設定
- domains: 下の[]の/の右側。名前をつけて複数設定できるっぽい
- ldap_uri: サーバの設定、portは省略できる
- ldap_tls_reqcert: 今回TLSは使わない
- ldap_search_base: ユーザーを直接含むノード
- ldap_default_bind_dn: 389DSの管理者
- id_provider: ldapを指定
- auth_provider: ldapを指定

パスワードは後から付けますので一旦これでファイルを作ります。

```conf:/etc/sssd/sssd.conf
[sssd]
services = nss,pam
domains = default

[domain/default]
ldap_uri = ldap://127.0.0.1
ldap_tls_reqcert = never
ldap_search_base = ou=Users,dc=home
ldap_default_bind_dn = cn=Directory Manager 
id_provider = ldap
auth_provider = ldap
```

ファイルのオーナーがrootでパーミッション600や640でないと怒られるようです。

```
$ chmod 600 /etc/sssd/sssd.conf

$ ls -la /etc/sss/sssd.conf
-rw--------. 1 root sssd 394  ...
```

LDAP管理者パスワードを設定します。-dの後ろはsssd.confのdomain/の後ろの名称です。

/etc/sssd/sssd.confの内容が自動で書き換わりますので、書き換えられると嫌なときはバックアップをとっておきましょう。

```bash
$ sss_obfuscate -d default

$ cat /etc/sssd/sssd.conf
...
# 以下自動で追加
access_provider = permit
sudo_provider = ldap
chpass_provider = ldap
autofs_provider = ldap
resolver_provider = ldap
ldap_default_authtok_type = obfuscated_password
ldap_default_authtok = AAAQAK122oMPpSZF4tAysnW+w69/...
```

この設定を使うようにNSSとPAMにも設定を行います。手動で`/etc/nsswitch.conf`や`/etc/pam.d/password-auth`を書き換えることもできますが、綴り間違いで死ぬ(やらかした😇)のでおとなしくコマンドに任せましょう。

```bash
$ authselect select sssd

$ cat /etc/nsswitch.conf
# いくつかのエントリのfilesの後ろにsssが追加されている
passwd:     files sss systemd
shadow:     files systemd
group:      files [SUCCESS=merge] sss [SUCCESS=merge] systemd

$ cat /etc/pam.d/password-auth
# いくつかのpam_sss.soを読み込む行が追加されている
auth        sufficient             pam_sss.so forward_pass
```

ここまででsssdを起動します。すでに起動してしまっていた場合はsssdを再起動してください。

```bash
$ systemctl start sssd
$ systemctl enable sssd
```

設定が上手くいっていればサーバにいない389DSで登録したユーザーが認識されます。

```bash
$ id aaa
uid=2001(aaa) gid=2001 groups=2001

$ getent passwd aaa
aaa:*:2001:2001:aaa:/home/aaa:
```

SSSDが起動時にhost名の解決をしようとするのでhost名からIPアドレスを引けるようにしておかないと`server_sort:Unable to register control ...`を筆頭にログにいっぱいエラーが表示されます😇
(認証はできる)

`::1 ホスト名`を/etc/hostsにポンっと放り込んでおけばエラーは消えます。

## Sambaのユーザーパスワードを設定

Sambaと389DSの連携ができたらsmbpasswdコマンドで389DSのユーザーのSamba用パスワードの設定ができるようになります。

最初MD4にして`sambaNTPassword`に突っ込めばいいんでしょ？とか思ったらMD4変換ができるツールがことごとく無くなってる上、`sambaNTPasswd`以外にも結構色々なデータが入るので手動設定は無理でした／(^o^)＼

```bash
$ smbpasswd -U aaa
No builtin backend found, trying to load plugin
smbldap_search_domain_info: Searching for:[(&(objectClass=sambaDomain)(sambaDomainName=MINIPC))]
smbldap_open_connection: connection opened
New SMB password:
Retype new SMB password:
init_sam_from_ldap: Entry found for user: aaa
init_ldap_from_sam: Setting entry for user: aaa
ldapsam_update_sam_account: successfully modified uid = aaa in the LDAP database
```

パスワードを2回入れて最後にsuccessfullyと出てきたらパスワードの設定が成功です。`sambaNTPassword`や`sambaAcctFlags`が増えていますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/b72a5d89-4abe-447c-867e-18e1940cb723.png)

smbclientやWindowsなどからログインできることを確認しておきましょう。

```
$ smbclient //localhost/share -U aaa
Password for [SAMBA\aaa]:
Try "help" to get a list of possible commands.
smb: \> ls
  .                                   D        0  Sat Aug 10 14:39:44 2024
  ..                                  D        0  Sat Aug 10 14:39:44 2024
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/b4536f04-1624-48c9-ab8e-c75d35b4071c.png)

# SSHでログインできるようにする

## ユーザーの設定

SSHのパスワード認証が有効ならユーザー編集でuserPassword属性を追加してパスワードを突っ込めば終わりです。平文で設定したら自動で暗号化してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/d9220be2-7e3f-4ef3-8874-218e04655dca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/c2e547c8-48fa-4c36-a040-f163035a3971.png)

とはいえ通常は鍵認証を使うと思うのでuserPasswordではなくnsSshPublicKeyを設定していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/f761de60-6315-455f-9950-e3cd9d3327fa.png)

値の設定画面ではコピペでPublicKeyを設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140718/5f6585ee-f03a-4865-8501-93980cc0cfe8.png)

## sshdとsssdを設定

sshdがPAMを使ってLDAP認証を行えるようにします。ついでに.ssh下の公開鍵は見ないようにしてLDAPを使わないSSHログインができないようにしておきます。

```conf:/etc/ssh/sshd_config
...
#AuthorizedKeysFile     .ssh/authorized_keys
AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
AuthorizedKeysCommandUser nobody
...
UsePAM yes
...
```

```bash
$ systemctl restart sshd
```

これで一旦SSHでログインできなくなりました。

続けてsssdの修正を行います。

```conf:/etc/sssd/sssd.conf
[sssd]
# sshを追加
services = nss,pam,ssh

[domain/default]
...
# PublicKeyの属性名を設定
ldap_user_ssh_public_key = nsSshPublicKey
```

sssdのキャッシュを消して再起動します。

```bash
$ sss_cache -E
$ systemctl restart sssd
```

いつも通り外部からSSHログインできれば成功です。