Недавно мне довелось обновлять старую FreeIPA в большой компании. Эта FreeIPA была установлена в LXC-контейнере на CentOS 7 и находилась в нерабочем состоянии уже несколько месяцев. Мне передали бэкап LXC-контейнера для Proxmox, и я взялся за дело.

Изначально план был такой:

  • Восстановить работоспособность системы.

  • Обновить сертификаты.

  • Сделать бэкап.

  • Перенести бэкап на новую обновляемую систему: Fedora или Rocky Linux — поскольку поддержка CentOS уже прекращена.

Проблема запуска LXC с устаревшим systemd на свежем Proxmox

Так как образ был в формате архивированного LXC-контейнера, при его восстановлении выяснилось, что у меня слишком свежая версия Proxmox, которая уже не поддерживает версию systemd из этого контейнера. Проблема в том, что новый Proxmox работает с Cgroups v2, а устаревший systemd контейнера поддерживает только Cgroups v1.

Таким образом первая же проблема, с которой я столкнулся, — это запуск LXC-контейнера. К счастью, в контейнере не запускался только systemd (init-система, которая запускает всё остальное), но в контейнер по-прежнему можно было попасть, запустив обычный bash.

Ну, хорошо, доступ в контейнер у нас теперь есть, а значит, мы можем попробовать обновить в нем операционную систему. Сделать это можно точно так же, как это обычно решается в chroot-окружениях.

В Proxmox, чтобы попасть в пространство LXC-контейнера, достаточно выполнить следующую команду:

pct enter 112

Но в отличие от обычного chroot network в LXC-контейнере namespace изолированный — благо, Proxmox уже создал все необходимые интерфейсы, осталось только их настроить.

Начнем с сети:

ip addr add 192.168.20.109/16 dev eth0
ip link set eth0 up
Ip route add defaut via 192.168.20.1

Так как CentOS достиг EOL, то официальные репозитории больше недоступны по привычным адресам. Заменим их на архивные адреса:

sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-

Теперь установим новый systemd из бэкпортов:

curl https://copr.fedorainfracloud.org/coprs/jsynacek/systemd-backports-for-centos-7/repo/epel-7/jsynacek-systemd-backports-for-centos-7-epel-7.repo -o /etc/yum.repos.d/jsynacek-systemd-centos-7.repo
yum update systemd

В результате мы получаем работоспособную систему с обновленным systemd, который работает в новом Proxmox. Однако пока мы лишь запустили контейнер, и нам всё ещё предстоит разобраться с проблемой, которую попросил решить заказчик.

Проблема с истекшими сертификатами

Первое, на что стоит смотреть при диагностике FreeIPA — это состояние системных сертификатов. Для этого достаточно запустить следующую команду:

# getcert list | grep -E "Request ID|status|certificate|expires"

В консоли получился такой вывод:

Number of certificates and requests being tracked: 7.
Request ID '20180730085204':
    	status: CA_UNREACHABLE
    	certificate: type=FILE,location='/var/lib/ipa/ra-agent.pem'
    	expires: 2024-05-04 13:35:31 UTC
Request ID '20180730085237':
    	status: CA_UNREACHABLE
    	certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='auditSigningCert cert-pki-ca',token='NSS Certificate DB'
    	expires: 2024-05-04 13:36:01 UTC
Request ID '20180730085238':
    	status: CA_UNREACHABLE
    	certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='ocspSigningCert cert-pki-ca',token='NSS Certificate DB'
    	expires: 2024-05-04 13:37:01 UTC
Request ID '20180730085239':
    	status: CA_UNREACHABLE
    	certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='subsystemCert cert-pki-ca',token='NSS Certificate DB'
    	expires: 2024-05-04 13:35:51 UTC
Request ID '20180730085240':
    	status: CA_UNREACHABLE
    	certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='caSigningCert cert-pki-ca',token='NSS Certificate DB'
    	expires: 2038-07-30 08:51:36 UTC
Request ID '20180730085241':
    	status: CA_UNREACHABLE
    	certificate: type=NSSDB,location='/etc/pki/pki-tomcat/alias',nickname='Server-Cert cert-pki-ca',token='NSS Certificate DB'
    	expires: 2024-05-04 13:36:31 UTC
Request ID '20180730085358':
    	status: CA_UNREACHABLE
    	certificate: type=FILE,location='/va

Можно заметить что большинство сертификатов просрочены — именно по этой причине многие сервисы FreeIPA не стартуют.

Основная проблема здесь заключается в том, что нам нужно перевыпустить сертификаты. И чтобы их перевыпустить, должны исправно работать сервисы FreeIPA. А сервисы эти не могут запуститься из-за того, что сертификаты просроченные и коммуникация между ними не работает?

