Создание SSH-туннелей с помощью PuTTY. Что такое 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 на клиентской стороне.

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

Очень часто, когда речь заходит об удаленном доступе к сетям с низким уровнем безопасности, первое что приходит на ум - это VPN, однако ради административных соединений поднимать VPN не всегда целесообразно, особенно если речь идет об аутсорсинге или "приходящем админе". Кроме того, не всегда условия связи позволяют поднять устойчивое VPN-соединение, особенно если приходится использовать мобильные сети.

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

Строго говоря, SSH-туннели не являются полноценными туннелями и это название следует рассматривать как сложившееся в профессиональной среде устойчивое наименование. Официальное название технологии - SSH Port Forwarding - это опциональная возможность протокола SSH, которая позволяет передать TCP-пакет с одной стороны SSH-соединения на другую и произвести в процессе передачи трансляцию IP-заголовка по заранее определенному правилу.

Также, в отличие от VPN-туннелей, которые позволяют передавать любой трафик в любом направлении, SSH-туннель имеет точку входа и может работать только с TCP-пакетами. По факту это больше всего похоже на проброс портов (о чем и говорит официальное название), только поверх протокола SSH.

Рассмотрим работу SSH-туннеля более подробно. В качестве примера возьмем классический случай обеспечения доступа к некоторому удаленному серверу по протоколу RDP.

Допустим, что в удаленной сети существует целевой сервер с адресом 192.168.0.105, но доступа к нему из внешней сети нет, единственное устройство к которому мы можем подключиться - это маршрутизатор с адресом 192.168.0.1 с которым мы можем установить SSH-соединение.

Остановимся на очень важном моменте: все параметры SSH-туннеля устанавливает инициатор подключения, он же SSH-клиент , вторым концом туннеля всегда является сервер, к которому мы подключаемся, он же SSH-сервер . В данном контексте следует понимать клиент и сервер сугубо как стороны соединения, например, в роли SSH-клиента может выступать VPS-сервер, а в роли SSH-сервера ноутбук админа.

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

Рассмотрим схему выше. Мы установили SSH-туннель с локальной машины к удаленному маршрутизатору, указав локальную точку входа 127.0.0.1:3389 и правило трансляции 192.168.0.105:3389 . Еще раз обращаем ваше внимание, что правило трансляции не указывает на точку выхода, а определяет узел, которому будут посланы пакеты по выходу из туннеля. Если вы укажете недействительный адрес, либо узел не будет принимать соединения, то SSH-туннель установится, но доступа к целевому узлу не будет.

Согласно указанной точке входа служба SSH создаст локальный TCP-сокет, который будет ожидать подключений на порт 3389. Поэтому в окне RDP-подключения указываем в качестве назначения localhost или 127.0.0.1 , RDP-клиент открывает динамический порт и отсылает пакет с адресом назначения 127.0.0.1:3389 и адресом источника 127.0.0.1:61256 , о реальном назначении получателя пакета ему ничего не известно.

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

Таким образом RDP-клиент работает с локальным сокетом и далее этого узла RDP-пакеты не уходят, внутри туннеля они передаются поверх протокола SSH в зашифрованном виде, а вот между SSH-сервером и RDP-сервером в сети 192.168.0.0 устанавливается обычное RDP-соединение, в открытом виде. Это следует учитывать при использовании небезопасных протоколов, твердо запомнив, что если правило трансляции указывает за пределы узла с точкой выхода, то такое соединение (между точкой выхода и узлом назначения) не защищается посредством SSH.

Разобравшись в общих чертах как работают SSH-туннели перейдем к практическим вариантам их использования, в качестве платформы мы будем рассматривать Linux-системы семейства Debian/Ubuntu, но все нижеизложенное с небольшими поправками будет справедливо для любой UNIX-подобной системы.

SSH-туннель с локальной точкой входа

