【问题标题】:'composer install' command fails on Docker giving 'SSL Operation Failed with code 1' errorDocker 上的“composer install”命令失败,给出“SSL 操作失败,代码 1”错误
【发布时间】:2020-03-03 20:56:22
【问题描述】:

我在 Windows 机器上,正在运行 Docker。 Docker 镜像是FROM php:7.3-apache

系统:Linux b6df004de9df 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64

使用 Composer 版本 1.9.0 2019-08-02 20:55:32 在此容器中成功安装 Composer。

现在,我进入容器的bash 并输入命令$ composer init 成功运行并初始化作曲家,然而,在$ composer install命令,它给出了一个错误

[Composer\Downloader\TransportException] “https://repo.packagist.org/packages.json”文件不能 已下载:SSL 操作失败,代码为 1。打开 SSL 错误 消息:错误:1416F086:SSL 例程:tls_process_server_certificate:证书验证失败
启用加密失败打开流失败:操作失败

我可以看到它是证书的 OpenSSL 错误,我试图得到确切的错误:

root@b6df004de9df:/var/www/html/my_JSON_proj# openssl s_client -连接 www.google.com:443 CONNECTED(00000003) depth=2 C = US, ST = California, O = Zscaler Inc., OU = Zscaler Inc., CN = Zscaler 中间根 CA (zscalertwo.net) , emailAddress = support@zscaler.com 验证错误:num=20:unable to get local issuer certificate

为了再次确认,我再次尝试:

root@b6df004de9df:/var/www/html/my_JSON_proj# curl https://google.com curl: (60) SSL 证书问题:无法获取本地颁发者证书

Openssl 版本:OpenSSL 1.1.0k 2019 年 5 月 28 日

openssl_get_cert_locations() 的输出:

array(8) {
["default_cert_file"]=> "/usr/lib/ssl/cert.pem"
["default_cert_file_env"]=> "SSL_CERT_FILE"
["default_cert_dir"]=> "/usr/lib/ssl/certs"
["default_cert_dir_env"]=> "SSL_CERT_DIR"
["default_private_dir"]=> "/usr/lib/ssl/private"
["default_default_cert_area"]=> "/usr/lib/ssl"
["ini_cafile"]=> ""
["ini_capath"]=> ""
}

所以要解决这个我尝试过的解决方案

  1. 我创建了我的本地主机证书参考:https://www.digicert.com/ssl-support/openssl-quick-reference-guide.htm#:~:targetText=OpenSSL%20is%20an%20open%2Dsource,and%20how%20to%20use%20them。但不确定何时将该证书放置在 /usr/local/share/ca-certifcates/ 文件夹中并尝试过 curl https://google.com/ --cacert /usr/local/share/ca-certifcates/localhost.pem - 还是一样的错误

  2. 编辑了我的/usr/local/etc/php/php.ini php 配置文件以添加

curl.cainfo="/usr/local/share/ca-certificates/localhost.pem"

openssl.cafile = "/usr/local/share/ca-certificates/localhost.pem" 只是为了找到相同的错误

我一直在尝试这个,但没有运气。我从字面上浏览了几乎所有与 curl、OpenSSL、SSL、Docker 等相关的堆栈溢出帖子,但找不到答案。

  • 进一步的更新和发现
    1. 令人惊讶的是,我想知道 https://curl.haxx.se/ca/cacert.pem(注意 - https)提供的文件“cacert.pem”来解决 SSL 问题,而我无法连接到安全链接,我什至如何从 https 下载 pem 文件?有点僵局?无论如何,所以我尝试使用 wget http://curl.haxx.se/ca/cacert.pem 下载获取 pem 文件的非安全方式,我得到的输出为:
root@b6df004de9df:/usr/local/etc/openssl# wget http://curl.haxx.se/ca/cacert.pem
--2019-11-08 10:21:30--  http://curl.haxx.se/ca/cacert.pem
Resolving curl.haxx.se (curl.haxx.se)... 151.101.38.49, 2a04:4e42:9::561
Connecting to curl.haxx.se (curl.haxx.se)|151.101.38.49|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://curl.haxx.se/ca/cacert.pem [following]
--2019-11-08 10:21:31--  https://curl.haxx.se/ca/cacert.pem
Connecting to curl.haxx.se (curl.haxx.se)|151.101.38.49|:443... connected.
ERROR: The certificate of 'curl.haxx.se' is not trusted.
ERROR: The certificate of 'curl.haxx.se' hasn't got a known issuer.

