将http:// @ nushX与HAProxy结合使用不起作用

时间:2018-04-25 12:39:28

标签: nginx haproxy http2 proxy-protocol

当在HaProxy后面配置nginX时,我无法使HTTP / 2推送工作。然而,当网络浏览器直接点击nginX时, 工作。

已经做了很多研究,但没有找到任何提示。希望有人知道我做错了什么。请参阅下面的配置和进一步观察。

配置

相关的HaProxy(版本1.8.7)配置由:

给出

    frontend appname
        bind *:443 ssl crt certificate.pem alpn h2,http/1.1
        mode tcp
        use_backend app-http2 if { ssl_fc_alpn -i h2 }
        default_backend app

    backend app-http2
        mode tcp
        server lamp2 127.0.0.1:8002 check send-proxy

相关的nginX(版本1.14.0)配置如下:


    http {
        # This is the one I would like to use
        server {
            listen       8002 http2 proxy_protocol;

            server_name  _;
            root         /usr/share/nginx/html;

            location / {
                http2_push /image.jpg;
            }
        }

        # This one can be accessed directly; and *does* work
        server {
            listen       8004 http2 ssl;

            ssl_certificate certificate.pem;
            ssl_certificate_key private.key;

            server_name  _;
            root         /usr/share/nginx/html;

            location / {
                http2_push /image.jpg;
            }
        }
    }

观察

  • 在nginx日志中,我可以验证访问内容的两种方式都使用HTTP2。
  • 当我使用Chrome访问该页面时,我可以看到只有在直接访问nginX时才使用push

2018年5月更新 还是没有解决。但人们似乎都认为这是一个错误。我在他们的问题跟踪器上打开了一个问题:https://trac.nginx.org/nginx/ticket/1549#ticket

2018年4月26日更新

似乎问题比http2推送更大。如果我记录$scheme nginX变量,它始终设置为http。从http2。

访问http时都是

所以这显然是问题所在。但是我不知道如何解决这个问题。 Haproxy正在工作tcp模式;因此可能不会做错任何事。

相关(但可能已过时)的Stack Overflow主题为nginx $scheme variable behind load balancer。但是这个答案无助于解决这个问题!

2018年4月25日更新

仍然无法正常工作。但又向前迈进了一步。两个都是nghttp2,结果如下。

两者似乎都嵌入了/image.jpg资源。但是通过haproxy的那个将它的方案设置为http;而不是https。正如人们可以在这个差异中看到的那样:

diff of nghttp requests

我认为是因为这个; Chrome不会使用此推送资源。但我不确定是什么原因造成的!

有没有人有线索?