Туннели с локальной точкой входа используются для получения доступа к узлам в удаленной сети при возможности установить SSH-соединение с одним из ее узлов, что предполагает наличие у удаленной сети выделенного IP-адреса.

Мы будем рассматривать все тот-же вариант, RDP-подключение к удаленному серверу, оранжевым пунктиром на схеме обозначено безопасное SSH-соединение, синими стрелками - обычное TCP-подключение.

В самом простом варианте мы просто устанавливаем соединение с клиентского ПК к маршрутизатору в удаленной сети, указывая в правиле трансляции целевой узел:

Ssh -L 127.0.0.1:3389:192.168.0.105:3389 [email protected]

Ключ -L указывает на то, что точка входа расположена локально, затем через двоеточие указываются адрес и порт точки входа и адрес, порт правила трансляции. Точкой выхода является узел, к которому мы подключаемся, т.е. rt.example.com .

Если в вашей сети также присутствует маршрутизатор (или иной Linux-сервер), то можно сделать точкой входа его, что позволит подключаться к удаленному серверу любому RDP-клиенту из локальной сети. В теории для этого следует поднять такой туннель:

Ssh -L 192.168.31.100:3389:192.168.0.105:3389 [email protected]

В таком случае служба SSH должна будет открыть TCP-сокет на интерфейсе 192.168.31.100, но на практике этого не произойдет. Это связано с особенностями реализации OpenSSH, который является стандартом для подавляющего большинства UNIX-подобных систем.

По умолчанию OpenSSH открывает точку входа только на локальном интерфейсе . В этом несложно убедиться:

Для того, чтобы предоставить доступ к TCP-сокету с внешних интерфейсов следует использовать ключ -g , либо добавить в конфигурационный файл /etc/ssh/sshd_config опцию:

GatewayPorts yes

Однако после этого сокет будет принимать соединения с любого сетевого интерфейса инициатора:

Это значит, что порт 3389 будет открыт на всех сетевых интерфейсах, поэтому если точка входа является пограничным устройством, то следует ограничить доступ к сокету, например, средствами iptables. Для примера заблокируем доступ из внешней сети (интерфейс eth0):

Iptables -A INPUT -i eth0 -p tcp --dport 3389 -j DROP

Таким образом рабочий туннель следует поднимать командой:

Ssh -L -g 3389:192.168.0.105:3389 [email protected]

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

Также мы советуем использовать по возможности ключ -g , а не добавление опции в конфигурационный файл, так как в последнем случае вы рискуете, забыв об этой настройке, открыть наружу доступ к незащищенным службам удаленной сети.

SSH-туннель с удаленной точкой входа

Туннель с удаленной точкой входа позволяет наоборот опубликовать любую локальную службу в удаленной сети, одно из наиболее частых применений - доступ в сети без выделенного IP-адреса, однако это требует "белый" IP со стороны сети администратора.

В первом варианте удаленный сервер сам устанавливает подключение с маршрутизатором локальной сети. Это можно сделать простой командой:

Ssh -R 3389:127.0.0.1:3389 [email protected]

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

Внимательный читатель заметит, что мы не указали ключ -g , да, это так. Дело в том, что для туннелей с удаленной точкой входа данный ключ неприменим и следует использовать опцию

GatewayPorts yes

на стороне SSH-сервера.

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

Iptables -P INPUT DROP
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT

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

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

Ssh -R 3389:192.168.0.105:3389 [email protected]

Снова обратим ваше внимание, что точка входа у нас располагается на противоположной стороне туннеля, поэтому трансляция указывается для стороны инициатора туннеля, т.е. в данном случае SSH-клиент устанавливает два соединения: одно SSH с rt.example.com, а второе RDP c 192.168.0.105, тогда как при туннеле с локальной точкой входа инициатор устанавливает единственное соединение с SSH-сервером.

Двойной SSH-туннель

Достаточно часто возникают ситуации, когда требуется соединить два узла не имеющих выделенных IP-адресов. В этом случае обычно используется TeamViewer или аналогичное стороннее ПО, но если у вас есть доступный сервер с выделенным IP-адресом, то можно поступить проще.

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

