いつも手順を忘れて結構な時間を食うのでメモ化する。
ファイルを格納するディレクトリを作る。
mkdir -p {data/certs,data/ldap_config,data/ldap_db,data/ldif}
ここではホスト名にワイルドカードDNSサービスのnip.ioを使い、https://ldap.<コンテナを起動するホストのIP>.nip.io
でアクセスする。
その設定のために、dcやホスト名に使うホストのIPをハイフン繋ぎに変換した環境変数を用意する。
IP部分は自分のIPに書き換えること。また環境によっては無理に使う必要はない。
export HOST_IP=$(sed "s/\./-/g" <<< 192.168.0.15)
自己署名証明書を作成する。LDAPのコンテナ側に証明書の自動生成機能があるが、後述する--copy-service
をつけると自動生成した証明書が消えてしまうので(バグ?)、予め自作して読ませる。(持ち込みの人はここはスキップでOK)
cat <<'EOF' > ./make_certs.sh
#!/bin/bash
set -xe
mkdir certs
cd certs
export HOST_IP=$(sed "s/\./-/g" <<< 192.168.0.15)
export COMMONNAME=ldap.${HOST_IP}.nip.io
openssl genrsa -out ca.key 4096
chmod 400 ca.key
openssl req -key ca.key -new -x509 -days 3650 -sha512 -extensions v3_ca -subj "/C=JP/ST=Earth/L=Global/O=example/CN=$COMMONNAME" -out ca.crt
openssl genrsa -out client.key 4096
openssl req -new -subj "/emailAddress=demo@example.com/CN=$COMMONNAME/O=example/OU=example/C=JP/ST=Earth/L=Global" -key client.key -out client.csr
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=$COMMONNAME
DNS.2=$HOST_IP
DNS.3=hostname
EOF
openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in client.csr -out client.crt
openssl dhparam -out dhparam.pem 2048
cd -
cp certs/client.crt data/certs/ca.crt
cp certs/client.crt data/certs/ldap.crt
cp certs/client.key data/certs/ldap.key
cp certs/dhparam.pem data/certs/dhparam.pem
EOF
chmod +x ./make_certs.sh
./make_certs.sh
初期ユーザを定義したLDIFファイル(users.ldif
)を作成する。
cat <<EOF > ./data/ldif/users.ldif
dn: cn=user1,dc=ldap,dc=${HOST_IP},dc=nip,dc=io
objectClass: top
objectClass: inetOrgPerson
cn: user1
sn: User1
uid: user1
userPassword: password1
dn: cn=user2,dc=ldap,dc=${HOST_IP},dc=nip,dc=io
objectClass: top
objectClass: inetOrgPerson
cn: user2
sn: User2
uid: user2
userPassword: password2
EOF
docker-compose.yml
を作成する。
cat << EOF > ./docker-compose.yml
services:
slapd:
image: osixia/openldap
container_name: slapd
restart: always
hostname: "ldap.192-168-0-15.nip.io"
ports:
- 636:636
environment:
LDAP_ORGANISATION: "Example Inc."
LDAP_DOMAIN: "ldap.192-168-0-15.nip.io"
LDAP_BASE_DN: "dc=ldap,dc=192-168-0-15,dc=nip,dc=io"
LDAP_ADMIN_PASSWORD: "admin_password"
LDAP_READONLY_USER: "true"
LDAP_READONLY_USER_USERNAME: "readonly"
LDAP_READONLY_USER_PASSWORD: "readonly_password"
LDAP_TLS_VERIFY_CLIENT: "try"
LDAP_TLS_CA_CRT_FILENAME: "ca.crt"
LDAP_TLS_CRT_FILENAME: "ldap.crt"
LDAP_TLS_KEY_FILENAME: "ldap.key"
LDAP_TLS_DH_PARAM_FILENAME: "dhparam.pem"
volumes:
- ./data/ldap_db:/var/lib/ldap
- ./data/ldap_config:/etc/ldap/slapd.d
- ./data/certs:/container/service/slapd/assets/certs
- ./data/ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom
command: --copy-service
phpldapadmin:
image: osixia/phpldapadmin
container_name: phpldapadmin
restart: always
environment:
PHPLDAPADMIN_LDAP_HOSTS: "slapd"
PHPLDAPADMIN_LDAP_CLIENT_TLS_CRT_FILENAME: "ldap.crt"
PHPLDAPADMIN_LDAP_CLIENT_TLS_KEY_FILENAME: "ldap.key"
PHPLDAPADMIN_HTTPS: "true"
PHPLDAPADMIN_HTTPS_CRT_FILENAME: "ldapadmin.crt"
PHPLDAPADMIN_HTTPS_KEY_FILENAME: "ldapadmin.key"
ports:
- 80:80
- 443:443
volumes:
- ./data/certs:/container/service/phpldapadmin/assets/apache2/certs
- ./data/phpldapadmin:/var/www/phpldapadmin
depends_on:
- slapdEOF
ポイントとしては/container/service/slapd/assets/config/bootstrap/ldif/custom
にLDIFを入れると勝手にldapadd
してくれるのと、command: --copy-service
で既存の設定を残すようにすること。(参考:公式の説明)
docker-compose.yml
を作ったら起動する。
docker compose up -d
ブラウザでhttps://ldap.${HOST_IP}.nip.io
にアクセスするとログイン画面が表示されるので、Login DN
にcn=admin,dc=ldap,${HOST_IP},dc=nip,dc=io
を指定し、Password
にLDAP_ADMIN_PASSWORDの設定値
を入れてadminでログインする。cn=admin
を忘れないように。
ログインするとLDIFで定義した初期ユーザが確認できる。
ldapsearch
でも確認できる。
先に作成したca.crt
をOS上で信頼する。
信頼したら、ldapsearch
で検索すると上手く取得できることが確認できる。(定義したホスト名でないとエラーになるので注意)
$ ldapsearch -D "cn=admin,dc=ldap,dc=192-168-0-15,dc=nip,dc=io" -w "admin_password" -b "dc=ldap,dc=192-168-0-15,dc=nip,dc=io" -H ldaps://ldap.192-168-0-15.nip.io:636
:
# user1, ldap.192-168-0-15.nip.io
dn: cn=user1,dc=ldap,dc=192-168-0-15,dc=nip,dc=io
objectClass: top
objectClass: inetOrgPerson
cn: user1
sn: User1
uid: user1
userPassword:: cGFzc3dvcmQx
:
余談
ここで作成する証明書、Macだとよく分からない属性がつく。(アットマーク部分)
$ ls -l data/certs/
total 32
-rw-r--r--@ 1 imurata staff 2216 Mar 14 13:14 ca.crt
-rw-r--r--@ 1 imurata staff 424 Mar 14 13:14 dhparam.pem
-rw-r--r--@ 1 imurata staff 2216 Mar 14 13:14 ldap.crt
-rw-------@ 1 imurata staff 3272 Mar 14 13:14 ldap.key
属性の詳細はcom.apple.provenance
となっている。
ls -l@ data/certs/
total 32
-rw-r--r--@ 1 imurata staff 2216 Mar 14 13:14 ca.crt
com.apple.provenance 11
-rw-r--r--@ 1 imurata staff 424 Mar 14 13:14 dhparam.pem
com.apple.provenance 11
-rw-r--r--@ 1 imurata staff 2216 Mar 14 13:14 ldap.crt
com.apple.provenance 11
-rw-------@ 1 imurata staff 3272 Mar 14 13:14 ldap.key
com.apple.provenance 11
今回の検証ではこれはついていても問題ないのだが、削除したい場合はTerminal.app
からxattr -d com.apple.provenance <ファイル名>
で削除できる。
Terminal.app
というのがミソで、iTermからだと削除できない。
(情報元:What is the com.apple.provenance
xattr (extended attribute) and how can I delete it?)