Правило одного VPN в Android не блокує розміщений SSH-сервер
Обмеження одного VPN стосується VPN-сервісів, а не сокетів. SSH-сервер на телефоні відмовляє через слухача, доступ партнера або зворотний шлях.
Це переконання поширене настільки, що його сприймають як факт: 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 дотримується тих самих назв конфігурації.