Вам нужно решить, сколько техники заслуживает ваша лаборатория VPN. Маршрутизируемая шлюзовая VM между двумя сегментами VirtualBox воспроизводит трансляцию адресов, обратный путь и позицию межсетевого экрана, за которым сидит реальный клиент. Один сегмент только для хоста даёт одну контролируемую дверь и ничего больше. Вариант со шлюзом стоит три гостя и таблицу маршрутизации, которую вы поддерживаете; вариант только для хоста стоит одного гостя и одной политики. Три вопроса разделяют их, и третий решает, может ли ваш тест вообще пройти.

Ответьте на три вопроса, прежде чем что-либо клонировать

Начните с того, что должен наблюдать сервер VPN. Если сервер должен видеть адрес источника, который не принадлежит тестовому гостю, что-то должно транслировать между ними, и этим чем-то должен быть маршрутизатор, которым управляете вы. Сеть только для хоста даёт хосту адаптер в сегменте гостя, а не транслятор. Когда гостю затем нужно достичь чего-то снаружи, вы подключаете адаптер NAT, и собственный NAT-движок VirtualBox переписывает источник, не спрашивая вас.

Затем спросите, может ли гость достичь чего-либо иначе, чем через туннель. Этот ответ выбирает внутреннюю или только для хоста, и это тот вопрос, который пропускают большинство описаний лабораторий. Наконец, спросите, что должно произойти при падении туннеля, потому что это определяет политику, а не топологию, а лаборатория, доказывающая только счастливый путь, не проверила почти ничего.

What the test requiresRouted gateway VMHost-only guest
Server sees a translated source addressYes, from your own MASQUERADE ruleNo, VirtualBox NAT does it instead
The guest has exactly one egressYes, while the second adapter faces the tunnelOnly until a NAT adapter is attached
Policy is testable during a tunnel failureRules live in one placeRules live on each guest

Соедините три роли внутренними сетями

Используйте три гостя и два именованных сегмента, а шлюз пусть будет единственной машиной с адаптером на обоих:

VBoxManage modifyvm lab-client --nic1 intnet --intnet1 WAN
VBoxManage modifyvm lab-server --nic1 intnet --intnet1 LAN
VBoxManage modifyvm lab-gw --nic1 intnet --intnet1 WAN --nic2 intnet --intnet2 LAN

Отдельного шага создания для внутренней сети нет. Строка в --intnet1 и есть сегмент: две машины делят его, только если имя совпадает точно, и ничто на хосте к нему не подключено. Именно это последнее свойство и делает лабораторию чисто повторяемой, потому что маршруты хоста, его собственный клиент VPN и его межсетевой экран не могут случайно добраться до гостей. У внутреннего сегмента также нет DHCP-сервера, если вы его не добавите, поэтому статические адреса — самый короткий путь.

Дайте клиенту только его WAN-адрес, а шлюз по умолчанию должен указывать на WAN-адрес шлюза. Сервер получает LAN-адрес и использует LAN-адрес шлюза как свой шлюз по умолчанию. У гостя, который держит два адреса на одном сегменте или имеет заблудший маршрут в другой сегмент, есть путь в обход маршрутизатора, и тесты ниже будут вам лгать.

Я держу текстовый файл рядом с именами VM с четырьмя адресами и двумя именами сегментов и вставляю его в каждую оболочку. Недели спустя, когда изменение профиля что-то ломает, этот файл — разница между отладкой профиля и отладкой собственной памяти.

Выберите внутренний или только для хоста для сегмента, который не должен протекать

Режим только для хоста создаёт виртуальный адаптер на самом хосте, обычно vboxnet0, и даёт хосту адрес в сегменте гостя. Это удобно для администрирования и губительно для теста изоляции, потому что хост теперь может достичь гостя напрямую, и каждая служба на стороне хоста становится возможным путём. У внутреннего режима вообще нет адаптера хоста. Два режима легко перепутать в панели настроек сети, поэтому проверяйте документированное различие, а не ярлык (смотрите страницу подробности о сети VirtualBox).

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

