Idąc drogą poprawy infrastruktury, postanowiłem rozwiązać starą i uciążliwą kwestię — bez zbędnych ruchów dać kolegom (programistom, testerom, administratorom itd.) możliwość samodzielnego zarządzania swoimi wirtualkami w oVirt. W oVirt jest kilka komponentów, które trzeba skonfigurować do rozwiązania mojego problemu: sam interfejs webowy, konsola noVNC oraz ładowanie obrazów dysków.
Nie znalazłem przycisków „Zrób super”, dlatego pokazuję, jakie dźwignie kręciłem, aby rozwiązać ten problem. Pełna instrukcja pod katem:

ZASTRZEŻENIE:
Przed rozpoczęciem chciałbym zwrócić uwagę, że z jakiegoś mi nieznanego powodu, domeny infrastruktury są tworzone w prywatnych strefach lan, local itd.
Czemu nie można używać domeny organizacji w publicznej strefie, nie wiem. Na przykład zamiast domeny Alex-GLuck-Awesome-Company.local, można śmiało używać domeny dla strony firmy Alex-GLuck-Awesome-Company.com.
Jeśli obawiasz się, że nie będziesz mógł śledzić domen w swojej organizacji i coś się popsuć, za skromne 100 zł rocznie możesz wziąć oddzielną domenę dla infrastruktury aglac.com.
Dlaczego korzystanie z domen w publicznych strefach jest korzystniejsze:
1. W Twojej organizacji pojawiają się usługi wychodzące w przestrzeń publiczną: VPN, wymiana plików (Seafile, Nextcloud) i inne. Konfiguracja szyfrowania ruchu na takich usługach zazwyczaj wygląda jak małe chaos, a chronić się przed MitM nie zamierzamy, ponieważ jest to trudne (w rzeczywistości nie jest).
Albo w biurze masz jeden adres usługi, a z internetu inny, i te połączenia muszą być utrzymywane, co wymaga naszych ograniczonych zasobów specjalistów. No i pracownicy muszą zapamiętać różne adresy, co jest niewygodne.
2. Możesz korzystać z darmowych centrów certyfikacji do szyfrowania swoich wewnętrznych usług.
Własny PKI — to usługa, którą trzeba utrzymywać, 100 zł rocznie za możliwość korzystania z PKI od darmowych centrów certyfikacji z nawiązką pokrywa czas pracowników, którzy mogliby go poświęcić na inne zadania.
3. Korzystając z własnego centrum certyfikacyjnego, znacznie utrudnisz życie swoim zdalnym pracownikom i współpracownikom, którzy chcą korzystać z BYOD (przyprowadzają własne laptopy, telefony, tablety) i nie możesz zarządzać ich urządzeniami. Przynoszą Maci, Linuksy, Androidy, iOS, Windows — nie ma sensu wspierać takiego zoo.
Oczywiście są wyjątki, a banki oraz inne surowe przedsiębiorstwa z ustalonymi politykami bezpieczeństwa nigdy nie będą w stanie poprawić usług dla swoich pracowników.
Dla nich istnieją płatne centra certyfikacji, które za określoną opłatą mogą podpisać ich certyfikat CA (wystarczy wpisać w wyszukiwarkę „usługa podpisywania root”).
Są też inne powody, dla których korzystanie z publicznej domeny jest bardziej opłacalne (najważniejsze, aby należała do Ciebie), ale to nie jest temat tego artykułu.
Sedno sprawy…
UWAGA! Jeśli dodasz certyfikat CA od Let’s Encrypt do zaufanych dla ovirt’a, może to wpłynąć na bezpieczeństwo twoich systemów!
Pierwszą rzeczą, na którą należy zwrócić uwagę, jest to, że wystawianie interfejsów ovirta w internecie to zła praktyka, ponieważ nie ma w tym żadnego praktycznego sensu, a wprowadza dodatkowe zagrożenia dla bezpieczeństwa.
W związku z tym należy uzyskać certyfikat na naszym bastionowym hoście, a następnie przenieść certyfikat i klucz na nasz host z ovirt-engine.
Dodajemy zewnętrzny adres naszego bastionowego hosta do DNS z naszym imieniem ovirt’a. ovirtengine.example.com, instalację certbota i nginx pozostawię poza kadrem (jak to zrobić opisano już na Habrze).
Konfigurujemy nginx w wersji >=1.15.7
/etc/nginx/conf.d/default.conf
serwer {
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;
}
}
serwer {
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;
# zezwalamy serwerowi na dołączanie odpowiedzi OCSP, co zmniejsza czas ładowania stron u użytkowników
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location / {
return 444;
}
}
Następnie otrzymujemy nasz certyfikat i klucz:
certbot certonly --nginx -d ovirtengine.example.com
Archiwujemy nasz certyfikat i klucz:
tar Phczf /tmp/ovirtengine.example.com.tgz /etc/letsencrypt/live/ovirtengine.example.com
Pobieramy z hosta-bastionu archiwum, przenosimy na nasz ovirt-engine:
scp bastion-host:/tmp/ovirtengine.example.com.tgz /tmp/
scp /tmp/ovirtengine.example.com.tgz ovirtengine.example.com:/
Przechodzimy do celu
Następnie rozpakowujemy nasze archiwum i tworzymy dowiązania symboliczne dla lepszego zrozumienia systemu lokalizacji plików:
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
Konfigurujemy wbudowane pki w ovirt, aby do weryfikacji certyfikatów używało magazynu certyfikatów java(openjdk):
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
Konwertujemy CA od let’s encrypt’a na format der i dodajemy do magazynu certyfikatów java trust store ovirt (to kontener, w którym przechowywana jest lista certyfikatów, taka systema jest używana w 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
Edytujemy ustawienia SSL dla apache, dodajemy parametr do obsługi symlinków i usuwamy parametr dla CA, którym będą sprawdzane certyfikaty (domyślnie będzie używać systemowego zestawu zaufanych CA do sprawdzania):
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
Następnie na wszelki wypadek kopiujemy oryginalne pliki, wygenerowane przez PKI ovirta automatycznie, i zastępujemy je symlinkami do plików od 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
Przywracamy konteksty SELinux na plikach i restartujemy nasze usługi (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 — serwer www apache
ovirt-engine — interfejs webowy ovirt
ovirt-imageio-proxy — demon do ładowania obrazów dysków
ovirt-websocket-proxy — usługa do obsługi konsoli noVNC
Wszystko powyższe zostało sprawdzone na wersji ovirta 4.2.
Automatyczne aktualizacje certyfikatów na ovirt
Zgodnie z dobrymi praktykami bezpieczeństwa nie powinno być połączeń między bastion-hostem a ovirtem, a certyfikat jest wydawany tylko na 3 miesiące. Tutaj pojawia się kontrowersyjna sprawa dotycząca tego, jak zrealizowana jest aktualizacja certyfikatów u mnie.
Mam playbook Ansible, który uruchamia się codziennie o 5 rano na foreman. Ten playbook loguje się do ovirta, sprawdza datę ważności certyfikatu i jeśli do wygaśnięcia pozostało mniej niż 5 dni, idzie na bastion-host i uruchamia aktualizację certyfikatu.
Po zaktualizowaniu certyfikatu archiwizuje folder z plikami, ściąga na hosta foremana i rozpakowuje na hoście ovirta. Następnie przywraca konteksty SELinux na plikach i restartuje nasze usługi.
Źródło: habr.com
