【HTTP】在 curl 中使用指定 ip 来进行请求 https请求

如何调测HTTPS SNI 问题

curl -vvv https://www.example.com:443 -H 'Host: www.example.com'

# curl  -vvv  https://www.example.com:443 -H 'Host: www.example.com'

* About to connect() to www.example.com port 443 (#0)
*   Trying 93.184.215.14...
* Connected to www.example.com (93.184.215.14) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* Server certificate:
*       subject: CN=www.example.org,O=Internet Corporation for Assigned Names and Numbers,L=Los Angeles,ST=California,C=US
*       start date: Jan 30 00:00:00 2024 GMT
*       expire date: Mar 01 23:59:59 2025 GMT
*       common name: www.example.org
*       issuer: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1,O=DigiCert Inc,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> Host: www.example.com
>
< HTTP/1.1 200 OK
< Age: 342842
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Sun, 15 Sep 2024 03:41:21 GMT
< Etag: "3147526947+ident"
< Expires: Sun, 22 Sep 2024 03:41:21 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECAcc (sac/255D)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
* Connection #0 to host www.example.com left intact

echo "" | openssl s_client -showcerts -connect www.example.com:443

# echo   "" | openssl s_client -showcerts -connect www.example.com:443


CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1
verify return:1
depth=0 C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Los Angeles/O=Internet\xC2\xA0Corporation\xC2\xA0for\xC2\xA0Assigned\xC2\xA0Names\xC2\xA0and\xC2\xA0Numbers/CN=www.example.org
   i:/C=US/O=DigiCert Inc/CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
-----BEGIN CERTIFICATE-----
MIIHbjCCBlagAwIBAgIQB1vO8waJyK3fE+Ua9K/hhzANBgkqhkiG9w0BAQsFADBZ
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMTMwMQYDVQQDEypE
aWdpQ2VydCBHbG9iYWwgRzIgVExTIFJTQSBTSEEyNTYgMjAyMCBDQTEwHhcNMjQw
MTMwMDAwMDAwWhcNMjUwMzAxMjM1OTU5WjCBljELMAkGA1UEBhMCVVMxEzARBgNV
BAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMUIwQAYDVQQKDDlJ
bnRlcm5ldMKgQ29ycG9yYXRpb27CoGZvcsKgQXNzaWduZWTCoE5hbWVzwqBhbmTC
oE51bWJlcnMxGDAWBgNVBAMTD3d3dy5leGFtcGxlLm9yZzCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAIaFD7sO+cpf2fXgCjIsM9mqDgcpqC8IrXi9wga/
9y0rpqcnPVOmTMNLsid3INbBVEm4CNr5cKlh9rJJnWlX2vttJDRyLkfwBD+dsVvi
vGYxWTLmqX6/1LDUZPVrynv/cltemtg/1Aay88jcj2ZaRoRmqBgVeacIzgU8+zmJ
7236TnFSe7fkoKSclsBhPaQKcE3Djs1uszJs8sdECQTdoFX9I6UgeLKFXtg7rRf/
hcW5dI0zubhXbrW8aWXbCzySVZn0c7RkJMpnTCiZzNxnPXnHFpwr5quqqjVyN/aB
KkjoP04Zmr+eRqoyk/+lslq0sS8eaYSSHbC5ja/yMWyVhvMCAwEAAaOCA/IwggPu
MB8GA1UdIwQYMBaAFHSFgMBmx9833s+9KTeqAx2+7c0XMB0GA1UdDgQWBBRM/tAS
TS4hz2v68vK4TEkCHTGRijCBgQYDVR0RBHoweIIPd3d3LmV4YW1wbGUub3Jnggtl
eGFtcGxlLm5ldIILZXhhbXBsZS5lZHWCC2V4YW1wbGUuY29tggtleGFtcGxlLm9y
Z4IPd3d3LmV4YW1wbGUuY29tgg93d3cuZXhhbXBsZS5lZHWCD3d3dy5leGFtcGxl
Lm5ldDA+BgNVHSAENzA1MDMGBmeBDAECAjApMCcGCCsGAQUFBwIBFhtodHRwOi8v
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG
CCsGAQUFBwMBBggrBgEFBQcDAjCBnwYDVR0fBIGXMIGUMEigRqBEhkJodHRwOi8v
Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxHMlRMU1JTQVNIQTI1NjIw
MjBDQTEtMS5jcmwwSKBGoESGQmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdp
Q2VydEdsb2JhbEcyVExTUlNBU0hBMjU2MjAyMENBMS0xLmNybDCBhwYIKwYBBQUH
AQEEezB5MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wUQYI
KwYBBQUHMAKGRWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEds
b2JhbEcyVExTUlNBU0hBMjU2MjAyMENBMS0xLmNydDAMBgNVHRMBAf8EAjAAMIIB
fQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdABOdaMnXJoQwzhbbNTfP1LrHfDgjhuN
acCx+mSxYpo53wAAAY1b0vxkAAAEAwBFMEMCH0BRCgxPbBBVxhcWZ26a8JCe83P1
JZ6wmv56GsVcyMACIDgpMbEo5HJITTRPnoyT4mG8cLrWjEvhchUdEcWUuk1TAHYA
fVkeEuF4KnscYWd8Xv340IdcFKBOlZ65Ay/ZDowuebgAAAGNW9L8MAAABAMARzBF
AiBdv5Z3pZFbfgoM3tGpCTM3ZxBMQsxBRSdTS6d8d2NAcwIhALLoCT9mTMN9OyFz
IBV5MkXVLyuTf2OAzAOa7d8x2H6XAHcA5tIxY0B3jMEQQQbXcbnOwdJA9paEhvu6
hzId/R43jlAAAAGNW9L8XwAABAMASDBGAiEA4Koh/VizdQU1tjZ2E2VGgWSXXkwn
QmiYhmAeKcVLHeACIQD7JIGFsdGol7kss2pe4lYrCgPVc+iGZkuqnj26hqhr0TAN
BgkqhkiG9w0BAQsFAAOCAQEABOFuAj4N4yNG9OOWNQWTNSICC4Rd4nOG1HRP/Bsn
rz7KrcPORtb6D+Jx+Q0amhO31QhIvVBYs14gY4Ypyj7MzHgm4VmPXcqLvEkxb2G9
Qv9hYuEiNSQmm1fr5QAN/0AzbEbCM3cImLJ69kP5bUjfv/76KB57is8tYf9sh5ik
LGKauxCM/zRIcGa3bXLDafk5S2g5Vr2hs230d/NGW1wZrE+zdGuMxfGJzJP+DAFv
iBfcQnFg4+1zMEKcqS87oniOyG+60RMM0MdejBD7AS43m9us96Gsun/4kufLQUTI
FfnzxLutUV++3seshgefQOy5C/ayi8y1VTNmujPCxPCi6Q==
-----END CERTIFICATE-----
 1 s:/C=US/O=DigiCert Inc/CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root G2
-----BEGIN CERTIFICATE-----
MIIEyDCCA7CgAwIBAgIQDPW9BitWAvR6uFAsI8zwZjANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
MjAeFw0yMTAzMzAwMDAwMDBaFw0zMTAzMjkyMzU5NTlaMFkxCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKkRpZ2lDZXJ0IEdsb2Jh
bCBHMiBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAMz3EGJPprtjb+2QUlbFbSd7ehJWivH0+dbn4Y+9lavyYEEV
cNsSAPonCrVXOFt9slGTcZUOakGUWzUb+nv6u8W+JDD+Vu/E832X4xT1FE3LpxDy
FuqrIvAxIhFhaZAmunjZlx/jfWardUSVc8is/+9dCopZQ+GssjoP80j812s3wWPc
3kbW20X+fSP9kOhRBx5Ro1/tSUZUfyyIxfQTnJcVPAPooTncaQwywa8WV0yUR0J8
osicfebUTVSvQpmowQTCd5zWSOTOEeAqgJnwQ3DPP3Zr0UxJqyRewg2C/Uaoq2yT
zGJSQnWS+Jr6Xl6ysGHlHx+5fwmY6D36g39HaaECAwEAAaOCAYIwggF+MBIGA1Ud
EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHSFgMBmx9833s+9KTeqAx2+7c0XMB8G
A1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485MA4GA1UdDwEB/wQEAwIBhjAd
BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwdgYIKwYBBQUHAQEEajBoMCQG
CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKG
NGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RH
Mi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29t
L0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDA9BgNVHSAENjA0MAsGCWCGSAGG/WwC
ATAHBgVngQwBATAIBgZngQwBAgEwCAYGZ4EMAQICMAgGBmeBDAECAzANBgkqhkiG
9w0BAQsFAAOCAQEAkPFwyyiXaZd8dP3A+iZ7U6utzWX9upwGnIrXWkOH7U1MVl+t
wcW1BSAuWdH/SvWgKtiwla3JLko716f2b4gp/DA/JIS7w7d7kwcsr4drdjPtAFVS
slme5LnQ89/nD/7d+MS5EHKBCQRfz5eeLjJ1js+aWNJXMX43AYGyZm0pGrFmCW3R
bpD0ufovARTFXFZkAdl9h6g4U5+LXUZtXMYnhIHUfoyMo5tS58aI7Dd8KvvwVVo4
chDYABPPTHPbqjc1qCmBaZx2vN4Ye5DUys/vZwP9BFohFrH/6j/f3IL16/RZkiMN
JCqVJUzKoZHm1Lesh3Sz8W2jmdv51b2EQJ8HmA==
-----END CERTIFICATE-----
---
Server certificate
subject=/C=US/ST=California/L=Los Angeles/O=Internet\xC2\xA0Corporation\xC2\xA0for\xC2\xA0Assigned\xC2\xA0Names\xC2\xA0and\xC2\xA0Numbers/CN=www.example.org
issuer=/C=US/O=DigiCert Inc/CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3791 bytes and written 415 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: D47E52A551733EF7629BF646EAD1C5A953FA57DA930EC07C5602936FBCE58F9B
    Session-ID-ctx:
    Master-Key: FE65C22202FB1552E273A738B94C7DCC52E58D9E8BADCB4C5FB926A363037358A20146C6D7C8C6AB63FEC8AEBB0B0D10
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - f0 1e 9f 13 41 95 4c 0b-72 cf 31 3e c3 aa 1b 97   ....A.L.r.1>....
    0010 - 49 5e bc 68 fb 99 61 0b-82 38 c5 4c 4b 17 56 78   I^.h..a..8.LK.Vx
    0020 - c8 46 2b 85 eb 8a df 06-bc 48 f8 cb b6 59 71 38   .F+......H...Yq8
    0030 - 61 c9 4b b4 60 92 b6 ea-10 82 d4 52 72 24 79 27   a.K.`......Rr$y'
    0040 - e8 4a 2e 95 86 12 8e 19-cf db 75 22 54 a0 f1 71   .J........u"T..q
    0050 - 66 0e dc e9 56 d8 8b c0-f1 8e 99 56 27 c6 ab 0e   f...V......V'...
    0060 - c8 e5 ac ad 42 66 0b c4-3f be 60 d0 e4 46 f7 b7   ....Bf..?.`..F..
    0070 - a9 07 22 1f 31 30 16 98-78 5a d5 fa db fd c6 3f   ..".10..xZ.....?
    0080 - b8 05 61 e6 ab 1a c2 7d-46 48 83 66 67 3c 0b 25   ..a....}FH.fg<.%
    0090 - 22 14 10 4e ef e1 7b d1-3d 84 c7 fb fd 13 a3 93   "..N..{.=.......

    Start Time: 1726371571
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
DONE

