Tutorial sui passaggi da effettuare per configurare un certificato wildcard - per tutti i sotto livelli - di un dominio gestito da Cloudflare e online grazie al web server nginx attraverso il client acme.sh di Let’s Encrypt per sistemi Linux o Unix-like.

WILDCARD DNS

Per associare al dominio utilizzato un certificato wildcard TLS/SSL, l’unico metodo che Let’s Encrypt accetta è il “challenge DNS” per autenticare la proprietà del dominio. Perciò abbiamo bisogno delle API di Cloudflare per aggiungere/modificare i DNS del nostro dominio.

Prerequisiti per ottenere un certificato wildcard di Let’s Encrypt

Di seguito vengono illustrati i passaggi da effettuare per ottenere un certificato wildcard valido da utilizzare per il dominio in nostro possesso.

Nginx

C’è bisogno del web server Nginx installato e funzionante:

$ sudo apt install nginx 

Cloudflare

Collegarsi al pannello di controllo di Cloudflare e ottenere una API key cliccando su Token API e poi su Crea token:

Cloudflare DNS API passaggio 1

Successivamente cliccare su “Modifica DNS zona” –> “Usa modello”:

Cloudflare DNS API passaggio 2

Assicurarsi che l’autorizzazione al punto 1 sia su Modifica e che la Risorsa Zona, al punto 2, sia sul nome del dominio desiderato (in questo caso rmazzu.com e cliccare su Vai al riepilogo:

Cloudflare DNS API passaggio 3

Per ultimo, cliccare su Crea token in Modifica DNS zona Riepilogo token API:

  
      
      
Cloudflare DNS API passaggio 4

A questo punto si ottiene a schermo le API di accesso per Cloudflare. Mi raccomando, non condividere con nessuno queste token, tienile al sicuro e al segreto.

Installazione client acme.sh

Dopo aver ottenuto le API di Cloudflare, è tempo di configurare il client acme.sh.

Clonare il repo con il seguente comando:

$ cd /tmp/
$ git clone https://github.com/Neilpang/acme.sh.git

e per installare il client come primo passaggio bisogna loggarsi come root usando il comando su/sudo:

$ sudo -i
$ touch /root/.bashrc
$ cd /tmp/acme.sh/
$ acme.sh --install --accountemail [email protected]

Richiesta certificato wildcard Let’s Encrypt

Fino adesso è stato installato nginx ed è stata ottenuta la chiave per accedere all’API di Cloudflare ma ora è giunto il momento di utilizzare il client acme.sh per ottenere il certificato per il dominio rmazzu.com.

Come primo passaggio esportiamo il CF_Token con il comando che segue:

# Esportazione della singola variabile per l'autorizzazione DNS di Cloudflare
$ export CF_Token="Tuo_Cloudflare_DNS_API_Key_Inserito_Qui"

Non è richiesto l’inserimento delle variabili CF_Account_ID e CF_Zone_ID in quanto vengono estrapolate automaticamente dal client acme.me.

Prossimo passaggio è la richiesta del certificato. Sostituire rmazzu.com con il tuo domain:

$ acme.sh --issue --dns dns_cf --ocsp-must-staple --keylength 4096 -d rmazzu.com -d '*.rmazzu.com'

Se vuoi creare il certificato con criptografia Elliptic-curve (ECC/ECDSA) invece di RSA, eseguire:

$ acme.sh --issue --dns dns_cf --ocsp-must-staple --keylength ec-384 -d rmazzu.com -d '*.rmazzu.com'
[Tue 24 May 2021 08:23:43 AM UTC] Creating domain key
[Tue 24 May 2021 08:23:43 AM UTC] The domain key is here: /root/.acme.sh/rmazzu.com_ecc/rmazzu.com.key
[Tue 24 May 2021 08:23:43 AM UTC] Multi domain='DNS:rmazzu.com,DNS:*.rmazzu.com'
[Tue 24 May 2021 08:23:43 AM UTC] Getting domain auth token for each domain
[Tue 24 May 2021 08:23:44 AM UTC] Getting webroot for domain='rmazzu.com'
[Tue 24 May 2021 08:23:44 AM UTC] Getting webroot for domain='*.rmazzu.com'
[Tue 24 May 2021 08:23:44 AM UTC] rmazzu.com is already verified, skip dns-01.
[Tue 24 May 2021 08:23:44 AM UTC] *.rmazzu.com is already verified, skip dns-01.
[Tue 21 May 2021 08:23:44 AM UTC] Verify finished, start to sign.
[Tue 21 May 2021 08:23:44 AM UTC] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/91933311/4305449220
[Tue 24 May 2021 08:23:45 AM UTC] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/0436c4ebf2a5233d099b21e0debb665b9b11
[Tue 24 May 2021 08:41:45 AM UTC] Cert success.
-----BEGIN CERTIFICATE-----
MIIErHPPpppp990ìLkjUu8877U03AYRrHPPpppp990ìLkjUu8877U03ADQEBCwUA
MDEwMTkwODQxMjNaMBgxFjA323320u23eh81nmVyY2l0aS5iaXowdjAQBgcqhkjO
PQIBBgUrgdhyhHuyjaujUo9oiKO99kJhhKLLuYRrHPPpppp990ìLkjUu8877U03A
.....
..
RuA8fFHPPpppp990ìLkjUu8877U03AmUHPPpppp990ìLkjUu8A6Fj+BTbaLRFQqJ
HPPpppp990ìLkjUu8877U03Adddsfsdffwfa545554==
-----END CERTIFICATE-----
[Tue 24 May 2021 08:23:45 AM UTC] Your cert is in  /root/.acme.sh/rmazzu.com_ecc/rmazzu.com.cer 
[Tue 24 May 2021 08:23:45 AM UTC] Your cert key is in  /root/.acme.sh/rmazzu.com_ecc/rmazzu.com.key 
[Tue 24 May 2021 08:23:45 AM UTC] The intermediate CA cert is in  /root/.acme.sh/rmazzu.com_ecc/ca.cer 
[Tue 24 May 2021 08:23:45 AM UTC] And the full chain certs is there:  /root/.acme.sh/rmazzu.com_ecc/fullchain.cer

A questo punto le chiavi DNS API di Cloudflare verranno salvate in /root/.acme.sh/account.conf e, per essere sicuri, controllare il contenuto del file con il seguente comando:

$ cat /root/.acme.sh/account.conf
$ grep '_CF_' /root/.acme.sh/account.conf

Configurazione del web server Nginx

Come primo passaggio bisogna assicurarsi di creare il file contenente la chiave Diffie-Hellman con il comando openssl:

$ mkdir -pv /etc/nginx/ssl/rmazzu.com/
$ cd /etc/nginx/letsencrypt/rmazzu.com/
$ openssl dhparam -out /etc/nginx/ssl/rmazzu.com/dhparams.pem -dsaparam 4096

E poi editare il file nginx.conf:

$ vim /etc/nginx/nginx.conf

inserendo questo codice:


# Configurazione Porta 80
server {
 listen      80 default_server; # IPv4
 listen [::]:80 default_server; # IPv6
 server_name www.rmazzu.com;
 access_log  off;
 error_log   off;
 root        /var/www/html;
 return 301 https://$host$request_uri;
}
 
# Configurazione Porta 443
server {
 listen 443 ssl http2;                # IPv4
 listen [::]:443 ssl http2;           # HTTP/2 TLS IPv6
 server_name www.rmazzu.com;  # nome dominio
 # Settaggio document root 
 location / {
 root   /var/www/html;
 index  index.html;
 }
 
 # Settaggio logs di accesso e errori per il vhost
 access_log /var/log/nginx/rmazzu.com_access.log;
 error_log  /var/log/nginx/rmazzu.com_error.log;  
 # TLS/SSL CONFIG 
 ssl_certificate /etc/nginx/ssl/rmazzu.com/rmazzu.com.fullchain.cer;
 ssl_certificate_key /etc/nginx/ssl/rmazzu.com/rmazzu.com.key;
 
 # ECC/ECDSA certificati (dual config)
 #ssl_certificate /etc/nginx/ssl/rmazzu.com/rmazzu.com.fullchain.cer.ecc;
 #ssl_certificate_key /etc/nginx/ssl/rmazzu.com/rmazzu.com.key.ecc;
 ssl_dhparam  /etc/nginx/ssl/rmazzu.com/dhparams.pem;
 
 # Piccola ottimizzazione
 ssl_session_timeout 1d;
 ssl_session_cache shared:NixCraftSSL:10m;
 
 # TLS versione 1.2 e 1.3 
 ssl_session_tickets off;  
 ssl_protocols TLSv1.2 TLSv1.3;
 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
 ssl_prefer_server_ciphers off;  
 
 # HSTS (ngx_http_headers_module is required)
 # *************************************************************************
 # WARNING - Wrong headers can create problems. Read docs otherwise
 #           all 3rd party scripts/ads won't load and in some case 
 #           browser won't work. Read docs @ https://developer.mozilla.org
 # ************************************************************************* 
 add_header Strict-Transport-Security "max-age=63072000" always;
 add_header X-Content-Type-Options "nosniff" always;
 add_header X-Frame-Options "SAMEORIGIN" always;
 add_header X-Xss-Protection "1; mode=block" always;
 add_header Referrer-Policy  strict-origin-when-cross-origin always;
 add_header Feature-policy "accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; payment 'none'; usb 'none'" always;
 # ***************************************************************************************************
 # WARNING: The HTTP Content-Security-Policy response header allows sysadmin/developers 
 # to control resources the user agent is allowed to load for a given page. 
 # Wrong config can create problems for third party scripts/ad networks. Hence read the following url: 
 # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
 # ****************************************************************************************************
 add_header content-security-policy "default-src https://www.rmazzu.com:443" always;  # OCSP
 
 ssl_stapling on;
 ssl_stapling_verify on;  
 ssl_trusted_certificate /etc/nginx/ssl/rmazzu.com/rmazzu.com.fullchain.cer;  
 
 # Modificare in base all'indirizzo IP del resolver utilizzato
 resolver 1.1.1.1;
}

uscire da vim con il semplice :wq.

Installazione del certificato wildcard di Let’s Encrypt

Installare il certificato dalla shell (modificare systemctl reload nginx con il comando che la distro Linux/Unix utilizza):

$ DOMAIN="rmazzu.com"
$ CONFIG_ROOT="/etc/nginx/ssl/${DOMAIN}"
$ acme.sh -d "$DOMAIN" \
--install-cert \
--reloadcmd "systemctl reload nginx" \
--fullchain-file "${CONFIG_ROOT}/$DOMAIN.fullchain.cer" \
--key-file "${CONFIG_ROOT}/$DOMAIN.key" \
--cert-file "${CONFIG_ROOT}/$DOMAIN.cer"

Installare anche la versione ECC/ECDSA (come prima, modificare il comando systemctl reload nginx in base alla distro utilizzata):

$ acme.sh -d "$DOMAIN" \
--ecc \
--install-cert \
--reloadcmd "systemctl reload nginx" \
--fullchain-file "${CONFIG_ROOT}/$DOMAIN.fullchain.cer.ecc" \
--key-file "${CONFIG_ROOT}/$DOMAIN.key.ecc" \
--cert-file "${CONFIG_ROOT}/$DOMAIN.cer.ecc"

Rinnovo del certificato Let’s Encrypt

acme.sh installa in automatico in cronjob il comando per rinnovare il certificato e, quindi, non c’è bisogno di nessun intervento manuale.

Se, per qualsiasi motivo, si necessita di un rinnovo manuale, dalla shell va eseguito questo comando:

$ acme.sh --renew --force --dns dns_cf --ocsp-must-staple --keylength 4096 -d rmazzu.com -d '*.rmazzu.com'