Туннелирование портов. Как работает SSH-туннелирование. Локальный проброс порта

В данной статье будет описано как строить SSH–туннели с помощью PuTTY.

1. Локальный проброс порта

Рассмотрим следующую ситуацию. Мы находимся внутри корпоративной сети, у нашего компьютера адрес 192.168.0.2, доступ во внешний мир полностью закрыт (то есть никакого NAT–а, proxy и т.п.). Влиять на политику ограничения доступа у нас возможности нет, но зато есть SSH–доступ на один из серверов с маршрутизируемым IP–адресом, который доступен из Интернет. Внутренний адрес этого сервера, пусть будет для примера 192.168.0.3. Структура сети изображена на рисунке:

Предположим, что нам очень нужно подключиться, к примеру, по SSH на некоторый удалённый сервер с IP–адресом 212.212.212.212 где–то далеко в Интернет. Для этого запускаем PuTTY, создаём SSH–подключение к серверу 192.168.0.3 (далее по тексту SSH–сессия 1), идём в пункт Tunnels:

и указываем, что локальный порт 2222 нашего компьютера должен быть поставлен в соответствие порту 22 на сервере с IP–адресом 212.212.212.212. Далее жмём кнопку «Open», авторизуемся на сервере 192.168.0.3. Затем создаём ещё одно подключение (далее по тексту SSH–сессия 2), но уже на localhost, порт 2222 и жмём кнопку «Open»:

В результате SSH–сессия 2 будет туннелироваться (т.е. будет установлена внутри ранее установленной SSH–сессии 1). Для удалённого сервера 212.212.212.212 всё будет выглядеть так, как будто к нему подключается 111.111.111.111:

2. Удалённый проброс порта

В этом случае подключение внутри SSH–туннеля устанавливается в другую сторону - от удалённого сервера на наш локальный компьютер. Может быть полезно, если требуется открыть доступ к локальным сервисам нашего компьютера. Рассмотрим ту же сеть, что и в пункте 1, но для простоты предположим, что теперь у нас есть NAT:

Здесь уже у нас есть возможность подключаться через SSH напрямую к 212.212.212.212 благодаря наличию NAT–а. А вот 212.212.212.212 подключиться на 192.168.0.2 без специальных ухищрений, понятное дело, не сможет, т.к. 192.168.0.2 не подключён к Интернет непосредственно. Предположим, что пользователю, сидящему под X–ами на 212.212.212.212 нужно через remote desktop попасть на наш компьютер 192.168.0.2. Для этого в SSH–сеансе подключения с 192.168.0.2 на 212.212.212.212 нужно изменить настройки в разделе Tunnels следующим образом:

#lsof -i -nP | grep 3333 sshd 18598 avz 11u IPv4 592868957 TCP 127.0.0.1:3333 (LISTEN)

То есть sshd ожидает подключений на TCP–порт 3333, которые затем по SSH–туннелю будут перенаправлены на 192.168.0.2 порт 3389. И юзер сидящий за 212.212.212.212 сможет с помощью rdesktop увидеть наш рабочий стол:

3. Socks–proxy

В этом случае мы можем использовать сервер с SSH–демоном как промежуточный (proxy). Схема сети как в случае #1 (без NAT и штатных прокси):

Чтобы заставить PuTTY исполнять роль socks–прокси, нужно параметры SSH–сессии с 192.168.0.2 на 192.168.0.3 изменить следующим образом:

C:\>netstat -ano | find "1080" TCP 127.0.0.1:1080 0.0.0.0:0 LISTENING 2392 C:\>tasklist | find /i "2392" putty.exe 2392 Console 0 5420 КБ

То есть putty, выполняющийся с PID–ом 2392, начинает слушать порт 1080, ожидая подключений. Далее бёрем любое приложение, умеющее работать с SOCKS–прокси, например Firefox, и указываем ему использовать наш прокси:

Теперь все запросы от браузера будут проходить через сервер 192.168.0.3. В логах веб–сайтов, по которым мы таким образом будем ходить, будет отображаться внешний IP–адрес нашего сервера - 111.111.111.111.

P.S. Из help–файла Putty 0.58:

Question A.10.3: What does «PuTTY» mean?

It"s the name of a popular SSH and Telnet client. Any other meaning is in the eye of the beholder. It"s been rumoured that «PuTTY» is the antonym of «getty», or that it’s the stuff that makes your Windows useful… :)

Please enable JavaScript

© 2009–2019, сайт - При использовании материалов сайта желательно указывать источник. Спасибо!

Mar 28, 2012 By Jayson Broughton
in HOW-TOs SysAdmin

"Если вы видите свет в конце туннеля, то это свет приближающегося поезда", - Роберт Лоуэлл. Еще одна хорошая цитата. Эта статья посвящена построению туннелей с помощью SSH, или, как я называю эту тему, "VPN-туннелям для бедных". Несмотря на основные верования системных администраторов, туннели SSH на самом деле могут быть весьма полезной вещью как для технарей, так и для домашнего использования. Я сказал "несмотря на верования сисадминов" потому, что реверсивные туннели или завернутый в SSH веб-трафик могут продираться через межсетевые экраны и контентные фильтры. Статья, однако, не про то, как вам повергнуть корпоративную политику безопасности, а про то, как SSH-туннелирование может сделать нашу жизнь чуть-чуть менее сложной.

Почему SSH туннели вместо VPN? Ок, я использую дома то и то. Если вы следили за моими сообщениями на jaysonbroughton.com, то знаете, что у меня в работе трехфакторая аутентификация OpenVPN (имя пользователя, сертификат и одноразовый пароль). Но если я хочу проверить один из серверов под моим управлением через Андроид, или заглянуть в компьютер, на котором я не имею административных прав (а они нужны портативному OpenVPN-клиенту), или даже хочу исправить какие-то ошибки с помощью vnc-доступа поверх SSH-туннеля, тогда SSH - мой выбор способа обезопасить трафик.

