title: Nginx `proxy_ssl_trusted_certificate` with letsencrypt upstream
body: <p>I'm trying to use a <code>proxy_pass</code> with nginx where the connection to the upstream server is encrypted. The certificate of the upstream server has been created by a letsencrypt certbot.</p>
  <pre><code># upstream server: nginx.conf
  
  stream {
    server {
      listen 636 ssl;
  
      ssl_certificate /etc/letsencrypt/live/upstream.example.com/fullchain.pem; # managed by Certbot
      ssl_certificate_key /etc/letsencrypt/live/upstream.example.com/privkey.pem; # managed by Certbot
  
      # ...
    }
  }
  </code></pre>
  <p>When not verifying the proxy certificate in the downstream server, everything works fine.</p>
  <pre><code># downstream server: nginx.conf
  
  stream {
    server {
      listen 636 ssl;
  
      ssl_certificate /etc/letsencrypt/live/downstream.example.com/fullchain.pem; # managed by Certbot
      ssl_certificate_key /etc/letsencrypt/live/downstream.example.com/privkey.pem; # managed by Certbot
  
      proxy_ssl on;
      proxy_ssl_verify off;
  
      proxy_pass upstream.example.com:636;
  
      # ...
  
    }
  }
  </code></pre>
  <p>However, if I'm trying to verify the upstream certificate on the downstream server, I'm getting an <strong>upstream SSL certificate verify error: (2:unable to get issuer certificate) while SSL handshaking to upstream</strong> in the nginx error log.</p>
  <pre><code># downstream server: nginx.conf
  
  stream {
    server {
      listen 636 ssl;
  
      ssl_certificate /etc/letsencrypt/live/downstream.example.com/fullchain.pem; # managed by Certbot
      ssl_certificate_key /etc/letsencrypt/live/downstream.example.com/privkey.pem; # managed by Certbot
  
      proxy_ssl on;
      proxy_ssl_verify on;
      proxy_ssl_trusted_certificate /etc/nginx/ssl/upstream.example.com/chain.pem;
      proxy_ssl_verify_depth 2;
  
      proxy_pass upstream.example.com:636;
  
      # ...
  
    }
  }
  </code></pre>
  <p>Which settings for <code>proxy_ssl_trusted_certificate</code> and <code>proxy_ssl_verify_depth</code> do I need if the upstream server I'm trying to connect to has a letsencrypt certificate?</p>
  <p>I've varied <code>proxy_ssl_verify_depth</code> from 0 to 5, and I've used the upstream server's <code>fullchain.pem</code>, <code>chain.pem</code>, and <code>cert.pem</code> for <code>proxy_ssl_trusted_certificate</code>, but each was unsuccessful.</p>
  <h3>Additional info</h3>
  <p>Verifying the CA certificate with <code>openssl</code> works:</p>
  <pre><code># openssl verify -verify_depth 2 chain.pem
  chain.pem: OK
  </code></pre>
  <p>Verifying the certificate from the upstream server, <code>fullchain.pem</code>, against the CA certificate works:</p>
  <pre><code># openssl verify -CAfile chain.pem fullchain.pem
  fullchain.pem: OK
  </code></pre>
  <h3>Further references</h3>
  <ul>
  <li><a href="https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/" rel="nofollow noreferrer">https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/</a></li>
  <li><a href="https://nginx.org/en/docs/http/ngx_http_proxy_module.html" rel="nofollow noreferrer">https://nginx.org/en/docs/http/ngx_http_proxy_module.html</a></li>
  </ul>