我在 Ubuntu 上运行 Apache 2.4.20,并且配置了 SSL。我有一个SAN SSL 证书和www.example.com和www2.example.com共享同一个证书。
我得到了一个421 错误请求当我包含以下内容时出错:
Protocols h2 h2c http/1.1
H2Upgrade on
H2Direct
H2WindowSize 128000
如果我删除它们,网站就可以正常运行。
如果在同一个浏览器上,我会收到错误,www.example.com和www2.example.com被打开。如果我去www.example.com第一次加载后,它将正确加载。当我从该 SAN SSL 证书加载第二个网站时,我收到错误,例如www2.example.com。无论我先访问哪个网站,它总是会回应421 错误请求在第二个站点上。
我使用 HTTP/2 指令有什么问题?(顺便说一下,它们在 VirtualHost 中)
或者 HTTP/2 和 SAN SSL 实现存在问题?
如果重要的话,www.example.com 和 www2.example.com 都位于 AWS 托管的同一台服务器上。
谢谢。
编辑:
我也尝试了下面的设置,结果相同。
Protocols h2 http/1.1
H2Direct
H2WindowSize 128000
在 SSL 配置中
<IfModule mod_ssl.c>
SSLRandomSeed startup builtin
SSLRandomSeed startup file:/dev/urandom 512
SSLRandomSeed connect builtin
SSLRandomSeed connect file:/dev/urandom 512
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl .crl
SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase
SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000)
SSLSessionCacheTimeout 300
SSLOpenSSLConfCmd DHParameters "/path/dhparams.pem"
SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
SSLHonorCipherOrder on
SSLCompression Off
SSLSessionTickets Off
SSLUseStapling On
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:${APACHE_RUN_DIR}/ssl_stapling(32768)
SSLProtocol all -SSLv3
SSLInsecureRenegotiation Off
SSLStrictSNIVHostCheck Off
</IfModule>
在 VirtualHost 中
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin [email protected]
ServerName www.example.com
DocumentRoot /path/path
Protocols h2 http/1.1
H2Direct on
H2WindowSize 128000
SSLEngine on
SSLCACertificateFile /path/cert.crt
SSLCertificateFile /path/cert.crt
SSLCertificateKeyFile /path/key.key
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains; preload"
<Directory /path/path>
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
</IfModule>
答案1
这对我来说确实是一个问题。但我找到了答案 这里。
多个主机和错误重定向的请求
许多网站对多个虚拟主机使用相同的 TLS 证书。证书要么具有通配符名称(例如“*.example.org”),要么带有多个备用名称。使用 HTTP/2 的浏览器将识别这一点,并重用此类主机已打开的连接。
虽然这对性能有很大帮助,但代价是:此类虚拟主机在配置时需要更加小心。问题是,您将在同一个 TLS 连接上对多个主机发出多个请求。这使得重新协商变得不可能,因为 HTTP/2 标准禁止这样做。
因此,如果您有多个使用相同证书的虚拟主机,并且想要对它们使用 HTTP/2,则需要确保所有虚拟主机都具有完全相同的 SSL 配置。您需要相同的协议、密码和设置来进行客户端验证。
如果您混淆了某些内容,Apache httpd 将会检测到它并向客户端返回一个特殊的响应代码 421 错误重定向请求。
我有 3 个 VirtualHost 共享同一个证书。它们都使用我的“默认”SSL 设置进行配置。最后一个具有特殊配置,因为我不需要最后一个与许多浏览器兼容,所以我使用了更现代的密码和最新的 SSL 协议。那个特定的“特殊”VirtualHost 正在获取 421。
如果我禁用协议 h2 http/1.1,这将解决问题,但我不想禁用它。
在共享相同证书的所有 VirtualHost 上使用相同配置后,问题得到解决。
答案2
我今天遇到了这个问题,一开始有点困惑,因为我没有使用任何不同的密码等,所以我不明白上面答案中的“如果混合使用”到底是什么意思。好吧,事实证明,如果 SSLCertificateFile 和 SSLCertificateKeyFile 具有相同的内容并且文件是彼此相同的副本,那是不够的。这些配置设置必须指向同一个文件!我怀疑这是因为实际上不是浏览器看到了问题(我最初认为是这种情况),而是 Apache 已经检测到配置不相同并预先阻止任何 HTTP2 请求,因为它预计如果浏览器真的传递了页面(这很可能确实会发生),浏览器就会遇到问题。Apache 还向其日志文件写入相应的错误(“通过 SNI 提供的主机名 www.example.com 和通过 HTTP 提供的主机名 www2.example.com 没有兼容的 SSL 设置”)。此设置兼容性测试似乎相当简单,并不关心证书是否相同。它可能只会注意到不同的文件名/路径,然后就犹豫了。