Ao avançar no caminho da melhoria da infraestrutura, decidi resolver uma questão antiga e complicada — fornecer, sem grandes esforços, a meus colegas (desenvolvedores, testadores, administradores, etc.) a possibilidade de gerenciar suas máquinas virtuais no ovirt de forma autônoma. No ovirt, há vários componentes que precisam ser configurados para resolver minha questão: a própria interface web, o console noVNC e o upload de imagens de disco.
Não encontrei botões de "Fazer Incrível", então estou mostrando quais configurações fiz para resolver essa tarefa. Instruções completas a seguir:

AVISO LEGAL:
Antes de começar, gostaria de chamar a atenção para o fato de que, por uma razão que desconheço, os domínios da infraestrutura são criados em zonas privadas como lan, local, entre outras.
Não sei o que impede o uso do domínio da organização em uma zona pública. Por exemplo, em vez do domínio Alex-GLuck-Awesome-Company.local, você pode usar sem problemas o domínio do site da empresa Alex-GLuck-Awesome-Company.com.
Se você tem medo de não conseguir monitorar os domínios na sua organização e que isso possa causar problemas, pode adquirir um domínio separado para a infraestrutura por apenas 100 rublos por ano, como aglac.com.
Por que é mais vantajoso usar domínios em zonas públicas:
1. Você terá serviços internos que se conectam ao espaço público: vpn, compartilhamento de arquivos (seafile, nextcloud) e outros. Configurar a criptografia do tráfego nesses serviços geralmente parece ser uma solução improvisada, e não vamos nos proteger contra MitM, pois isso é difícil (na verdade, não é).
Ou, dentro do escritório, você tem um endereço de serviço, enquanto pela internet é outro, e essas conexões precisam ser mantidas, o que consome nossos recursos limitados de especialistas. Além disso, os funcionários precisam lembrar endereços diferentes, o que é inconveniente.
2. Você pode utilizar centros de certificação gratuitos para criptografar seus serviços internos.
Uma PKI própria — é um serviço que precisa ser mantido, e 100 rublos por ano pela utilização de PKI de centros de certificação gratuitos compensam amplamente o tempo dos funcionários que poderiam estar dedicando a outras tarefas.
3. Ao usar seu próprio centro de certificação, você estará dificultando o trabalho de seus funcionários remotos e colegas que desejam trabalhar com BYOD (trazendo seus próprios laptops, telefones, tablets), e você não consegue gerenciar seus dispositivos. Eles trazem Macs, Linux, Android, iOS, Windows — não há sentido em suportar esse zoológico.
Claro, existem exceções, e bancos com outras empresas robustas que possuem políticas de segurança estabelecidas nunca conseguirão melhorar o serviço para seus colaboradores.
Para eles, existem centros de certificação pagos, que, por uma certa quantia, podem assinar seu certificado CA (pesquise 'root signing service' no Google).
Existem outras razões pelas quais o uso de um domínio público é mais vantajoso (a principal é que ele deve pertencer a você), mas este artigo não é sobre isso.
A essência, na verdade...
ATENÇÃO! Se você adicionar um certificado CA da Let's Encrypt à lista de certificados confiáveis do ovirt, isso pode afetar a segurança de seus sistemas!
A primeira coisa a se atentar é que expor as interfaces do ovirt na internet é uma prática ruim, pois não há nenhum sentido prático nisso e gera ameaças adicionais à segurança.
Portanto, é necessário obter o certificado em algum de nossos bastion hosts e, em seguida, transferir o certificado e a chave para nosso host com o ovirt-engine.
Adicionamos o endereço externo do nosso bastion host no DNS com nosso nome do ovirt ovirtengine.example.com, a instalação do certbot e do nginx eu deixarei de fora (como fazer isso já foi descrito no Habr).
Configuramos o nginx na versão >=1.15.7
/etc/nginx/conf.d/default.conf
servidor {
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;
}
}
servidor {
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;
# Permite ao servidor anexar respostas OCSP, reduzindo assim o tempo de carregamento das páginas para os usuários
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location / {
return 444;
}
}
Depois, obtemos nosso certificado e chave:
certbot certonly --nginx -d ovirtengine.example.com
Arquivamos nosso certificado e chave:
tar Phczf /tmp/ovirtengine.example.com.tgz /etc/letsencrypt/live/ovirtengine.example.com
Baixamos do host bastião o arquivo compactado, subimos para nosso ovirt-engine:
scp bastion-host:/tmp/ovirtengine.example.com.tgz /tmp/
scp /tmp/ovirtengine.example.com.tgz ovirtengine.example.com:/
Vamos para o destino
Em seguida, descompactamos nosso arquivo e criamos links simbólicos para facilitar a compreensão do sistema de localização de arquivos:
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 o PKI incorporado no ovirt para usar o repositório de certificados do Java (openjdk) para verificar os certificados:
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
Convertendo o CA do Let's Encrypt para o formato der e adicionando ao repositório de certificados do Java trust store do ovirt (um contêiner que contém uma lista de certificados, esse sistema é usado em 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 as configurações de SSL para apache, adicionamos um parâmetro para suportar symlinks e removemos o parâmetro para CA, que verifica os certificados (por padrão, usará o conjunto de CA confiáveis do sistema para verificação):
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
Em seguida, fazemos backup, por precaução, dos arquivos originais gerados pelo PKI do ovirt e substituímos por symlinks para os arquivos do 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 os contextos do SElinux nos arquivos e reiniciamos nossos serviços (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 server apache
ovirt-engine — interface web do ovirt
ovirt-imageio-proxy — daemon para upload de imagens de discos
ovirt-websocket-proxy — serviço para funcionamento do console noVNC
Tudo o que foi mencionado acima foi verificado na versão 4.2 do ovirt.
Atualização automática de certificados no ovirt
De acordo com as boas práticas de segurança, não deve haver conexão entre o bastion-host e o ovirt, e o certificado é emitido apenas por 3 meses. Aqui surge a questão controversa sobre como a atualização dos certificados é implementada pra mim.
Eu tenho um playbook do ansible que é executado no foreman diariamente às 5 da manhã conforme programação. Este playbook acessa o ovirt, verifica a validade do certificado e, se faltar menos de 5 dias para a expiração, vai para o bastion-host e inicia a atualização do certificado.
Após a atualização do certificado, ele arquiva a pasta com os arquivos, baixa no host do foreman e descompacta no host do ovirt. Depois, restaura os contextos do SElinux nos arquivos e reiniciamos nossos serviços.
Fonte: habr.com
