Connecting to HTTPS with OpenSSL
OpenBSD uses LibreSSL, a fork of OpenSSL begun in 2014, which modernizes the codebase and improves security.
Connecting to HTTPS websites
To test a website's TLS:
$ openssl s_client -connect example.com:443
Replace example.com
with your actual hostname.
You should see the correct SSL subject and issuer:
$ openssl s_client -connect example.org:443 CONNECTED(00000003) depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1 verify return:1 depth=1 C = US, O = Let's Encrypt, CN = R11 verify return:1 depth=0 CN = example.com verify return:1 --- Certificate chain 0 s:/CN=example.com i:/C=US/O=Let's Encrypt/CN=R11 1 s:/C=US/O=Let's Encrypt/CN=R11 i:/C=US/O=Internet Security Research Group/CN=ISRG Root X1 --- Server certificate -----BEGIN CERTIFICATE----- MIIF+jCCBOKgAwIBAgISBBiSmYI1JcgnGriQsYnjgYNaMA0GCSqGSIb3DQEBCwUA MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD EwNSMTEwHhcNMjQxMTE0MDAzNjU3WhcNMjUwMjEyMDAzNjU2WjAfMR0wGwYDVQQD ExRqcm11Lmhvc3QuaXJjbm93Lm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC AgoCggIBANuLaDDkipvSVq4lPmSymFhbnqt7Exv3LRmzq6YvqzWpLOd1wkHNXFHg yxCE6AbVdz3jqZT00sVO1uF/A3YdN63qlziWJFP1GaCZzcyuJ7a2NAVX/igggxO3 guwzlfFh844AoudJ3+KPBCGfCmI8qWftjOTIz4/huCr3CRsPwuABySWKGh/p9n+3 wJE5EU425hkiTGGDNhF65aU8B/cT3clhdkFKwcNGEX4vkrQwlZeF43Mj9cQf3G3v uAOdP0DEGqhxyYQUrsGP/ml9S99VnQ91hxta1J4EYwTqCnG4UwyZ/unFJ3vRpajQ /8LKkVPBQxKaREJNafB0cv29sEqE2RTBWzot8RT6mSFN59b07O7m4pxqHs+OenkW ltH3lM9pwrFBc0RLipAXkkgauVSohBH7SbVuMDIwCMYFdOHCBRqgW6eDTk+hhklh nXWR0JJ2lRF1IUQQjduJWadEUDK9O/iUfLfnZr1a5ZfjXs4dlFqVU8NUQWQd3G5J 9d4iCX7VkEigXlJrxTgbohFLkPzeDiSPqdwKqx1GMEWLxrW65a71UR81AJEYTJJE ixOwGEb1kXtGEqKhM4CYywBLKiDNOEoMPsRg3UsOfHS1eaSDF6io42brmhKILAJL SP5CTPZw5LYKaqc+aO13keucLBTne5+aWhaQBD0ihqsssYPlxFehAgMBAAGjggIa MIICFjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF BwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFAVeGed5J7eod57c69KSUDiVDq7m MB8GA1UdIwQYMBaAFMXPRqTq9MPAemyVxC2wXpIvJuO5MFcGCCsGAQUFBwEBBEsw STAiBggrBgEFBQcwAYYWaHR0cDovL3IxMS5vLmxlbmNyLm9yZzAjBggrBgEFBQcw AoYXaHR0cDovL3IxMS5pLmxlbmNyLm9yZy8wHwYDVR0RBBgwFoIUanJtdS5ob3N0 LmlyY25vdy5vcmcwEwYDVR0gBAwwCjAIBgZngQwBAgEwggEGBgorBgEEAdZ5AgQC BIH3BIH0APIAdwDPEVbu1S58r/OHW9lpLpvpGnFnSrAX7KwB0lt3zsw7CAAAAZMo T6OZAAAEAwBIMEYCIQD+t4oiZ3lkJeY+nH1glYZjlktnSc31rKjJlBbJwnPTfwIh ALwVTA0TNEa2jo5zmOq7nypo7awprI48XnDofYsb7GK+AHcAE0rfGrWYQgl4DG/v THqRpBa3I0nOWFdq367ap8Kr4CIAAAGTKE+kEwAABAMASDBGAiEA5nosfBa3GTMC Rw9xjef4RVpwdvaaRsC8xDZy95CW86ECIQCLSXo2BqI9coah2trzV3gxq0LnEn9r XcciSxO0ZH4mCzANBgkqhkiG9w0BAQsFAAOCAQEApjLhmAFD1bEgI5lxzIcGQrdM 3CSgDn7OZEqQS6pbmTGdjk3aiWAUNsNlwBdatdWra171lytEd2wufDf/iN7RWkcK 6BK3RZeTsKK8KNdKiV7oXL9Kd/1NpYSHizVN1obqF3Knh1JM+Kes6YXTxod7L1Av ozkhle3d61jrUhUz4VEp053pNxi8ylDRd6jeDnIAQbAJlGJapD1P3Sfy0VL+Kprs ZoEucBa3ZaSh+JNNS0fxSnl/qKfWlwOSsiMNL8yj7sy6hcVEgWqhMkviGGYpNikY harUihdi26bReT1MXM9nFsYZa20+B1BUGk7Y/0TQ7zo1JtjhSXVIP4pB1zpuwg== -----END CERTIFICATE----- subject=/CN=example.com issuer=/C=US/O=Let's Encrypt/CN=R11 --- No client certificate CA names sent Server Temp Key: ECDH, X25519, 253 bits --- SSL handshake has read 3645 bytes and written 386 bytes --- New, TLSv1/SSLv3, Cipher is TLS_AES_256_GCM_SHA384 Server public key is 4096 bit Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1.3 Cipher : TLS_AES_256_GCM_SHA384 Session-ID: Session-ID-ctx: Master-Key: Start Time: 1731552214 Timeout : 7200 (sec) Verify return code: 0 (ok) ---
At this point, you can make normal HTTP GET requests like with netcat or telnet.
Expired Certificates
If your certificate has expired, you will see the following error message:
Verify return code: 10 (certificate has expired)
Make sure to renew your certificate using acme-client. Consider automating the renewal using cron.
Missing full certificate chain
If the web server is missing the full certificate chain, you will see the following return code:
Verify return code: 20 (unable to get local issuer certificate)
Double check that the web server is serving the full certificate chain.
If using acme-client, make sure you are
using the certificate that is specified in
acme-client.conf(5)'s
domain full chain certificate
.
Self-Signed Certificates
If you are using a self-signed certificate, you will see the following return code:
Verify return code: 18 (self signed certificate)
It's recommended to use a properly signed certificate from a trusted Certificate Authority to avoid issues with users trying to connect. Such certificates can be requested using acme-client. Self-signed certificates will often trigger validation errors from end-user clients.
Wrong Ports
Obtaining TLS certificate
To get the certificate from a website, type the command below, replacing example.com:
$ openssl s_client -connect example.com:443 2>&1 | sed -n '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > example.com.pem
See Also:
- Applied Cryptography: Protocols, Algorithms, and Source Code in C by Bruce Schneier
- SSL and TLS Essentials: Securing the Web by Stephen A. Thomas