如何在Nginx中扩展SSL握手错误日志以记录请求的域名?
嘿,这个问题我之前也踩过坑!默认情况下Nginx的SSL握手错误日志确实不会带上请求的域名,不过咱们可以通过调整日志配置轻松解决这个问题,具体操作如下:
第一步:利用Nginx的SNI变量
Nginx内置了$ssl_server_name变量,它会存储客户端在SSL握手阶段发送的SNI(Server Name Indication)字段——也就是咱们要的请求域名。哪怕握手失败了,只要客户端发送了SNI,这个变量就能拿到对应的值。第二步:定义自定义日志格式
在Nginx配置的http块里添加自定义的日志格式,把$ssl_server_name字段补充进去。示例配置如下:log_format ssl_handshake_log '$time_local [info] $pid#$pid: *$connection SSL_do_handshake() failed ($ssl_error) while SSL handshaking, client: $remote_addr, server: $server_addr:$server_port, requested domain: $ssl_server_name';这里的其他变量都是Nginx自带的,咱们只是新增了请求域名的记录项。
第三步:应用自定义日志格式
你可以选择全局配置或者针对特定站点配置:- 全局生效:在
http块里添加这条指令,让所有SSL握手错误都用自定义格式记录error_log /var/log/nginx/ssl_handshake_errors.log ssl_handshake_log; - 单个站点生效:在目标HTTPS站点的
server块里添加上述指令即可。
- 全局生效:在
验证配置效果
修改完配置后,重新加载Nginx让配置生效:sudo nginx -s reload之后再出现SSL握手错误时,日志就会变成类似这样的格式:
2023/02/27 12:27:58 [info] 60011#60011: *302628755 SSL_do_handshake() failed (SSL: error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher) while SSL handshaking, client: XXX.XXX.XXX.XXX, server: 0.0.0.0:443, requested domain: example.com
注意:如果客户端不支持SNI(比如非常老旧的浏览器),
$ssl_server_name会是空值,这时候日志里的requested domain字段就会显示为空,这是正常情况——毕竟客户端确实没发送域名信息。
备注:内容来源于stack exchange,提问作者Oleg