Туннель с локальной точкой входа на ПК админа:

Ssh -L 3389:127.0.0.1:3390 [email protected]

И туннель с удаленной точкой входа на RDP-сервере:

Ssh -R 3390:127.0.0.1:3389 [email protected]

Мы специально указали на удаленном сервере нестандартный порт для большей наглядности и теперь давайте посмотрим, как все это работает. Начнем с RDP-сервера, он поднимает туннель с удаленной точкой входа, открывая на промежуточном сервере TCP-сокет, который будет принимать подключения на порт 3390, в качестве трансляции укажем сам RDP-сервер - 127.0.0.1:3389, т.е. все пришедшие на вход этого туннеля пакеты будут направлены на локальный порт 3389.

Туннель с локальной точкой входа на ПК админа открывает локальный сокет на порт 3389, куда будет подключаться RDP-клиент, в качестве трансляции мы указываем точку входа второго туннеля - 127.0.0.1:3390.

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

Динамический SSH-туннель

В отличие от рассмотренных выше динамический туннель работает иначе, он открывает на хосте локальный TCP-сокет, который можно использовать как SOCKS4/SOCKS5 прокси для выхода в интернет через удаленный SSH-сервер. Это может быть полезно для обхода некоторых ограничений, когда поднимать полноценный VPN в другой юрисдикции нет необходимости, а использовать публичные прокси или VPN нельзя по соображениям безопасности.

Такой вид туннеля особенно удобен, если требуется разовый выход в интернет с другого узла. Простой пример: мой хороший знакомый привез из Штатов два операторских контрактных iPhone и попросил их разблокировать. Сложностей данная операция не таит, если условия контракта не были нарушены, то достаточно зайти на сайт оператора и заполнить заявку на разблокировку. Но проблема оказалась в том, что у оператора T-Mobile доступ к данному разделу сайта был доступен только для жителей США, а соединения с публичных прокси и VPN отвергались как небезопасные.

Динамический SSH-туннель позволил быстро решить эту проблему используя VPS в Штатах. Чтобы создать такой туннель введите команду:

Ssh -D 1080 [email protected]

Где 1080 - порт на котором будет доступен наш SOCKS-прокси. Остается только настроить браузер на использование локального прокси-сервера.

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

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

Несколько слов о безопасности

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

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

Поэтому после того, как вы проверили работоспособность туннеля запускать его следует с ключом -N, который запрещает выполнение команд на удаленном сервере, например:

Ssh -N -L -g 3389:192.168.0.105:3389 [email protected]

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

SSH-туннели в Windows

На протяжении всей статьи мы рассматривали SSH-туннели на примере Linux-систем и у пользователей Windows могло сложиться впечатление, что им данные возможности недоступны. Но это не так, под Windows существует множество SSH-клиентов, которые поддерживают создание тоннелей. Мы будем рассматривать наиболее популярного из них - PuTTY . Также под Windows можно запустить и SSH-сервер, но это требует определенной квалификации и не всегда можно добиться стабильной работы, поэтому этот вариант мы рассматривать не будем.

Откроем PuTTY и в левой части дерева перейдем в Connection - SSH -Tunnels :

Перед нами откроется следующее окно, основные настройки туннеля сосредоточены внизу, и мы выделили их красной рамкой. Source port - предназначен для указания порта точки входа, которая всегда располагается на локальном интерфейсе (127.0.0.1). Destination - трансляция, т.е. куда будут отправлены пакеты с точки выхода. Радиопереключатели Local - Remote - Dynamic задают тип туннеля и аналогичны ключам -L , -R и -D .

После того, как вы заполнили все необходимые поля можно добавить туннель кнопкой Add . Чтобы разрешить внешним узлам доступ к локальному сокету точки входа установите галочку Local ports accept connections from other hosts . В данном случае следует также ограничить доступ к открытым портам средствами брандмауэра Windows или стороннего сетевого фильтра.

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

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

  • Теги:

