WSL-Docker:curl:(60) 无法获取本地颁发者证书

cas*_*sen 4 ubuntu ssl curl windows-subsystem-for-linux

重新配置 PC 后,我无法正确使用 Docker,因为某些curl 命令由于 SSL/TLS 问题而被拒绝。

仅在一个示例中curl -vfsSL https://apt.releases.hashicorp.com/gpg返回以下错误:

*   Trying 52.222.214.125:443...
* TCP_NODELAY set
* Connected to apt.releases.hashicorp.com (52.222.214.125) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
Run Code Online (Sandbox Code Playgroud)

经过一番挖掘,我现在知道这个问题也出现在我的 WSL 映像中,但不会出现在主机 Windows 操作系统上。因此,我相信这一定是由我的 WSL 设置引起的问题,而不是由 Docker 本身引起的(?)。

serverfault/stackoverflow 上有很多相关问题,但我发现没有真正适用于这种情况的解决方案:

FWIW 我在一家企业工作,使用 IT 发布的操作系统。显然这可能是错误的根源,但他们无法帮助我调试这个问题。然而,在一位同事的电脑上,它运行得毫无问题。

有任何想法吗?


电脑设置:

  • Windows 10 企业版
    • 版本:21H1
    • 操作系统版本:19043.1645
    • Windows 功能体验包:120.2212.4170.0
  • WSL 2 与 Ubuntu-20.04
  • Docker Desktop 4.7.1 (77678) 与基于 WSL 2 的引擎

更新1

按照@Martin的建议,我尝试下载https://www.amazontrust.com/repository/AmazonRootCA1.pem,将其放入/tmpWSL Ubuntu 中,然后重新运行该命令,curl --cacert /tmp/AmazonRootCA1.pem -vfsSL https://apt.releases.hashicorp.com/gpg但无济于事:

curl --cacert /tmp/AmazonRootCA1.pem -vfsSL https://apt.releases.hashicorp.com/gpg
*   Trying 52.222.214.72:443...
* TCP_NODELAY set
* Connected to apt.releases.hashicorp.com (52.222.214.72) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /tmp/AmazonRootCA1.pem
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
Run Code Online (Sandbox Code Playgroud)

小智 12

我们终于弄清楚了。这里的问题是 IT 部门安装了一个防火墙来拦截 SSL 连接(许多防火墙这样做是为了能够阻止“不良”流量,这些流量由于加密而不会被检测到)。

为了能够拦截 SSL 连接,防火墙将自己的证书放在链接上,并充当代理。这就是问题的根源:docker 容器不信任防火墙使用的 CA,因此拒绝建立连接。显然,对于您的 Windows 计算机,CA 已经添加到信任存储中 - 这也需要为您的 docker 容器完成 - 或者您需要将开关添加--insecure到您的 curl 命令以忽略这些证书错误。

请注意,curl 会正确抛出错误,因为 https 证书机制的发明是为了能够检测“中间人”攻击,而这正是这里发生的情况。(我将在这里跳过我对防火墙破坏 SSL 安全性以便能够检查数据包内容的看法...)

要解决此问题,您需要网关中的 CA 文件来“签署”所有这些证书,并将该 CA 添加到受信任列表中。

为了完整起见,这是您看到的证书:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            6a:7b:6c:fd:70:b2:68:1a:56:e3:11:3c:43:ed:ae:29
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C = US, ST = California, L = Sunnyvale, O = Bad Server Certificate [invalid server certificate], CN = Bad Server Certificate
        Validity
            Not Before: Jan 26 07:08:23 2011 GMT
            Not After : Nov 11 07:08:23 2284 GMT
        Subject: CN = apt.releases.hashicorp.com
[cut]
Run Code Online (Sandbox Code Playgroud)

这是原来的:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            03:57:ef:0e:70:b2:68:1a:56:e3:11:3c:43:ed:ae:29
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
        Validity
            Not Before: Apr 27 00:00:00 2022 GMT
            Not After : May 26 23:59:59 2023 GMT
        Subject: CN = apt.releases.hashicorp.com
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。对我来说,向curl 命令添加 --insecure 标志是不可行/不可能的。所以我对正确的修复感兴趣。我转到 Windows 上的证书存储并从 Zscaler 根 CA 证书导出 CER 文件,现在它在执行 `curl --cacert ca.cer -fsSL https://apt.releases.hashicorp.com/gpg` 时可以工作万岁!最后,“全局”添加此证书的正确方法是什么,这样我就不必每次都指定它? (3认同)
  • 没关系 - 发现于:https://ubuntu.com/server/docs/security-trust-store。万分感谢! (3认同)