# OpenLDAP [dockerhub_bitnami/openldap](https://hub.docker.com/r/bitnami/openldap/) [github_wheelybird/ldap-user-manager](https://github.com/wheelybird/ldap-user-manager) ## Server ### 架設 - docker-compose.yaml ```yaml= services: openldap: image: bitnami/openldap:2.6.7 container_name: openldap restart: always ports: - '1389:1389' # non-TLS - '1636:1636' # TLS environment: - LDAP_ROOT=dc=google,dc=org - LDAP_ADMIN_DN=cn=admin,dc=google,dc=org - LDAP_ADMIN_USERNAME=admin - LDAP_ADMIN_PASSWORD=password - LDAP_ENABLE_TLS=yes - LDAP_TLS_CERT_FILE=/opt/bitnami/openldap/certs/cert.pem - LDAP_TLS_KEY_FILE=/opt/bitnami/openldap/certs/privkey.pem - LDAP_TLS_CA_FILE=/opt/bitnami/openldap/certs/chain.pem volumes: - './bitnami/openldap:/bitnami/openldap' - './opt/bitnami/openldap/certs:/opt/bitnami/openldap/certs' lum: image: wheelybird/ldap-user-manager:v1.11 container_name: lum restart: always ports: - "8080:80" - "4433:443" environment: - LDAP_URI=ldaps://openldap:1636 - LDAP_BASE_DN=dc=google,dc=org - LDAP_ADMIN_BIND_DN=cn=admin,dc=google,dc=org - LDAP_ADMIN_BIND_PWD=password - LDAP_ADMINS_GROUP=admins - LDAP_IGNORE_CERT_ERRORS=true - NO_HTTPS=true ``` ### Init ``` docker compose up -d ``` 進入`localhost:8080/setup` ### Config #### Configuring slapd OpenLDAP從2.3版開始改用dynamic runtime configuration engine 需要以`ldapmodify`, `ldapdelete`, `ldapadd`的方式來修改,直接以服務修改的話,就要用`slapadd`和`slapmodify` 而儲存的檔案會在`/slapd.d`,不能直接修改這個資料夾內的檔案,否則checkSum會不相符而導致錯誤 這個改動也讓我們可以不用重啟slapd來Apply更動的Config,改成先定義一個LDIF檔案,在透過指令變更LDAP上的Config #### Configuration Layout Slapd的configuration有個定義好的架構和DIT(Dictionary Information Tree) ![image](https://hackmd.io/_uploads/rJ6AsCZm0.png) LDAP的configuration root 叫做`cn=config`,包含著global configuration LDAP Database是無序的,因此在Config會有個{n},用來代表設定Database的順序,這個順序是自動產生的 大部分的 attributes and objectClasses 都會有`olc`的prefix 每個argument用空白分開,如果有argument是有空格的,那要使用雙引號包起來,`"like this"` #### 如何修改 首先要先找到誰有權限可以修改,由於我是使用bitnami/openldap,他的config位於`/bitnami/openldap/slapd.d/cn=config` - `cat olcDatabase\=\{0\}config.ldif` ``` # AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify. # CRC32 e5118730 dn: olcDatabase={0}config objectClass: olcDatabaseConfig olcDatabase: {0}config olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=1001,cn=peercred,cn=exter nal,cn=auth" manage by * none structuralObjectClass: olcDatabaseConfig entryUUID: 396b8800-a21f-103e-98fb-114693e3b917 creatorsName: cn=config createTimestamp: 20240509071222Z entryCSN: 20240509071222.209499Z#000000#000#000000 modifiersName: cn=config modifyTimestamp: 20240509071222Z ``` 可以看到只有uid=1001可以編輯,但是gid=0,這代表他的Group是root 一般的Openldap都是允許uid=0,gid=0的user可以修改,但是因為這是bitnami/openldap,而`docker exec -it openldap bash`後,會發現符合上述的需求 ```bash I have no name!@93d5dd35d30d:/$ id uid=1001 gid=0(root) groups=0(root) ``` 這時再執行`ldapmodify -Y EXTERNAL -H ldapi:///`就可以輸入想修改的`ldif`內容 - 讓使用者可以自己修改密碼 ```ldif dn: olcDatabase={2}mdb,cn=config changetype: modify replace: olcAccess olcAccess: {0}to attrs=userPassword by self write # 自己可以修改 by anonymous auth # 不明使用者要驗證 by users none # 經過驗證也沒權限 olcAccess: {1}to * by * read # 所有人都有讀的權限 ``` #### 常用指令 `ldapsearch -Y EXTERNAL -H ldapi:/// -b "dc=google,dc=org" "(uid=*)"` 搜尋所有使用者 `ldapdelete -x -D "cn=admin,dc=google,dc=org" -W -H ldapi:/// "cn=user02,ou=users,dc=google,dc=org"` 刪除使用者 #### 格式 `#`開頭會被辨識為註解 開頭若有空格會被辨識為上一行 每個Entity使用空白行來區分 ## Client ### 安裝 ```bash apt -y install libnss-ldapd libpam-ldapd ldap-utils; ``` ``` Package configuration ┌─────────────────────────┤ Configuring nslcd ├──────────────────────────┐ │ Please enter the Uniform Resource Identifier of the LDAP server. The │ │ format is "ldap://<hostname_or_IP_address>:<port>/". Alternatively, │ │ "ldaps://" or "ldapi://" can be used. The port number is optional. │ │ │ │ When using an ldap or ldaps scheme it is recommended to use an IP │ │ address to avoid failures when domain name services are unavailable. │ │ │ │ Multiple URIs can be separated by spaces. │ │ │ │ LDAP server URI: │ │ │ │ ldaps://openldap:1636/________________________________________________ │ │ │ │ <Ok> <Cancel> │ │ │ └────────────────────────────────────────────────────────────────────────┘ ``` ``` Package configuration ┌───────────────────────────┤ Configuring nslcd ├───────────────────────────┐ │ Please enter the distinguished name of the LDAP search base. Many sites │ │ use the components of their domain names for this purpose. For example, │ │ the domain "example.net" would use "dc=example,dc=net" as the │ │ distinguished name of the search base. │ │ │ │ LDAP server search base: │ │ │ │ dc=google,dc=org_________________________________________________________ │ │ │ │ <Ok> <Cancel> │ │ │ └───────────────────────────────────────────────────────────────────────────┘ ``` ``` Package configuration ┌────────────────────────┤ Configuring nslcd ├─────────────────────────┐ │ Please choose what type of authentication the LDAP database should │ │ require (if any): │ │ │ │ * none: no authentication; │ │ * simple: simple bind DN and password authentication; │ │ * SASL: any Simple Authentication and Security Layer mechanism. │ │ │ │ LDAP authentication to use: │ │ │ │ *none │ │ simple │ │ SASL │ │ │ │ │ │ <Ok> <Cancel> │ │ │ └──────────────────────────────────────────────────────────────────────┘ ``` ``` Package configuration ┌──────┤ Configuring nslcd ├───────┐ │ Check server's SSL certificate: │ │ │ │ never │ │ allow │ │ try │ │ *demand │ │ │ │ │ │ <Ok> <Cancel> │ │ │ └──────────────────────────────────┘ ``` ``` Package configuration ┌────────────────────────┤ Configuring nslcd ├────────────────────────┐ │ When certificate checking is enabled this file contains the X.509 │ │ certificate that is used to check the certificate provided by the │ │ server. │ │ │ │ Certificate authority certificate: │ │ │ │ /etc/ssl/certs/ca-certificates.crt_________________________________ │ │ │ │ <Ok> <Cancel> │ │ │ └─────────────────────────────────────────────────────────────────────┘ ``` ``` Package configuration ┌───────────────────────┤ Configuring libnss-ldapd ├────────────────────────┐ │ For this package to work, you need to modify the /etc/nsswitch.conf file │ │ to use the ldap datasource. │ │ │ │ You can select the services that should have LDAP lookups enabled. The │ │ new LDAP lookups will be added as the last datasource. Be sure to review │ │ these changes. │ │ │ │ Name services to configure: │ │ │ │ [*] passwd ↑ │ │ [*] group ▮ │ │ [*] shadow ▒ │ │ [ ] hosts ▒ │ │ [ ] networks ↓ │ │ │ │ │ │ <Ok> │ │ │ └───────────────────────────────────────────────────────────────────────────┘ ``` - Ldap使用者登入時自動新增Home dir ```bash= echo "session optional pam_mkhomedir.so skel=/etc/skel umask=077" >> /etc/pam.d/common-session systemctl restart nscd nslcd; ``` - 設定指定group有sudo權限 ```bash sudo visudo ``` 加上`%admins ALL=(ALL) ALL` `admins`為在Ldap指定的群組名稱 ### libnss-ldapd [文件 - nsswitch.conf](https://linux.die.net/man/5/nsswitch.conf) - 對應Service `nscd.service` - 重新以ui設定 `dpkg-reconfigure libnss-ldapd` - `/etc/nsswitch.conf` ```bash= # # Example configuration of GNU Name Service Switch functionality. # If you have the `glibc-doc-reference' and `info' packages installed, try: # `info libc "Name Service Switch"' for information about this file. passwd: files systemd ldap group: files systemd ldap shadow: files ldap gshadow: files hosts: files dns networks: files protocols: db files services: db files ethers: db files rpc: db files netgroup: nis ``` ### libpam-ldapd [文件 - nslcd.conf](https://linux.die.net/man/5/nslcd.conf) - 對應Service `nslcd.service` - 重新以ui設定 `dpkg-reconfigure nslcd` - `/etc/nslcd.conf` ```bash= # /etc/nslcd.conf # nslcd configuration file. See nslcd.conf(5) # for details. # The user and group nslcd should run as. uid nslcd gid nslcd # The location at which the LDAP server(s) should be reachable. uri ldaps://openldap:1636/ # The search base that will be used for all queries. base dc=google,dc=org # The LDAP protocol version to use. #ldap_version 3 # The DN to bind with for normal lookups. #binddn cn=annonymous,dc=example,dc=net #bindpw secret # The DN used for password modifications by root. #rootpwmoddn cn=admin,dc=example,dc=com # SSL options ssl on tls_reqcert demand tls_cacertfile /etc/ssl/certs/ca-certificates.crt # The search scope. #scope sub ``` - debug ```bash= systemctl stop nscd nslcd nslcd -d ``` - TLS 若選用TLS LDAP,要注意uri必須與憑證申請的範圍一致 ### ldap-utils LDAP Debug工具 [ldap.conf](https://linux.die.net/man/5/ldap.conf) `/etc/ldap/ldap.conf` ### 讓LDAP指定Group可以使用docker 讓User使用ssh登入時,確認是否符合指定的Group,符合後給予這個User docker group - `addDocker.sh` ```bash #!/bin/bash username="${PAM_USER}" if id -nG "$username" | grep -qw "smms"; then if ! id -nG "$username" | grep -qw "docker"; then usermod -aG docker "$username" fi fi ``` 先把放到任意指定位置,這邊是放在`/etc/security` 在`/etc/pam.d/sshd`增加`auth [default=ignore] pam_exec.so seteuid /etc/security/smmsDocker.sh` 如此一來每次ssh登入時都會跑`addDocker.sh`,來檢查是否給予docker group