CentOS7でOpenLDAPサーバを作る

# はじめに

サーバをそこそこ台数管理したい場合、アカウント改廃等が手間になりすぎる。
アカウントをどこかで集約して管理するのがよい。
集約手段はいろいろあるけれどLDAPがメジャーで、
あまり複雑なことをさせないなら、OpenLDAPで事足りる感じ。

CentOS7をLDAPサーバで認証するための、
LDAPサーバの作り方、使い方、OS認証方法をまとめておく。

# 構成

```
server
OpenLDAP Server
os:centos7
  |
client
os:centos7
```

# OpenLDAPサーバを作る

ホスト server で作業する。

## サービスを起動する

```bash
yum install openldap-servers openldap-clients -y
cat /usr/share/openldap-servers/DB_CONFIG.example \
| sudo -u ldap tee /var/lib/ldap/DB_CONFIG
systemctl start slapd
systemctl enable slapd
```

## 管理者パスワードを設定する

```bash
admin_password=ADMIN_SECRET

slappasswd -s $admin_password | tee /root/admin_password.txt
cat <<__LDIF__ | tee add_admin_password.ldif
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: $(cat /root/admin_password.txt)
__LDIF__
ldapmodify -a -H ldapi:/// -f add_admin_password.ldif
```

## デフォルトのドメイン設定を変える

```bash
domain="dc=example,dc=com"

cat <<__LDIF__ | tee /root/replace_domain.ldif
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=Manager,$domain" read by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: $domain

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,$domain
__LDIF__
ldapmodify -H ldapi:/// -f /root/replace_domain.ldif
```

## スキーマを拡張する

```bash
ldapmodify -a -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapmodify -a -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapmodify -a -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
```

## アクセス権を変える

```bash
cat <<__LDIF__ | tee /root/add_access.ldif
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange by dn="cn=Manager,$domain" write by self write by anonymous auth by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to * by dn="cn=Manager,$domain" write by * read
__LDIF__
ldapmodify -H ldapi:/// -f /root/add_access.ldif
```

## ディレクトリ管理者のパスワードを設定する

```bash
dm_password=DM_SECRET

slappasswd -s $dm_password | tee /root/dm_password.txt
cat <<__LDIF__ | tee add_dm_password.ldif
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: $(cat /root/dm_password.txt)
__LDIF__
ldapmodify -H ldapi:/// -f /root/add_dm_password.ldif
```

## 初期エントリを作る

```bash
cat <<__LDIF__ | tee /root/initial.ldif
dn: $domain
objectclass: dcObject
objectclass: organization
o: Example Company
dc: example

dn: cn=Manager,$domain
objectclass: organizationalRole
cn: Manager

dn: ou=People,$domain
objectClass: organizationalUnit
ou: People

dn: ou=Group,$domain
objectClass: organizationalUnit
ou: Group
__LDIF__
ldapmodify -a -x -D "cn=Manager,$domain" -w $dm_password -f /root/initial.ldif
```

## ファイアウォールを設定する

```bash
firewall-cmd --permanent --add-service=ldap
firewall-cmd --reload
```

# OpenLDAPサーバにユーザアカウントを加える

## ユーザを加える

```bash
username=ldapuser1
password=SECRET

path=/root/${username}_password.txt
slappasswd -s $password | tee $path
cat <<__LDIF__ | tee /root/${username}.ldif
dn: uid=$username,ou=People,$domain
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: Janitor Joe
sn: Janitor
userPassword: $(cat $path)
loginShell: /bin/bash
uidNumber: 2000
gidNumber: 2000
homeDirectory: /home/guests/$username

dn: cn=ldapuser1,ou=Group,$domain
objectClass: posixGroup
objectClass: top
cn: ldapuser1
gidNumber: 2000
__LDIF__
ldapmodify -a -x -D "cn=Manager,$domain" -w $dm_password -f /root/$username.ldif
```

# OSのユーザ認証にLDAP認証を加える

ホスト client で作業する。

## OSにLDAP認証の設定を加える

```bash
yum install nss-pam-ldapd pam_ldap -y
authconfig-tui
  # [*] Use LDAP
  # [*] Use LDAP Authentication
  # [Next]

  # [ ] Use TLS
  # Server: ldap://server/
  # Base DN: dc=example,dc=com
  # [OK]

getent passwd ldapuser1
  # --> ldapuser1:x:2000:2000:Janitor Joe:/home/guests/ldapuser1:/bin/bash
getent group ldapuser1
  # --> ldapuser1:*:2000:
```

## LDAP認証を試す

```bash
ssh ldapuser1@localhost
```

```console
[root@client ~]# ssh ldapuser1@localhost
The authenticity of host 'localhost (::1)' can't be established.
ECDSA key fingerprint is SHA256:+V8LNjx+VZy+Q6+8BIAPfq4sm/usZxCnQ4NV7RmcIrk.
ECDSA key fingerprint is MD5:0e:dc:25:49:53:bf:f2:0c:03:d6:c7:e6:8a:58:33:f9.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
ldapuser1@localhost's password:
Could not chdir to home directory /home/guests/ldapuser1: No such file or directory
/usr/bin/id: cannot find name for group ID 2000
-bash-4.2$
```

## ユーザがパスワードを変える

TODO

## 蛇足

OpenLDAPはRHEL7.4からdeprecated扱いなので、
RHEL8以降でOS標準パッケージから消えるかもしれない。

けど 389-ds は大きすぎるんだよ。

## 参考資料

* https://www.openldap.org/
* https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/openldap
* https://www.server-world.info/
* https://access.redhat.com/solutions/2440481

<!-- vim:set ft=markdown: -->