Nginx: How to combine ssl_preread_protocol with ssl_preread_server_name (ssh-multiplexing and ssl-sni-passthrough)

nginxpassthroughsni

I have the nginx.conf file shown below.

I want to run both ssh and a webserver on port 443/SSL.
Also known as SSL-port-multiplexing.
At the same time, I want to use ssl-passthrough with SNI.

For ssh-multiplexing, I use $ssl_preread_protocol.
For SSL-SNI-passthrough, I use $ssl_preread_server_name

If I set proxy_pass $upstream;, then ssh works fine, but the webpage(s) don't work.
If I set proxy_pass $name;, then SSL-SNI-passthrough works, but ssh can't be accessed.

How can I combine the two map instructions ?
e.g. something like

if $upstream = ssh 
then proxy_pass $upstream
else proxy_pass $name;
endif

The problem is I need a way to combine the protocol-selection with the server_name-selection.

if(ssh) => forward to port 22
else => forward to port xy depending on server_name

Here's my config file:

stream{

    upstream ssh 
    {
        server 127.0.0.1:22;
    }
    
    upstream https_default_backend 
    {
        server 127.0.0.1:443;
    }
    
    upstream daniel_backend 
    {
        server 127.0.0.1:5005;
    }
    
    
    map $ssl_preread_protocol $upstream 
    {
        default ssh;
        "TLSv1.3" https_default_backend;
        "TLSv1.2" https_default_backend;
        "TLSv1.1" https_default_backend;
        "TLSv1" https_default_backend;
    }
    
    
    map $ssl_preread_server_name $name 
    {
        localhost daniel_backend;
        prodesk daniel_backend;
        daniel-steiger.ch daniel_backend;
        www.daniel-steiger.ch daniel_backend;
        default https_default_backend;
    }
    
    
    # SSH and SSL on the same port
    server {
        listen 443;
        
        ssl_preread on;
        #proxy_protocol on;
        
        # proxy_pass $upstream;
        proxy_pass $name;
    }
    
}

Best Answer

Already find the solution?

I also have this problem, and I try this. It seems ok.

stream {

upstream ssh {
    server 127.0.0.1:22;
}

upstream https_default_backend {
    server 127.0.0.1:443;
}

upstream daniel_backend {
    server 127.0.0.1:5005;
}

map $ssl_preread_protocol $upstream {
    "" ssh;
    default $name;
    "TLSv1.3" $name;
    "TLSv1.2" $name;
    "TLSv1.1" $name;
    "TLSv1" $name;
}
    
map $ssl_preread_server_name $name {
    localhost daniel_backend;
    prodesk daniel_backend;
    daniel-steiger.ch daniel_backend;
    www.daniel-steiger.ch daniel_backend;
    default https_default_backend;
}

server {
    listen 443;
    ssl_preread on;
    proxy_pass $upstream;
}
}