RabbitMQ для Directum RX по TLS: перевод без простоя, продление сертификата и типовые ошибки подключения
Как перевести подключения сервисов Directum RX к RabbitMQ на TLS без остановки системы. Брокер слушает оба порта на время перехода, клиенты переводятся по одному, список открытых соединений показывает, кто ещё не перешёл. Настройки rabbitmq.conf, проверка сертификатов, продление без перезапуска, ошибки в журналах брокера и RX.
Коротко. Брокер на время перехода слушает 5672 и 5671. Клиенты переводятся по одному, откат это прежний порт. Кто ещё без TLS, показывает
rabbitmqctl list_connections ... ssl. Обычный порт закрывается, когда список пуст сутки. После продления сертификата сбрасывается кэш, у RX корень должен быть доверен внутри контейнеров.
Сервисы Directum RX обмениваются сообщениями через RabbitMQ: асинхронные обработчики, фоновые процессы, индексация. По умолчанию это обычный AMQP на порту 5672 без шифрования, и в нём ходят учётные данные брокера и содержимое сообщений. Когда служба ИБ просит закрыть этот трафик, первое желание включить TLS и перезапустить всё разом. Переход можно сделать по частям, без простоя для пользователей и с понятной точкой отката.
Симптом
После неудачного перевода на TLS обычно видно одно из следующего:
- В журналах RX
RabbitMQ is not available. Possible problems: TLS configuration (check useTls setting). Incorrect port. - Брокер после перезапуска не слушает 5671, в его журнале ошибка чтения файла ключа.
- RX подключился, а другой клиент брокера (сервис интеллектуальной обработки, мониторинг, скрипт выгрузки) перестал, потому что о нём забыли.
- После продления сертификата брокер продолжает отдавать старый.
Почему так
RabbitMQ может слушать обычный порт и порт с TLS одновременно. Это и позволяет переходить по частям: включить TLS-порт, перевести клиентов по одному, убедиться, что на обычном порту никого не осталось, и только после этого его закрыть. Если сделать наоборот и сначала закрыть 5672, все клиенты, которые не успели перейти, теряют брокер одновременно, и фоновая работа RX встаёт.
У каждого клиента три настройки должны совпасть с брокером: порт (5671 для TLS), признак TLS и имя хоста, которое есть в сертификате брокера. Кроме того, клиент должен доверять удостоверяющему центру, который выпустил сертификат. Сервисы RX работают в контейнерах, хранилище сертификатов хоста им не видно, и корень добавляется внутрь контейнера.
Подготовка
Сертификат брокера
- В поле SAN имена, по которым к брокеру подключаются клиенты. Для кластера это имя каждого узла и общее имя, если подключение идёт через балансировщик.
- Файл сертификата содержит сертификат и промежуточные по порядку, файл ключа читается пользователем, от которого работает RabbitMQ.
- Проверить пару до выкладки:
openssl x509 -in server.crt -noout -subject -ext subjectAltName -enddate
openssl x509 -in server.crt -noout -pubkey | sha256sum
openssl pkey -in server.key -pubout | sha256sum # суммы должны совпасть
grep -c 'BEGIN CERTIFICATE' server.crt; grep -c 'END CERTIFICATE' server.crt
Кто вообще подключается к брокеру
До начала работ нужен полный список клиентов. Брокер его знает:
rabbitmqctl list_connections user peer_host ssl | sort | uniq -c
В выводе видно учётку, адрес и признак TLS. Если по адресу непонятно, что это за клиент, добавьте колонку
client_properties: в ней название и версия клиентской библиотеки. Каждого клиента из списка нужно будет
перевести, иначе он сломается при закрытии 5672.
Переход
1. Включить TLS-порт рядом с обычным
# rabbitmq.conf
listeners.tcp.default = 5672
listeners.ssl.default = 5671
ssl_options.cacertfile = /etc/rabbitmq/tls/ca.crt
ssl_options.certfile = /etc/rabbitmq/tls/server.crt
ssl_options.keyfile = /etc/rabbitmq/tls/server.key
ssl_options.verify = verify_none
ssl_options.fail_if_no_peer_cert = false
ssl_options.versions.1 = tlsv1.3
ssl_options.versions.2 = tlsv1.2
verify_none здесь означает, что брокер не требует сертификата от клиента. Клиенты подключаются по логину
и паролю, а шифрование и проверка сертификата брокера на стороне клиента работают как обычно.
Новые слушатели появляются после перезапуска узла. В кластере узлы перезапускаются по одному, с проверкой, что предыдущий вернулся в кластер и очереди синхронизированы. Клиенты RX при перезапуске узла переподключаются сами.
Проверка:
rabbitmq-diagnostics listeners # должны быть и 5672, и 5671
openssl s_client -connect rabbit01.example.local:5671 -servername rabbit01.example.local </dev/null | head -20
2. Перевести клиентов по одному
Для RX это включение признака TLS и порт 5671 в настройках подключения к брокеру, плюс доверенный корень
внутри контейнеров сервисов. После перезапуска сервисов в списке соединений у них должно появиться ssl = true:
rabbitmqctl list_connections user peer_host ssl ssl_protocol
Так же переводятся остальные клиенты. Если что-то пошло не так, откат это вернуть клиенту прежний порт: 5672 всё ещё работает.
3. Закрыть обычный порт
Когда в списке соединений не осталось ни одного с ssl = false (и он остаётся пустым хотя бы сутки,
чтобы попались ночные задания и редкие выгрузки), обычный слушатель отключается:
listeners.tcp = none
И снова перезапуск узлов по одному.
Что ещё в брокере ходит без TLS
- Веб-интерфейс управления на 15672. Переводится отдельными настройками
management.ssl.*на 15671. - Метрики для Prometheus на 15692. Это HTTP, содержимое не секретное, но доступ к порту стоит ограничить.
- Обмен между узлами кластера. TLS для него настраивается отдельно и сложнее. Обычно узлы кластера стоят в одном закрытом сегменте, и межузловой трафик закрывают сетью, а не TLS. Если требования ИБ иначе, на это нужна отдельная репетиция.
Продление сертификата
RabbitMQ кэширует прочитанные сертификаты. Если просто заменить файлы, новые соединения ещё какое-то время получают старый сертификат. Кэш сбрасывается на каждом узле без перезапуска:
rabbitmqctl eval 'ssl:clear_pem_cache().'
После этого проверка через openssl s_client должна показывать новый срок действия. Срок сертификата брокера
стоит держать под наблюдением вместе с остальными сертификатами контура.
Типовые ошибки
| Где и что | Причина |
|---|---|
RX: check useTls setting. Incorrect port |
признак TLS и порт не совпадают с брокером, или брокер недоступен. Разбор в справочнике |
RX: RemoteCertificateNameMismatch |
имени, по которому подключается RX, нет в SAN сертификата брокера |
RX: UntrustedRoot или PartialChain |
корень не доверен в контейнере или брокер не отдаёт промежуточный сертификат. Разбор в справочнике |
Брокер: CLIENT ALERT: Fatal - Certificate Unknown |
клиент не принял сертификат брокера; искать на стороне клиента |
| Брокер: ошибка рукопожатия от клиента на 5671 без TLS | клиент подключается к TLS-порту обычным AMQP |
| Брокер не слушает 5671 после перезапуска | не читается ключ или сертификат: права, путь, формат; причина в журнале узла при старте |
Брокер: ACCESS_REFUSED |
TLS ни при чём, неверный логин или пароль. Разбор в справочнике |
Чего не делать
- Не закрывать 5672 одновременно с включением 5671. Все, кто не успел перейти, потеряют брокер разом.
- Не закрывать 5672, пока в списке соединений есть клиенты без TLS. Смотрите список не один раз, а в течение суток.
- Не отключать проверку сертификата брокера на клиентах, чтобы «заработало». Шифрование без проверки не защищает от подмены брокера.
- Не перезапускать все узлы кластера одновременно.
- Не забывать сбросить кэш сертификатов после продления.
Похожая картина у вас?
Разберём ваш контур за 30 минут бесплатного созвона: версия RX, состав сервисов, что болит сильнее всего.
Написать