我有一个网站,可以通过HTTP访问TLS。它是多主的,所以主机名有几个DNS条目.此外,在同一组IP地址上有几个带有多个主机名的网站,所以这都是在Apache2中使用几个NameVirtualHost设置的。
使用浏览器或WebDAV客户端等访问网站就像一种魅力。
但是,当我试图连接"openssl s_client“时,我无法让它在我的生活中发挥作用。Apache向我抛出一个400“坏请求”错误。Apache选择正确的X.509证书,因此SNI必须由openssl正确设置。当我在"GET“行上按下"enter”,甚至在我可以添加任何标题之前,就会发生这种情况。我使用的HTTP语法(基本上是"GET / HTTP/1.1\nHost: hostname“)适用于网站的非TLS版本(该版本仅重定向到TLS版本),因此不会出现问题。相同的HTTP语法也可以连接到例如TLS上的www.google.com (端口443),因此它看起来也是正确的。
Apache服务器的日志显示一个带有尾换行符的请求,也许这是一个提示。尽管Apache为我连接到的主机名发送了X.509证书,但日志条目指向了该IP/端口的默认VirtualHost,这与默认的不同。
我已经和wireshark确认了SNI是在ClientHello中设置的。
下面是一个示例会话:
输入$ openssl s_client -connect hostname:443
输出
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = hostname
verify return:1
---
Certificate chain
0 s:CN = hostname
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
i:O = Digital Signature Trust Co., CN = DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
(...)
-----END CERTIFICATE-----
subject=CN = hostname
issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 3121 bytes and written 388 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: FBFD6172E3C659D4071B68A36BD5983A8571906C00190A745B5DAA1359D4087C
Session-ID-ctx:
Resumption PSK: 21957A3C267DAA25CE2D7F6BFD3C3593CCFA1E6FC45C4DC5D0CE35C29175F7E9BBDD59EE6C213DC53B8291B7BD055238
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - 18 4b 25 ae 49 61 e8 f3-73 b5 bb 3b 50 2f 1d c4 .K%.Ia..s..;P/..
0010 - 7e 02 e9 41 01 9e ed 8b-a1 b6 ec 48 4d 12 11 f2 ~..A.......HM...
Start Time: 1602857943
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Session-ID: 627DF7810556DB2918484F393E66DEA7BF22DD3A42288B47E46FCDCDEF176125
Session-ID-ctx:
Resumption PSK: 851978077C93284CB3D69B541B77844A48D1CFC8800F60B6F7CF3D297911D0D93E0E935017B78777E2BD51A29E13329F
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 300 (seconds)
TLS session ticket:
0000 - c0 1a 60 23 36 80 bf 27-83 0e 1f 26 4b 04 f2 53 ..`#6..'...&K..S
0010 - a0 8a 2d 6e 41 44 17 c7-9b 11 5d dc 7f 08 71 fc ..-nAD....]...q.
Start Time: 1602857943
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
Max Early Data: 0
---
read R BLOCK
输入(注意第一个空行后没有空行) GET / HTTP/1.1
输出
Date: Fri, 16 Oct 2020 14:19:11 GMT
Server: Apache/2.4.38 (Debian)
Content-Length: 322
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.38 (Debian) Server at default_hostname Port 443</address>
</body></html>
closed
注意:错误消息提到default_hostname,而不是主机名!
相应的Apache日志条目是:default_hostname:443 1.2.3.4 - - [16/Oct/2020:16:19:11 +0200] "GET / HTTP/1.1\n" 400 3279 "-" "-"
请注意,default_hostname不是主机名,而且Apache发送了正确的服务器证书,因此它已经确定了正确的VirtualHost!如果我不使用SNI进行连接(openssl s_client -connect 4.3.2.1:443),那么它将为default_hostname发送服务器证书。
发布于 2020-10-16 06:56:47
你确实发出了一个格式错误的请求。HTTP/1.1要求主机:报头的存在,而在SNI中,主机:报头的内容必须与SNI主机名匹配。
再试一次,这次提供正确的主机:头。
https://serverfault.com/questions/1038981
复制