Як працює зворотне тунелювання SSH?


350

Наскільки я розумію це, брандмауері (припускаючи налаштування за замовчуванням) заперечують весь вхідний трафік, який не має попереднього відповідного вихідного трафіку.

На основі реверсування SSH-з'єднання та SSH Tunneling Made Easy , зворотне тунелювання SSH може бути використане для подолання скучних обмежень брандмауера.

Я хотів би виконувати команди оболонки на віддаленій машині. Віддалена машина має власний брандмауер і знаходиться позаду додаткового брандмауера (маршрутизатора). Він має IP-адресу, як 192.168.1.126 (або щось подібне). Я не за брандмауером і знаю IP-адресу віддаленої машини, як видно з Інтернету (не адресу 192.168.1.126). Крім того, я можу попросити когось спочатку виконати ssh (something)як root на віддаленій машині.

Чи може хто-небудь пояснити мені крок за кроком, як працює зворотне тунелювання SSH, щоб обійти між брандмауерами (брандмауери місцевих та віддалених машин та додатковий міжмережевий екран)?

Яка роль перемикачів ( -R, -f, -L, -N)?


Відповіді:


402

Я люблю пояснювати подібну річ через візуалізацію. :-)

Подумайте про свої SSH-з'єднання як пробірки. Великі трубочки. Зазвичай через ці трубки ви досягнете оболонки на віддаленому комп'ютері. Оболонка працює у віртуальному терміналі (tty). Але ви вже знаєте цю частину.

Подумайте про свій тунель як про трубу всередині трубки. У вас ще є великий SSH-з'єднання, але опція -L або -R дозволяє встановити всередині нього меншу трубку.

Кожна трубка має початок і кінець. Велика трубка, ваше з'єднання SSH, розпочалося з вашого клієнта SSH і закінчилося на сервері SSH, до якого ви підключились. Усі менші трубки мають однакові кінцеві точки, за винятком того, що роль "початку" або "кінця" визначається тим, чи використовували ви їх ( -Lабо -Rвідповідно) для їх створення.

(Ви ще не говорили, але я припускаю, що «віддалений» апарат, про який ви згадали, той, що знаходиться за брандмауером, може отримати доступ до Інтернету за допомогою трансляції мережевих адрес (NAT). Це дуже важливо, тому будь ласка, виправте це припущення, якщо воно помилкове.)

Коли ви створюєте тунель, ви вказуєте адресу та порт, на який він буде відповідати, та адресу та порт, на який він буде доставлений. -LОпція вказує тунель , щоб відповісти на локальній стороні тунелю (господар працює ваш клієнт). -RОпція вказує тунель , щоб відповісти на віддаленій стороні (сервер SSH).

напрямки ssh тунелю

Отже ... Щоб мати змогу передавати SSH з Інтернету в машину за брандмауером, вам потрібна машина, щоб відкрити SSH-з'єднання із зовнішнім світом та включити -Rтунель, точка "входу" якого є "віддаленою" стороною його зв’язок.

З двох моделей, показаних вище, ви хочете, щоб той був праворуч.

Від хазяїна, що захищається,:

ssh -f -N -T -R22222:localhost:22 yourpublichost.example.com

Це повідомляє вашому клієнту створити тунель з -Rточкою входу емоцій. Все, що приєднується до порту 22222 на дальньому кінці тунелю, насправді дістанеться до "localhost port 22", де "localhost" знаходиться з точки зору точки виходу тунелю (тобто вашого ssh-клієнта).

Інші варіанти:

  • -f повідомляє ssh самому фону після його автентифікації, тому вам не доведеться сидіти, виконуючи щось на віддаленому сервері, щоб тунель залишився живим.
  • -Nговорить, що ви хочете з'єднання SSH, але насправді не хочете запускати віддалені команди. Якщо все, що ви створюєте, - це тунель, то включення цієї опції економить ресурси.
  • -T вимикає розподіл псевдо-tty, що підходить, оскільки ви не намагаєтесь створити інтерактивну оболонку.

Виникне пароль, якщо ви не встановили клавіші DSA або RSA для входу без пароля.

Зауважте, що настійно рекомендується використовувати обліковий запис (не власний логін), який ви створили саме для цього тунелю / клієнта / сервера.

Тепер із оболонки на своємупублікості встановіть з'єднання з хостом, який пройшов через канал , через тунель:

ssh -p 22222 username@localhost

Ви отримаєте ключовий виклик хоста, оскільки ви, ймовірно, ніколи раніше не потрапляли на цей хост. Тоді ви отримаєте виклик пароля для usernameоблікового запису (якщо ви не встановили ключі для безкористувацького входу).

Якщо ви збираєтеся регулярно отримувати доступ до цього хоста, ви також можете спростити доступ, додавши до свого ~/.ssh/configфайлу кілька рядків :

host remotehostname
    User remoteusername
    Hostname localhost
    Port 22222