由于它是一个 Linux 服务器并且没有可用的 GUI,所以我似乎唯一可能的下载方式是通过终端,而不是浏览器。

话虽如此,我手动创建了 cacert.pem 文件并从 curl.haxx.se 中输入了内容。然后使用以下更改更新 php.ini 并重新启动 apache 服务器。

curl.cainfo: /usr/local/etc/openssl/cacert.pem & openssl.cafile: /usr/local/etc/openssl/cacert.pem 仍然 - curl: (60) SSL 证书问题:无法获取本地颁发者证书

  1. 根据“openssl_get_cert_locations()”更新了 curl.cainfo 和 openssl.cafile 的 php.ini,将“/usr/lib/ssl/cert.pem”作为其“default_cert_file”。重新启动 apache 服务器。尝试使用 curl https://www.google.com - 仍然 curl: (60) SSL 证书问题:无法获取本地颁发者证书

  2. 创建了一个新目录“ssl”,因为它还没有存在,并假设默认情况下,OpenSSL 目录是/usr/local/ssl。在该文件夹中创建了 cacert.pem 文件。用这个新的更新路径更新了 php.ini 中的 curl.cainfo 和 openssl.cafile 条目。为了安全起见,请执行update-ca-certificates --fresh 以防万一。重新启动了apache服务器。尝试使用 curl https://www.google.com - 仍然 curl: (60) SSL 证书问题:无法获取本地颁发者证书

附注 cURL 命令的完整输出

root@b6df004de9df:/usr/lib/ssl/certs# curl https://thawte.com
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
root@b6df004de9df:/usr/lib/ssl/certs# openssl s_client -connect thawte.com:443
CONNECTED(00000003)
depth=2 C = US, ST = California, O = Zscaler Inc., OU = Zscaler Inc., CN = Zscaler Intermediate Root CA (zscalertwo.net)
, emailAddress = support@zscaler.com
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:/businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=Utah/serialNumber=5299537-0142/C=US/ST=Utah/
L=Lehi/O=DigiCert, Inc./OU=IT/CN=thawte.com
   i:/C=US/ST=California/O=Zscaler Inc./OU=Zscaler Inc./CN=Zscaler Intermediate Root CA (zscalertwo.net) (t)
 1 s:/C=US/ST=California/O=Zscaler Inc./OU=Zscaler Inc./CN=Zscaler Intermediate Root CA (zscalertwo.net) (t)
   i:/C=US/ST=California/O=Zscaler Inc./OU=Zscaler Inc./CN=Zscaler Intermediate Root CA (zscalertwo.net)/emailAddress=su
pport@zscaler.com
 2 s:/C=US/ST=California/O=Zscaler Inc./OU=Zscaler Inc./CN=Zscaler Intermediate Root CA (zscalertwo.net)/emailAddress=su
pport@zscaler.com
   i:/C=US/ST=California/L=San Jose/O=Zscaler Inc./OU=Zscaler Inc./CN=Zscaler Root CA/emailAddress=support@zscaler.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGpzCCBY+gAwIBAgIQv2zANBgkqhkiG9w0XcVFbs+k59YwRwR4v+pBAQsFADCB
jTELMAkMxEzARBgNVBAgGA1UEBhMCVVTCkNhbGlmb3JuaWExFTATBgNVBAoTDFpz
... few more lines ...
vxrc40H5bMPW/NgnBjRtUEPnAx9b3ll/sj3KfhbxU0bgnEYNMLb+nwnK6NDZRFpC
5E3fG+TFc9ehaBcF5xWttKz28Wr2nUUhMLhC
-----END CERTIFICATE-----
subject=/businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=Utah/serialNumber=5299537-0142/C=US/ST=Ut
ah/L=Lehi/O=DigiCert, Inc./OU=IT/CN=thawte.com
issuer=/C=US/ST=California/O=Zscaler Inc./OU=Zscaler Inc./CN=Zscaler Intermediate Root CA (zscalertwo.net) (t)
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4270 bytes and written 326 bytes
Verification error: unable to get local issuer certificate
---
New, TLSv1.0, Cipher is ECDHE-RSA-AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-SHA
    Session-ID:
    Session-ID-ctx:
    Master-Key: 06D54188D4F60C7746664262F72361EFE8DC728E9D37FDB25641A28C226DE83C3C574C781A0E4A268A7AEB6187EF54BF
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1573209517
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
    Extended master secret: no