两个命令的完整输出:


    nghttp -nv https://127.0.0.1:8004/

    [  0.001] Connected
    The negotiated protocol: h2
    [  0.003] send SETTINGS frame 
    (niv=2)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=201, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=101, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=7, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=3, weight=1, exclusive=0)
    [  0.003] send HEADERS frame 
    ; END_STREAM | END_HEADERS | PRIORITY
    (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
    ; Open new stream
    :method: GET
    :path: /
    :scheme: https
    :authority: 127.0.0.1:8004
    accept: */*
    accept-encoding: gzip, deflate
    user-agent: nghttp2/1.25.0
    [  0.003] recv SETTINGS frame 
    (niv=3)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
    [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
    [  0.003] recv WINDOW_UPDATE frame 
    (window_size_increment=2147418112)
    [  0.003] send SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.003] recv SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.003] recv (stream_id=13) :method: GET
    [  0.003] recv (stream_id=13) :path: /image.jpg
    [  0.003] recv (stream_id=13) :scheme: https
    [  0.003] recv (stream_id=13) :authority: 127.0.0.1:8004
    [  0.003] recv (stream_id=13) accept-encoding: gzip, deflate
    [  0.003] recv (stream_id=13) user-agent: nghttp2/1.25.0
    [  0.003] recv PUSH_PROMISE frame 
    ; END_HEADERS
    (padlen=0, promised_stream_id=2)
    [  0.003] recv (stream_id=13) :status: 200
    [  0.003] recv (stream_id=13) server: nginx/1.14.0
    [  0.003] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:26 GMT
    [  0.003] recv (stream_id=13) content-type: text/html
    [  0.003] recv (stream_id=13) content-length: 638
    [  0.003] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT
    [  0.003] recv (stream_id=13) etag: "5ae069c2-27e"
    [  0.003] recv (stream_id=13) accept-ranges: bytes
    [  0.003] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First response header
    [  0.004] recv DATA frame 
    ; END_STREAM
    [  0.004] recv (stream_id=2) :status: 200
    [  0.004] recv (stream_id=2) server: nginx/1.14.0
    [  0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:26 GMT
    [  0.004] recv (stream_id=2) content-type: image/jpeg
    [  0.004] recv (stream_id=2) content-length: 182884
    [  0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT
    [  0.004] recv (stream_id=2) etag: "57656be2-2ca64"
    [  0.004] recv (stream_id=2) accept-ranges: bytes
    [  0.004] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First push response header
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=33248)
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32925)
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.046] recv DATA frame 
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] recv DATA frame 
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.090] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.134] recv DATA frame 
    [  0.134] recv DATA frame 
    [  0.134] recv DATA frame 
    ; END_STREAM
    [  0.134] send GOAWAY frame 
    (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])


    nghttp -nv https://127.0.0.1:8002/

    [  0.001] Connected
    The negotiated protocol: h2
    [  0.003] send SETTINGS frame 
    (niv=2)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=201, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=101, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=0, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=7, weight=1, exclusive=0)
    [  0.003] send PRIORITY frame 
    (dep_stream_id=3, weight=1, exclusive=0)
    [  0.003] send HEADERS frame 
    ; END_STREAM | END_HEADERS | PRIORITY
    (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
    ; Open new stream
    :method: GET
    :path: /
    :scheme: https
    :authority: 127.0.0.1:8002
    accept: */*
    accept-encoding: gzip, deflate
    user-agent: nghttp2/1.25.0
    [  0.003] recv SETTINGS frame 
    (niv=3)
    [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
    [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
    [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
    [  0.003] recv WINDOW_UPDATE frame 
    (window_size_increment=2147418112)
    [  0.003] send SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.004] recv SETTINGS frame 
    ; ACK
    (niv=0)
    [  0.004] recv (stream_id=13) :method: GET
    [  0.004] recv (stream_id=13) :path: /image.jpg
    [  0.004] recv (stream_id=13) :scheme: http
    [  0.004] recv (stream_id=13) :authority: 127.0.0.1:8002
    [  0.004] recv (stream_id=13) accept-encoding: gzip, deflate
    [  0.004] recv (stream_id=13) user-agent: nghttp2/1.25.0
    [  0.004] recv PUSH_PROMISE frame 
    ; END_HEADERS
    (padlen=0, promised_stream_id=2)
    [  0.004] recv (stream_id=13) :status: 200
    [  0.004] recv (stream_id=13) server: nginx/1.14.0
    [  0.004] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:45 GMT
    [  0.004] recv (stream_id=13) content-type: text/html
    [  0.004] recv (stream_id=13) content-length: 638
    [  0.004] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT
    [  0.004] recv (stream_id=13) etag: "5ae069c2-27e"
    [  0.004] recv (stream_id=13) accept-ranges: bytes
    [  0.004] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First response header
    [  0.004] recv DATA frame 
    ; END_STREAM
    [  0.004] recv (stream_id=2) :status: 200
    [  0.004] recv (stream_id=2) server: nginx/1.14.0
    [  0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:45 GMT
    [  0.004] recv (stream_id=2) content-type: image/jpeg
    [  0.004] recv (stream_id=2) content-length: 182884
    [  0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT
    [  0.004] recv (stream_id=2) etag: "57656be2-2ca64"
    [  0.004] recv (stream_id=2) accept-ranges: bytes
    [  0.004] recv HEADERS frame 
    ; END_HEADERS
    (padlen=0)
    ; First push response header
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=33406)
    [  0.004] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.004] recv DATA frame 
    [  0.044] recv DATA frame 
    [  0.044] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.044] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.044] recv DATA frame 
    [  0.044] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] recv DATA frame 
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.045] send WINDOW_UPDATE frame 
    (window_size_increment=32767)
    [  0.045] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] send WINDOW_UPDATE frame 
    (window_size_increment=32768)
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    [  0.046] recv DATA frame 
    ; END_STREAM
    [  0.046] send GOAWAY frame 
    (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])

2 个答案:

答案 0 :(得分:0)

Chrome似乎确保如果在与https方案提供的请求相对应的流上发送推送,则承诺也会使用相同的方案:https://chromium.googlesource.com/chromium/src/+/master/net/spdy/chromium/spdy_session.cc#1766

我不确定检查是否正确:RFC 7540说发送PUSH_PROMISE的服务器应具有权威性。对于http,这意味着主机名匹配,因此浏览器应该能够处理该文件。

也就是说,即使浏览器接受了推送,它也只会在浏览器发出针对http://127.0.0.1:8002/image.jpg的请求时使用它。如果HTML是通过https获取并且请求/image.jpg,那么我不确定浏览器是否会接受提取http://127.0.0.1:8002/image.jpg

这使我们将nginx设置为http。我认为这是因为haproxy执行SSL终止,因此ngnix会看到一个明文连接传入,并且就其而言,方案<​​em>是 http。我不太了解ngnix建议修复此问题。

答案 1 :(得分:0)

我最终在NginX跟踪器上打开了一张票。它已修复。该修补程序在最近发布的1.15.1版本中可用。

  

修正:如果SSL被nginx前面的代理服务器终止,则HTTP / 2服务器推送不起作用。

感谢您的帮助!