dockerコンテナ使ってOpenLDAPでLDAPSを提供させ、centos8からssh接続

◆◆◆

※2022年6月にcentos8のdockerコンテナ使えないことに気づいたのとauthselectについての記述が欠けてたので、centosではないredhatクローンを使う方法に切り替えた。

前に一度作ったdockerコンテナでの環境を、普段使いのdocker環境に追記して最近やり直したのでメモ。

ldap版の方法はここ。これを足がかりにしてldapsにしてみる。

phpldapadminではldifファイルってのが扱えて、ou以下のグループとユーザIDをエクスポート・インポートできる。

ldap版で作ったouとかはldifにエクスポートしておき、ldaps版にインポートする。

コンテナ起動のためのdocker-compose.yml内容はここ。

openldapのコンテナ起動

docker-compose.ymlを用意して起動。

自分のルールとしては、練習じゃなくて常時稼働にするサーバにはコンテナ名の頭に”sv_”をつける。

ldapからldapsにするついでに、phpldapadminもhttpsにしてみる。

  sv_ldap-server:                   ←★sv_つける
    image: osixia/openldap:latest   
    restart: always
    container_name: svldap-server   ←★svつける
    environment:
      LDAP_ORGANISATION: "gvis"
      LDAP_DOMAIN: "intra-gavann-it.com"
      LDAP_ADMIN_PASSWORD: "hogehoge"
      LDAP_TLS_VERIFY_CLIENT: "never"   ←★自己証明書使うから証明書チェックさせない
    ports:
      - "11389:389"
      - "11636:636"

  ### https://nafslinux.intra.gavann-it.com:11802/
  ### cn=admin,dc=intra-gavann-it,dc=com
  ### hogehoge
  ### 
  ### 参考URL https://github.com/osixia/docker-phpLDAPadmin
  ###
  ### httpsを使うときは、証明書が自動作成されているので取得してクライアント側に設定すること
  ### コンテナ内の保管先:/container/service/slapd/assets/certs
  ###
  ### 参考URL https://github.com/osixia/docker-openldap#use-your-own-certificate

  sv_ldap-admin:
    image: osixia/phpldapadmin:latest
    restart: always
    container_name: svldap-admin
    environment:
      PHPLDAPADMIN_LDAP_HOSTS: "ldap-host"
    ports:
      - "11801:80"
      - "11802:443"                 ←★https提供してもらうため
    depends_on:
      - "sv_ldap-server"
    links:
      - sv_ldap-server:ldap-host

起動した後のdocker psはこんな感じ。

$ docker ps
CONTAINER ID   IMAGE                        COMMAND                  CREATED       STATUS             PORTS                                                                                  NAMES
028ce44e812a   osixia/phpldapadmin:latest   "/container/tool/run"    3 hours ago   Up 3 hours         0.0.0.0:11801->80/tcp, :::11801->80/tcp, 0.0.0.0:11802->443/tcp, :::11802->443/tcp     svldap-admin
0e1af753333d   osixia/openldap:latest       "/container/tool/run"    3 hours ago   Up 3 hours         0.0.0.0:11389->389/tcp, :::11389->389/tcp, 0.0.0.0:11636->636/tcp, :::11636->636/tcp   svldap-server

phpldapaminに接続してldifファイルをインポート

ログインしてみる。

gvis-ldaps

phpldapadminにログインした後、左上のほうに「import」と「export」って表記がある。
ツリー構造の「dc=」の箇所をクリックしてからインポートすると登録内容をldifって形式のファイルとして出力してくれて以下のようなouを再現してくれる。

gvis-ldaps

ldap版でexportさせたldif内容はこんな感じで、これをldaps版でインポートした。
コンテナは作り直すこと多いから、そのときにはこれを流し込む。

あ、Entry1は既にあるからインポートではエラーになるけど、エラー発生しても続行するようにインポートさせて気にせず先に進む。

# LDIF Export for dc=intra-gavann-it,dc=com
# Server: ldap (ldap)
# Search Scope: sub
# Search Filter: (objectClass=*)
# Total Entries: 4
#
# Generated by phpLDAPadmin (http://phpldapadmin.sourceforge.net) on September 27, 2021 9:41 pm
# Version: 1.2.5

