AWS负载均衡器后客户端证书认证的问题排查
问题解答
1. 该握手流程是否可行?
可行,但必须让AWS负载均衡器正确处理客户端证书认证的相关信息。默认情况下,AWS负载均衡器若采用SSL终止模式,不会自动将客户端证书转发给后端Apache服务器,导致后端Apache在/login/register*路径要求客户端证书时,无法获取到证书信息,进而触发错误,最终表现为502 Bad Gateway。
实现该流程有两种常见模式:
- SSL直通模式:负载均衡器不终止SSL连接,直接将SSL流量转发给后端Apache,此时后端直接与客户端完成SSL握手及证书验证,原有Apache配置可直接生效,但负载均衡器无法开展基于HTTP的路由等操作。
- SSL终止+证书转发模式:负载均衡器终止SSL连接,同时配置获取客户端证书,并通过HTTP请求头(如
X-SSL-Client-Cert)将证书信息转发给后端Apache,后端需修改配置从请求头提取证书信息,而非直接从SSL会话获取。
2. 排查错误的建议
检查负载均衡器SSL配置
- 确认监听协议:若为HTTPS监听,需开启客户端证书验证选项,并上传对应CA证书
- 若用SSL终止模式,确认是否配置了将客户端证书通过请求头转发给后端服务器
- 若用SSL直通模式,确认负载均衡器是否直接转发TCP流量到后端HTTPS端口(而非HTTP端口)
查看后端Apache日志
- 检查错误日志(通常在
logs/error.log),查找502错误对应的具体原因,比如是否出现SSL client certificate required but not presented类报错 - 查看访问日志,确认负载均衡器的请求是否到达后端,以及请求头中是否包含客户端证书相关信息(若配置了转发)
适配后端Apache配置
- 若负载均衡器为SSL终止并转发证书头,需修改Apache配置:
- 在
<LocationMatch ^/login/register*>块中,将SSLVerifyClient require改为SSLVerifyClient none——因为SSL握手已在负载均衡器完成,后端无需再验证证书 - 添加配置从请求头提取客户端DN信息:
这样PHP代码中RequestHeader set SSL_CLIENT_S_DN "%{X-SSL-Client-DN}e"getenv("SSL_CLIENT_S_DN")就能获取到负载均衡器转发的DN信息
- 在
- 确保Apache的
mod_headers模块已启用,否则无法处理请求头
测试负载均衡器到后端的连通性
- 直接访问后端Apache的
/login/register路径,确认原有功能正常(排除后端自身故障) - 用curl等工具模拟负载均衡器的请求,携带客户端证书相关请求头,测试后端是否能正常响应
原配置与代码参考
Apache服务器配置
SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL SSLCertificateFile cert/2022/test_aws.pem SSLCertificateKeyFile cert/2022/private-key.key SSLCACertificateFile "D:/Apache24/cert/mycard_ca_bundle.crt" SSLCADNRequestFile "D:/Apache24/cert/mycard_ca_bundle_client_cas.crt" SSLVerifyClient none SSLVerifyDepth 10 <LocationMatch ^/login/register*> SSLVerifyClient require </LocationMatch>
register.php代码
<?php ... $clientDN = getenv("SSL_CLIENT_S_DN"); error_log("clientDN=".$clientDN); $emailpair = explode(",", $clientDN)[0]; $email = explode("=", $emailpair)[1]; error_log("user_email=".$email);//further operation for in app authentication ?>
内容的提问来源于stack exchange,提问作者Alexeev Alexander
相关产品推荐
相关产品推荐