Мы обсудим базовые вещи: как построить туннель, что означает тот или иной синтаксис команды, разберем примеры реверсивных туннелей и ситуации, в которых вы должны использовать тот или другой подход. Я также поверхностно пробежался по структуре конфигурационног файла.

Итак, о системных требованиях. Я использую Дебиан в виртуальной среде, поэтому ваши результаты могут отличаться от моих. Поэтому привожу информацию о инструментах: эксплуатируется сервер OpenSSH_5.3p1 и различные по версиям клиенты OpenSSH 5.X. Перед тем, как погрузиться в глубины ssh-туннелирования должен сказать: перед тем, как проковырять дыру в безопасности компании с помощью реверсивного туннеля или заворачивания http-трафика убедитесь, что вы не нарушите какого либо стека внутренних регламентов типа Internet Acceptable Use Policy. Понятно, что в этом случае Системные Администраторы немедленно выследят и поджарят вас, особенно если вы используете туннель для попадания на сервер на работе из дома. В качестве Системного Администратора сам я получаю немалое удовольствие, обнаружив таких персонажей. Поверьте, при небольшой проверке выяснится, что системные администраторы вовсе не держиморды.

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

Построение SSH-туннелей довольно несложная вещь. Понимание того, что происходит и изучение подходов может оказаться несколько сложнее. Поэтому я дам несколько типичных случаев для настройки сознания перед тем, как мы перейдем к подробностям команд. До того, как у меня появились дети, я довольно много путешествовал. В своих путешествиях мне приходилось оказываться в весьма странных отелях, в комнатах которых были весьма странные Wi-Fi точки доступа. Вы действительно захотите коннектится к точке доступа отеля, у которой SSID набран непереводимой абракадаброй? Или в аэропорту, где несколько открытых сетей? Когда я где-то во внешнем мире, предпочитаю туннелировать веб-трафик на свой рутованный андроид через домашний сервер. Когда у меня в руках мой лэптоп, я открываю ssh-туннель и перенаправляю веб-трафик через socks5 так, чтобы весь входящий ко мне поток был шифрованным. Я доверяю открытым WAP лишь постольку, поскольку могу через них ходить. Что еще об открытом тексте? Я туннелирую SMTP трафик на своем компьютере через домашний сервер когда в некоторых местах вижу, что исходящий SMTP блокируется. Похожая ситуация с POP3. Другой пример: можно управлять X-приложениями через туннель. Можно заворачивать в туннель VNC-сессии. Одна из техник, которую я начал использовать раньше других - это реверсивные туннели. В этом случае вы создаете туннель от сервера, который находится за межсетевым экраном. Когда вы заходите на тот SSH-сервер, вы можете восстановить соединение.

Примеры

Перед тем, как глянуть со стороны клиента, нужно выполнить некоторые вещи на стороне сервера с помощью редактирования конфигурационного файла sshd.config, где я советую произвести указанные ниже изменения. Перед внесением изменений скопируйте оригинальный конфиг для сохранности, если что-то пойдет не так как задумано.

Если внесли изменения, должны перезапустить sshd-сервер для их применения.

Перейдем к ключам командной строки.

Типичный ssh-туннель (без туннелирования Х-протокола) выглядит примерно так:

Как можно догадаться, опция -X обеспечивает туннелирование Х. Помните однако, что команда обеспечит туннелирование вашего приложения с вашей удаленной машины на вашу клиентскую машину с Линуксом. Если же вы в Виндоус, просто установите Cygwin/X (http://x.cygwin.com/) на вашу гостевую машину. Я сам этого не пробовал, но как понимаю это должно помочь запустить удаленное Х-приложение в Виндоус.

Когда вы переходите к установлению VNC-сессий, нужно быть осторожным. Если удаленный сервер с VNC запущен на 5900 порту, впоследствии убедитесь, что вы не подключились к самому себе. Сама же сессия туннелируется как и в других случаях с помощью прозрачной команды:

И вот вы его заимели, реверсивный туннель.

Для наглядности daddoo и nerdboy4200 из #linuxjournal объединили свои усилия и создали Mscgen, это программулина, которая парсит последовательность сообщений и строит наглядную диаграмму обмена сообщениями для разных протоколов. Она конечно, опенсорсная и довольно ужасна на вид (http://www.mcternan.me.uk/mscgen/). Для случая реверсивного туннеля с помощью своего поделия они построили диаграмму (далее автор вставил в свой текст диаграмму, на которой ничего не видно - прим. перев.).

Заключение

Итак, то, что вы можете наворотить с помощью туннелирования ограничено лишь вашим воображением, здесь мы только дали несколько примеров. Возможно, в последующих постах я расскажу, как правильно настроить SSH на клиентской стороне.

SSH туннелирование пригодится для обхода неких ограничений установленных брандмауэром или же просто для создания безопасного туннеля передачи данных. Кроме прямого SSH туннелирования можно также сделать проброс данных с локального порта через SSH туннель на некий порт некой удалённой машины или наоборот.

Как в случае прямого SSH туннелирования так и с пробросом порта, на одной из сторон всегда должен быть установлен рабочий SSH сервер! SSH туннелирование даёт возможность бродить по сети от имени того компьютера, к которому был организован SSH туннель. Например если у нас имеется доступ к SSH где-то в Зимбабве, то при помощи SSH туннеля мы можем лазить по сети от имени Зимбабве:)