version: 1

# Entry 1: dc=intra-gavann-it,dc=com
dn: dc=intra-gavann-it,dc=com
dc: intra-gavann-it
o: gvis
objectclass: top
objectclass: dcObject
objectclass: organization

# Entry 2: ou=gvis,dc=intra-gavann-it,dc=com
dn: ou=gvis,dc=intra-gavann-it,dc=com
objectclass: organizationalUnit
objectclass: top
ou: gvis

# Entry 3: cn=gavann it,ou=gvis,dc=intra-gavann-it,dc=com
dn: cn=gavann it,ou=gvis,dc=intra-gavann-it,dc=com
cn: gavann it
gidnumber: 500
givenname: gavann
homedirectory: /home/gavann-it
loginshell: /bin/bash
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: it
uid: gavann-it
uidnumber: 2000
userpassword: {MD5}rj6D4vqzp9hoPY7vq9HnTQ==

# Entry 4: cn=gvis-group,ou=gvis,dc=intra-gavann-it,dc=com
dn: cn=gvis-group,ou=gvis,dc=intra-gavann-it,dc=com
cn: gvis-group
gidnumber: 500
objectclass: posixGroup
objectclass: top



# Entry 5: cn=gavann it,ou=gvis,dc=intra-gavann-it,dc=com
dn: cn=gavann is,ou=gvis,dc=intra-gavann-it,dc=com
cn: gavann is
gidnumber: 500
givenname: gavanns
homedirectory: /home/gavann-is
loginshell: /bin/bash
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: it
uid: gavann-is
uidnumber: 2001
userpassword: {MD5}rj6D4vqzp9hoPY7vq9HnTQ==

ldapsのための証明書をとってくる

docker-compose.ymlに書いた「osixia/openldap」の説明が書いてあるgithubを見ると、sslのための電子証明書を自動で作ってくれるらしい。

GitHub - osixia/docker-openldap: OpenLDAP container image 🐳🌴
OpenLDAP container image 🐳🌴. Contribute to osixia/docker-openldap development by creating an account on GitHub.

電子証明書ってイマイチ苦手なのな。keygenとかで作ったような気もするし、awsやgcpでsshするときの設定でも作ったと思う。なぜ必要かはわからなくないけど、ちゃんと別の機会に勉強せなあかん。

ldapsで接続するクライアント側にはこの電子証明書を置く必要があるので、ldapsを提供するために起動したOpenLDAPのコンテナに入ってファイルを取ってくる。

まずはファイルの所在確認。githubに書いてあったコンテナ内のフォルダ「/container/service/slapd/assets/certs」にldap.crtがあるのでこれを使う。

長いパス書くの嫌なので、いったんコンテナ内の/tmpにコピーしておいて、docker cpでホストOSに持って来る。

コンテナはJST設定しなかったからファイルのタイムスタンプがずれてるな。まぁいいか。

# docker exec -it svldap-server bash
root@0e1af753333d:/# cd /container/service/slapd/assets/certs
root@0e1af753333d:/container/service/slapd/assets/certs# ls -l
total 16
lrwxrwxrwx 1 openldap openldap   62 Sep 29 18:05 ca.crt -> /container/service/:ssl-tools/assets/default-ca/default-ca.pem
-rw------- 1 openldap openldap  424 Feb 19  2021 dhparam.pem
-rw-r--r-- 1 openldap openldap 1099 Sep 29 18:05 ldap.crt
-rw------- 1 openldap openldap  288 Sep 29 18:05 ldap.key
-rw-rw-r-- 1 openldap openldap  173 Feb 19  2021 README.md
root@0e1af753333d:/container/service/slapd/assets/certs# cp -p ./ldap.crt /tmp/
root@0e1af753333d:/container/service/slapd/assets/certs# exit
exit
# docker cp svldap-server:/tmp/ldap.crt ./

ldap.crtの中をwindows端末で開くと、有効期限が1年なのがわかる。
コンテナは1年以内に必ず作り直すようにしている自分にはこれでいいからこのまま使う。

gvis-ldaps

証明書をcentos8に設置する

永続化領域(/gvis/download)をcentos8には持たせているので、ldap.crtはそこ経由で設置した。いったん所有権をrootにしてパーミッションも600にしとく。

