【问题标题】:Browser won't upgrade to h2 (HTTP/2) although "Upgrade" headers are sent尽管发送了“升级”标头,但浏览器不会升级到 h2 (HTTP/2)
【发布时间】:2016-09-16 06:53:21
【问题描述】:

我正在尝试让 h2 (HTTP/2) 在我的网络服务器上运行。通过“ondrej”存储库安装了 Apache 2.4.20。我在 Debian 8 和 Ubuntu 14.04 服务器上进行了测试,但我一直遇到同样的问题。我正在运行 OpenSSL 1.0.2 和 SSL 虚拟主机。

奇怪的是升级标头(连接:升级和升级:h2)被发送。当我进行一些外部服务器测试时,我得到了 h2 在 ALPN 支持下正常运行的响应。但问题是我测试的浏览器(Win7 上的 Chrome 和 FireFox)不会升级到 h2。

我注意到缺少的一件事是 HTTP/2-Settings 标头,但我在任何 Apache 文档中都找不到任何内容来实现此功能或强制 Apache 发送此标头。

遗憾的是,我无法使用 cUrl 进行测试,因为我可以访问的服务器不支持任何支持 HTTP/2 的版本。

我的 SSL 虚拟主机设置:

Protocols h2 http/1.1
SSLEngine On
SSLCACertificateFile xxxxxxxx
SSLProtocol all -SSLv2 -SSLv3
SSLCompression Off
SSLHonorCipherOrder On
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RSA+AES RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4 !AES128"
Header always set Strict-Transport-Security "max-age=15552000;includeSubDomains"
SSLCertificateFile xxxxxxxx
SSLCertificateKeyFile xxxxxxxx

我正在使用 prefork 模块而不是 worker 运行 Apache。

谁能告诉我怎么了?

【问题讨论】:

  • 我在安装 mod_http2 后出现了同样的症状。就我而言,最后也切换到使用 php-fpm(如此处所述:techwombat.com/enable-http2-apache-ubuntu-16-04)为我解决了这个问题。只是把它扔在那里,以防其他人过来!

标签: apache ssl http2 alpn


【解决方案1】:

最后我得到了它的工作。问题是将“SSLChiperSuite”更改为此字符串:

SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-A$

旧版本 - 可以这么说 - 一个阻止 http2 的选项。顺便说一句,我的 SSL 测试等级仍然是 A+。

【讨论】:

    【解决方案2】:

    您不能升级h2 协议。

    HTTP/1.1 升级机制是由客户端发起的。

    如果我对您的理解正确,并且您尝试将 UpgradeHTTP2-Settings 标头从服务器发送到客户端,那么这没有任何意义。客户端发送这些标头,而不是服务器。

    此外,虽然 HTTP/2 协议本身允许通过 HTTP/1.1 升级到 h2c 进行明文通信(请注意协议名称末尾的 c),但浏览器供应商尚未实现此机制并且仅在 ALPN 协商后使用 HTTP/2 协议。

    总结:

    • 您可以从 HTTP/1.1 升级到 HTTP/2 明文 (h2c),但仅限于非浏览器客户端,例如 nghttp。这是here 解释的。
    • 升级机制仅由客户端发起,它们将发送UpgradeHTTP2-Settings 标头,而不是服务器。
    • 浏览器仅支持通过 ALPN (h2) 协商 HTTP/2。这意味着您不能在浏览器和服务器之间使用明文 HTTP/2。

    【讨论】:

    • 谢谢,但我从来没有提到过 h2c,我也不想让它发挥作用。除此之外,你误解了关于标题的部分,没关系。
    • 您在问题标题和正文中提到并强调的是具有升级标题。 sbordet 指出升级仅用于明文是正确的,但他可能不知道某些客户端可能会为 h2 发送这些标头。只有当标头表明浏览器正在尝试 h2 时,它才能提供信息。服务器被指定忽略“升级:h2”,正是因为 HTTP/2 将通过 ALPN 在安全连接上进行协商。所以这解释了你的“奇怪的事情”。升级标头显示了浏览器的意图,但它们并没有真正为安全的 HTTP/2 做任何事情。
    【解决方案3】:

    预分叉

    您提到,您使用 prefork mpm。如果配置了 prefork mpm,Apache 网络服务器将不会使用 HTTP/2,它会默认使用 HTTP 1.1。

    *"Disable and give warning when mpm_prefork is encountered. The server will 
    continue to work, but HTTP/2 will no longer be negotiated."* ([Apache Revision 
    : SECURITY: CVE-2017-9789: Read after free in mod_http2.][1])
    

    虽然这在提出问题时可能有效,但这不会 目前工作。使用不同的 mpm 或切换到 php-pm 和 worker 或 event。


    HTTPS

    正如其中一个答案中已经提到的,加密可能是一个问题。应为 HTTPS 正确配置服务器,并且应通过 HTTPS 提供请求。


    更多信息

    【讨论】:

      【解决方案4】:

      我有同样的问题,所以我尝试了你的“解决方案”。 但是使用这个 cipherSuite-Code 大多数 IE,Android 和 Safari 将因为“handshake_failure”而被阻止!

      https://www.ssllabs.com/ssltest/analyze.html上测试

      您知道哪些 cipherSuite 条目确实阻止了 HTTP2(ALPN 不可用)吗?

      【讨论】:

      • 我刚刚用 Certbot 的这个密码替换了整个密码。这个工作: EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE- RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256: DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384: AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4
      猜你喜欢
      • 2017-05-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 2015-11-03
      • 1970-01-01
      • 1970-01-01
      • 2014-06-29
      • 2020-08-14
      相关资源
      最近更新 更多