0

What im trying to do is have Nginx sit in the middle on a dedicated server and then when it sees a connection on

anything.(localport).vm.example.net

it passes the connection to 127.0.0.1:localport (http) and to 127.0.0.1:localport2 (https, the 2 is the diffrence)

I have it working for http. but for https i need to be able to let the server its passing the connection to set up the SSL.

here is my current nginx config

server {
    listen 195.154.156.215:80;
    server_name ~^(.[^\.]+)(\.)(\d+)\.vm\.example\.net$;

    location / {
      access_log off;
      proxy_pass http://127.0.0.1:$3;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    error_page 501 502 503 /VM-Offline.html;
    location = /VM-Offline.html {
      root   /var/www/html;
    }
}

2 Answers2

0

That doesn't work because nginx needs to read the Host header to route the requests. If you want to use TLS, nginx needs to be the endpoint, or it won't be able to read the header. As far as I know nginx can't read the SNI to route the requests.

That means you have to terminate the requests in the nginx proxy or it won't work.

EDIT

I was wrong. The nginx stream module does support reading the SNI and extracting the hostname with the ngx_stream_ssl_preread_module. This extracts the hostname from the SNI and makes it accessible vie the $ssl_preread_server_name variable. The module is not built by default though.

Christopher Perrin
  • 4,811
  • 19
  • 33
  • If Nginx doesn't understand SNI, then perhaps Nginx could be replaced with something which does understand SNI. – kasperd Oct 12 '18 at 14:35
  • @kasperd I am not aware of any server that can intercept the ClientHello for the SNI message. Terminating SSL in Nginx is the better solution, especially now that LetsEncrypt allows Wildcards. – Christopher Perrin Oct 15 '18 at 10:22
  • Extracting the hostname from the SNI field in the ClientHello message and using that to choose a backend is really easy. I find it hard to believe that I would be the only one who has done it. When I implemented http://v4-frontend.netiter.com/ I needed just 42 lines of code to support SNI. – kasperd Oct 15 '18 at 12:28
  • 1
    You are right. I dug a bit deeper and the Stream module can extract the SNI: http://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html – Christopher Perrin Oct 16 '18 at 12:14
  • HAProxy does it too. It's not all that difficult. – Michael Hampton Oct 16 '18 at 13:45
  • Is till don't think it is a good idea with things like encrypted SNI coming to browsers now. – Christopher Perrin Oct 19 '18 at 14:34
0

Christopher Perrin is right that Nginx will need to terminate the SSL, but after it does you should be able to proxy pass to https again to the local daemon. This question addresses a similar issue.

I'm a little confused about the flow of the routing though, you say the request comes in over the public port, and gets routed to two local ports?

Jon Buys
  • 244
  • 2
  • 5