如何使用 cURL 调试 SSL 握手?

我想用客户端证书对每个目录身份验证进行故障排除。我特别想知道服务器发送哪些可接受的客户端证书。

如何调试 SSL 握手,最好使用 cURL?

184782 次浏览

curl probably does have some options for showing more information but for things like this I always use openssl s_client

With the -debug option this gives lots of useful information

Maybe I should add that this also works with non HTTP connections. So if you are doing "https", try the curl commands suggested below. If you aren't or want a second option openssl s_client might be good

I have used this command to troubleshoot client certificate negotiation:

openssl s_client -connect www.test.com:443 -prexit

The output will probably contain "Acceptable client certificate CA names" and a list of CA certificates from the server, or possibly "No client certificate CA names sent", if the server doesn't always require client certificates.

curl -iv https://your.domain.io

That will give you cert and header output if you do not wish to use openssl command.

  1. For TLS handshake troubleshooting please use openssl s_client instead of curl.
  2. -msg does the trick!
  3. -debug helps to see what actually travels over the socket.
  4. -status OCSP stapling should be standard nowadays.
openssl s_client -connect example.com:443 -tls1_2 -status -msg -debug -CAfile <path to trusted root ca pem> -key <path to client private key pem> -cert <path to client cert pem>

Other useful switches -tlsextdebug -prexit -state

https://www.openssl.org/docs/man1.0.2/man1/s_client.html

Actually openssl command is a better tool than curl for checking and debugging SSL. Here is an example with openssl:

openssl s_client -showcerts -connect stackoverflow.com:443 < /dev/null

and < /dev/null is for adding EOL to the STDIN otherwise it hangs on the Terminal.


But if you liked, you can wrap some useful openssl commands with curl (as I did with curly) and make it more human readable like so:

# check if SSL is valid
>>> curly --ssl valid -d stackoverflow.com
Verify return code: 0 (ok)
issuer=C = US
O = Let's Encrypt
CN = R3
subject=CN = *.stackexchange.com


option: ssl
action: valid
status: OK

# check how many days it will be valid
>>> curly --ssl date -d stackoverflow.com
Verify return code: 0 (ok)
from: Tue Feb  9 16:13:16 UTC 2021
till: Mon May 10 16:13:16 UTC 2021
days total:  89
days passed: 8
days left:   81


option: ssl
action: date
status: OK

# check which names it supports
curly --ssl name -d stackoverflow.com
*.askubuntu.com
*.blogoverflow.com
*.mathoverflow.net
*.meta.stackexchange.com
*.meta.stackoverflow.com
*.serverfault.com
*.sstatic.net
*.stackexchange.com
*.stackoverflow.com
*.stackoverflow.email
*.superuser.com
askubuntu.com
blogoverflow.com
mathoverflow.net
openid.stackauth.com
serverfault.com
sstatic.net
stackapps.com
stackauth.com
stackexchange.com
stackoverflow.blog
stackoverflow.com
stackoverflow.email
stacksnippets.net
superuser.com


option: ssl
action: name
status: OK

