Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine nginx "stream" and "http" for the same servername?

Tags:

nginx

I would like to handle 2 servernames, say "web1.example.com" and "web2.example.com" on the same port (443) in the same nginx config where the first should be a local http server, and the second needs to be forwarded to an external upstream without terminating the SSL connection.

How do I configure this?

Details:

I can use nginx to look at the first SSL message (CLientHello) and use it to proxy/forward the entire connection without terminating SSL. This can even look at the SNI and choose a different upstream based on the servername in it. This uses the ngx_stream_ssl_preread_module with proxy_pass and ssl_preread on. The config is something like this:

stream {
    upstream web1 {
        server 10.0.0.1:443;
    }
    upstream web2 {
        server 10.0.0.2:443;
    }

    map $ssl_preread_server_name $upstream {
        web1.example.com web1;
        web1-alias.example.com web1;
        web2.example.com web2;
    }

    server {
        listen 443;

        resolver 1.1.1.1;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;

        proxy_pass $upstream;
        ssl_preread on;
    }
}

This is configured in the stream config section of nginx.

But I can also configure a local http server in the http config section of nginx. So what if I want web1 ("web1.example.com" in the example) to use such a "local nginx http server", and not an external "upstream server"? ("web2" should still be forwarded as before.) So I want to configure "web1.example.com" in the http config section of nginx, and "forward" to it in the stream config section of nginx.

To be clear, I want "web1.example.com" to be configured like this:

http {
    server {
        listen 443 ssl;
        server_name web1.example.com web1-alias.example.com;

        ssl_certificate ...
        location ...
        ...
    }
}

This all works find if I do either stream or http listening on the same port. But how do I do both on the same port? How can I "call" the http config section from the streams config section? Can proxy_pass refer to a local nginx http server somehow?

like image 597
Coder Nr 23 Avatar asked Nov 06 '22 03:11

Coder Nr 23


1 Answers

I don't think you can use both on the same port, but maybe something like this would work?

stream {
    upstream web1 {
        server 127.0.0.1:8443;
    }
    upstream web2 {
        server 10.0.0.2:443;
    }

    map $ssl_preread_server_name $upstream {
        web1.example.com web1;
        web1-alias.example.com web1;
        web2.example.com web2;
    }

    server {
        listen 443;

        resolver 1.1.1.1;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;

        proxy_pass $upstream;
        ssl_preread on;
    }
}

http {
    server {
        listen 8443 ssl;
        server_name web1.example.com web1-alias.example.com;

        ssl_certificate ...
        location ...
        ...
    }
}
like image 115
Ivan Shatsky Avatar answered Dec 04 '22 08:12

Ivan Shatsky