如何让Git接受自签名证书?

943

使用Git,有没有一种方法可以告诉它接受自签名证书?

我正在使用https服务器托管git服务器,但目前的证书是自签名的。

当我尝试第一次在那里创建仓库时:

git push origin master -f

我遇到了以下错误:

error: Cannot access URL     
https://the server/git.aspx/PocketReferences/, return code 22

fatal: git-http-push failed

在OSX/macintosh上,似乎git不会使用sslcainfo选项。如果您可以成功使用curl --cacert拉取存储库路径,但git无法工作,则应将证书添加到神秘的OSX Keychain程序中。更多信息请参见http://superuser.com/questions/605900/why-wont-os-x-trust-githubs-ssl-certificate。 - amwinter
我发现这份文档很有用 https://gist.github.com/evantoli/f8c23a37eb3558ab8765 - Mofaggol Hoshen
这是我发现的最好的解决方案之一:http://www.f15ijp.com/2012/08/git-ssl-certificate-problem-how-to-turn-off-ssl-validation-for-a-repo/ - vikas etagi
另一种解决方案是使用git协议(通过ssh)而不是https。 - Nathan Long
我曾经遇到过同样的问题 - 但是当我使用我的工作电脑上授权的工作电子邮件登录到另一个Github账户时 - 我就可以推送到远程Git而不会出现任何SSL相关的问题。 - Marina Kim
20个回答

1711

永久接受特定证书

尝试使用http.sslCAPathhttp.sslCAInfo。请参考Adam Spiers的回答,其中有一些非常好的示例。这是该问题最安全的解决方案。

禁用单个git命令的TLS/SSL验证

尝试向git传递-c与正确的配置变量,或者使用Flow的回答

git -c http.sslVerify=false clone https://example.com/path/to/git

禁用所有存储库的SSL验证

可以全局停用SSL验证。 这极不推荐,但为了完整性而提及:

git config --global http.sslVerify false # Do NOT do this!

git中有相当多的 SSL 配置选项。从 git config 的说明页中得知:

http.sslVerify
    Whether to verify the SSL certificate when fetching or pushing over HTTPS.
    Can be overridden by the GIT_SSL_NO_VERIFY environment variable.

http.sslCAInfo
    File containing the certificates to verify the peer with when fetching or pushing
    over HTTPS. Can be overridden by the GIT_SSL_CAINFO environment variable.

http.sslCAPath
    Path containing files with the CA certificates to verify the peer with when
    fetching or pushing over HTTPS.
    Can be overridden by the GIT_SSL_CAPATH environment variable.

还有其他几个有用的 SSL 配置选项:

http.sslCert
    File containing the SSL certificate when fetching or pushing over HTTPS.
    Can be overridden by the GIT_SSL_CERT environment variable.

http.sslKey
    File containing the SSL private key when fetching or pushing over HTTPS.
    Can be overridden by the GIT_SSL_KEY environment variable.

http.sslCertPasswordProtected
    Enable git's password prompt for the SSL certificate. Otherwise OpenSSL will
    prompt the user, possibly many times, if the certificate or private key is encrypted.
    Can be overridden by the GIT_SSL_CERT_PASSWORD_PROTECTED environment variable.

223
您永远不应该全局禁用TLS(/SSL)证书验证。 - Flow
7
@Flow--我完全同意。我已经编辑了这个(现在相当古老的)答案,让它更加激进,反对禁用TLS/SSL证书验证。 - Christopher
9
如果我们处于雇主是中间人攻击者的工作环境中,有什么替代方案可以全局禁用TLS/SSL? - Stevoisiak
3
正如Steven Vascellaro所指出的那样:如果离开公司网络的唯一方法是通过公司代理,那么必须处理的证书就是公司的证书,并且代理需要负责防范中间人攻击。在这种情况下,“git config --global http.sslVerify false”不会造成安全问题。 - TNT
7
对于受影响的Git项目,为什么不使用 git config --local http.sslVerify false 呢? - Datz
显示剩余5条评论

192
您可以将GIT_SSL_NO_VERIFY设置为true:
GIT_SSL_NO_VERIFY=true git clone https://example.com/path/to/git

或者在命令行中配置 Git 不要验证连接:

git -c http.sslVerify=false clone https://example.com/path/to/git

请注意,如果您不验证SSL / TLS证书,则容易受到中间人攻击的影响。