Решить эту проблему достаточно просто — нам нужно перевести системное время. Но так как LXC-контейнер наследует время хоста, мы сделаем это прямо на гипервизоре. Кроме того, надо будет отключить сервис NTP (Network Time Protocol, протокол сетевого времени), иначе он будет автоматически синхронизировать время по интернету и менять его на корректное.

Итак, отключаем NTP. А после этого меняем дату на более старую, чем expired у сертификатов (чтобы система думала, что сертификаты ещё действительны):

timedatectl set-ntp 0
date -s '2024-05-03'

Далее запускаем сервисы:

ipactl restart

Сервисы стартовали, но вывод getcert list, скорее всего, не обновился. Вы можете форсировать обновление сертификатов командой ipa-getcert resubmit -i, а в качестве аргумента передать ей Request ID из вывода getcert list. После этого надо будет запустить ее повторно, чтобы снова проверить состояние:

ipa-getcert resubmit -i 20240227134251

Необходимо добиться того, чтобы все сертификаты перешли в состояние MONITORING. Если мы не завершим обновление сертификатов до того, как поменяем время обратно, на текущее, многие сервисы всё так же останутся неработоспособными.

Убедившись, что все сертификаты в состоянии MONITORING, выставим в системе актуальное время (по сути, достаточно просто включить NTP):

timedatectl set-ntp 1

Отлично! Мы продвинулись еще на один шаг и теперь у нас есть полностью работоспособная FreeIPA, хоть и старой версии.

Подготовка к миграции на новую ОС и обновление формата nssdb

Почти все сертификаты FreeIPA хранятся в обособленных nssdb-базах данных (NSS Shared DB).

Начиная с CentOS 7 nssdb изменил свой формат базы данных (cert8) на новый формат SQL (cert9). Но если в Centos 7 старый формат ещё поддерживался, то на новых системах эта поддержка была удалена. Поэтому базу данных старого формата использовать не получится.

В моем случае оказалось, что некоторые из сервисов по-прежнему используют старый формат хранилища. Поэтому я предположил, что и вы можете столкнуться с подобной проблемой. Ниже я приведу её решение. 

Для начала найдем все эти базы (и старого, и нового формата) в системе:

find / -name cert8.db
find / -name cert9.db

Все файлы с такими паттернами в названии: cert8.db key3.db secmod.db — это базы старого формата.

Если паттерны в названиях файлов такие: cert9.db key4.db pkcs11.txt — это новый SQL-формат.

Проверить сертификаты в хранилище можно так (EXAMPLE-ORG замените на свой домен):

Старый формат

/usr/bin/certutil -d /etc/dirsrv/slapd-EXAMPLE-ORG -L -f /etc/dirsrv/slapd-EXAMPLE-ORG/pwdfile.txt

Новый формат

/usr/bin/certutil -d sql:/etc/dirsrv/slapd-EXAMPLE-ORG -L -f /etc/dirsrv/slapd-EXAMPLE-ORG/pwdfile.txt

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

certutil -W -d sql:/etc/pki/pki-tomcat/alias -f /etc/pki/pki-tomcat/alias/pwdfile.txt -@ /etc/pki/pki-tomcat/alias/pwdfile.txt

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

Перед стартом процесса миграции нам нужно убедиться, что все сертификаты из базы в старом формате добавлены в БД уже в новом формате. Если этого не сделать, то, скорее всего, на новой системе вы получите примерно такую ошибку:

NSS is built without support of the legacy database(DBM) directory '/etc/ipa/nssdb'

Миграция на новую ОС

Перед миграцией необходимо обновить систему и все пакеты до самой свежей версии:

yum update

Кажется, теперь мы готовы для миграции на новый Rocky Linux 8.

Создаём бэкап на старой CentOS 7:

ipa-backup

Копируем его на Rocky Linux. Дважды проверяем что корректный FQDN и IP-адрес записаны в /etc/hosts.

Затем запускаем процесс восстановления данных из нашего бэкапа:

ipa-restore -v /var/lib/ipa/backup/ipa-full-2024-07-03-23-24-04/

Видимо, из-за разницы форматов на разных ОС мы сразу же сталкиваемся с проблемой отсутствующего файла /var/lib/ipa/auth_backup/authselect.backup. Получить его можно, выполнив во время запуска вот такую команду (она сохранить настройки текущего профиля authselect в файл):

authselect current --raw > /var/lib/ipa/auth_backup/authselect.backup

Дальше я столкнулся с тем, что процесс восстановления падает на этапе обновления FreeIPA после запуска такой команды: 

ipa-server-upgrade

