VM Vagrant исчезает при подключении VPN: чей маршрут сломался
Машина, отвечавшая минуту назад, исчезает в момент подключения. Решите, кому принадлежит сломанный маршрут, прежде чем что-то менять.
Машина отвечала минуту назад, VPN подключился, и теперь тот же адрес уходит в тайм-аут. Три неисправности дают этот симптом, и они живут на разных машинах. Хост может потерять маршрут к частной сети, диапазон NAT гостя может столкнуться с диапазоном, который туннель теперь анонсирует, или полный туннель может забрать владение каждым маршрутом на хосте. Выясните, какая случилась, прежде чем менять любую конфигурацию, потому что каждое исправление живёт в другом месте.
Смотрите на маршрут, а не на машину
Посмотрите на решение хоста о маршрутизации для адреса гостя, пока туннель поднят. Маршрут, который по-прежнему указывает на адаптер только для хоста, не является проблемой. Маршрут, который теперь указывает на адаптер VPN, и есть проблема, и его изменил клиент, а не вы. То, что адаптер сохраняет адрес, говорит о выживании интерфейса, а это другой факт, чем выживание пути.
SSH-сеанс, который падает ровно в момент подключения, — ожидаемое поведение. Клиент переиспользует адаптеры и устанавливает маршруты, поэтому соединение умирает на несколько секунд. Неисправность — это соединение, которое не возвращается, а не то, что лишь мигнуло.
Снимите таблицу до туннеля и ещё раз после него, затем сравните эти два вывода. Разница и есть диагноз, и она же служит доказательством, которое попросит владелец сети.
ip -4 route get 192.168.56.10
ip -brief addr show
ip route show table main | head -20Прочитайте таблицу хоста до и после
В Linux предпочтение между перекрывающимися маршрутами определяется длиной префикса и метрикой, поэтому более конкретный маршрут VPN выигрывает, даже когда он неверен. В Windows ничью решает метрика интерфейса, и адаптер туннеля обычно приходит с меньшей метрикой, чем виртуальный. В обоих случаях видимый симптом одинаков: пакеты уходят через адаптер туннеля и исчезают.
Выведите адаптеры и их метрики рядом с маршрутом для префикса гостя. Эта пара выводов отвечает на вопрос о владении с одного взгляда.
Get-NetAdapter | Select-Object Name, InterfaceIndex, InterfaceMetric
Get-NetRoute -DestinationPrefix 192.168.56.0/24
route print -4 | Select-String '192.168.56'Если маршрут изменился, а метрика адаптера нет, клиент установил конкурирующий маршрут. Если метрика изменилась, клиент переставил адаптеры. И то и другое исправимо, и исправляется в разных местах.
Когда диапазон NAT гостя и есть столкновение
VirtualBox NAT по умолчанию использует 10.0.2.0/24, и туннель, который проталкивает тот же диапазон, заставляет гостя отправлять этот трафик на свой NAT-шлюз вместо настоящего назначения. Пакет никогда не покидает хост, поэтому ни один журнал межсетевого экрана на той стороне его не покажет. У Docker Machine тот же класс конфликта в его плане только для хоста, и изменение этого плана может потребовать пересоздания машины вместе с её сертификатами.
Выберите замену, перечислив, что туннель уже анонсирует, затем что использует офисная сеть, затем что заявил каждый виртуальный адаптер на этом хосте. Маршрутизацию ломает перекрытие, а сходство не важно. Один диапазон может целиком лежать внутри другого, хотя на первый взгляд они совсем не похожи.
Задайте новый диапазон при создании машины или измените его и перезагрузите, затем снова проверьте сбойное соединение с гостя. Собственная таблица гостя — это тот вид, который имеет значение.
VBoxManage modifyvm devbox --natnet1 10.77.0.0/24
vagrant reload devbox --provision
vagrant ssh devbox -c 'ip route get 10.20.0.15'Восстановите путь, не воюя с клиентом
Каждая платформа предлагает способ снова выдвинуть префикс только для хоста вперёд. В macOS статический маршрут к интерфейсу только для хоста работает до следующего подключения. В Windows более низкая метрика интерфейса на виртуальном адаптере удерживает его предпочтительным. В Linux операция замены покрывает один префикс. Все три — обходные пути, потому что клиент, который вновь утверждает свои маршруты, их отменит.
Напишите проверку скриптом вместо слепого переподключения при загрузке. Небольшой скрипт, который после каждого подключения печатает маршрут для префикса гостя, превращает загадку в строку журнала.
Если профиль — полный туннель, попросите владельца сети о раздельном туннелировании или документированном исключении. Тихо добавлять маршруты в обход политики безопасности — это не исправление, а вторая проблема, которая придёт позже вместе с аудитором.
Проверьте исправление с обеих сторон
После изменения проверьте три пути: хост к гостю, гость к корпоративному хосту и гость в интернет. Исправление, которое восстанавливает один и ломает другой, — это изменение конфигурации под видом ремонта. Снимите те же выводы, что собрали до изменения, чтобы сравнение было равным с равным.
Запишите интерфейс, метрику и изменившийся маршрут вместе со временем, чтобы следующий случай был поиском, а не перестройкой. Эта заметка ценнее длинной ветки заявки.
ip -4 route get 192.168.56.10
traceroute -n -m 4 10.20.0.15
curl -sS -o /dev/null -w '%{http_code}\n' https://example.comКогда хост снова достигает гостя, а гость достигает локальной сети, вы восстановили путь, с которого начали. Когда работает только одно из этого, оставшаяся неисправность находится на территории другого владельца, и разница говорит, какая это территория.