1
@SkylarSaveland 请注意:git -c http.sslVerify=false <gitSubCommand>也可以通过中间人的方式工作。 - Flow
这个命令是将 git config http.sslVerify false,对我很有效。谢谢。 - Fernando Nogueira
3
答案仅描述了最不安全的选项。 - cp.engr
"-c" 的意思是什么? - Sergio Durán Vega
第一个对我有用,开启了Git LFS。第二个没有。我怀疑某些分叉的进程仍然会正确地获取环境变量。 - Randy

190

我不是特别喜欢现有答案的[编辑:原始版本],因为禁用安全检查应该是最后的手段,而不是首选解决方案。虽然你不能在第一次接收自签名证书时信任它而不进行其他验证方法,但至少在随后的 git 操作中使用证书可以使攻击者在下载证书之后发生的攻击变得更加困难。换句话说,如果你下载的证书是真实的,那么你从那时起就是安全的。相比之下,如果你只是禁用验证,那么你就会在任何时候都面临各种中间人攻击。

给出一个具体的例子:著名的repo.or.cz代码库提供自签名证书。我可以下载该文件,将其放置在像/etc/ssl/certs这样的地方,然后执行:

# Initial clone
GIT_SSL_CAINFO=/etc/ssl/certs/rorcz_root_cert.pem \
    git clone https://repo.or.cz/org-mode.git

# Ensure all future interactions with origin remote also work
cd org-mode
git config http.sslCAInfo /etc/ssl/certs/rorcz_root_cert.pem
注意,这里使用本地git config(即没有--global)意味着这个自签名证书仅在此特定存储库中受信任,这很好。这比使用GIT_SSL_CAPATH更好,因为它消除了通过不同的证书颁发机构验证可能会被攻击的风险。

4
巧合的是,http.sslCAPath 使用了 libcurl 的 ssl_capath 逻辑。我认为您实际上可以在 /etc/ssl/certs/ 目录中存储任意数量的证书,并且它会有效地整理出所需的所有内容。请注意,我没有测试过,但它可能允许您使用 --global 来使用大量的证书。值得测试一下。 - Christopher
13
考虑到禁用 SSL 验证的风险,以及问题是“如何使 git 接受自签名证书?”,这个答案应该被接受。 - PLNech
6
在理想的世界中,会有类似于“git config http.validCertFingerprint <base64编码的证书哈希值>”这样的东西。 - Flow
7
从一个新的克隆副本开始,可以使用以下一行命令完成:git clone --config http.sslCAInfo=<证书路径> https://repo.or.cz/org-mode.git(无需在后面调用“git config”命令)。 - Aaron
1
我怎么在Windows中获取证书路径? - Fakhar Ahmad Rasul
显示剩余7条评论

65

Git自签名证书配置

tl;dr

永远不要禁用所有SSL验证!

这会造成糟糕的安全文化。不要成为那个人。

你需要的配置键是:

这些是用于配置您信任的主机证书

这些是用于配置您的证书以响应SSL挑战。

有选择地将上述设置应用于特定主机。

全局.gitconfig用于自签名证书颁发机构

为了我和我的同事,请允许我们在不禁用sslVerify的情况下使自签名证书工作。通过编辑您的.gitconfig,使用git config --global -e添加以下内容:

# Specify the scheme and host as a 'context' that only these settings apply
# Must use Git v1.8.5+ for these contexts to work
[credential "https://your.domain.com"]
  username = user.name

  # Uncomment the credential helper that applies to your platform
  # Windows
  # helper = manager

  # OSX
  # helper = osxkeychain

  # Linux (in-memory credential helper)
  # helper = cache

  # Linux (permanent storage credential helper)
  # https://askubuntu.com/a/776335/491772

# Specify the scheme and host as a 'context' that only these settings apply 
# Must use Git v1.8.5+ for these contexts to work
[http "https://your.domain.com"]
  ##################################
  # Self Signed Server Certificate #
  ##################################

  # MUST be PEM format
  # Some situations require both the CAPath AND CAInfo 
  sslCAInfo = /path/to/selfCA/self-signed-certificate.crt
  sslCAPath = /path/to/selfCA/
  sslVerify = true

  ###########################################
  # Private Key and Certificate information #
  ###########################################

  # Must be PEM format and include BEGIN CERTIFICATE / END CERTIFICATE, 
  # not just the BEGIN PRIVATE KEY / END PRIVATE KEY for Git to recognise it.
  sslCert = /path/to/privatekey/myprivatecert.pem

  # Even if your PEM file is password protected, set this to false.
  # Setting this to true always asks for a password even if you don't have one.
  # When you do have a password, even with this set to false it will prompt anyhow. 
  sslCertPasswordProtected = 0

