nginx.net-coredocker-composegrpc

How to correctly configure NGINX for gRPC with SSL to connect to a .NET gRPC server?


I have a .NET 8 gRPC server running. Since it's in the testing phase, I configured it to accept gRPC requests on both HTTP 5000 and HTTPS 12345 ports. Everything works fine on my local machine.

However, when I run the server along with NGINX in Docker containers, only the HTTP port works. When I test , I get a 502 Bad Gateway error, but the error logs for local and remote access are different.

2024/11/29 01:31:27 [error] 30#30: *1 upstream prematurely closed connection while reading response header from upstream, client: 172.19.0.1, server: grpcgateway, request: "POST /xxxx/Register HTTP/2.0", upstream: "grpc://172.19.0.4:12345", host: "localhost:12345
172.19.0.1 - - [29/Nov/2024:01:31:27 +0000] "POST /xxxx/Register HTTP/2.0" 502 157 "-" "grpc-node-js/1.8.10"
2024/11/29 02:02:43 [error] 33#33: *31 upstream prematurely closed connection while reading response header from upstream, client: 172.25.88.146, server: grpcgateway, request: "POST /xxxx/Register HTTP/2.0", upstream: "grpc://172.19.0.4:12345", host: "172.25.88.91:12345"
172.25.88.146 - - [29/Nov/2024:02:02:43 +0000] "POST /xxxx/Register HTTP/2.0" 502 157 "-" "grpc-node-js/1.11.0-postman.1"
172.25.88.146 - - [29/Nov/2024:02:02:44 +0000] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03\xB23'iA\xF6\x98FxqZ\xD1\xC8xo\xD0\xA8\x91\xCC\xF4\xB7\xA9\xE4\x85\xE9\xF9L\xF6x\xCD\x0C, \x866\xC7\xC2\x93\xA7\xA7\xD9\xB4\xA8\xD3\xD1\x0E\x85R2\x5Cc\xA7\x89j\xAB\xA1h\xD9\xF7\xB6\xF4\xE8\xDE=\xAF\x00$\x13\x01\x13\x02\x13\x03\xC0/\xC0+\xC00\xC0,\xC0'\xCC\xA9\xCC\xA8\xC0\x09\xC0\x13\xC0" 400 157 "-" "-"
172.25.88.146 - - [29/Nov/2024:02:02:44 +0000] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03" 400 157 "-" "-"

Is there something wrong with my configuration?

Below are the configurations for my .NET server and NGINX.

var serverCert = X509Certificate2.CreateFromPemFile("Credentials/nginx.crt", "Credentials/nginx.key");
option.ListenAnyIP(5000, o =>
{
    o.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
});
option.ListenAnyIP(12345, o => o.UseHttps(httpsOptions =>
    {
        httpsOptions.ServerCertificate = serverCert;
    }
));
worker_processes auto;
 
events {
    worker_connections 1024;
}
 
http {
    include       mime.types;
    default_type  application/octet-stream;
    
    ssl_certificate      /etc/nginx/nginx.crt;
    ssl_certificate_key  /etc/nginx/nginx.key;
    
    server {
        listen 12345 ssl http2;
        server_name grpcgateway;
        default_type application/grpc;

        ssl_session_cache builtin:1000 shared:SSL:10m;
        ssl_session_timeout  5m;

        location / {
           grpc_set_header X-Forwarded-For $remote_addr;
           grpc_pass grpc://abc-server:12345;
        }
    }

    server {
        listen 5000 http2;
        server_name grpcgateway;
        default_type application/grpc;

        location / {
           grpc_set_header X-Forwarded-For $remote_addr;
           grpc_pass grpc://abc-server:5000;
        }
    }
}

PS: My certificates are not important, I would even like to bypass them for testing purposes.


Solution

  • Update: I’ve found the issue.

    server {
        listen 12345 ssl http2;
        server_name grpcgateway;
        default_type application/grpc;
    
        ssl_session_cache builtin:1000 shared:SSL:10m;
        ssl_session_timeout  5m;
    
        location / {
           grpc_set_header X-Forwarded-For $remote_addr;
           grpc_pass grpc://abc-server:12345;
        }
    }
    

    The grpc protocol here should be changed to grpcs:

    grpc_pass grpcs://abc-server:12345;