Differences between revisions 15 and 16
Revision 15 as of 2021-07-16 08:24:16
Size: 10948
Editor: Kurgan
Comment:
Revision 16 as of 2021-08-26 14:45:38
Size: 11615
Editor: Kurgan
Comment:
Deletions are marked like this. Additions are marked like this.
Line 96: Line 96:
        DocumentRoot /var/www/dovevuoitu
        
        # USARE UNA SOLA DELLE SEGUENTI DUE SOLUZIONI DI REDIRECT:

        # se ho un solo servername, questa richiede meno risorse ma l'hostname
        # a cui faccio redirect e` necessariamente hardcoded.
Line 97: Line 103:
        DocumentRoot /var/www/dovevuoitu
        # Se ho dei ServerAlias e voglio ridirigere ogni alias a se` stesso ma in https
        # allora uso questa al posto del redirectMatch di prima.
        # Ovviamente richiede mod-rewrite attivo
        <ifmodule mod_rewrite.c>
            RewriteEngine On
            RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
            RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
        </ifmodule>

Let's Encrypt - acme.sh

In origine c'era solo Let's Encrypt, poi sono nate altre CA più o meno gratuite che usano le stesse API per generare certificati. Ora il client acme.sh del quale si parla in questa pagina supporta diverse CA, e anzi, a partire dalla versione 3 ha passato il default da Let's Encrypt a ZeroSSL. È tuttavia possibile scegliere quale CA usare fra quelle supportate, vedi più sotto.

Installazione del client acme.sh

Il client acme.sh non e` il client ufficiale di Let's Encrypt, e` un client di terza parte che non richiede altro che bash e wget per girare. Puo` essere eseguito anche se non si e` root, pero` dovete ricordarvi che lo script deve poter scrivere dentro la vostra webroot (o accedere alle config del vostro dns) per funzionare.

  • Scaricare lo zip per l'installazione da https://github.com/Neilpang/acme.sh (o usare la copia locale qui allegata, pero` ovviamente questa e` vecchia acme.sh-master.zip)

  • Unzippare il pacchetto master.zip e portarsi dentro la directory dove avete appena unzippato la roba
  • eseguire l' installazione con il comando ./acme.sh install. Il risultato sara` che avete il vostro script dentro alla vostra home, sotto la directory .acme.sh/ e che in cron dell'utente dal quale avete installato verra` messa una chiamata a acme.sh per il rinnovo automatico dei certificati.

  • Dalla versione 3 acme.sh usa ZeroSSL e non Let's Encrypt come default tuttavia è facile fare in modo che torni a usare Let's Encrypt con il comando acme.sh --set-default-ca --server letsencrypt

Aggiormamento del client acme.sh

Il client, una volta installato, puo` essere aggiornato col comando acme.sh --upgrade. Puo` anche essere messo in auto-aggiornamento con il comando acme.sh --upgrade --auto-upgrade. Io pero` l'auto-aggiornamento lo eviterei.

Anno 2020 - 2021: Un aggiornamento da una versione molto vecchia di Acme.sh ad una molto recente potrebbe non funzionare: il client si aggiorna correttamente senza problemi ma i certificati potrebbero avere nelle loro configurazioni dei riferimenti alle API v1 di Let's Encrypt che non sono più in uso, quindi di fatto l'aggiornamento dei certificati potrebbe fallire. Del resto aggiornare acme.sh e usare le API v2 ora è necessario, quindi non potete evitare il problema semplicemente non aggiornando nulla. La soluzione è aggiornare il client, e poi è possibile modificare la configurazione dei singoli cert eliminando i riferimenti agli URL di Let's Encrypt e poi rinnovare, oppure più semplicemente ri-emettere da capo i certificati. Notare che dalla 3.0.0 Acme.sh usa ZeroSSL e non Let's Encrypt per default. Nel caso si voglia usare Let's Encrypt, si può dare questo comando per impostare il default prima di rinnovare / creare nuovi cert (una volta sola basta per sempre):

  • acme.sh --set-default-ca  --server  letsencrypt

Uso del client acme.sh

Per creare i certificati e` necessario un metodo di "autenticazione" del dominio, il piu` comodo per l'automatismo e` un web server che risponda all'hostname (www.dominio.tld, webmail.dominio.ltd, ecc) per il quale vogliamo generare il certificato. In pratica il sistema di Let's Encrypt deve poter scaricare un file dal vostro web server, file che viene generato da acme.sh. Questo significa anche che acme.sh deve poter scrivere nella webroot del vostro web server. (se lo eseguite da root, no problem)

