421 使用 HTTP/2 和 SAN SSL 的错误定向请求

jar*_*vis 2 ssl https amazon-web-services apache-2.4 ubuntu-14.04

我在 Ubuntu 上运行 Apache 2.4.20,并且配置了 SSL。我有一个SAN SSL 证书www.example.comwww2.example.com共享同一个证书。

当我包含以下内容时,我收到421 Misdirected Request错误:

Protocols h2 h2c http/1.1
H2Upgrade on
H2Direct
H2WindowSize 128000
Run Code Online (Sandbox Code Playgroud)

如果我删除它们,网站会正常运行。

如果在同一浏览器上打开www.example.comwww2.example.com,我会收到错误消息。如果我先访问www.example.com,它将正确加载。当我从该 SAN SSL 证书加载第二个站点时出现错误,例如www2.example.com。我先去哪个网站并不重要。它总是在第二个站点上响应421 Misdirected Request

我使用 HTTP/2 指令有什么问题?(顺便说一下,它们在 VirtualHost 中)

或者 HTTP/2 和 SAN SSL 实施是否存在问题?

如果重要的话,www.example.com 和 www2.example.com 都位于 AWS 中托管的同一台服务器上。

谢谢。

编辑:

我还尝试了以下设置,结果相同。

Protocols h2 http/1.1
H2Direct
H2WindowSize 128000
Run Code Online (Sandbox Code Playgroud)

在 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>
Run Code Online (Sandbox Code Playgroud)

在虚拟主机中

<IfModule mod_ssl.c>
  <VirtualHost *:443>
    ServerAdmin mail@example.com
    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>
Run Code Online (Sandbox Code Playgroud)

jar*_*vis 5

这对我来说是一个真正的问题。但我在 这里找到了答案

多个主机和错误定向的请求

许多站点对多个虚拟主机使用相同的 TLS 证书。该证书要么具有通配符名称,例如“*.example.org”,要么带有多个备用名称。使用 HTTP/2 的浏览器会识别出这一点,并为这些主机重用已经打开的连接。

虽然这对性能很有好处,但它是有代价的:这样的虚拟主机需要在配置上更加小心。问题是您将在同一个 TLS 连接上对多个主机发出多个请求。这使得重新协商变得不可能,因为 HTTP/2 标准禁止它。

因此,如果您有多个使用相同证书的虚拟主机并希望为它们使用 HTTP/2,则需要确保所有虚拟主机都具有完全相同的 SSL 配置。您需要相同的协议、密码和设置来进行客户端验证。

如果您混合使用,Apache httpd 将检测到它并向客户端返回一个特殊的响应代码,421 Misdirected Request。

我有 3 个 VirtualHosts 共享相同的证书。它们都使用我的“默认”SSL 设置进行配置。最后一个有特殊配置,因为我不需要最后一个与许多浏览器兼容,所以我使用了更现代的密码,并且只使用了最新的 SSL 协议。那个特殊的“特殊”VirtualHost 得到了 421。

如果我禁用协议 h2 http/1.1 可以解决问题,但我不想禁用它。

在所有共享相同证书的 VirtualHost 上使用相同的配置后,问题得到解决