我在 Centos7 虚拟机上安装了 Apache 和 mod_ssl。我尝试使用 PKCS#11 上 HSM 保护的私钥来使 TLS 工作,但当我尝试启动 Apache 时,它找不到我的私钥(请参阅下面的错误)。此外,我们的 PKCS#11 库的日志中没有任何内容。
另一方面,如果我尝试直接从命令行使用具有相同 PKCS#11 URI 的 OpenSSL,它能够与 HSM 后端通信并识别密钥。同时还会出现 PKCS#11 库的日志。
openssl rsautl -engine pkcs11 -keyform engine -inkey 'pkcs11:type=private?pin-value=121212;token=VendorPKCS11;id=%51' -sign -in myinputfile.txt -out myoutputfile.txt
对我来说,Apache 似乎出于某种原因没有加载我们的 PKCS#11 库,但我不知道为什么。我发现这在 Google 中,但不是很详细。
以下是我所设置的...
/etc/httpd/conf.d/ssl.conf:
(注意:apachecert.pem 是使用 HSM 上的私钥进行自签名的。)
Listen 443 https
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice pkcs11
<VirtualHost _default_:443>
DocumentRoot "/var/www/html"
ServerName myserver:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/apachecert.pem
SSLCertificateKeyFile "pkcs11:type=private?pin-value=121212;token=VendorPKCS11;id=%51"
</VirtualHost>
/etc/pki/tls/openssl.cnf:
openssl_conf = openssl_def
[openssl_def]
engines = engine_section
[engine_section]
pkcs11 = pkcs11_section
[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib64/openssl/engines/libpkcs11.so
MODULE_PATH = /etc/pki/tls/libVendorPKCS11.so
init = 0
/etc/pki/tls/VendorPKCS11.properties:
log.folder.path=/etc/pki/tls/p11logs
log.level=5
delay.between.auto.recovery.attempts=300
authentication.mode=TICKET
portal.server.list=node1
token.label=VendorPKCS11
token.manufacturer.id=Vendor
token.model=HSM Portal Token
token.serial.number=1
token.max.pin.length=1024
token.min.pin.length=1
token.hardware.version=1.0
token.firmware.version=1.0
slot.description=Vendor HSM Portal PKCS11
slot.manufacturer.id=Vendor
slot.hardware.version=1.0
slot.firmware.version=1.0
info.cryptoki.interface.version=2.20
info.manufacturer.id=Vendor
info.library.description=HSM Portal based PKCS11 library
info.library.version=2.0
credentials.user.name=username
portal.node1.uri=backendserver:8999
portal.node1.certificate.path=/etc/pki/tls/rootcer.pem
portal.node1.concurrent.clients=2
timeout.connection=15000
timeout.command=60000
timeout.keep.alive=600000
尝试启动 Apache 时看到的错误:
Oct 22 08:55:25 myserver systemd[1]: Starting The Apache HTTP Server...
Oct 22 08:55:25 myserver httpd[11013]: AH00526: Syntax error on line 112 of /etc/httpd/conf.d/ssl.conf:
Oct 22 08:55:25 myserver httpd[11013]: SSLCertificateKeyFile: file '/etc/httpd/pkcs11:type=private?pin-value=121212;token=VendorPKCS11;id=%51' does not exist or is empty
Oct 22 08:55:25 myserver systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
Oct 22 08:55:25 myserver kill[11015]: kill: cannot find process ""
Oct 22 08:55:25 myserver systemd[1]: httpd.service: control process exited, code=exited status=1
Oct 22 08:55:25 myserver systemd[1]: Failed to start The Apache HTTP Server.
Oct 22 08:55:25 myserver systemd[1]: Unit httpd.service entered failed state.
Oct 22 08:55:25 myserver systemd[1]: httpd.service failed.
有谁知道为什么 Apache 无法找到供应商 PKCS#11 库或至少没有显示任何日志?我还发现奇怪的是,在 Apache 的错误输出中,某些内容在 PKCS#11 URI 前面添加了“/etc/httpd/”。
答案1
经过一番思考后,我意识到 PKCS#11 URI 仅在 Apache 的开发分支(版本 2.5.1)中实现。它在最新的稳定版本 2.4 中不可用。
包含此功能的一个修订版本如下:https://svn.apache.org/viewvc?view=revision&revision=1830819
因此目前我尝试实现的目标似乎无法通过 Apache 2.4 和 mod_ssl 实现。
由于 Apache 次版本号中的奇数仅被视为 Alpha/Beta,因此我们似乎需要等待 httpd 2.6 发布。我找不到有关这方面的任何信息,所以现在我不会抱太大希望。
我一直在研究使用 Apache 和 PKCS#11 的其他方法:
- 使用 mod_nss 而不是 mod_ssl
- 拥有一个 PKCS#11 模块,能够从假密钥文件中获取参数(以便 Apache 2.4 能够无问题地读取 ssl 配置)