# check the CERT of the SSL
>>> curly --ssl cert -d stackoverflow.com
-----BEGIN CERTIFICATE-----
MIIG9DCCBdygAwIBAgISBOh5mcfyJFrMPr3vuAuikAYwMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMTAyMDkxNjEzMTZaFw0yMTA1MTAxNjEzMTZaMB4xHDAaBgNVBAMM
Eyouc3RhY2tleGNoYW5nZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDRDObYpjCvb2smnCP+UUpkKdSr6nVsIN8vkI6YlJfC4xC72bY2v38lE2xB
LCaL9MzKhsINrQZRIUivnEHuDOZyJ3Xwmxq3wY0qUKo2c963U7ZJpsIFsj37L1Ac
Qp4pubyyKPxTeFAzKbpfwhNml633Ao78Cy/l/sYjNFhMPoBN4LYBX7/WJNIfc3UZ
niMfh230NE2dwoXGqA0MnkPQyFKlIwHcmMb+ZI5T8TziYq0WQiYUY3ssOEu1CI5n
wh0+BTAwpx7XBUe5Z+B9SrFp8BUDYWcWuVEIh2btYvo763mrr+lmm8PP23XKkE4f
287Iwlfg/IqxxIxKv9smFoPkyZcFAgMBAAGjggQWMIIEEjAOBgNVHQ8BAf8EBAMC
BaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAw
HQYDVR0OBBYEFMnjX41T+J1bbLgG9TjR/4CvHLv/MB8GA1UdIwQYMBaAFBQusxe3
WFbLrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0
cDovL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRwOi8vcjMuaS5sZW5j
ci5vcmcvMIIB5AYDVR0RBIIB2zCCAdeCDyouYXNrdWJ1bnR1LmNvbYISKi5ibG9n
b3ZlcmZsb3cuY29tghIqLm1hdGhvdmVyZmxvdy5uZXSCGCoubWV0YS5zdGFja2V4
Y2hhbmdlLmNvbYIYKi5tZXRhLnN0YWNrb3ZlcmZsb3cuY29tghEqLnNlcnZlcmZh
dWx0LmNvbYINKi5zc3RhdGljLm5ldIITKi5zdGFja2V4Y2hhbmdlLmNvbYITKi5z
dGFja292ZXJmbG93LmNvbYIVKi5zdGFja292ZXJmbG93LmVtYWlsgg8qLnN1cGVy
dXNlci5jb22CDWFza3VidW50dS5jb22CEGJsb2dvdmVyZmxvdy5jb22CEG1hdGhv
dmVyZmxvdy5uZXSCFG9wZW5pZC5zdGFja2F1dGguY29tgg9zZXJ2ZXJmYXVsdC5j
b22CC3NzdGF0aWMubmV0gg1zdGFja2FwcHMuY29tgg1zdGFja2F1dGguY29tghFz
dGFja2V4Y2hhbmdlLmNvbYISc3RhY2tvdmVyZmxvdy5ibG9nghFzdGFja292ZXJm
bG93LmNvbYITc3RhY2tvdmVyZmxvdy5lbWFpbIIRc3RhY2tzbmlwcGV0cy5uZXSC
DXN1cGVydXNlci5jb20wTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMB
AQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEE
BgorBgEEAdZ5AgQCBIH1BIHyAPAAdgBElGUusO7Or8RAB9io/ijA2uaCvtjLMbU/
0zOWtbaBqAAAAXeHyHI8AAAEAwBHMEUCIQDnzDcCrmCPdfgcb/ojY0WJV1rCj+uE
hCiQi0+4fBP9lgIgSI5mwEqBmVcQwRfKikUzhkH0w6K/6wq0e/1zJA0j5a4AdgD2
XJQv0XcwIhRUGAgwlFaO400TGTO/3wwvIAvMTvFk4wAAAXeHyHIoAAAEAwBHMEUC
IHd0ZLB3j0b31Sh/D3RIfF8C31NxIRSG6m/BFSCGlxSWAiEAvYlgPjrPcBZpX4Xm
SdkF39KbVicTGnFOSAqDpRB3IJwwDQYJKoZIhvcNAQELBQADggEBABZ+2WXyP4w/
A+jJtBgKTZQsA5VhUCabAFDEZdnlWWcV3WYrz4iuJjp5v6kL4MNzAvAVzyCTqD1T
m7EUn/usz59m02mZF82+ELLW6Mqix8krYZTpYt7Hu3Znf6HxiK3QrjEIVlwSGkjV
XMCzOHdALreTkB+UJaL6bEs1sB+9h20zSnZAKrPokGL/XwgxUclXIQXr1uDAShJB
Ts0yjoSY9D687W9sjhq+BIjNYIWg1n9NJ7HM48FWBCDmV3NlCR0Zh1Yx15pXCUhb
UqWd6RzoSLmIfdOxgfi9uRSUe0QTZ9o/Fs4YoMi5K50tfRycLKW+BoYDgde37As5
0pCUFwVVH2E=
-----END CERTIFICATE-----


option: ssl
action: cert
status: OK

curl has a --trace (and --trace-ascii) option, which prints basically everything, including all SSL/TSL handshaking. Since --trace supersedes other verbosity options, all you need is

curl --trace /path/to/trace.log https://example.com

You can then read up on ietf to match the messages from the log to the respective messages from the standard - e.g. TLS v1.2, TLS v1.3, curl even prints the corresponding message number from the standard like:

== Info: TLSv1.3 (OUT), TLS handshake, Client hello (1):

Where the (1) is the message number.

--trace-ascii works just as --trace but does not print the binary data.