Nginx 是不是支持以明文形式从 http/1.1 升级 http/2 (h2c)

Posted

技术标签:

【中文标题】Nginx 是不是支持以明文形式从 http/1.1 升级 http/2 (h2c)【英文标题】:Is Nginx support http/2 upgrade from http/1.1 in clear text(h2c)Nginx 是否支持以明文形式从 http/1.1 升级 http/2 (h2c) 【发布时间】:2019-10-10 20:46:03 【问题描述】:

有没有办法支持在nginx中http1.1升级到h2c(不是ssl)?

使用 curl 测试站点http://nghttp2.org/

$ curl --http2  http://nghttp2.org/ -s -o /dev/null -v

我得到以下结果:

*   Trying 139.162.123.134...
* TCP_NODELAY set
* Connected to nghttp2.org (139.162.123.134) port 80 (#0)
> GET / HTTP/1.1
> Host: nghttp2.org
> User-Agent: curl/7.54.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
>
< HTTP/1.1 101 Switching Protocols
< Connection: Upgrade
< Upgrade: h2c
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=33
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200
< date: Fri, 24 May 2019 08:58:43 GMT
< content-type: text/html
< last-modified: Thu, 18 Apr 2019 06:19:33 GMT
< etag: "5cb816f5-19d8"
< accept-ranges: bytes
< content-length: 6616
< x-backend-header-rtt: 0.009521
< server: nghttpx
< via: 2 nghttpx
< x-frame-options: SAMEORIGIN
< x-xss-protection: 1; mode=block
< x-content-type-options: nosniff
<
 [2159 bytes data]
* Connection #0 to host nghttp2.org left intact

但是当我访问一个 nginx 静态网站时,它会失败。

$ curl --http2 -v 10.10.5.89:9006
* Rebuilt URL to: 10.10.5.89:9006/
*   Trying 10.10.5.89...
* TCP_NODELAY set
* Connected to 10.10.5.89 (10.10.5.89) port 9006 (#0)
> GET / HTTP/1.1
> Host: 10.10.5.89:9006
> User-Agent: curl/7.54.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
>
* Connection #0 to host 10.10.5.89 left intact
$

这是我的 nginx 配置文件


server 
    listen 9006 http2 fastopen=3 reuseport;

    location / 
        autoindex_exact_size off;
        root /www/;
        autoindex on;
                
    


nginx 调试信息:

2019/05/24 16:49:53 [debug] 348#348: *1 invalid http2 connection preface "GET / HTTP/1.1
"
2019/05/24 16:49:53 [debug] 348#348: *1 http2 state connection error
2019/05/24 16:49:53 [debug] 348#348: *1 http2 send GOAWAY frame: last sid 0, error 1
2019/05/24 16:49:53 [debug] 348#348: *1 http2 frame out: 0000561508B48B08 sid:0 bl:0 len:8
2019/05/24 16:49:53 [debug] 348#348: *1 http2 frame out: 0000561508B48A58 sid:0 bl:0 len:4
2019/05/24 16:49:53 [debug] 348#348: *1 http2 frame out: 0000561508B489A0 sid:0 bl:0 len:18

【问题讨论】:

【参考方案1】:

使用--http2 标志和http:// URL curl 发送一条HTTP/1.1 消息,请求升级到HTTP/2(upgrade HTTP 标头和HTTP2-Settings HTTP 标头),然后升级,如果网站声明它支持带有 upgrade HTTP 标头的 103 响应的 HTTP/2。

这就是您在对 nghttp2 站点的第一个请求中看到的情况,并且这仅在站点同时理解 HTTP/1.1 和 HTTP/2 时才有效。

您的 nginx 配置仅支持 HTTP/2 而不是 HTTP/1.1,因此这不起作用,因为它不理解初始 HTTP/1.1 请求。 Its not possible to make Nginx support both HTTP/1.1 and HTTP/2 on the same port 所以你的配置是正确的——它不能与那个 curl 命令一起工作。您需要这样做才能让 curl 从一开始就使用 HTTP/2(called prior knowledge in the HTTP/2 spec - 因此是命令行选项名称):

curl --http2-prior-knowledge -v 10.10.5.89:9006

【讨论】:

我知道“--http2-prior-knowledge”选项会起作用。只是想确定一下nginx是否支持http1.1升级到http2。还是谢谢你。

以上是关于Nginx 是不是支持以明文形式从 http/1.1 升级 http/2 (h2c)的主要内容,如果未能解决你的问题,请参考以下文章

利用nginx反向代理嗅探明文密码

打开调试日志记录时,apache httpclient 以明文形式记录密码

升级nginx以支持http2的方法

有没有一种安全的方式通过电子邮件以明文形式向用户发送密码?

在TLS / SSL握手(证书等)中泄露了哪些信息? [关闭]

使用凭证文件(而不是明文)的 RODBC 到 SQL