Configure Nginx to proxy requests to an HTTPS upstream

Encrypt the upstream connection, verify its certificate, and configure SNI and the HTTP Host header deliberately.

Best practices
Illustration of server operations and request logs

Use an https:// upstream URL and explicitly enable certificate verification. Nginx can terminate the client's TLS connection and create a separate TLS connection to the backend. Both network hops are encrypted, but Nginx can still read the traffic between them.

Configure TLS on both hops

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    location / {
        proxy_pass https://internal-app.example.net:8443;
        proxy_ssl_server_name on;
        proxy_ssl_name internal-app.example.net;
        proxy_ssl_verify on;
        proxy_ssl_trusted_certificate /etc/nginx/ssl/internal-ca.pem;
        proxy_ssl_verify_depth 2;

        proxy_set_header Host internal-app.example.net;
        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;
    }
}

Supply real certificate and trust-bundle paths. Choose the verification depth for the actual chain. The backend must run TLS on the specified port and present a certificate valid for internal-app.example.net.

SNI selects the backend's TLS virtual host; the HTTP Host header selects its HTTP virtual host. They are separate settings. If the application expects the public host, use proxy_set_header Host $host instead and ensure that host is accepted by the backend. This does not change the certificate name used for verification.

Trust private certificates explicitly

Nginx's proxy_ssl_verify defaults to off; merely switching to HTTPS does not authenticate the upstream. For an internal CA, install the appropriate CA certificate bundle. For a self-signed endpoint, explicitly trusting the intended certificate can be appropriate for a controlled setup, with a renewal plan.

proxy_ssl_verify off leaves encryption without upstream identity verification. Do not use it as the permanent answer to a broken certificate chain.

Check names, upstream groups, and TLS versions

When proxy_pass refers to a group such as https://app_pool, set proxy_ssl_name to the backend's certificate name rather than assuming the group label appears in its certificate. Enable SNI when the upstream uses it to select a virtual host. Missing SNI can select a different certificate or endpoint; it does not inevitably fail if the default certificate already matches.

If protocol negotiation fails, compare supported versions at both ends. For a compatible build and backend, an explicit setting is:

proxy_ssl_protocols TLSv1.2 TLSv1.3;

Test the same name and trust path independently:

openssl s_client -connect internal-app.example.net:8443 \
  -servername internal-app.example.net \
  -CAfile /etc/nginx/ssl/internal-ca.pem \
  -verify_hostname internal-app.example.net -verify_return_error

Preserve the full Nginx error and upstream address. Guance's Nginx integration can collect configured logs; verify parsing before relying on fields to distinguish certificate errors from negotiation failures.

FAQ

Does the upstream need its own certificate?

Yes. The frontend certificate does not automatically configure the backend. A private CA is sufficient when Nginx trusts it and verifies the expected name.

Can the public side use HTTP while the upstream uses HTTPS?

Yes, but only the upstream hop is encrypted. For a public service, redirect clients to a correctly configured HTTPS endpoint.

When is upstream TLS useful?

Use it when traffic crosses an untrusted network or your requirements call for encrypted, authenticated hops. Even on a private network, assess exposure and certificate-management costs explicitly; a private address alone does not establish trust.

Reference: Nginx proxy TLS directives.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting