Curl

如何在 cURL 命令行中信任自簽名證書?

  • February 7, 2022

我使用Let’s Encrypt 推薦使用這個 Makefile為 foo.localhost 創建了一個自簽名證書:

include ../.env

configuration = csr.cnf
certificate = self-signed.crt
key = self-signed.key

.PHONY: all
all: $(certificate)

$(certificate): $(configuration)
   openssl req -x509 -out $@ -keyout $(key) -newkey rsa:2048 -nodes -sha256 -subj '/CN=$(HOSTNAME)' -extensions EXT -config $(configuration)

$(configuration):
   printf "[dn]\nCN=$(HOSTNAME)\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:$(HOSTNAME)\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth" > $@

.PHONY: clean
clean:
   $(RM) $(configuration)

然後,我將其分配給 Web 伺服器。我已驗證伺服器返回相關證書:

$ openssl s_client -showcerts -connect foo.localhost:8443 < /dev/null
CONNECTED(00000003)
depth=0 CN = foo.localhost
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = foo.localhost
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/CN=foo.localhost
  i:/CN=foo.localhost
-----BEGIN CERTIFICATE-----
[…]
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=foo.localhost
issuer=/CN=foo.localhost
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1330 bytes and written 269 bytes
Verification error: unable to verify the first certificate
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
   Protocol  : TLSv1.2
   Cipher    : ECDHE-RSA-AES128-GCM-SHA256
   Session-ID: […]
   Session-ID-ctx: 
   Master-Key: […]
   PSK identity: None
   PSK identity hint: None
   SRP username: None
   TLS session ticket:
   […]

   Start Time: 1529622990
   Timeout   : 7200 (sec)
   Verify return code: 21 (unable to verify the first certificate)
   Extended master secret: no
---
DONE

如何在不修改 /etc 中的任何內容的情況下讓 cURL 信任它? --cacert不起作用,大概是因為沒有CA

$ curl --cacert tls/foo.localhost.crt 'https://foo.localhost:8443/'
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.

目標是在開發過程中啟用 HTTPS:

  • 如果沒有在所有開發環境中啟用 DNS 驗證的大量工作,我就無法擁有完全類似於生產的證書。因此我必須使用自簽名證書。
  • 我顯然仍然想讓我的開發環境盡可能類似於生產環境,所以我不能簡單地忽略任何和所有證書問題。curl -k就像catch (Exception e) {}在這種情況下一樣 - 完全不像瀏覽器與 Web 伺服器通信。

換句話說,當我跑步時,curl [something] https://project.local/api/foo我想確信

  1. 如果 TLS 配置正確,除了具有自簽名證書,該命令將成功並且
  2. 如果我的 TLS 配置有任何問題,除了擁有自簽名證書,該命令將失敗。

使用 HTTP 或--insecure不符合第二個標準。

嘗試-k

curl -k https://yourhost/

它應該“接受”自簽名證書

遵循這些步驟應該可以解決您的問題:

  1. 下載並保存自簽名證書:echo quit | openssl s_client -showcerts -servername "${API_HOST}" -connect "${API_HOST}":443 > cacert.pem
  2. 告訴curl客戶:curl --cacert cacert.pem --location --silent https://${API_HOST}

也可以使用 wget 並忽略以下證書:wget --no-check-certificate https://${API_HOST}

引用自:https://unix.stackexchange.com/questions/451207