Gestione di certificati SSL per Apache con letsencrypt

From RVM Wiki
Jump to navigation Jump to search


  • Vogliamo installare un certificato ssl con
CNAME= www.example.com
ALTN: webmail.example.com
  • Il sito è servito da un webserver apache, con webroot in
/var/www/example.com/www/html/

Procedura con dehydrated

Configurazione di Apache

  • Per verificare l'attendibilità della richiesta, il server di Letsencrypt cercherà di reperire il files di verifica all'url
http://www.example.com/.well-known/acme-challenge/
  • Quindi bisogna creare questa risorsa sul server apache in HTTP non in https, dove dovranno essere posizionati ifiles di verifica creati da letsencrypt.sh

Definizione location di validazione challenge

  • You need to make sure that all (sub-)domains that you want to sign have access to this directory! That includes rewrites etc.
  • The acme validation is done only using plain http and will not honour redirects etc.
    RewriteEngine   on
    RewriteRule     ^/.well-known/acme-challenge/ - [L]
    RewriteCond     %{SERVER_PORT} ^80$
    RewriteRule     ^/(.*) https://%{SERVER_NAME}/$1 [L,R]
  • Verificare l'accessibilità in HTTP (NON in https)) del'url

http://www.example.com/.well-known/acme-challenge/

Per apache 2.4

sudoedit /etc/apache2/conf-available/letsencrypt.conf
<Directory "/etc/letsencrypt.sh/.well-known/acme-challenge/">
   Options None
   AllowOverride None
   Require all granted
   Header add Content-Type text/plain
</Directory>

Alias /.well-known/acme-challenge/ /etc/letsencrypt.sh/.well-known/acme-challenge/
sudo a2enconf  letsencrypt

Per apache 2.2

sudoedit /etc/apache2/conf.d/letsencrypt.conf
<Directory "/etc/dehydrated/.well-known/acme-challenge/">
    Options None
    AllowOverride None
    Order deny,allow
    Allow from all
</Directory>

Alias /.well-known/acme-challenge/ /etc/dehydrated/.well-known/acme-challenge/

Installazione

Installazione con pacchetto RVM

sudo apt-get install dehydrated

Installazione da sorgente

  • Creare uno user di sistema apposito
sudo adduser --system --force-badname letsencrypt.sh
  • Creare le directories necessarie:
sudo mkdir -p  /etc/letsencrypt.sh/{hooks,cron,config.d,.well-known/acme-challenge/}
sudo touch /etc/letsencrypt.sh/config.d/dummy.sh
sudo chown -R letsencrypt.sh  /etc/letsencrypt.sh
  • Installare le dipendenze:
sudo apt-get install curl openssl
  • Installare l'eseguibile:
cd /tmp
git clone https://github.com/lukas2511/letsencrypt.sh.git
sudo mkdir -p /usr/local/bin/
sudo cp letsencrypt.sh/letsencrypt.sh /usr/local/bin/
  • Riavviare apache e testare se la directory sia servita:
sudo systemctl restart apache2.service
wget -O - http://www.example.com/.well-known/acme-challenge/


  • Creare il wrapper che sarà eseguito da cron per rinnovare i certificati:
sudoedit cron/dehydrated.cron
#!/bin/bash

cd /etc/dehydrated
/usr/local/bin/dehydrated --cron
  • Renderlo eseguibile:
sudo chmod +x cron/dehydrated.cron
  • Sistemare i diritti dei files creati:
 sudo chown -R dehydrated  /etc/dehydrated
  • Creare il file di cron
sudoedit /etc/cron.d/letsencrypt
01 11 * * * dehydrated /etc/dehydrated/cron/dehydrated.cron > /dev/null

Configurazione

  • Modificare la configurazione:
cd /etc/dehydrated/
sudoedit config
CONFIG_D=/etc/dehydrated/config.d
BASEDIR=/etc/dehydrated
WELLKNOWN="/etc/dehydrated/.well-known/acme-challenge/"
CONTACT_EMAIL=admin@example.com
  • Creare il file contenente i certificati da richiedere
cd /etc/dehydrated
sudoedit domains.txt
www.example.com example.com
  • Testarlo:
sudo -u dehydrated /etc/dehydrated/cron/dehydrated.cron
  • Se tutto funziona, i certificati saranno in
/etc/dehydrated/certs/www.example.com/
privkey.pem è la private key
fullchain.pem è il certificato concatenato con le CA
cert.pem è il certificato standalone

Configurazione del Virtualhost HTTPS

  • I certificati verranno utilizzati in apache come:
