Lonko
Lonko

Reputation: 379

nginx ssl_preload ssh,http,https setup

I saw examples of combining HTTPS/SSH Selecting an upstream based on SSL protocol version:

map $ssl_preread_protocol $upstream {
    default   ssh.example.com:22;
    "TLSv1.2" new.example.com:443;
}

# ssh and https on the same port
server {
    listen      192.168.0.1:443;
    proxy_pass  $upstream;
    ssl_preread on;
}

But i don't know how to combine SSH, HTTPS(TLS) and HTTP on same port? Is this even possible ?

Thank you

Upvotes: 1

Views: 1249

Answers (1)

saga111a
saga111a

Reputation: 40

Fast answer

you should change type of mapping and set upstream blocks.

#set block with web upstream
#set block with ssh upstream

map $ssl_preread_protocol $upstream {
    ""   ssh.example.com:22;       #change to ssh upstream
    "TLSv1.2" new.example.com:443; #change to web upstream
    default new.example.com:443;   #change to web upstream
}

Normal answer

But Fast answer is wrong too. In second place of "TLSv1.2" new.example.com:443; should stay name of streaming like web or ssh or my_home_server.

e.g "TLSv1.2" new.example.com:443; -> "TLSv1.2" web.

And you should set upstream blocks.

   upstream web {
       server new.example.com:443;
   }
   upstream ssh {
       server ssh.example.com:22;
   }

Just answer

I see that you try to use the subdomain for ssh. It is not necessary. You can choose not to use subdomain in upstream map with $ssl_preread_protocol and change SSL server listen port fro 443 to 4433(or any else). e.g. ssh and https in same port by nginx.

After combining information from top we can set that

 stream {
       upstream ssh {
           server localhost:22;   # ssh port in our server
       }

       upstream web {
           server localhost:4433; # SSL web page port in our server
       }

       map $ssl_preread_protocol $upstream {
           "" ssh;    #if $ssl_preread_protocol is EMPTY try to use ssh upstream
           "TLSv1.2" web;  #if $ssl_preread_protocol is TLSv1.2(may be add more TLSv1.3) try to use web upstream    
           default web;
       }

       server {
         listen 443;    
         proxy_pass $upstream;  #send connetion to specific upstream that correspondintly map block
         ssl_preread on;  #allow to read $ssl_preread_protocol variable
       }

and in block with ssl cert has only one changes port from 443 to 4433.

##block server 80 port
. . .
server {


    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;
    server_name www.example.com example.com; # managed by Certbot

    location / {
        try_files $uri $uri/ =404;
    }
#changed from 443 to 4433
    listen [::]:4433 ssl ipv6only=on; # managed by Certbot
#changed from 443 to 4433
    listen 4433 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
. . .
##block redirect from http to https

I hope this can help someone because I have been looking for this solution for a long time.

Upvotes: 1

Related Questions