Найти тему
Slonik

Обновление сертификатов oVirt

Оглавление
Логотип Ovirt
Логотип Ovirt

Введение

oVirt — свободная, кроссплатформенная система управления виртуализацией. Была разработана компанией Red Hat как проект сообщества на котором основан продукт Red Hat Virtualization.

oVirt состоит из двух основных компонент - oVirt engine и oVirt node.

oVirt engine управляет всеми хостами виртуализации, общими дисковыми ресурсами и виртуальными сетями. Может быть размещён как на отдельном сервере (standalone), так и на виртуальной машине внутри гипервизоров, которыми управляет (self-hosted engine).

oVirt node - физический сервер с RHEL, Centos, Scientific Linux с KVM гипервизором и службой VDSM (Virtual Desktop and Server Manager), которая управляет всеми ресурсами, доступными серверу (вычисления, ОЗУ, хранилище, сеть), а также управляет запуском виртуальных машин. Несколько узлов могут быть объединены в кластер.

В примерах ниже будут один oVirt engine и три oVirt node:

  • oVirt engine - virt-he.example.test
  • oVirt node - virt-host1.example.test, virt-host2.example.test, virt-host3.example.test

Обмен данными между oVirt engine и oVirt node осуществляется с использованием SSL сертификатов.

Автоматическое обновление сертификатов не производится, поэтому очень важно обновлять сертификаты вручную до истечения сроков их действия.

Стандартными средствами обновить сертификаты можно, если до окончания срока действия осталось менее 60 дней (для версии 4.5).

В oVirt необходимо обновлять вручную два типа сертификатов:

  1. сертификаты oVirt Engine - службы, которая предоставляет графический интерфейс и REST API для управления ресурсами виртуальных машин
  2. сертификаты для обмена данным между гипервизорами oVirt node и центром управления виртуальными машинами oVirt Engine

Определить дату окончания действия сертификатов oVirt Engine можно в свойствах сертификата сайта.

Определить дату окончания действия сертификатов гипервизоров можно с помощью openssl:

  1. Подключаемся через SSH на физический сервер oVirt node
  2. Определяем дату:
openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem

В версиях oVirt до 4.5, у всех сертификатов время жизни составляет 398 дней.

Начиная с версии 4.5, у самоподписных сертификатов для обмена данным между гипервизорами oVirt node и центром управления виртуальными машинами oVirt engine установлено время действия 5 лет.

У сертификатов, которые видят браузеры, срок действия установлен в 398 дней, их необходимо обновлять раз в год.

Процедура обновления действующих сертификатов описана в официальной документации https://www.ovirt.org/documentation/administration_guide/index.html#chap-Renewing_certificates_RHV_backup_restore

Если вы допустите истечение срока действия сертификатов, то гипервизоры и центр управления Engine перестанут взаимодействовать.

В Web-консоль невозможно будет войти, виртуальные машины продолжать работать, но с ними ничего нельзя будет сделать: нельзя изменить параметры виртуального железа, нельзя мигрировать на другой узел, после выключения ВМ её будет невозможно включить снова.

На странице web-консоли будет сообщение: "PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed"

Восстановление займёт много времени.

Процедура восстановления просроченных сертификатов описана в руководстве https://access.redhat.com/solutions/3532921. Для доступа к нему необходима действующая платная подписка Red Hat Virtualization (RHV) 4.x

Решение для восстановления без подписки я обнаружил на GitHub https://github.com/natman/ovirt_renew_certs

Автор подготовил решения для Ansible в соответствии с рекомендациями от Red hat. Если вы знакомы с Ansible и у вас много гипервизоров с просроченными сертификатами, то можно использовать решение от natman.

Решение ниже подходит для небольшого числа гипервизоров, но при условии, что центр управления Engine у вас запущен и вы можете получить к нему доступ через ssh. Предполагается, что в качестве центра управления используется HostedEngine - центр управления гипервизорами запускается внутри самого гипервизора.

Если центр управления Engine выключен и не запускается, а в журнале journalctl на гипервизоре появляются записи

