写在前面的话:
部署openLDAP 2.4.44
(centOS 7.X 直接yum 安装的版本),之前在网上查找过教程,大多数openLDAP 2.3.X
初始配置已经有了很大变化。说直接改/etc/openldap/slapd.conf
没有就新建,或者修改/etc/openldap/slapd.d/
下的文件。最后导致slapd服务总是起不来。所以写下这个教程,避坑。
yum install -y openldap openldap-servers openldap-clients openldap-devel
[root@localhost ~]# slappasswd
New password: //此处输入密码
Re-enter new password: //再次密码
{SSHA}CrdqT5EAh8H2y2SorEUbuxP3R5eOggjb
{SSHA}CrdqT5EAh8H2y2SorEUbuxP3R5eOggjb
复制出来,后面用得到
OpenLDAP 2.3之后的版本取消了/etc/openldap/slapd.conf的配置方式,使用ldif文件动态配置
vi /usr/share/openldap-servers/slapd.ldif
可以参考我的修改
[root@localhost ~]# cat /usr/share/openldap-servers/slapd.ldif
#
# See slapd-config(5) for details on configuration options.
# This file should NOT be world readable.
#
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
#
# TLS settings
# 这是关于ssl协议的证书配置,我是用是openSSL生成的自签证书
olcTLSCACertificatePath: /etc/openldap/certs
olcTLSCertificateFile: /etc/openldap/certs/ldap.crt
olcTLSCertificateKeyFile: /etc/openldap/certs/ldap.key
#
# Do not enable referrals until AFTER you have a working directory
# service AND an understanding of referrals.
#
#olcReferral: ldap://root.openldap.org
#
# Sample security restrictions
# Require integrity protection (prevent hijacking)
# Require 112-bit (3DES or better) encryption for updates
# Require 64-bit encryption for simple bind
#
#olcSecurity: ssf=1 update_ssf=112 simple_bind=64
#
# Load dynamic backend modules:
# - modulepath is architecture dependent value (32/64-bit system)
# - back_sql.la backend requires openldap-servers-sql package
# - dyngroup.la and dynlist.la cannot be used at the same time
#
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
#olcModulepath: /usr/lib/openldap
olcModulepath: /usr/lib64/openldap
olcModuleload: accesslog.la
olcModuleload: auditlog.la
olcModuleload: back_dnssrv.la
olcModuleload: back_ldap.la
olcModuleload: back_mdb.la
olcModuleload: back_meta.la
olcModuleload: back_null.la
olcModuleload: back_passwd.la
olcModuleload: back_relay.la
olcModuleload: back_shell.la
olcModuleload: back_sock.la
olcModuleload: collect.la
olcModuleload: constraint.la
olcModuleload: dds.la
olcModuleload: deref.la
#olcModuleload: dyngroup.la
olcModuleload: dynlist.la
olcModuleload: memberof.la
olcModuleload: pcache.la
olcModuleload: ppolicy.la
olcModuleload: refint.la
olcModuleload: retcode.la
olcModuleload: rwm.la
olcModuleload: seqmod.la
olcModuleload: smbk5pwd.la
olcModuleload: sssvlv.la
olcModuleload: syncprov.la
olcModuleload: translucent.la
olcModuleload: unique.la
olcModuleload: valsort.la
#
# Schema settings
#
dn: cn=schema,cn=config
objectClass: olcSchemaConfig
cn: schema
include: file:///etc/openldap/schema/core.ldif
#
# Frontend settings
#
dn: olcDatabase=frontend,cn=config
objectClass: olcDatabaseConfig
objectClass: olcFrontendConfig
olcDatabase: frontend
#
# Sample global access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
#
#olcAccess: to dn.base="" by * read
#olcAccess: to dn.base="cn=Subschema" by * read
#olcAccess: to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!
#
#
# Configuration database
#
dn: olcDatabase=config,cn=config
objectClass: olcDatabaseConfig
olcDatabase: config
olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,c
n=auth" manage by * none
#
# Server status monitoring
#
dn: olcDatabase=monitor,cn=config
objectClass: olcDatabaseConfig
olcDatabase: monitor
olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,c
n=auth" read by dn.base="cn=root,dc=这里改成自己的,dc=com" read by * none
#
# Backend database definitions
#
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
olcSuffix: dc=这里改成自己的,dc=com
olcRootDN: cn=root,dc=这里改成自己的,dc=com
olcRootPW: {SSHA}PU4CNCews363SCGpb4hUYmrkHyMnUCrX 密码是前面生成的
olcDbDirectory: /var/lib/ldap
olcDbIndex: objectClass eq,pres
olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub
[root@localhost ~]#
[root@localhost ~]# rm -rf /etc/openldap/slapd.d/*
[root@localhost ~]# cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
[root@localhost ~]# slapadd -n 0 -F /etc/openldap/slapd.d -l /usr/share/openldap-servers/slapd.ldif
[root@localhost ~]# chown -R ldap.ldap /etc/openldap/slapd.d/*
[root@localhost ~]# chown -R ldap.ldap /var/lib/ldap/*
[root@localhost ~]# systemctl start slapd
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
[root@localhost ~]# ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
[root@localhost ~]# vim base.ldif
dn: dc=这里改成自己的,dc=com
o: 这里改成自己的
objectclass: dcObject
objectclass: organization
[root@localhost ~]# ldapadd -f base.ldif -x -D cn=root,dc=这里改成自己的,dc=com -W
输入密码
slapd -h "ldap:/// ldaps:///"
slapd -h "ldap://:123"
netstat -tunlp 查看
一.Server端自签名证书(ldap.key(私钥)、ldap.crt(证书、公钥))
1、首先安装openssl,已安装请忽略
yum -y install openssl
2、生成server端的私钥
cd /etc/openldap/certs/
openssl genrsa -out ldap.key 2048 //私钥
3、生成签名请求
openssl req -new -key ldap.key -out ldap.csr //生成签名请求
只有Common Name项一定要填写Sever的IP或域名,其余项可不填写。
4、生成自签名CA证书(报错,用于导入华为存储的)
openssl x509 -req -days 1095 -in ldap.csr -signkey ldap.key -out ldap.crt//公钥(自签名)
/**
* 连接LDAP
* @param userName uid
* @param passwd
* @param SearchName 所在的目录 例如ou=test,dc=maxcrc,dc=com
* @return
*/
public static DirContext connectLDAP(String userName, String passwd) {
Hashtable env = new Hashtable();
logger.debug("===" + userName + "==="+passwd);
env.put(Context.SECURITY_PRINCIPAL, userName );//用户名 全路径
env.put(Context.SECURITY_CREDENTIALS, passwd);//密码
env.put(Context.PROVIDER_URL, "ldap://127.0.0.1:389");//连接LDAP的URL和端口
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");//JNDI Context工厂类
env.put(Context.SECURITY_AUTHENTICATION, "simple");//认证类型
DirContext ctx=null;
try {
ctx = new InitialLdapContext(env, null);//开始连接
logger.debug("===auth OK===");
} catch (NamingException e) {
e.printStackTrace();
logger.error("===auth ERR==="+e.getMessage());
}
return ctx;
}
根据网上教程,导入后
keytool -import -alias ldapserver -file D:\test\server.cert -keystore cacerts -storepass changeit
//具体可百度
env.put(Context.PROVIDER_URL, "ldaps://127.0.0.1:636");//导入的是jre目录下的cacerts 就可以连接
因为JVM启动只加载一次证书,如果不重启加载,这需要重写SSL SocketFactory
public class LdapSocketFactory extends SocketFactory {
private static final Logger logger = RootLogger.getLog(LdapSocketFactory.class.getName());
private static LdapSocketFactory instance = null;
private SSLContext sslContext = null;
private static String certFileName = "C:\\ldap.crt";
public static SocketFactory getDefault() {
try {
instance = new LdapSocketFactory();
instance.initFactory();
} catch (Exception e) {
e.printStackTrace();
logger.debug("Returning null socket factory");
}
return instance;
}
private void initFactory() throws Exception {
logger.debug("Initializing socket factory...");
InputStream certStream = new FileInputStream(certFileName);
CertificateFactory certificateFactory = CertificateFactory
.getInstance("X.509");
Certificate certificate = certificateFactory
.generateCertificate(certStream);
logger.debug("The certificate was generated. It is issued to "
+ ((X509Certificate) certificate).getSubjectDN());
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, "myPassword".toCharArray()); //自定义密码
new KeyStore.TrustedCertificateEntry(certificate);
keyStore.setCertificateEntry("myCert", certificate);//自定义名称
logger.debug("The Keystore was initialized.");
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance("SunX509", "SunJSSE");
trustManagerFactory.init(keyStore);
logger.debug("The TrustManagerFactory was initialized.");
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(),
new SecureRandom());
logger.debug("The SSLContext was initialized.");
}
@Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
// TODO Auto-generated method stub
return sslContext.getSocketFactory().createSocket(host, port);
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
// TODO Auto-generated method stub
return sslContext.getSocketFactory().createSocket(host, port);
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException, UnknownHostException {
// TODO Auto-generated method stub
return sslContext.getSocketFactory().createSocket(host, port, localHost, localPort);
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
int localPort) throws IOException {
// TODO Auto-generated method stub
return sslContext.getSocketFactory().createSocket(address, port, localAddress, localPort);
}
}
在connectLDAP方法中 添加
env.put("java.naming.ldap.factory.socket", LdapSocketFactory.class.getName());
如此,每次连接都会加载证书