curl --resolve 'www.example.com:443:xx.xx.xx.xx' https://www.example.com -vvv

# ping www.example.com
PING www.example.com (93.184.215.14) 56(84) bytes of data.
64 bytes from 93.184.215.14 (93.184.215.14): icmp_seq=1 ttl=43 time=132 ms



# curl --resolve 'www.example.com:443:93.184.215.14'  https://www.example.com  -vvv
* Added www.example.com:443:93.184.215.14 to DNS cache
* About to connect() to www.example.com port 443 (#0)
*   Trying 93.184.215.14...
* Connected to www.example.com (93.184.215.14) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* Server certificate:
*       subject: CN=www.example.org,O=Internet Corporation for Assigned Names and Numbers,L=Los Angeles,ST=California,C=US
*       start date: Jan 30 00:00:00 2024 GMT
*       expire date: Mar 01 23:59:59 2025 GMT
*       common name: www.example.org
*       issuer: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1,O=DigiCert Inc,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: www.example.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Age: 208511
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
< Date: Sun, 15 Sep 2024 04:37:44 GMT
< Etag: "3147526947+gzip+ident"
< Expires: Sun, 22 Sep 2024 04:37:44 GMT
< Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
< Server: ECAcc (sac/2567)
< Vary: Accept-Encoding
< X-Cache: HIT
< Content-Length: 1256
<
<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
        background-color: #f0f0f2;
        margin: 0;
        padding: 0;
        font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

    }
    div {
        width: 600px;
        margin: 5em auto;
        padding: 2em;
        background-color: #fdfdff;
        border-radius: 0.5em;
        box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
    }
    a:link, a:visited {
        color: #38488f;
        text-decoration: none;
    }
    @media (max-width: 700px) {
        div {
            margin: 0 auto;
            width: auto;
        }
    }
    </style>
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is for use in illustrative examples in documents. You may use this
    domain in literature without prior coordination or asking for permission.</p>
    <p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