Прямое SSH туннелирование

Что имеется ввиду под "Прямое SSH туннелирование "? Прямое SSH туннелирование это когда SSH клиент запускается в режиме sock-proxy (опция -D ) и соединившись с удалённой машиной по SSH протоколу передает через неё (удалённую машину ) TCP трафик, например сессия прямого SSH туннеля с удалённой машиной через консольный SSH клиент (OpenSSH ) в Windows:

C:\OpenSSH\bin> ssh -D 4444 -p 28666 user@ remotehost.com The authenticity of host "remotehost.com (96.172.128.114)" cant be establishe d. RSA key fingerprint is 5e:ea:62 :5f:fc:3b:b2:38 :d6:ba:6b:aa:65 :3f:d4:35 . Are you sure you want to continue connecting (yes/ no) ? y Please type "yes" or "no" : yes Warning: Permanently added "remotehost.com,96.172.128.114" (RSA) to the list o f known hosts. user@ remotehost.com password: Last login: Thu Feb 7 03:34 :45 2013 from 108.95.46.202 [ user@ remotehost ~] $

Запуская SSH клиент с опцией -D 4444 мы повелеваем ему после запуска прослушивать локальный порт 4444 и после подключения к удалённому хосту remotehost.com, на удалённый порт -p 28666 и с именем пользователя user, отправлять наш TCP трафик к месту назначения от своего имени - т.е. от имени remotehost.com с ИП 96.172.128.114.

Проброс порта через SSH туннель на порт удалённой машины

В этом случае, после подключения по SSH протоколу с удалённой машиной [email protected], данные с локального порта через SSH туннель удаленной машины будут переданы будут переданы дальше на некий порт некой удалённой машины, например прокси-серверу. Выглядит это примерно так:

ssh -L [ bind_address:] port:host:hostport -p 28666 user@ remotehost.com

Аналогично предыдущему примеру с той лишь разницей, что конечной точкой пересылающей/принимающей наш TCP трафик будет не [email protected], а некий host:hostport

Есть также вариант проброса TCP трафик с удалённого порта удалённой машины [email protected] на локальный порт локальной машины или ещё куда-нибудь.

ssh -R [ bind_address:] port:host:hostport -p 28666 user@ remotehost.com

В консольных ssh клиентах для Unix подобных ОС есть ещё одна полезная опция -C (Requests compression of all data ) для сжатия данных, которая отсутствует в ssh клиенте (OpenSSH ) для Windows, но есть в PLINK.EXE от PuTTY .

В качестве SSHD для Windows можно предложить WinSSHD , а в качестве консольного SSH клиента под Windows OpenSSH соответственно или на худой конец PLINK.EXE от PuTTY .

SSH тунель в PuTTY

Для использования в PuTTY SSH туннелирования в настройках " Сonnection -> SSH -> Tunnels " введите:

Source port: 4444 Destination: localhost:4444

Отметьте пункт " Dynamic " и нажмите " Add ". В " Session " укажите нужное " Host Name " имя хоста, укажите SSH протокол и сохраните настройки выбрав в " Saved Sessions " подходящее имя, ну, например, " HostName aka ssh tunnel on 4444 " и сохраните " Save ", после чего двойным кликом на этом имени установите соединение.

Когда SSH-соединение будет установлено, мы сможем использовать свой браузер через локальны прокси на порту 4444. Зайдите на любую веб-страницу, где определяется ваш IP адрес и убедитесь в том, что определяется не ваш реальный IP адрес, а IP адрес удаленной машины.

Вложенные SSH туннели

Допускаются вложенные SSH туннели, например:

ssh -L [ bind_address:] port:host:hostport -p 28666 user@ remotehost1.com \ ssh -L [ bind_address:] port:host:hostport -p 28666 user@ remotehost2.com ssh -L 192.168.0.2:8080 :127.1 :9999 user@ 8.8.8.8 \ ssh -L 127.1 :9999 :127.1 :80 user2@ 10.1.1.2

В этом примере (рисунок ниже ) мы бросаем данные с порта 8080 компьютера "А" (192.168.0.2 ), на локальный хост и порт 9999 компьютера "Б" (8.8.8.8 ), а сразу после подключения к компьютеру "Б" (8.8.8.8 ) запускаем на нём ssh клиент, принимаем данные (127.1:9999 ) и бросаем их дальше на локальный хост 127.1:80 компьютера внутренней сети 10.1.1.2.

Реверс сокс-прокси. По идее офицеры службы безопасности, которые озабочены запретом Интернета на машине 10.1.1.2, должны повыдёргивать на попе все волосы, ибо приведённая ниже команда должна организовать доступ к сети Интернет для машины 10.1.1.2 через сокс-прокси, который запущен на машине «А».

ssh -D 8080 -R 127.1 :8080 :127.1 :8080 user@ 8.8.8.8 \ ssh -R 127.1 :8080 :127.1 :8080 user@ 10.1.1.2

Конфигурация SSHD

Для гарантированного обхода ограничений фаервола можно в конфигурации SSHD демона /etc/ssh/sshd_config открыть сразу несколько портов , т.е. SSHD будет принимать запросы сразу по нескольким портам, например.

Существует три различных типа туннелирования, и все они используются для решения разных задач. Каждая задача предполагает использование SSH-сервера для перенаправления трафика из одного сетевого порта в другой. Трафик передается по зашифрованному SSH-соединению , поэтому его нельзя отследить или изменить в процессе передачи:

Туннелирование можно реализовать с помощью ssh-команды в Linux , Mac OS и операционных системах семейства UNIX . Для пользователей Windows , где нет встроенной ssh-команды , мы предлагаем бесплатный инструмент PuTTY . Он умеет подключаться к SSH-серверам . Он также поддерживает SSH-туннелирование .

