(Koen Vervloesem) Een certificaatautoriteit voor ssh is veiliger en gebruiksvriendelijker dan ssh-sleutels. Met step-ca zet je eenvoudig zo’n certificaatautoriteit voor je ssh-verbindingen op.

Ssh is een veilige manier om via internet op computers in te loggen omdat de communicatie wordt versleuteld. Maar de meest gebruikte authenticatiemethode voor ssh, wachtwoorden, is eigenlijk niet zo veilig. Iemand die je wachtwoord raadt of toevallig meeleest, kan gewoon in je account inloggen.

OpenSSH heeft een oplossing daarvoor in de vorm van ssh-sleutels. In plaats van een wachtwoord te gebruiken, genereer je een sleutelpaar: een geheime sleutel en een publieke sleutel. De publieke sleutel upload je naar de server(s) waarop je wilt inloggen. De geheime sleutel staat alleen op de computer die je gebruikt om op de server in te loggen. OpenSSH laat je alleen in de server binnen als je de geheime sleutel hebt die bij de publieke sleutel hoort.

Maar authenticatie met ssh-sleutels heeft ook zijn nadelen. Je moet immers je publieke sleutel verspreiden naar alle servers waarop je wilt inloggen. En de meesten hergebruiken één sleutel om op alle servers in te loggen, wat een veiligheidsrisico is: iemand die je geheime sleutel dan te pakken krijgt, kan in al je servers die je publieke sleutel accepteren inloggen.

Tot slot is het systeem ook niet zo gebruiksvriendelijk: als je voor het eerst met een server verbindt via ssh, krijg je een vage waarschuwing waarin je opgedragen wordt om de vingerafdruk van de publieke sleutel van de server te verifiëren (wat bijna niemand doet).

Certificaten

Gelukkig ondersteunt OpenSSH nog een derde manier van authenticatie: met ssh-certificaten. Die zijn te vergelijken met tls-certificaten voor https. Een ssh-certificaat bindt een publieke sleutel aan een (gebruikers)naam en gegevens zoals gebruikersrechten en een geldigheidsdatum.

Dit certificaat kun je dan laten ondertekenen door een certificaatautoriteit (ca). Dan hoef je alleen nog maar te configureren dat de ssh-server de publieke sleutel van de ca gebruikt om gebruikerscertificaten te verifiëren en dat de ssh-client diezelfde publieke sleutel van de ca gebruikt om certificaten van servers te verifiëren. Daarna hoef je geen publieke sleutels meer rond te sturen of de vingerafdruk van een serversleutel te verifiëren.

Een certificaatautoriteit voor ssh