[root@clcent8 ~]# cp -p /gvis/download/ldap.crt /etc/openldap/certs/
[root@clcent8 ~]# cd /etc/openldap/certs/
[root@clcent8 certs]# chown root:root ./ldap.crt
[root@clcent8 certs]# chmod 600 ./ldap.crt
[root@clcent8 certs]# ls -lh
total 16K
-rw------- 1 root root 1.1K  9月 30 03:05 ldap.crt

centos8のコンテナでLDAPSのための証明書の正常性を確認する

持ってきた鍵がちゃんと使える内容になっているか念のため確認してみる。

TLS1.2だと、そのままでは7200秒まってから応答が戻るようなので、timeout使って3秒で処理を切り上げる。

自己証明書では「Verify return code: 19 (self signed certificate in certificate chain)」って戻るのを確認。このまま使うことにする。

tlsって1.2より上もあるんやろな。dockerコンテナとイメージ作り直したら勝手に上がっていくやろ。

# timeout 3 openssl s_client -connect svldap-server:636
CONNECTED(00000003)
Can't use SSL_get_servername
depth=1 C = US, ST = New Mexico, L = Albuquerque, O = A1A Car Wash, OU = Information Technology Dep., CN = docker-light-baseimage
verify error:num=19:self signed certificate in certificate chain
verify return:1
depth=1 C = US, ST = New Mexico, L = Albuquerque, O = A1A Car Wash, OU = Information Technology Dep., CN = docker-light-baseimage
verify return:1
depth=0 C = US, ST = New Mexico, L = Albuquerque, O = A1A Car Wash, OU = Information Technology Dep., CN = 0e1af753333d
verify return:1
---
Certificate chain
 0 s:C = US, ST = New Mexico, L = Albuquerque, O = A1A Car Wash, OU = Information Technology Dep., CN = 0e1af753333d
   i:C = US, ST = New Mexico, L = Albuquerque, O = A1A Car Wash, OU = Information Technology Dep., CN = docker-light-baseimage
 1 s:C = US, ST = New Mexico, L = Albuquerque, O = A1A Car Wash, OU = Information Technology Dep., CN = docker-light-baseimage
   i:C = US, ST = New Mexico, L = Albuquerque, O = A1A Car Wash, OU = Information Technology Dep., CN = docker-light-baseimage
:
:(中略)
:
Verification error: self signed certificate in certificate chain
---
New, TLSv1.2, Cipher is ECDHE-ECDSA-AES256-GCM-SHA384
Server public key is 384 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES256-GCM-SHA384
:
:(中略)
:
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES256-GCM-SHA384
    Session-ID: 292D90F30701A276FA4528074E8528389D073CF848F82C29B2A5495697598F25
    Session-ID-ctx:
    Master-Key: C97832AC15BC5FB451FC0672E1D033BAC719188A1B80AD96128E7EA1B69BCEC52853C5C76B611820F070BDFF4006AE8C
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1632951794
    Timeout   : 7200 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
    Extended master secret: yes
---
#

centos8から接続設定

ldap版でのファイルを流用して作る。

ポート開放確認

まずはdocker内のcentos8コンテナからLDAPSサーバのポート開放確認。やる気満々で待ち受けてますなぁ。

