本文首發:https://www.somata.net/2019/openldap_server_config_and_management.html
本文主要在debian配置,如果需要在CentOS上部署,需要修改大部分的路徑,這里需要自行修改。
LDAP
服務按照個人理解,也可使理解為一個數據庫,但是這個數據庫的讀寫性能不像 MySQL
一樣擁有良好的讀寫性能,而 LDAP
更偏向於讀取,而弱於寫入。並且 LDAP
的數據類型屬於面向對象的數據類型,這和 MySQL
的數據類型不同,並且使用樹狀結構記錄數據,這些都與普通的數據庫(關系型數據庫),有着極大的差別。而這一切的一切都代表着 LDAP
這個服務並不是用做一個普通的數據庫(關系型數據庫)用的,而是用於類似於賬戶存儲等這種少存入、多讀取、需要包含對象類型和對象相關屬性的場合。
LDAP工作機制
就跟上面說的一樣,LDAP是樹狀結構的數據庫,所以說如果想要找到其中一個節點,就得通過逐層查詢,並且必須保證每一個節點的路徑唯一,那么這個節點的路徑就稱之為dn,dn 的編寫路徑必須是由下而上編寫的,例如:
cn=scott,ou=marketing,ou=people,dc=mydomain,dc=org
關鍵字 | 英文全稱 | 含義 |
---|---|---|
dc | Domain Component | 域名的部分,其格式是將完整的域名分成幾部分,如域名為 example.com 那么就是: dc=example,dc=com |
uid | User Id | 用戶 ID,如 “tom” |
ou | Organization Unit | 組織單位,類似於 Linux 文件系統中的子目錄,它是一個容器對象,組織單位可以包含其他各種對象(包括其他組織單元),如 “market” |
cn | Common Name | 公共名稱,如 “Thomas Johansson” |
sn | Surname | 姓,如 “Johansson” |
c | Country | 國家,如 “CN” 或“US”等。 |
o | Organization | 組織名,如 “Example, Inc.” |
dn | Distinguished Name | 惟一辨別名,類似於 Linux 文件系統中的絕對路徑,每個對象都有一個惟一的名稱,如 “uid= tom,ou=market,dc=example,dc=com”,在一個目錄樹中 DN 總是惟一的 |
rdn | Relative dn | 相對辨別名,類似於文件系統中的相對路徑,它是與目錄樹結構無關的部分,如 “uid=tom” 或“cn= Thomas Johansson” |
以上這些類別沒有指定特定的用法,這些完全由應用程序自行決定。
LDAP 安裝
debian:
apt install slapd ldap-utils # slapd 為服務端, ldap-utils 為客戶端程序
CentOS:
yum install openldap-servers openldap-clients # 上同
LDAP 服務器配置初始化
做這一步的目的是為了完全自定義初始化數據庫,拋棄由軟件包構成的數據庫。
當然你也可以跳過這個步驟,直接開始下一步,這樣也是無所謂的。
你也可以你使用 debian 提供的便捷方式來完成服務器配置: dpkg-reconfig slapd
首先先來解釋一些為什么要按照如下(完全屬於個人理解):
新版的 OpenLdap 已經棄用了 slapd.conf 配置文件,改而使用 slapd.d 目錄下的樹狀目錄文件來配置服務器的相關配置。但是 slapd.d 是由服務進程維護的,並且使用CRC來校驗文本是否改動,我們無法輕易修改,slapd安裝包給我們提供了一個命令 slapadd
用於創建配置文件,所以才用了下面的方法來初始化數據庫。后期使用 ldapmodify
或 ldapadd
來完成服務器配置。
首先停止數據庫服務:
systemctl stop slapd
然后編輯文件:
# 首先備份文件,以免無法復原
mkdir /root/back
tar -Jcvf /root/back/slapd.config-`date '+(%Y.%m.%d_%H:%M:%S)'`.tar.xz /etc/ldap/slapd.d/
tar -Jcvf /root/back/slapd.data-`date '+(%Y.%m.%d_%H:%M:%S)'`.tar.xz /var/lib/ldap /var/lib/slapd
# 然后再刪除配置文件
rm -rf /etc/ldap/slapd.d/*
rm -rf /var/lib/slapd/*
rm -rf /var/lib/ldap/*
# 復制配置文件到臨時目錄
cp /usr/share/slapd/slapd.init.ldif /tmp
cd /tmp
這里我創建一個sed的規則表,方便使用,以下請自行選擇。
# file: rules
##################################
# 本文請自行選擇復制到到文件內 #
##################################
#自定義基本域名(必選):
s/@SUFFIX@/$(basename)/g
#自定義管理員用戶密碼(必須):
s/@PASSWORD@/$(password)/g
#自定義管理員用戶名稱(可選):
s/cn=admin/cn=$(username)/g
#數據庫類型(3選1,必選):
# mdb
s/@BACKEND@/mdb/g
s/@BACKENDOBJECTCLASS@/olcMdbConfig/g
s/@BACKENDOPTIONS@/olcDbMaxSize: 1073741824/g
# hdb
s/@BACKEND@/hdb/g
s/@BACKENDOBJECTCLASS@/olcHdbConfig/g
s/@BACKENDOPTIONS@/olcDbConfig: set_cachesize 0 2097152 0\nolcDbConfig: set_lk_max_objects 1500\nolcDbConfig: set_lk_max_locks 1500\nolcDbConfig: set_lk_max_lockers 1500/g
# bdb
s/@BACKEND@/bdb/g
s/@BACKENDOBJECTCLASS@/olcBdbConfig/g
s/@BACKENDOPTIONS@/olcDbConfig: set_cachesize 0 2097152 0\nolcDbConfig: set_lk_max_objects 1500\nolcDbConfig: set_lk_max_locks 1500\nolcDbConfig: set_lk_max_lockers 1500/g
這里我選擇hdb數據庫,樣例如下:
# file:rule
s/@SUFFIX@/dc=black,dc=com/g
s/@PASSWORD@/{SSHA}RadcVPriXsR6gCwhwPKsCLkhnHy3r1ZS/g
s/cn=admin/cn=root/g
s/@BACKEND@/hdb/g
s/@BACKENDOBJECTCLASS@/olcHdbConfig/g
s/@BACKENDOPTIONS@/olcDbConfig: set_cachesize 0 2097152 0\nolcDbConfig: set_lk_max_objects 1500\nolcDbConfig: set_lk_max_locks 1500\nolcDbConfig: set_lk_max_lockers 1500/g
其中密碼是這樣生成的:
slappasswd -s 147258369
{SSHA}RadcVPriXsR6gCwhwPKsCLkhnHy3r1ZS
再然后通過命令修改配置文件,並且生成配置文件和數據庫:
sed -i -f rule /tmp/slapd.init.ldif
slapadd -F "/etc/ldap/slapd.d/" -b "cn=config" -l slapd.init.ldif
_#################### 100.00% eta none elapsed none fast!
Closing DB...
我們再查看一下這些文件的:
ll /etc/ldap/slapd.d/*
-rw------- 1 root root 478 Jul 10 09:06 /etc/ldap/slapd.d/cn=config.ldif
/etc/ldap/slapd.d/cn=config:
total 28
-rw------- 1 root root 452 Jul 10 09:06 cn=module{0}.ldif
drwxr-x--- 2 root root 4096 Jul 10 09:06 cn=schema
-rw------- 1 root root 394 Jul 10 09:06 cn=schema.ldif
-rw------- 1 root root 412 Jul 10 09:06 olcBackend={0}hdb.ldif
-rw------- 1 root root 542 Jul 10 09:06 olcDatabase={0}config.ldif
-rw------- 1 root root 657 Jul 10 09:06 olcDatabase={-1}frontend.ldif
-rw------- 1 root root 1084 Jul 10 09:06 olcDatabase={1}hdb.ldif
哦,我們這里看到了好像文件權限不對啊,所以我們也改改文件屬主。
chown -R openldap:openldap slapd.d
chown -R openldap:openldap /var/lib/slapd/*
chown -R openldap:openldap /var/lib/ldap/*
那么這里就可以正常啟動服務器了:
systemctl start slapd
LDAP 數據庫創建
這里我們還需要注意雖然前面創建的服務器配置里有DN信息,但是真正的數據庫完全沒有創建,這里我們必須手動創建這些數據庫。當然你可以使用命令 slapcat
或者 ldapsearch
命令來查詢是否有數據存在。
首先創建一個文件,用於記錄需要存入的數據,ldap數據庫沒有交互式界面,每一次操作都必須一條命令,其實這也側面證明了LDAP是是個偏讀取的面向對象型的服務,而不是一個綜合型的數據庫服務。
# file:base.ldif
# 根節點 復制時,注意把這這個注釋刪了!!!!
dn: dc=black,dc=com
dc: black
objectClass: top
objectClass: domain
# 管理員用戶root
dn: cn=root,dc=black,dc=com
objectClass: organizationalRole
cn: root
description: LDAP Manager
然后我們再通過命令,將 base.ldif
這的信息導入至數據庫
ldapadd -x -D "cn=root,dc=black,dc=com" -w 147258369 -f base.ldif
adding new entry "dc=black,dc=com"
adding new entry "cn=root,dc=black,dc=com"
這里需要解釋一項這里命令的基本用法:
- -x: 表示使用基本擁擠認證
- -D "cn=root,dc=black,dc=com" -w 147258369: 指定用戶和密碼
- -f: 指定文件
那么這里再驗證一下數據庫是否創建成功:
ldapsearch -x -D "cn=root,dc=black,dc=com" -w 147258369 -b "dc=black,dc=com"
# extended LDIF
#
# LDAPv3
# base <dc=black,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# black.com
dn: dc=black,dc=com
dc: black
objectClass: top
objectClass: domain
# root, black.com
dn: cn=root,dc=black,dc=com
objectClass: organizationalRole
cn: root
description: LDAP Manager
# search result
search: 2
result: 0 Success
# numResponses: 3
# numEntries: 2
再解釋一個參數:
- -b: 指定需要搜索的base目錄
LDAP 后期管理
數據庫管理
這里的數據庫管理也可是使用一些 LDAP 軟件來完成(部署 LDAP 應用),不過還以要寫寫命令行,因為命令行的靈活性高,而且便於理解,這些都是應用程序無法比擬的。
ldapadd 條目添加
還是和上面數據庫創建一樣的,需要先創建一個文件用於存放數據。
# file: group.ldif
# 組織單元
dn: ou=User,dc=black,dc=com
objectClass: organizationalUnit
ou: User
# 用戶1
dn: uid=User1,ou=User,dc=black,dc=com
objectClass: account
objectClass: simpleSecurityObject
uid: User1
userPassword: {SSHA}5WjJz9QfntUjurHirfv9C4832x1xh9Kt
# 用戶2
dn: uid=User2,ou=User,dc=black,dc=com
objectClass: account
objectClass: simpleSecurityObject
uid: User2
userPassword: {SSHA}9biML+BP/W8w3mRkVack7CyB1hfDi8cD
然后我們再通過命令將文件添加到數據庫:
ldapadd -x -D "cn=root,dc=black,dc=com" -w 147258369 -f group.ldif
adding new entry "ou=User,dc=black,dc=com"
adding new entry "uid=User1,ou=User,dc=black,dc=com"
adding new entry "uid=User2,ou=User,dc=black,dc=com"
ldapadd 可以從文件中讀取數據,同時也可從標准輸入輸出讀取數據:
cat << EOF | ldapadd -x -D "cn=root,dc=black,dc=com" -w 147258369
dn: uid=User3,ou=User,dc=black,dc=com
objectClass: account
objectClass: simpleSecurityObject
uid: User3
userPassword: {SSHA}iES3qeH0nYUcwGtSQm1hIBCEsV+gBF3P
EOF
adding new entry "uid=User3,ou=User,dc=black,dc=com"
這樣就可以臨時添加數據了,同時這樣也可使用bash腳本完成批量用戶添加,這里我就不演示了。
ldapmodify 條目更改
還是一樣的將數據寫入文件,不過這里需要注意,因為是更改條目,所以需要編寫指明更改模式,和更改目標。
# file: change.ldif
dn: uid=User3,ou=User,dc=black,dc=com
changetype: modify
replace: userPassword
userPassword: {SSHA}9TM5y06bvepK6k8i+Jfkc/9C6GkVsobm
然后使用命令即可。
ldapmodify -x -D "cn=root,dc=black,dc=com" -w 147258369 -f change.ldif
modifying entry "uid=User3,ou=User,dc=black,dc=com"
那么再來驗證一下:
ldapwhoami -x -D "uid=User3,ou=User,dc=black,dc=com" -w 147
dn:uid=User3,ou=User,dc=black,dc=com
ldapdelete 條目刪除
刪除條目不需要寫清除如何如何,只需要指定條目路徑即可,也就是dn.
ldapdelete -x -D "cn=root,dc=black,dc=com" -w 147258369 "uid=User3,ou=User,dc=black,dc=com"
這個命令沒有返回信息,那么表明執行成功。我們再次使用命令驗證:
ldapwhoami -x -D "uid=User3,ou=User,dc=black,dc=com" -w 123456
ldap_bind: Invalid credentials (49)
ldapsearch 條目搜尋
這個就不多說了,直接上命令:
ldapsearch -x -b "dc=black,dc=com" -D "cn=root,dc=black,dc=com" -w 147258369 "(&(objectclass=account)(uid=User1))" # 這里最后一段是filter,用於過濾查詢結果
# extended LDIF
#
# LDAPv3
# base <dc=black,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# User1, User, black.com
dn: uid=User1,ou=User,dc=black,dc=com
objectClass: account
objectClass: simpleSecurityObject
userPassword:: e1NTSEF9OWJpTUwrQlAvVzh3M21Sa1ZhY2s3Q3lCMWhmRGk4Y0Q=
uid: User1
# search result
search: 2
result: 0 Success
# numResponses: 6
# numEntries: 5
ldapwhomai 用戶查詢
前面也用過了,直接上命令:
ldapwhoami -x -D "cn=root,dc=black,dc=com" -w 147258369
dn:cn=root,dc=black,dc=com
服務器配置
這里服務器的后續配置,不能再動 slapd.d 目錄下的文件了,必須通過 ldap 提供的 API 接口完成服務器配置,這點是非常重要的,因為默認的配置是只允許通過本地SASL認證的用戶才能修改服務器的配置文件,這樣才能保證服務器的安全性。所以我們還需要通過客戶端命令 ldapmodify 命令來進行服務配置,比如所修改管理員密碼:
這里的dn節點與數據庫節點不同,你可以看到這些條目對應的就是 slapd.d 目錄下的文件了,當然是去去除了后綴名(ldif)的節點。
# file: config.ldif
dn: olcDatabase={1}hdb,cn=config
changetype: modify
replace: olcRootPW
olcRootPW: {SSHA}5WjJz9QfntUjurHirfv9C4832x1xh9Kt
然后通過命令完成修改:
ldapmodify -Y EXTERNAL -H ldapi:/// -f config.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={1}hdb,cn=config"
注:如果節點不存在,但是你還是想要創建也是可是的,你需要將dn節點指定到你需要創建的文件路徑,然后使用命令ldapadd 添加即可。
LDAP 備份和還原
這里我使用了 slapd 提供的命令完成了該操作,主要就是方便而且全面,也不想去了解別的方法,都沒這個實在。
服務器備份
slapcat -n 0 -l slapcat.bak.0.ldif # 0 表示備份服務器配置
slapcat -n 1 -l slapcat.bak.1.ldif # 1 表示備份數據庫
服務器還原
關閉服務器:
systemctl stop slapd
刪除原始文件:
# 首先備份文件,以免無法復原
mkdir /root/back
tar -Jcvf /root/back/slapd.config-`date '+(%Y.%m.%d_%H:%M:%S)'`.tar.xz /etc/ldap/slapd.d/
tar -Jcvf /root/back/slapd.data-`date '+(%Y.%m.%d_%H:%M:%S)'`.tar.xz /var/lib/ldap /var/lib/slapd
# 然后再刪除配置文件
rm -rf /etc/ldap/slapd.d/*
rm -rf /var/lib/slapd/*
rm -rf /var/lib/ldap/*
還原數據庫:
slapadd -l slapcat.bak.0.ldif -F /etc/ldap/slapd.d/ -b "cn=config" # 還原服務器配置
slapadd -l slapcat.bak.1.ldif -F /etc/ldap/slapd.d/ # 還原數據庫
_#################### 100.00% eta none elapsed none fast!
Closing DB..._#################### 100.00% eta none elapsed none fast!
Closing DB...
這樣就搞定了。
但是還是需要注意權限:
chown -R openldap:openldap /etc/ldap/slapd.d/*
chown -R openldap:openldap /var/lib/slapd/*
chown -R openldap:openldap /var/lib/ldap/*
啟動服務器:
systemctl start slapd
部署 LDAP 應用
這里直接使用 phpldapadmin了, 我也不想再多弄了,怎么簡單,怎么來了。
apt install phpldapadmin
然后配置一下 phpladpadmin的文件即可:
# file: /etc/phpldap/config.php
……
$servers->setValue('server','base',array('dc=black,dc=com')); # 在300行,更改服務器
……
……
$servers->setValue('login','bind_id','cn=root,dc=black,dc=com'); # 在326行,更改登入的默認字符串
……
然后登入即可:
界面如下:
本文經「原本」原創認證,作者乾坤盤,訪問yuanben.io查詢【2P9ZA60S】獲取授權信息。