Please enable JavaScript to view the

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

Рассмотрим создание и настройку по нескольким вариантам.

И так, у нас имеется сервер, назовём его host-1 . К нему у нас есть полный доступ только по SSH — но нам необходимо открыть Tomcat , работающий на порту 8082 — к которому нас никак пропустить не могут.

Рассматривать вариант будем с настройкой Windows и Putty .

Открываем SSH -соединение к нужному серверу, логинимся.

Указываем такие параметры:

Source port: любой неиспользуемый порт в вашей системе;
Destination port: 127.0.0.1:8082

Жмём Add , потом Apply .

Переходим в настройки браузера, и устанавливаем параметры прокси:

Теперь остаётся в браузере открыть страницу http://localhost:3002 — и попадаем на страницу Tomcat на сервере host-1 .

Если туннель не работает — проверьте на сервере, включена ли пересылка пакетов. В файле /etc/ssh/sshd_config найдите и раскоментируйте строку:

AllowTcpForwarding yes

И перезапустие SSHd:

# service sshd restart Stopping sshd: [ OK ] Starting sshd: [ OK ]

Ещё один пример — у нас есть тот же внешний сервер, с которого есть нормальный доступ к любым ресурсам в Сети. А вот с рабочего места у нас доступ к и закрыт.

Выполняем похожие действия, но с небольшими отличиями. Настройки в Putty :

Source port — оставляем прежний, но вместо Local — выбираем Dynamic . Нажимаем Add , Apply .

Переходим к настройкам браузера:

Обратите внимание, что тип прокси тут не HTTP — а SOCKS .

Наслаждаемся доступом к любимым сайтам.

И более интересный случай.

Имеем прежний host-1 . Кроме него — второй сервер, назовём его host-2 . Кроме этого — у нас есть машина с Windows , которой необходимо предоставить доступ к ресурсу TeamCity на сервере host-1 на порту 8111. При этом — доступ с Windows -машины у нас есть только к серверу host-2 , и только на 22-ой порт.

Для начала — поднимаем туннель между host-1 и host-2 . Выполняем на host-1 :

$ ssh -f -N -R host-2:8082:localhost:8111 username@host-2

Так мы открываем туннель, который локально (на host-1 ) смотрит на порт 8111 , а с другой стороны — машина host-2 , на которой открывается порт 8082 , и ждёт входящих соединений. При получении пакетов на порт 8082 (при чём — только по интерфейсу lo0 ! это важно) — он будет их перенаправлять на машину host-1 порт 8111 .

Что касается интерфейса lo0 . При установлении SSH -туннеля, даже при указании внешнего IP машины — соединение поднимается только с localhost , т.е. 127.0.0.1 .

Посмотрим на host-2 :

$ netstat -anp | grep 8082 tcp 0 0 127.0.0.1:8082 0.0.0.0:* LISTEN -

Что бы изменить это — необходимо отредактировать файл конфигурации демона sshd — /etc/ssh/sshd_config и изменить параметр:

#GatewayPorts no

Но сейчас мы этого делать не будем, это просто заметка.

Продолжим. Переходим к настройке Putty на нашей Windows -машине. Тут всё просто — пользуемся примером 1 из этой статьи, только меняем порт на нужный (в скриншоте, кстати, он и есть). Подключаемся Putty к хосту host-2 , настраиваем tunnel . В браузере меняем настройки proxy — и получаем необходимое, указываем адрес http://localhost:3002:

SSH довольно чувствителен к потерям пакетов, поэтому туннели могут часто обрываться.

Что бы избежать этого — можно либо поиграться с параметрами в файле настроек sshd — /etc/ssh/sshd_config:

#TCPKeepAlive yes #ServerAliveInterval #ServerAliveCountMax

Либо — воспользоваться утилитой autossh.

В статье дан подробный анализ теории и практики построения 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@Прокси