Прокси SOCKS через SSH на Android: почему подключается только половина приложений
ssh -D создаёт SOCKS-слушатель, а не туннель всего устройства. Пройдите цепочку от приложения к адаптеру и SSH, затем проверьте пробелы в DNS и жизненном цикле.
Вы входите по SSH, добавляете -D 1080, и команда выполняется. Теперь на телефоне есть SOCKS-слушатель, а половина приложений по-прежнему выходит через мобильные данные. Это нормальный результат, а не сломанный туннель: ssh -D создаёт конечную точку прокси, а приложения Android используют прокси только если что-то заставляет их. Пошаговый проход по цепочке показывает, где на самом деле живёт каждая часть работы.
Начните там, где начинается трафик
Выберите одно приложение, которое должно использовать туннель, и проверьте, есть ли у него собственная настройка прокси. Браузер с полем SOCKS — простой случай: направьте его на 127.0.0.1:1080, включите удалённый DNS, если такая настройка есть, и запрос проходит. У чат-клиента, приложения карт или игры без такого поля нет способа использовать слушатель, и ничто из введённого в команду SSH этого не меняет.
Прежде чем вовлекать что-то ещё, докажите, что слушатель работает из оболочки самого телефона с клиентом, который говорит SOCKS напрямую:
ssh -N -D 1080 [email protected]
curl --socks5-hostname 127.0.0.1:1080 https://ifconfig.me
Возвращаемый адрес должен принадлежать серверу SSH, а не телефону. Если так, половина прокси готова, а остальная работа — про охват. Если нет, сначала исправьте сторону SSH: аутентификацию по ключу, способность сервера достичь назначения и собственный выход сервера SSH.
Добавьте часть, которая нужна Android
Приложениям без настройки прокси нужно нечто, что перехватит их пакеты и превратит их в прокси-соединения. На устройстве без root это адаптер службы VPN: приложение, которое берёт виртуальный интерфейс и направляет выбранный трафик в локальный слушатель SOCKS. Цепочка становится такой: приложение, адаптер, слушатель SOCKS, соединение SSH, назначение.
Установите адаптер, дайте ему разрешение VPN и выберите приложения или маршруты, которые он должен перехватывать. Значок ключа в строке состояния тогда обозначает адаптер, а не отдельный коммерческий VPN. Android разрешает одно активное соединение службы VPN на профиль пользователя, поэтому запуск второго VPN-приложения не добавляет слой к цепочке: он конкурирует за ту же роль.
Это ещё и шаг, на котором успешный тест может ввести вас в заблуждение. Если адаптер настроен перехватывать только тот браузер, который вы уже направили на прокси, всё работает, и больше ничего не покрыто. Прочитайте список перехвата, прежде чем заключать, что устройство в туннеле.
Держите транспорт SSH вне перехвата
Само соединение SSH не должно возвращаться в туннель SOCKS, который оно поддерживает. Если адаптер перехватывает трафик приложения SSH, туннель зависит от соединения, которое ждёт туннель, и результат — петля, которая встаёт или ломается, как только адаптер запускается.
Интегрированные реализации защищают собственный транспортный сокет. С отдельными приложениями нужно поддерживаемое исключение: оставьте приложение SSH вне перехвата или исключите конечную точку SSH по адресу. Оба варианта имеют цену. Исключение целого терминального приложения убирает из туннеля и его постороннюю сетевую активность, а исключение по адресу ломается, когда адрес сервера меняется или когда имя при следующем подключении разрешается иначе.
Проверьте исключение снаружи: переподключите адаптер, затем убедитесь, что сессия SSH выживает и что запрос через прокси по-прежнему сообщает адрес сервера. Сессия, которая работает до запуска адаптера, а затем замирает, и есть эта петля.
Проследите DNS и UDP до конца цепочки
Динамическая переадресация OpenSSH переносит TCP-соединения. Это не транспорт UDP-associate или ICMP, и адаптер не может выдумать переадресацию UDP, принимая UDP-пакеты. Всё, что требует UDP, включая QUIC и медиа WebRTC, либо потерпит неудачу, либо откатится на TCP в зависимости от приложения.
DNS требует собственного решения. Приложение, которое разрешает имя локально, отправляет запрос через обычный резолвер до подключения, поэтому туннель переносит соединение, но не поиск. Клиент, знающий о прокси, с опцией удалённого DNS избегает этого; перехваченное приложение без такой опции — нет. Проверьте, какой резолвер ответил, вместо того чтобы предполагать, что адаптер это изменил.
Держите слушатель SOCKS привязанным к loopback, проверьте ключ хоста сервера SSH при первом использовании и оставьте обычную проверку HTTPS на месте для конечного сайта. SSH защищает участок от телефона до сервера; он не шифрует то, что сервер делает дальше.
Проверьте два жизненных цикла и решите
У адаптера и сессии SSH разные жизненные циклы. Если SSH падает, пока адаптер продолжает перехватывать, приложения могут зависнуть без явной ошибки, потому что их пакеты всё ещё попадают в виртуальный интерфейс, у которого больше нет работающего выхода. Если адаптер останавливается, приложения либо идут напрямую, либо блокируются в зависимости от политики VPN устройства.
Намеренно проверьте оба направления: убейте сессию SSH при работающем адаптере, затем остановите адаптер, пока SSH остаётся поднятым. То, что телефон делает в каждом случае, — это политика, которую вы действительно внедряете, что бы ни утверждала инструкция по установке.
Если рабочий процесс требует охвата всего устройства с предсказуемым режимом отказа, честный ответ — настоящий IP VPN или поддерживаемый адаптер, созданный для этой цепочки. Сессия оболочки, оставленная работать рядом с посторонним перехватывающим приложением, — не поддерживаемый туннель устройства; это два компонента без договорённости о том, что происходит, когда один из них заканчивается.