【问题标题】:GIT with client certificates failing and working with curl客户端证书失败并使用 curl 的 GIT
【发布时间】:2019-12-19 18:19:14
【问题描述】:

我在使用 GIT 连接到受客户端证书保护的 GIT 服务器时遇到了问题。我正在尝试使用 Azure Pipeline Agent 在全新的 Azure VM 上运行作业。

我正在连接到通过客户端证书保护到 Internet 的本地 TFS 实例。

经过反复试验,我得到了正确的证书以将代理连接到服务器。像这样使用 OpenSSL

openssl pkcs12 -in cert.pfx -cacerts -nokeys -out ca.pem -passin pass:
openssl pkcs12 -in cert.pfx -clcerts -nokeys -out clientcert.pem -passin pass:
openssl pkcs12 -in cert.pfx -clcerts -nocerts -out clientcert-key-pass.pem -passin pass: -passout pass:$pfxpassword
openssl pkcs12 -in cert.pfx -out temp.pem -nodes -passin pass:
openssl pkcs12 -export -out cert-secure.pfx -in temp.pem -passout pass:$pfxpassword

这就是乐趣结束的地方......

作为背景,我在 Ubuntu 18.04 上运行并尝试了 GIT 2.17 和 2.22。

当我在具有相同证书集的机器上运行 curl 时,它正确地通过了服务器上的客户端证书安全性,并允许我访问返回 401 的底层服务,这是预期的。

但是,当使用来自 GIT 的相同证书时,我始终收到 403 错误,并且由于客户端证书问题,服务器拒绝连接。

我为 GIT 运行的命令是

GIT_CURL_VERBOSE=1 GIT_TRACE=1 git -c http.sslcainfo="/home/scott/ca.pem" -c http.sslcert="/home/scott/clientcert.pem" -c http.sslkey="/home/scott/clientcert-key-pass.pem" -c http.sslCertPasswordProtected=true fetch --force --tags --prune --progress --no-recurse-submodules origin

结果是(编辑的网址)

