通过 cURL 发送 Pushkit 通知 - curl: (60) SSL 证书问题:无法获得本地颁发者证书

问题描述

我使用 cURL 向 Apple 发送 pushkit 通知。我的 Rails 代码如下所示:

curl --http2 -v -d '#{payload.to_json}' --cert #{pem} #{pushkit_base_uri}/#{registration_id}

自 20201 年 1 月 19 日以来,在 Ubuntu 上运行此命令一直返回以下内容

...
...
...

* SSL certificate problem: unable to get local issuer certificate
* stopped the pause stream!
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl Failed to verify the legitimacy of the server and therefore Could not
establish a secure connection to it. To learn more about this situation and
how to fix it,please visit the web page mentioned above.

到目前为止,我已经尝试了以下解决方案:

  1. update-ca-certificates(文档 here
  2. 列出的解决方here

我还没有能够让它工作。感谢任何帮助,如果我找到解决方案,我会更新这篇文章

解决方法

滚动到 TLDR 结尾;

通过运行 awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | less,我们能够查看操作系统信任的所有权限列表。

...
...
...
subject=C = PL,O = Unizeto Technologies S.A.,OU = Certum Certification Authority,CN = Certum Trusted Network CA
subject=C = PL,CN = Certum Trusted Network CA 2
subject=C = EU,L = Madrid (see current address at www.camerfirma.com/address),serialNumber = A82743287,O = AC Camerfirma S.A.,CN = Chambers of Commerce Root - 2008
subject=C = GB,ST = Greater Manchester,L = Salford,O = Comodo CA Limited,CN = AAA Certificate Services
subject=O = "Cybertrust,Inc",CN = Cybertrust Global Root
subject=C = DE,O = D-Trust GmbH,CN = D-TRUST Root Class 3 CA 2 2009
subject=C = DE,CN = D-TRUST Root Class 3 CA 2 EV 2009
subject=O = Digital Signature Trust Co.,CN = DST Root CA X3
...
...
...

通过在 Firefox 中打开 api.push.apple.com,我们可以检查他们的证书。

Apple Certificate Details on Firefox

根据您的浏览器上次更新其 CA Store 的时间,该站点可能会或可能不会显示为安全。我们看到 Apple IST CA 2 - G1 证书是由 GeoTrust Global CA 颁发的。在我们的操作系统中搜索可信 CA 列表时,这两个词都没有返回结果。

为了解决这个问题,我们可以下载 Firefox 提供的 api-push-apple-com-chain.pem maid,然后在我们提出 cURL 请求时使用它:

curl --cacert '#{ca_cert}' --http2 -v -d ...

虽然这解决了我们的问题并且我们的请求成功了,但我们可以继续尝试了解这个问题开始出现的原因。查看 /etc/ca-certificates.conf,我们发现多个 GeoTrust CA 已被标记为不可信。 (注意行首的爆炸声)

...
...
 !mozilla/GeoTrust_Global_CA.crt
 !mozilla/GeoTrust_Primary_Certification_Authority.crt
 mozilla/GeoTrust_Primary_Certification_Authority_-_G2.crt
 !mozilla/GeoTrust_Primary_Certification_Authority_-_G3.crt
 !mozilla/GeoTrust_Universal_CA.crt
 !mozilla/GeoTrust_Universal_CA_2.crt
...
...

通过谷歌搜索,我们发现了这个 ticket 和这个 wiki

根据 2017 年通过的共识提案,Mozilla 开始不信任 2016 年 6 月 1 日之前在 Firefox 60 中发布的赛门铁克(包括 GeoTrust、RapidSSL 和 Thawte)证书,并计划不信任赛门铁克证书,无论从 Firefox 64 开始的发布日期,除非它们是由具有以下 SHA-256 主题公钥哈希 (subjectPublicKeyInfo) 的白名单从属 CA 发布的:

它还包括列入白名单的 Apple 证书列表:

c0554bde87a075ec13a61f275983ae023957294b454caf0a9724e3b21b7935bc
56e98deac006a729afa2ed79f9e419df69f451242596d2aaf284c74a855e352e
7289c06dedd16b71a7dcca66578572e2e109b11d70ad04c2601b6743bc66d07b
fae46000d8f7042558541e98acf351279589f83b6d3001c18442e4403d111849
b5cf82d47ef9823f9aa78f123186c52e8879ea84b0f822c91d83e04279b78fd5
e24f8e8c2185da2f5e88d4579e817c47bf6eafbc8505f0f960fd5a0df4473ad3
3174d9092f9531c06026ba489891016b436d5ec02623f9aafe2009ecc3e4d557

这使我们可以在 Firefox 上安全地打开 URL。 (由于某种原因不在 Firefox 开发者版本上)

TLDR:在 --cacert 命令中使用 attached file 作为 cURL