libvirtd[2101]: The server certificate /etc/pki/vdsm/certs/vdsmcert.pem has expired
...
systemd[1]: Failed to start Virtualization daemon

то единственным вариантом восстановления будет изменение времени на гипервизоре на более ранее (в пределах срока действия сертификатов) и обновление сертификатов стандартным образом.

Итак, ниже будет рассмотрено три ситуации:

  1. Обновление сертификатов до истечения сроков действия - все сертификаты действуют, до окончания осталось менее 60 дней
  2. Обновление сертификатов после истечения сроков действия - у части сертификатов или у всех истек срок действия, все виртуальные машины продолжают работать, нет доступа к web-консоли, есть доступ по ssh к oVirt Engine и oVirt Node
  3. Обновление сертификатов после истечения сроков действия при недоступном HostedEngine - у части сертификатов или у всех истек срок действия, oVirt Engine был выключен, но есть доступ по ssh к oVirt Node

Во всех случаях необходимо обновить сертификаты на серверах oVirt Node, oVirt Engine, а так же служб ovirt-provider-ovn.service и ovsdb-server.service на сервере с oVirt Engine, т.к. для указанных служб скрипт не производит обновление сертификатов.

Обновление сертификатов до истечения сроков действия

Обновление сертификатов oVirt node

Переводим узел (гипервизор) в режим обслуживания (Managament -> Maintenance) - все машины на узле будут мигрированы, привязаные (pinned) машины будут выключены.

Перевод сервера oVirt node в режим обслуживания
Перевод сервера oVirt node в режим обслуживания

Выбираем Installation -> Enroll Certificate

Запуск обновления сертификатов oVirt node
Запуск обновления сертификатов oVirt node

Выводим узел из режима обслуживания

Активация сервера oVirt node
Активация сервера oVirt node

Повторяем операции для всех оставшихся узлов в кластере

Обновление сертификатов oVirt Engine

Подключаемся к физическому серверу гипервизору oVirt node через SSH

Переводим центр управления ВМ в режим обслуживания (для Self-hosted типа развёртывания)

[root@virt-host1 ~]# hosted-engine --set-maintenance --mode=global

Подключаемся к виртуальной машине с центром управления oVirt engine через SSH, запускаем настройку engine (web-консоль будет остановлена)

[root@virt-he ~]# engine-setup --offline

Отвечаем на вопросы

Если до истечения срока действия сертификата осталось менее 60 дней, то скрипт предложит обновить сертификаты:

Renew certificates? (Yes, No) [No]: Yes

Работа скрипта engine-setup
Работа скрипта engine-setup

Дожидаемся окончания работы скрипта.

Выводим центр управления ВМ из режима обслуживания:

[root@virt-host1 ~]# hosted-engine --set-maintenance --mode=none

Перезапускаем службу загрузки файлов на oVirt Node и oVirt Engine:

[root@virt-he ~]# systemctl restart ovirt-imageio.service
[root@virt-host1 ~]# systemctl restart ovirt-imageio.service
[root@virt-host2 ~]# systemctl restart ovirt-imageio.service
[root@virt-host3 ~]# systemctl restart ovirt-imageio.service

Утилита engine-setup не обновляет сертификаты у служб ovirt-provider-ovn.service и ovsdb-server.service, поэтому заменяем сертификаты и ключи служб на обновлённые от web-сервера, т.к. имя субъекта и subject alternative name у них совпадает, отличаются только приватные ключи:

[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.key.nopass /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.key.nopass.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.key.nopass /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.key.nopass
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.p12 /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.p12.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.p12 /etc/pki/ovirt-engine/keys/ovirt-provider-ovn.p12
[root@virt-he ~]# mv /etc/pki/ovirt-engine/certs/ovirt-provider-ovn.cer /etc/pki/ovirt-engine/certs/ovirt-provider-ovn.cer.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/certs/apache.cer /etc/pki/ovirt-engine/certs/ovirt-provider-ovn.cer

Перезапускаем службу ovirt-provider-ovn.service на oVirt Engine

[root@virt-he ~]# systemctl restart ovirt-provider-ovn.service

Версия oVirt, что я использовал, не обновляла сертификаты службы ovsdb (ovn-sdb.cer, ovn-ndb.cer). При истечении срока действия сертификатов в журналах появились ошибки. Поэтому заменяем ключи и сертификаты службы ovsdb-server.service на обновлённые от web-сервера (других обновлённых сертификатов я не обнаружил). Если ваша версия oVirt корректно обновляет сертификаты для службы ovsdb-server.service, то заменять их не нужно.

[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-ndb.key.nopass /etc/pki/ovirt-engine/keys/ovn-ndb.key.nopass.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.key.nopass /etc/pki/ovirt-engine/keys/ovn-ndb.key.nopass
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-ndb.p12 /etc/pki/ovirt-engine/keys/ovn-ndb.p12.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.p12 /etc/pki/ovirt-engine/keys/ovn-ndb.p12
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-sdb.key.nopass /etc/pki/ovirt-engine/keys/ovn-sdb.key.nopass.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.key.nopass /etc/pki/ovirt-engine/keys/ovn-sdb.key.nopass
[root@virt-he ~]# mv /etc/pki/ovirt-engine/keys/ovn-sdb.p12 /etc/pki/ovirt-engine/keys/ovn-sdb.p12.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/keys/apache.p12 /etc/pki/ovirt-engine/keys/ovn-sdb.p12
[root@virt-he ~]# mv /etc/pki/ovirt-engine/certs/ovn-ndb.cer /etc/pki/ovirt-engine/certs/ovn-ndb.cer.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/certs/apache.cer /etc/pki/ovirt-engine/certs/ovn-ndb.cer
[root@virt-he ~]# mv /etc/pki/ovirt-engine/certs/ovn-sdb.cer /etc/pki/ovirt-engine/certs/ovn-sdb.cer.bak
[root@virt-he ~]# ln -s /etc/pki/ovirt-engine/certs/apache.cer /etc/pki/ovirt-engine/certs/ovn-sdb.cer

Служба ovsdb-server.service запускается от пользователя openvswitch, группа hugetlbfs. Чтобы она смогла прочитать файл с приватным ключом Apache, я добавляю права чтения для группы на файл.

Добавляем права на чтение ключа для службы ovsdb-server.service:

[root@virt-he keys]# chgrp hugetlbfs /etc/pki/ovirt-engine/keys/apache.key.nopass
[root@virt-he keys]# chmod g+r /etc/pki/ovirt-engine/keys/apache.key.nopass

Можно вместо создания символических ссылок скопировать сертификаты, ключи и выставить права на копии, а права на apache.key.nopass не менять, но тогда это нужно повторять каждый раз после обновления сертификатов.

Перезапускаем службу ovsdb-server.service на oVirt Engine и oVirt Node (сертификатов на Node у службы нет, но её необходимо перезапустить)

[root@virt-he ~]# systemctl restart ovsdb-server.service
[root@virt-host1 ~]# systemctl restart ovsdb-server.service
[root@virt-host2 ~]# systemctl restart ovsdb-server.service
[root@virt-host3 ~]# systemctl restart ovsdb-server.service

Подключаемся к web-консоли и проверяем дату окончания действия сертификата.

Обновление сертификатов после истечения сроков действия

Если вы допустите истечение срока действия сертификатов, то в web-консоль невозможно будет войти:

PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
Ошибка при входе на web-консоль после истечения срока действия сертификатов
Ошибка при входе на web-консоль после истечения срока действия сертификатов

Гипервизоры и центр управления Engine перестанут взаимодействовать.

Потеря взаимодействия между oVirt engine и oVirt node после истечения срока действия сертификатов
Потеря взаимодействия между oVirt engine и oVirt node после истечения срока действия сертификатов

Чтобы восстановить сертификаты выполняем следующие шаги.

Подключаемся через SSH на узел гипервизора oVirt node (в примере имя узла virt-host1).

Создаем запрос сертификата на основании ключа службы VDSM /etc/pki/vdsm/keys/vdsmkey.pem

[root@virt-host1 ~]# openssl req -new \
-key /etc/pki/vdsm/keys/vdsmkey.pem \
-out /tmp/test_virt-host1_vdsm.csr \
-batch \
-subj "/"

Подписываем запрос с помощью корневого сертификата oVirt engine, для этого подключаемся через SSH на ВМ с oVirt engine, копируем запрос с oVirt node (virt-host1) на oVirt engine в /tmp и выполняем команды

[root@virt-he ~]# cd /etc/pki/ovirt-engine/
[root@virt-he ~]# openssl ca -batch \
-policy policy_match \
-config openssl.conf \
-cert ca.pem \
-keyfile private/ca.pem \
-days +"365" \
-in /tmp/test_virt-host1_vdsm.csr \
-out /tmp/test_virt-host1_vdsm.cer \
-startdate `(date --utc --date "now -1 days" +"%y%m%d%H%M%SZ")` \
-subj "/O=example.test/CN=virt-host1.example.test" \
-utf8

Имя субъекта в сертификате должно быть в формате "/O=example.test/CN=virt-host1.example.test", укажите ваши значения.

Копируем новый сертификат с oVirt engine на oVirt node (virt-host1) в /tmp.

Копируем новый сертификат в каталоги служб предварительно создав копию существующих сертификатов

[root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/vdsm/certs/vdsmcert.pem.bak
[root@virt-host1 ~]# cp /tmp/test_virt-host1_vdsm.cer /etc/pki/vdsm/certs/vdsmcert.pem
[root@virt-host1 ~]# cp /etc/pki/vdsm/libvirt-spice/server-cert.pem /etc/pki/vdsm/libvirt-spice/server-cert.pem.bak
[root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/vdsm/libvirt-spice/server-cert.pem
[root@virt-host1 ~]# cp /etc/pki/libvirt/clientcert.pem /etc/pki/libvirt/clientcert.pem.bak
[root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/libvirt/clientcert.pem

Перезапускаем службы:

[root@virt-host1 ~]# systemctl restart libvirtd
[root@virt-host1 ~]# systemctl restart vdsmd

Проверяем срок действия сертификата

[root@virt-host1 ~]# openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem

Повторяем процедуру на остальных узлах с истёкшим сроком действия сертификатов.

Выполняем обновления сертификатов центра управления, как описано в "Обновление сертификатов oVirt Engine"

Заходим на web-консоль и проверяем работу кластера.

У созданных таким образом сертификатов будет отсутствовать subject alternative name, о чём будет выдано предупреждение (через несколько часов):

Certificate of host virt-host1.example.test is invalid. The certificate doesn't contain valid subject alternative name, please enroll new certificate for the host.

Поэтому после восстановления доступа к web-консоли необходимо выполнить обновление сертификатов согласно официальной документации https://www.ovirt.org/documentation/administration_guide/index.html#chap-Renewing_certificates_RHV_backup_restore

Обновление сертификатов после истечения сроков действия при недоступном HostedEngine

На практике данное решение не проверялось, но теоретически оно должно сработать.

Если центр управления Engine выключен и не запускается, а в журнале journalctl на гипервизоре появляются записи

libvirtd[2101]: The server certificate /etc/pki/vdsm/certs/vdsmcert.pem has expired
...
systemd[1]: Failed to start Virtualization daemon

Оставляем включенным один гипервизор.

Определяем время окончания действия сертификата гипервизора:

[root@virt-host1 ~]# openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem

Устанавливаем дату и время до окончания действия сертификата

[root@virt-host1 ~]# systemctl stop chronyd
[root@virt-host1 ~]# timedatectl set-time "2023-01-01 12:00:00"

Перезапускаем службы

[root@virt-host1 ~]# systemctl restart libvirtd
[root@virt-host1 ~]# systemctl restart vdsmd

Подключаемся к libvirtd через virsh и ждём когда запустится HostedEngine

[root@virt-host1 ~]# virsh -c qemu:///system?authfile=/etc/ovirt-hosted-engine/virsh_auth.conf
virsh # list --all
Id Name State
------------------------------
1 HostedEngine running

Выполняем обновление сертификатов по процедуре "Обновление сертификатов до истечения сроков действия"

Использованные материалы

Документация oVirt

Проект natman

Wikipedia

Блог IT-KB