有没有人使用 OpenLDAP 进行 SSL 客户端身份验证(在 CentOS7 上 - 使用 moznss)?
过去两天我一直试图让它工作,既使用 certutil 数据库,也使用直接 PEM 配置,但很沮丧,因为它不起作用。
我最初的想法是客户端没有发送 SSL 证书进行验证,并且我在使用 PEM 身份验证和 strace 时证明了这一点(并且 crt 文件或密钥上没有 open())。
首先这是RHEL7,并且客户端和服务端都安装了相同版本的openldap:
服务器:
openldap-servers-2.4.39-6.el7.x86_64
openldap-2.4.39-6.el7.x86_64
客户:
openldap-clients-2.4.39-6.el7.x86_64
openldap-2.4.39-6.el7.x86_64
SSL:我自己的 CA。
使用 PEM 身份验证:
服务器(cn=config.ldif):
olcTLSCACertificateFile: /etc/openldap/tls/ldap-ca.crts
olcTLSCertificateFile: /etc/openldap/tls/ldap-server.crt
olcTLSCertificateKeyFile: /etc/openldap/tls/ldap-server.key
olcTLSVerifyClient: hard
服务器(/usr/sbin/slapd -u ldap -h "ldapi:/// ldap:/// ldaps:///" -d 1):
55935ff8 slap_listener_activate(10):
55935ff8 >>> slap_listener(ldaps:///)
55935ff8 connection_get(18): got connid=1000
55935ff8 connection_read(18): checking for input on id=1000
TLS: loaded CA certificate file /etc/openldap/tls/ldap-ca.crts.
TLS: error: the certificate '/etc/openldap/tls/ldap-server.crt' could not be found in the database - error -12285:Unable to find the certificate or key necessary for authentication..
TLS: certificate '/etc/openldap/tls/ldap-server.crt' successfully loaded from PEM file.
TLS: no unlocked certificate for certificate 'CN=x.x.x,...,C=AU'.
TLS: certificate [CN=x.x.x,...,C=AU] is valid
55935ff8 connection_get(18): got connid=1000
55935ff8 connection_read(18): checking for input on id=1000
TLS: error: accept - force handshake failure: errno 11 - moznss error -12285
TLS: can't accept: TLS error -12285:Unable to find the certificate or key necessary for authentication..
55935ff8 connection_read(18): TLS accept failure error=-1 id=1000, closing
55935ff8 connection_close: conn=1000 sd=18
客户端(/etc/openldap/ldap.conf):
TLS_CACERT /etc/openldap/tls/ldap-ca.crts
TLS_CERT /etc/openldap/tls/ldap-client.crt
TLS_KEY /etc/openldap/tls/ldap-client.key
TLS_REQCERT never
客户端(ldapsearch -d1 -H ldaps://xxx -bc=AU'uid=x'):
TLS: loaded CA certificate file /etc/openldap/tls/ldap-ca.crts.
TLS: certificate [CN=x.x.x,...,C=AU] is valid
TLS: error: connect - force handshake failure: errno 21 - moznss error -12271
TLS: can't connect: TLS error -12271:SSL peer cannot verify your certificate..
客户端(strace – 未提供客户端证书)
...
8047 stat("/etc/openldap/tls/ldap-ca.crts", {st_mode=S_IFREG|0644, st_size=5287, ...}) = 0
8047 open("/etc/openldap/tls/ldap-ca.crts", O_RDONLY) = 4
...
仅使用 openssl connect 的客户端连接就可以正常工作:
openssl s_client -connect x.x.x:636 -showcerts -CAfile /etc/openldap/tls/ldap-ca.crts -key /etc/openldap/tls/ldap-client.key -state -cert /etc/openldap/tls/ldap-client.crt
...
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-SHA
Session-ID: [long hex value]
Session-ID-ctx:
Master-Key: [long hex value]
Key-Arg : None
Krb5 Principal: None
PSK identity: None
PSK identity hint: None
Start Time: 1435722028
Timeout : 300 (sec)
Verify return code: 0 (ok)
使用 certutil(moznss 数据库):
同样的问题:
服务器(cn=config.ldif):
olcTLSVerifyClient: hard
olcTLSCertificateFile: "x.x.x - X"
olcTLSCACertificatePath: /etc/openldap/certs
服务器(moznss):
[root@host certs]# certutil -d . -L
Certificate Nickname Trust Attributes
SSL,S/MIME,JAR/XPI
x LDAP CA CT,C,C
x.x.x - X u,u,u
x CA CT,C,C
x CA CT,C,C
服务器(/usr/sbin/slapd -u ldap -h "ldapi:/// ldap:/// ldaps:///" -d 1):
559363d2 connection_get(18): got connid=1000
559363d2 connection_read(18): checking for input on id=1000
TLS: certdb config: configDir='/etc/openldap/certs' tokenDescription='ldap(0)' certPrefix='' keyPrefix='' flags=readOnly
TLS: using moznss security dir /etc/openldap/certs prefix .
TLS: certificate 'x.x.x - X' successfully loaded from moznss database.
TLS: no unlocked certificate for certificate 'CN=x.x.x,...,C=AU'.
TLS: certificate [CN=x.x.x,...,C=AU] is valid
559363d2 connection_get(18): got connid=1000
559363d2 connection_read(18): checking for input on id=1000
TLS: error: accept - force handshake failure: errno 11 - moznss error -12285
TLS: can't accept: TLS error -12285:Unable to find the certificate or key necessary for authentication..
客户端(/etc/openldap/ldap.conf):
TLS_CACERTDIR /etc/openldap/certs
TLS_CERT "x - X"
TLS_REQCERT never
客户端(moznss):
[root@client certs]# certutil -d . -L
Certificate Nickname Trust Attributes
SSL,S/MIME,JAR/XPI
X LDAP CA CT,C,C
x - X u,u,u
X Root CA CT,C,C
X CA CT,,
客户端(ldapsearch -d1 -H ldaps://xxx -bc=AU'uid=x'):
TLS: certdb config: configDir='/etc/openldap/certs' tokenDescription='ldap(0)' certPrefix='' keyPrefix='' flags=readOnly
TLS: using moznss security dir /etc/openldap/certs prefix .
TLS: certificate [CN=x.x.x,...,C=AU] is valid
TLS: error: connect - force handshake failure: errno 21 - moznss error -12271
TLS: can't connect: TLS error -12271:SSL peer cannot verify your certificate..
使用此方法 openssl 测试工作正常,但是 ldapsearch 因相同的错误而失败。strace 没有帮助,但确实显示打开了证书的数据库文件。
客户端(strace):
8075 stat("/etc/openldap/certs/cert8.db", {st_mode=S_IFREG|0644, st_size=65536, ...}) = 0
8075 open("/etc/openldap/certs/cert8.db", O_RDONLY) = 4
8075 stat("/etc/openldap/certs/key3.db", {st_mode=S_IFREG|0644, st_size=16384, ...}) = 0
8075 open("/etc/openldap/certs/key3.db", O_RDONLY) = 5
有人有任何提示吗?(很沮丧 - 我知道我在旧版本的 CentOS 上也做过这个)
答案1
以下内容取自正在运行的 CentOS7 ldap 服务器,应该涵盖 SASL/EXTERNAL(TLS) 身份验证的关键方面。
小贴士:
- 在此示例中,服务器还充当客户端。-
此示例使用~/.ldaprc
而不是/etc/openldap/ldap.conf
- 此示例使用olcTLSVerifyClient: verify
而不是,hard
因为服务器除了支持 SASL/EXTERNAL(TLS) 身份验证之外,还支持其他身份验证类型。
slapd 配置
[root@ldap ~]# ldapsearch cn=config olcTLSCACertificateFile olcTLSCertificateFile olcTLSCertificateKeyFile olcTLSVerifyClient
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <cn=config> (default) with scope subtree
# filter: cn=config
# requesting: olcTLSCACertificateFile olcTLSCertificateFile olcTLSCertificateKeyFile olcTLSVerifyClient
#
# config
dn: cn=config
olcTLSCACertificateFile: /etc/pki/tls/certs/ldap.example.com_CA.crt
olcTLSCertificateFile: /etc/pki/tls/certs/ldap.example.com.crt
olcTLSCertificateKeyFile: /etc/pki/tls/private/ldap.example.com.key
olcTLSVerifyClient: try
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1
证书密钥权限
[root@ldap ~]# ls -lZ /etc/pki/tls/private/ldap.example.com.key
-rw-r-----+ root root unconfined_u:object_r:cert_t:s0 /etc/pki/tls/private/ldap.example.com.key
[root@ldap ~]# getfacl /etc/pki/tls/private/ldap.example.com.key
getfacl: Removing leading '/' from absolute path names
# file: etc/pki/tls/private/ldap.example.com.key
# owner: root
# group: root
user::rw-
user:ldap:r--
group::---
mask::r--
other::---
sasl 配置
[root@ldap ~]# cat /etc/sasl2/slapd.conf
mech_list: external gssapi plain
pwcheck_method: saslauthd
ldap 客户端设置
[root@ldap ~]# cat .ldaprc
URI ldapi:///
BASE cn=config
SASL_MECH external
#TLS_CACERT /etc/ssl/certs/ca-bundle.crt
TLS_CACERT /etc/pki/tls/certs/ldap.example.com_CA.crt
TLS_CERT /etc/pki/tls/certs/ldap.example.com.crt
TLS_KEY /etc/pki/tls/private/ldap.example.com.key
SASL/EXTERNAL(TLS) 绑定成功
[root@ldap ~]# ldapwhoami -ZZ -h ldap.example.com
SASL/EXTERNAL authentication started
SASL username: cn=ldap.example.com,<cert locality info>
SASL SSF: 0
dn:cn=ldap.example.com,<cert locality info>
[root@ldap ~]# ldapwhoami -H ldaps://ldap.example.com
SASL/EXTERNAL authentication started
SASL username: cn=ldap.example.com,<cert locality info>
SASL SSF: 0