Lo script salvera` i certificati generati, con anche le relative configurazioni, come ad esempio i comandi che lo script in cron deve eseguire per riavviare i demoni che usano i certificati in seguito al rinnovo degli stessi, nella home dell'utente sotto a .acme.sh/. Per comodita` insegno allo script acme.sh a copiare i certificati sotto a /etc/letsencrypt dove saranno a disposizione di tutti i demoni che devono usarli, avendo cura anche di concatenare i vari cert delle varie CA necessari per costruire la corretta catena di trust.

  • Creare il certificato (anche piu` di uno, ovviamente) Ricorda che la webroot deve coincidere con l'hostname (named virtual, nel caso), altrimenti la verifica automatica fallisce. In questo esempio l'hostname mater.kurgan.org non e` un named virtual, e non ha una webroot personale, ma usa il default /var/www (/var/www/html in certe installazioni di Apache, come ad esempio centos o debian 8)
     # acme.sh --issue  -d <hostname per il cert> -w <path webroot>
     acme.sh --issue  -d mater.kurgan.org -w /var/www/
  • Se vogliamo fare un certificato con diversi hostname, basta mettere piu` di una volta il parametro "-d hostname". Otterremo un certificato valido per tutti gli hostname (ad esempio, con e senza www).
  • Se vogliamo farne altri, non dobbiamo fare altro che ripetere il comando con i giusti parametri per hostname e webroot. Notare che tutti i cert che generiamo verranno automaticamente rinnovati dallo script in cron.
  • verificare in cron che ci sia il renew automatico (crontab -e)
  • creare la directory /etc/letsencrypt (o quella che volete voi, per metterci i certificati che poi vanno letto dai vari demoni che li usano)
  • eseguire il comando per mettere le chiavi dentro a /etc/letsencypt. Notare che questo comando salva i certificati dell'host e della CA concatenati (fullchain) e non il singolo certificato nel file "cer", per poter costruire la chain of trust corretta. Questo comando fra l'altro riavvia i demoni che usano i certificati. Una volta eseguito questo comando, al momento del rinnovo lo script in cron automaticamente eseguira` nuovamente questo comando, copiando i certificati e riavviando i demoni. All'atto pratico i parametri che passiamo a questo comando vengono salvati nella configurazione di acme.sh relativa all'hostname per questo certificato, ed eseguiti automaticamente ad ogni rinnovo.
    acme.sh --installcert -d mater.kurgan.org --keypath /etc/letsencrypt/mater.kurgan.org.key --fullchainpath /etc/letsencrypt/mater.kurgan.org.cert --reloadcmd "service exim4 reload; service apache2 reload; service dovecot reload"
  • modificare le config dei vari demoni (apache, exim, dovecot nell'esempio) per leggere i certificati dai files giusti.
  • ricaricare i vari demoni
  • verificare, dopo 80 giorni, se l'autorenew ha funzionato

Metodi alternativi di issue del certificato

Se per qualche motivo il metodo "classico" di scrivere un file nella webroot non dovesse essere disponibile, ci sono altri metodi per generare i certificati. Il motivo puo` essere per esempio che sul server non c'e` un web server, o che il web server e` configurato in modo da rendere difficile se non impossibile generare il certificato, per esempio perche` vogliamo un certificato con diversi hostname dentro, ma i diversi hostname puntano tutti a webroot diverse, oppure perche` il web server ha una configurazione con dei redirect o altre stranezze che impediscono al server di Let's Encrypt di leggere il suo file dal nostro web server, eccetera.

Nota bene: l'operazione di "issue" viene ripetuta automaticamente dal cron ogni 60 giorni. E` importante tenere conto che deve poter funzionare anche in seguito, non solo quando diamo il comando a mano per la prima volta

Il client acme.sh supporta diversi metodi, e vi consiglio di leggere la documentazione per vedere come funzionano. Ne cito tuttavia alcuni:

  • Standalone: se non abbiamo un web server, ma possiamo tenere la 80 o la 443) aperta, possiamo dire allo script di fare lui da web server, temporaneamente, per il tempo necessario a generare il certificato (e ad ogni rinnovo)
    acme.sh --issue  -d dominio.tld  --standalone
  • Apache: se abbiamo apache2, possiamo dire allo script di modificare la config di apache, fare la verifica, e rimetterla a posto. Questo crea ovviamente un piccolo disservizio e, potenzialmente, un disservizio lungo se lo script si incarta a meta` operazione e non rimette a posto la config di apache. (Esiste un modo equivalente per nginx)
    acme.sh --issue  -d dominio.tld --apache
  • DNS: Se abbiamo accesso al DNS, possiamo creare dei record TXT nella zona DNS del nostro dominio e usare quelli come verifica. E` piu` scomodo, ma una volta fatto ce ne possiamo dimenticare, e non abbiamo problemi di interferenza con Apache, Nginx, la porta 80, eccetera. Ci sono tre passaggi: creare una chiave, metterla nel dns (a mano) e poi fare l'effettiva emissione del certificato. I record TXT devono rimanere nel DNS per i futuri rinnovi.
    acme.sh --issue --dns -d dominio.tld
    # metti nel dns i record che vengono indicati
    acme.sh --renew -d dominio.tld

Config e test per Apache2

La configurazione minimale di Apache 2.2 e` questa:

SSLCertificateFile /etc/letsencrypt/mater.kurgan.org.cert
SSLCertificateChainFile /etc/letsencrypt/mater.kurgan.org.cert
SSLCertificateKeyFile /etc/letsencrypt/mater.kurgan.org.key

La configurazione minimale di Apache 2.4.8 o successivo non richiede piu` "SSLCertificateChainFile".

Attenzione: se si usa un redirect da http a https al momento del rinnovo questo fallirà a causa del redirect stesso.

Occorre usare un trucco per evitare il redirect per il file che viene usato per la verifica da let's encrypt. Questo trucco e` presto spiegato: usare un RedirectMatch "negato", ovvero dire ad Apache di ridirigere tutto TRANNE CHE la richiesta al file di "verifica" generato da letsencrypt. Ovviamente non usate "pippo.com", mettete una documentroot che esista, eccetera.

<VirtualHost *:80>
        ServerName www.pippo.com
        ServerAdmin email@pippo.com
        DocumentRoot /var/www/dovevuoitu 
        
        # USARE UNA SOLA DELLE SEGUENTI DUE SOLUZIONI DI REDIRECT:

        # se ho un solo servername, questa richiede meno risorse ma l'hostname
        # a cui faccio redirect e` necessariamente hardcoded.
        RedirectMatch 301 ^(?!/\.well-known/acme-challenge/).* https://www.pippo.com$0

        # Se ho dei ServerAlias e voglio ridirigere ogni alias a se` stesso ma in https
        # allora uso questa al posto del redirectMatch di prima. 
        # Ovviamente richiede mod-rewrite attivo
        <ifmodule mod_rewrite.c>
            RewriteEngine On
            RewriteCond %{REQUEST_URI} !^/\.well\-known/acme\-challenge/
            RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
        </ifmodule>

</VirtualHost>

<IfModule mod_ssl.c>
   <VirtualHost *:443>
        SSLEngine on
        SSLCertificateFile /etc/letsencrypt/hostname.cert
        SSLCertificateKeyFile /etc/letsencrypt/hostname.key
        ServerName hostname
        ServerAdmin webmaster@hostname
        DocumentRoot /var/www/dovevuoi
        ErrorLog ${APACHE_LOG_DIR}/hostname-error.log
        CustomLog ${APACHE_LOG_DIR}/hostname-access.log combined
    <IfModule mod_headers.c>
      Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
    </IfModule>
   </VirtualHost>
</IfModule>

Per testare se tutto funziona, potete usare questo servizio: https://www.ssllabs.com

Config per Dovecot

La configurazione minimale per Dovecot e`:

ssl_cert = </etc/letsencrypt/mater.kurgan.org.cert
ssl_key =  </etc/letsencrypt/mater.kurgan.org.key

Config per Exim 4

La configurazione minimale per Exim 4 e`:

tls_certificate = /etc/letsencrypt/mater.kurgan.org.cert
tls_privatekey =  /etc/letsencrypt/mater.kurgan.org.key
tls_advertise_hosts = *

LetsEncrypt (last edited 2023-01-17 09:10:04 by Kurgan)