【问题标题】:How to determine which Linux TLS certificate does allow me to access the given host?如何确定哪个 Linux TLS 证书允许我访问给定的主机?
【发布时间】:2021-01-04 07:27:30
【问题描述】:

我们在公司 MITM 代理后面有两台 Ubuntu Linux 机器,它重新加密 HTTPS 流量。为了通过这个代理,我们需要将自定义 TLS 证书添加到 Ubuntu 的/etc/ssl/cert/ca-certificates.crt 文件中。

现在,我们的一台机器设置正确,因此它可以访问主机 A。另一台机器无法访问,可能是因为缺少正确的证书。我们想知道哪些证书是“正确的”并将它们添加到另一台机器上。

成功会话的痕迹如下(部分名称和 IP 已更改):

$ curl  -L https://A.com -vvvv
*   Trying 10.123.89.26...
* TCP_NODELAY set
* Connected to <PROXY> port 3128 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to A.com:443
> CONNECT A.com:443 HTTP/1.1
> Host: A.com:443
> User-Agent: curl/7.58.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs                                                                                                                                                    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
* CONNECT phase completed!
* CONNECT phase completed!
* TLSv1.3 (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: C=CN; DC=appName gitlab; DC=caName sha256; ST=pkiNo 255088; O=EVILCORP; OU=IT; CN=A.com; emailAddress=admin@admin.com
*  start date: Jan 10 09:02:59 2019 GMT
*  expire date: Jan  9 09:02:59 2024 GMT
*  subjectAltName: host "A.com" matched cert's "A.com"
*  issuer: CN=HWIT Enterprise CA 1
*  SSL certificate verify ok.

现在,我们还应该收集什么信息才能说,例如,是证书 X 允许我们运行此会话?

X 指的是 ca-certificate.crt 中显示的证书:

-----BEGIN CERTIFICATE-----
MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE
AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw
...
...
-----END CERTIFICATE-----

【问题讨论】:

  • 我不明白您为什么不对第二台主机执行与第一台主机相同的操作。见https://docs.mitmproxy.org/stable/concepts-certificates/
  • @PresidentJamesK.Polk 实际上,我们的目标正是让第二台主机像我们的第一台主机一样工作。当然,如果我们可以控制 MITM 配置,那将是微不足道的。不幸的是,我们没有此类信息,只能使用黑盒式网关。
  • 另外让我澄清一下,我们是两台主机的用户,而不是管理员。这个问题是关于配置逆向工程的,我认为可以帮助人们更好地理解 TLS 在内部是如何工作的。
  • 我曾假设您正在与this 软件产品进行交互,但现在我不太确定。无论如何,下面的答案应该告诉您如何从主机 A 找到您需要的 CA 证书,以便您可以将其添加到主机 B 上的文件中。

标签: ubuntu ssl encryption proxy


【解决方案1】:

最简单的方法:肯定有一种完善的方法可以找到和下载 MITM 代理的 CA 证书,而且肯定有记录在某处。您不需要从另一台机器的系统池中寻找正确的 CA。

也就是说,如果您真的必须知道如何仅使用与随机网站的连接来找到正确的 CA 证书,请继续阅读。


这可以分两步完成:

  1. 在服务器返回的链中找到最顶层证书的颁发者的可分辨名称
  2. 查找其主题可分辨名称与刚刚找到的 CA 证书匹配的 CA 证书

查找发行人的专有名称

要查找发布者的名称,请向几乎所有主机发出请求。提供的服务器证书将是来自您的 MITM 代理的证书,而不是真正的证书,但过程完全相同。

让我们以www.google.com 为例:注意我是故意告诉openssl 不要使用系统 CA 池,实际上不信任任何东西。运行它时,不需要-no-CApath 参数。

$ openssl s_client -no-CApath  -connect www.google.com:443 
CONNECTED(00000003)
depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
   i:C = US, O = Google Trust Services, CN = GTS CA 1O1
 1 s:C = US, O = Google Trust Services, CN = GTS CA 1O1
   i:OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
---
etc.....

服务器返回两个证书:带有CN = www.google.com 的服务器证书和属于Google Trust Services 的颁发者(中间CA)。中间 CA 是由GlobalSign Root CA - R2 颁发的,这就是我们需要找到的证书。


查找匹配的 CA 证书: 我现在需要找到具有匹配专有名称的 CA 证书:OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign

要解码系统池中的证书,我可以再次使用openssl。让我们只检查一个证书(如果文件名对您没有帮助,您可能需要检查多个证书。一个小脚本应该可以解决问题):

$ openssl x509 -text -in /usr/share/ca-certificates/mozilla/GlobalSign_Root_CA_-_R2.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            04:00:00:00:00:01:0f:86:26:e6:0d
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
        Validity
            Not Before: Dec 15 08:00:00 2006 GMT
            Not After : Dec 15 08:00:00 2021 GMT
        Subject: OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
etc...

此证书具有主题专有名称:

OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign

这与颁发者的专有名称完全匹配。它可能是正确的证书(可能有多个同名证书,通常在证书更新时)。


注意事项:在您的示例中,返回单个证书(而不是服务器证书和一些中间 CA)。这同样适用:您需要找到具有主题名称的 CA 证书:CN=HWIT Enterprise CA 1(假设 curl 打印了整个名称)。

如前所述,可能有多个 CA 具有匹配的专有名称。最简单的方法是将它们全部添加到 CA 证书目录中。在某些情况下(并非总是如此,因为这不是必需的),证书也有一个 Authority Key Identifier,可以与可能的 CA 的 Subject Key Identifier 匹配。

【讨论】:

  • 您似乎在这里解决了另一个问题,或者我很困惑。 OP 似乎正在使用一个名为mitmproxy 的开源包。他需要安装的 CA 证书是他的 mitmproxy 实例的 mitmproxy 蛇油 CA。
  • 我认为这是正确的:他有一个来自他们的私有 CA 的证书来响应每个请求,并且需要从一台机器上找到私有 CA 证书以将其复制到另一台机器上,以便它可以被正确地 MITMed。他发出的任何请求都将是 MITM 并以 MITM 的证书作为响应。他可以从中提取颁发者 DN 并找到 CA 文件。我错过了什么吗?
  • 嗯,不,你的回答通常是正确的,但我认为他不明白如何找到 mitmproxy 的 CA 文件,该文件被隐藏在某个目录中代理。
  • 您说得有道理,有更快、更简单的方法可以从相关工具的标准位置获取 CA。我在我的答案前面加上了“正常解决方案”。剩下的留着,以防有人真的想知道。
  • @PresidentJamesK.Polk:使用 mitmproxy 作为“企业 MITM 代理”将是一个非常不理想的解决方案,OP 发布的 curl 输出确实表明情况并非如此。我很确定 OP 只是将标签误认为是通用术语,我已将其删除。
猜你喜欢
  • 1970-01-01
  • 2019-05-06
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 2017-09-15
  • 2018-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多