Hashicorp Vault
Oct 11 2023
Hoe beginnen we hieraan?
Een wachtwoord manager is tegenwoordig geen overbodige luxe om te hebben. Containers vormen vaak een basis van ontwikkelingen en die moeten automatisch en op een veilige manier hun configuratie krijgen. Het is dan niet veilig als je dan een wachtwoord als clear text
in een bestand laat staan. Iedereen met toegang tot de configuratie, kan dan meteen het wachtwoord uitlezen. Veel beter is dan een wachtwoordmanager zoals Vault van Hashicorp. Dit soort wachtwoordmanager is niet bedoelt voor jouw dagdagelijks gebruik zoals een Bitwarden in jouw browser of smartphone. Deze is ontworpen zodat andere computers, API's en dergelijke, hier gemakkelijk gebruik van kunnen maken. Hoe dat gebeurt, lees je hieronder. Eerst hebben we en paar zaken nodig voor we van start gaan.
Repo
Om te beginnen, moeten we de repo van Hashicorp toevoegen. Hun software zit namelijk niet in de standaard repo's van Red Hat of Fedora. Toevoegen van die repo's is eenvoudig werk. Je vindt hun repo ook vrij snel op hun website. Hier toch even de stappen voor jouw gemak. 😉
wget https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
mv hashicorp.repo /etc/yum.repos.d/
sudo dnf update
sudo dnf -y install vault
Certificaat
Om een beveiligde verbinding te kunnen maken met onze server, moeten we ook een certificaat hebben. In het veld wil je steeds één van de volgende opties gebruiken:
- Een certificaat ondertekend door een interne Certificate Authority (CA).
- Een certificaat van een erkende CA.
- Een geldig certificaat via
Let's encrypt
.
Bekijk mijn blog post over Let's Encrypt om na te gaan hoe je
certbot
op jouw toestel zet. Daarmee kunnnen we nu een geldig certificaat genereren.
Als je het certificaat rechtstreeks op de server genereert, kan je het Let's Encrypt
certificaat terugvinden in /etc/letsencrypt/live/domeinnaam/fuulchain.pem
en de key in dezelfde map maar dan privkey.pem
. Deze ga je in de volgende stap willen invullen.
Configure Vault
We hebben nu ons certificaat en Vault is geïnstalleerd. We zijn er bijna, toch? Neen toch niet maar hou dat enthousiasme vast! In de configuratie ga je nu een verwijzing willen maken naar jouw certificaat. Die configuratie vind je in: /etc/vault.d/vault.hcl
.
#HTTPS listener
...
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/domain.crt"
tls_key_file = "/opt/vault/tls/domain.key"
...
}
Nu dat klaar is, moeten we Vault daar ook toegang tot geven. Een elegante oplossing is een extra group aanmaken en de vault
gebruiker daar lid van te maken. Deze groep kunnen we dan de nodige rechten geven op de map met ons certificaat. We moeten ook zeker zijn dat als de host naar ons domeinnaam wilt, die naar de lokale server verwijst. Dat kunnen we doen door ons domeinnaam aan /etc/hosts
toe te voegen.
Je kan deze stap overslaan als je Let's Encrypt niet op deze server hebt uitgevoerd. Dan moet het certificaat enkel de juiste rechten hebben. Dat kan dan
vault
als eigenaar en groep van de bestanden.
sudo groupadd pki
sudo chgrp -R pki /opt/vault/tls/
sudo chmod -R g+rx /opt/vault/tls/
sudo usermod -a -G pki vault
echo 127.0.0.1 <domainname> | sudo tee -a /etc/hosts
Start en initialiseer vervolgens Vault. Bij het initialiseren, geven we een paar opties mee. Key shares
verwijst naar het aantal tokens dat we gaan maken om onze kluis te ontgrendelen en key threshold
is het aantal tokens die nodig zijn om de kluis effectief te ontgrendelen.
# Start service
sudo systemctl enable --now vault.service
# Geef aan hoe de vault bereitk wordt
export VAULT_ADDR=https://<vault adres>:8200
# Initialeseer de kluis
vault operator init -key-shares=3 -key-threshold=2
Let op dat je de Root EN Unseal Tokens goed noteert. Deze gaan niet meer opnieuw getoond worden en zijn de enigste manier om in jouw kluis te komen.
Werken met de vault
Onze kluis is aangemaakt en standaard is die meteen vergrendeld. Voordat we nu dus kunnen werken met onze kluis, moeten we die dus eerst ontgrendelen. Omdat we key threshold
op twee gezet hebben, moeten we twee Unseal Tokens
ingeven. Dat kunnen we door onderstaand commando tweemaal uit te voeren. Je kan dan iedere keer een andere token ingeven.
vault operator unseal
Nu onze kluis ontgendeld is, kunnen we aan het echte werk beginnen. We kunnen een key vault activeren, geheimen daar in steken en die ook oplijsten of ophalen.
root_token=<jouw root token>
VAULT_TOKEN=$root_token vault secrets enable kv
# Lijst secrets
VAULT_TOKEN=$root_token vault secrets list
# schijf secret
VAULT_TOKEN=$root_token vault write kv/message value=mypassword
# Lees secrit
VAULT_TOKEN=$root_token vault read kv/message
Policies maken
Dit is voorlopig nog niet erg handig. We hebben namelijk maar één manier om de kluis te openen en dan staat de deur ineens open voor alles. Dit kan beter. Dit kunnen we compartmentaliseren. Via een policy
kunnen we een API of externe tool toch gegevens laten uitwisselen maar dan enkel de info die wij goedkeuren. Belangrijk is dus dat we dan eerst goed aangeven wat er exact mag. Onze applicatie mag bijvoorbeeld enkel gegevens uitlezen vanuit kv/message
. Om dat te realiseren steken we dat in een bestand zoals bijvoorbeeld: kv_message_read.hcl
Verzamel jouw policies in een gedeelde map en geef deze beduidende namen. De naam
policy.hcl
is dus een slecht voorbeeld. Beter is dankv_message_read
waarin je meteen aangeeft waarover het gaat en wat toegestaan is.
path "kv/message" {
capabilities = ["read"]
}
Dit bestand kunnen we nu inlezen om er daarna een App token
van te maken. Deze token, kunnen we dan gebruiken in onze externe tool of API. Noteer deze dus goed als je onderstaande commando's uitvoert. Die token is het toegangsticket voor onze externe tool.
VAULT_TOKEN=$root_token vault policy write message-readonly kv_message_read.hcl
VAULT_TOKEN=$root_token vault token create -policy="message-readonly"
Nu we onze app_token
hebben, kunnen we deze in onze API of tool gebruiken. Ben je curieus wat nu wel of niet werkt? Voer de commando's onder Werken met Vault
opnieuw uit maar dan met de app_token
. Als alles goed gaat, kan je nu enkel de gegevens lezen uit kv/message.
app_token=<jouw app token hier>
# Dit werkt
VAULT_TOKEN=$app_token vault read kv/message
# Dit niet
VAULT_TOKEN=$app_token vault list kv/
Wil je hiermee nog wat verder spelen? Lees dan zeker de verdere documentatie van Hashicorp. Daarnaast probeer ik dit voorbeeld nog verder uit te werken met een praktisch voorbeeld. Stay tuned voor deel 2!