Сборка Go, установка Composer и клиент Python дома работают, а внутри корпоративного VPN все терпят неудачу. Этот шаблон говорит о пути, а не о приложении. Что-то на туннеле изменило цепочку сертификатов, которую видит ваш процесс, или сбросило рукопожатие ещё до того, как цепочка вообще пришла. Обе неисправности выглядят в терминале похоже и требуют совершенно разных действий.

Три сообщения, три механизма

Ошибка x509 certificate signed by unknown authority означает, что цепочка была построена, а её корень отсутствует в хранилище доверия, которое использует этот процесс. Ошибка self-signed certificate in certificate chain обычно означает, что прокси-инспектор ответил собственным сертификатом, а это цепочка, которую ваша среда выполнения не признаёт. SSL EOF во время рукопожатия означает, что соединение закрылось до отправки любого пригодного сертификата, и это промежуточное устройство, отклоняющее ClientHello, а вовсе не проблема доверия.

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

Найдите пакет, который процесс действительно читает

Корпоративный корень, установленный в хранилище Windows, исправляет браузеры и приложения .NET, которые обращаются к системному хранилищу. Он ничего не делает для сборки, работающей внутри контейнера, который несёт собственный пакет CA, и ничего для процесса Python с certifi или процесса Node с его встроенным списком. Go читает системный пул среды, в которой работает бинарный файл, то есть контейнера, а не ноутбука. Поэтому одна машина одновременно даёт работающий браузер и сбойный инструмент сборки.

Спросите инструмент, а не предполагайте. python3 -c "import ssl; print(ssl.get_default_verify_paths())" выводит файлы, к которым обратится Python, а node -e "console.log(process.env.NODE_EXTRA_CA_CERTS)" показывает, задано ли уже переопределение. Для контейнера запустите ту же проверку внутри образа, потому что именно эту среду сборка действительно использует.

Установите один корень там, где идёт сборка

Получите корень инспекции в ИТ-отделе как файл PEM и проверьте его отпечаток по отдельному каналу, прежде чем доверять ему. На образах на базе Debian скопируйте его в /usr/local/share/ca-certificates/ и выполните update-ca-certificates; образы семейства RHEL используют update-ca-trust после того, как файл положен в /etc/pki/ca-trust/source/anchors/. В сборке контейнера добавьте эти шаги перед сбойной командой, чтобы слой кэшировался выше установки зависимостей.

Для локального devcontainer смонтируйте PEM и выполняйте ту же команду обновления при запуске, вместо того чтобы запекать её в личный образ, который никто другой не воспроизведёт. Инструменты, несущие собственный пакет, нуждаются в собственном документированном переопределении: у pip есть настройка сертификата, у npm есть настройка cafile, а большинство остальных принимают стандартные переменные среды.

Это не то же самое, что принимать любой сертификат. Вы добавляете один конкретный корень, полученный от стороны, проводящей инспекцию, в одну среду, и проверка остаётся включённой для любой другой цепочки. Запишите, какой файл добавлен и когда он истекает, потому что корень инспекции обновляется, как любой другой CA.

Когда рукопожатие умирает до сертификата

Если ничего не предъявлено, никакое изменение хранилища доверия не поможет. Сравните тот же запрос с включённым и выключенным туннелем, затем посмотрите цепочку напрямую с помощью openssl s_client -connect host:443 -servername host -showcerts. Соединение, которое завершается вне VPN и сбрасывается внутри неё, — это политическое решение промежуточного устройства, и лекарство — исключение для этого хоста, а не ещё один сертификат. Попросите пропускать реестр пакетов или конечную точку API без изменений.

Разделение туннеля, чтобы инструмент обходил VPN, избегает инспекции этого трафика, что может нарушать политику и не делает инструмент надёжным.

Запишите результат по каждому инструменту

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

И держите два предложения отдельно в заявке: мы установили конкретный корпоративный корень, и мы отключили проверку. Только одно из этого — действие поддержки.

Похожие статьи