LDAP簡介
LDAP(輕量級目錄訪問協議,Lightweight Directory Access Protocol)是實現提供被稱為目錄服務的信息服務。目錄服務是一種特殊的數據庫系統,其專門針對讀取,瀏覽和搜索操作進行了特定的優化。目錄一般用來包含描述性的,基於屬性的信息並支持精細復雜的過濾能力。目錄一般不支持通用數據庫針對大量更新操作操作需要的復雜的事務管理或回卷策略。而目錄服務的更新則一般都非常簡單。這種目錄可以存儲包括個人信息、web鏈結、jpeg圖像等各種信息。為了訪問存儲在目錄中的信息,就需要使用運行在TCP/IP 之上的訪問協議—LDAP。
LDAP目錄中的信息是是按照樹型結構組織,具體信息存儲在條目(entry)的數據結構中。條目相當於關系數據庫中表的記錄;條目是具有區別名DN (Distinguished Name)的屬性(Attribute),DN是用來引用條目的,DN相當於關系數據庫表中的關鍵字(Primary Key)。屬性由類型(Type)和一個或多個值(Values)組成,相當於關系數據庫中的字段(Field)由字段名和數據類型組成,只是為了方便檢索的需要,LDAP中的Type可以有多個Value,而不是關系數據庫中為降低數據的冗余性要求實現的各個域必須是不相關的。LDAP中條目的組織一般按照地理位置和組織關系進行組織,非常的直觀。LDAP把數據存放在文件中,為提高效率可以使用基於索引的文件數據庫,而不是關系數據庫。類型的一個例子就是mail,其值將是一個電子郵件地址。
LDAP的信息是以樹型結構存儲的,在樹根一般定義國家(c=CN)或域名(dc=com),在其下則往往定義一個或多個組織 (organization)(o=Acme)或組織單元(organizational units) (ou=People)。一個組織單元可能包含諸如所有雇員、大樓內的所有打印機等信息。此外,LDAP支持對條目能夠和必須支持哪些屬性進行控制,這是有一個特殊的稱為對象類別(objectClass)的屬性來實現的。該屬性的值決定了該條目必須遵循的一些規則,其規定了該條目能夠及至少應該包含哪些屬性。例如:inetorgPerson對象類需要支持sn(surname)和cn(common name)屬性,但也可以包含可選的如郵件,電話號碼等屬性。
LDAP簡稱對應
- o:organization(組織-公司)
- ou:organization unit(組織單元-部門)
- c:countryName(國家)
- dc:domainComponent(域名)
- sn:surname(姓氏)
- cn:common name(常用名稱)
安裝LADP
參考:https://blog.csdn.net/woloqun/article/details/89216120
關閉selinux和防火牆【很重要】
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config && setenforce 0&& systemctl disable firewalld.service && systemctl stop firewalld.service && shutdown -r now
安裝OpenLdap
yum -y install openldap compat-openldap openldap-clients \
openldap-servers openldap-servers-sql openldap-devel migrationtools
查看版本OpenLdap版本
[root@kudu ~]# slapd -VV
@(#) $OpenLDAP: slapd 2.4.44 (Jan 29 2019 17:42:45) $
mockbuild@x86-01.bsys.centos.org:/builddir/build/BUILD/openldap-2.4.44/openldap-2.4.44/servers/slapd
配置管理員密碼
這里明文密碼設置成hadoop
[root@kudu ~]# slappasswd -s hadoop
{SSHA}RpuO1/rVtgStK4acAM3oqBu/YihUReq1
修改olcDatabase={2}hdb.ldif文件
vi /etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif
末尾添加一行
olcRootPW: {SSHA}RpuO1/rVtgStK4acAM3oqBu/YihUReq1
修改
olcSuffix: dc=haohaozhu,dc=com
olcRootDN: cn=Manager,dc=haohaozhu,dc=com
完整文件
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 b9e69d7c
dn: olcDatabase={2}hdb
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {2}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=haohaozhu,dc=com
olcRootDN: cn=Manager,dc=haohaozhu,dc=com
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
structuralObjectClass: olcHdbConfig
entryUUID: 46d0a66c-f07f-1038-8e63-7f8e33666833
creatorsName: cn=config
createTimestamp: 20190411082641Z
entryCSN: 20190411082641.038876Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190411082641Z
olcRootPW: {SSHA}RpuO1/rVtgStK4acAM3oqBu/YihUReq1
修改olcDatabase={1}monitor.ldif文件
vi /etc/openldap/slapd.d/cn=config/olcDatabase\=\{1\}monitor.ldif
修改如下行
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
al,cn=auth" read by dn.base="cn=Manager,dc=haohaozhu,dc=com" read by * none
完整文件
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 ffaba6ec
dn: olcDatabase={1}monitor
objectClass: olcDatabaseConfig
olcDatabase: {1}monitor
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
al,cn=auth" read by dn.base="cn=Manager,dc=haohaozhu,dc=com" read by * none
structuralObjectClass: olcDatabaseConfig
entryUUID: 46d0a2f2-f07f-1038-8e62-7f8e33666833
creatorsName: cn=config
createTimestamp: 20190411082641Z
entryCSN: 20190411082641.038787Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20190411082641Z
驗證配置文件是否正確
[root@kudu ~]# slaptest -u
5caefca6 ldif_read_file: checksum error on "/etc/openldap/slapd.d/cn=config/olcDatabase={1}monitor.ldif"
5caefca6 ldif_read_file: checksum error on "/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif"
config file testing succeeded
啟動服務&&查看服務
systemctl enable slapd
systemctl start slapd
systemctl status slapd
輸出
[root@kudu ~]# systemctl status slapd
● slapd.service - OpenLDAP Server Daemon
Loaded: loaded (/usr/lib/systemd/system/slapd.service; enabled; vendor preset: disabled)
Active: active (running) since 四 2019-04-11 16:38:08 CST; 5s ago
Docs: man:slapd
man:slapd-config
man:slapd-hdb
man:slapd-mdb
file:///usr/share/doc/openldap-servers/guide.html
Process: 12884 ExecStart=/usr/sbin/slapd -u ldap -h ${SLAPD_URLS} $SLAPD_OPTIONS (code=exited, status=0/SUCCESS)
Process: 12870 ExecStartPre=/usr/libexec/openldap/check-config.sh (code=exited, status=0/SUCCESS)
Main PID: 12886 (slapd)
CGroup: /system.slice/slapd.service
└─12886 /usr/sbin/slapd -u ldap -h ldapi:/// ldap:///
4月 11 16:38:08 kudu systemd[1]: Starting OpenLDAP Server Daemon...
4月 11 16:38:08 kudu runuser[12873]: pam_unix(runuser:session): session opened for user ldap by (uid=0)
4月 11 16:38:08 kudu slapd[12884]: @(#) $OpenLDAP: slapd 2.4.44 (Jan 29 2019 17:42:45) $
mockbuild@x86-01.bsys.centos.org:/builddir/build/BUILD/openldap-2.4.44/openldap-2.4.44/servers/slapd
4月 11 16:38:08 kudu slapd[12884]: ldif_read_file: checksum error on "/etc/openldap/slapd.d/cn=config/olcDatabase={1}monitor.ldif"
4月 11 16:38:08 kudu slapd[12884]: ldif_read_file: checksum error on "/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif"
4月 11 16:38:08 kudu slapd[12884]: tlsmc_get_pin: INFO: Please note the extracted key file will not be protected with a PIN any more, however it will be still protec...permissions.
4月 11 16:38:08 kudu slapd[12886]: hdb_db_open: warning - no DB_CONFIG file found in directory /var/lib/ldap: (2).
Expect poor performance for suffix "dc=haohaozhu,dc=com".
4月 11 16:38:08 kudu slapd[12886]: slapd starting
4月 11 16:38:08 kudu systemd[1]: Started OpenLDAP Server Daemon.
Hint: Some lines were ellipsized, use -l to show in full.
查看監聽端口389
[root@kudu ~]# netstat -anpl|grep 389
tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN 12886/slapd
tcp6 0 0 :::389 :::* LISTEN 12886/slapd
配置OpenLDAP數據庫
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown ldap:ldap -R /var/lib/ldap
chmod 700 -R /var/lib/ldap
ll /var/lib/ldap/
注意:/var/lib/ldap/就是BerkeleyDB數據庫默認存儲的路徑。
導入基本Schema
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
輸出
[root@kudu ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=cosine,cn=schema,cn=config"
[root@kudu ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=nis,cn=schema,cn=config"
[root@kudu ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=inetorgperson,cn=schema,cn=config"
修改migrate_common.ph文件
vi /usr/share/migrationtools/migrate_common.ph
修改如下變量
$DEFAULT_MAIL_DOMAIN = "haohaozhu.com";
$DEFAULT_BASE = "dc=haohaozhu,dc=com";
$EXTENDED_SCHEMA = 1;
添加用戶及用戶組
默認情況下OpenLDAP是沒有普通用戶的,但是有一個管理員用戶。管理用戶就是前面我們剛剛配置的root。
現在我們把系統中的用戶,添加到OpenLDAP中。為了進行區分,我們現在新加兩個用戶ldapuser1和ldapuser2,和兩個用戶組ldapgroup1和ldapgroup2,如下:
添加用戶組,使用如下命令:
groupadd ldapgroup1
groupadd ldapgroup2
添加用戶並設置密碼,使用如下命令
useradd -g ldapgroup1 ldapuser1
useradd -g ldapgroup2 ldapuser2
passwd ldapuser1
passwd ldapuser2
密碼都設置為:hadoop
提取用戶和組
grep ":10[0-9][0-9]" /etc/passwd > /root/users
grep ":10[0-9][0-9]" /etc/group > /root/groups
結果
[root@kudu ~]# cat users
ldapuser1:x:1000:1000::/home/ldapuser1:/bin/bash
ldapuser2:x:1001:1001::/home/ldapuser2:/bin/bash
[root@kudu ~]# cat groups
ldapgroup1:x:1000:
ldapgroup2:x:1001:
生成用戶和組的ldif文件
/usr/share/migrationtools/migrate_passwd.pl /root/users > /root/users.ldif
/usr/share/migrationtools/migrate_group.pl /root/groups > /root/groups.ldif
cat /root/users.ldif
cat /root/groups.ldif
輸出
[root@kudu ~]# cat /root/groups.ldif
dn: cn=ldapgroup1,ou=Group,dc=haohaozhu,dc=com
objectClass: posixGroup
objectClass: top
cn: ldapgroup1
userPassword: {crypt}x
gidNumber: 1000
dn: cn=ldapgroup2,ou=Group,dc=haohaozhu,dc=com
objectClass: posixGroup
objectClass: top
cn: ldapgroup2
userPassword: {crypt}x
gidNumber: 1001
導入用戶及用戶組到OpenLDAP數據庫
配置openldap基礎的數據庫,如下:
cat > /root/base.ldif << EOF
dn: dc=haohaozhu,dc=com
o: haohaozhu com
dc: haohaozhu
objectClass: top
objectClass: dcObject
objectclass: organization
dn: cn=Manager,dc=haohaozhu,dc=com
cn: Manager
objectClass: organizationalRole
description: Directory Manager
dn: ou=People,dc=haohaozhu,dc=com
ou: People
objectClass: top
objectClass: organizationalUnit
dn: ou=Group,dc=haohaozhu,dc=com
ou: Group
objectClass: top
objectClass: organizationalUnit
EOF
導入基礎數據庫,使用如下命令:
ldapadd -x -w "hadoop" -D "cn=Manager,dc=haohaozhu,dc=com" -f /root/base.ldif
輸出
[root@kudu ~]# ldapadd -x -w "hadoop" -D "cn=Manager,dc=haohaozhu,dc=com" -f /root/base.ldif
adding new entry "dc=haohaozhu,dc=com"
adding new entry "cn=Manager,dc=haohaozhu,dc=com"
adding new entry "ou=People,dc=haohaozhu,dc=com"
adding new entry "ou=Group,dc=haohaozhu,dc=com"
導入用戶
ldapadd -x -w "hadoop" -D "cn=Manager,dc=haohaozhu,dc=com" -f /root/users.ldif
輸出
[root@kudu ~]# ldapadd -x -w "hadoop" -D "cn=Manager,dc=haohaozhu,dc=com" -f /root/users.ldif
adding new entry "uid=ldapuser1,ou=People,dc=haohaozhu,dc=com"
adding new entry "uid=ldapuser2,ou=People,dc=haohaozhu,dc=com"
把OpenLDAP用戶加入到用戶組
盡管我們已經把用戶和用戶組信息,導入到OpenLDAP數據庫中了。但實際上目前OpenLDAP用戶和用戶組之間是沒有任何關聯的。
如果我們要把OpenLDAP數據庫中的用戶和用戶組關聯起來的話,我們還需要做另外單獨的配置。
現在我們要把ldapuser1用戶加入到ldapgroup1用戶組,需要新建添加用戶到用戶組的ldif文件,如下
cat > add_user_to_groups.ldif << "EOF"
dn: cn=ldapgroup1,ou=Group,dc=haohaozhu,dc=com
changetype: modify
add: memberuid
memberuid: ldapuser1
EOF
導入ldif
ldapadd -x -w "hadoop" -D "cn=Manager,dc=haohaozhu,dc=com" -f /root/add_user_to_groups.ldif
輸出
[root@kudu ~]# ldapadd -x -w "hadoop" -D "cn=Manager,dc=haohaozhu,dc=com" -f /root/add_user_to_groups.ldif
modifying entry "cn=ldapgroup1,ou=Group,dc=haohaozhu,dc=com"
查詢用戶
ldapsearch -LLL -x -D 'cn=Manager,dc=haohaozhu,dc=com' -w "hadoop" -b 'dc=haohaozhu,dc=com' 'cn=ldapgroup1'
輸出
[root@kudu ~]# ldapsearch -LLL -x -D 'cn=Manager,dc=haohaozhu,dc=com' -w "hadoop" -b 'dc=haohaozhu,dc=com' 'cn=ldapgroup1'
dn: cn=ldapgroup1,ou=Group,dc=haohaozhu,dc=com
objectClass: posixGroup
objectClass: top
cn: ldapgroup1
userPassword:: e2NyeXB0fXg=
gidNumber: 1000
memberUid: ldapuser1
開啟OpenLDAP日志訪問功能
默認情況下OpenLDAP是沒有啟用日志記錄功能的,但是在實際使用過程中,我們為了定位問題需要使用到OpenLDAP日志。
新建日志配置ldif文件,如下
cat > /root/loglevel.ldif << "EOF"
dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats
EOF
導入到OpenLDAP中,並重啟OpenLDAP服務,如下:
ldapmodify -Y EXTERNAL -H ldapi:/// -f /root/loglevel.ldif
systemctl restart slapd
修改rsyslog配置文件,並重啟rsyslog服務,如下:
cat >> /etc/rsyslog.conf << "EOF"
local4.* /var/log/slapd.log
EOF
systemctl restart rsyslog
安裝和配置LDAP管理工具PHPldapadmin
[root@localhost ~]# yum -y install httpd php php-ldap php-gd php-mbstring php-pear php-bcmath php-xml
[root@localhost ~]# yum -y install epel-release
[root@localhost ~]# yum --enablerepo=epel -y install phpldapadmin
修改配置文件
[root@localhost ~]# vim /etc/phpldapadmin/config.php
#397行取消注釋,398行添加注釋
$servers->setValue('login','attr','dn');
// $servers->setValue('login','attr','uid');
[root@localhost ~]# vim /etc/httpd/conf.d/phpldapadmin.conf
// 修改配置
<IfModule mod_authz_core.c>
# Apache 2.4
Require local
#添加一行內容,指定可訪問的ip段
Require ip 172.16.186.58
</IfModule>
注:我這里和參考博客不一樣,具體如下
設置開機自啟並啟動Apache:
systemctl enable httpd
systemctl start httpd
登陸web控制台
用戶名:cn=Manager,dc=haohaozhu,dc=com
密碼:hadoop
整合SpringBoot
配置
spring:
ldap:
urls: ldap://192.168.1.145:389
base: dc=haohaozhu,dc=com
username: uid=ldapuser1,ou=People,dc=haohaozhu,dc=com
password: hadoop
#username: cn=Manager,dc=haohaozhu,dc=com
類
package com.dalinpai.springbootldap.bo;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import javax.naming.Name;
/**
* @author WGR
* @create 2021/4/16 -- 17:47
*/
@Entry(base = "ou=people,dc=didispace,dc=com", objectClasses = "inetOrgPerson")
public class Person {
@Id
private Name id;
@DnAttribute(value = "uid")
private String uid;
@Attribute(name = "cn")
private String commonName;
@Attribute(name = "sn")
private String suerName;
private String userPassword;
@Attribute(name="ou")
private String group;
public Name getId() {
return id;
}
public void setId(Name id) {
this.id = id;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getCommonName() {
return commonName;
}
public void setCommonName(String commonName) {
this.commonName = commonName;
}
public String getSuerName() {
return suerName;
}
public void setSuerName(String suerName) {
this.suerName = suerName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", uid='" + uid + '\'' +
", commonName='" + commonName + '\'' +
", suerName='" + suerName + '\'' +
", userPassword='" + userPassword + '\'' +
", group='" + group + '\'' +
'}';
}
}
/**
* @author WGR
* @create 2021/4/16 -- 19:29
*/
public interface PersonRepository extends CrudRepository<Person, Name> {
}
@Autowired
private PersonRepository personRepository;
@Autowired
private LdapTemplate template;
@Test
public void findAll() throws Exception {
personRepository.findAll().forEach(p -> {
System.out.println(p);
});
}
@Test
public void findAll2(){
Person person = template.findOne(query().where("uid").is("ldapuser2"), Person.class);
System.out.println(person);
}
測試結果: