Это убеждение распространено настолько, что его принимают за факт: Android разрешает только один VPN, поэтому SSH-сервер на телефоне не может работать через этот туннель. Первая половина верна, а вывод из неё не следует. Ограничение платформы касается того, сколько приложений может занимать место VPN-сервиса, а не того, сколько сокетов может существовать и кому разрешено подключаться к телефону. SSH-демон со слушающим сокетом — обычное приложение с обычным портом, а туннель — один из путей, по которым может идти его трафик.

Что на самом деле ограничивает правило одного VPN

VpnService — ресурс с одним местом. Когда приложение устанавливает туннель, оно становится VPN устройства, а второму приложению, пытающемуся установить свой, отказывают, пока первое не исчезнет. Это правило о владении туннелем, и оно объясняет, почему два VPN-клиента не могут работать одновременно.

О слушающих сокетах оно не говорит ничего. SSH-сервер не вызывает VpnService, не перехватывает пакеты и не конкурирует за это место. Он привязывает порт и принимает соединения — то же самое, что делал бы вообще без установленного VPN. Так миф смешивает ограничение на поставщиков туннелей с ограничением на сетевые соединения, а между ними нет никакой связи.

Слушатель — это адресат, а не часть туннеля

Как только туннель существует, у телефона есть на нём адрес, а у партнёрского устройства — маршрут к этому адресу. Ответит ли что-нибудь, решает слушатель. Демон, привязанный к loopback, доступен только с самого телефона; демон, привязанный к старому адресу туннеля, может сохранить привязку после переподключения, хотя адрес, к которому он привязался, изменился.

Правила привязки — обычная конфигурация SSH: адрес и порт прослушивания и то, кто может проходить аутентификацию. В Android эти настройки живут в конфигурации самого приложения, а владельцу процесса приложения может быть запрещено использовать привилегированные порты, поэтому привычка с настольного компьютера привязывать порт 22 от имени root не переносится без изменений.

ListenAddress 10.90.0.4
Port 2222
AllowUsers alice

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

Обратный путь — это место, где обычно всё ломается

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

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

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

Обход VPN не чинит входящий сервис

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

То же касается открытия публичного порта на роутере. Если требование состоит в том, чтобы одно уполномоченное устройство достигало телефона через VPN, то выставление SSH в интернет — это другая модель угроз, а не ремонт.

Сначала определите адрес сервиса: LAN-адрес телефона, его адрес в туннеле или намеренно перенаправленную конечную точку. У каждого свои условия доступности и экспозиции, и их смешение — это то, как небольшая проблема доступа превращается в постоянную дыру.

Диагностируйте одно направление за раз

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

adb shell ip -br addr
adb shell ip route get 10.90.0.9
nc -vz 10.90.0.4 2222

Запускайте проверку порта с партнёра, а не с телефона, и читайте подробный вывод SSH-клиента, чтобы понять, терпит ли он неудачу до или после рукопожатия TCP. Сокет, который так и не подключается, и отклонённый вход — это разные этапы с разными ответственными.

Во время отладки не трогайте проверку ключа хоста и ограничения учётной записи. Именно ограничение слушателя и разрешённых пользователей делает доступный сервер приемлемым; ослабление их ради работающего соединения меняет одну проблему на более плохую. Справочник по серверу OpenSSH описывает управление прослушиванием и доступом, если ваша реализация Android следует тем же именам параметров.

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