👌 2022-04-06 LDAP over TLS「StartTLS」
FileInfo Filename - LDAP over TLS Version - v1.0.2204(2022/04/06 ~ 2022/04/07) Author - nuo standuke Email - shadowdoker@gmail.com DescriptionKey - LDAP over TLS with sssd
[TOC]
概述
本文包含如下几点
- LDAP 只允许 StartTLS 访问,后续接入强制要求 TLS 否则拒绝
- ldapphpadmin 使用 StartTLS 访问 LDAP Server
- 客户机 sssd 使用 StartTLS 访问 LDAP Server
- 客户机 ldap-client 使用 StartTLS 访问 LDAP Server
- 第三方客户端 ApacheDirectoryStudio 使用 StartTLS 访问 LDAP Server
感慨 构建完善的 LDAP 企业方案实在是让人头疼,网上资料实在是太少,有也是老版本的配置方法,甚至是完全错误的配置。前前后后琢磨 LDAP over TLS with sssd 大概花了一周时间,从 LDAP 的三种认证方案「这里指的是 LDAP / LDAP+ssl / LDAP+TLS」到 sssd 的接入,再到构建 CA 证书、签发服务端证书,最后实现全程强制 LDAP over TLS,加强企业用户认证安全性。 建议先耐心地将本篇文章仔细阅读完,再去网上搜索其他资料,然后你会发现国内外的好多 LDAP over TLS with sssd 配置文章都是错误的 心累啊……
==此部分操作简单概括来说就是将原先的配置全部改动为使用 StartTLS 方式==
LDAP 的三种认证方案
https://blog.csdn.net/zhf_sy/article/details/117993664 https://www.jianshu.com/p/4c67d3b5e9b7
- LDAP 不加密 = 不安全「默认不加密情况下走 389 端口」
- LDAP over SSL(即 ldaps) = 不够安全,淘汰「当使用 ldaps 的时候走 636 端口」
- LDAP over TLS(即 ldap + TLS)= 够安全「默认走 389 端口,但是会通讯的时候加密,客户端连接LDAP时,需要指明通讯类型为 TLS」
装前先看「错误示范」
1. TLS_REQCERT
官方材料: https://www.openldap.org/software//man.cgi?query=ldap.conf&sektion=5&apropos=0&manpath=OpenLDAP+2.4-Release https://www.openldap.org/doc/admin21/tls.html
网上把 /etc/openldap/ldap.conf
内配置 TLS_REQCERT never
是大错特错
客户端 TLS_REQCERT 参数有以下含义,也就是说,配置了 never 完全是背离 TLS 初衷,同时该参数等效于服务器的 TLSVerifyClient 选项。对于客户端,默认值是 demand,通常没有必要去改此设置。也就是网上在 TLS 配置完后无法使用 LDAP 认证的原因,最后又设置为 never 的独特操作。 对于 LDAP 服务端 TLSVerifyClient 只有在需要双向 TLS 认证的需求下才配置,一般生产环境非高等级安全要求只需要认证服务端有效性即可。不然每个客户端都要签发证书。
TLS_REQCERT <level>
Specifies what checks to perform on server certificates in a TLS
session, if any. The <level> can be specified as one of the
following keywords:
never The client will not request or check any server
certificate.
allow The server certificate is requested. If no certificate is
provided, the session proceeds normally. If a bad
certificate is provided, it will be ignored and the
session proceeds normally.
try The server certificate is requested. If no certificate is
provided, the session proceeds normally. If a bad
certificate is provided, the session is immediately
terminated.
demand | hard
These keywords are equivalent. The server certificate is
requested. If no certificate is provided, or a bad
certificate is provided, the session is immediately
terminated. This is the default setting.
以下为安装完 openldap-client 客户端后默认生成的客户端连接配置文件,从中可以看到,默认只配置了两个参数,注意不要去改动这两个参数
[root@ipa-server ~]# cat /etc/openldap/ldap.conf
#
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#BASE dc=example,dc=com
#URI ldap://ldap.example.com ldap://ldap-master.example.com:666
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
TLS_CACERTDIR /etc/openldap/cacerts
# Turning this off breaks GSSAPI used with krb5 when rdns = false
SASL_NOCANON on
- SASL_NOCANON <on/true/yes/off/false/no>
Turning this off breaks GSSAPI used with krb5 when rdns = false Do not perform reverse DNS lookups to canonicalize SASL host names. The default is off. 关闭此功能会中断 GSSAPI,当 rdns = false 时,与 krb5 一起使用 不要执行反向 DNS 查找以规范化 SASL 主机名。默认值为关闭。
- TLS_CACERTDIR
Specifies the path of a directory that contains Certificate Authority certificates in separate individual files. The TLS_CACERT is always used before TLS_CACERTDIR. This parameter is ignored with GnuTLS. When using Mozilla NSS, may contain a Mozilla NSS cert/key database. If contains a Mozilla NSS cert/key database and CA cert files, OpenLDAP will use the cert/key database and will ignore the CA cert files. 指定在单独的单个文件中包含证书颁发机构证书的目录的路径。 TLS_CACERT 始终在 TLS_CACERTDIR 之前使用。此参数在 GnuTLS 中被忽略。 使用 Mozilla NSS 时, 可能包含 Mozilla NSS 证书/密钥数据库。 如果包含 Mozilla NSS 证书/密钥数据库和 CA 证书文件,OpenLDAP 将使用证书/密钥数据库,并将忽略 CA 证书文件。
构建证书
认证原理
约定 S = Server 服务端,LDAP 服务端 C = Client 客户端,LDAP 客户端
CA 证书是所有证书的鼻祖,所有后续签发的证书均由 CA 证书签发而来。故,为了使所有证书有效,S/C 端必须同时信任 CA 证书,所以 CA 证书需要发放至服务端和客户端。 但这样还没有进行证书通信,所以,还需要签发一个服务端证书,即 ldap 证书,放置在 s 服务端,C 客户端去访问服务端时会拿到 S 服务端的 ldap 证书。那么怎么验证这个 ldap 证书是否有效,就是使用 S/C 共同信任的 CA 证书去验证 ldap 证书的有效性。
创建 CA 证书
使用 OpenSSL 命令行管理证书 openssl生成自签名证书(完整版)
openssl genrsa -out ca.key
openssl req -new -x509 -key ca.key -out ca.crt -days 36525
创建 ldap 证书「即 server 证书」
openssl genrsa -out server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -days 36524
⚠️ 注意:这边在最后第二步,设置 Common Name 的时候必须要设置为 LDAP Server 服务端的 hostname,否则在 client 端验证不通过
验证证书有效性
cp ca.crt ca.pem // 前面懒得改了
openssl verify -CAfile ca.pem ldap.crt
分发证书
cp ca.crt ca.pem // 前面懒得改了
[root@ldap-server certs]# ll
总用量 24
-rw-r--r-- 1 root root 1562 4月 6 19:54 ca.crt # CA 证书,需要发放到每个 LDAP 客户端和服务端
-rw-r--r-- 1 root root 1675 4月 6 19:50 ca.key
-rw-r--r-- 1 root root 1562 4月 6 19:56 ca.pem # = ca.crt CA 证书,需要发放到每个 LDAP 客户端和服务端,只是后缀改了
-rw-r--r-- 1 root root 1456 4月 6 20:43 ldap.crt # LDAP 证书,放在 LDAP 服务端
-rw-r--r-- 1 root root 1147 4月 6 20:42 ldap.csr
-rw-r--r-- 1 root root 1679 4月 6 20:41 ldap.key # LDAP 证书密钥,放在 LDAP 服务端
- LDAP Server
/etc/openldap/certs/ldap.key
/etc/openldap/certs/ldap.crt
/etc/openldap/certs/ca.pem
- LDAP Clients
/etc/openldap/cacerts/ca.pem
开始配置 TLS
LDAP Server
设置主机名
使用 hostnamectl 以及 /etc/hosts 文件配置本机主机名
hostname = TLS 证书的 Common Name
LDAP Server 开启 TLS
- 先把证书放到预定的位置
- 然后在 slapd 内通过 ldapmodify 方式添加配置
[root@ldap-server setup]# cat stan-tls.ldif
dn: cn=config
changetype: modify
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/ldap.key
dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/ldap.crt
[root@ldap-server setup]# cat stan-ca.ldif
dn: cn=config
changetype: modify
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/openldap/certs/ca.pem
ldapmodify -Y EXTERNAL -H ldapi:/// -f stan-tls.ldif
ldapmodify -Y EXTERNAL -H ldapi:/// -f stan-ca.ldif
你可能会遇到如下报错
[root@ldap-server certs]# ldapmodify -Y EXTERNAL -H ldapi:/// -f stan-ca.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"
ldap_modify: Other (e.g., implementation specific) error (80)
就如网上说的一样,是顺序问题,那么问题来了,正确顺序是什么呢?我研究了一下,需要看 cn\=config.ldif
配置文件内的 olcTLSCACertificatePath
、
olcTLSCertificateFile
、
olcTLSCertificateKeyFile
三个参数的顺序,
[root@ldap-server certs]# cat /etc/openldap/slapd.d/cn\=config.ldif
# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 111a4976
dn: cn=config
objectClass: olcGlobal
cn: config
olcArgsFile: /var/run/openldap/slapd.args
olcPidFile: /var/run/openldap/slapd.pid
olcTLSCACertificatePath: /etc/openldap/certs
olcTLSCertificateFile: "OpenLDAP Server"
olcTLSCertificateKeyFile: /etc/openldap/certs/password
structuralObjectClass: olcGlobal
entryUUID: f8d66cdc-4dd5-103c-849c-41b34136ece7
creatorsName: cn=config
createTimestamp: 20220411112627Z
entryCSN: 20220411112627.581346Z#000000#000#000000
modifiersName: cn=config
正如我这边,顺序依次是 olcTLSCACertificatePath
、
olcTLSCertificateFile
、
olcTLSCertificateKeyFile
。
LDAP Server 强制使用 TLS
不配置也可以,这样子有 TLS 证书就会走 TLS 方式,没有的话就会走默认 ldap:/// 方式,处于安全性考虑可以在 Server 服务端强制要求走 TLS 认证
# cat stan-force-tls.ldif
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcSecurity
olcSecurity: tls=1
LDAP Client
LDAP 客户端分为两种,一种是 ldap-client 直接去查询,另一种为 sssd 方式,默认 CLI 使用的是 ldap-client,系统认证走的是 sssd。
设置主机名
通过 /etc/hosts 文件配置服务端主机名
192.168.2.137 ldap-server.expwd.com
ldap-client
#
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
BASE dc=expwd,dc=com
URI ldap://ldap-server.expwd.com/ # 必须要用域名
#URI ldap://ldap.example.com ldap://ldap-master.example.com:666
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
TLS_CACERT /etc/openldap/cacerts/ca.pem # 配置 CA 文件位置
#TLS_CACERTDIR /etc/openldap/cacerts
#TLS_REQCERT try # 客户端不配置,默认是 demand
# Turning this off breaks GSSAPI used with krb5 when rdns = false
SASL_NOCANON on
sssd
[domain/default]
autofs_provider = ldap
cache_credentials = False
#krb5_realm = EXAMPLE.COM
ldap_search_base = dc=expwd,dc=com
#krb5_server = ipa-server.example.com:88
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
ldap_uri = ldap://ldap-server.expwd.com/ # 必须要用域名
ldap_id_use_start_tls = True
ldap_tls_cacertdir = /etc/openldap/cacerts
#ldap_tls_reqcert = never 不配置,默认是 demand
验证
ldapsearch -x -ZZ
能出来结果就可以啦,这个命令意思是强制走 TLS 方式去获取 LDAP 信息。
参考资料
「LDAP开启TLS」👍 https://blog.csdn.net/u011607971/article/details/86153804 「如何加密的OpenLDAP连接使用STARTTLS」 https://blog.csdn.net/seanzed/article/details/77648319 「官方手册」 https://www.openldap.org/doc/admin24/tls.html https://www.openldap.org/software//man.cgi?query=ldap.conf&sektion=5&apropos=0&manpath=OpenLDAP+2.4-Release 「Openldap开启TLS」👍 https://blog.csdn.net/sinat_28007043/article/details/115929633 「openldap加密传输sssd」👍 http://t.zoukankan.com/liujitao79-p-5896878.html 「LDAP over TLS」 https://www.server-world.info/en/note?os=CentOS_6&p=ldap&f=3 「4. 将 LDAP 客户端连接到安全 LDAP 服务」 https://support.google.com/cloudidentity/answer/9089736?hl=zh-Hans#zippy=%2Cgitlab%2Csssdred-hat-enterprise-%E5%92%8C-centos 「3.2. 配置 SSSD 以使用 LDAP 并需要 TLS 身份验证」👍 https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/8/html/configuring_authentication_and_authorization_in_rhel/configuring-sssd-to-use-ldap-and-require-tls-authentication_configuring-sssd-to-use-ldap-and-require-tls-authentication 「TLS Overview」 https://ldapwiki.com/wiki/StartTLS