Застосунку, який говорить лише SOCKS, немає з ким розмовляти у звичайній VPN, бо тунель переносить пакети, а застосунок хоче проксі-кінцеву точку. OpenSSH може надати цю точку, якщо власник доступу дозволяє, оскільки динамічне переспрямування перетворює один сеанс SSH на локальний проксі. Далі є два переходи, які треба тримати окремо: тунель, що досягає хоста SSH, і з'єднання, яке цей хост відкриває далі. Їх розділення пояснює і те, чому схема працює, і те, чого вона ніколи не зробить.

Чим слухач SSH стає, а чим ні

Динамічне переспрямування змушує клієнт SSH слухати локально й говорити SOCKS4 або SOCKS5 з усім, що підключається. Кожен запит називає пункт призначення, і сервер SSH відкриває наступне з'єднання, тому пошук пункту призначення може відбуватися на дальньому боці. Це переспрямування TCP на рівні застосунку, а не VPN для всього пристрою. Воно не несе ні UDP-асоціації, ні ICMP, ні чогось для застосунків, які повністю ігнорують налаштування проксі. Перехід від сервера SSH до застосунку теж не всередині вашого тунелю, що важливо, коли пункт призначення приймає трафік лише з відомих мереж.

Передумови реальні: маршрут до хоста SSH, авторизований обліковий запис, перевірений ключ хоста сервера й дозвіл на переспрямування. Жодної з них не створює проксі, а остання зазвичай відсутня першою. Підтвердьте всі чотири, перш ніж щось інше налагоджувати, бо з боку клієнта збій виглядає однаково, якої б не бракувало.

Запустіть його на loopback з явним портом

Виберіть невикористаний локальний порт і явно прив'яжіть його до loopback, а не залишайте адресу порожньою. Три варіанти нижче існують кожен з однієї причини.

ssh -D 127.0.0.1:1080 -NT -o ControlPath=none -o ExitOnForwardFailure=yes \
  [email protected]

-N пропускає віддалену команду, а -T пропускає псевдотермінал, тож сеанс існує лише для переспрямування. ExitOnForwardFailure змушує клієнт завершитися, коли слухача не можна створити, замість роботи без запитаного переспрямування. ControlPath=none тримає сеанс поза наявним мультиплексованим з'єднанням, яке могло б додати власні переспрямування. Loopback тримає слухач поза LAN, але на спільній машині це не межа авторизації, бо до нього можуть дістатися й інші локальні процеси. Довідка клієнта OpenSSH документує всі ці прапорці, а попередження про loopback випливає з того, чим є сокет, що слухає.

Надсилайте імена через проксі, а не повз нього

Клієнт SOCKS5 може сам розв'язати пункт призначення або попросити проксі зробити це, і цей вибір визначає, який резолвер відповість. З socks5h curl надсилає ім'я хоста через проксі, тож пошук відбувається на сервері SSH. Зі звичайним socks5 ноутбук розв'язує першим і подорожує лише з'єднання, що тихо знецінює сенс, коли ім'я внутрішнє. Запит нижче також очищає список без проксі, щоб успадковане значення NO_PROXY не могло провести його повз проксі.

curl -sS --noproxy '' --proxy socks5h://127.0.0.1:1080 https://app.corp.example/health

Перевірка сертифіката й власний вхід застосунку все ще діють, бо проксі не замінює ні того, ні того. Залишаються два пошуки: ноутбук має досягти хоста SSH дозволеним шляхом VPN і DNS, а сервер SSH має сам розв'язати ім'я застосунку. Другий можна перевірити окремо, перш ніж через проксі піде будь-який трафік.

ssh [email protected] getent hosts app.corp.example

Доведіть один дозволений пункт призначення, потім закрийте сеанс

Перевірте пункт призначення, який політика дозволяє, і той, який вона має відхилити, бо робоче переспрямування доводить лише те, що слухач працює, і нічого більше. Застосунок бачить адресу джерела, яку вибирає сервер SSH, і це не адреса тунелю вашого ноутбука. Там, де дальній бік журналює з'єднання за джерелом, саме ця різниця є першим, що треба перевірити, коли запит відхилено.

Зупиніть сеанс через процес, який ним володіє, а не вбиваючи сторонню оболонку. Потім переконайтеся, що слухач зник, бо порт, який ще відповідає, — це сеанс, який ви насправді не закрили. Видаліть лише налаштування проксі, яке ввів цей приклад, і залиште решту конфігурації застосунку спокійно. Термінал без нагляду з правилом переспрямування — не сервіс, і постійному проксі потрібен схвалений життєвий цикл, а не забуте вікно.

ss -ltn | grep 1080

Збої, які ця схема не може виправити

Деякі симптоми вказують прямо на наведені вище межі, і раннє їх розпізнавання економить пів дня налагодження проксі. Таблиця пов'язує те, що ви бачите, з тим, що це зазвичай означає. Усе в останньому стовпці — питання проєктування, а не помилка конфігурації.

What you seeWhat it usually meansWhere to look
The app connects and nothing followsIt ignores proxy settings entirelyIts own network settings, not the SSH session
A name resolution error for the destinationThe SSH server cannot resolve itServer resolver and search domains
A UDP-only application failsDynamic forwarding carries TCP onlyThis arrangement cannot serve it
curl works, the browser does notThe browser is not using the socks5h endpointBrowser proxy configuration
The listener answers after the session endedAnother process owns port 1080The ss output, then the owning process

Перші три рядки — ті, які люди діагностують неправильно, бо кожен дає спробу з'єднання замість помилки про сам проксі. Ім'я, що розв'язується на ноутбуці, нічого не каже про резолвер сервера, і збій читається радше як проблема сертифіката або тайм-ауту. Застосунки лише з UDP стоять поза схемою, а не зламані всередині неї, і жодна додаткова опція ssh цього не змінює. Рядок про браузер — звичайне нагадування, що налаштування проксі задаються для кожного застосунку. Останній рядок — причина, чому існує перевірка під час закриття: порт, який ще слухає, означає, що тепер ним володіє щось інше.

Схожі статті