YubiKey搭配Nginx Ingress Controller出现SSL证书400错误的技术问询
在RKE2集群中配置了nginx-ingress-controller,某应用通过Ingress资源启用客户端证书认证,注解配置如下:
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: true nginx.ingress.kubernetes.io/auth-tls-secret: namespace/trusted-certificates nginx.ingress.kubernetes.io/auth-tls-verify-client: on nginx.ingress.kubernetes.io/auth-tls-verify-depth: 3 nginx.ingress.kubernetes.io/backend-protocol: HTTP
客户端证书基于两层PKI层级签发:client-cert <-- SubCA <-- RootCA。使用软PKCS#12密钥库时认证正常,但将密钥库导入YubiKey 5C的PIV应用认证插槽9a后,选择证书并输入PIN后出现400 Bad Request The SSL certificate error nginx错误。Nginx控制器调试日志显示:
client SSL certificate verify error: (2:unable to get issuer certificate) while reading client request header
说明YubiKey未发送客户端证书的签发者证书链。尝试将SubCA和RootCA证书导入YubiKey的82插槽无效,目前仅可行方案是将完整证书链加入Ingress的auth-tls-secret对应的Secret,但需求是仅信任SubCA签发的证书,不想在Ingress配置RootCA,希望YubiKey能像PKCS#12一样发送完整证书链,询问安全配置方法及YubiKey是否支持发送完整链。
1. 导入客户端证书时附带完整签发链
YubiKey的PIV插槽默认仅存储客户端证书本身,不会自动携带签发链。导入到插槽9a时,必须将客户端证书+SubCA证书合并为一个PEM文件后再导入,具体操作:
- 合并证书文件:
cat client-cert.pem subca-cert.pem > client-full-chain.pem - 使用
yubico-piv-tool导入完整链到插槽9a:
完成后YubiKey在TLS握手时会自动发送客户端证书+SubCA证书的完整链,Nginx即可通过SubCA验证客户端证书有效性。yubico-piv-tool -s 9a -i client-full-chain.pem -a import-certificate
2. 优化Ingress验证配置
保持auth-tls-secret中仅存放SubCA证书(无需RootCA),同时将auth-tls-verify-depth调整为2(客户端证书到SubCA仅1层签名,深度设为2足够覆盖验证逻辑,原3的配置也可保留,但2更精准)。此时Nginx会直接用SubCA验证客户端证书的签名,完全符合“仅信任SubCA签发证书”的需求。
3. 验证YubiKey的证书链配置
导入完成后,通过命令检查插槽9a的证书内容,确认包含完整链:
yubico-piv-tool -s 9a -a read-certificate
输出应显示连续的客户端证书和SubCA证书内容。
4. 排除系统证书存储干扰
部分操作系统会默认从系统信任库加载根证书,可能影响YubiKey的证书链发送行为。测试时可指定仅使用YubiKey的证书,例如用curl测试:
curl --cert-type PEM --engine pkcs11 --cert "pkcs11:token=YubiKey;object=Authentication" https://your-ingress-domain
内容的提问来源于stack exchange,提问作者user1563721

