Creazione e rinnovo certificato SSL Letsencrypt con Certbot e Docker e caricamento su AWS ACM

Prerequisiti

  1. Docker installato sul sistema
  2. AWS cli installata e configurata
  3. 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 myemail@mydomain.com

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.

Come controllare la scadenza di un certificato SSL da console con Ubuntu

Talvolta verificare quale sia la data di scadenza di un certificato crt o pem, presente sul proprio filesystem, specie se la macchina dove si trova tale certificato, non è esposta su internet o semplicemente il certificato non è visualizzabile per mezzo di un web browser, come nel caso dei certificati SSL per i siti web.

Pertanto, entriamo subito nel vivo e vediamo come fare per ottenere l’expiration date del certificato SSL.

Leggere la data di scadenza di un certificato SSL con estensione pem o con estensione crt, eseguendo un comando direttamente da terminale su OS Linux Ubuntu.

È possibile controllare quando scade la validità di un certificato SSL (di tipo pem o di tipo crt) eseguendo un semplice comando dalla console di Ubuntu (da bash nel terminale).

Per farlo possiamo usare i comandi forniti da OpenSSL.

cat /path/to/my/cert/certificate.crt | openssl x509 -noout -enddate

Ovviamente dopo il comando “cat”, che stampa il testo del certificato, ci deve essere il path completo del certificato, sostituire quello fornito in esempio.

Si dovrebbe ottenere in uscita un testo simile a questo:

notAfter=Jul 17 08:01:33 2021 GMT

Dove è riportata la data dopo la quale il certificato viene considerato scaduto.