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

Что обычно описывает обращение

Представьте телефон в Wi-Fi с поднятым туннелем. Интерфейс Wi-Fi держит адрес локальной сети, интерфейс туннеля держит назначенный внутренний адрес, а запрос, выходящий через туннель, приходит в публичный сервис с того источника, который переживёт любое преобразование по пути. Приложение, печатающее внутренний адрес, и сервер, записывающий преобразованный источник, сообщают оба точно, и эти два значения никогда не совпадут.

Три наблюдения различаются тем, что они могут доказать, а не только тем, что они описывают.

ObservationWhat it describesWhat it cannot prove
An address on a local interfaceOne configured attachment: Wi-Fi, cellular or a tunnelThe source a remote site receives
A socket's local endpointThe binding used by that one connectionThe address after translation further along
The peer address at a serviceWhat arrived at that observation pointAny other interface on the phone

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

На что вызов сокета может и не может ответить

На уровне API getsockname сообщает локальную конечную точку, которая сейчас привязана к конкретному сокету. Для подключённого сокета это источник, который ядро выбрало для этого соединения, и это уже конкретнее любого списка интерфейсов. Это не поиск публичного адреса, и вызов его на несвязанном сокете почти ничего не говорит. Что бы он ни возвращал, это может быть позже переписано по пути, поэтому только собственное наблюдение сервиса авторитетно в отношении того, что сервис получил.

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

Разделённый туннель делает разницу видимой. Один запрос может выйти через туннель, а следующий, направленный на другое место назначения или другое семейство адресов, нет, поэтому два результата одного и того же приложения с разницей в секунды могут быть честными и разными.

Выберите наблюдение, которое соответствует вопросу

Выбирайте осознанно, а не измеряйте всё. Для того, что видит бэкенд, записывайте источник на бэкенде, а там, где впереди стоит обратный прокси, читайте адрес клиента из заголовка пересылки, который ваше развёртывание действительно устанавливает, а не из того, что прислал клиент.

Чтобы узнать, настроен ли туннель, читайте интерфейс. Чтобы узнать, использовал ли его трафик этого приложения, отправьте трафик из этого приложения на контролируемое вами место назначения и сравните источник на обоих концах.

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

Имена интерфейсов не детектор

Не используйте имя интерфейса и как проверку VPN. Имена не являются публичным контрактом, и телефон может держать несколько подключений, пока только одно из них несёт ваш запрос.

Называйте поле по наблюдению, которое оно хранит. local_interface_address, socket_local_endpoint и service_observed_source неуклюжи и однозначны, а однозначность это то, что нужно, когда значение через неделю попадает в обращение в поддержку. Один столбец с именем device IP соберёт все три, а потом ему будут доверять так, будто он один.

Держите идентичность вне столбца адреса

Общий выход VPN это не идентичность пользователя, а приватный адрес не учётные данные доступа. Оба описывают путь, а не человека, и отношение к любому из них как к аутентификации превращает случайность маршрутизации в решение об авторизации.

Когда кто-то спрашивает, какой адрес у телефона, полезный ответ это вопрос о том, какое соединение и какой наблюдатель. Определение getsockname стоит процитировать для среднего случая, потому что оно решает вопрос сокета, не делая вид, что решает два других.

Затем запишите, какое из трёх ваш продукт действительно должен показывать, и удалите два других из интерфейса.

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