07:04:43.587108 git.c:439               trace: built-in: git fetch --force --tags --prune --progress --no-recurse-submodules origin
07:04:43.587518 run-command.c:663       trace: run_command: GIT_DIR=.git git-remote-https origin https://*****
Password for 'cert:////home/scott/clientcert.pem':
* Couldn't find host **** in the .netrc file; using defaults
*   Trying 3.248.79.34...
* TCP_NODELAY set
* Connected to **** (3.248.79.34) port 443 (#0)
* found 3 certificates in /home/scott/ca.crt
* found 402 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*        server certificate verification SKIPPED
*        server certificate status verification SKIPPED
*        common name: *** (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: **** - redacted
*        start date: Mon, 08 Apr 2019 00:00:00 GMT
*        expire date: Tue, 07 Apr 2020 12:00:00 GMT
*        issuer: C=US,O=DigiCert Inc,CN=DigiCert SHA2 Secure Server CA
*        compression: NULL
* ALPN, server accepted to use http/1.1
> GET /****/info/refs?service=git-upload-pack HTTP/1.1
Host: ****.com
User-Agent: git/2.22.0
Accept: */*
Accept-Encoding: deflate, gzip
Accept-Language: C, *;q=0.9
Pragma: no-cache

< HTTP/1.1 403 Forbidden
< Content-Type: text/html
< Server: Microsoft-IIS/10.0
< Date: Tue, 13 Aug 2019 07:04:47 GMT
< Content-Length: 1300
<
* Connection #0 to host ****.com left intact
fatal: unable to access 'https://*****': The requested URL returned error: 403

GIT 似乎出于某种原因跳过了客户端身份验证

等效的 curl 命令是

curl -v --http1.0 --cacert /home/scott/ca.pem --key /home/scott/clientcert-key-pass.pem --cert /home/scott/clientcert.pem https://****.com/tfs/****/refs?service=git-upload-pack

这会导致成功,并且可以通过网络服务器上的客户端身份验证并连接到底层服务

*   Trying 3.248.79.34...
* TCP_NODELAY set
* Connected to tfsemea1.ta.philips.com (3.248.79.34) port 443 (#0)
* ALPN, offering http/1.1
Enter PEM pass phrase:
* successfully set certificate verify locations:
*   CAfile: /home/scott/ca.pem
  CApath: /etc/ssl/certs
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: ******
*  start date: Apr  8 00:00:00 2019 GMT
*  expire date: Apr  7 12:00:00 2020 GMT
*  subjectAltName: host "***.com" matched cert's "***.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
*  SSL certificate verify ok.
> GET /***/info/refs?service=git-upload-pack HTTP/1.0
> Host: ***.com
> User-Agent: curl/7.58.0
> Accept: */*
>
* TLSv1.2 (IN), TLS handshake, Hello request (0):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
< HTTP/1.1 401 Unauthorized
< Content-Type: text/html; charset=utf-8
< Server: Microsoft-IIS/10.0
< P3P: CP="CAO DSP COR ADMa DEV CONo TELo CUR PSA PSD TAI IVDo OUR SAMi BUS DEM NAV STA UNI COM INT PHY ONL FIN PUR LOC CNT"
< WWW-Authenticate: Bearer
< WWW-Authenticate: Basic realm="https://***.com/tfs"
< WWW-Authenticate: Negotiate
< WWW-Authenticate: NTLM
< X-TFS-ProcessId: d2b304b0-a0ef-48b9-89b8-3281cb42c26d
< ActivityId: 07d4f17f-3940-4006-aab5-5c7afa57e84a
< X-TFS-Session: 07d4f17f-3940-4006-aab5-5c7afa57e84a
< X-VSS-E2EID: 07d4f17f-3940-4006-aab5-5c7afa57e84a
< X-FRAME-OPTIONS: SAMEORIGIN
< X-TFS-SoapException: %3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3Csoap%3AEnvelope%20xmlns%3Asoap%3D%22http%3A%2F%2Fwww.w3.org%2F2003%2F05%2Fsoap-envelope%22%3E%3Csoap%3ABody%3E%3Csoap%3AFault%3E%3Csoap%3ACode%3E%3Csoap%3AValue%3Esoap%3AReceiver%3C%2Fsoap%3AValue%3E%3Csoap%3ASubcode%3E%3Csoap%3AValue%3EUnauthorizedRequestException%3C%2Fsoap%3AValue%3E%3C%2Fsoap%3ASubcode%3E%3C%2Fsoap%3ACode%3E%3Csoap%3AReason%3E%3Csoap%3AText%20xml%3Alang%3D%22en%22%3ETF400813%3A%20Resource%20not%20available%20for%20anonymous%20access.%20Client%20authentication%20required.%3C%2Fsoap%3AText%3E%3C%2Fsoap%3AReason%3E%3C%2Fsoap%3AFault%3E%3C%2Fsoap%3ABody%3E%3C%2Fsoap%3AEnvelope%3E
< X-TFS-ServiceError: TF400813%3A%20Resource%20not%20available%20for%20anonymous%20access.%20Client%20authentication%20required.
< X-Powered-By: ASP.NET
< Lfs-Authenticate: NTLM
< X-Content-Type-Options: nosniff
< X-Powered-By: ARR/3.0
< Date: Tue, 13 Aug 2019 07:58:27 GMT
< Connection: close
< Content-Length: 20158

在@VonC 的建议下,我尝试使用以下命令不使用相同的密钥,不使用密码

GIT_CURL_VERBOSE=1 GIT_TRACE=1 git -c http.sslcainfo="/home/scott/ca.pem" -c http.sslcert="/home/scott/clientcert.pem" -c http.sslkey="/home/scott/nopass.pem" fetch --force --tags --prune --progress --no-recurse-submodules origin

我使用openssl rsa -in ~/clientcert-key-pass.pem -out ~/nopass.pem删除了密码

它产生了一个非常相似的输出

15:22:57.671901 git.c:440               trace: built-in: git fetch --force --tags --prune --progress --no-recurse-submodules origin
15:22:57.672253 run-command.c:663       trace: run_command: GIT_DIR=.git git-remote-https origin https://****
* Couldn't find host **** in the .netrc file; using defaults
*   Trying 52.18.21.126...
* TCP_NODELAY set
* Connected to **** (52.18.21.126) port 443 (#0)
* found 3 certificates in /home/scott/ca.pem
* found 402 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_256_GCM_SHA384
*        server certificate verification SKIPPED
*        server certificate status verification SKIPPED
*        common name: **** (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: ****
*        start date: Thu, 29 Aug 2019 00:00:00 GMT
*        expire date: Tue, 07 Apr 2020 12:00:00 GMT
*        issuer: C=US,O=DigiCert Inc,CN=DigiCert SHA2 Secure Server CA
*        compression: NULL
* ALPN, server accepted to use http/1.1
> GET /tfs/***/info/refs?service=git-upload-pack HTTP/1.1
Host: ****
User-Agent: git/2.23.0
Accept: */*
Accept-Encoding: deflate, gzip
Accept-Language: C, *;q=0.9
Pragma: no-cache

< HTTP/1.1 403 Forbidden
< Content-Type: text/html
< Server: Microsoft-IIS/10.0
< Date: Sun, 22 Sep 2019 13:22:56 GMT
< Content-Length: 1300
<
* Connection #0 to host **** left intact
fatal: unable to access 'https://****/': The requested URL returned error: 403

输出的唯一区别是提示输入密码

Password for 'cert:////home/scott/clientcert.pem':

运行 git config -l 从我正在使用的文件夹中生成以下有效配置

core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=https://****
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
gc.auto=0

我在这件事上纠结了一段时间,我开始认为某处有问题,GIT 没有启动客户端证书握手过程,你可以在 curl 中看到它只是没有呈现它,因此得到了403.

我错过了什么吗?

更新:

403 - 表示网络服务器由于客户端证书问题而拒绝请求 401 - 表示底层服务 (TFS) 由于身份验证问题而拒绝请求(这是一个单独的问题)

【问题讨论】:

  • http.sslBackend 设置为openssl 有什么改变吗?
  • 我已经试过了。 linux 的默认(也是唯一记录的选项)是 openssl。
  • 403 错误表明 git 服务器未授予您对该存储库的读取权限,或者 Web 服务器未授予对 git-http-backend CGI 程序的访问权限。

标签: git authentication https ssl-certificate azure-virtual-machine


【解决方案1】:

http.sslCertPasswordProtected:每次我必须使用证书时,我总是使用key from which I removed the password

为了测试,您应该尝试看看git fetch 命令是否会更好地使用密钥证书不需要需要密码。

【讨论】:

  • 我试过这个(只是再次尝试验证)并且没有骰子。如果对可用的密钥和证书的大小和类型有任何限制,有什么想法吗?看起来它正在连接到服务器,只是由于某种原因没有提供证书。
  • @ScottGuymer 你能用 git 设置和 curl 日志编辑问题,说明连接失败,使用没有密码的证书吗?
【解决方案2】:

我不确定你的 curl 是否比 git 工作得更好,因为你也会遇到错误:

HTTP/1.1 401 未经授权

请说明您认为 curl 成功的原因。

我看到的是,在这两种情况下(git 和 curl),服务器在 TLS 握手期间接受客户端,然后后端 Web 服务拒绝请求。 (如果 TLS 握手失败,那么您将永远看不到 &gt; GET ... 部分)

后端 Web 服务如何决定是否授予访问权限?是否使用客户端证书信息?

【讨论】:

  • 我会更新问题,但 403 - 表示 Web 服务器因客户端证书问题而拒绝请求 401 - 表示服务因身份验证问题而拒绝请求(这是一个单独的问题)
  • 我想我明白你现在在说什么了。客户端证书协商正在完成,但由于某种原因,Web 服务器拒绝了未经授权的证书。它与 curl 版本中的证书完全相同,所以我不确定为什么会发生这种情况。
  • 这作为评论会更好,这不是答案。
【解决方案3】:

阅读doc,我注意到以下配置参数:

http.sslTry

通过常规 FTP 协议连接时,尝试使用 AUTH SSL/TLS 和加密数据传输。如果 FTP 服务器出于安全原因需要它,或者您希望连接 只要远程 FTP 服务器支持它就安全。默认为假 因为它可能会触发证书验证错误 服务器配置错误。

我不太明白为什么它谈到 FTP(可能是错误的复制/粘贴?),因为配置参数与 http 相关......但也许你应该试试这个。

【讨论】:

    猜你喜欢
    • 2011-11-21
    • 1970-01-01
    • 2015-08-07
    • 2022-01-17
    • 2016-05-22
    • 2017-06-27
    • 2019-02-28
    • 2018-01-08
    • 1970-01-01
    相关资源
    最近更新 更多