SSLCertificateKeyFile /etc/dehydrated/certs/www.example.com/privkey.pem
SSLCertificateFile    /etc/dehydrated/certs/www.example.com/fullchain.pem
SSLCertificateChainFile /etc/dehydrated/certs/www.example.com/fullchain.pem
  • Riavviare Apache e testare l'accesso in HTTPS:
sudo /etc/init.d/apache2 restart

Copia manuale dei certificati

  • Copiamo i certificati manualmente per essere usati da Apache:
sudo cp -i /etc/dehydrated/certs/www.example.com/fullchain.pem /etc/ssl/certs/www.example.com.crt
sudo cp -i /etc/dehydrated/certs/www.example.com/privkey.pem   /etc/ssl/private/www.example.com.key
  • Installare la CA:
sudo cp -i /etc/dehydrated/certs/www.example.com/chain.pem /usr/local/share/ca-certificates/letsencrypt.org.crt
sudo update-ca-certificates
  • Verificare che sia presente:
ls /etc/ssl/certs/letsencrypt.org.pem
lrwxrwxrwx 1 root root 52 Feb 29 10:16 /etc/ssl/certs/letsencrypt.org.pem -> /usr/local/share/ca-certificates/letsencrypt.org.crt
  • La definzione dei certificati sarà quindi:
SSLCertificateKeyFile /etc/ssl/private/www.example.com.key
SSLCertificateFile    /etc/ssl/certs/www.example.com.crt
SSLCertificateChainFile /etc/ssl/certs/www.example.com.crt

Script di deploy dei certificati

  • Ora dehydrated provvederà rinnovare il certificato quando avrà meno di 30 giorni di validità. Dobbiamo implementare il meccanismo con cui i certificati vengono ricaricati in Apache al loro rinnovo
  • Se si sono dichiarati i certificti nella posizione standard /etc/ssl, allora i certificati dovranno essere spostati nelle relative directory sotto /etc/ssl
  • Creiamo un altro script, che dovrà esere eseguito come root, che confronta i certificati in uso con quelli
sudoedit /etc/letsencrypt.sh/hooks/deploy.sh
#!/bin/bash
#
# MUST BE RUN AS ROOT
#

BASEDIR="/etc/letsencrypt.sh"
SSLDIR="/etc/ssl"

CERTS=$(/bin/ls -x ${BASEDIR}/certs/)

for CERT in $CERTS
do
	# Check if the certificate has changed
  	if !(diff -q ${BASEDIR}/certs/${CERT}/fullchain.pem ${SSLDIR}/certs/${CERT}.crt > /dev/null)
	then
		echo "Certificate for ${CERT} has been renewed."
		cp -L "${BASEDIR}/certs/${CERT}/privkey.pem"   "${SSLDIR}/private/${CERT}.key"
		cp -L "${BASEDIR}/certs/${CERT}/fullchain.pem" "${SSLDIR}/certs/${CERT}.crt"
		chmod 400 "${SSLDIR}/private/${CERT}.key"
		chmod 644 "${SSLDIR}/certs/${CERT}.crt"

		# Restart relevant services
		#  [[ "${jail}" = "http" ]] && jexec ${jail} service apache24 restart
	  	#[[ "${jail}" = "mail" ]] && jexec ${jail} service smtpd    restart
		/etc/init.d/apache2 restart > /dev/null

		# Clean up old keys and certs
		sudo -u letsencrypt.sh /usr/local/bin/letsencrypt.sh --cleanup > /dev/null
	fi
done
  • Renderlo eseguibile, e testarlo: non deve fare nulla:
sudo chmod a+x /etc/letsencrypt.sh/hooks/deploy.sh
sudo /etc/letsencrypt.sh/hooks/deploy.sh
  • Impostarne l'esecuzione COME ROOT subito dopo il lancio di letsencrypt. Attenzione: viene usato sudo nello script:
sudoedit /etc/cron.d/letsencrypt
11 11 * * * root            /etc/letsencrypt.sh/hooks/deploy.sh

Riferimenti

Procedura con acme-tiny

Attenzione questo articolo è ancora incompleto.
Sentiti libero di contribuire cliccando sul tasto edit.
 openssl req -new -sha256 -key domain.key -subj "/CN=www.rvmgroup.it" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:www.rvmgroup.it,DNS:support.rvmgroup.it,DNS:smtp.rvmgroup.it,DNS:webmail.rvmgroup.it")) |sudo tee domain.csr

 openssl req -in domain.csr -text -noout

 sudo python /opt/acme-tiny/acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/rvmgroup.it/www/html/.well-known/acme-challenge/ | sudo tee ./signed.crt

 openssl x509 -in signed.crt -text -noout

 wget -O - https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem | sudo tee intermediate.pem

 cat signed.crt intermediate.pem | sudo tee chained.pem