docker 映射到/dev:/dev,设置ejbca容器privileged权限
services:
ejbca:
image: keyfactor/ejbca-ce
hostname: ca.hetao.me
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- ./data/ejbca/persistent:/mnt/persistent
- ./data/ejbca/external:/mnt/external
- ./data/ejbca/pkcs11:/opt/pkcs11
- ./data/ejbca/pkcs11/99-deny-all.rules:/etc/polkit-1/rules.d/99-deny-all.rules
- ./data/ejbca/conf/web.properties:/opt/keyfactor/ejbca/conf/web.properties
- /dev:/dev
ports:
- 192.168.33.38:443:8443/tcp
- 192.168.33.38:80:8080/tcp
# devices:
#- /dev/bus/usb
privileged: true
environment:
- "TLS_SETUP_ENABLED=later"
- "PROXY_HTTP_BIND=0.0.0.0"
- "TZ=Asia/Shanghai"
执行
microdnf install chkconfig pcsc-lite procps-ng opensc vi usbutils psmisc tar gzip -y
rpm -i SafenetAuthenticationClient-core-10.8.1050-1.el9.x86_64.rpm
web.properties添加以下内容
cryptotoken.p11.lib.200.name=eToken
cryptotoken.p11.lib.200.file=/usr/lib64/libeToken.so
执行以下命令,开启java的pkcs11功能
echo -e "\nJAVA_OPTS=\"\$JAVA_OPTS --add-exports=jdk.crypto.cryptoki/sun.security.pkcs11.wrapper=ALL-UNNAMED\"" >> /opt/keyfactor/appserver/bin/standalone.conf
创建/etc/polkit-1/rules.d/99-deny-all.rules
并添加以下内容
polkit.addRule(function(action, subject) {
return polkit.Result.YES;
});
然后执行
systemctl daemon-reload && systemctl daemon-reexec
(如果有systemctl的话)
和
/opt/keyfactor/appserver/bin/jboss-cli.sh --connect ':reload'
最后只是调出了pkcs11 token的选项,并不能正常使用pkcs11 token(容器中缺少必要的组件和安全服务(polkit))
在原生Linux中用上述方法是能成功的
同样的方法也适用于基于OpenSC的ePass2003,但是OpenSC似乎不完善,会出现RSA签名无法通过验证,etoken 5110生成密钥速度慢,但还算稳定,在almalinux和ubuntu上都没有任何问题,就是linux上的驱动不好找。
后来分析了pcscd以及polkit的日志及源码,发现是polkit启动的时候依懒dbus服务,容器中无法启动dbus服务。但是新版本的pcscd提供了选项可以在编译时和运行时禁用polkit的支持。
重新编译最新版本的pcsc,然后以以下命令启动即可:
tar -zxf pcsc.tar.gz -C / --strip-components 1
tar -zxf ccid.tar.gz -C / --strip-components 1
pcscd --disable-polkit
使用中发现如果pcscd进程重启后,java进程也要重启,不然会报Token has been removed的异常。
对于ePass2003无法执行RSA签名的问题可以通过
update-crypto-policies --set LEGACY
来修复
通过参考这里的方法:https://github.com/Keyfactor/keyfactorcommunity/blob/main/hsm-integration/hsm-driver-smartcard-hsm/README.md
我有了更好的解决方案
services:
ejbca:
image: keyfactor/ejbca-ce
hostname: ca.hetao.me
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- ./data/ejbca/persistent:/mnt/persistent
- ./data/ejbca/external:/mnt/external
- ./data/ejbca/conf/web.properties:/opt/keyfactor/ejbca/conf/web.properties
- ./data/ejbca/conf/standalone.conf:/opt/keyfactor/wildfly-33.0.0.Final/bin/standalone.conf
- /lib/x86_64-linux-gnu/libpcsclite.so.1.0.0:/usr/lib64/libpcsclite.so.1.0.0:ro
- /lib/x86_64-linux-gnu/libpcsclite.so.1.0.0:/usr/lib64/libpcsclite.so.1:ro
- ./data/ejbca/pkcs11/libeToken.so:/usr/lib64/pkcs11/libeToken.so:ro
- ./data/ejbca/pkcs11/libeToken.so:/usr/lib64/libeToken.so:ro
- /var/run/pcscd:/var/run/pcscd:ro
ports:
- 192.168.33.38:443:8443/tcp
- 192.168.33.38:80:8080/tcp
以这种方式创建ebjca容器可以在在ejbca中直接使用eToken5110。
原理是在缩主机上运行pcscd服务,在容器中运行pcsc客户端功能,需要把pcsc的socket(/var/run/pcscd/pcscd.comm)和客户端(libpcsclite.so)库映射到容器中。
eToken的pkcs11库可以从rpm包中提取出来映射到容器中,至于OpenSC也不是eToken必须的,这样就不需要在容器中安装任何软件了。
其它问题
- 修复ePass2003 RSA密钥无法签名的问题
在cesecore.properties中添加以下配置
pkcs11.disableHashingSignMechanisms=false
这样在签名时不使用java自己的hash,而是使用hsm内置的hash,有些token不允许在外部进行hash.
这样修改后以前生成的CA证书会失效,需要注意。
参考:
https://www.smartcard-hsm.com/2014/09/05/Accessing_your_SmartCard-HSM_from_EJBCA.html
https://doc.primekey.com/ejbca/ejbca-integration/hardware-security-modules-hsm/nitrokey-hsm