Ssh-certificaten
- May 18, 2017
- 0
De meeste gebruikers van OpenSSH beperken zich tot het inloggen op servers met een wachtwoord. Wie wat meer aandacht aan beveiliging besteedt, maakt gebruik van ssh-sleutels. De beste beveiliging verkrijg je echter met ssh-certificaten. In deze workshop kijken we hoe je dit gebruikt.
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 privésleutel en een publieke sleutel. De publieke sleutel upload je naar de server(s) waarop je wilt inloggen. De privé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 privésleutel hebt die bij de publieke sleutel hoort.
Een ssh-sleutelpaar aanmaken, gaat heel eenvoudig:
*******************start listing*******************
ssh-keygen
*******************eind listing*******************
Dit genereert een 2048-bit RSA-sleutelpaar en slaat dit op in ~/.ssh/id_rsa (privésleutel) en ~/.ssh/id_rsa.pub (publieke sleutel). Met de optie -b kies je een ander aantal bits, met de optie -t kies je een ander type dan RSA en met -f geef je een andere bestandsnaam op.
Het programma ssh-keygen vraagt je om een wachtwoordzin op te geven en een tweede keer om te bevestigen. Als je geen wachtwoordzin ingeeft, kan iedereen die je privésleutel te pakken krijgt daarmee inloggen. Door die wachtwoordzin wordt de privésleutel versleuteld, waardoor alleen degene met de wachtwoordzin iets met de privésleutel kan.
Wanneer je sleutelpaar is aangemaakt, kopieer je de publieke sleutel naar de server waarop je wilt inloggen. OpenSSH heeft daarvoor het programma ssh-copy-id:
*******************start listing*******************
ssh-copy-id -i ~/.ssh/id_rsa.pub GEBRUIKER@SERVER
*******************eind listing*******************
Geef in plaats van SERVER de servernaam in en in plaats van GEBRUIKER je gebruikersnaam op de server. Verander de naam van het publieke sleutelbestand als je bij het aanmaken van het sleutelpaar een andere locatie hebt gekozen. Ssh-copy-id logt nu in op de server (op de klassieke manier, dus je moet je wachtwoord nog ingeven) en voegt de publieke sleutel toe aan het bestand ~/.ssh/authorized_keys.
Als je daarna op de server inlogt met ssh vanaf je computer met de privésleutel, wordt voor de authenticatie niet het wachtwoord van je gebruiker verwacht, maar je privésleutel, die je met je passphrase ontsleutelt. Ben je niet zeker of je ssh-server je sleutelpaar voor de authenticatie gebruikt, log dan in met de optie -v en zoek in de uitvoer naar een regel met Authentication succeeded (publickey):
******************start listing*******************
ssh -v SERVER
[…]
Enter passphrase for key ‘/home/test/.ssh/id_rsa’:
debug1: read PEM private key done: type RSA
debug1: Authentication succeeded (publickey).
[…]
*******************eind listing*******************
Inloggen met wachtwoord uitschakelen
Als je zeker bent dat je op je server kunt inloggen met je sleutelpaar en dat je met dat account ook root kunt worden dankzij sudo (of als het om root gaat), moet je niet meer kunnen inloggen met alleen een wachtwoord. Die mogelijkheid kun je dan uitschakelen. Dat kan met de volgende regel in het bestand /etc/sshd/sshd_config op de server:
*******************start listing*******************
PasswordAuthentication no
*******************eind listing*******************
Herstart nu de ssh-server. Zonder systemd gaat dat met /etc/init.d/sshd restart en met systemd doe je het met systemctl restart sshd.service. Probeer daarna uit (bijvoorbeeld vanaf een ander account) of je zonder privésleutel en met gebruik van slechts een wachtwoord kunt inloggen. Je zou de foutmelding “Permission denied (publickey).” moeten krijgen.
Meer flexibiliteit met SSH-certificaten
Wat je tot nu toe in deze workshop hebt gelezen, is voor systeembeheerders en veiligheidsbewuste thuisgebruikers algemene kennis. Maar het is niet erg bekend dat OpenSSH ook certificaten kent, te vergelijken met OpenSSL-certificaten voor HTTPS. Deze functie werd in maart 2010 geïntroduceerd in OpenSSH 5.4. Enerzijds is dat nog relatief recent, waardoor de functie nog niet zo vaak gebruikt wordt. Anderzijds is het toch al meer dan vijf jaar geleden en wordt het toch wel eens tijd dat zo’n belangrijke functie meer ingeburgerd raakt.
Het principe is eenvoudig: als je heel wat sleutels voor gebruikers aanmaakt, moet je die aan heel wat authorized_keys bestanden toevoegen. Door een Certificate Authority (CA) te introduceren, maakt OpenSSH dit proces wat gemakkelijker. Je laat al je sleutels dan ondertekenen door de CA en je hoeft je machines alleen te laten weten dat je sleutels die door de CA zijn ondertekend vertrouwt. Ondertekende sleutels kunnen ook een vervaldatum hebben (dat is niet mogelijk met traditionele ssh-sleutels).
Traditioneel vraagt OpenSSH je de eerste keer dat je op een machine inlogt of je die machine wilt vertrouwen en toont je een signature van de host key, de sleutel van de machine. Met een CA kun je ook host keys ondertekenen. Is de host key ondertekend door een CA die je vertrouwt, dan krijg je die melding niet meer.
Certificate Authority aanmaken
De eerste stap om gebruik te maken van ssh-certificaten is een CA-sleutelpaar aanmaken. Dat kan eenvoudig door met ssh-keygen een sleutelpaar aan te maken. Geef het sleutelpaar een beschrijvende bestandsnaam en geef in het commentaar ook aan wat de bedoeling ervan is. We maken een afzonderlijke CA voor user keys en een andere voor host keys. En omdat het zo’n belangrijk sleutelpaar is, gebruiken we een sleutelgrootte van 4096 bits in plaats van de standaard 2048 bits. Dat gaat als volgt:
*******************start listing*******************
ssh-keygen -b 4096 -f example-com-user-ca -C “User CA key for example.com”
ssh-keygen -b 4096 -f example-com-host-ca -C “Host CA key for example.com”
*******************eind listing*******************
Geef zeker een passphrase in bij het aanmaken van de CA-sleutelparen, want anders kan iedereen die de privésleutel te pakken krijgt willekeurige ssh-sleutels ondertekenen en dus als vertrouwd aanduiden. Maak de CA-sleutelparen bovendien aan op een veilige computer die volledig onder jouw controle staat, dus niet op een server, maar op je eigen werkstation.
Vraag nu aan je gebruikers om hun publieke ssh-sleutels te bezorgen (hun privésleutels moeten ze altijd strikt voor zichzelf houden). Die onderteken je dan met de CA-privésleutel. Dat gaat weer met het programma ssh-keygen, bijvoorbeeld:
*******************start listing*******************
ssh-keygen -s example-com-user-ca -n gebruiker -I example.com-gebruiker -V +52w id_rsa.pub
*******************eind listing*******************
Met de optie -s duid je de signing key aan, namelijk de privésleutel van het CA-sleutelpaar dat we eerder aanmaakten. Met de optie -n geef je de naam van de gebruiker aan en met -I geef je de ondertekende sleutel een naam. Gebruik daarvoor bijvoorbeeld een combinatie van je domein en de gebruikersnaam. Die naam wordt in de logbestanden van OpenSSH gebruikt en die heb je ook nodig als je later een sleutel weer wilt intrekken. Met de optie -V geef je de geldigheid aan, in dit geval 52 weken of één jaar. Helemaal op het laatst komt de bestandsnaam van de publieke sleutel die je wilt ondertekenen.
De ssh-keygen-opdracht zal je om de wachtwoordzin voor de CA-privésleutel vragen. Het resultaat van de opdracht is een bestand id_rsa-cert.pub in dezelfde directory als de publieke sleutel. Dit is het certificaat.
Inloggen met ondertekende user keys
Bezorg nu het certificaat aan je gebruiker en vraag hem om dat op zijn computer naast zijn id_rsa.pub (in de directory ~/.ssh/) te plaatsen. Dat is het enige wat de gebruiker hoeft te doen.
Op de server die ondertekende user keys moet vertrouwen, moet je nu de publieke sleutel van het CA-sleutelpaar plaatsen. Kopieer daarvoor het bestand example-com-user-ca.pub dat je hierboven hebt aangemaakt, bijvoorbeeld naar /etc/ssh/. Voeg dan in het bestand /etc/ssh/sshd_config de volgende regel toe:
*******************start listing*******************
TrustedUserCAKeys /etc/ssh/example-com-user-ca.pub
*******************eind listing*******************
Herstart de ssh-server. Daarna hoeven gebruikers waarvan de ssh-sleutel door de user CA is ondertekend, hun publieke sleutel niet meer in het bestand authorized_keys op de server te kopiëren om in te loggen. De server herkent automatisch dat het om een vertrouwde sleutel gaat.
Wil je ook je gebruikers de zekerheid geven dat ze op de juiste machines inloggen, onderteken dan de host keys van al je machines. Dat gaat met dezelfde ssh-keygen-opdracht als het ondertekenen van user keys, met slechts één verschil: de optie -h om aan te geven dat het om een host key gaat. OpenSSH maakt immers geen enkel verschil in het bestandsformaat van een user key of host key, dus dit onderscheid moeten we zelf aangeven. De opdracht wordt dan bijvoorbeeld:
*******************start listing*******************
ssh-keygen -s example-com-host-ca -h -n host.example.com -I host.example.com-sleutel -V +52w ssh_host_rsa_key.pub
*******************eind listing*******************
Na de optie -s komt de privésleutel van de host CA, met -n geven we de naam van de host aan (voeg ,IPADRES toe als je ook via het ip-adres wilt inloggen) en geef de ondertekende sleutel een naam. Ook hier kun je de geldigheid aangeven en komt op het einde de bestandsnaam van de te ondertekenen publieke sleutel. Het resultaat is een bestand ssh_host_rsa_key-cert.pub in dezelfde directory. Dit is het certificaat.
Ondertekende host keys gebruiken
Plaats het certificaat nu op de server naast de host key, doorgaans is dat in /etc/ssh/ssh_host_rsa_key-cert.pub. Voeg aan /etc/ssh/sshd_config de volgende regel toe:
*******************start listing*******************
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub
*******************eind listing*******************
Herstart de OpenSSH-server. Op de clients voeg je aan het bestand ~/.ssh/known_hosts van de gebruikers de volgende regel toe:
*******************start listing*******************
@cert-authority *.example.com INHOUDVANSIGNINGKEY.PUB
*******************eind listing*******************
In plaats van .example.com gebruik je uiteraard jouw domein of als je het certificaat op alle hosts wilt toepassen. En in plaats van INHOUDVANSIGNINGKEY.PUB komt letterlijk de inhoud van de publieke sleutel van de host CA, example-com-host-ca.pub, alles op één regel.
Als de gebruikers met deze regel in hun known_hosts-bestand nu inloggen op een server met een certificaat dat door de host CA is ondertekend, krijgen ze niet de vraag of ze de host key vertrouwen en willen toevoegen aan hun known_hosts. Het is immers al vertrouwd omdat ze de CA vertrouwen.
Sleutels intrekken
Een laatste voordeel van het gebruik van een CA is dat je hiermee ssh-sleutels kunt intrekken, bijvoorbeeld als je weet dat de privésleutel van een gebruiker in verkeerde handen is gevallen. Maak daarvoor eerst op al je servers een leeg bestand revoked_keys aan als root:
*******************start listing*******************
# touch /etc/ssh/revoked_keys
*******************eind listing*******************
Voeg daarna aan het bestand etc/ssh/sshd_config de volgende regel toe:
*******************start listing*******************
RevokedKeys /etc/ssh/revoked_keys
*******************eind listing*******************
En herstart de ssh-server. Nu maken we met ssh-keygen een Key Revocation List (KRL) aan. Ken je de namen van de publieke sleutels (wat na de optie -I kwam bij het ondertekenen door de CA) die je wilt intrekken, maak dan eerst een bestand ‘in-te-trekken-sleutels’ aan met de volgende inhoud:
******************start listing*******************
id: example.com-gebruiker1
id: example.com-gebruiker2
*******************eind listing*******************
Roep daarna ssh-keygen aan om de KRL op basis van dit bestand aan te maken:
*******************start listing*******************
ssh-keygen -k -f revoked_keys -u -s example-com-user-ca in-te-trekken-sleutels
*******************eind listing*******************
Met -k geven we aan dat we een KRL willen aanmaken of updaten en met -f geven we de bestandsnaam van de KRL aan. Met -u geven we aan dat we het bestand willen updaten. De eerste keer dat je een KRL aanmaakt, laat je de optie -u dan ook weg, want dan bestaat het bestand nog niet. Met -s geven we de CA-sleutel op. Gebruik het volledige pad als die niet in dezelfde directory staat. Op het einde komt de bestandsnaam met de in te trekken sleutels.
Het resultaat is een bestand revoked_keys. Verspreid dit nu naar al je servers en plaats het op de juiste plaats, /etc/ssh/revoked_keys. De servers zullen gebruikers met die ingetrokken sleutels niet meer toelaten.