Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx proxy over https to server - different hostname on cert than Host header

Tags:

nginx

proxy

ssl

I want to receive traffic at https://example.com, on server 1. I then want to proxy that traffic over https to server 2. Server 2 has Nginx set up with the exact same tls certificate and key as Server 1, so it should theoretically be able to serve the requests. However, when Nginx on server 2 tries to proxy a request to server 2, it sends it to server2.example.com, which differs from the common name on the cert, which is just example.com.

Is there a way to configure nginx to expect the name on the tls cert offered by the host (during tls handshake) to which it is proxying requests to be different from the address of the host to which it is proxying?

Example config on server 1:

server {
    listen        443 ssl;
    server_name   example.com;

    ssl_certificate        /srv/tls/example.com.crt;
    ssl_certificate_key    /srv/tls/example.com.key;

    location / {
        proxy_pass https://server2.example.com;
        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 https;
    }
}

Example config on server 2:

server {
    listen        443 ssl;
    server_name   example.com;

    ssl_certificate        /srv/tls/example.com.crt;
    ssl_certificate_key    /srv/tls/example.com.key;

    location / {
        proxy_pass http://localhost:12345;
        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 https;
    }
}

Example curl from server 1:

$ curl https://server2.example.com/chat -H "Host: example.com"
curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.

If need be, I could generate a new self-signed cert and use that on server 2. However, I assumed it would be faster to just change the Nginx configuration. If the config change is not possible, I'll create a new cert.

like image 586
izrik Avatar asked Apr 07 '18 16:04

izrik


1 Answers

You can use the proxy_ssl_name directive to specify the server name of the proxied host's certificate.

For example:

location / {
    proxy_pass https://server2.example.com;
    proxy_set_header Host $host;
    proxy_ssl_name $host;
    ...
}

See this document for details.

like image 112
Richard Smith Avatar answered Jan 21 '23 14:01

Richard Smith