Come integrare Ovirt e Let’s Encrypt

Intraprendendo il cammino per migliorare l'infrastruttura, ho deciso di risolvere una questione antica e fastidiosa: fornire senza complicazioni ai colleghi (sviluppatori, tester, amministratori, ecc.) la possibilità di gestire autonomamente le proprie macchine virtuali in ovirt. In ovirt ci sono diversi componenti da configurare per risolvere questa questione: l'interfaccia web stessa, la console noVNC e il caricamento delle immagini dei dischi.

Non ho trovato il pulsante "Fallo Bene", quindi mostro quali impostazioni ho modificato per risolvere questo compito. La guida completa è sotto il tag:

Come collegare Ovirt e Let's Encrypt

DISCLAIMER:

Prima di iniziare, vorrei attirare l'attenzione sul fatto che, per qualche motivo a me sconosciuto, i domini dell'infrastruttura vengono creati nelle zone private lan, local, ecc.

Non so cosa impedisca di utilizzare il dominio dell'organizzazione in una zona pubblica. Ad esempio, anziché il dominio Alex-GLuck-Awesome-Company.local, si può tranquillamente utilizzare il dominio per il sito dell'azienda Alex-GLuck-Awesome-Company.com.

Se hai paura di non riuscire a tenere traccia dei domini nella tua organizzazione e che ciò possa causare problemi, per una modesta cifra di 100 rubli all'anno puoi acquistare un dominio separato per l'infrastruttura aglac.com.

Perché è vantaggioso utilizzare domini in zone pubbliche:

1. All'interno della vostra organizzazione sorgono servizi che escono nello spazio pubblico: vpn, condivisione di file (seafile, nextcloud) e altro. Configurare la crittografia del traffico su tali servizi di solito appare come un lavoro approssimativo, e non ci proteggeremo da MitM, perché è complicato (in realtà non lo è).

Oppure, all'interno dell'ufficio avete un indirizzo del servizio, mentre dall'esterno ce n'è un altro, e questi collegamenti devono essere mantenuti, il che consuma le nostre risorse limitate di specialisti. Inoltre, ai dipendenti viene chiesto di ricordare diversi indirizzi, cosa scomoda.

2. Potete utilizzare centri di certificazione gratuiti per crittografare i vostri servizi interni.

Un PKI proprio è un servizio che deve essere mantenuto; 100 rubli all'anno per la possibilità di usare un PKI dai centri di certificazione gratuiti ripagano benissimo il tempo dei dipendenti, che altrimenti potrebbero dedicare ad altri compiti.

3. Utilizzando un proprio centro di certificazione, metterete i bastoni tra le ruote ai vostri collaboratori e colleghi remoti, che desiderano lavorare con BYOD (bring your own device — portano i propri laptop, telefoni, tablet) e non potete gestire i loro dispositivi. Portano Mac, Linux, Android, iOS, Windows: mantenere un tale zoo non ha alcun senso.

Naturalmente ci sono delle eccezioni, e le banche con altre grandi aziende rigorose, che hanno politiche di sicurezza consolidate, non potranno mai migliorare il servizio per i loro dipendenti.

Per loro ci sono centri di certificazione a pagamento, che, per una certa somma, possono firmare il loro certificato CA (cercate 'root signing service').

Ci sono anche altri motivi per cui utilizzare un dominio pubblico è più vantaggioso (la cosa più importante è che appartenga a voi), ma questo articolo non è focalizzato su questo.

Il punto è...

ATTENZIONE! Se aggiungete il certificato CA di Let’s Encrypt all'elenco dei certificati attendibili per oVirt, questo potrebbe influenzare la sicurezza dei vostri sistemi!

Il primo aspetto da considerare è che esporre le interfacce oVirt su Internet è una cattiva pratica, poiché non ha alcun senso pratico e crea ulteriori minacce alla sicurezza.

Pertanto, è necessario ottenere un certificato su uno dei nostri bastion host, per poi trasferire il certificato e la chiave sul nostro host con oVirt Engine.

Aggiungiamo l'indirizzo esterno del nostro bastion host nel DNS con il nostro nome oVirt. ovirtengine.example.com, l'installazione di certbot e nginx la lascerò fuori dal contesto (come fare questo è già stato descritto su Habr).

Configuriamo Nginx versione >=1.15.7

/etc/nginx/conf.d/default.conf

server {
    server_name _;
    listen 80 default_server;
    location /robots.txt { alias /usr/share/nginx/html/robots.txt; }
    location /.well-known {
        root /usr/share/nginx/html;
    }
    location / {
        return 444;
    }
}

server {
    server_name _;
    listen 443 ssl http2 default_server;
    location /robots.txt { alias /usr/share/nginx/html/robots.txt; }
    location /.well-known {
        root /usr/share/nginx/html;
    }

    ssl_certificate /etc/nginx/ssl/$ssl_server_name/fullchain.pem; 
    ssl_certificate_key /etc/nginx/ssl/$ssl_server_name/privkey.pem;

    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;

    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;

    # Permettiamo al server di allegare risposte OCSP, riducendo così i tempi di caricamento delle pagine per gli utenti
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header Strict-Transport-Security max-age=15768000;

    location / {
        return 444;
    }
}

