Вебхук GitHub не доходит до приватного Jenkins: исправьте путь
Сеанс VPN на ноутбуке не даёт GitHub маршрута к Jenkins. Сравните входящую точку, релей и опрос, а затем проверьте путь, по которому идут события.
Вы можете открыть Jenkins через VPN и всё равно увидеть, что GitHub сообщает об ошибке вебхука, потому что это два разных соединения с двумя разными владельцами. Браузер идёт через туннель, который согласовал ваш ноутбук; служба доставки GitHub начинается в публичном интернете и не имеет маршрута в частную сеть. Доступ к репозиторию этого не меняет, хотя сам Jenkins может без проблем забирать из того же репозитория. Выберите входную точку, релей или опрос, а затем проверьте путь, по которому событие действительно идёт.
Сеанс браузера доказывает только одно направление
VPN-соединение отвечает на один вопрос: может ли этот ноутбук добраться до внутреннего хоста. Доставка вебхука спрашивает о другом: может ли внешняя служба открыть соединение к этому хосту. То, что Jenkins забирает из репозитория, — исходящий трафик, и он ничего не говорит о входящей доступности. Держите оба направления на отдельных линиях схемы, включая то, какая сторона начинает каждое из них.
Прочитайте запись доставки, прежде чем что-либо менять. Тайм-аут, сброс соединения и принятый запрос, не совпавший ни с одной задачей, имеют трёх разных владельцев: сеть, прокси и настройку триггера.
Вариант A: открыть узкую точку входа
Если организация уже публикует одобренный вход, откройте путь вебхука, а не панель управления. Обычно это означает правило обратного прокси, которое принимает POST по URL хука и передаёт их в Jenkins, пока административный интерфейс остаётся недоступным снаружи.
curl -sS -o /dev/null -w "%{http_code}\n" -X POST https://jenkins.example.com/github-webhook/Выполните этот тест из сети без доступа к VPN, потому что успех изнутри туннеля ничего не доказывает. Точка входа должна отклонять запросы без общего секрета, который GitHub присылает в заголовке подписи, и принимать только тот единственный путь и метод, которые вы опубликовали. Публичная консоль Jenkins — это не исправление вебхука, а инцидент, ждущий следующего сканера. Ограничьте правило достаточно узко, чтобы остальная часть приложения сохранила прежние средства контроля доступа.
Вариант B: развернуть направление релеем
Там, где входящее раскрытие не одобрят, небольшой клиент внутри сети может держать исходящее соединение с релеем и получать пересланные события. Тогда релей становится частью пути доставки, поэтому его доступность и аутентификация так же важны, как и задача сборки.
ssh -N -R 9000:localhost:8080 relay.example.netРекомендации Jenkins о вебхуках за межсетевыми экранами описывают эту схему, и их стоит прочитать, прежде чем писать собственный пересыльщик. Завершайте TLS на релее, проверяйте подпись до того, как событие дойдёт до задачи, и следите за исходящим каналом, потому что упавший туннель выглядит точно так же, как событие, которое так и не отправили. Убедитесь также, что релей сохраняет тело запроса байт в байт, поскольку проверки подписи не проходят на JSON, который по дороге разобрали и заново закодировали.
Вариант C: опрашивать репозиторий
Опрос меняет задержку на простоту и вообще не требует входящего пути. Jenkins может опрашивать по расписанию, или небольшая задача может запросить API и запустить сборку, увидев незнакомую ревизию.
curl -sS -u "$USER:$TOKEN" "https://api.github.com/repos/OWNER/REPO/commits?per_page=1"Каждый опрос расходует вызовы API и добавляет задержку между push и сборкой, что заметно на загруженных репозиториях и при общих ограничениях скорости. Ему также нужны учётные данные, хранящиеся там, где работает опросчик, поэтому ограничьте токен доступом к репозиторию только на чтение и меняйте его, как любой другой секрет. Выбирайте это, когда поток событий невелик или когда входную точку никогда не одобрят, и напишите об этом в описании задачи, чтобы потом никто не удивлялся, почему сборки отстают.
Принимайте настоящую доставку, а не загрузку страницы
Какой бы вариант вы ни выбрали, приёмочный тест — это событие, отправленное исходной платформой, а не вкладка браузера, открытая с привилегированного ноутбука. Отправьте пустой коммит в черновую ветку и прочитайте код ответа доставки, журнал релея или вывод задачи опроса — именно в таком порядке. Ответ 200 от точки входа без сборки означает, что фильтр триггера неверен; тайм-аут означает, что путь всё ещё закрыт. Запишите, какая из трёх схем используется, иначе следующий отладчик повторит тест в браузере и попадёт в тот же тупик.
Примените ту же логику к обратным вызовам платежей и другим внешним уведомлениям: каждому нужен свой маршрут в частное приложение, даже когда у каждого человека уже есть сеанс VPN. Путь доставки относится к проектированию приложения, а не к сноске про сети.