Caminando por el camino de la mejora de la infraestructura, decidí resolver una antigua y dolorosa cuestión: sin gestos innecesarios, brindar a los colegas (desarrolladores, evaluadores, administradores, etc.) la oportunidad de administrar de forma independiente sus máquinas virtuales en ovirt. Ovirt tiene varios componentes que deben configurarse para resolver mi problema: la interfaz web en sí, la consola noVNC y la carga de imágenes de disco.
No encontré el botón "Make It Bad", así que les muestro qué perillas giré para resolver este problema. Instrucciones completas debajo del corte:

EXENCIÓN DE RESPONSABILIDADES:
Antes de comenzar, me gustaría llamar su atención sobre el hecho de que, por alguna razón que desconozco, los dominios de infraestructura se crean en zonas privadas LAN, locales, etc.
No sé qué me impide utilizar el dominio de una organización en una zona pública. Por ejemplo, en lugar del dominio Alex-GLuck-Awesome-Company.local, puede utilizar de forma segura el dominio del sitio web de la empresa Alex-GLuck-Awesome-Company.com.
Si tiene miedo de no poder realizar un seguimiento de los dominios de su organización y esto romperá algo, entonces por unos modestos 100 rublos al año puede comprar un dominio separado para la infraestructura aglac.com.
Por qué es más rentable utilizar dominios en zonas públicas:
1. Su organización cuenta con servicios de acceso público: vpn, intercambio de archivos (seafile, nextcloud) y otros. Configurar el cifrado de tráfico en estos servicios suele ser un poco improvisado, y no nos defenderemos de ataques MitM porque es difícil (en realidad, no).
O tiene una dirección de servicio dentro de la oficina y otra de Internet, y es necesario mantener estas conexiones, lo que desperdicia nuestros limitados recursos especializados. Bueno, los empleados tienen que recordar diferentes direcciones, lo cual es un inconveniente.
2. Puede utilizar autoridades certificadoras gratuitas para cifrar sus servicios internos.
Su propia PKI es un servicio que necesita apoyo: 100 rublos al año por la oportunidad de utilizar PKI de las autoridades de certificación gratuitas pagan con creces el tiempo de los empleados que podrían dedicarlo a otras tareas.
3. Al utilizar su propia autoridad de certificación, pondrá un freno a sus empleados y colegas remotos que quieran trabajar con BYOD (traigan sus propias computadoras portátiles, teléfonos, tabletas) y no podrá administrar sus dispositivos. Traen Mac, Linux, Android, iOS, Windows; no tiene sentido apoyar un zoológico así.
Por supuesto, en todo hay excepciones, y los bancos con otras empresas duras que han establecido políticas de seguridad nunca podrán mejorar el servicio a sus empleados.
Para ellos, existen autoridades de certificación pagas que pueden firmar su certificado de CA por una determinada cantidad (el “servicio de firma raíz” de Google).
Hay otras razones por las que es más rentable utilizar un dominio público (lo más importante es que te pertenezca), pero este artículo no trata de eso.
La cuestión es...
¡ATENCIÓN! Si agrega un certificado CA de Let's Encrypt a la lista de confianza de ovirt, ¡puede afectar la seguridad de sus sistemas!
Lo primero a lo que hay que prestar atención es que exponer las interfaces de Ovirt a Internet es una mala práctica, porque Esto no tiene sentido práctico y crea amenazas de seguridad adicionales.
Por lo tanto, debe obtener un certificado en uno de nuestros hosts bastión y luego transferir el certificado y la clave a nuestro host con ovirt-engine.
Agregamos la dirección externa de nuestro host bastión al dns con nuestro nombre ovirt ovirtengine.ejemplo.com, Dejaré la instalación de certbot y nginx detrás de escena (ya se describe cómo hacerlo en Habré).
Configurando la versión de njinx >=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;
# позволяем серверу прикреплять OCSP-ответы, тем самым уменьшая время загрузки страниц у пользователей
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location / {
return 444;
}
}
Luego obtenemos nuestro certificado y clave:
certbot certonly --nginx -d ovirtengine.example.com
Archivar nuestro certificado y clave:
tar Phczf /tmp/ovirtengine.example.com.tgz /etc/letsencrypt/live/ovirtengine.example.com
Descargue el archivo del host bastión y cárguelo en nuestro motor ovirt:
scp bastion-host:/tmp/ovirtengine.example.com.tgz /tmp/
scp /tmp/ovirtengine.example.com.tgz ovirtengine.example.com:/
Pasemos a la meta
A continuación, descomprimimos nuestro archivo y creamos enlaces simbólicos para simplificar la comprensión del sistema de ubicación de archivos:
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
Configuramos el pki integrado en Ovirt para que se utilice el almacén de certificados de Java (openjdk) para verificar los certificados:
cat << EOF > /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
Convertimos la CA de let's encrypt al formato der y la agregamos al almacén de certificados del almacén de confianza de ovirt java (este es un contenedor que contiene una lista de certificados, dicho sistema se usa en 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
Editamos la configuración de SSL para Apache, agregamos un parámetro para admitir enlaces simbólicos y eliminamos el parámetro de la CA con la que verificar los certificados (de forma predeterminada, se utilizará el conjunto del sistema de CA confiables para la verificación):
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
Luego, por si acaso, hacemos una copia de seguridad de los archivos originales generados a través de la PKI automática de ovirt y los reemplazamos con enlaces simbólicos con archivos de 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
Restauramos los contextos de SElinux en los archivos y reiniciamos nuestros servicios (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 — servidor web apache
ovirt-engine - interfaz web de ovirt
ovirt-imageio-proxy - demonio para descargar imágenes de disco
ovirt-websocket-proxy: servicio para ejecutar la consola noVNC
Todo lo anterior fue probado en la versión 4.2 de Ovirt.
Renovación automática de certificados en ovirt
Según las buenas prácticas de seguridad, no debe haber conexión entre el host bastión y el ovirt, y el certificado se emite solo por 3 meses. Aquí surge un tema controvertido sobre cómo implementé la renovación de certificados.
Tengo un libro de jugadas ansible que se ejecuta en Foreman todos los días a las 5 am según un horario. Este libro de jugadas va al ovirt, verifica el período de validez del certificado y, si quedan menos de 5 días antes del vencimiento, va al host bastión y comienza a actualizar el certificado.
Después de actualizar el certificado, archiva la carpeta con archivos, la descarga en el host de Forman y la descomprime en el host de Ovirt. Después de lo cual SElinux restaura los contextos de los archivos y reinicia nuestros servicios.
Fuente: habr.com
