Nginx `proxy_ssl_trusted_certificate` 与 letsencrypt 上游

Nginx `proxy_ssl_trusted_certificate` with letsencrypt upstream

我正在尝试将 proxy_pass 与 nginx 一起使用,其中与上游服务器的连接是加密的。上游服务器的证书已由 letsencrypt certbot 创建。

# 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

    # ...
  }
}

当不验证下游服务器中的代理证书时,一切正常。

# 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;

    # ...

  }
}

但是,如果我尝试验证下游服务器上的上游证书,我会收到 上游 SSL 证书验证错误:(2:无法获得颁发者证书),同时 SSL 握手到 nginx 错误日志中的上游

# 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;

    # ...

  }
}

如果我尝试连接的上游服务器有 letsencrypt 证书,我需要 proxy_ssl_trusted_certificateproxy_ssl_verify_depth 的哪些设置?

我将 proxy_ssl_verify_depth 从 0 变为 5,并且我将上游服务器的 fullchain.pemchain.pemcert.pem 用于 proxy_ssl_trusted_certificate,但都没有成功。

附加信息

使用 openssl 验证 CA 证书有效:

# openssl verify -verify_depth 2 chain.pem
chain.pem: OK

根据 CA 证书验证来自上游服务器 fullchain.pem 的证书有效:

# openssl verify -CAfile chain.pem fullchain.pem
fullchain.pem: OK

更多参考资料

proxy_ssl_trusted_certificate 所需的 CA 证书不是由 letsencrypt 或上游服务器提供的。它已经安装在下游服务器上。

在 Ubuntu,CA 证书的位置是 /etc/ssl/certs/ca-certificates.crt

# 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/ssl/certs/ca-certificates.crt;

    proxy_pass upstream.example.com:636;

    # ...

  }
}

文档

https://nginx.org/en/docs/http/ngx_http_proxy_module.html

proxy_ssl_verify on | off;

Enables or disables verification of the proxied HTTPS server certificate.

proxy_ssl_verify_depth number;

Sets the verification depth in the proxied HTTPS server certificates chain.

proxy_ssl_trusted_certificate file;

pecifies a file with trusted CA certificates in the PEM format used to verify the certificate of the proxied HTTPS server.

另见