Загрузка 0
ПОДЕЛИТЬСЯ

Мой блог

Листай вниз

Как подключить GigaChat к n8n в Docker и решить проблему с сертификатами Минцифры

Как подключить GigaChat к n8n в Docker и решить проблему с сертификатами Минцифры

Когда я настраивал локальный стек автоматизации на базе n8n в Docker и пытался интегрировать GigaChat API, я сразу же столкнулся с классической ошибкой SSL-верификации. В этой статье я подробно покажу, как правильно подружить российскую языковую модель с Node.js-окружением, не прибегая к опасным отключениям безопасности.

Помимо технической настройки сертификатов, я поделюсь забавным инцидентом из практики, когда наша нейросеть начала массово называть всех клиентов «Иваном» из-за особенностей генерации JSON.

Как подключить GigaChat к n8n в Docker и решить проблему с сертификатами Минцифры
Как подключить GigaChat к n8n в Docker и решить проблему с сертификатами Минцифры

Архитектура проекта и назначение сервисов

Для реализации проекта мы развернули на собственном VPS изолированный стек инструментов, каждый из которых выполняет свою роль в обработке пользовательских запросов и хранении оперативных данных:

Реклама
  • n8n в Docker — основной визуальный оркестратор рабочих процессов и сценариев;
  • PostgreSQL в Docker — надежная реляционная база данных для кэширования, хранения сессий и лидов;
  • GigaChat API (Сбер) — специализированная LLM для обработки входящего текстового трафика на русском языке;
  • Gemini Flash (Google) — дополнительная языковая модель, задействованная для фоновых задач скоринга.

Интеграция со Сбером потребовалась нам для реализации строгих требований 152-ФЗ. Когда пользователи пишут в чат-виджет на сайте и оставляют конфиденциальные персональные данные вроде номеров телефонов или электронной почты, система должна перехватывать эти сведения и направлять их в изолированный контур. Выбор пал именно на GigaChat, поскольку его серверы физически расположены в России, исключая передачу чувствительной информации за рубеж.

Симптоматика проблемы: UNABLE_TO_VERIFY_LEAF_SIGNATURE

После развертывания инфраструктуры я добавил в рабочую схему n8n стандартную ноду HTTP Request, прописал официальный эндпоинт для генерации ответов, передал необходимые авторизационные заголовки и тестовый полезный груз в формате JSON. Однако при попытке тестового запуска выполнение моментально прерывалось с ошибкой:

Error: unable to verify the first certificate
at TLSSocket.onConnectSecure (node:_tls_wrap:1674:34)
code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'

Корень этой проблемы кроется в архитектуре доверия сертификатов. Доменные имена сервисов Сбера подписаны официальным Головным удостоверяющим центром Минцифры РФ. В то же время стандартная среда выполнения Node.js по умолчанию опирается исключительно на встроенный набор корневых сертификатов от Mozilla Foundation.

Реклама

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

Почему нельзя отключать проверку TLS через глобальные флаги

Самый первый импульс, возникающий при виде подобных сбоев в сети — быстро отключить верификацию, прописав переменную окружения NODE_TLS_REJECT_UNAUTHORIZED=0 прямо в конфигурационном файле docker-compose. На начальном этапе отладки я поступил точно так же, отложив правильное решение на потом.

Спустя пару месяцев я обнаружил, что этот временный метод незаметно закрепился в продакшене. Главная угроза такого решения заключается в том, что данный параметр деактивирует проверку сертификатов глобально для всего процесса Node.js внутри контейнера.

В результате n8n перестает проверять безопасность не только при запросах к GigaChat, но и при обмене данными с внешними вебхуками, защищенными базами данных и Telegram Bot API. Если злоумышленник перехватит маршрутизацию трафика, он сможет провести атаку типа Man-in-the-Middle и украсть рабочие Bearer-токены.

Инструкция по настройке сертификатов Минцифры в Docker

Чтобы восстановить безопасность контура, необходимо заставить рантайм Node.js довериться корневым сертификатам Минцифры на легитимных основаниях. Сборка необходимого бандла на хосте выполняется несколькими простыми командами в терминале:

mkdir -p /opt/certs
curl -k -s https://gu-st.ru/content/Other/doc/russian_trusted_root_ca.cer > /opt/certs/russian_trusted_root_ca.crt
echo "" >> /opt/certs/russian_trusted_root_ca.crt
curl -k -s https://gu-st.ru/content/Other/doc/russian_trusted_sub_ca.cer >> /opt/certs/russian_trusted_sub_ca.crt
chmod 644 /opt/certs/russian_trusted_root_ca.crt

Затем полученный файл сертификата прокидывается внутрь контейнера через механизм volume в файле конфигурации оркестратора, а также задается специальная переменная окружения:

services:
  n8n:
    image: n8nio/n8n:latest
    volumes:
      - /opt/certs/russian_trusted_root_ca.crt:/home/node/certs/russian_trusted_root_ca.crt:ro
    environment:
      - NODE_EXTRA_CA_CERTS=/home/node/certs/russian_trusted_root_ca.crt

После применения изменений и перезапуска контейнеров не стоит тестировать соединение через консольную утилиту openssl s_client, поскольку она считывает системное хранилище ОС и не учитывает специфические переменные Node.js. Проверку работоспособности лучше выполнять непосредственно внутри рабочего пространства:

docker exec -it n8n node -e "require('https').get('https://gigachat.devices.sberbank.ru', (res) => console.log('TLS code:', res.statusCode)).on('error', console.error)"

Успешный ответ с кодом 200 или 403 подтверждает, что защищенный протокол функционирует корректно, а сертификаты успешно подхватились системой.

Тонкости работы с переменными окружения в n8n 1.x

При дальнейшей настройке токенов в новых версиях n8n я столкнулся с еще одной программной особенностью. Попытка обратиться к переменной окружения вроде $env.GIGACHAT_TOKEN прямо из выражения ноды приводит к ошибке доступа.

Разработчики платформы в первой версии намеренно заблокировали прямой вызов переменных окружения из рабочих блоков по соображениям безопасности. Разумеется, можно снять это ограничение глобальным параметром, но гораздо безопаснее и грамотнее прописывать секретные ключи через штатный интерфейс авторизации Header Auth в меню Credentials.

Интересный кейс: как мы столкнулись с «синдромом Ивана»

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

Проблема проявилась на обезличенных обращениях, когда пользователь писал вопрос общего характера без указания имени. По условиям задачи модель обязана сформировать строгий JSON, однако пустые строки или значение null в требуемом поле вызывают сбой валидации.

Не найдя реальных данных в сообщении, модель подставляла самое распространенное мужское имя из своей обучающей выборки — Иван. В результате наш чат-бот стал настойчиво приветствовать каждого посетителя, включая женщин и корпоративных клиентов, фразой «Здравствуйте, Иван!».

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

Заключение

Интеграция отечественных ИИ-сервисов в современные рабочие процессы на базе n8n требует внимательного отношения к деталям безопасности. Не стоит отключать проверку SSL-сертификатов с помощью сомнительных обходных путей. Корректная установка корневых сертификатов Минцифры занимает минимум времени, позволяя сохранить криптографическую целостность всей инфраструктуры.

01.