【问题标题】:Is it possible to run HTTP/2 on NGINX port 443 without ssl?是否可以在没有 ssl 的情况下在 NGINX 端口 443 上运行 HTTP/2?
【发布时间】:2020-08-30 02:38:12
【问题描述】:

我有 Envoy 代理处理 SSL 终止。 Nginx(docker 容器中的 1.17.0,编译为 --with-http_v2_module)是多个上游服务之一。结果,Nginx 在 443 端口接收流量,但不使用ssl 模块:

server {
    listen 443;
    server_name example.com www.example.com;
    root /var/www/html;

...

这很好,但如果我尝试将http2 添加到我收到的监听行的末尾:

curl: (1) Received HTTP/0.9 when not allowed

...不仅针对有问题的 example.com,还针对所有服务器。

出于明显的性能原因,我希望 Envoy 通过 HTTP/2 与 Nginx 对话。

是否有一些技巧可以让 nginx 在端口 443 上使用 http2 而无需 SSL 终止?


编辑:

核心nginx.conf

user  nginx;
worker_processes  2;

pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    client_max_body_size 64M;

    sendfile        on;

    keepalive_timeout  65;

    fastcgi_cache_path /etc/nginx-cache levels=1:2 keys_zone=multipress:100m inactive=60m;
    fastcgi_cache_key "$scheme$request_method$host$request_uri";
    fastcgi_cache_use_stale error timeout invalid_header http_500;
    fastcgi_ignore_headers Cache-Control Expires Set-Cookie;

    gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

请注意,我可以使用明确的 curl --http2 命令成功地 curl 当前的 Envoy HTTP2 服务器。问题是 Envoy 和 Nginx 之间的 HTTP2 连接。

【问题讨论】:

  • 你能显示你正在使用的 curl 命令吗?
  • @BarryPollard 这实际上也是 Kubernetes 健康检查返回的错误。但我只是从 docker 容器内部做了一个“curl localhost:443”。当然我的curl版本支持http2,我已经在http/2服务器上测试过了。事实上,当我使用当前 Envoy (http2) -> nginx (http1) 路径卷曲相同的资源时,它就可以工作。

标签: ssl nginx http2 envoyproxy


【解决方案1】:

Include "http2" right after the listen port in /etc/nginx/nginx.conf 如下和restart nginx pid(服务 nginx 重启)

server {
    listen 80 http2;
    server_name  myhost.mydomain.com;

location ^~ /api/detection/ {
    include uwsgi_params;
    proxy_pass    http://models;
}

【讨论】:

  • 这里让 nginx 返回一个坏的返回。状态为 200 并显示一条消息:HTTP/1.0 200 This buggy server did not return headers
【解决方案2】:

Nginx 只支持 h2c(也就是没有 HTTPS 的 HTTP/2 的叫法),所以不能使用 HTTP/1.1 连接再升级。

事实上,如果你尝试使用 HTTP/1.1 连接,那么 nginx 会报错为it doesn’t support HTTP/1.1 and HTTP/2 on the same port unless you are using HTTPS

所以对于 curl 你必须使用这个语法直接跳转到 HTTP/2:

curl --http2-prior-knowledge localhost:80

不确定 Envoy 中是否存在与不使用类似的配置,但如果上述配置适用于 curl 并且 Envoy 仍然出现相同的错误,那么至少你已经得到了 Nginx 问题的答案。

但是,我完全不确定为后端服务器启用 h2c 是否必要,甚至是否明智。首先,如上所述禁用 HTTP/1.1,任何其他应用程序、服务,甚至使用 HTTP/1.1 的 curl 测试命令都会中断。

除了the benefits of HTTP/2 at the back end are questionable,主要好处是客户端到服务器的连接,而不是服务器到服务器的后端连接。

【讨论】:

  • 非常好,非常彻底——我没有意识到关于 HTTP/2 后端的这一点。那我就放弃这个想法了:)
猜你喜欢
  • 2016-09-17
  • 1970-01-01
  • 2018-01-03
  • 2021-12-28
  • 2013-12-31
  • 2017-04-01
  • 2019-07-02
  • 2011-07-24
  • 1970-01-01
相关资源
最近更新 更多