0

I am trying to convert an old infrastructure featuring several webservers into a virtualized environment with a single public IP address.

All servers are relatively low-traffic, so performance isn't an issue.

I currently have nginx installed directly on my firewall/bastion-host reverse proxying to a few servers (three, at the moment).

I have everything working with plain HTTP.

My current HTTP configuration is (simplified):

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen 80;
        server_name mydom.com www.mydom.com;
        location / {
            proxy_pass http://192.168.99.20:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    server {
        listen 80;
        server_name redmine.mydom.com git.mydom.com;
        location / {
            proxy_pass http://192.168.99.30:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    server {
        listen 80;
        server_name mail.mydom.com email.mydom.com webmail.mydom.com;
        location / {
            proxy_pass http://192.168.99.10:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

Question is: How should I configure nginx to forward HTTPS/SSL?

I tried something along the lines:

server {
    listen       443 ssl;
    server_name mydom.com www.mydom.com;
    location / {
        proxy_pass https://192.168.99.20;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

but this does not work for lack of ssl_... stanzas.

The "real" (proxyed) servers already have their certificates, but nginx seems to need "local" certificates (which I wouldn't like to provide).

What is "best practice" in this usage case?

NOTE: as said I need to deploy the reverse-proxy on my firewall (IPFire) so I'm rather limited in my choices; nginx and haproxy are supprted, sniproxy isn't.

  • If you're going to have nginx making any decision at all based on the request, it needs a key/cert pair to be able to read the request. – DerfK Nov 2 '16 at 18:45
  • If it is OK to have the connections from Nginx to the servers unencrypted. consider deploying the certificates in Nginx. – aventurin Nov 2 '16 at 18:51
  • @DerfK: The only decision nginx will need to make is where to proxy and that is completely determined by server_name. Do I need local certs? – ZioByte Nov 2 '16 at 20:09
  • @aventurin: Reason why I don't like that solution is I'm planning to use letsencrypt.org Certbot and I'm unsure how well their ACME protocol will play with split configuration. Any hint? – ZioByte Nov 2 '16 at 20:12
1

Try haproxy

I had success in using it. I portfoward all my incoming traffic to the haproxy VM then it carried over the SSL connections to my websites running in other VMs.

Here is a good start using haproxy

  • I have not been able to understand how to use haproxy in my use case. All pass-through configurations seem to involve load balancing (i.e.: a pool of equivalent servers) while I need to do virtual server dispatching. – ZioByte Nov 2 '16 at 23:52
  • @ZioByte This post seems to be what you need, but I've never used haproxy before and I don't know how to separate out the SNI-related bits from all the other haproxy stuff – DerfK Nov 3 '16 at 18:03
0

You can do this even without installing certificates on nginx using the stream module. This way nginx acts as a TCP proxy though and you loose the ability to act based on the HTTP content (headers, cookies, etc).

Here you can fond more from the official documentation:

https://www.nginx.com/resources/admin-guide/tcp-load-balancing/

https://nginx.org/en/docs/stream/ngx_stream_core_module.html

  • 1
    I need the ability to chose the "right" backend server based on server_name, otherwise the whole exercise is pointless. I'll edit the question adding my current (working) HTTP configuration. – ZioByte Nov 2 '16 at 23:59
  • Maybe this can help in your case: nginx.org/en/docs/stream/ngx_stream_ssl_module.html I see there is support for SNI – Fredi Nov 4 '16 at 11:19
0

I don't think nginx has the ability to do this, but I ran across sniproxy that appears to be designed to do what you want by starting the SNI handshake to identify the desired hostname, then passing it on to the correct server without needing the actual keys or certificates.

Since it requires SNI, connections to it from IE on XP and other old clients that don't support itwill fail.

  • Nice, but I need to deploy to a rather limited firewall (IPFire) where nginx and haproxy are supported, but sniproxy does not appear. – ZioByte Nov 2 '16 at 23:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.