Je kunt je ssh-certificaten met ssh-keygen aanmaken en ondertekenen, maar dat kan ook met externe tools die het allemaal wat stroomlijnen. Een van die tools ken je al: in het vorige nummer van Linux Magazine zag je hoe je met step-ca (https://smallstep.com/certificates/) van het bedrijf smallstep (https://smallstep.com/) een eigen certificaatautoriteit en acme-server voor tls creëert en daarbij een alternatief voor Let’s Encrypt opzet. Step-ca is echter niet alleen een ca voor x.509-certificaten (gebruikt in tls), maar ook voor ssh-certificaten.

We gaan er in deze workshop dus van uit dat je step-ca geïnstalleerd hebt (zie de vorige Linux Magazine voor de installatiestappen). Daarna verloopt de eerste configuratie lichtjes anders. In plaats van step ca init gebruik je step ca init –ssh om de ca te initialiseren. Buiten die extra optie waardoor step-ca ook root-certificaten voor gebruikers en hosts creëert, verloopt de rest hetzelfde.

Daarna draai je de certificaatautoriteit ook hetzelfde als we in het vorige nummer toonden:

server:~$ step-ca $(step path)/config/ca.json

Je dient nu het ingestelde wachtwoord in te voeren om de geheime sleutels van je rootcertificaten voor tls, ssh-gebruikers en ssh-hosts te ontcijferen. Daarna draait je ca zowel voor tls als ssh.

We gaan ervan uit dat je op je apparaten step-cli hebt geïnstalleerd en gebootstrapt met de vingerafdruk en url van je ca. Verifieer of de communicatie met je ca correct verloopt (je zou de boodschap ok moeten zien):

client:~$ step ca health

Hostcertificaat ondertekenen

Creëer nu een hostcertificaat voor een ssh-server waarop je wilt inloggen, bijvoorbeeld zen.home:

step ssh certificate –host zen.home ssh_host_ecdsa_key

Kies de standaard provisioner, niet de acme-provisioner voor tls. Aangezien het om een host key gaat, voer je geen wachtwoord in om de geheime sleutel mee te encrypteren.

Het resultaat zijn drie bestanden: de geheime sleutel ssh_host_ecdsa_key, de publieke sleutel ssh_host_ecdsa_key.pub en het door je ca ondertekende certificaat ssh_host_ecdsa_key-cert.pub. Plaats deze alle drie in de directory /etc/ssh/ van de server. Voeg dan aan /etc/ssh/sshd_config de volgende regels toe:

HostKey /etc/ssh/ssh_host_ecdsa_key
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub

Eventueel dien je bij HostKeyAlgorithms nog ecdsa-sha2-nistp256 toe te voegen als je de gebruikte algoritmes ingeperkt hebt.

Herstart daarna de ssh-server.

 

Vraag een door je certificaat ondertekend hostcertificaat aan met step-ca.

Certificaatautoriteit vertrouwen

Het enige wat nu aan de clientkant nog ontbreekt, is dat we de step-ca-server als certificaatautoriteit voor sleutels moetenopgeven. Dat doe je door bijvoorbeeld aan het bestand ~/.ssh/known_hosts van elke gebruiker de volgende regel toe te voegen:

@cert-authority *.home ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAbL55OzZJMNQkUNwRp0ZdFSaen9INm4gsh+HlRZ1I4KLcDGKMlPSyXF8DP6Rk8O9/GHtYPq+cmmEXVmatPMuTE=

We configureren ssh hier zodat de certificaatautoriteit voor alle servers in het domein home gebruikt worden. Pas dit aan je configuratie aan. De publieke sleutel die begint met ecdsa-sha2-nistp256 AAAA… is de inhoud van het bestand ssh_host_key.pub uit de directory $(step path)/certs van de machine waarop step-ca draait. Uiteraard vul je hier je eigen publieke sleutel in.

Als je nu op de server via ssh inlogt, krijg je niet meer de melding dat de server niet vertrouwd is met de vraag om de vingerafdruk te verifiëren. Je krijgt nu onmiddellijk de loginprompt te zien omdat je ssh-client de server vertrouwt als de host key door je ca is ondertekend. Dat werkt zelfs als je nog nooit op de server ingelogd bent.

Gebruikerscertificaten

Je kunt nu op een gelijkaardige manier een sleutelpaar en bijbehorend certificaat voor een gebruiker maken:

step ssh certificate –principal=koan koen@vervloesem.eu id_ecdsa

De ‘principal’ is de gebruikersnaam waarvoor het certificaat geldig is, het e-mailadres is je id. Voer deze keer wel een wachtwoord in om de geheime sleutel mee te encrypteren, want het gaat hier om je eigen persoonlijke sleutel.

Het resultaat zijn weer drie bestanden: de geheime sleutel id_ecdsa (versleuteld met je wachtwoord), de publieke sleutel id_ecdsa.pub en het door je ca ondertekende certificaat id_ecdsa-cert.pub. Standaard heeft dit certificaat een geldigheid van vier uur. Bekijk de uitvoer van step ssh certificate -h om dit aan te passen en de vele andere opties. Je kunt de voor een al gegenereerd certificaat ingestelde opties bekijken met:

ssh-keygen -L -f id_ecdsa-cert.pub

Na het aanmaken van het certificaat heeft step ssh certificate dit certificaat ook aan je ssh-agent-sessie toegevoegd. Je dient hiervoor ook een wachtwoordzin in te voeren. Verifieer of je certificaat aan je sessie is toegevoegd:

ssh-add -l

Nu dien je alleen nog één regel toe te voegen aan /etc/ssh/sshd_config van de server waarop je wilt inloggen:

TrustedUserCAKeys /etc/ssh/ssh_user_key.pub

Dit bestand ssh_user_key.pub haal je uit de directory $(step path)/certs van de machine waarop step-ca draait. Plaats het in /etc/ssh op de ssh-server.

Log nu vanaf je client op de server in met je gebruikerssleutel als identiteit:

ssh -i id_ecdsa zen.home

Als alles goed gaat, ben je nu onmiddellijk ingelogd in je server. Indien je ssh-agent gebruikt, hoef je zelfs niet meer het wachtwoord in te voeren. De ssh-server hoeft je publieke sleutel ook niet meer in het bestand authorized_keys te hebben: hij herkent automatisch dat je met een vertrouwde sleutel inlogt omdat die door de ca is ondertekend. Na de ingestelde geldigheidsduur wordt je ssh-sessie automatisch afgesloten en dien je een nieuw certificaat aan te vragen om te kunnen inloggen.