Table of Contents

, ,

Proxy pass nginx connection using self-signed certificates

This is when the domain itself is using letsencrypt certificates but the the connection is proxied to a different server by ssl with self-signed certs.

Create the certificates first.

Frontend server configuration

location / {
        proxy_pass https://remoteapp;
        proxy_set_header Host $host;
 
	proxy_ssl_name                  appdomain;
	proxy_ssl_server_name           on;
        proxy_ssl_certificate           /etc/ssl/certs/client.crt;
        proxy_ssl_certificate_key       /etc/ssl/certs/client.key;
        proxy_ssl_trusted_certificate   /etc/ssl/certs/trusted_ca_cert.crt;
        proxy_ssl_verify                on;
        proxy_ssl_verify_depth          2;
        proxy_ssl_session_reuse         on;
        proxy_ssl_protocols             TLSv1.2 TLSv1.3;
        proxy_ssl_ciphers               HIGH:!aNULL:!MD5;

If you followed the certificate creation howto from above, certificate name and key name should all be the same. The trusted_ca_cert.crt file should contain the concatenated server.crt and rootCA contents.

proxy_ssl_name should be exactly the same as the CN field in the server.crt. Otherwise, the nginx will look at the proxy_pass directly and take that hostname and try to compare it with info in the certificate. So if you created the server.crt with CN named “remote”, the proxy_ssl_name and proxy_ssl_server_name are not needed.

Now we only need remoteapp upstream configuration

upstream remoteapp {
        server 1.1.1.1:443 fail_timeout=10s max_fails=3;
    }

Backend server

This server is not directly accessible on http(s) port. It should only accept connection from the “Frontend” server above.

Remote server nginx configuration (i.e. server with ip 1.1.1.1 from above)

upstream myapp {
    server 127.0.0.1:4000 fail_timeout=10s max_fails=3;
}
 
server {
 
    listen 1.1.1.1:443 ssl;
    server_name example.com;
 
    ssl_certificate     /etc/ssl/certs/server.crt;
    ssl_certificate_key /etc/ssl/certs/server.key;
    ssl_client_certificate /etc/ssl/certs/rootCA.crt;
    ssl_verify_client      optional;
 
    access_log /var/log/nginx/example.com_access.log;
    error_log /var/log/nginx/example.com_error.log;
 
    location / {
        proxy_pass http://myapp;
        proxy_set_header Host $host;
        }
}

Tested on

See also

References