Auf dem Weg zur Verbesserung der Infrastruktur habe ich beschlossen, eine alte und lästige Frage zu klären – ohne unnötige Umstände Kollegen (Entwicklern, Testern, Administratoren usw.) die Möglichkeit zu geben, ihre virtuellen Maschinen in Ovirt selbstständig zu verwalten. In Ovirt gibt es mehrere Komponenten, die konfiguriert werden müssen, um mein Anliegen zu lösen: die Weboberfläche selbst, die noVNC-Konsole und das Hochladen von Festplattendisk-Images.
Die Schaltflächen „Mach es großartig“ habe ich nicht gefunden, daher zeige ich, welche Einstellungen ich vorgenommen habe, um dieses Problem zu lösen. Eine vollständige Anleitung finden Sie weiter unten:

HAFTUNGSAUSSCHLUSS:
Vorab möchte ich darauf hinweisen, dass aus mir unbekannten Gründen die Infrastrukturdomänen in privaten Zonen wie lan, local usw. erstellt werden.
Mir ist unklar, was gegen die Verwendung der Organisationsdomäne in einer öffentlichen Zone spricht. Anstatt beispielsweise die Domäne Alex-GLuck-Awesome-Company.local zu verwenden, könnte man ohne Bedenken die Domäne für die Unternehmenswebsite Alex-GLuck-Awesome-Company.com verwenden.
Wenn Sie befürchten, dass Sie den Überblick über die Domänen in Ihrer Organisation verlieren und dies etwas kaputt macht, können Sie für bescheidene 100 Rubel im Jahr eine separate Domäne für die Infrastruktur aglac.com erwerben.
Warum es vorteilhafter ist, Domänen in öffentlichen Zonen zu verwenden:
1. Innerhalb Ihrer Organisation entstehen Services, die ins öffentliche Netz gehen: VPN, Dateiaustausch (seafile, nextcloud) und andere. Die Einrichtung der Traffic-Verschlüsselung auf solchen Services sieht in der Regel wie eine kurzsichtige Lösung aus, und gegen MitM sind wir nicht geschützt, weil es kompliziert ist (tatsächlich ist es das nicht).
Oder innerhalb des Büros haben Sie eine Adresse für den Service, und aus dem Internet eine andere, und diese Verbindungen müssen aufrechterhalten werden, was die begrenzten Ressourcen unserer Spezialisten beansprucht. Außerdem müssen sich die Mitarbeiter verschiedene Adressen merken, was unpraktisch ist.
2. Sie können kostenlose Zertifizierungsstellen für die Verschlüsselung Ihrer internen Services nutzen.
Eine eigene PKI ist ein Service, der aufrechterhalten werden muss. 100 Rubel im Jahr für die Nutzung von PKI aus kostenlosen Zertifizierungsstellen rechtfertigen sich durch die Zeit, die Mitarbeiter für andere Aufgaben aufwenden könnten.
3. Wenn Sie ein eigenes Zertifizierungszentrum verwenden, stellen Sie Ihren entfernten Mitarbeitern und Kollegen, die mit BYOD (Bring Your Own Device) arbeiten möchten, Hindernisse in den Weg, und Sie können deren Geräte nicht verwalten. Sie bringen Macs, Linux, Android, iOS, Windows - es macht keinen Sinn, einen solchen Zoo zu unterstützen.
Natürlich gibt es Ausnahmen, und Banken sowie andere große Unternehmen mit etablierten Sicherheitsrichtlinien werden ihren Mitarbeitern den Service niemals verbessern können.
Für sie gibt es kostenpflichtige Zertifizierungszentren, die gegen eine bestimmte Gebühr ihr CA-Zertifikat signieren können (googeln Sie "root signing service").
Es gibt auch andere Gründe, warum ein öffentlicher Domain wirtschaftlicher ist (das Wichtigste ist, dass er Ihnen gehört), aber darum geht es in diesem Artikel nicht.
Die Essenz und das Prinzip...
Achtung! Wenn Sie das CA-Zertifikat von Let’s Encrypt zur Liste der vertrauenswürdigen für ovirt hinzufügen, kann dies die Sicherheit Ihrer Systeme beeinträchtigen!
Das Erste, worauf man achten sollte, ist, dass die ovirt-Interfaces ins Internet auszustellen, eine schlechte Praxis ist, da dies keinen praktischen Sinn hat und zusätzliche Sicherheitsbedrohungen schafft.
Folglich müssen Sie das Zertifikat auf einem unserer Bastion-Hosts erhalten und dann das Zertifikat und den Schlüssel zu unserem Host mit ovirt-engine übertragen.
Fügen Sie die externe Adresse unseres Bastion-Hosts in den DNS mit unserem ovirt-Namen ein. ovirtengine.example.com, die Installation von certbot und nginx überlasse ich der Fantasie (wie man das macht, wurde bereits auf Habr beschrieben).
Konfigurieren Sie Nginx-Versionen >=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;
# Erlauben Sie dem Server, OCSP-Antworten anzuhängen, um die Ladezeit der Seiten für Benutzer zu verringern
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location / {
return 444;
}
}
Dann erhalten wir unser Zertifikat und unseren Schlüssel:
certbot certonly --nginx -d ovirtengine.example.com
Wir archivieren unser Zertifikat und unseren Schlüssel:
tar Phczf /tmp/ovirtengine.example.com.tgz /etc/letsencrypt/live/ovirtengine.example.com
Wir laden das Archiv vom Bastion-Host herunter und übertragen es auf unseren oVirt-Engine:
scp bastion-host:/tmp/ovirtengine.example.com.tgz /tmp/
scp /tmp/ovirtengine.example.com.tgz ovirtengine.example.com:/
Gehen wir zum Ziel
Anschließend entpacken wir unser Archiv und erstellen symbolische Links zur Vereinfachung des Verständnisses des Dateisystems:
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
Wir konfigurieren die integrierte PKI in oVirt, damit zur Überprüfung von Zertifikaten der Java-Zertifikatspeicher (openjdk) verwendet wird:
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
Wir konvertieren das CA von Let’s Encrypt in das DER-Format und fügen es dem Zertifikatspeicher des oVirt-Truststores hinzu (das ist ein Container, in dem die Liste der Zertifikate aufbewahrt wird, ein solches System wird in Java verwendet):
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
Wir bearbeiten die SSL-Einstellungen für Apache, fügen einen Parameter zur Unterstützung von Symlinks hinzu und entfernen den Parameter für CA, mit dem Zertifikate überprüft werden (standardmäßig wird das systemeigene Trusted CA-Bündel zur Überprüfung verwendet):
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
Anschließend sichern wir vorsichtshalber die Originaldateien, die automatisch über PKI von ovirt generiert wurden, und ersetzen sie durch Symlinks auf die Dateien von 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
Wir stellen die SElinux-Kontexte für die Dateien wieder her und starten unsere Dienste neu (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 — Webserver apache
ovirt-engine — Weboberfläche von ovirt
ovirt-imageio-proxy — Dienst zum Hochladen von Disk-Images
ovirt-websocket-proxy — Dienst für die Nutzung der noVNC-Konsole
Alles Vorhandene wurde mit der Version ovirt 4.2 überprüft.
Automatische Zertifikatserneuerung in ovirt
Laut guter Sicherheitspraktiken sollte keine Verbindung zwischen dem Bastion-Host und ovirt bestehen, und das Zertifikat wird nur für 3 Monate ausgestellt. Hier entsteht ein strittiger Punkt, wie das Update der Zertifikate bei mir umgesetzt wird.
Ich habe ein Ansible-Playbook, das täglich um 5 Uhr morgens nach Plan auf Foreman ausgeführt wird. Dieses Playbook geht auf ovirt, prüft das Ablaufdatum des Zertifikats, und wenn weniger als 5 Tage bis zur Ablauffristen verbleiben, geht es zum Bastion-Host und startet das Update des Zertifikats.
Nach der Zertifikatserneuerung wird der Ordner mit den Dateien archiviert, auf den Foreman-Host heruntergeladen und auf dem ovirt-Host entpackt. Danach werden die SElinux-Kontexte für die Dateien wiederhergestellt und unsere Dienste neu gestartet.
Quelle: habr.com