Локальное перенаправление портов (port forwarding): получаем доступ к удалённым ресурсам на локальной системе

«Локальное перенаправление портов » позволяет осуществлять доступ к ресурсам, находящимся внутри локальной сети. Предположим, что нужно попасть на офисный сервер БД, сидя дома. В целях безопасности этот сервер настроен так, чтобы принимать подключения только с ПК, находящихся в локальной сети офиса. Но если у вас есть доступ к SSH-серверу , находящемуся в офисе, и этот SSH-сервер разрешает подключения из-за пределов офисной сети, то к нему можно подключиться из дома. Затем осуществить доступ к БД. Проще защитить от атак один SSH-сервер , чем защищать каждый ресурс локальной сети по отдельности.

Чтобы сделать это, вы устанавливаете SSH-соединение с SSH-сервером и говорите клиенту передать трафик с указанного порта на локальном ПК. Например, с порта 1234 на адрес сервера базы данных и его порт внутри офисной сети. Когда вы пытаетесь получить доступ к БД через порт 1234 на вашем ПК («localhost ») трафик автоматически «туннелируется » по SSH-соединению и отправляется на сервер БД.

SSH-сервер выступает посредником, пересылая трафик туда-сюда. При этом можно использовать любую командную строку или графический инструмент для осуществления доступа к базе данных, как вы обычно делаете это на локальном ПК.

Чтобы использовать локальное перенаправление, подключитесь к SSH-серверу с использованием вспомогательного аргумента -L . Синтаксис для туннелирования трафика будет следующим:

ssh -L local_port:remote_address:remote_port [email protected]

Предположим, что офисный сервер находится по адресу 192.168.1.111 . У вас есть доступ к SSH-серверу через адрес ssh.youroffice.com , и имя вашего аккаунта на SSH-сервере — bob . В таком случае необходимая команда будет выглядеть следующим образом:

ssh -L 8888:192.168.1.111:1234 [email protected]

Запустив эту команду, вы попадете на офисный сервер баз данных через порт 8888 на localhost . Если у СУБД есть веб-интерфейс, можно вписать в адресную строку браузера http://localhost:8888 . Если у вас инструмент командной строки, которому необходим сетевой адрес базы данных, то направьте его на localhost:8888 . Весь трафик, отправленный на порт 8888 на ПК, будет перенаправлен на 192.168.1.111:1234 внутри офисной сети:


Это слегка сбивает с толку, если надо подключиться к серверному приложению, запущенному в той же системе, где и сам SSH-сервер . К примеру, есть SSH-сервер , работающий на порте 22 на офисном ПК. Но у вас также есть сервер баз данных, работающий на порте 1234 в той же системе по тому же адресу. Вам нужно подключиться к БД из дома, но система принимает только SSH-подключение через 22 порт , и сетевой экран не пропускает любые внешние подключения. В таком случае можно запустить следующую команду:

ssh -L 8888:localhost:1234 [email protected]

При попытке подключиться к БД через 8888 порт на вашем ПК, трафик будет передаваться с помощью SSH-подключения . Когда он достигнет системы, в которой работает SSH , SSH-сервер отправит его на порт 1234 на «localhost », принадлежащий тому же ПК, на котором запущен SSH-сервер . То есть, «localhost » в приведённой выше команде означает «localhost » с перспективы удалённого сервера:


Чтобы сделать это в PuTTY на Windows , выберите опцию Connection > SSH > Tunnels . Далее опцию «Local ». В поле «Source Port » укажите локальный порт. В поле «Destination удалённый_адрес:удалённый_порт .

Например, если нужно настроить SSH-тоннель , как это сделано выше, то введите 8888 в качестве порта-источника и localhost:1234 в качестве целевого адреса. После этого нажмите «Add » и затем «Open », чтобы открыть SSH-подключение . До подключения SSH туннелирования нужно ввести адрес и порт самого SSH-сервера в разделе «Session »:


Дистанционное перенаправление портов: открываем доступ к локальным ресурсам на удалённой системе

«Дистанционное перенаправление портов » — ситуация, противоположная локальному перенаправлению, и используется не так часто. Она позволяет открывать доступ к ресурсам на локальном ПК через SSH-сервер . Предположим, что на локальном ПК настроен веб-сервер. Но ваш ПК защищён сетевым экраном, который не пропускает входящий трафик на сервер.

Если есть доступ к удалённому SSH-серверу , можно подключиться к этому SSH-серверу и использовать дистанционное перенаправление портов. Ваш SSH-клиент укажет серверу перенаправлять трафик с определённого порта – скажем, 1234 – на SSH-сервере на указанный адрес и порт на вашем ПК или внутри локальной сети. Когда кто-то подключается к порту 1234 на SSH-сервере , этот трафик автоматически «туннелируется » по SSH-соединению . Любой, кто подключается к SSH-серверу , сможет получить доступ к серверу, запущенному на вашем ПК. Это достаточно эффективный способ обхода фаерволов.

Чтобы воспользоваться дистанционным туннелированием IP , используйте ssh-команду с аргументом —R . Синтаксис здесь будет практически таким же, как и в случае с локальным перенаправлением:

ssh -R remote_port:local_address:local_port [email protected]

Предположим, что нужно создать серверное приложение, прослушивающее порт 1234 на вашем ПК. Оно доступно через порт 8888 на удалённом SSH-сервере . Адрес SSH-сервера ssh.youroffice.com , а ваше имя пользователя на SSH-сервере bob . Значит, команда будет следующей:

ssh -R 8888:localhost:1234 [email protected]

Затем кто-то может подключиться к SSH-серверу через порт 8888 , и это подключение будет туннелировано на серверное приложение, запущенное на порте 1234 ПК , с которого вы подключались:


Чтобы сделать это в PuTTY для Windows , выберите опцию Connection > SSH > Tunnels . Далее – опцию «Remote ». В поле «Source Port » укажите удалённый порт. В поле «Destination » введите целевой адрес и порт в формате локальный_адрес:локальный_порт .

Например, если нужно настроить SSH-тоннель , как это сделано выше, то укажите 8888 в качестве порта-источника и localhost:1234 в качестве целевого адреса. После этого нажмите «Add » и затем «Open », чтобы открыть SSH-подключение . До подключения нужно будет ввести адрес и порт самого SSH-сервера в разделе «Session ».

После этого пользователи смогут подключаться к порту 8888 на SSH-сервере и их трафик будет передаваться на порт 1234 на вашей локальной системе:


По умолчанию, удалённый SSH-сервер будет слушать только подключения с того же хоста. Другими словами, доступ будет только у людей из той же системы, на которой запущен SSH-сервер . При туннелировании трафика так делается в целях безопасности.

Нужно включить опцию «GatewayPorts » в sshd_config на удалённом SSH-сервере , если хотите изменить эти настройки.

Динамическое перенаправление портов: используем SSH-сервер в качестве прокси

Также существует «динамическое перенаправление портов », которое работает по тому же принципу что прокси или VPN-сервер . SSH-клиент создаёт SOCKS-прокси , который можно настраивать под собственные приложения. Весь трафик, отправляемый через прокси, будет отправляться через SSH-сервер . Принцип здесь схож с локальным перенаправлением – берётся локальный трафик, отправленный на определённый порт на вашем ПК, и перенаправляется через SSH-соединение на удалённый адрес.

Предположим, что вы используете общедоступную Wi-Fi сеть. Но хочется делать это безопасно. Если у вас есть доступ к SSH-серверу из дома, то можно подключиться к нему и использовать динамическое перенаправление. SSH-клиент создаст SOCKS-прокси на вашем ПК. Весь трафик, отправленный на этот прокси, будет отправляться через подключение к SSH-серверу . Никто из тех, кто использует общедоступную Wi-Fi сеть, не сможет отслеживать ваши перемещения в сети или закрывать доступ к сайтам. С перспективы сайтов, которые посещаете, будет казаться, что вы заходите на них с домашнего ПК.

Или же может понадобиться подключиться к медиа-серверу, находящемуся в вашей домашней сети. В целях безопасности, к интернету подключен только ваш SSH-сервер . При этом вы не разрешаете подключаться к медиа-серверу через интернет. В таком случае можно включить динамическое перенаправление портов, настроить SOCKS-прокси в браузере и затем подключаться к серверам, работающим в домашней сети, через браузер, как будто вы сидите дома.

Например, если медиа-сервер находится по адресу 192.168.1.123 в вашей домашней сети, то можно добавить адрес 192.168.1.123 в любое приложение при помощи SOCKS-прокси и получить доступ к медиа-серверу, как будто вы находитесь внутри домашней сети.

Чтобы воспользоваться динамическим перенаправлением, запустите ssh-команду с аргументом —D :

ssh -D local_port [email protected]

Предположим, что у вас есть доступ к SSH-серверу по адресу ssh.yourhome.com , а ваш логин на SSH-сервере – bob . Нужно использовать динамическое перенаправление для того, чтобы открыть SOCKS-прокси по порту 8888 на текущем ПК. Тогда команда для SSH туннелирования будет выглядеть следующим образом:

ssh -D 8888 [email protected]

После этого можно настроить браузер или другое приложение на использование локального IP-адреса (127.0.0.1) и порта 8888 . Весь трафик этого приложения будет перенаправляться через туннель:


Чтобы сделать это в PuTTY для Windows , выберите опцию Connection > SSH > Tunnels . Далее – опцию «Dynamic ». В поле «Source Port » укажите локальный порт.

Например, если вам нужно настроить SOCKS-прокси на порт 8888 , то введите 8888 в качестве порта-источника. После этого нажмите «Add » и затем «Open », чтобы открыть SSH-подключение .

В статье дан подробный анализ теории и практики построения SSH-туннелей на базе PuTTY. Информации по этому поводу в интернете очень много, однако она не носит систематического характера и зачастую представляет собой лишь разрозненный набор практических рецептов.

Терминология

Для упрощения понимания материала в статье использована терминология, которой я строго придерживаюсь и которая имеет чёткий смысл.

Клиент — компьютер-источник запросов. Например, браузер или ssh-клиент.
Сервер — компьютер-обработчик запросов. Например, десктоп в локальной сети.
Базовая схема — схема взаимодействия, в которой участвуют лишь Клиент и Сервер.
Расширенная схема — расширение базовой схемы, когда Клиент и Сервер опосредованы Прокси.
Прокси — компьютер-посредник между Клиентом и Сервером в расширенной схеме.
Прямой туннель — туннель, в котором направление инициирования SSH-сесии и запросов совпадают.
Обратный туннель — направление инициирования SSH-сессии и клиентских запросов противоположны.
Source port (исходный порт) — порт на одном из концов туннеля, куда приходит запрос от Клиента.
Может быть для PuTTY локальным «Local» (на том же конце туннеля, что и PuTTY) и удалённым «Remote» (на противоположном конце).
Destination (адрес назначения) — IP-адрес и порт компьютера, для которого предназначены пакеты, выходящие из туннеля. В расшриренной схеме это всегда сам Сервер.