Изучив логи, я увидел, что не стартует pki-tomcatd@pki-tomcat.service.d, который запускает CA-листенера для FreeIPA, который, в свою очередь, и занимается выписыванием сертификатов.

Посмотреть логи можно следующим образом:

journalctl -u pki-tomcatd@pki-tomcat.service.d

Также в некоторых случаях может быть очень полезно изучить дебаг-лог CA:

tail -f /var/log/pki/pki-tomcat/ca/debug

Подробно изучив логи, я заметил ошибки доступа к файлам из /etc/sysconfig/pki-tomcat, видимо, логика восстановления бэкапа не отработала корректно, поэтому поправим вручную:

sudo chown pkiuser:pkiuser /etc/sysconfig/pki-tomcat
sudo chown -R pkiuser:pkiuser /etc/pki/pki-tomcat/alias/

Кроме того, на момент восстановления желательно отключить SELinux.

Вторая проблема заключалась в том, что Tomcat в Rocky Linux 8 имеет версию выше, чем тот, что был у нас на CentOS 7, и формат конфига у него сильно изменился. То есть при восстановлении бэкапа у нас восстановился старый /etc/pki/pki-tomcat/server.xml, а обновленный Tomcat больше не может его использовать. Вы можете получить новый файл, в правильном формате, если проинициируете FreeIPA с теми же параметрами с помощью следующей команды:

ipa-server-install

Сделайте это на соседней виртуалке, а потом просто скопируйте этот файл на ту виртуалку, где вы восстанавливаете бэкап.

После этого запускаем обновление вручную ещё раз:

ipa-server-upgrade -v

Готово, FreeIPA успешно восстановлена и обновлена до последней версии.

Проверка сертификатов на новом сервере

Проверяем сертификаты, снова запустив команду уже на новой машине:

getcert list | grep -E "Request ID|status|certificate|expires"

видим, что некоторые из них зависли в состоянии NEWLY_ADDED_NEED_KEYINFO_READ_PIN. Это означает, что сертификаты были только что добавлены и им требуется PIN — странное поведение, как по мне, но OK, спишем и это на несовершенство скрипта для восстановления бэкапа.

Указать нужный PIN можно такой командой:

ipa-getcert start-tracking -i 20240703234954 -P "$(cat /etc/pki/pki-tomcat/alias/pwdfile.txt)"

20240703234954 — это Request ID, полученный из вывода команды getcert list, которую мы запускали выше. Обратите особое внимание на местоположение сертификата и укажите для него правильный password file из того же хранилища.

Необходимо добиться состояния, при котором все сертификаты перейдут в состояние MONITORING. Если же вы увидите статусы CA_UNREACHABLE, значит, вам нужно разобраться, почему не работает CA-листенер. Для этого изучайте логи 

journalctl -u pki-tomcatd@pki-tomcat.service.d
tail -f /var/log/pki/pki-tomcat/ca/debug

Подведем итоги

В случае возникновения проблем с сертификатами поиск решения почти всегда связан с шагами, описанными в этой статье.

Общий алгоритм действий такой:

  1. Проверьте Tomcat и сервис CA, который он запускает.

  2. Проверьте состояние запросов для сертификатов в getcert list.

  3. Перезаказать сертификаты с помощью ipa-getcert resubmit или start-tracking.

Дополнительные пожелания

Работа FreeIPA зависит от сертификатов в ‘getcert list’. В нормальной ситуации эта команда должна возвращать все сертификаты в состоянии MONITORING. Если же что-то идёт не так, воспользуйтесь советами из статьи. Чаще всего проблема заключается в сервисе CA, который выполняет подпись этих сертификатов.

Некоторые мои заметки в неформатированном виде можно посмотреть в этом gist.

И еще один важный момент: крайне желательно настроить мониторинг, который будет проверять вывод этой команды.

Комментарии (5)


  1. ZVEZDO4ETik
    01.08.2024 03:42

    Отлично! Осталось теперь обновится с RHEL 8 на RHEL 9. Интересно там тоже будет всё так трудно с обновлением ипа?


    1. kvaps Автор
      01.08.2024 03:42
      +1

      Думаю в рамках одного дистрибутива обновление будет происходить проще, но увидим, главное что экспертиза теперь есть


  1. randomsimplenumber
    01.08.2024 03:42

    находилась в нерабочем состоянии уже несколько месяцев

    Если система находится несколько месяцев в оффлайне, и никто не заметил - не похоже что она кому -то нужна. В процессах крупной компании она точно не используется.


    1. kvaps Автор
      01.08.2024 03:42
      +1

      Они переводили время на гипервизоре на несколько месяцев назад и продолжали использовать)


      1. randomsimplenumber
        01.08.2024 03:42

        Ну значит не совсем в офлайне ;)