curl: (60) SSL证书问题:无法获取本地颁发者证书

486
root@sclrdev:/home/sclr/certs/FreshCerts# curl --ftp-ssl --verbose ftp://{abc}/ -u trup:trup --cacert /etc/ssl/certs/ca-certificates.crt
* About to connect() to {abc} port 21 (#0)
*   Trying {abc}...
* Connected to {abc} ({abc}) port 21 (#0)
< 220-Cerberus FTP Server - Home Edition
< 220-This is the UNLICENSED Home Edition and may be used for home, personal use only
< 220-Welcome to Cerberus FTP Server
< 220 Created by Cerberus, LLC
> AUTH SSL
< 234 Authentication method accepted
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* 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: http://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.

我曾经遇到过类似的问题。这个链接对我有用:https://dev59.com/NmAg5IYBdhLWcg3w9e_m#29649024 - Sagruob
2
在我的情况下,https://superuser.com/a/719047/137881 有所帮助。 - Abdull
请查看以下链接以获取解决方案:https://dev59.com/WV4b5IYBdhLWcg3wojFg#61177063 - pankaj
如果您是在组织机构而不是个人电脑上工作,可能会处于代理互联网连接中。如果任何可能的解决方案都不起作用,请请求静态IP。 - Deepak Thakur
显示剩余2条评论
37个回答

11

我也遇到了这个问题。我看了这个帖子,大多数回答对我来说都太复杂了。由于我在网络主题方面没有经验,所以这个答案是给像我这样的人的。

在我的情况下,出现这种错误是因为我在应用程序中使用的证书旁边没有包含中间和根证书。

以下是我从SSL证书供应商那里得到的内容:

- abc.crt
- abc.pem
- abc-bunde.crt

在`abc.crt`文件中,只有一个证书:
-----BEGIN CERTIFICATE-----
/*certificate content here*/
-----END CERTIFICATE-----

如果我以这种格式提供它,浏览器将不会显示任何错误(Firefox),但是当我进行curl请求时,我将收到curl:(60)SSL证书:无法获得本地颁发者证书的错误信息。

要解决此错误,请检查您的abc-bunde.crt文件。您很可能会看到如下内容:

-----BEGIN CERTIFICATE-----
/*additional certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*other certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*different certificate content here*/
-----END CERTIFICATE-----

这些是您的中间证书和根证书。错误发生是因为在您提供给应用程序的SSL证书中缺少它们。
要解决此错误,请按以下格式合并这两个文件的内容:
-----BEGIN CERTIFICATE-----
/*certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*additional certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*other certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*different certificate content here*/
-----END CERTIFICATE-----

请注意,在证书之间、文件开头或结尾处都不能有空格。将这个组合证书提供给你的应用程序后,你的问题就应该解决了。

这解决了我的问题。没想到在证书之间留空行是不好的。 - Beefster
阅读后,我使用“-certfile”选项重新生成了服务器的.pfx文件,而不是使用“-CAfile”选项。这解决了使用curl调用服务器API时出现的问题。例如:openssl pkcs12 -export -out a.pfx -inkey privateKey.pem -in uri.crt -certfile certs.ca-bundle - Sushil

9
根据cURL文档,您还可以将证书传递给curl命令:

获取可验证远程服务器的CA证书,并使用正确的选项指定此CA证书进行连接验证。 对于libcurl开发人员:curl_easy_setopt(curl, CURLOPT_CAPATH, capath);

对于curl命令行工具:--cacert [file]


例如:
curl --cacert mycertificate.cer -v https://www.stackoverflow.com

8
尝试在Ubuntu中重新安装curl,并使用sudo update-ca-certificates --fresh更新我的CA证书,以更新证书。

7
如果你只是想测试一下,那么在 curl 命令中加入 --insecure 参数以跳过验证。

工作得很好;谢谢 - Kalnode

6
我的方法是在cURL命令中添加“-k”选项。不需要让事情变得复杂。

curl -LOk https://dl.k8s.io/release/v1.20.0/bin/linux/amd64/kubectl


10
这只是跳过安全问题,不是真正的解决方案。 - Vladislav Rastrusny
这只是一个临时的解决方案,而不是一个解决方法... -k 或者 --ignore 的意思是不执行/检查安全性...所以这违背了使用证书和TLS的主要目的。 - Mr.P

4

是的,您还需要添加CA证书。以下是Node.js中用于清晰视图的代码片段。

var fs = require(fs)
var path = require('path')
var https = require('https')
var port = process.env.PORT || 8080;
var app = express();

https.createServer({
key: fs.readFileSync(path.join(__dirname, './path to your private key/privkey.pem')),
cert: fs.readFileSync(path.join(__dirname, './path to your certificate/cert.pem')),
ca: fs.readFileSync(path.join(__dirname, './path to your CA file/chain.pem'))}, app).listen(port)

4

您需要将服务器证书从 cert.pem 更改为 fullchain.pem
我在使用Perl HTTPS Daemon时也遇到了同样的问题:
我已经更改了:
SSL_cert_file => '/etc/letsencrypt/live/mydomain/cert.pem'
为:
SSL_cert_file => '/etc/letsencrypt/live/mydomain/fullchain.pem'


我在将现有证书移动到CyberPanel托管时遇到了这个问题,以下是我解决它的方法。 - Bigue Nique

3
在Windows上我遇到了这个问题。Curl是由mysysgit安装的,所以下载并安装最新版本解决了我的问题。
否则,您可以尝试这些不错的说明来更新您的CA证书。 instructions

3

输入这两个代码来禁用SSL证书问题。在我做了很多研究之后,它对我起作用了。

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

ssl certificate


我应该在哪里输入这些代码行?在哪个文件中?位置是什么? - asa
1
似乎重复了2015年这个(同样值得怀疑的)答案 https://dev59.com/KmAf5IYBdhLWcg3weyoe#29443322 - enharmonic

2

我的情况有所不同。我正在防火墙后面托管一个网站。这个错误是由pfSense引起的。

Network layout: |Web Server 10.x.x.x| <-> |pfSense 49.x.x.x| <-> |Open Internet|

我是偶然发现了原因,感谢这个答案


当我从WAN访问我的网站时,一切正常。

然而,当从内部LAN访问网站时(例如,当Wordpress向其自己的服务器发出curl请求时,尽管使用WAN IP 49.x.x.x),它会提供pfSense登录页面。

我确定证书为pfSense webConfigurator Self-Signed Certificate。难怪curl会抛出错误。

原因:发生的情况是curl正在使用网站的WAN IP地址49.x.x.x。但是,在Web服务器的上下文中,WAN IP是防火墙。

调试:我发现我得到了pfSense证书。

解决方案:在托管网站的服务器上,将其自己的域名指向127.0.0.1

通过应用该解决方案,curl的请求被Web服务器正确处理,而不是被转发到响应发送登录页面的防火墙。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接