SSH-туннели создаются для решения 2-х независимых задач:

  1. Обеспечение конфиденциальности данных, передаваемых по защищённому каналу
  2. Создание связующего мостика (или нескольких мостиков) между Клиентом и Сервером через промежуточные компьютеры, так как Клиент может не иметь прямого доступа к Серверу. В этом случае конфиденциальность является второстепенной или вовсе не требуется.

SSH-туннели могут быть организованы как в режиме перенаправленя отдельных TCP-портов (Port forwarding), так и в режиме настоящих VPN-туннелей через виртуальные интерфейсы, когда передаваться может трафик любых протоколов и с любых портов. В данной статье мы рассмотрим первый режим.

При работе в режиме Port Forwarding пакет, поступающий на входной порт туннеля, должен быть передан в неизменном виде на его выходной порт. Такая схема применяется в работе интернет-шлюзов: пакеты с одного интерфейса передаются на другой без изменения и анализа.

Таким образом, SSH-канал в этом режме со всей его инфраструктурой напоминает виртуальный шлюз с входным и выходным интерфейсами, но только по конкретной паре TCP-портов:

Стрелкой указано направление инициирования SSH-сессии. В данном случае инициатором соединения выступает Клиент с установленным на нём PuTTY.

Приведённая выше схема является базовой, в которой взаимодействуют лишь 2 участника Клиент и Сервер. На практике же между Клиентом и Сервером может быть несколько промежуточных хостов. И до попадания на вход конкретного туннеля и после выхода из него пакеты могут передаваться по незащищённым каналам.

Для установления связи по SSH-протоколу необходима учётная запись на SSH-сервере, которая может быть любой, в том числе без каких бы то ни было прав и даже без шелла, если вы открываете на прослушивание непривелигированные порты от 1024 и выше. В противном случае необходим рутовый доступ и значение директивы PermitRootLogin равное yes или without-password .

Анализ связности и доступности участников взаимодействия

Приступая к решению задачи о том, как обеспечить доступ с Клиента на Сервер, полезно построить схему связности участников взаимодействия по SSH-протоколу, поскольку именно по этому протоколу создаются туннели, через которые затем можно пропустить данные любого другого протокола.

Для этого мы должны ответить на вопрос, где находятся SSH-серверы и доступны ли они с помощью SSH-клиентов с других хостов.

Рассмотрим эти шаги на базе расширенной схемы, состоящей из Клиента, промежуточного Прокси-сервера и Сервера. На практике такие схемы встречаются чаще всего.

Если соединять стрелками машины, доступные по SSH-протоколу, то возможны следующие варианты:

В частности, мы соединяем стрелкой Клиента с Прокси, если Прокси доступен с Клиента на 22-м порту. Перебрав попарно всех участников взаимодействия, получим схему связности. Например:

Стрелки схемы связности показывают, откуда может быть инициирован туннель на машину с SSH-сервером.

После построения схемы связности необходимо убедиться в доступности участников взаимодействия друг для друга по произвольным протоколам и портам, поскольку к созданному туннелю нужно как-то подключаться, либо, наоборот переправлять данные далее. Иными словами, необходимо проверить пингуются они или нет. По аналогии со схемой связности можно построить схему доступности, которая как минимум совпадает со схемой связности, но чаще всего шире её:

Схема доступности показывает, в каком направлении можно передать данные по незащищённому туннелем каналу.

Комбинация обеих схем помогает ответить на вопрос о том, имеется ли принципиальная возможность установления соединения Клиента с Сервером, а если её нет, то что надо добавить, чтобы её получить.

В дальнейшем мы воспользуемся этими схемами для построения канала связи.

Приведённая выше схема очень распространена: Клиент и Сервер (чаще всего на базе Windows) находятся в разных локальных сетях за NAT, имеют выход в интернет и «видят» удалённый Прокси-сервер, тогда как с Прокси они недоступны ни по SSH ни по другим протоколам. На Прокси, как правило, установлена *nix-подобная операционная система, в которой SSH-сервер есть по умолчанию.

В схемах на базе *nix систем практически все звенья полносвязные, поскольку на всех машинах имеются SSH-серверы, а SSH-порты обычно открыты для подключений.

Алгоритм построения канала связи с помощью SSH-туннелей

Разберём алгоритм построения канала связи с помощью SSH-туннеля на примере схемы, приведённой выше, где Клиент и Сервер находятся в разных локальных сетях за NAT-ами, и могут быть связаны только через Интернет с помощью некоторого Прокси-сервера.

1) Составление схемы SSH-связности

SSH-сервер у нас имеется только на Прокси, поэтому мы можем инициировать 2 туннеля: с Клиента и с Сервера:

Это схема с двумя односвязными звеньями.

2) Составление схемы доступности

Клиент и Сервер находятся за NAT, поэтому недоступны извне с Прокси, но Прокси пингуется как с Клиента, так и с Сервера

3) Выбор звена для создания туннеля

Для обеспечения связи между Клиентом и Сервером достаточно одного туннеля — либо Клиент-Прокси, либо Прокси-Клиент, так как на оставшемся участке пакеты можно передать по незащищённому каналу.

Туннель Клиент-Прокси выглядит предпочтительнее, поскольку в таком случае все операции по организации связи мы смогли бы произвести с Клиента, и с него же по условиям задачи требуется работать с Сервером.

Пакеты, поступающие на вход туннеля на компьютере Клиента, передаются на Прокси и затем должны перенаправляться на адрес назначения (Destination), которым является Сервер. Однако согласно схеме доступности, Сервер недоступен с Прокси через интернет:

Поэтому для передачи пакетов не обойтись без создания второго туннеля между Прокси и Сервером:

А вот первый туннель, на который мы возлагали надежды, будет в такой схеме избыточен — мы можем направлять пакеты с Клиента на Прокси через незащищённую среду напрямую без использования туннеля:

Туннель Клиент-Прокси можно оставить лишь в том случае, если это важно с точки зрения конфиденциальности (по нему что-то передаётся открытым текстом и т.п.).

4) Выбор типа туннеля Прокси-Сервер: прямой или обратный

На самом деле тип туннеля уже предопределён. Запросы клиента поступают на порт источника (Source Port), который находится на Прокси, а туннель инициируется с Сервера. Это значит, что направление инициирования туннеля и запросов клиента будут противоположны. Следовательно туннель будет обратным (опция -R).

5) Прописывание параметров подключения и создания туннеля

Таким образом, вырисовывается следующий алгоритм построения канала связи

  1. Составить схему SSH-связности, исходя из расположения SSH-серверов
  2. Составить схему доступности.
  3. Выбрать звено: Клиент-Прокси или Прокси-Сервер (для расширенной схемы)
  4. Выбрать направление инициирования туннеля, если звено полносвязное.
  5. Выбрать тип туннеля, отталкиваясь от направления запросов клиента: прямой или обратный
  6. Написать формулы проброса портов в PuTTY (Source port, Destination и дополнительные опции) для каждого туннеля

Понимая описанные выше принципы, легко выставить правильные настройки как на вкладке SSH-Tunnels в PuTTY, так и в командной строке OpenSSH-клиента. В частности, справедливы следующие аксиомы:

Source port — это порт туннеля, на который поступают запросы Клиента.
Если направление инициирования туннеля и запросов Клиента совпадают (прямой туннель), то порт находится на том же конце, что и PuTTY и является для PuTTY локальным (опция -L, Local).
В противном случае Source port находится на противоположной стороне обратного туннеля и для PuTTY является удалённым (опция -R, Remote)
В 99% случаев Source port открывается на прослушивание на петлевом интерфейсе той машины, на которую приходят запросы от Клиента, и поэтому обычно опускается. В PuTTY для IP-адреса источника запросов даже не предусмотрено отдельного места — только Source port.

Destination — это IP-адрес и порт компьютера, на который передаются данные на выходе из туннеля. Если PuTTY находится на Destination, то это, очевидно, будет localhost.
В отличие от петлевого IP-адреса на входе туннеля, данные на выходе из туннеля могут передаваться куда угодно, в том числе на хосты с другими IP-адресами.

Этого достаточно, чтобы выставить правильные настройки для всех вариантов SSH-туннелей. Наиболее типичные из них представлены далее на конкретных примерах.

Приведу, также, синтаксис командной строки OpenSSH клиента в терминах PuTTY, если вы захотите инициировать туннель с какой-нибудь *nix-системы по базовой схеме:

ssh [-g] [-p port] : user@Сервер

и по расширенной схеме:

ssh [-g] [-p port] : user@Прокси

Здесь под понимается порт с ключами, например: -L 5000 (прямой туннель), -R 5000 (обратный туннель) или -D 5000 (динамический проброс порта; в этом случае опускается)
[-p port] — соединиться с Сервером или Прокси на порт, отличный от 22.
[-g] — опция, разрешающая подключение к локальному (Local) или динамическому (Dynamic) порту не только с localhost, но и с внешних адресов.

Для разрешения аналогичной возможности подключения к удалённому (Remote) порту с внешних адресов необходимо прописать в конфигурационном файле SSH-сервера /etc/ssh/sshd_config опцию:

GatewayPorts clientspecified

благодаря которой включение этой возможности производится по запросу клиента, либо

GatewayPorts yes

когда эта опция включена всегда.

Базовая схема

В базовой схеме взаимодействия участвуют лишь 2 компьютера, соединённые туннелем.

По этой схеме возможны 2 вида туннелей — прямой и обратный, в зависимости от того, с какой стороны выполняется инициирование SSH-сессии. Согласно этому, PuTTY всегда находится на том конце туннеля, где стрелка начинается.

Расширенная схема

Расширением базовой схемы является схема с промежуточным прокси-сервером, к которому либо подключается Клиент, либо с которого устанавливается соединение с Сервером. Здесь возможны 4 варианта.

В принципе, все четыре варианта расширенной схемы равноправны, если абстрагироваться от конкретной реализации SSH-клиента. Но коль скоро мы рассматриваем в данной статье работу через PuTTY, то инициировать туннели мы можем только с машин на базе Windows, т.е. чаще всего либо с Клиента, либо с Сервера.

Ситуации, в которых SSH-сессия с помощью PuTTY инициируется с промежуточного сервера, довольно редки, так как прокси-серверы обычно представляют собой машины без графической оболочки под управлением *nix-подобных ОС, и вместо PuTTY там будет OpenSSH.

Для полноты картины ниже рассмотрен и синтаксис OpenSSH клиента в терминах PuTTY, если вдруг вам понадобится инициировать туннель с помощью OpenSSH.

Практические примеры применения SSH-туннелей

1. Прямой туннель по базовой схеме

Рассмотрим защиту открытого протокола от перехвата на примере POP3.

Вместо того, чтобы получать почту на локальном компьютере напрямую через интернет и подвергать себя риску утраты пароля, передаваемого в открытом виде, мы получаем её через туннель с почтовым сервером на порт 110. Почтовый клиент в данном случае должен быть настроен на получение писем с адреса localhost:5000

Схема приведена в иллюстративных целях, поскольку все почтовые клиенты сейчас умеют работать по защищённым протоколам, а выбор портов строго ограничен.