Poi otteniamo il nostro certificato e la chiave:

certbot certonly --nginx -d ovirtengine.example.com

Archivia il nostro certificato e chiave:

tar Phczf /tmp/ovirtengine.example.com.tgz /etc/letsencrypt/live/ovirtengine.example.com

Scarichiamo l'archivio dall'host bastione e lo carichiamo sul nostro ovirt-engine:

scp bastion-host:/tmp/ovirtengine.example.com.tgz /tmp/
scp /tmp/ovirtengine.example.com.tgz ovirtengine.example.com:/

Procediamo verso la destinazione

Successivamente, estraiamo il nostro archivio e creiamo collegamenti simbolici per semplificare la comprensione della posizione dei file:

tar Pxzf /ovirtengine.example.com.tgz && rm -f ovirtengine.example.com.tgz
mkdir -p /etc/letsencrypt/live
ln -f -s /etc/letsencrypt/live /etc/pki/letsencrypt

Configuriamo il PKI integrato in ovirt affinché utilizzi il keystore di certificati Java (openjdk) per la verifica dei certificati:

cat < /etc/ovirt-engine/engine.conf.d/99-setup-pki.conf 
ENGINE_HTTPS_PKI_TRUST_STORE="/etc/pki/java/cacerts"
ENGINE_HTTPS_PKI_TRUST_STORE_PASSWORD=""
EOF

Convertiamo il CA di Let’s Encrypt nel formato DER e lo aggiungiamo al keystore di certificati Java trust store di ovirt (questo è un contenitore che contiene l'elenco dei certificati, un sistema utilizzato in Java):

openssl x509 -outform der -in /etc/pki/letsencrypt/ovirtengine.example.com/chain.pem -out /tmp/ovirtengine.example.com.chain.der
keytool -import -alias "Let's Encrypt Authority X3" -file /tmp/ovirtengine.example.com.chain.der -keystore /etc/pki/ovirt-engine/.truststore -storepass $(grep '^ENGINE_PKI_TRUST_STORE_PASSWORD' /etc/ovirt-engine/engine.conf.d/10-setup-pki.conf | cut -f 2 -d '"')
rm -f /tmp/ovirtengine.example.com.chain.der

Modifichiamo le impostazioni SSL per Apache, aggiungiamo un parametro per supportare i symlink e rimuoviamo il parametro per il CA che verifica i certificati (per impostazione predefinita utilizzerà l'insieme di CA affidabili del sistema per la verifica):

sed -r -i 's|^(SSLCACertificateFile.*)|#1|g' /etc/httpd/conf.d/ssl.conf
sed -r -i '0,/^(#?SSLCACertificateFile.*)/ s//1nOptions FollowSymlinks/' /etc/httpd/conf.d/ssl.conf

Dopo di che facciamo un backup, per sicurezza, dei file originali generati automaticamente tramite PKI oVirt e sostituiamo i symlink con i file di Let's Encrypt:

ln -f -s /etc/pki/letsencrypt/ovirtengine.example.com/fullchain.pem /etc/pki/ovirt-engine/apache-chain.pem
services=( 'apache' 'imageio-proxy' 'websocket-proxy' )
for i in "${services[@]}"; do
cp /etc/pki/ovirt-engine/certs/$i.cer{,."$( date +%F )".bak}
cp /etc/pki/ovirt-engine/keys/$i.key.nopass{,."$( date +%F )".bak}
ln -f -s /etc/pki/letsencrypt/ovirtengine.example.com/privkey.pem /etc/pki/ovirt-engine/keys/$i.key.nopass
ln -f -s /etc/pki/letsencrypt/ovirtengine.example.com/cert.pem /etc/pki/ovirt-engine/certs/{apache,imageio-proxy,websocket-proxy}.cer
done

Ripristiniamo i contesti SElinux sui file e riavviamo i nostri servizi (httpd, ovirt-engine, ovirt-imageio-proxy, ovirt-websocket-proxy):

restorecon -Rv /etc/pki
systemctl restart httpd ovirt-engine ovirt-imageio-proxy ovirt-websocket-proxy

httpd — server web apache
ovirt-engine — interfaccia web di ovirt
ovirt-imageio-proxy — demone per il caricamento delle immagini dei dischi
ovirt-websocket-proxy — servizio per l'uso della console noVNC

Tutto quanto sopra è stato testato sulla versione di Ovirt 4.2.

Aggiornamento automatico dei certificati su Ovirt

Secondo le buone pratiche di sicurezza, non ci dovrebbe essere comunicazione tra l'host bastione e Ovirt, e il certificato viene rilasciato solo per 3 mesi. Qui si presenta un punto controverso su come è implementato l'aggiornamento dei certificati da parte mia.

Ho un playbook di Ansible che viene eseguito su Foreman ogni giorno alle 5 del mattino secondo un programma. Questo playbook accede a Ovirt, controlla la scadenza del certificato e se mancano meno di 5 giorni alla scadenza, si collega all'host bastione e avvia l'aggiornamento del certificato.

Dopo l'aggiornamento del certificato, archivia la cartella con i file, scarica su Foreman e decomprime sull'host di Ovirt. Dopodiché ripristina i contesti SElinux sui file e riavviamo i nostri servizi.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster