Tls-encryptie is tegenwoordig wijdverspreid: geen enkele serieuze applicatie biedt nog uitsluitend unencrypted communicatie aan. Natuurlijk juichen we de verbeterde security toe, maar als sysadmin zorgt die extra laag soms ook voor extra problemen. Tijd om je toolkit uit te breiden met nieuwe troubleshooting skills!

Filip Vervloesem

Foutief geconfigureerde certificaten zijn verantwoordelijk voor veel verbindingsproblemen tussen jouw server en de clients, of tussen verschillende services onderling. Vermoed je dat het probleem bij een tls-certificaat ligt, dan controleer je uiteraard eerst een aantal basiszaken. Bijvoorbeeld:

– Is het certificaat momenteel wel geldig?

– Komt het Subject van het certificaat overeen met de naam van de server (of in het geval van verschillende vhosts met één certificaat: bevat het Subject Alternative Name-veld wel alle mogelijke hostnames)?

– Is het certificaat door een erkende CA uitgegeven (of wanneer je jouw eigen CA gebruikt: beschikt de client over het correcte CA-certificaat)?

Openssl

Nu ben je misschien geneigd om dat te controleren via een browser, maar dat is niet de beste methode. Niet elke service kun je benaderen via http: denk maar aan een smtp-server met tls-encryptie. Ook zoeken naar specifieke velden in het certificaat is behoorlijk tijdrovend. Gelukkig bestaat er een prima commandline tool onder Linux om certificaten te troubleshooten: OpenSSL. OpenSSL bevat een vijftigtal (!) subcommando’s voor alle denkbare acties in verband met certificaten. Wat je ook wilt controleren, de vraag is niet óf openssl het kan, maar hóe! Wil je weten welke subcommando’s jouw versie van OpenSSL bevat, gebruik dan;

$ openssl help

Dat commando toont je meteen ook de ondersteunde message digest en cipher algoritmes. Je leest de documentatie via man <subcommando> of man openssl-<subcommando> (als er al een Linux-commando bestaat met dezelfde naam als het subcommando). Bijvoorbeeld:

$ man x509
$ man openssl-passwd

Certificaat ophalen

Om het certificaat van een service op te halen, gebruik je eerst het s_client-commando om een tls-verbinding op te zetten. Een voorbeeld voor onze eigen webserver:

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

Je krijg dan een heleboel informatie te zien over de verbinding, zoals certificate chain, server certificate, gebruikte protocol en cipher, enzovoorts. Lijkt die informatie niet te kloppen? Dat is goed mogelijk: op een server met meerdere vhosts met elk hun eigen certificaat moet je de servername expliciet opgeven:

$ openssl s_client -connect www.reshift.nl:443 -servername www.reshift.nl

Vervolgens wacht s_client op jouw invoer om opdrachten door te sturen naar de server. Maar daarin zijn we nu niet geïnteresseerd. We willen de verbinding meteen afsluiten en enkel het certificaat tonen. Dat doe je door stderr en stdin te redirecten naar /dev/null en via knip-en-plakwerk met sed (of jouw favoriete text processing tool):

$ openssl s_client -connect www.reshift.nl:443 -servername www.reshift.nl 
2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

Informatie zoeken

Je krijgt nu het certificaat in pem-formaat te zien, wat nog niet bijster leesbaar is! Daarom voegen we volgend x509-subcommando toe aan de pipe:

$ ... | openssl x509 -in - -noout -text

Nu vind je met de gebruikelijke tools snel de gewenste informatie, zoals de CA die het certificaat verstrekt heeft:

$ ... | grep 'Issuer:'

Of de geldigheid ervan:

$ ... | grep -E 'Not (Before|After)'

Fingerprint en meer

De -text-optie van x509 toont veel informatie, maar de fingerprint ontbreekt. Die vraag je apart op met de optie -fingerprint, al dan niet in combinatie met -text. Standaard toont openssl de sha1-fingerprint: voeg de optie -sha256 om de sha256-versie te tonen:

... | openssl x509 -in - -noout -fingerprint -sha256

Dit was slechts een zéér beknopte inleiding tot OpenSSL. Snuister zeker eens door de verschillende manpages om een idee te krijgen van de overige mogelijkheden!