如何找出Nginx用作http/2负载平衡器时为何返回400? [英] How to find out why Nginx return 400 while use it as http/2 load balancer?

查看:300
本文介绍了如何找出Nginx用作http/2负载平衡器时为何返回400?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我自己实现了一个http/2代理,并且使用Nginx作为负载均衡器.

I'm implementing a http/2 proxy myself, and I'm using Nginx as load balancer.

当我将Nginx用作h2c负载均衡器时,它会起作用:

When I use Nginx as h2c load balancer, it works:

server {
    listen 8443 http2;

    location / {
        error_log /Users/jiajun/nginx_error_log.log debug;
        grpc_pass grpc://127.0.0.1:2017;
    }
}

运行它:

$ go run example/grpc_client/main.go
calling to 127.0.0.1:2019
2019/01/28 11:50:46 gonna call c.SayHello...
2019/01/28 11:50:46 Greeting: Hello world

Nginx访问日志为:

And Nginx access log is:

127.0.0.1 - - [28/Jan/2019:11:50:46 +0800] "POST /helloworld.Greeter/SayHello HTTP/2.0" 200 18 "-" "grpc-go/1.16.0" "-"


但是当我在SSL下提供它时,它不起作用:


But it does not work while I'm serving it under SSL:

server {
    listen 8443 ssl http2;
    ssl_certificate     /Users/jiajun/127.0.0.1.crt;
    ssl_certificate_key /Users/jiajun/127.0.0.1.key;

    location / {
        error_log /Users/jiajun/nginx_error_log.log debug;
        grpc_pass grpc://127.0.0.1:2017;
    }
}

运行它:

$ go run example/grpc_client/main.go
calling to 127.0.0.1:2019
2019/01/28 11:53:06 gonna call c.SayHello...
2019/01/28 11:53:06 could not greet: rpc error: code = Unavailable desc = transport is closing
exit status 1

而且,Nginx访问日志是:

And, Nginx access log is:

127.0.0.1 - - [28/Jan/2019:11:53:06 +0800] "PRI * HTTP/2.0" 400 157 "-" "-" "-"


所以我试图找出为什么在我使用SSL时它返回400的原因.但是,即使我已将日志级别设置为调试(并且已使用-with-debug 选项进行编译),Nginx仍不会在错误日志中记录该过程.


So I'm trying to find out why it return a 400 while I'm using SSL. But Nginx does not record the process in error log even I've set log level to debug(and it had compiled with --with-debug option).

是否有调试的好主意?

推荐答案

当go客户端发送连接序言消息("PRI * HTTP/2.0"时,Nginx认为它不是在讲HTTP/2)),Nginx认为这是真实的消息.

Looks like Nginx doesn’t think it’s talking HTTP/2 as the go client is sending the connection preface message ("PRI * HTTP/2.0") which Nginx thinks is a real message.

可能的问题是Nginx没有在SSL/TLS握手中说明它通过ALPN(或更旧的NPN)支持HTTP/2.Nginx使用哪个版本的OpenSSL(或等效版本)?运行 nginx -V 进行查看.理想情况下,您希望1.0.2或更高版本支持ALPN.

The likely issue is that Nginx has not stated in the SSL/TLS handshake that it supports HTTP/2 via ALPN (or the older NPN). Which version of OpenSSL (or equivalent) was Nginx built with? Run nginx -V to see this. Ideally you want 1.0.2 or above to support ALPN.

还要检查您的SSL/TLS密码是否未使用禁止使用的一种密码HTTP/2 .如下所示的配置(由Mozilla SSL配置生成器生成的 )应确保首选正确的密码:

Also check that your SSL/TLS cipher is not using one of the ciphers forbidden for HTTP/2. Config like below (generated by the Mozilla SSL config generator) should ensure the right ciphers are preferred:

# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;

这篇关于如何找出Nginx用作http/2负载平衡器时为何返回400?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