Prerequisiti
- Docker installato sul sistema
- AWS cli installata e configurata
- Utente AWS cli con permessi IAM di gestione di DNS Route53
Il problema
In breve:
Vogliamo creare un certificato SSL autofirmato e caricarlo su AWS ACM.
In dettaglio:
Vogliamo utilizzare un certbot dockerizzato che ci consenta di usare letsencrypt, per creare un certificato SSL.
Il metodo di validazione (la challenge) del dominio che abbiamo scelto è la dns-challenge, che consiste nel creare uno o più record DNS nella zona del dominio.
La validazione è uno step indispensabile per consentire a letsencrypt e in generale all’ente certificatore, di certificare che si è proprietari di un determinato dominio.
Su AWS il servizio che si occupa di gestire le zone DNS è Route-53 (per gli amici R53), dove possiamo gestire tutti i record DNS della propria zona.
Il certbot dockerizzato sfrutta un plugin chiamato dns-route53 (certbot/dns-route53) che si collega direttamente a Route-53 e si occupa della validazione, cosa di cui quindi non dovremo preoccuparci.
L’unica cosa che è necessaria per poter usare i comandi è un utente IAM (di AWS) con i privilegi di gestione dei DNS su R-53, che ci consenta di automatizzare il processo di verifica.
Un utente IAM AWS, può disporre di accesso cli (in questo caso è obbligatorio), per il quale occorre ACCESS_KEY_ID e AWS_SECRET_ACCESS_KEY.
L’esempio che ho effettuato, è stato testato usando un utente IAM admin di R53, con in pratica deve avere tutti i permessi per la gestione delle rotte e delle zone dns. Tuttavia per le tue esigenze reali, potresti aver bisogno di permessi più circoscritti e con un livello di granularità maggiore (ad esempio limitando la cosa solo a determinate zone DNS).
La Soluzione
Questo comando, consente la creazione di un certificato SSL con letsencrypt, con verifica automatica del dominio. Se tutto va a buon fine esso produrrà sotto la cartella /etc/letsencrypt i certificati in formato pem.
Ecco il comando:
docker run --rm -it --env AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID --env AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY -v "/etc/letsencrypt:/etc/letsencrypt" certbot/dns-route53 certonly --dns-route53 -d mydomain.com --agree-tos --email [email protected]
NOTA: Ripetere il comando si tradurrà in aggiornare i file che compongono il certificato, che in ogni caso scadrà dopo un massimo di 3 mesi.
Per chiarezza è bene tenere presente che la parte
-v "/etc/letsencrypt:/etc/letsencrypt"
rappresenta un volume, concretamente è il mapping tra la cartella letsencrypt nel container e quella fuori (quella di sistema), per consentire la persistenza dei dati prodotti (i certificati) anche fuori dal container.
Per verificare che tutto sia andato a buon fine potete visitare la cartella
/etc/letsencrypt/live/mydomain.com
e controllare che tutti i certificati siano stati creati.
Normalmente i file sono:
- cert.pem
- chain.pem
- fullchain.pem
- privkey.pem
Per verificare la data di scadenza di un certificato puoi usare il openssl, come ho spiegato in questo articolo.
Caricare il certificato su AWS ACM
Una volta che è stato correttamente generato, il certificato può essere caricato tramite pannello web di AWS ACM, o via CLI.
Per caricare il certificato via CLI, è necessario avere installato sul proprio sistema la console di AWS e aver definito le credenziali di accesso, cosa che normalmente si trova nel file ~/.aws/credential.
Il comando che segue consente di effettuare l’upload del certificato (ovvero dei file che lo compongono) su AWS ACM:
aws acm import-certificate --certificate fileb:///etc/letsencrypt/live/mydomain.com/cert.pem --private-key fileb:///etc/letsencrypt/live/mydomain.com/privkey.pem --certificate-chain fileb:///etc/letsencrypt/live/mydomain.com/fullchain.pem
In risposta si otterrà qualcosa di questo tipo:
{
"CertificateArn": "arn:aws:acm:eu-central-1:*******:certificate/**********"
}
In questo caso la zona del certificato è “eu-central-1” (Francoforte) e, anche se è ovvio, al posto degli asterischi ci sono dei numeri.
Per l’update del certificato, invece, va utilizzato un comando leggermente diverso, questo:
aws acm get-certificate --certificate-arn arn:aws:acm:eu-central-1:*********:certificate/****************
L’ARN è un identificativo univoco di una risorsa su AWS, anche il certificato SSL su ACM ha un ARN che può essere letto da pannello web, oppure direttamente dalla risposta avuta in fase di primo caricamento.
Spero di essere stato utile con questo articolo liberamente ispirato all’esempio proposto su coderevolve, preso a riferimento.