IBM Cloud Private (ICP) をOpenLDAPで認証する

# 経緯

ICP(IBM Cloud Private)のダッシュボードやCLIでマルチユーザに対応するためにはLDAPサーバが必要です。しかし公式に対応しているLDAPサーバは

- IBM Tivoli Directory Server
- IBM Lotus Domino
- IBM SecureWay Directory Server
- Novell eDirectory
- Sun Java™ System Directory Server
- Netscape Directory Server
- Microsoft Active Directory
- Custom

となっており、有償製品ばかりとなっています（バージョン2.1.0.2時点）。

そこで、一番下のCustomを利用して、OpenLDAPで認証してみます。

なお、KubernetesのLDAP認証のやり方はほとんど情報がないため、今回トライアントエラーを繰り返しながら検証しました。根本的に間違っているところがあるかもしれませんし、未検証の部分もあります、その点はご容赦ください。

検証環境
- IBM Cloud Private 2.1.0.2 (Kubernetes 1.9.1)
- CentOS 7

# 手順

## OpenLDAPサーバの設定

検証にはCentOS 7を利用しました。まず関連パッケージをインストールします。

```
# yum -y install openldap-clients openldap-servers
```

HDBの設定をします。

```
# cp -p /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
```

slapdを起動します。

```
# systemctl enable slapd
# systemctl start slapd
```

管理者用パスワードを生成します。

```
# slappasswd
New password:
Re-enter new password:
{SSHA}ハッシュ値
```

管理者パスワードをセットします。

```
# ldapadd -Y EXTERNAL -H ldapi:// << EOF
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}ハッシュ値
EOF
```

ドメインとアクセス権を設定します。

```
# ldapmodify -x -D cn=config -W << EOF
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=ldapadmin,dc=lab,dc=hoge,dc=jp" read by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=lab,dc=hoge,dc=jp

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=ldapadmin,dc=lab,dc=hoge,dc=jp

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}ハッシュ値（先ほどとは違うものを生成するのがいいでしょう）
EOF
```

ドメインオブジェクトを登録します。

```
# ldapadd -x -D cn=ldapadmin,dc=lab,dc=hoge,dc=jp -W << EOF
dn: dc=lab,dc=hoge,dc=jp
objectClass: dcObject
objectClass: organization
dc: lab
o: lab
EOF
```

cosineとinetOrgPersonのスキーマを登録します。先にcosineを登録しないとinetOrgPersonの登録でエラーになるので注意です。

```
# ldapadd -x -D cn=config -W -f /etc/openldap/schema/cosine.ldif
# ldapadd -x -D cn=config -W -f /etc/openldap/schema/inetorgperson.ldif
```

ユーザが所属するグループを登録します。今回は管理者グループadminsとします。`objectClass: groupOfUniqueNames` を付与します。uniqueMemberはまだユーザがいないですが、ここに書かないとエラーになるので空で登録します。

```
# ldapadd -x -D cn=ldapadmin,dc=lab,dc=hoge,dc=jp -W << EOF
dn: cn=admins,dc=lab,dc=hoge,dc=jp
objectClass: top
objectClass: groupOfUniqueNames
cn: admins
uniqueMember:
EOF
```

ユーザを追加します。cnとsnとuidを一致させます。displayNameとgivenNameはなくてもいいですがICPがそれらの属性を取得している動きがログから読みとれたので念のため設定します。mailは設定されていればICPのコンソールでメールアドレスが表示されます。

```
# ldapadd -x -D cn=ldapadmin,dc=lab,dc=lesmiz,dc=jp -W << EOF
dn: cn=teru,dc=lab,dc=hoge,dc=jp
objectClass: uidObject
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: teru
sn: teru
uid: teru
displayName: Teruyuki Takazawa
givenName: Teruyuki
mail: teru@lab.hoge.jp
userPassword: {SSHA}PB/nzjStVNzOhcOTVyxpc/7DefQUc3VE
EOF
```

ユーザを管理者グループに参加させます。先ほど空で登録したuniqueMemberをreplaceします。2人目からはreplaceではなくaddにします。

```
ldapmodify -x -D cn=ldapadmin,dc=lab,dc=lesmiz,dc=jp -W << EOF
dn: cn=admins,dc=lab,dc=lesmiz,dc=jp
replace: uniqueMember
uniqueMember: cn=teru,dc=lab,dc=lesmiz,dc=jp
EOF
```

## ICPのLDAP設定

adminでICPのダッシュボードにログインし、Manage -> Authenticatin からLDAPの設定を追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241424/a89f048c-310a-dc6d-84ff-c58c2afab54c.png)

FilterはUser FilterのePersonをPersonに直します。後はこのままでよいです。テスト接続してエラーにならないことを確認してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241424/cb9ae32d-5abb-bc1a-a64d-2b1efae2a208.png)

## チーム・グループ・ユーザの設定

同じくダッシュボードで Manage -> Team で Create Team を選択します。

チーム名を入力し、GroupsでLDAPのグループ名を一部入力するとグループが表示されるので、選択します。Roleは今回はCluster administratorとし、Createします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/241424/ea1c3d26-f90d-6ed5-b56c-ae5fc385210e.png)

## 確認

ダッシュボードをログアウトして、新たに登録したユーザでログインできることを確認してください。無事ログイン出来たら成功です。