Налаштовуйте remotehostnameі remoteusernameпідлаштовуйте. remoteusernameПоле має відповідати своєму імені користувача на віддаленому сервері, але remotehostnameможе бути будь-яким ім'ям хоста , який підходить вам, він не повинен відповідати нічого вирішити.

(Щоб виставити зворотну кінцеву точку в IP -адресі , що не є локальним , перегляньте цю публікацію )


2
що з ssh -D. Будь ласка, поясніть, використовуючи той самий метод.
BigSack

6
Проксі-сервери SOCKS не такі, як тунелі. Якщо у вас є питання щодо їх використання, будь ласка, задайте його .
ghoti

12
Мені дуже важко дотримуватися цього пояснення через слабке використання термінів: сервер, клієнт, локальна машина, віддалена машина, хост, вашpublichost, localhost, remotehostname. Зважаючи на всі ці розгублені та невизначені терміни, можна припустити, що комусь знадобиться аж 8 комп’ютерів, щоб налаштувати це. Я констатую це, тому що в усіх інших аспектах це здається дуже хорошим поясненням. Скоротіть та визначте умови.
Rucent88

4
@ Rucent88, я не впевнений, яке зменшення було б можливим. Клієнт встановлює з'єднання з сервером. Це поширена термінологія в усьому світі. Місцеві та віддалені машини здаються досить очевидними. Якщо після прочитання документації ви заплуталися в SSH або загальній термінології Unix, я впевнений, що у вас не виникне проблем з пошуку людей, які дуже хочуть відповісти на будь-які питання, які у вас є.
ghoti

9
@ghoti Це справді заплутано, адже локальні та віддалені машини відносні. Коли я сиджу на робочому місці, мій домашній комп'ютер - це віддалений, коли я сиджу вдома, робочий комп'ютер віддалений. Сервер і клієнт також плутають, коли говорять про тунелювання. Наприклад, якщо я підключаюся до дому з роботи з ssh -R. Я підключаюсь до своєї роботи з домашнього комп’ютера, підключаючи localhost. Отже, з точки зору сокетів, сервер - це сам домашній комп'ютер. Але логічно я підключився до свого робочого комп’ютера. Це заплутано.
Кальмарій

357

Я намалював кілька ескізів

Машина, на якій набрана команда ssh tunnel, називається « ваш хост» .

ssh тунель, починаючи з місцевих


ssh тунель, починаючи з віддаленого

Вступ

  1. місцеві: -L Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side.

    ssh -L sourcePort:forwardToHost:onPort connectToHostозначає: підключіться з ssh до connectToHostта переадресуйте всі спроби підключення до локального sourcePort до порту onPortна машині forwardToHost, що називається , до якої можна дістатися з connectToHostмашини.

  2. віддалений: -R Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side.

    ssh -R sourcePort:forwardToHost:onPort connectToHostозначає: підключіться з ssh до connectToHostта переадресуйте всі спроби підключення до віддаленого sourcePort до порту onPortна машині forwardToHost, що називається , до якої можна дістатися з вашої локальної машини.

Додаткові параметри

  • -f повідомляє ssh самому фону після його автентифікації, тому вам не доведеться сидіти, виконуючи щось на віддаленому сервері, щоб тунель залишився живим.
  • -Nговорить, що ви хочете з'єднання SSH, але насправді не хочете запускати віддалені команди. Якщо все, що ви створюєте, - це тунель, то включення цієї опції економить ресурси.
  • -T вимикає розподіл псевдо-tty, що підходить, оскільки ви не намагаєтесь створити інтерактивну оболонку.

Ваш приклад

Третє зображення являє собою цей тунель. Але синій комп'ютер під назвою "ваш хост" являє собою комп'ютер, де хтось запускає ssh-тунель, в даному випадку машина, що захищається фаєром.

Отже, попросіть когось запустити ssh-тунельне підключення до вашої машини. В основному команда повинна виглядати так

ssh -R 12345:localhost:22 YOURIP

Зараз тунель відкритий. Тепер ви можете підключитися через ssh до машини з фаєром через тунель командою

ssh -p 12345 localhost

який підключиться до вашого власного localhost(вашої машини) на порту 12345, але порт 12345передається через тунель до порту 22 локального хосту комп'ютера, що захищається (тобто самого комп'ютера, що захищається пером).


9
Чудова відповідь! Буде використовувати це у презентації.
Ісая Тернер

4
Дякую. Ласкаво просимо. Якщо ви хочете векторні зображення (svg або pdf), напишіть мені повідомлення.
erik

1
@erik, Як ти малював ці зображення?
Pacerier

31
о людино, я б хотів, щоб на сторінках man могли бути такі пояснення! Дякую!
Лукас Поттерський

30
Знаєш, що ? Мені навіть не довелося читати пояснення тексту. Чудова робота !
deppfx

21

ssh тунелювання працює за допомогою вже встановленого ssh-з'єднання для надсилання додаткового трафіку.