VBoxManage modifyvm lab-client --nic1 hostonly --hostonlyadapter1 vboxnet0

Изоляция, которую вы можете доказать, — это изоляция, которую вы настроили. У гостя с одним внутренним адаптером, маршрутом по умолчанию на шлюзе и без адаптера NAT нет пути в обход шлюза. У гостя с адаптером только для хоста и адаптером NAT есть два пути, и только один из них — тот, который вы хотели проверить.

Маршрутизируйте и транслируйте на шлюзе, а затем заставьте его отказать закрыто

VirtualBox не пересылает между сегментами; это делает гость. Когда VM сервера VPN стоит за шлюзом, включите пересылку и транслируйте трафик клиента, когда он уходит к серверу:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

С этим правилом сервер видит LAN-адрес шлюза вместо адреса клиента, и именно так реальный клиент за NAT оператора выглядит для головного узла сети. Сохраните значение sysctl в /etc/sysctl.d/, а правило — в той службе межсетевого экрана, которую использует дистрибутив, иначе перезагрузка тихо вернёт лабораторию в маршрутизированное, но нетранслированное состояние.

Пересылка — это не авторизация. При политике FORWARD по умолчанию со значением ACCEPT гость, чей маршрут по умолчанию указывает на шлюз, выходит через тот интерфейс, который выберет таблица маршрутизации, с туннелем или без. Если у шлюза есть ещё и адаптер NAT для установки пакетов, этот адаптер — работающий незашифрованный выход в тот момент, когда туннель падает, и ваш тест «только VPN» никогда не был тестом «только VPN».

Когда сервер удалён, а туннель завершает сам шлюз, то же решение указывает на интерфейс туннеля, а не на сетевую карту, которая выходит в интернет:

iptables -P FORWARD DROP
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

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

Проверяйте путь со стороны гостя, а не хоста

Работайте наружу. Убедитесь, что клиент достигает WAN-адреса шлюза, затем сервера через шлюз, затем что соединение к порту VPN уходит и возвращается. Запись на обоих интерфейсах шлюза показывает, приходит ли ответ и отбрасывается ли он на обратном пути, чего запись только на клиенте различить не может:

tcpdump -ni eth0 udp port 1194
tcpdump -ni tun0 udp port 1194

Затем докажите выход. Спросите из гостя службу отражения адресов, какой источник она видит, и сравните с собственным выходным адресом шлюза; если ответ совпадает с адресом хоста, путь в обход туннеля существует. Проверьте, какой распознаватель гость действительно использует, и проверьте IPv6 отдельно, потому что сегмент, где IPv6 включён, а туннель несёт только IPv4, протекает по замыслу, а не случайно.

Наконец, сломайте это намеренно. Остановите туннель или заблокируйте его внешний порт и откройте новое соединение из гостя. Оно должно не удаться, и причина должна быть такой, которую вы можете назвать: нет маршрута, есть правило отклонения или распознаватель мёртв. Перезапустите туннель и убедитесь, что гость восстанавливается без перестройки сети. Если mesh VPN вроде Hamachi или ZeroTier делит лабораторию, помните, что мостовой адаптер следует за именем адаптера, а не за mesh, поэтому мост нужно перенаправить после того, как клиент установит свой собственный виртуальный адаптер.

VBoxManage list bridgedifs
VBoxManage modifyvm lab-client --bridgeadapter1 <mesh-adapter-name>

Совместное использование туннеля гостя с хостом отражает проблему. Направить маршрут хоста по умолчанию на гостя — работает, как и прокси внутри гостя; NAT через хост не несёт туннель гостя для трафика, который начал хост. Сохраните имена сегментов и правила межсетевого экрана в одном месте, сделайте снимок работающего состояния и запишите адрес источника, который наблюдал сервер. Тогда следующее изменение профиля будет стоить одного запуска скрипта вместо перестроенной лаборатории.

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