* Connection #0 to host www.example.com left intact

示例1:

# curl --resolve 'www.example.com:443:180.101.50.188'  https://www.example.com  -vvv

* Added www.example.com:443:180.101.50.188 to DNS cache
* About to connect() to www.example.com port 443 (#0)
*   Trying 180.101.50.188...
* Connected to www.example.com (180.101.50.188) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* Server certificate:
*       subject: CN=baidu.com,O="Beijing Baidu Netcom Science Technology Co., Ltd",L=beijing,ST=beijing,C=CN
*       start date: Jul 08 01:41:02 2024 GMT
*       expire date: Aug 09 01:41:01 2025 GMT
*       common name: baidu.com
*       issuer: CN=GlobalSign RSA OV SSL CA 2018,O=GlobalSign nv-sa,C=BE
* NSS error -12276 (SSL_ERROR_BAD_CERT_DOMAIN)
* Unable to communicate securely with peer: requested domain name does not match the server's certificate.
* Closing connection 0
curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.

这个 curl 命令尝试连接到 www.example.com,并使用了 --resolve 选项来直接指定 IP 地址。根据返回的详细日志,连接过程中出现了 SSL/TLS 证书域名不匹配的问题。以下是详细解读:

  1. --resolve 选项的使用:

    • curl --resolve 'www.example.com:443:180.101.50.188' https://www.example.com -vvv 命令指定了一个自定义的 DNS 解析规则,将 www.example.com 域名解析为 IP 地址 180.101.50.188
  2. 连接建立过程:

    • * Added www.example.com:443:180.101.50.188 to DNS cache 表示 curl 将指定的 IP 地址和端口添加到了 DNS 缓存中。
    • * About to connect() to www.example.com port 443 (#0) 表示 curl 正准备连接到 www.example.com 的 443 端口。
    • * Trying 180.101.50.188... 表示 curl 正尝试连接到 IP 地址 180.101.50.188
    • * Connected to www.example.com (180.101.50.188) port 443 (#0) 表示成功建立了连接。
  3. SSL/TLS 证书相关信息:

    • * Initializing NSS with certpath: sql:/etc/pki/nssdb 表示正在初始化 NSS(Network Security Services),这是用于处理 SSL/TLS 的库。
    • * CAfile: /etc/pki/tls/certs/ca-bundle.crt 表示 curl 使用的 CA 证书文件路径。
    • * Server certificate: 部分列出了服务器的 SSL/TLS 证书信息,包括证书的主题(CN=baidu.com)、有效期等。
  4. 证书域名不匹配错误:

    • * NSS error -12276 (SSL_ERROR_BAD_CERT_DOMAIN)* Unable to communicate securely with peer: requested domain name does not match the server's certificate. 表示出现了 SSL/TLS 域名不匹配的错误。
    • 具体而言,证书的主题是 baidu.com,而你请求的是 www.example.com。这意味着服务器的证书是为 baidu.com 签发的,但你连接到的却是 www.example.com,导致域名不匹配。
  5. 连接关闭:

    • * Closing connection 0 表示 curl 正在关闭连接。
    • curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.curl 报告的错误,指出由于域名不匹配,无法建立安全连接。

解决方案

  1. 确保正确的域名和证书匹配:

    • 确保你请求的域名(www.example.com)与服务器的 SSL/TLS 证书中的主题域名匹配。如果你实际访问的应该是 baidu.com,则你应该使用 baidu.com 作为目标域名。
  2. 使用正确的 IP 地址:

    • 如果你需要测试某个域名,确保你使用的 IP 地址和域名匹配,并且该 IP 地址上的服务器有正确的证书配置。
  3. 检查服务器配置:

    • 如果你控制服务器,检查服务器的 SSL/TLS 配置,确保它提供了正确的证书,特别是证书中的域名(Common Name 或 Subject Alternative Name)应与请求的域名匹配。

通过这些步骤,你应该能解决这个域名不匹配的问题。

SNI(Server Name Indication)是一个在 HTTPS 协议中非常重要的扩展,它允许客户端在建立 TLS 连接时指定所请求的主机名。

这对于使用 CDN(内容分发网络)和共享 IP 地址的服务器特别重要。

让我们深入探讨 SNI 的作用及其在 CDN 和 HTTPS 配置中的关系。

SNI 和 HTTPS

  1. SNI 基本概念:

    • SNI 的作用:SNI 扩展允许客户端在发起 TLS 握手时发送主机名。这使得服务器能够根据客户端请求的主机名选择合适的 SSL/TLS 证书来建立加密连接。
    • 为什么需要 SNI:在没有 SNI 的情况下,服务器在 TLS 握手开始时无法知道客户端请求的是哪个主机名,从而无法提供正确的证书。这就造成了一个问题:多个主机名(或网站)共享一个 IP 地址时,服务器无法知道要提供哪个证书。
  2. SNI 的工作原理:

    • 客户端行为:客户端(如浏览器或 curl)在 TLS 握手的开始阶段,会在“Client Hello”消息中发送请求的主机名。
    • 服务器行为:服务器接收到客户端的主机名后,可以选择合适的证书来回应,确保证书中的主机名与客户端请求的主机名匹配。

CDN 和 SNI

  1. CDN 的作用:

    • CDN 的基本功能:CDN 通过将内容缓存分布到多个地理位置的服务器上,来加速用户的访问速度,并减轻原始服务器的负担。
    • CDN 和 IP 地址共享:多个域名(网站)可能通过同一个 CDN 配置,这样它们可能会共享相同的 IP 地址。CDN 服务器会根据请求的主机名来提供适当的内容。
  2. CDN 中的 SNI:

    • SNI 的重要性:由于 CDN 服务器通常使用共享 IP 地址来处理来自不同域名的请求,SNI 允许 CDN 确保客户端请求的主机名能够正确映射到 CDN 为每个域名配置的 SSL/TLS 证书。
    • 证书管理:使用 SNI,CDN 提供商可以为不同的域名配置不同的证书,即使它们共享同一个 IP 地址。这样,即使多个域名都通过 CDN 进行服务,也能确保每个域名都有正确的 SSL/TLS 证书。

实际例子

假设你通过 CDN 提供两个网站服务,分别是 www.example.comwww.example2.com。它们共享一个 IP 地址。没有 SNI,CDN 服务器在建立 TLS 连接时无法知道客户端请求的是哪个域名,因此可能无法提供正确的证书。然而,通过 SNI,当客户端发起 TLS 连接时,它会在握手过程中告知服务器其请求的主机名。CDN 服务器使用这个信息来选择并提供正确的证书,从而实现安全的 HTTPS 连接。

你的示例中的问题与 SNI

在你给出的 curl 命令的输出中,curl 报告了证书域名不匹配的错误,提示服务器返回了一个与请求的域名不匹配的证书。这个问题通常发生在以下几种情况:

  1. 没有使用 SNI: 如果客户端在发起请求时没有指定主机名,服务器可能无法提供正确的证书,尤其是在 CDN 环境中。

  2. DNS 解析问题: 如果你使用 --resolve 选项来指定 IP 地址,但这个 IP 地址上的服务器没有为你请求的域名(www.example.com)配置正确的证书,那么你会遇到证书域名不匹配的问题。

  3. 证书配置问题: 服务器或 CDN 配置可能不正确,导致返回了与请求主机名不匹配的证书。

通过确保使用 SNI 和正确配置证书,可以避免此类证书域名不匹配的问题。

示例2:

# curl --resolve 'www.example.com:443:125.77.134.38'  https://www.example.com  -vvv

* Added www.example.com:443:125.77.134.38 to DNS cache
* About to connect() to www.example.com port 443 (#0)
*   Trying 125.77.134.38...
* Connected to www.example.com (125.77.134.38) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -5938 (PR_END_OF_FILE_ERROR)
* Encountered end of file
* Closing connection 0
curl: (35) Encountered end of file

当然,这条 curl 命令和其输出中包含的信息可以从以下几个方面来解读:

命令解析

命令:

curl --resolve 'www.example.com:443:125.77.134.38' https://www.example.com -vvv
  • --resolve 'www.example.com:443:125.77.134.38':这个选项告诉 curl 使用指定的 IP 地址(125.77.134.38)来访问 www.example.com 的 443 端口。也就是说,它会绕过 DNS 查找,直接连接到这个 IP。
  • https://www.example.com:这是要请求的 URL。
  • -vvv:这个选项开启了 curl 的详细输出模式,以帮助调试。

输出分析

  1. DNS 缓存

    * Added www.example.com:443:125.77.134.38 to DNS cache
    

    这条消息表明 curl 将指定的 IP 地址和主机名映射添加到了 DNS 缓存中。此步骤是因为使用了 --resolve 选项。

  2. 连接

    * About to connect() to www.example.com port 443 (#0)
    *   Trying 125.77.134.38...
    * Connected to www.example.com (125.77.134.38) port 443 (#0)
    

    curl 正在尝试连接到 IP 地址为 125.77.134.38 的主机上的 443 端口,并成功建立了连接。

  3. 初始化 NSS

    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    

    curl 正在初始化 NSS(Network Security Services)库来处理 SSL/TLS 证书。它会查找证书颁发机构 (CA) 的证书文件,以验证服务器的证书。

  4. 错误信息

    * NSS error -5938 (PR_END_OF_FILE_ERROR)
    * Encountered end of file
    * Closing connection 0
    curl: (35) Encountered end of file
    

    这里 curl 遇到了一个 SSL/TLS 错误,具体是 PR_END_OF_FILE_ERROR,这个错误通常表示在 SSL 握手过程中,连接意外地关闭或中断。可能的原因包括:

    • 服务器端的 SSL/TLS 配置问题。
    • 服务器拒绝了连接,或者没有正确地响应 SSL 握手。
    • 证书链不完整或证书无效。

可能的解决方案

  1. 检查服务器端 SSL/TLS 配置:确保服务器配置正确,并且支持您尝试使用的协议和加密套件。

  2. 查看服务器证书:使用工具(如 openssl)检查服务器的证书链是否完整并且有效。例如:

    openssl s_client -connect www.example.com:443
    
  3. 更新 CA 证书:确保本地的 CA 证书文件是最新的。可能需要更新 ca-bundle.crt 文件。

  4. 测试其他客户端:使用其他工具或浏览器尝试访问相同的 URL,以确认问题是否特定于 curl

这个错误通常需要从服务器端和客户端两个方面去调查,找到问题的根源,并做相应的修复。

示例3:

# curl --resolve 'www.example.com:443:120.92.36.128'  https://www.example.com  -vvv

* Added www.example.com:443:120.92.36.128 to DNS cache
* About to connect() to www.example.com port 443 (#0)
*   Trying 120.92.36.128...
* Connected to www.example.com (120.92.36.128) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* NSS error -12263 (SSL_ERROR_RX_RECORD_TOO_LONG)
* SSL received a record that exceeded the maximum permissible length.
* Closing connection 0
curl: (35) SSL received a record that exceeded the maximum permissible length.

当然,这条 curl 命令及其输出表明了不同的 SSL/TLS 错误。让我们详细解读一下。

命令解析

命令:

curl --resolve 'www.example.com:443:120.92.36.128' https://www.example.com -vvv
  • --resolve 'www.example.com:443:120.92.36.128':指定 www.example.com 使用 IP 地址 120.92.36.128 进行连接。
  • https://www.example.com:请求的 URL。
  • -vvv:启用详细模式以便于调试。

输出分析

  1. DNS 缓存

    * Added www.example.com:443:120.92.36.128 to DNS cache
    

    curl 将主机名和指定的 IP 地址添加到了 DNS 缓存中。

  2. 连接

    * About to connect() to www.example.com port 443 (#0)
    *   Trying 120.92.36.128...
    * Connected to www.example.com (120.92.36.128) port 443 (#0)
    

    curl 成功建立了与 IP 地址 120.92.36.128 的连接,并且连接到了 443 端口(HTTPS)。

  3. 初始化 NSS

    * Initializing NSS with certpath: sql:/etc/pki/nssdb
    *   CAfile: /etc/pki/tls/certs/ca-bundle.crt
      CApath: none
    

    curl 正在初始化 NSS(Network Security Services)库,并指定了 CA 证书文件的路径,用于验证 SSL/TLS 证书。

  4. 错误信息

    * NSS error -12263 (SSL_ERROR_RX_RECORD_TOO_LONG)
    * SSL received a record that exceeded the maximum permissible length.
    * Closing connection 0
    curl: (35) SSL received a record that exceeded the maximum permissible length.
    

    这里 curl 遇到了 SSL_ERROR_RX_RECORD_TOO_LONG 错误。这表明 SSL/TLS 协议中的一个记录(数据包)超出了允许的最大长度。这通常意味着以下几种情况:

    • 服务器端配置错误:服务器可能将非 SSL/TLS 数据(例如,HTTP 数据)发送到 SSL/TLS 连接上,导致协议混淆。
    • 端口配置错误:有可能服务器的 443 端口未配置为 SSL/TLS 服务,或者服务器错误地将 443 端口配置为普通 HTTP 服务。
    • 反向代理或负载均衡器问题:如果有反向代理或负载均衡器,它们可能没有正确地处理 SSL/TLS 流量,从而导致这个错误。

可能的解决方案

  1. 检查服务器配置:确保服务器在 443 端口上正确配置了 SSL/TLS。可以通过使用工具如 openssl 来检查服务器响应:

    openssl s_client -connect www.example.com:443
    
  2. 确认服务器端口:确保端口 443 确实是用于 SSL/TLS 的,而不是用作其他用途。

  3. 检查代理和负载均衡器:如果有使用反向代理或负载均衡器,确保它们正确处理 SSL/TLS 连接。

  4. 验证 SSL/TLS 配置:如果你有访问服务器的权限,检查服务器的 SSL/TLS 配置,确保没有配置错误。

这些步骤将帮助你找出并解决造成 SSL_ERROR_RX_RECORD_TOO_LONG 错误的根本原因。

参考

How to troubleshoot SNI enabled endpoints with curl and openssl?
https://www.suse.com/support/kb/doc/?id=000020154

什么是SNI?TLS服务器名称指示如何工作
https://www.cloudflare.com/zh-cn/learning/ssl/what-is-sni/

49fef30b186bd8029bd3d69e6478fe86_731426468600579072.png

在 curl 中使用指定 ip 来进行请求 https
https://blog.mozcp.com/curl-request-https-specify-ip/

记一次 HTTPS 抓包分析和 SNI 的思考
https://imlht.com/archives/394/

回源SNI
https://www.ctyun.cn/document/10015932/10150658

SNI (Server Name Indication)
https://zqfan.github.io/2020/01/24/sni/

HTTPS之SNI介绍
https://blog.51cto.com/zengestudy/2170245

SNI可能引发的HTTPS访问异常
https://help.aliyun.com/zh/anti-ddos/how-to-handle-https-access-exceptions-that-occur-when-clients-do-not-support-sni

零基础如何使用CDN
https://www.ctyun.cn/document/10015932/10136415

SNI兼容性导致HTTPS访问异常(服务器证书不可信)
https://help.aliyun.com/zh/waf/https-access-exceptions-arising-from-sni-compatibility

SNI所导致的证书错误问题
https://stephenzhou.net/2018/07/12/sni-https-failed/

CDN回源时网站出现5xx报错的排查方法
https://help.aliyun.com/zh/oss/how-to-troubleshoot-5xx-errors-reported-on-websites-when-cdn-initiates-a-back-to-origin-request

iOS 支持 SNI 方案调研
https://github.com/yuhanle/blogbag/issues/15

浅谈SNI 兼容性导致 HTTPS 出错问题
https://wwww.lvmoo.com/933.love/

HOW WELL DO YOU KNOW SSL?
https://www.ssllabs.com/ssltest/

User Agent Capabilities
https://www.ssllabs.com/ssltest/clients.html

什么是加密的 SNI? | ESNI 如何工作
https://www.cloudflare-cn.com/learning/ssl/what-is-encrypted-sni/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容