1. 目的
Keycloak 和 Crowd 是企业内部常用的两种单点登录系统,二者都支持使用 Active Directory 作为用户、组的存储,以及作为背后真正的认证系统。本文使用 Samba 4 替代 Active Directory,并配置 Keycloak 和 Crowd 使用 Samba 4 ,整个过程使用了 macOS 以及 VMWare Fusion 虚拟机,这些步骤也可以照搬到真实物理机上。
2. 搭建 Samba DC
Samba 4 增加了 Microsoft Active Directory 的 Domain Controller 功能,包含 DNS server, Kerberos server, LDAP server,实际对于 Keycloak 和 Crowd 来说只需要用 AD 里头 LDAP server 功能。 以下步骤参考 Matei Cezar 的 Samba 系列文章:
-
Create an Active Directory Infrastructure with Samba4 on Ubuntu – Part 1
-
How to Manage Samba4 AD Infrastructure from Linux Command Line – Part 2
2.1 在 VMware Fusion 里安装 Ubuntu 20.04 server edition
这个没啥好说的,具体步骤省略。
2.2 安装 Samba DC
这里假定 Ubuntu 主机名为 ad
,域为 example.me
。
-
apt install samba winbind krb5-user
-
确保 samba 服务是停止状态:
systemctl stop samba-ad-dc.service smbd.service nmbd.service winbind.service systemctl disable samba-ad-dc.service smbd.service nmbd.service winbind.service
-
备份
/etc/samba/smb.conf
mv /etc/samba/smb.conf /etc/samba/smb.conf.initial
-
初始化 AD domain
samba-tool domain provision --use-rfc2307 --interactive # Realm 填写:EXAMPLE.ME # 后面都选默认值,除了 DNS forwarder IP address 填写非本机 IP,因为 Ubuntu # 默认启动了 systemd-resolved 监听本机 53 端口,会跟 winbindd 冲突
-
设置默认
/etc/krb5.conf
配置:mv /etc/krb5.conf /etc/krb5.conf.initial ln -s /var/lib/samba/private/krb5.conf /etc/
-
禁用
systemd-resolved
,避免跟winbindd
冲突systemctl stop systemd-resolved systemctl disable systemd-resolved # 修改 /etc/resolv.conf,内容如下: nameserver 127.0.0.1 options edns0 search example.me
-
启动 Samba Active Directory Domain Controller 服务:
systemctl unmask samba-ad-dc.service # Samba 安装后默认是 standalone 模式,这个 service 被自动 mask 掉了 systemctl start samba-ad-dc.service systemctl status samba-ad-dc.service systemctl enable samba-ad-dc.service
-
检查 Samba 是否运行正常
samba-tool domain level show # 应该输出: Domain and forest function level for domain 'DC=example,DC=me' host -t A example.me host -t A ad.example.me host -t SRV _kerberos._udp.example.me # UDP Kerberos SRV record host -t SRV _ldap._tcp.example.me # TCP LDAP SRV record # 应该都能成功解析 kinit administrator@EXAMPLE.ME klist # 应该能成功申请到 ticket
-
增加测试用户和组
samba-tool user add test --given-name=test-given --surname=test-sur \ --mail-address=test@example.me --login-shell=/bin/bash samba-tool user list samba-tool group add test-group samba-tool group list samba-tool group addmembers test-group test samba-tool group listmembers test-group samba-tool domain passwordsettings show wbinfo -g # 显示组列表 wbinfo -u # 显示用户列表 wbinfo -i test # 显示用户信息
3. 配置 Crowd
-
配置 JDK 的 cacerts 文件,信任 samba server 的 CA 证书
# 复制 /var/lib/samba/private/tls/ca.pem 到 Crowd 所在机器(本文使用本地的 macOS 系统) # 导入到 cacerts,cacerts keystore 的默认密码是 changeit sudo keytool -import -alias ad.example.me-ca -file ca.pem \ -keystore /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/security/cacerts
-
修改 /etc/hosts 加入
172.16.56.137 ad.example.me
,这里的 IP 是 Samba 服务所在机器的 IP,请自行修正。 -
启动 Crowd
# JDK >= 11 默认使用 TLS 1.3,但实现有个问题,会导致 Crowd 连接 Samba 时报错: # javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request # 解决办法是使用 JDK < 11,或者使用 java 选项 -Djdk.tls.client.protocols=TLSv1.2 # 参考: https://mongodb.github.io/mongo-java-driver/4.1/driver/tutorials/ssl/ export JAVA_HOME=`/usr/libexec/java_home -v 1.8` atlassian-crowd-4.1.0/start_crowd.sh
-
在 Crowd 里增加 Directory,在 Connector 标签页里设置如下字段:
- URL: ldaps://ad.example.me:636/
- SSL: LDAPS
- Base DN: CN=Users,DC=example,DC=me
- Username: administrator@EXAMPLE
-
在 Crowd 里配置对应目录的对应组可以登录 Crowd web console:
- Applications 标签页,选择 “Crowd”
- Directories & groups 标签页,添加刚配置的 Active Directory,并拖动调整优先级到第一位,然后此目录条目右边的 Action,选择 “Configure authentication”,把 test-group 加入允许列表里。
4. 配置 Keycloak
-
配置 JDK 的 cacerts 文件,同上
-
修改 /etc/hosts,同上
-
启动 Keycloak
export JAVA_HOME=`/usr/libexec/java_home -v 1.8` keycloak-11.0.3/bin/standalone.sh
-
在 Keycloak 里增加 LDAP 类型的 User Federation,在 Settings 标签页里设置如下字段:
- Import Users: ON
- Edit Mode: WRITABLE
- Sync Registrations: ON
- Vendor: Active Directory
- Username LDAP attribute: sAMAccountName
- Connection URL: ldaps://ad.example.me:636
- Users DN: CN=Users,DC=example,DC=me
- Bind DN: administrator@EXAMPLE
5. 使用 Apache Directory Studio 访问 Samba DC
在新建连接对话框里设置如下:
- Hostname: ad.example.me
- Port: 636
- Encryption method: Use SSL encryption (ldaps://)
- Bind DN or user: administrator@EXAMPLE