SSL 适用于浏览器、wget 和 curl,但适用于 git

Posted

技术标签:

【中文标题】SSL 适用于浏览器、wget 和 curl,但适用于 git【英文标题】:SSL works with browser, wget, and curl, but fails with git 【发布时间】:2011-12-10 11:52:45 【问题描述】:

我有一个网站用来托管 redmine 和几个 git 存储库

这对http非常有效,但我不能用https克隆,即

git clone http://mysite.com/git/test.git

工作正常,但是

git clone https://mysite.com/git/test.git

失败

奇怪的是,https 似乎适用于我测试过的所有其他内容。如果我打开

https://mysite.com/git/test.git

在浏览器中(在 chrome 和 firefox 中测试),我没有收到任何错误或警告。我也可以

curl https://mysite.com/git/test.git
wget https://mysite.com/git/test.git

两者都可以正常工作,没有任何投诉或警告。

这是 git 的详细输出:

$ GIT_CURL_VERBOSE=1 git clone https://user@mysite.com/test/test.git
Cloning into test...
Password:
* Couldn't find host mysite.com in the .netrc file; using defaults
* About to connect() to mysite.com port 443 (#0)
*   Trying 127.0.0.1... * Connected to mysite.com (127.0.0.1) port 443 (#0)
* found 157 certificates in /etc/ssl/certs/ca-certificates.crt
* server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
* Closing connection #0
* Couldn't find host mysite.com in the .netrc file; using defaults
* About to connect() to mysite.com port 443 (#0)
*   Trying 127.0.0.1... * Connected to mysite.com (127.0.0.1) port 443 (#0)
* found 157 certificates in /etc/ssl/certs/ca-certificates.crt
* server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
* Closing connection #0
error: server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none while accessing https://user\
@mysite.com/test/test.git/info/refs

fatal: HTTP request failed

这是 curl 的详细输出,个人信息已更改:

* About to connect() to mysite.com port 443 (#0)
*   Trying 127.0.0.1... connected
* Connected to mysite.com (127.0.0.1) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*        subject: C=US; <... cut my certs info ...>
*        start date: 2011-10-18 00:00:00 GMT
*        expire date: 2013-10-17 23:59:59 GMT
*        subjectAltName: mysite.com matched
*        issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO High-Assurance Secure Server CA
*        SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.21.6 (x86_64-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3
> Host: mysite.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 18 Oct 2011 21:39:54 GMT
< Server: Apache/2.2.14 (Ubuntu)
< Last-Modified: Fri, 14 Oct 2011 03:20:01 GMT
< ETag: "8209c-87-4af39bb89ccac"
< Accept-Ranges: bytes
< Content-Length: 135
< Vary: Accept-Encoding
< Content-Type: text/html
< X-Pad: avoid browser bug
<
<p>Welcome to the mysite.com<p/>
* Connection #0 to host mysite.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):

我能看到的唯一区别是 git 似乎在使用显式 CAfile 而 curl 使用整个目录?我是 ssl 的新手(至少在管理员方面),所以我不确定这意味着什么或如何配置 git 以与 curl 相同的方式工作。

我在 Ubuntu 10.04 上使用 git 1.7.5.4 和 apache 2.2.14。我尝试从 3 个不同的 linux 主机(包括服务器本身的另一个帐户)进行克隆,但没有任何效果。

我还使用 openssl 工具在服务器上验证了我的证书:

$openssl verify -purpose sslserver -CAfile chain.crt signed.pem 
signed.pem: OK

这可能与错误 https://bugs.maemo.org/show_bug.cgi?id=4953 有关,但似乎有所不同,因为我在任何其他程序中都没有收到任何警告或错误。

值得一提的是,我正在使用 gitolite 和 redmine_git_hosting 使用智能 http 通过 https 进行身份验证。不过,我不认为这有任何问题,因为即使我只是在 /var/www 中粘贴了一个可以正常工作的裸仓库并直接访问它,问题仍然存在。此外,git over ssh(有和没有 gitolite)也可以工作。

如果您知道可能出了什么问题,或者您想了解更多信息,请告诉我。我真的更希望让 ssl 正常工作,而不是强迫所有人禁用 git 中的证书检查,尽管这是当前的解决方法。

感谢您阅读这篇长文!

【问题讨论】:

请注意,使用 Git 2.5+,您将能够指定一个密码列表供 curl 使用。那会有所帮助。见***.com/a/30442395/6309 【参考方案1】:

导出 GIT_SSL_NO_VERIFY=1

来自http://blog.breadncup.com/2011/06/09/skip-git-ssl-verification/

警告:正如某些人所提到的,这会禁用验证,让您面临各种安全问题。您不应该长期依赖它,但在紧要关头,它会完成工作。

【讨论】:

这就像解锁门的问题通过让门一直解锁来解决。存在一些相关的安全风险。 这对我不起作用@debian wheezy,git 1.7.10.4,仍然 gnutls_handshake() 失败:(。 请不要这样做。如果没有验证,您基本上是在要求 git 在您的系统上放置恶意软件。 请添加警告......这很容易做到,但对某些用户来说可能是个坏主意 这在服务器没有正确设置但用户无法控制的情况下在专用网络上操作时非常有用。作为一个只持续与您的 TTY 会话一样长的变量,它比更改全局 git 配置值要好得多。点赞。【参考方案2】:

问题可能是你没有正确配置Apache

您可能需要将您的服务器名称添加到 Apache 配置文件中 /etc/apache2/sites-enabled/default-ssl.conf,例如:

ServerName demo.personalserver.com

发件人:https://www.progclub.org/blog/2014/09/03/gnutls_handshake-failed-using-git/#comment-96924

【讨论】:

【参考方案3】:

我的一个 Comodo PositiveSSL 证书遇到了这个错误,并且能够通过更改中间证书的顺序来修复它。

订购证书后,我获得了以下文件:

根 CA 证书 - AddTrustExternalCARoot.crt 中间 CA 证书 - COMODORSAAddTrustCA.crt 中间 CA 证书 - COMODORSADomainValidationSecureServerCA.crt PositiveSSL 通配符证书 - STAR_mydomain_com.crt

原来我提供给nginx.crt中的证书顺序如下:

PositiveSSL 通配符证书 - STAR_mydomain_com.crt 中间 CA 证书 - COMODORSAAddTrustCA.crt 中间 CA 证书 - COMODORSADomainValidationSecureServerCA.crt

但是,我将最后两个证书的顺序颠倒了,Git 不再抛出验证错误。

【讨论】:

【参考方案4】:

事实证明这是一个 gnuTLS 问题。 gnuTLS 是顺序敏感的,而 openssl 不是。我重新订购了中间证书文件中的证书,问题就消失了

【讨论】:

你说的是哪个中间证书文件?服务器端 apache 证书链还是客户端文件?如果是第二个,是哪一个? 它是服务器端的中间证书文件 我知道这是一个老问题,但我得到了类似的答案。您能否提供有关如何执行此操作的更多详细信息? 这是很久以前的事了,所以我的记忆很生疏。我依稀记得有人给了我一个证书文件放在我的服务器上。这是由*** SSL 授权签署的,并在我托管的服务器上提供了 ssl。解决方案是转到该文件(它位于某个地方的 apache 配置中)并查看它。它有两个证书,我只是重新订购它们,然后它开始工作(重新启动 apache 后)【参考方案5】:

git 使用 gnutls 来处理这些东西,这需要指定 CA。这可以通过每个存储库来完成:

git config http.sslcapath <path to CA directory>

git config http.sslcainfo <path to CA cert>

您也可以指定 --system 或 --global。

【讨论】:

【参考方案6】:

XCondE 的回答将解决这个问题,但关闭安全警告总是感觉不好。如果您在 ubuntu 机器上运行,那么问题可能是您的 Web 服务器的 CA 证书不在 /etc/ssl/certs/ca-certificates.crt 文件中。我在使用由 www.incommon.org 签名的 SSL 证书的 Web 服务器上托管的 git 服务器遇到了这个问题。

您可以将中间证书添加到您的 ca-certificates 文件中,如下所示:

wget http://cert.incommon.org/InCommonServerCA.crt
openssl x509 -inform DER -in InCommonServerCA.crt -out incommon.pem
cat /etc/ssl/certs/ca-certificates.crt incommon.pem > ca-certs2.crt
sudo cp /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt.bak
sudo cp ca-certs2.crt /etc/ssl/certs/ca-certificates.crt

这里对幕后发生的事情进行了很好的讨论: http://curl.haxx.se/docs/sslcerts.html

【讨论】:

以上是关于SSL 适用于浏览器、wget 和 curl,但适用于 git的主要内容,如果未能解决你的问题,请参考以下文章

GET 请求在浏览器中工作,但在 curl 中给出错误 SSL_ERROR_SYSCALL

linux 测试 get 请求 跳过SSL证书验证

windows curl工具怎么用

httpd-2.4.18 mod_http2 适用于 curl 和 nghttp 但不适用于浏览器

JBoss WildFly 13 上的 RESTful Web 服务适用于浏览器和 curl,但不适用于单元测试 - 404 错误

客户端凭据流适用于 curl 但不适用于浏览器