Keycloak使用群晖Synology Directory Server作为AD/LDAP用户数据源
这又是keycloak的另外一个大坑。keycloak并不会自动创建一系列SSL证书相关的配置,都要自己手撸。
如果还没安装keycloak,可以参考前一篇文章『Docker Compose安装Keycloak』
然后,你的群晖要先把AD配置好,这里就不重复了。
1、获得群晖AD对应的SSL证书
首先,要把群晖为AD所生产的自签名SSL证书下载回来,后面需要用。
位置:群晖DSM管理后台-控制面板-安全性-证书。如果不太确定是哪张证书,可以点击『设置』,找到『Synology Directory Server』对应的证书下拉。
在对应的证书上点击右键,选择『导出证书』
导出的证书解压后有两个文件,一个是证书本身cert.pem,另外一个是证书的私钥privkey.pem,我们需要用到的是cert.pem
另外一个使用OpenSSL来获取证书的方法(方便不支持导出的LDAP服务器)
openssl s_client -showcerts -verify 5 -connect <AD/LDAP服务器IP或者域名>:636 < /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/) {a++}; out="ad-cert-"a".pem"; print >out}'
上面命令运行后,当前目录下会生成多个ad-cert-x.pem的证书文件,找到对应的证书即可。
OK,基础数据准备好,我们开始干活。
2、为keycloak生成Java所需要用的keystore文件
这里有个大坑。虽然新版本的Java建议出于更高的安全性考虑,keystore应该使用PKCS12格式,keytool也是默认创建PKCS12格式的keystore。但,keycloak不认。
所以,我们还是需要创建JKS格式的keystore文件。
别问我怎么知道的,晚上10点搞到凌晨3点。
我们进入到放置docker-compose.yml
的目录,创建一个存放证书的目录certs
,并且把前面群晖导出的cert.pem
也拷贝进去,一会需要用来导入
mkdir certs
# 下面的cert.pem改为自己实际存放的路径
cp ~/archive/cert.pem certs
# 创建keystore文件
keytool -genkeypair -storepass password -storetype JKS -keyalg RSA -keysize 2048 -validity 3650 -dname "CN=KeyCloak" -alias KeyCloak -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore certs/server.jks
# 把群晖的证书导入keystore
keytool -storepass password -noprompt -trustcacerts -alias nas.synology -import -file certs/cert.pem -keystore certs/server.jks
如果系统提示没有keytool,那么安装一下
apt install openjdk-11-jre-headless
3、把keystore映射到docker
正常情况下,docker-compose的up和down会删掉镜像里面的内容重新创建,所以刚才创建的证书如果直接放入到容器里,会丢失。我们有两个方法解决这个问题,一个是自己通过dockerfile创建docker镜像,另外一个是把文件夹映射到容器。我们就不整那么麻烦的事情了,直接映射文件夹是最方便的。
我们需要在docker-compose.yml
里面增加下面两段
volumes:
- ./certs:/opt/keycloak/certs
这样就把当前certs文件夹映射到容器的/opt/keycloak/certs了
4、为KeyCloak指定使用自己创建的keystore文件
同样,在docker-compose.yml
里面,environment段增加下面的内容
KC_SPI_TRUSTSTORE_FILE_FILE: /opt/keycloak/certs/server.jks
KC_SPI_TRUSTSTORE_FILE_PASSWORD: password
KC_SPI_TRUSTSTORE_FILE_HOSTNAME_VERIFICATION_POLICY: ANY
KC_HTTPS_TRUST_STORE_FILE: /opt/keycloak/certs/server.jks
KC_HTTPS_TRUST_STORE_PASSWORD: password
修改过的docker-compose.yml
,看起来大概是这样(注意缩进,注意缩进,注意缩进)
然后,我们重启一下容器
docker-compose down
docker-compose up -d
这样,KeyCloak应该就可以正确识别SSL证书了。
5、KeyCloak中增加User Federation
我们进入KeyCloak的管理后台,左侧导航点击『User federation』,选择添加一个LDAP的源。
接着就看图说话。基本上只要改前面的内容,后面的内容就保持默认好了。
关于DN的问题,可以参考文章『Gitlab整合群晖Synology Active Directory』
提供上面的一些字符串,方便复制修改
CN=Administrator,CN=Users,DC=NAIZHAO,DC=COM
CN=Administrator,CN=Users,DC=BRA,DC=DO
保存完,我们就可以开始测试了。
6、测试用户数据是否正常
点击左侧导航Clients,然后点击account右边的URL,会进入到一个登陆页面(新开个浏览器,或者浏览器开个无痕窗口,不然当前浏览器有cookie,默认就登录了)。点击页面右上角的『Sign in』,新页面里面输入AD里面的用户名和密码,正常的话就登录成功了。
然后我们回到管理页面,点击左侧的Users,Search Users的输入框里面输入一个星号*,点击搜索,你会发现AD里面的用户都出来了
OK,搞定。后面可以继续创建realm,创建openid client。
7、关于DN,多说一嘴
很多朋友搞不清什么是DN。其实简单理解,DN和文件夹、DNS都很像,也有一定的关联。
比如有个用户叫Bra,组织架构是在集团Com,事业群Naizhao,研发部Dev的运维Ops下面,那么找到Bra,有几种方法:
文件夹(目录)方式
COM\NAIZHAO\DEV\OPS\BRA
域名方式
bra.ops.dev.naizhao.com
Active Directory/LDAP的DN方式
CN=Bra,CN=Ops,CN=Dev,DC=NAIZHAO,DC=COM
8、关于从Windows Active Directory同步的其他一些补充
从Windows AD同步的时候,cn属性值是用户的全名。Windows AD用户全名默认是用户的姓+名的组合,所以并不一定是登陆的用户名,特别是姓名是中文的时候。所以,如果使用Windows AD作为用户数据源,我们需要把设置中『LDAP searching and updating』-『Username LDAP attribute』从cn改为sAMAccountName,同时把『Mappers』-『username』-『LDAP Attribute』也从cn改为sAMAccountName,保存即可。