参考文献:

git clone时指定配置

如果您需要对每个仓库应用它,文档告诉您只需在您的仓库目录中运行git config --local。但是,当您还没有将仓库本地克隆时,这并不有用。

您可以通过设置全局配置,然后将这些设置复制到本地仓库配置中来进行全局 -> 本地的操作...

或者,您可以在git clone时指定配置命令,这些命令会在目标仓库克隆后应用。

# Declare variables to make clone command less verbose     
OUR_CA_PATH=/path/to/selfCA/
OUR_CA_FILE=$OUR_CA_PATH/self-signed-certificate.crt
MY_PEM_FILE=/path/to/privatekey/myprivatecert.pem
SELF_SIGN_CONFIG="-c http.sslCAPath=$OUR_CA_PATH -c http.sslCAInfo=$OUR_CA_FILE -c http.sslVerify=1 -c http.sslCert=$MY_PEM_FILE -c http.sslCertPasswordProtected=0"

# With this environment variable defined it makes subsequent clones easier if you need to pull down multiple repos.
git clone $SELF_SIGN_CONFIG https://mygit.server.com/projects/myproject.git myproject/

一句话简述

编辑:请参见VonC答案,该答案指出了关于绝对路径和相对路径在特定Git版本2.14.x / 2.15到这个一行命令中的一个警告。

git clone -c http.sslCAPath="/path/to/selfCA" -c http.sslCAInfo="/path/to/selfCA/self-signed-certificate.crt" -c http.sslVerify=1 -c http.sslCert="/path/to/privatekey/myprivatecert.pem" -c http.sslCertPasswordProtected=0 https://mygit.server.com/projects/myproject.git myproject/

CentOS 无法加载客户端密钥

如果您正在尝试在CentOS上执行此操作,并且您的.pem文件出现问题,

unable to load client key: "-8178 (SEC_ERROR_BAD_KEY)"

您可能需要查看这个StackOverflow答案,了解curl如何使用NSS而不是Open SSL。

并且,您可能需要从源代码重新构建curl

git clone http://github.com/curl/curl.git curl/
cd curl/
# Need these for ./buildconf
yum install autoconf automake libtool m4 nroff perl -y
#Need these for ./configure
yum install openssl-devel openldap-devel libssh2-devel -y

./buildconf
su # Switch to super user to install into /usr/bin/curl
./configure --with-openssl --with-ldap --with-libssh2 --prefix=/usr/
make
make install

由于libcurl仍然作为共享库存在内存中,因此请重新启动计算机

Python、pip和conda

相关问题:如何在Windows中将自定义CA根证书添加到pip使用的CA Store中?


在 Git 接受它之前,我必须确保自签名服务器证书是 PEM 格式的。此外,上面的一些答案表明,只需要使用 http.sslCAPath 提供证书文件夹的路径即可。但在我的情况下,我必须使用 http.sslCAInfo 来指定特定的文件。这样做可以让 Git 连接到我们的私有 GitHub,而不必禁用 SSL 验证。 - Zarepheth
@Zarepheth 感谢您提供的信息。我遇到了同样需要CAPath和CAInfo的问题。由于我们的CA证书是PEM格式,所以我忽略了记录它。我已经更新了答案并添加了这些内容。很高兴您能够安全连接。 - Josh Peak
如果你被迫使用HTTPS进行克隆,而无法使用SSH绕过证书问题,那么这可能是最好的长期“修复”答案。 - dragon788
1
我正要添加这个答案!很高兴有人已经发现了它。 - Franklin Yu

34
这个答案摘自Michael Kauffman所写的这篇文章
使用带有企业SSL证书的Git for Windows
问题:
如果你有一个企业SSL证书,并且想要从控制台或VSCode克隆你的仓库,你会遇到以下错误:
fatal: unable to access ‘https://myserver/tfs/DefaultCollection/_git/Proj/’: SSL certificate problem: unable to get local issuer certificate 解决方案:
1. 将根自签名证书导出到文件中。你可以在浏览器内完成此操作。 2. 在你的git文件夹中找到“ca-bundle.crt”文件(当前版本为C:\Program Files\Git\usr\ssl\certs,但过去可能已更改)。将该文件复制到你的用户配置文件中。用类似VSCode的文本编辑器打开它,并将导出证书的内容添加到文件末尾。
现在我们需要配置git使用新文件。

