Tijdens mijn inspanningen om de infrastructuur te verbeteren, besloot ik een oud en pijnlijk probleem op te lossen — zonder al te veel gedoe de mogelijkheid te bieden aan collega's (ontwikkelaars, testers, beheerders, etc.) om zelf hun virtuele machines in ovirt te beheren. In ovirt zijn er verschillende componenten die moeten worden ingesteld om dit probleem op te lossen: de webinterface zelf, de noVNC-console en het uploaden van schijfimages.
Ik heb de knop 'Maak Geweldig' niet gevonden, daarom laat ik zien welke handelingen ik heb uitgevoerd om deze taak op te lossen. De volledige instructie vind je hieronder:

DISCLAIMER:
Voordat ik begin, wil ik graag vermelden dat om voor mij onbekende redenen de domeinen van de infrastructuur worden aangemaakt in privé zones zoals lan, local, enzovoorts.
Wat de reden is om het domein van de organisatie niet in de publieke zone te gebruiken, is mij onbekend. Bijvoorbeeld, in plaats van het domein Alex-GLuck-Awesome-Company.local, kun je gerust het domein van de bedrijfswebsite Alex-GLuck-Awesome-Company.com gebruiken.
Als je bang bent dat je niet in staat bent om de domeinen in je organisatie te volgen en dat dit iets breekt, dan kun je voor een bescheiden bedrag van 100 roebel per jaar een apart domein voor de infrastructuur aglac.com verkrijgen.
Waarom het voordeliger is om domeinen in publieke zones te gebruiken:
1. Binnen je organisatie ontstaan er diensten die naar de publieke ruimte gaan: vpn, bestandsuitwisseling (seafile, nextcloud) en anderen. Het configureren van verkeer encryptie op dergelijke diensten lijkt meestal een rommeltje, en het is lastig om je te beschermen tegen MitM-aanvallen (dat is het eigenlijk niet).
Of binnen het kantoor heb je één adres voor de dienst, terwijl je vanuit het internet een ander hebt, en deze verbindingen moeten in stand worden gehouden, wat onze beperkte middelen kost. Bovendien moeten medewerkers verschillende adressen onthouden, wat onhandig is.
2. Je kunt gratis certificeringsinstellingen gebruiken voor het versleutelen van je interne diensten.
Eigen PKI is een dienst die moet worden onderhouden; 100 roebel per jaar voor de mogelijkheid om gebruik te maken van PKI van gratis certificeringsinstellingen betaalt zich ruimschoots terug in de tijd van medewerkers die dit anders aan andere taken zouden kunnen besteden.
3. Bij het gebruik van een eigen certificeringscentrum belemmert u uw externe medewerkers en collega's die willen werken met BYOD (breng uw eigen laptops, telefoons, tablets mee) en u kunt hun apparaten niet beheren. Ze brengen Macs, Linux, Android, iOS, Windows mee — het heeft totaal geen zin om zo'n zooitje te ondersteunen.
Er zijn natuurlijk uitzonderingen, en banken met andere zware ondernemingen die gevestigde beveiligingsbeleid hebben, zullen nooit in staat zijn om de service voor hun medewerkers te verbeteren.
Voor hen zijn er betaalde certificeringscentra die, tegen betaling, hun CA-certificaat kunnen ondertekenen (google ‘root signing service’).
Er zijn ook andere redenen waarom het voordeliger is om een openbare domein te gebruiken (het belangrijkste is dat het u toebehoort), maar dat is niet waar dit artikel over gaat.
De essentie, welnu...
LET OP! Als u het CA-certificaat van Let’s Encrypt toevoegt aan de vertrouwde lijst voor ovirt, kan dit invloed hebben op de beveiliging van uw systemen!
Het eerste waar u op moet letten — interfaces van ovirt blootstellen aan het internet is een slechte praktijk, omdat dit geen praktisch nut heeft en extra beveiligingsrisico's met zich meebrengt.
Daarom is het noodzakelijk om een certificaat te verkrijgen op een van onze bastion-hosts en vervolgens het certificaat en de sleutel naar onze host met ovirt-engine te verplaatsen.
Voeg het externe adres van onze bastion-host toe aan DNS met onze naam van ovirt. ovirtengine.example.com, de installatie van certbot en nginx laat ik buiten beschouwing (hoe dit te doen is al beschreven op Habr).
We configureren Nginx versie >=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;
# laat de server OCSP-responses bijvoegen, waardoor de laadtijd voor gebruikers korter wordt
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location / {
return 444;
}
}
Vervolgens verkrijgen we ons certificaat en sleutel:
certbot certonly --nginx -d ovirtengine.example.com
We archiveren ons certificaat en sleutel:
tar Phczf /tmp/ovirtengine.example.com.tgz /etc/letsencrypt/live/ovirtengine.example.com
We downloaden het archief van de bastion-host en uploaden het naar onze ovirt-engine:
scp bastion-host:/tmp/ovirtengine.example.com.tgz /tmp/
scp /tmp/ovirtengine.example.com.tgz ovirtengine.example.com:/
We gaan verder naar het doel
Daarna pakken we ons archief uit en maken we symbolische koppelingen voor een beter begrip van de bestandenstructuur:
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
We configureren de ingebouwde pki in ovirt, zodat de java trust store wordt gebruikt voor certificaatverificatie:
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
We converteren de CA van Let's Encrypt naar het der-formaat en voegen deze toe aan de java trust store van ovirt (dit is een container waarin een lijst van certificaten is opgeslagen, een systeem dat in java wordt gebruikt):
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
We edit SSL settings for Apache, adding a parameter to support symlinks and removing the parameter for CA used to verify certificates (by default, it will use the system's set of trusted CAs for verification):
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
After that, we back up the original files generated through PKI oVirt automatically, and replace them with symlinks to the files from 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
We restore SELinux contexts on the files and restart our services (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 — web servers kunt huren. apache
ovirt-engine — web interface of oVirt
ovirt-imageio-proxy — daemon for loading disk images
ovirt-websocket-proxy — service for using noVNC console
All the above has been tested on oVirt version 4.2.
Automatic certificate renewal on oVirt
According to good security practices, there should be no communication between the bastion host and oVirt, and the certificate is issued for only 3 months. Here comes the controversial point about how the certificate renewal is implemented.
I have an Ansible playbook that runs on Foreman daily at 5 AM as scheduled. This playbook logs into oVirt, checks the expiration date of the certificate, and if there are less than 5 days left before expiration, it goes to the bastion host and triggers the certificate renewal.
After renewing the certificate, it archives the folder with the files, downloads it to the Foreman host, and extracts it on the oVirt host. Then, it restores the SELinux contexts on the files and restarts our services.
Bron: habr.com
