不能。mod_log_config无法记录SSL/TLS握手失败的底层错误码,因握手失败时连接未建立,HTTP流程未启动,该模块不参与且%{SSL_*}x变量均为空;错误码仅见于error_log中,需配合LogLevel ssl:debug和openssl errstr解析。

不能。
mod_log_config 无法记录 SSL/TLS 握手失败时的底层错误码,因为它根本收不到失败连接的日志事件。
握手失败发生在 TLS 协商阶段,连接尚未建立成功,HTTP 请求流程不会启动,Apache 的日志模块(包括 mod_log_config)完全不参与这个过程。所有 %{SSL_*}x 类变量(如 %{SSL_PROTOCOL}x、%{SSL_CIPHER}x)都依赖 OpenSSL 已完成握手并创建了有效 SSL 连接对象——失败场景下这些变量为空或不可用,mod_log_config 拿不到任何值。
真正能捕获失败错误码的地方只有一个:Apache 的 error_log。
✅ 正确做法:从 error_log 中提取 OpenSSL 错误码
握手失败时,mod_ssl 会在 error_log 中输出带 SSL_do_handshake() failed 或 SSL_accept() failed 的行,并附带 OpenSSL 错误码,例如:
[ssl:info] [pid 12345] SSL_do_handshake() failed: ... [ssl:error] [pid 12345] SSL Library Error: error:1407609C:SSL routines:SSL23_GET_CLIENT_HELLO:http request
这类十六进制错误码(如 1407609C)就是你要的“底层详细协议错误码”。
- 使用
openssl errstr 1407609C可解析含义(本例为客户端发了 HTTP 明文请求,却连了 HTTPS 端口); - 日志中紧邻的上下文(如
SNI hostname、protocol、cipher list received)也常含关键线索。
? 提升 error_log 诊断能力的关键配置
# 在 httpd.conf 或虚拟主机配置中设置 LogLevel info ssl:debug
-
ssl:debug是重点:它会让mod_ssl输出握手各阶段状态(ClientHello 解析、证书加载、密钥交换尝试等),远比warn或error级别详细; - 注意:仅临时开启,避免日志爆炸和性能影响。
同时确保:
-
SSLEngine on已启用; -
ErrorLog路径可写,且未被重定向或截断。
? 为什么其他方式不行?
-
CustomLog+mod_log_config格式:所有%{SSL_*}x字段在握手失败时无值,日志行甚至不会生成; -
环境变量(如
%{SSL_CIPHER}e):同样依赖会话已建立,失败时不设; -
SetEnvIf匹配 TLS 字段:无法匹配不存在的握手上下文。
? 补充建议:快速定位错误码的实用命令
在服务器上执行:
# 实时跟踪最新 SSL 相关错误 tail -f /var/log/apache2/error.log | grep -i -E "(ssl|handshake|failed|error:...)" # 解析特定错误码(替换为你看到的码) openssl errstr 1408A0C1
若需结构化分析,可配合 awk/grep 提取错误码并批量解析,或用 logrotate 配合脚本做日志归档与告警。
不复杂但容易忽略。











