跳到主要内容
ecdsa.com
OpenSSL (client side)OpenSSL CLI

错误信息

SSL routines:ssl3_read_bytes:tlsv1 unrecognized name

也可能输出为

  • error:0A000458:SSL routines::tlsv1 unrecognized name
  • SSL alert number 112

OpenSSL 3.x 输出“error:0A000458:SSL routines:ssl3_read_bytes:tlsv1 unrecognized name:…:SSL alert number 112”。Java 客户端把同一个告警报告为“javax.net.ssl.SSLHandshakeException: Received fatal alert: unrecognized_name”。

OpenSSL (client side) — TLS alert 112 (unrecognized_name) sent by a server that does not serve the requested SNI name

含义

客户端发送的服务器名称(SNI)不在该服务器的服务范围内,服务器以致命告警的形式返回了 TLS 告警 112(unrecognized_name)。RFC 6066 允许服务器以警告级或致命级发送这个告警;严格的服务器(以及部分专用设备)把未知名称视为致命错误,因此握手在出示任何证书之前就结束了。

原因

修复方法

  1. 1.

    找出服务器接受的名称

    用每个候选名称分别尝试握手;握手成功的名称就是服务器上已配置的名称。

    bash
    # Which names does the server accept?
    for n in example.com www.example.com api.example.com; do
      printf '%-20s ' "$n"
      echo | openssl s_client -connect 203.0.113.10:443 -servername "$n" -brief 2>&1 | grep -m1 -E 'Protocol version|error' || echo fail
    done
  2. 2.

    在服务器上配置缺失的名称

    把这个名称添加到 server 块(或 CDN/平台的域名列表)中,同时配置覆盖该名称的证书。

    text
    # nginx: a server block (and certificate) for every name clients use
    server {
        listen 443 ssl;
        server_name api.example.com legacy-api.example.com;
        ssl_certificate     /etc/nginx/tls/api.fullchain.pem;
        ssl_certificate_key /etc/nginx/tls/api.key;
    }
  3. 3.

    让客户端发送正确的名称

    在 URL 中保留真实的主机名,只覆盖地址(curl --resolve、各个库中的 servername 选项)。

    bash
    # Send the server's real name as SNI when connecting by address
    curl --resolve api.example.com:443:203.0.113.10 https://api.example.com/
    openssl s_client -connect 203.0.113.10:443 -servername api.example.com </dev/null

相关错误

浏览完整的签名错误库