Один URL для офиса и VPN? Почему миф о списке разрешённых не работает
VPN-подключение не меняет адрес, который видит разрешённый сайт. Проверьте реальный выход, прыжок доверенного прокси и путь IPv6, прежде чем добавлять URL.
Подключите туннель, откройте ту же закладку, и разрешённый сайт отвечает точно так же, как отвечал из офиса. Это то предположение, на котором молча держится большинство планов удалённого доступа, и оно верно лишь до тех пор, пока три отдельные вещи остаются истинными одновременно. Ни одна из них не является функцией VPN-клиента, и ни одна запись DNS не может дать ни одну из них. Когда закладка не работает дома, браузер выдаёт одну общую ошибку, будь то отсутствующий маршрут, неодобренный адрес выхода или прокси, подменивший источник, о котором он сообщает. Относиться к этим трём как к одной проблеме — это путь, на котором небольшая правка политики превращается в неделю расширения списков разрешённых.
Архитектура, которая выдерживает столкновение с реальной офисной сетью, уже предположения: явная таблица решений из трёх строк, одна точка применения, которую нельзя обойти, и тест отказа, который что-то доказывает. Разбор предположения идёт первым, потому что всё дальнейшее зависит от знания того, какой уровень неверно представляет источник.
Миф: подключение — это не маршрутизация
Туннель устанавливается, и клиент устанавливает маршруты для некоторого набора префиксов. Это всё, что делает подключение. Пойдёт ли посторонний HTTPS-запрос через туннель и с какого публичного адреса он выглядит приходящим, когда прибывает, — это решения, которые позже принимают другие компоненты: таблица маршрутизации выбирает путь, а выход выбирает источник.
Поэтому офис и кухонный стол расходятся при одном и том же ноутбуке, одном профиле браузера и одной закладке. В офисе запрос уходит через обслуживаемый публичный адрес, с которым согласился оператор сайта. Через полный туннель он может уйти через выход VPN, а это другой адрес и, пока кто-нибудь его не добавит, неодобренный. Через разделённый туннель он может вообще не попасть в туннель. Только два из этих трёх путей когда-либо были частью договорённости с владельцем сайта, а третий — не дефект, который нужно латать лишней строкой allow.
Три состояния запроса, два одобренных выхода
Запишите матрицу до того, как трогать межсетевой экран, потому что таблица — это и есть архитектура, а правило лишь одна её реализация. Адреса ниже — диапазоны для документации; замените их своими обслуживаемыми значениями и храните там, где владелец сайта сможет их проверить.
| Request path | Source the site sees | Intended decision |
|---|---|---|
| Office, no tunnel | Office public exit | Admit to the application login |
| Remote, approved full tunnel | Approved VPN egress | Admit to the same login |
| Remote, ordinary connection | Neither approved address | Deny at the network boundary |
Именно в средней строке большинство таких планов ломается. Важен адрес, который видит устройство применения, а не частный адрес, который ноутбук держит внутри туннеля, и не его адрес в LAN. Значение вроде 10.8.0.6 для публичного сайта не значит ничего, как и 192.168.1.44. Адрес туннеля — это деталь адресации туннеля, а не удостоверение, которое сайт может проверить.
Если ваш VPN не может обеспечить стабильный задокументированный выход, в матрице нет допустимой средней строки, и никакое количество списков разрешённых её не придумает. Честные варианты в этот момент — частный сайт, доступный по явным частным маршрутам, либо шлюз доступа с учётом идентичности перед приложением. У обоих другой контракт, чем у публичного списка разрешённых, и оба проще объяснить аудитору, чем список, который рос, пока случайно не заработал.
Читайте источник там, где принимается решение
Поместите ограничение на устройство, которое завершает запрос, и убедитесь, что никакой альтернативный путь происхождения его не обходит. Модуль доступа Nginx оценивает директивы allow и deny по порядку, побеждает первое совпадение, а правила, унаследованные из охватывающего блока, продолжают действовать внутри location. Узкий allow рядом с широким allow в одном месте обычно означает, что решает широкий. Прочитайте всю действующую конфигурацию для этого location, прежде чем править хотя бы одну её строку.
server {
listen 443 ssl;
server_name intranet.example.com;
set_real_ip_from 10.20.0.10;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
location /app/ {
allow 203.0.113.24; # office public exit
allow 198.51.100.77; # approved VPN egress
deny all;
proxy_pass http://app_backend;
}
}
За балансировщиком нагрузки или обратным прокси это правило видит прокси, если не сказать ему иначе. Восстанавливайте адрес вызывающего только через поддерживаемый механизм доверенного прокси, с явным списком адресов прокси. Заголовок запроса, заявляющий одобренный адрес, не является доказательством того, что вызывающий им владеет, а на публичном слушателе непроверенный переданный заголовок превращает список разрешённых в украшение.
Затем проверьте другое семейство адресов. Набор правил, охватывающий только IPv4, — неполное решение для имени хоста, которое отвечает и на AAAA, и клиент с работающим IPv6 дойдёт до того же приложения путём, который вы никогда не проверяли.
Разделённый туннель: запрос, который никогда не входит
Разделённый туннель несёт только префиксы из своего списка. Внутренние офисные подсети обычно входят в этот список; публичный сайт — нет. Браузер разрешает имя, сравнивает выбранный адрес с таблицей маршрутизации и всё равно находит перед собой локальный шлюз по умолчанию.
Так запрос приходит из домашнего подключения пользователя, получает отказ, и отчёт говорит, что VPN сломан, тогда как туннель делает ровно то, для чего был настроен. Две правки законны: направьте это назначение через туннель и дайте одобренному выходу его нести, либо признайте, что сайт достижим напрямую, и дайте удалённым пользователям другой одобренный путь, например шлюз доступа. Расширять публичный список разрешённых сайта, пока в него случайно не попадёт домашний адрес, — ни то ни другое, и это убирает границу, которую архитектура должна была применять. Первые две сохраняют матрицу честной; третья молча удаляет из неё строку.
Докажите отказ, затем восстановление
Проверяйте запросом, который задействует реальное решение, с клиента, стоящего в каждой строке таблицы. Проверка доступности к какой-нибудь посторонней странице, показывающей адрес, ничего не доказывает, потому что это назначение может идти другим путём, чем приложение.
curl -sS -o /dev/null -w 'status=%{http_code}
' https://intranet.example.com/app/login
# repeat with the tunnel up, then with it down
tail -f /var/log/nginx/access.log | grep ' /app/'
Сравните запись доступа на границе с тем, что предсказала таблица. Затем опустите туннель и сделайте новый запрос, который должен быть отклонён; уже загруженная страница или уже открытое соединение не проверяют ровно ничего. Если отказа не появилось, точка применения не там, где вы думаете.
Сохраняйте аутентификацию приложения после допуска в сеть, потому что офисный выход и выход VPN каждый представляет многих людей, и ни один не идентифицирует человека. Инструкция для пользователей остаётся короткой: поднимите одобренный туннель, затем повторите попытку. Именно это сохраняет один URL удобным, пока правило об источнике остаётся решением, а не догадкой.