Tegenwoordig worden steeds meer services enkel nog encrypted aangeboden, zelfs binnen bedrijfsnetwerken. Qua security is dat een goede zaak, maar het maakt het troubleshooten als sysadmin soms knap lastig. Even telnetten naar poort 8080 om een Tomcat-instance te debuggen, zit er niet meer in. Ook de eigenlijke SSL-setups reageren niet altijd zoals je verwacht. Problemen met certificates of certificate chains kom je helaas vaker tegen dan je lief is! Dat alles kan je gelukkig debuggen met openssl’s s_client, zeg maar telnet voor SSL-verbindingen.

Om een verbinding op te zetten met een SSL-enabled service hoef je enkel de hostname en port mee te geven aan s_client:

 

$ openssl s_client -connect www.google.nl:443

s_client toont nu een hele waslijst aan informatie, zoals het server certificate, de certificate chain (CA die het certificate gesigned heeft en eventuele intermediate CA’s), gebruikte protocol en cipher, etc. Je hoeft je daarover verder niet te bekommeren als je de service zelf (en niet zozeer de SSL-setup) wilt debuggen. Vanaf dit punt kan je gewoon protocol-specifieke commando’s versturen net zoals je dat bij telnet zou doen, bijvoorbeeld GET / HTTP/1.1 … voor HTTP of HELO, MAIL FROM:, RCTP TO:, … voor SMTP.

Maakt de service gebruik van STARTTLS? Voeg dan de optie -starttls <protocol> toe om s_client te vertellen met welk protocol je verbinding probeert te maken. s_client ondersteunt STARTTLS voor smtp, pop3, imap en ftp. Vergeet ook niet om nu de plaintext port te gebruiken, zoals 587 in plaats van 465 voor mail submission over SMTP of 143 in plaats van 993 voor IMAP.

Valideren
s_client is ook een prima tool om te controleren of een server wel een geldig certificaat aanbiedt. Daarvoor heeft s_client wel een bestand of directory met trusted root certificates nodig. Voor een publiek toegankelijke service wil je natuurlijk weten of het certificaat kan worden gevalideerd met de standaard root certificates, die in elk OS aanwezig zijn. Staan die op jouw systeem bijvoorbeeld onder /etc/ssl/certs, dan gebruik je de -CApath-optie:

$ openssl s_client -connect www.google.nl:443 -CApath /etc/ssl/certs

s_client probeert nu elk certificaat uit de certificate chain achtereenvolgens te valideren. De resultaten zie je aan het begin van de output, op verschillende regels beginnend met “depth=” en “verify return:”. Als alles goed verloopt, krijg je aan het einde van de output ook “Verify return code: 0 (ok)” te zien. Mislukt de validatie, dan wil je misschien alle tussenliggende certificaten verder bestuderen. Die worden enkel getoond als je de optie “-showcerts” toevoegt (standaard toont s_client enkel het server certificate volledig).

Extra controles
De optie -CAfile is dan weer vooral handig om eigen certificaten voor intern gebruik te valideren. In dat geval verwijs je niet naar de directory met default root certificates van je OS, maar naar het certificaat van je eigen CA.

Daarnaast kan s_client controleren of het certificate purpose wel klopt en of het certificaat niet is ingetrokken via een Certificate Revocation List. Meer informatie daarover vind je in de manpage van het verify-commando bij de opties -purpose en -crl_check.

s_client biedt je ook controle over het gebruikte protocol (SSLv3, TLSv1.0, …) en de geselecteerde cipher. Het is weliswaar de server die de laatste keuze daarin heeft, maar via s_client kan je verschillende clients simuleren, die verschillende protocollen en ciphers al dan niet ondersteunen. Zo controleer je bijvoorbeeld of een webserver TLS met de ciphers ECDHE-RSA-AES256-GCM-SHA384 of ECDHE-ECDSA-AES256-GCM-SHA384 ondersteunt:

$ openssl s_client -connect www.google.nl:443 -no_ssl2 -no_ssl3 -cipher ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384

Als de webserver geen ondersteuning biedt voor de gekozen protocollen, dan zal de SSL handshake gewoon mislukken. Het commando “openssl ciphers” toont een lijst van alle mogelijke ciphers.

Client authentication
In bepaalde SSL-setups laat de server toe dat clients zich via een certificaat authenticeren als alternatief voor de klassieke user/password authentication. In principe mag elke client verbinding maken met de server, maar clients met een geldig certificaat krijgen meer mogelijkheden. Bij een webserver is dat bijvoorbeeld toegang tot een afgeschermd gedeelte van de website of bij een mailserver de mogelijkheid om e-mails te versturen. SSL client authentication test je als volgt met s_client (voorbeeld van een SMTP-sessie mét en zonder client certificate, de volledige SMTP-communicatie is hier weggelaten):

$ openssl s_client -connect mailserver.com:587 -starttls smtp -CApath /etc/ssl/certs -cert yourclient.crt -key yourclient.key

HELO / MAIL FROM / RCPT TO …

.

250 2.0.0 Ok: queued as E57EC616BC

$ openssl s_client -connect mailserver.com:587 -starttls smtp -CApath /etc/ssl/certs

HELO / MAIL FROM / RCPT TO …

.

554 5.7.1 <yourclient.com[www.xxx.yyy.zzz]>: Client host rejected: Access denied