Ports and connections
openssl s_client
Opens a TLS connection by hand and shows the certificate the server presents, and who signed it.
openssl s_client -connect HOST:443 -servername NAME does the TLS handshake and prints the certificate
chain. Pipe it into openssl x509 -noout -subject -issuer -dates to read the one certificate that matters: the
subject (which names it covers), the issuer (who vouches for it) and its dates. A certificate for the wrong
name, or signed by someone unexpected, is what an interception proxy looks like from the inside.
-showcerts prints every certificate the server sends, so a missing intermediate shows. openssl verify -CAfile ROOT -untrusted INTERMEDIATES CERT walks a chain by hand. And openssl is a whole CA in one tool: openssl req makes keys,
self-signed certificates and signing requests, openssl x509 -req -CA … -CAkey … signs them.
openssl s_client command usage
echo | openssl s_client -connect HOST:PORT -servername NAME [-showcerts] … | openssl x509 -noout -subject -issuer -dates -ext subjectAltName openssl verify -CAfile ROOT [-untrusted CHAIN] CERT
Options
-
-connect bank.lab:443 - where to connect
-
-servername bank.lab - the name to ask for (SNI): the server picks its certificate by it
-
x509 -noout -subject -issuer - print only the certificate's names
-
-dates - when it starts and stops being valid
-
-showcerts - print every certificate the server sends, not only its own
-
-verify_hostname NAME - check the certificate's names too, as curl does; s_client does not by default
-
-fingerprint -sha256 - a digest of the whole certificate, to compare with a copy read elsewhere
-
-attime SECONDS - check the certificate's dates as of that Unix time, not the clock's
openssl s_client examples
-
echo | openssl s_client -connect bank.lab:443 -servername bank.lab 2>/dev/null | openssl x509 -noout -subject -issuer - Prints which name the server's certificate covers and who signed it.
-
echo | openssl s_client -connect bank.lab:443 -servername bank.lab 2>/dev/null | openssl x509 -noout -dates - Prints when the certificate became valid and when it expires.
-
openssl s_client -showcerts -connect shop.lab:443 -servername shop.lab </dev/null 2>/dev/null | grep -E '^ *[0-9] s:|i:' - Lists the chain the server sends: each certificate's subject and issuer, its own first.
-
openssl verify -CAfile root.pem -untrusted issuing.pem server.pem - Checks that server.pem chains through issuing.pem to root.pem.
-
openssl x509 -in server.pem -noout -text - Decodes a certificate in full: names, dates, key, extensions.
-
openssl x509 -in server.pem -noout -ext subjectAltName - Prints only the names the certificate covers: browsers check these, not the CN.
-
openssl x509 -in server.pem -noout -checkend 2592000 - Exits 1 if the certificate expires within 30 days (2592000 seconds): a check for a cron job.
-
openssl req -x509 -newkey rsa:2048 -noenc -keyout shop.key -out shop.pem -days 365 -subj '/CN=shop.lab' -addext 'subjectAltName=DNS:shop.lab' - Makes a self-signed certificate and its unencrypted key in one step (-noenc is OpenSSL 3; older ones say -nodes).
-
openssl req -new -newkey rsa:2048 -noenc -keyout shop.key -out shop.csr -subj '/CN=shop.lab' - Makes a key and a certificate signing request to send to a CA.
-
openssl req -in shop.csr -noout -text - Shows what a signing request asks for before you send it.
-
openssl s_client -connect bank.lab:443 -servername bank.lab -tls1_3 </dev/null - Checks whether the server speaks TLS 1.3: the handshake fails if it does not.
-
openssl s_client -connect mail.lab:25 -starttls smtp </dev/null - Upgrades an SMTP connection to TLS and shows the mail server's certificate.
-
openssl x509 -in cert.der -inform der -out cert.pem - Converts a binary DER certificate to the PEM text form.
-
openssl pkcs12 -export -in shop.pem -inkey shop.key -out shop.p12 - Packs the certificate and key into one PKCS#12 file, the form Windows and Java import.
Pitfalls
echo |closes the connection after the handshake; without it, s_client waits for you to type.- s_client prints Verify return code but connects anyway: it reports a bad certificate, it does not refuse it.
- A browser can hide a missing intermediate it remembers from another site; test servers with s_client or curl.