[root@clcent8 ~]# nmap -p636 -Pn svldap-server
Starting Nmap 7.70 ( https://nmap.org ) at 2021-09-30 07:00 JST
Nmap scan report for svldap-server (172.18.0.2)
Host is up (0.000096s latency).
rDNS record for 172.18.0.2: svldap-server.docker_default

PORT    STATE SERVICE
636/tcp open  ldapssl
MAC Address: 02:42:AC:12:00:02 (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 0.59 seconds
[root@clcent8 ~]#

ついでに、dockerホストから確認。ポート番号変えてるからSERVICEがunknownになってる。このポートは後で使う。

# nmap -p11636 -Pn localhost
Starting Nmap 7.80 ( https://nmap.org ) at 2021-09-30 06:56 JST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00010s latency).

PORT      STATE SERVICE
11636/tcp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 0.11 seconds
#

openldap.confの設定

編集は「vi /etc/openldap/ldap.conf」で書き換える。
BASEの行はldap版のときに書いた内容そのまま。

TLS_CACERT      /etc/openldap/certs/ldap.crt    ←★さっきの証明書ファイル
URI             ldaps://svldap-server           ←★dockerコンテナのldapsのサーバ
BASE            dc=intra-gavann-it,dc=com

sssd.confの設定

編集は「vi /etc/sssd/sssd.conf」で書き換える。
ldap版のときの内容から、ここも★印の箇所を書き換えた。
書き換えたら設定を反映するために「systemctl restart sssd.service」を忘れずに。
セキュリティポリシー書き換えてコンテナ再起度するから今はやらない。

[sssd]
debug_level = 4
services = nss, pam, ifp, sudo
domains = gvis

[nss]
homedir_substring = /home 
filter_groups = root 
filter_users = root

[pam]

[sudo]

[domain/gvis]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
sudo_provider = ldap
autofs_provider = ldap

cache_credentials = True
case_sensitive = False

ldap_uri = ldaps://svldap-server                            ←★ldaps指定
ldap_search_base = ou=gvis, dc=intra-gavann-it,dc=com
ldap_default_bind_dn = cn=admin, dc=intra-gavann-it,dc=com

ldap_tls_cacert = /etc/openldap/certs/ldap.crt              ←★設置した証明書を指定
ldap_id_use_start_tls = True                                ←★ldapsのための設定
ldap_tls_reqcert = never                                    ←★自己証明書のための設定

ldap_default_authtok_type = obfuscated_password
ldap_default_authtok = AAAQAMHjxTYytMbzEbbFP0x4tZSWkTZlBMhmQlmAjbyyxEGFXQi7yJ9o6SGcdyHW44KeYfnmPHV2CvHSwTswkUUnVmQAAQID

最後の2行にあるldap_default_authtokで始まる行は、ldapsになったら不要なのかなって思っていったん削ってたけど、書いとかないと認証できないので残した。

sss_obfuscate使って難読化する方法も含め、ldap版のときの内容そのままにしといた。

centos8のセキュリティポリシーを設定する

legacy設定を使わないようにする。centos8もredhat8もデフォルトはDEFAULTになっている。
docker使ってなかったらOS再起動で「shutdown -r now」ってやる。
docker使ってるからホストOSから「docker-compose restart cl_cent8」をやった。

[root@clcent8 ~]# update-crypto-policies --set DEFAULT
Setting system policy to DEFAULT
Note: System-wide crypto policies are applied on application start-up.
It is recommended to restart the system for the change of policies
to fully take place.
[root@clcent8 ~]# update-crypto-policies --show
DEFAULT

centos8から接続

ldaps化してsssd.confに書いたドメインの状態を確認してみる。ちゃんとOnlineになってる。

[root@clcent8 ~]# sssctl domain-status gvis
Online status: Online

Active servers:
LDAP: svldap-server

Discovered LDAP servers:
- svldap-server

[root@clcent8 ~]#

sssd.confに書いたドメインの状態確認

ldaps化した状態でアカウント情報が取れるかどうか確認してみる。これも行けてそう。

[root@clcent8 ~]# getent passwd gavann-it
gavann-it:*:2000:500:gavann it:/home/gavann-it:/bin/bash
[root@clcent8 ~]#

キャッシュの削除

以前のキャッシュ情報をクリアしておく。

[root@clcent8 ~]# sssctl cache-remove
SSSD must not be running. Stop SSSD now? (yes/no) [yes] yes
Creating backup of local data...
SSSD backup of local data already exists, override? (yes/no) [no] yes
Removing cache files...
SSSD needs to be running. Start SSSD now? (yes/no) [yes] yes
[root@clcent8 ~]#

接続

実際につないでみる。passwdにldapsサーバに作ったposixユーザのgavann-itと同じものがローカルOSには存在しないことを確認。おお、行けてるみたい。

[root@clcent8 ~]# cat /etc/passwd | grep gavann
[root@clcent8 ~]#
[root@clcent8 ~]# ssh gavann-it@localhost
gavann-it@localhost's password:
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Thu Sep 30 04:21:22 2021 from 127.0.0.1
[gavann-it@clcent8 ~]$ whoami
gavann-it
[gavann-it@clcent8 ~]$

apache directory studioをインストーラなしで使う

自分はphpldapadminのコンテナを使って立ち上げて使うけど、apache ldap studioからディレクトリを管理するっていう手もある。ldaps化したコンテナへの接続ができるか設定入れてみた。

Welcome to Apache Directory Studio — Apache Directory

javaでのっそり動くこれを使うと、クライアントサイドから簡単にLDAPのツリー構造が見える。readonlyってスイッチがついてるので、ちょっと見たいっていうときに便利かも。

自分では、まぁあんまり使わない。

設定方法を探してみたらアドバイス書いてくれている方がおられた。

作者さんありがとう。

【Apache Directory Studio】インストール導入と使い方~Windows PCからLDAPツリー(登録内容)を一覧化する~
Apache Directory Studio とは LDAP サーバを運用している際に、LDAP の中身を見たいなぁ、というときは ldapsearch を使うことがあるかと思います。ですがコマンドもオプションが思い出せずに毎回調べるのも

iniファイルを自分用に書き換える必要があり、jdkも必要。

Java Archive Downloads - Java SE 17
Java Archive Downloads - Java SE 17

自分はこういうソフトウェアを「インストール」ではなくzip展開して設置するほうをが好き。
まずはダウンロードし、jdkを適当に置いてみる。

apache directory studioは「Windows 64 bit zip archive」ってあるものを取ってきて、jdkは「Windows x64 Compressed Archive」ってあるものを取ってくる。

jdk17をApacheDirectoryStudioに置いてみるとこんな感じ。

gvis-ldaps

ここでiniファイルいじる。「-vm」っていうオプションにはjdkの場所の中のbinフォルダを指定しなきゃいけない。下のほうに-Xmsと-Xmxの指定があるから、ヒープの指定もできるみたい。以下、設定ファイルの内容。

-startup
plugins/org.eclipse.equinox.launcher_1.6.0.v20200915-1508.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.2.0.v20200915-1442
/studio-rcp/resources/icons/linux/studio.xpm
###
#Uncomment_to_configure_the_language
#https://directory.apache.org/studio/faqs.html#how-to-set-the-language-of-studio
-nl   ←★言語設定らしい
en    ←★jpとかjaとか指定したら日本語になるかもしれないけど、とりあえず英語でそのまま
###
#Uncomment_to_configure_Java_version_to_use
#https://directory.apache.org/studio/faqs.html#how-to-set-the-java-vm-to-use
-vm   ←★たぶんjvmの設定
C:\personal\TsukasaNari\ApacheDirectoryStudio\jdk-17\bin  ←★ここ足した
-vmargs
-Dosgi.requiredJavaVersion=11
###
#Uncomment_to_configure_heap_memory
#https://directory.apache.org/studio/faqs.html#how-to-increase-the-heap-memory
#-Xms1g
#-Xmx2g

とりあえず起動はできる。とても残念だったのは、フォルダをlinux上のsmb共有に置いたらjavaがexception吐き出して起動できなかったこと。javaはすぐこういうことになるから好かない。

sqldeveloperみたいにsmb共有に置いてもjava系処理起動できたら使おうと思ったけど、ダメだったのでこれ書き終わったら削除確定。

LDAPSなので、LDAPとは違って証明書を受け入れる設定が必要。

あと、linux上ではなくwindowsからなので、さっきnmapで確認したdocker動かしているホスト名、外部ポートを指定してview certificateを押す。

gvis-ldaps

次は証明書を「いつも信用してね」の設定入れとく。

gvis-ldaps

念のため証明書も確認。

gvis-ldaps

さっき入力した認証情報を入れる。

gvis-ldaps

すんなりLDAPSの情報が見えた。

gvis-ldaps

ldap認証を使うとsssdを使う設定がredhat8で必須ってなったとき、ldapサーバへの接続設定は悩んだ。openldap/sssdの設定ファイルを用意するのと、セキュリティポリシー設定のLEGACYが必要ってことにたどり着くまで時間かかった。

ldapsでの認証はdockerで実現できたけど、まぁいい勉強になった。

タイトルとURLをコピーしました