Клиент# ssh -L 5000:Сервер:110 user@Сервер

Схема связности и доступности для системы с Сервером за NAT:

Это тот случай, когда вам по локальной сети нужно зайти с одного компьютера (Клиент) на другой (Сервер), но прямого соединения с ним не предусмотрено. Однако, с Сервера доступ к Клиенту имеется. Для этого SSH-сессия инициируется с Сервера, то есть с компьютера, к которому мы хотим подключиться. В результате создаётся обратный туннель.

Для поднятия обратного туннеля на Клиент необходимо установить SSH-сервер и указать, с какого удалённого порта (Remote Source port) на какой локальный для PuTTY будет выполняться проброс.

Эквивалентная команда для OpenSSH клиента:

Сервер# ssh -R 5000:localhost:3389 user@Клиент

Схема связности и доступности для системы с Клиентом за NAT:

Такая схема позволяет безопасно подключаться к интернету через непроверенные источники, например Wi-Fi точки доступа в кафе и ресторанах. Весь трафик идёт через точку доступа в зашифрованном виде с удалённого Сервера.

Как известно, браузер направляет запросы к сайтам в интернет с произвольных портов WAN-интерфейса компьютера. В PuTTY такой режим предусмотрен в в виде опции Dynamic. Все запросы браузера через туннель направляются с некоторого исходного порта 5000 на компьютере с SSH-клиентом, а на другом конце назначаются динамически. Поэтому конечный порт не прописывается.

Поскольку браузеры не умеют работать через SSH-туннели напрямую, в настройках подключения через прокси-сервер нужно выбрать подключение через SOCKS (v5) на адрес localhost:5000 и удалить localhost или 127.0.0.1 из поля «Не использовать прокси для:», если он там прописан автоматически.

Эквивалентная команда для OpenSSH клиента:

Клиент# ssh -D 5000 user@Сервер

Добавляя опцию -g, которая эквивалентна опции PuTTY «Local ports accept connections from other hosts», можно разрешить другим компьютерам подключаться к Клиенту на указанный порт и превратить его, таким образом, в точку доступа.

Схема аналогична предыдущей, только с обратной схемой связности (Клиенту запрещён выход в интернет).

Это значит, что инициировать туннель мы можем только с Сервера. Очевидно, что на Клиенте должен быть развёрнут SSH-сервер. Для Клиентов на базе Windows хорошим выбором будет Bitvise SSH-сервер на 443 порту. FreeSSHd сервер с обратными туннелями у меня не заработал.

Итак, чтобы схема работала, нужно сделать из Сервера Socks proxy на 5000-м порту, создав туннель с самим собой:

Сервер# ssh -D 5000 user@Сервер

А после этого установить обратный туннель с Клиентом, в котором запросы на порт XXXX перенаправляются на 5000 порт нашего Socks proxy:

Сервер# ssh -R XXXX:localhost:5000 user@Клиент

Особенность такой схемы в том, что обратные туннели по цепочке можно пробрасывать и далее на другие компьютеры, не имеющие доступа в интернет.

Эта идея лежит в основе аналогичной схемы из данной статьи , но в ней туннель инициируется в обратном направлении выражением следующего вида:

Прокси# ssh -D 5000 -R XXXX:localhost:5000 user@Сервер

А уже затем к Серверу с помощью обратного туннеля подключается компьютер, не имеющий доступа в интернет:

Сервер# ssh -R YYYY:localhost:XXXX user@Компьютер

Однако в данном случае интернет-запрос на порт Сервера XXXX по обратному туннелю перенаправляется на компьютер, играющий роль Прокси-сервера, а затем возвращается на Cервер, чтобы быть обслуженным на нём же:

Очевидно, что в таком способе используется лишняя петля, состоящая из Туннелей 2 и 3, которую мы исключили выше, организовав раздачу интернета непосредственно с самого Сервера.

5. Прямой туннель на промежуточный SSH-сервер

В даном случае туннель создаётся с промежуточным Прокси-сервером, а уже с него выполняется подключение к конечному удалённому Серверу.

Такая схема выручает тогда, когда с локального компьютера нет прямого доступа в интернет, но есть доступ к некоторому серверу внутри локальной сети, который подключен к интернет. Пример схемы связности и доступности для случая, когда Клиент и Прокси находятся за NAT, а Сервер доступен из Интернета:



В другом случае Сервер находится в удалённой локальной сети и недоступен из интернета напрямую, но к нему можно подключиться через промежуточный Прокси в той же локальной сети. Возможная схема связности и доступности для случая, когда Прокси является шлюзом, а Клиент разсположен за NAT в собственной LAN:



В обоих случаях Клиенту нужно подключиться на адрес localhost:5000.

Эквивалентная команда для OpenSSH клиента:

Клиент# ssh -L 5000:Сервер:3389 user@Прокси

Эта схема уже подробно рассматривалась в самом начале:

В даном случае нам нужно зайти с домашнего компьютера на удалённый, к которому нет доступа из интернет, но есть промежуточный Прокси, доступный как для Клиента, так и для Сервера. Мы выяснили, что связь можно наладить только с помощью обратного туннеля Сервера с Прокси.

Для разрешения удалённого подключения Клиента необходимо также отметить опцию . Эта опция работает только в том случае, когда разрешение на подключение на удалённый порт по запросу клиента разрешено в файле конфигурации ssh-демона Прокси-сервера /etc/ssh/sshd_conf :

GatewayPorts clientspecified

После этого Сервер должен стать доступным с Клиента по RDP на адрес Прокси:5000

Эквивалентная команда для OpenSSH клиента:

Сервер# ssh -R 5000:localhost:3389 user@Прокси