Как работает обратное SSH туннелирование?

350

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

Основанный на обратном ssh-соединении и SSH-туннелировании Made Easy , обратное SSH-туннелирование может использоваться, чтобы обойти надоедливые ограничения брандмауэра.

Я хотел бы выполнять команды оболочки на удаленной машине. Удаленная машина имеет собственный брандмауэр и находится за дополнительным брандмауэром (маршрутизатором). У него есть IP-адрес, например 192.168.1.126 (или что-то подобное). Я не за брандмауэром, и я знаю IP-адрес удаленного компьютера, как видно из Интернета (не адрес 192.168.1.126). Кроме того, я могу попросить кого-нибудь выполнить ssh (something)сначала как root на удаленной машине.

Может ли кто-нибудь объяснить мне, шаг за шагом, как работает обратное туннелирование SSH, чтобы обойти брандмауэры (брандмауэры локальных и удаленных машин и дополнительный брандмауэр между ними)?

Какова роль переключателей ( -R, -f, -L, -N)?

Али
источник
4
Связанный (с практическими рекомендациями
Жиль

Ответы:

403

Я люблю объяснять такие вещи с помощью визуализации. :-)

Думайте о своих соединениях 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точкой входа emote. Все, что подключается к порту 22222 в дальнем конце туннеля, фактически достигнет «порта 22 локального хоста», где «локальный хост» находится с точки зрения точки выхода из туннеля (т. Е. Вашего клиента 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 -адресе , прочитайте этот пост )

Ghoti
источник
2
как насчет ssh -D. Пожалуйста, объясните, используя тот же метод.
BigSack
6
SOCKS прокси не совпадают с туннелями. Если у вас есть вопрос о том, как их использовать, пожалуйста, задайте его .
ghoti
12
Мне очень трудно следовать этому объяснению из-за слабого использования терминов: сервер, клиент, локальный компьютер, удаленный компьютер, хост, yourpublichost, localhost, remotehostname. Со всеми этими свободными и неопределенными терминами можно предположить, что кому-то потребуется целых 8 компьютеров, чтобы настроить это. Я утверждаю это, потому что во всех других аспектах это кажется очень хорошим объяснением. Пожалуйста, уменьшите и определите термины.
Rucent88
4
@ Rucent88, я не уверен, какое сокращение будет возможно. Клиент устанавливает соединение с сервером. Это общая терминология во всем мире сетей. Локальные и удаленные машины кажутся довольно очевидными. Если после прочтения документации вы не понимаете, что такое SSH или общая терминология Unix, я уверен, у вас не возникнет проблем с поиском людей, готовых ответить на любые ваши вопросы.
ghoti
9
@ghoti Это действительно сбивает с толку, потому что локальные и удаленные машины являются относительными. Когда я сижу на рабочем месте, мой домашний компьютер является удаленным, когда я сижу дома, компьютер на рабочем месте является удаленным. Сервер и клиент также сбивают с толку, говоря о туннелировании. Например, если я подключаюсь к дому с работы с помощью ssh -R. Я подключаюсь к своей работе с домашнего компьютера, подключив localhost. Таким образом, с точки зрения сокетов, сервер сам является домашним компьютером. Но логически я подключился к своему рабочему компьютеру. Это сбивает с толку.
Кальмариус
356

Я нарисовал несколько эскизов

Компьютер, на котором набрана команда 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 локального хоста компьютера с брандмауэром (то есть самого компьютера с брандмауэром).

Erik
источник
9
Отличный ответ! Будет использовать это в презентации.
Исаия Тернер
4
Спасибо. Пожалуйста. Если вы хотите, чтобы векторные изображения (SVG или PDF) напишите мне сообщение.
Эрик
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 и говорит "любой трафик на этом канале идет в YYYY: ZZZZ
  5. Удаленный SSH подключается к YYYY: ZZZZ и отправляет обратно «ОК, канал открыт»
  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 Öçal машины

  • 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: локальный хост: 11000 remote.server.com

Источник: иллюстрированное руководство, учебное пособие, инструкции по туннелированию ssh .

kenorb
источник
6
ухо и рот ясно показывают, кто говорит, а кто слушает!
Thufir
1
Я люблю твои иллюстрации!
mcantsin