git config --global http.sslCAInfo C:/Users/<yourname>/ca-bundle.crt

这将在您的用户配置文件根目录的.gitconfig文件中添加以下条目。

[http] sslCAInfo = C:/Users/<yourname>/ca-bundle.crt


1
谢谢,我发现这个答案对于Windows来说更简单和更安全。 - Stefano
1
如何从浏览器导出证书到文件:https://medium.com/@menakajain/export-download-ssl-certificate-from-server-site-url-bcfc41ea46a2 - Quad Coders
有两个 ca-bundle.crt 文件:C:\Program Files\Git\usr\ssl\certs\ca-bundle.crtC:\Program Files\Git\mingw64\ssl\certs\ca-bundle.crt,将证书添加到第一个文件无效 - 添加到第二个文件有效。 - Tom Charles Zhang
1
谢谢,谢谢 - 这个问题困扰了我一段时间! - Chris McAllister
1
谢谢,谢谢 - 这个问题困扰了我一段时间! - undefined
显示剩余3条评论

28

将http.sslVerify设置为false不是一个好的做法。相反,我们可以使用SSL证书。

因此,构建代理将使用带有SSL证书和PAT用于身份验证的https。进入图片描述

进入图片描述

进入图片描述

复制包括-begin和-end--在内的cer文件的内容。

在构建代理的git bash中 => git config –global http.sslcainfo “C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt” 转到此文件并附加.cer内容。

因此,构建代理可以访问SSL证书。


需要进行系统重启吗?我已经添加了,但在Git Bash中仍显示与OP中给出的相同错误。 - rinilnath
请尝试重新启动构建代理程序。 - Palash Roy

16

很好,虽然如果有使用本地配置选项会更好。 - Adam Spiers
5
您可以随时fork它并去掉--global选项;-) - Craig
这很不错,它可以批量处理吗? - Halter

6
在Windows上使用64位版本的Git,只需将自签名CA证书添加到以下文件中:
  • C:\Program Files\Git\mingw64\ssl\certs\ca-bundle.crt
  • C:\Program Files\Git\mingw64\ssl\certs\ca-bundle.trust.crt
如果只是服务器自签名证书,请将其添加到以下文件中:
  • C:\Program Files\Git\mingw64\ssl\cert.pem

1
这是处理我们公司重新签署所有HTTPS流量的防火墙的最佳方法。我只需将防火墙证书的PEM格式crt文件作为文本复制并粘贴到ca-bundle中,它就像魔法般地运行。 - Mitten.O
按照这个做了,但还是出现同样的错误。 - rinilnath

5
在Windows上,我是这样做的:
将自签名证书的内容添加到 ca-bundle 文件末尾,包括-----BEGIN CERTIFICATE----------END CERTIFICATE----- 两行。 ca-bundle 文件通常位于 C:\Program Files\Git\mingw64\ssl\certs 路径下。
然后,将 ca-bundle 文件的路径添加到全局 git 配置中。使用以下命令:git config --global http.sslCAInfo "C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt" 注意:文件路径取决于你本地的 ca-bundle 文件路径!

5
检查您的杀毒软件和防火墙设置。
有一天,git突然不能使用了。通过上面所描述的,我发现卡巴斯基在中间放了一个自签名的个人根证书。我没有成功地按照上面的说明让Git接受该证书。我放弃了。对我有效的方法是禁用扫描加密连接功能。
  1. 打开卡巴斯基
  2. 设置 > 额外 > 网络 > 不扫描加密连接
这样做后,git再次启动,并启用sslVerify功能。
注意。这对我仍然不够满意,因为我想保持我的杀毒软件处于活动状态。在高级设置中,卡巴斯基显示了一份将无法使用该功能的网站列表。Github没有列入其中。我将在卡巴斯基论坛进行核实。似乎有一些主题,例如https://forum.kaspersky.com/index.php?/topic/395220-kis-interfering-with-git/&tab=comments#comment-2801211

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