【问题标题】:curl certificate fail in docker containercurl证书在docker容器中失败
【发布时间】:2020-02-08 19:19:24
【问题描述】:

我在coporate proxy 后面有一个Ubuntu 18.04 server

我设置了http_proxyhttps_proxy 环境变量。

服务器正在运行 Docker 19.03,它也被配置为使用 http_proxy 和 https_poxy。

如果在容器内运行docker run -it ubuntu:18.04,我可以执行apt updateapt install curl -y

然后我可以做类似curl www.google.com 的事情。

但它不适用于https

root@1b6abfb4ff90:/# curl -v -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
% Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                             Dload  Upload   Total   Spent    Left  Speed
0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     
0*   Trying 10.30.88.14...
* TCP_NODELAY set
* Connected to xxx (10.30.88.14) port 8080 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to raw.githubusercontent.com:443
> CONNECT raw.githubusercontent.com:443 HTTP/1.1
> Host: raw.githubusercontent.com:443
> User-Agent: curl/7.58.0
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 200 Connected
< 
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* CONNECT phase completed!
* CONNECT phase completed!
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [91 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2741 bytes data]
* TLSv1.2 (OUT), TLS alert, Server hello (2):
} [2 bytes data]
* SSL certificate problem: unable to get local issuer certificate
* stopped the pause stream!
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* 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 未能验证服务器的合法性,因此无法 建立与它的安全连接。要了解更多关于这种情况和 如何修复它,请访问上面提到的网页。

在容器之外,它工作正常。我还在另一台不在代理后面且在容器内工作的服务器上进行了完全相同的尝试。

所以我想这是 docker 守护进程的配置问题。或者也许我错了...... 解决办法是什么?

【问题讨论】:

  • 您是否尝试安装apt-get install ca-certificates
  • 是的,它是最新的。它是用 curl 安装的。
  • 能否提供curl -v -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar 的输出,好吗?还要检查容器中是否有证书颁发者的 CA 证书。
  • 我更新了问题。如何检查容器中证书颁发者的 CA 证书是否可用?

标签: docker ssl curl ubuntu-18.04


【解决方案1】:

您需要将 SSL 证书安装到 Ubuntu 容器中。例如,在一个正在运行的实例上,您可以这样做:

apt-get update
apt-get install ca-certificates

然后,您的所有 HTTPs 连接都可以使用 CA 根证书的本地副本进行验证。

对于生产部署,此命令应位于 Dockerfile 中:

RUN \
  apt-get update && \
  apt-get install ca-certificates && \
  apt-get clean

编辑

您的代理可能具有不受信任的证书。您可以将其添加到捆绑包中,或者告诉curl 不要使用curl --proxy-insecure 检查代理的证书。

来自https://curl.se/docs/sslcerts.html

从 7.52.0 版本开始,curl 可以单独对代理做 HTTPS 与服务器的连接。此 TLS 连接已处理 与服务器连接分开,因此而不是 --insecure 和 --cacert 控制证书验证,您使用--proxy-insecure 和--proxy-cacert。使用这些选项,您可以确保 TLS 连接和代理的信任可以完全保持 与服务器的 TLS 连接分开。

【讨论】:

    【解决方案2】:

    https://curl.haxx.se/ca/cacert.pem 下载最新的 cacert.pem,更好的方法是在 dockerfile 中添加一个步骤来安装证书作为构建步骤的一部分。

    按照步骤安装

    1. https://curl.haxx.se/ca/cacert.pem下载文件
    2. 将文件重命名为 cacert.crt
    3. 将文件复制到 Go to /usr/local/share/ca-certificates/
    4. 运行命令sudo update-ca-certificates

    【讨论】:

    • 我应该把它放在哪里?在 /etc/ssl/certs/ca-certificates.crt 中?如果是,则没有任何改变。
    • 谢谢,第 2 步是我需要的解决方案。
    【解决方案3】:

    不要将 /etc/:/etc/ 挂载到 docker 容器。主机中的 /etc/ 不适用于 docker 容器。让 docker 容器使用自己的 /etc/。

    【讨论】:

      猜你喜欢
      • 2018-10-20
      • 1970-01-01
      • 2017-10-19
      • 2015-06-05
      • 2014-10-14
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多