Під час підключення до віддаленого сервера у вас зазвичай є лише 1 канал для нормальної взаємодії з користувачем (або 3 канали, якщо ви вважаєте, що STDIN / STDOUT / STDERR є окремими). У будь-який час локальний або віддалений ssh-процес може відкрити додаткові канали для існуючого з'єднання. Потім ці канали надсилають / приймають тунельний трафік. Під час надсилання або отримання будь-якого трафіку процес ssh просто говорить "цей трафік призначений для каналу foobar".

Це по суті працює так:

  1. Ви говорите ssh для початку прослуховування в порту XXXX, і будь-який отриманий трафік повинен бути тунельований, а потім встановити значення YYYY на порт ZZZZ.
  2. Місцевий ssh ​​починає слухати на порту XXXX (як правило, увімкнено 127.0.0.1, але його можна змінити).
  3. Деяка програма відкриває з'єднання з портом XXXX на локальній машині.
  4. Місцевий ssh ​​відкриває канал до віддаленого ssh і каже, "будь-який трафік на цьому каналі йде на РРРР: ZZZZ
  5. Віддалений ssh ​​підключається до РРРР: ZZZZ і повертає назад "OK, канал відкритий"
  6. Тепер будь-який трафік, надісланий уздовж з'єднання до порту XXXX на локальній машині, прошивається ssh до YYYY: ZZZZ.

Цей процес є абсолютно однаковим як для прямого, так і для зворотного тунелювання (просто поміняйте слова "локальний" та "віддалений" у вищевказаній процедурі). Будь-яка сторона може запустити тунель. Це навіть не повинно бути при першому запуску ssh. Ви можете відкривати тунелі, поки ssh вже працює (див. ESCAPE CHARACTERSКонкретно ~C).

Для ролі -R, -f, -Lі -Nви на самому справі потрібно просто звернутися до сторінці, це дає вам найкраще можливе пояснення. Але згадаю -Rі -L.
-Rповідомляє віддаленому ssh прослуховувати з'єднання та що локальний ssh ​​повинен підключитися до реального пункту призначення. -Lвказує місцевому ssh прослуховувати з'єднання, а віддалений ssh ​​повинен з'єднуватися з реальним пунктом призначення.

Зауважте, це дуже грубе опис, але воно повинно дати вам достатньо інформації, щоб знати, що відбувається


16

Це пояснено в посібнику з SSH, особливо різниці між -L(локальними) та -R(віддаленими).


-L

-L [bind_address:]port:host:hostport

Вказує, що даний порт на локальному (клієнтському) хості повинен бути пересланий на даний хост і порт на віддаленій стороні .

Це працює, виділяючи сокет для прослуховування порту на локальній стороні, необов'язково прив’язаний до вказаної адреси bind_address.

Кожного разу, коли встановлено з'єднання з цим портом, з'єднання передається через захищений канал, а з'єднання здійснюється до hostпорту hostportз віддаленої машини .

Наступний приклад тунелює сеанс IRC з клієнтської машини 127.0.0.1( localhost) за допомогою порту 1234 на віддалений сервер server.example.com:

$ ssh -f -L 1234:localhost:6667 server.example.com sleep 10

Примітка: -fФоновий параметр ssh та віддалена команда sleep 10задаються, щоб дозволити кількість часу для запуску послуги, яку потрібно тунелювати.

Приклад:

ssh `-N` -L 22000:localhost:11000 remote.server.com
  • -N Після підключення просто повісьте там (ви не отримаєте підказку оболонки)

    Не виконуйте віддалену команду.

  • -L 22000З'єднання відбуватиметься на порту 22000 вашого персонального апарату L- ocal

  • localhost:11000- remote.server.comпереконається, що другий кінець тунелю - localhostпорт11000

ssh -N -L 22000: 192.168.1.2: 11000 remote.server.com

Джерело: Ілюстрований посібник, навчальний посібник, практичні вказівки щодо тунелювання на ssh .


-R

-R [bind_address:]port:host:hostport

Вказує, що даний порт на віддаленому (серверному) хості повинен бути пересланий на даний хост і порт на локальній стороні .

Це працює, виділяючи сокет для прослуховування portна віддаленій стороні, і щоразу, коли з'єднання здійснюється з цим портом, з'єднання пересилається через захищений канал, і встановлюється з'єднання для hostпорту hostportз локальної машини .

Приклад:

ssh -N -R 22000:localhost:11000 remote.server.com
  • -N Після підключення просто повісьте там (ви не отримаєте підказку оболонки)

    Не виконуйте віддалену команду.

  • -R22000 Підключення буде здійснюватися на порту 22000 комп’ютера R emote (у цьому випадку remote.server.com)

  • localhost:11000ваш особистий локальний комп'ютер переконається, що другий кінець тунелю - localhostпорт11000

ssh -N -R 22000: localhost: 11000 remote.server.com

Джерело: Ілюстрований посібник, навчальний посібник, практичні вказівки щодо тунелювання на ssh .


6
вухо і рот дозволяють зрозуміти, хто говорить і хто слухає!
Туфір

1
Я люблю ваші ілюстрації!
mcantsin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.