Commands / Ports and connections

Ports and connections

openssl s_client

Also openssl, certificate, tls handshake

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.

Run it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Open this lab