Как выяснить, почему Nginx возвращает 400, когда использует его как балансировщик нагрузки http / 2? - PullRequest
0 голосов
/ 28 января 2019

Я сам реализую прокси-сервер http / 2 и использую Nginx в качестве балансировщика нагрузки.

Когда я использую Nginx в качестве балансировщика нагрузки h2c, он работает:

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:

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:

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:

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

Поэтому я пытаюсь выяснить, почему он возвращает 400, а яиспользую SSL.Но Nginx не записывает процесс в журнал ошибок, даже если я установил уровень журнала для отладки (и он был скомпилирован с опцией --with-debug).

Есть ли хорошая идея отладить его?

1 Ответ

0 голосов
/ 28 января 2019

Похоже, Nginx не думает, что говорит HTTP / 2, поскольку клиент go отправляет предисловие к соединению ("PRI * HTTP/2.0"), которое Nginx считает реальным сообщением.

Вероятная проблема заключается в том, что Nginxне сказал в рукопожатии SSL / TLS, что он поддерживает HTTP / 2 через ALPN (или более старый NPN).С какой версией OpenSSL (или эквивалентной) была построена Nginx?Запустите nginx -V, чтобы увидеть это.В идеале вы хотите, чтобы версия 1.0.2 или выше поддерживала ALPN.

Также убедитесь, что ваш шифр SSL / TLS не использует один из шифров, запрещенных для HTTP / 2 .Конфигурация, подобная приведенной ниже (, сгенерированная генератором конфигурации SSL Mozilla ), должна обеспечивать предпочтение правильных шифров:

# 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;
...