Запросы приложения не проходят за корпоративным VPN, а браузер работает
Одно приложение падает, пока браузер загружает сайт. Пройдите по порядку унаследованный прокси, политику портов, сбросы сырого TCP и ограничения размера полезной нагрузки.
Вы открываете внутренний портал в браузере, и он загружается. Вы запускаете приложение, которое обращается к тому же хосту, и оно падает с сообщением, не называющим ни одного уровня. Туннель несёт браузер, поэтому туннель не первый подозреваемый. Между вашим запросом и сервисом стоят четыре вещи, и каждая оставляет свой след. Вот порядок, которого я держусь: начиная с запроса, который приложение действительно отправляет, а не со страницы настроек VPN-клиента.
Посмотрите на запрос, который приложение действительно отправляет
Прежде чем трогать конфигурацию, заставьте приложение рассказать, что оно делает. Перехват одного запроса с явно отключённым прокси и простая проверка порта дают две базовые линии, с которыми сверяются следующие шаги. Если запрос проходит при отключённом прокси, три из четырёх уровней уже закрыты.
env | grep -i proxy # Linux/macOS
netsh winhttp show proxy # Windows, machine-wide
curl -sv --noproxy '*' https://svc.internal/
nc -vz svc.internal 8080Запустите две последние команды на тот же адрес и посмотрите, где они расходятся. Работающий браузер плюс работающий curl плюс неработающее приложение сужают проблему до того, что добавляет приложение: прокси, транспорта или размера сообщения.
Приложение унаследовало прокси, который никто не настраивал
Большинство HTTP-стеков по умолчанию читают настройки прокси из операционной системы. Корпоративный VPN-клиент часто устанавливает прокси как часть своего профиля доступа, поэтому запросы уходят через прокси, о котором разработчик никогда не упоминал в коде. В .NET обработчик по умолчанию берёт настройки из IE/WinHTTP; Java читает -Dhttp.proxyHost; в Node прокси нет, пока библиотека его не добавит. Сбой редко бывает чистым отказом, поэтому люди начинают смотреть на сервер.
Проверка стоит одного запроса: отключите прокси явно на одном обработчике и сравните.
var handler = new HttpClientHandler { UseProxy = false };
using var client = new HttpClient(handler);Если это сработает, исправление относится к конфигурации приложения, а не к туннелю. Повторите аудит для каждой среды выполнения в проекте, потому что каждая читает свой источник, и сломанной может быть только одна.
Выбранный порт — не тот, который разрешает политика
Маршрутизируемый хост — ещё не разрешённый сервис. Корпоративная политика обычно разрешает исходящие веб-порты и отбрасывает остальные, поэтому сервис на 8080 или 1883 недоступен, а 443 работает нормально. Браузер здесь ничего не доказывает: он по определению использует 443.
Опубликуйте тот же сервис за 443 и доберитесь до него по имени, прежде чем просить исключение. Если исключение действительно нужно, ограничьте его одним диапазоном источника и одним назначением и считайте частью определения сервиса, а не чьим-то личным обходом.
Сырой TCP, который путь сбрасывает
Долгоживущие соединения сырого TCP — это уровень, который падает самым запутанным образом. Путь, разрешающий веб-трафик, всё равно может сбрасывать или переписывать необычный исходящий TCP, и клиент сообщает об ошибке сокета, которая читается как обрыв. Сервисы сообщений и событий обычно поставляют транспорт WebSocket именно для таких сетей, и переключение — это опция клиента, а не изменение туннеля.
Смените транспорт, проверьте снова и в том же прогоне больше ничего не меняйте. Этот тест с одной переменной скажет, откуда пришёл сброс — из пути или из сервиса.
Соединения, которые закрываются только на больших нагрузках
Запрос, который проходит, а затем умирает примерно через секунду, но только когда тело большое, указывает на ограничение размера где-то посередине. Посредник, считающий байты сообщений, может сбросить соединение посреди передачи, и клиент сообщает об аномальном закрытии вместо тайм-аута.
Дробите нагрузку на уровне приложения. Держите это отдельно от работы с MTU: уменьшение размера пакета туннеля помогает, когда обычные сессии TCP встают на неизменном числе байт, и ничего не делает для сообщения, которое посредник считает слишком большим.
Как отличить четыре за один проход
Три наблюдения решают большинство случаев. Сбой происходит сразу или только с большим телом? Проходит ли тот же запрос с отключённым прокси? Меняется ли результат при смене порта или транспорта? Запишите ответы до следующего изменения, потому что корпоративный VPN плюс унаследованный прокси плюс настройка по умолчанию дают сразу три вероятные причины.
Держите одну переменную на тест и записывайте использованный хост назначения. Без этой базовой линии следующий человек повторяет все четыре шага с начала.