---
read:errno=0

当前用于构建镜像的 DockerFile:

FROM php:7.3-apache 

RUN docker-php-ext-install mysql mysqli

RUN apt-get update -y && apt-get install -y sendmail libpng-dev

RUN apt-get update && \
    apt-get install -y \
        zlib1g-dev 
        libbz2-dev \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng12-dev \
        libxpm-dev \
        libvpx-dev \
        libmcrypt-dev \
        libmemcached-dev \
        && \

RUN docker-php-ext-install mbstring

RUN docker-php-ext-install zip

RUN docker-php-ext-install gd

RUN docker-php-ext-install opcache

RUN docker-php-ext-install \
        bcmath \
        bz2 \
        exif \
        ftp \
        gd \
        gettext \
        mbstring \
        mcrypt \
        mysqli \
        opcache \
        pdo_mysql \
        shmop \
        sockets \
        sysvmsg \
        sysvsem \
        sysvshm \
        zip \
        p7zip-full \
    && \

【问题讨论】:

    标签: php docker ssl curl openssl


    【解决方案1】:

    我认为您使用了代理 (Zscaler),请尝试获取证书并更新它们,步骤如下:https://stackoverflow.com/a/70011298/5078874

    【讨论】:

      【解决方案2】:

      终于把问题解决了。实际上,我从来不需要设置 curl.cainfoopenssl.cafile 或任何其他更新,例如下载证书以在容器中使用等。After I create a Self Signed Certificate,我必须 配置 Apache 以使用 SSL将这些与 SSL 相关的更改放入 Apache 服务器,我们都准备好了。

      【讨论】:

        【解决方案3】:

        你可以试试:

        1.将此添加到您的 Dockerfile 并再次构建映像

        RUN apt-get update && apt-get install -y libssl-dev
        RUN apt-get install -y libcurl4-gnutls-dev
        RUN apt-get install -y libcurl4-openssl-dev
        RUN apt-get install -y libcurl4
        

        2.通过浏览器下载证书,并复制到容器中 阅读Mount volume (-v, --read-only)

        3. 在不安全模式下使用 wget(不推荐) - 使用标志 --no-check-certificate

        【讨论】:

        • **1.**更新 Dockerfile 以再次构建映像:``` 以下软件包具有未满足的依赖关系:libcurl4-gnutls-dev:冲突:libcurl4-openssl-dev 但 7.64.0- 4要安装libcurl4-openssl-dev:冲突:libcurl4-gnutls-dev但要安装7.64.0-4 ``` **2.**通过我的Windows机器上的浏览器下载证书但无法通过文件放入容器中。有点迷失在那里。 **3.**使用 wget 下载证书文件?如果是这样,我也试过了,并给出了空文件。
        • @SandipT 使用 approad 2 并挂载卷,因此如果您将主机上的证书复制到您挂载的目录,它将在您用于挂载卷的 docker 映像目录下可见。
        • 哦……嗯,是的,我做到了……但是,在我下载并在容器中访问之后,我不确定将下载的 cert/pem 文件放在容器文件夹中的哪个位置供最终使用,以便系统始终使用它,并且“composer install”命令将无缝工作。你看,我不能总是传递证书文件的位置,因为 composer install 间接使用安全 url,并且由于无论我放入什么文件夹,系统都不会选择证书文件,结果证明这是一项徒劳的工作。我希望我的解释清楚。
        • 好的,关于调查结果的进一步更新...正如@Jimmix 建议的那样,在我的 Windows 主机上下载文件,复制到 C:>www 文件夹,该文件夹映射到容器中的 /var/www/html 文件夹.然后更新 php.ini,设置 curl.cainfo = /var/www/html/cacert.pem,重新启动 apache 并执行'curl https://thawte.com' - 仍然错误“curl:(60)SSL证书问题:无法获得本地颁发者证书”。甚至从命令行尝试了'curl https://thawte.com --cacert /var/www/html/cacert.pem',非常直接的cmd,仍然是“curl:(60)SSL证书问题:无法获取本地颁发者证书”错误。
        猜你喜欢
        • 2017-11-07
        • 1970-01-01
        • 2019-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-27
        • 2013-08-25
        • 1970-01-01
        相关资源
        最近更新 更多