Git зависает в WSL2 через VPN: MTU интерфейса или путь?
Git проходит проверку подлинности и потом зависает в WSL2? Сравните интерфейс Linux с адаптером VPN Windows, проверьте одно меньшее значение и спланируйте его жизненный цикл.
Клон проходит проверку подлинности, появляется счётчик объектов, а затем несколько минут ничего не движется. Windows сообщает, что VPN подключён, имя узла разрешается, а браузер на той же машине без труда загружает ту же страницу репозитория. Такое сочетание указывает на размер пакета, а не на учётные данные, и вопрос о размере нужно задать в двух местах, потому что у WSL2 есть собственный интерфейс Linux со своим MTU. Одно число относится к стороне Windows пути, другое к дистрибутиву, и чтение только адаптера VPN оставляет половину пути неисследованной.
Три признака отделяют проблему размера от прочего
Первый признак — форма: установка соединения и небольшой обмен проходят, затем массовая передача перестаёт продвигаться. Второй — симметрия: тот же репозиторий и тот же транспорт терпят неудачу, тогда как другой узел на том же пути работает, или отказ меняется с размером полезной нагрузки, а не со временем суток. Третий — тишина: нет ошибки проверки подлинности, нет отказа прокси, нет сбоя разрешения имён, только передача, которая никогда не завершается.
Эти три вместе оправдывают гипотезу о размере пакета. Сбой DNS, просроченный токен, отклонённый ключ SSH и прокси, отвергающий CONNECT, дают каждый свою ошибку, и ни одна из них не похожа на остановку после успеха. Сохранение того же репозитория, транспорта и временного окна при тестировании — вот что делает сравнение честным.
Сравните оба интерфейса, прежде чем решать
Соберите вид Windows и вид Linux в одной сессии и держитесь адреса репозитория вместо догадки о том, какой интерфейс его несёт. Команда ниже сначала разрешает адрес назначения, чтобы поиск маршрута описывал реальный сервер, с которым связывается клон, а он может отличаться от имени, показанного браузером. Запускайте обе половины близко по времени, потому что VPN может менять метрики интерфейса между попытками.
netsh interface ipv4 show subinterfaces
wsl -d Ubuntu -- bash -lc 'dest=$(getent ahostsv4 github.com | awk \'NR==1{print $1}\'); ip -br link show; ip route get "$dest"'
Запускайте половину Linux внутри дистрибутива, а не вставляйте вывод в оболочку Windows, поскольку имена интерфейсов и выбор маршрута имеют смысл только там. Вставка из оболочки Windows сообщает неверные числа с большой уверенностью. Запишите устройство, выбранный маршрут и MTU с каждой стороны, прежде чем что-либо менять.
Решите, должно ли число быть меньше
Больший MTU интерфейса, чем может нести путь, не является автоматически дефектом, потому что обнаружение MTU пути существует именно для этого. Режим отказа проявляется, когда обнаружение подавлено: сообщения ICMP фильтруются где-то по пути, отправитель так и не узнаёт предел, и большие пакеты исчезают, тогда как малые проходят. Это свойство пути, а не свойство Git. Это же причина, по которой маленький файл может пройти по соединению, где большой никогда не завершается.
Если доказательства это подтверждают, временное изменение на интерфейсе Linux — самый дешёвый тест. Выберите значение ниже используемого размера пути, запишите предыдущее и оставьте всё остальное неизменным, чтобы сравнение что-то значило. Если передача завершается при меньшем значении, у вас диагноз, а не совпадение.
ip -br link show dev eth0
sudo ip link set dev eth0 mtu 1380
ip -br link show dev eth0
Решите, где должна жить настройка
Из теста следуют три варианта, и обычно подходит только один из них. Если меньшее значение исправляет передачу и значение действительно нужно этой сети, настройке нужен владелец жизненного цикла: хук запуска в дистрибутиве, сетевая конфигурация, управляемая платформой, или документированная процедура. Если значение ничего не исправляет, верните его и вернитесь к вопросам транспорта, прокси и проверки подлинности.
Наличие хука запуска зависит от используемых версий Windows и WSL и от настроенного режима сети. Зеркалирование сети Windows может изменить то, как VPN взаимодействует с дистрибутивом, способами, которые важнее настройки MTU, поэтому определите режим, прежде чем проектировать обходное решение для него. Значение, подходящее одному оператору или одному профилю VPN, не является значением по умолчанию для следующего.
Чего следует избегать — это соблазнительное размещение: привилегированная сетевая команда в файле запуска каждой интерактивной оболочки или sudo без пароля для всего двоичного файла ip, чтобы скрипт мог выполнить одну строку. И то и другое превращает диагностику в постоянную уязвимость и затрудняет обнаружение исходной проблемы позже.
Проверьте после чистой загрузки, затем откатите
Изменение, которое держится только до перезапуска дистрибутива, не является исправлением. Перезапустите дистрибутив, снова подключите VPN и повторите исходную операцию Git, а не замену вроде ping или небольшого HTTP-запроса. Затем подтвердите, что интерфейс несёт нужное значение в новой сессии.
ip -br link show dev eth0
ip route get "$(getent ahostsv4 github.com | awk 'NR==1{print $1}')"
Держите записанное исходное значение рядом с изменением, чтобы эксперимент можно было чисто отменить, и отметьте, какое семейство адресов проверялось, поскольку результат IPv4 ничего не говорит о соединении IPv6 на том же узле. Документация по сетям WSL описывает режимы, которые определяют, как должно выглядеть исправление; само число MTU — локальное измерение, а не рекомендация.