Какой адрес источника NGINX запишет для клиента VPN?
Решите, что NGINX видит рядом с OpenVPN на одном хосте: внутренний адрес туннеля, публичный адрес выхода или переданного партнёра, в зависимости от пройденного пути.
В конфигурации NGINX и OpenVPN на одном хосте появляются три клиентских адреса, по одному на каждый путь, который может выбрать запрос. Браузер, приходящий на адрес туннеля, браузер, приходящий на публичный адрес, и программа, выходящая по интернет-маршруту шлюза, выглядят на слушающем сокете по-разному. Решите, какой путь вы наблюдаете, прежде чем толковать строку журнала. Решение зависит от адресата, который использовал клиент, от исключения для внешней конечной точки VPN и от того, переводит ли что-нибудь пакет по дороге.
Решайте по адресату, а не по тому, кто пользователь
Начните с адреса, на который отправлен запрос, потому что именно этот адрес выбирает путь. Запрос к адресу туннеля хоста приходит на интерфейс туннеля с внутренним адресом клиента в качестве источника. Запрос к публичному адресу хоста обычно приходит на интерфейс, обращённый в интернет, с публичным адресом клиента, даже когда на том же ноутбуке в этот момент поднят туннель. Поэтому принадлежность к пулу VPN — свойство пути пакета, а не свойство, которое следует за пользователем.
| Path the request took | Source the site normally records |
|---|---|
| Client reaches the site at its tunnel address, 10.24.0.1 | Client inner address, 10.24.0.20 |
| Client reaches another internet site through the gateway | Gateway public egress address, 192.0.2.44 |
| Client reaches the gateway's public address through the endpoint exception | Client's own public access address |
Именно эту третью строку стоит проверить первой, когда в журнале появляется пользователь VPN с адресом, не имеющим отношения к туннелю. Это также объясняет, почему два пользователя на одном профиле могут давать разные записи: их собственные сети доступа различаются, и ничто в туннеле это не перезаписывает.
Почему внешняя конечная точка создаёт второй публичный путь
Клиент должен достичь публичного адреса шлюза, чтобы установить туннель, поэтому маршрут к этому адресу должен существовать вне туннеля. Когда клиент направляет весь трафик внутрь, разумная реализация сохраняет явный маршрут хоста к публичному адресу сервера, чтобы избежать туннеля, зависящего от самого себя. Это исключение не разбирает службы, поэтому ему следует любой запрос к тому же публичному адресу, включая запрос браузера к сайту, размещённому на шлюзе.
Это механизм, стоящий за большинством запутанных сообщений в этой области, и он зависит от реализации клиента, а не сервера. Поэтому два клиента с одинаковыми профилями могут вести себя по-разному. Удаление исключения, чтобы »починить« журнал, роняет и туннель, поэтому оставьте его и проектируйте вокруг него.
Читайте сокет, таблицу и формат журнала вместе
Три наблюдения решают, какой путь вы видите: где слушает сокет, какой интерфейс отвечает на адресата и что формат журнала действительно записывает. Если слушатель привязан только к адресу туннеля, публичный запрос вообще не может до него дойти, что сразу исключает две строки. Если поиск для клиента возвращает устройство туннеля, запрос пришёл с внутренним источником, и журнал должен это показать.
ss -lntp 'sport = :443'
ip route get 10.24.0.20
ip route get 192.0.2.44Затем читайте формат, а не строку. Поле, питаемое переданным заголовком, записывает утверждение, а не партнёра сокета, и утверждение имеет значение только когда непосредственный партнёр — доверенный прокси. Запись обоих значений в журнал закрывает последующие споры, потому что непосредственный партнёр и подменённый адрес — разные факты, и только один из них пришёл из сети.
log_format tunneled '$remote_addr $realip_remote_addr $request $status';
grep -n 'log_format' /etc/nginx/nginx.confВыберите нужную точку входа и согласуйте DNS
Если сайт должен быть только через туннель, дайте ему имя, которое для клиентов VPN разрешается в адрес туннеля, и применяйте политику на слушающем сокете. Ответ разделённого DNS, возвращающий 10.24.0.1 для внутреннего имени, — это решение о маршрутизации в костюме подробности разрешения имён. Если сайт должен быть и публичным, держите два имени или два порта и позвольте журналу сказать, какой из них обслужил запрос.
Правила разрешения следуют той же логике. Разрешение пула туннеля не даёт прав на публичный запрос и не заполнит внутренний адрес в соединении, пришедшем через интернет. Смешивание обеих точек входа под одним именем превращает записанный источник в побочный эффект маршрутизации клиента вместо проектного решения.
Проверьте путь, затем политику
Подтвердите путь перехватом на шлюзе и запросом, который вы контролируете. Перехват на устройстве туннеля и один на публичном интерфейсе показывают, какой из них нёс байты, а порядок пакетов говорит, произошёл ли между ними перевод.
tcpdump -ni tun0 port 443 -c 5
tcpdump -ni eth0 port 443 -c 5Затем проверьте доступ в обе стороны: предполагаемая именованная точка входа работает для предполагаемого клиента, а неодобренный публичный путь отклоняется, а не просто медленный. Обычный сайт эха IP доказывает что-то о выходе шлюза в интернет и ничего об этом сайте на том же хосте. Когда страница и WebSocket расходятся, сравните их URL, семейства адресов и ответы DNS, прежде чем трогать конфигурацию сервера.