Создание ssh туннеля. Создание SSH-туннелей с помощью PuTTY. Прямой туннель на промежуточный SSH-сервер

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-команды в 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-подключение .

Posted by: admin октября 17th, 2017

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



SSH туннель или SSH Port Forwarding, как его называет man(1) ssh – это опциональный функционал протокола, который работает поверх всем знакомой обычной SSH сессии. SSH туннель позволяет послать TCP пакет с одной стороны SSH соединения на другую его сторону и произвести трансляцию IP заголовка по заранее определенному правилу в процессе передачи.

Понять, как работает SSH туннель очень просто: если представить его в виде point-to-point соединения. Так же как и в PPP, любой пакет, попавший в один конец соединения, будет передан и получен на другом конце туннеля. Дальше, в зависимости от адреса получателя заданного в IP заголовке, пакет будет либо обработан принимающей стороной туннеля (если пакет предназначается непосредственно ей), либо смаршрутизирован дальше в сеть (если адресатом является другой узел сети).

Основное отличие SSH туннеля от PPP соединения в том, что в SSH туннель можно завернуть только TCP трафик. (Примечание: есть несколько хаков, как можно передать UDP через TCP-сокет внутри SSH туннеля, но это решение выходит за рамки данной статьи).

Второе отличие состоит в том, что в point-to-point соединении входящий трафик может быть инициирован с любой стороны, тогда как для SSH туннеля необходимо явно задать «точку входа» для трафика. «Точка входа» – это параметр вида <адрес>:<порт>, указывающий какой сокет открыть для входа в туннель (с локальной или удалённой стороны SSH сессии).

Кроме точки входа дополнительно нужно указать правило вида <адрес>:<порт>, по которому должен быть переписан заголовок (точнее, адрес и порт назначения) TCP пакета в процессе передачи. Точка входа может задаваться с любого конца туннеля. За этот параметр отвечают ключи –L (local) и –R (remote). Под local и remote подразумеваются стороны туннеля с точки зрения стороны-оригинатора, то есть того хоста, который устанавливает SSH сессию.

Пока выглядит немного запутанно, поэтому давайте разберём на конкретном примере.

Прямой туннель SSH - обеспечиваем доступ к серверу за NAT

Алекс работает системным администратором в маленькой компании Qwerty Cakes, занимающейся производством яблочных пирогов. Вся сеть компании находится в одном броадкаст домене 192.168.0.0/24. Для доступа в интернет используется программный маршрутизатор на базе Linux, адрес которого 192.168.0.1 со стороны сети компании и 1.1.1.1 со стороны сети Интернет. На маршрутизаторе поднят и работает демон OpenSSD, который доступен по сокету 1.1.1.1:22. Внутри сети на сервере с адресом 192.168.0.2 установлен внутренний корпоративный портал, на котором до завтрашнего утра Алексу нужно сделать изменения через Web интерфейс. Однако Алекс не хочет задерживаться на работе допоздна, он хочет получить доступ к порталу из дома со своего домашнего компьютера с адресом 2.2.2.2.

Алекс приходит домой и после ужина устанавливает следующее соединение с маршрутизатором компании:

Что произошло? Алекс установил SSH сессию между адресами 2.2.2.2 и 1.1.1.1, при этом открыв локальную «точку входа» в туннель 127.0.0.1:8080 на своем домашнем компьютере:

alex@Alex-PC:~$ sudo lsof -nPi | grep 8080

ssh 3153 alex 4u IPv4 9862 0t0 TCP 27.0.0.1:8080 (LISTEN)

Любой TCP пакет, который попадёт в сокет 127.0.0.1:8080 со стороны компьютера Алекса, будет отправлен по point-to-point соединению внутри сессии SSH, при этом адрес назначения в TCP заголовке будет перезаписан с 127.0.0.1 на 192.168.0.2, а порт с 8080 на 80.

Теперь Алексу, чтобы попасть на портал своей компании, нужно всего лишь набрать в браузере:

Как проходят сетевые пакеты внутри SSH-туннеля

Давайте детально разберём, что произошло с TCP пакетом в процессе его прохождения по SSH туннелю:

1. TCP пакет с адресом источника 127.0.0.1 и адресом и портом назначения 127.0.0.1:8080 попал в сокет 127.0.0.1:8080, открытый процессом ssh;

2. Процесс ssh получил пакет, в соответствии с правилом трансляции переписал адрес и порт назначения на 192.168.0.2:80 и отправил его внутри SSH сессии удалённой стороне 1.1.1.1;

3. Процесс sshd на маршрутизаторе 1.1.1.1 получил пакет и, просмотрев адрес назначения, отправил его хосту 192.168.0.2, переписав при этом адрес источника с 127.0.0.1 на адрес собственного интерфейса 192.168.0.1, для того чтобы получатель, который ничего не знает про существование SSH туннеля, вернул пакет роутеру, а не отправил в свой же localhost 127.0.0.1.

alex@Alex-PC:~$ ssh -L

127.0.0.1:8080:192.0.0.2:80 [email protected]


В данном примере, если бы портал или любой другой ресурс, к которому Алексу нужно получить доступ, находился на самом роутере (например, по адресу 192.168.0.1:80), то команда выглядела бы следующим образом:


Если сервис доступен по адресу localhost (например, локальный SQL сервер), то и к нему можно получить доступ:

alex@Alex-PC:~$ ssh -L

127.0.0.1:13306:127.0.0.1:3306 [email protected]


Конструкции вида -L 127.0.0.1:80:127.0.0.1:80 могут выглядеть, на первый взгляд, довольно странными. Но в них нет ничего сложного, если помнить, что решение о маршрутизации пакета принимается на удалённой стороне туннеля. Нужно помнить основное правило: вторая пара <адрес>:<порт> обрабатывается удалённой стороной туннеля.

Поэтому пакет с адресом назначения 127.0.0.1 в правиле трансляции будет обработан второй стороной SSH сессии, и никак иначе.

Как вы уже, наверное, догадались, точку входа в туннель можно создавать не только на loopback интерфейсе. Если туннель нужно сделать доступным не только для локального хоста, но и для других участников сети, то в качестве адреса сокета можно указать реальный адрес интерфейса.

alex@Alex-PC:~$ ssh -L

10.0.0.5:8080:192.0.0.2:80 [email protected]


Компьютер Алекса Alex-PC имеет два сетевых интерфейса с адресами 2.2.2.2 и 10.0.0.5. В процессе установления сессии ssh откроет сокет 10.0.0.5:8080 на компьютере Alex-PC. Теперь Алекс может получить доступ к порталу 192.168.0.2:80 со своего ноутбука с адресом 10.0.0.4 и со всей своей домашней сети 10.0.0.0/24.

Обратный SSH-туннель - выставить свои ресурсы в интернет

Как я уже говорил, точку входа в туннель можно открывать не только со стороны оригинатора ssh сессии, но и с удалённой стороны, то есть с той, к которой мы устанавливаем ssh сессию. Для этого вместо параметра -L используется параметр -R. Для чего это нужно?

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

На ноутбуке Алекса запущен Web сервер apache доступный по адресу 127.0.0.1 с тестовой копией портала компании. Алексу нужно дать доступ к Web серверу своим коллегам для проведения тестирования интерфейса. Вообще, для подобных целей Алексу неплохо было бы реализовать более надёжную тестовую песочницу. Но так как наш Алекс не более чем виртуальный персонаж этой статьи, он для демонстрации работы SSH туннеля устанавливает сессию между своим ноутбуком и маршрутизатором Linux. А с помощью параметра -R открывает порт 8080 на внутреннем интерфейсе маршрутизатора с адресом 192.168.0.1, который ссылается на сокет 127.0.0.1:80 его тестового Web сервера.

Как видите, на маршрутизаторе процесс sshd открыл локальный сокет 8080

alex@Router:~$

sudo lsof -nPi | grep 8080

sshd

17233 alex 9u IPv4

95930 0t0 TCP 192.168.0.1:8080 (LISTEN)

Давайте посмотрим, что произойдёт с TCP пакетом, отправленным с компьютера 192.168.0.200 в сторону тестового портала, опубликованного на 192.168.0.1:8080:

1. TCP пакет с адресом источника 192.168.0.200 и адресом и портом назначения 192.168.0.1:8080 попадёт в сокет 192.168.0.1:8080, открытый процессом sshd;

2. Процесс sshd, получив пакет, в соответствии с правилом трансляции перепишет адрес и порт назначения с 192.168.0.1:8080 на 127.0.0.1:80 и отправит его внутри SSH сессии стороне-оригинатору 2.2.2.2;

3. Процесс ssh на ноутбуке Алекса, получив пакет и просмотрев адрес его назначения, перепишет адрес отправителя с 192.168.0.200 на адрес своего loopback, и отправит его в локальный сокет 127.0.0.1:80, открытый процессом apache.


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

Одно важное замечание, которое я оставил на конец статьи.

Если при открытии точки входа в туннель используется localhost вместо адреса реального интерфейса, то его можно опустить, сократив, таким образом, команду с

alex@Alex-PC:~$ ssh -L 127.0.0.1:8080:192.0.0.1:80 [email protected]

до

alex@Alex-PC:~ssh -L

8080:192.0.0.1:80 [email protected]

Эта важная особенность синтаксиса пригодится нам в следующем примере.

Двойное туннелирование

Давайте посмотрим на чуть более сложный пример. Пользователю SQL-Tester, находящемуся за NAT, нужно получить доступ к базе данных на SQL сервере, который тоже находится за NAT. SQL-Tester не может установить соединение напрямую к серверу, так как в NAT серверной сети нет соответствующих трансляций. Однако от обоих хостов можно установить SSH сессию с промежуточным сервером 3.3.3.3.


С SQL сервера устанавливаем SSH соединение с сервером 3.3.3.3 и открываем на loopback интерфейсе сервера 3.3.3.3 порт 13306, ссылающийся на локальный сервис SQL, запущенный на локальном сокете 127.0.0.1:3306 SQL сервера:

dbuser@SQL-server:~$ ssh -R 13306:127.0.0.1:3306

[email protected]

Теперь с клиентского хоста SQL-Tester устанавливаем соединение с 3.3.3.3 и открываем порт 3306 на loopback интерфейсе клиента, который, в свою очередь, ссылается на 127.0.0.1:13306 на сервере 3.3.3.3, который… ссылается на 127.0.0.1:3306 на SQL сервере. Всё просто.

tester@SQL-Tester:~$ ssh -L

3306:127.0.0.1:13306 [email protected]

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

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

Пример:

Создаём сокет динамического туннеля 127.0.0.1:5555 на хосте client внутри сессии SSH к серверу 2.2.2.2

user@client:~$ ssh -D 5555 [email protected]


Проверяем, что порт открыт

user@client:~$ sudo lsof -nPi | grep 5555

7284 user 7u

IPv4 0x74fcb9e03a5ef5b1 0t0 TCP 127.0.0.1:5555 (LISTEN)

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

Теперь весь трафик браузера будет идти через SOCKS прокси внутри шифрованного соединения SSH между хостами 1.1.1.1 и 2.2.2.2.

Как использовать SSH в Microsoft Windows?

Прочитав статью, вы возможно, решите, что все преимущества SSH туннелей доступны только пользователям Unix-like систем. Однако это не так. Практически все терминальные клиенты для Windows работающие по протоколу SSH имеют поддержку туннелирования.

С некоторых пор, имеется возможность использовать Windows не только в качестве клиента SSH. Есть возможность установить SSH-сервер на Windows.

В каких случаях использовать SSH-туннели?

Конечно же, для создания постоянных туннелей на боевых серверах нужно использовать специальное программное обеспечение. Но для быстрого решения задачи по пробросу портов, траблшутинга, получения быстрого удалённого доступа да и вообще решения конкретной задачи “здесь и сейчас” зачастую хорошим подспорьем будет использование 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
Автор: Jayson Broughton
Дата публикации: 28 марта 2012 г.
Перевод: Алексей Жбанов
Дата перевода: 28 сентября 2012 г.

"Если мы видим свет в конце туннеля, то это свет приближающегося поезда" (Роберт Лоуэлл)

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

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

Я дам здесь лишь самые основы: расскажу, как создавать туннели, объясню синтаксис команд, приведу примеры обратных туннелей и причины для использования каждого из них. Кратко коснусь файла ssh_config; более подробно он будет рассмотрен в будущем.

Итак, с чем мы будем работать? Я использую Debian в виртуальном окружении, поэтому ваши реалии могут отличаться от моих. В данном случае я использовал OpenSSH_5.3p1 в качестве сервера и различные OpenSSH-клиенты 5 версии. Перед тем, как углубиться в туннели, хочу сказать следующее: если вам хочется использовать SSH-туннели для шифрования HTTP или обратные SSH-туннели для обхода корпоративного файервола, удостоверьтесь, что вы не нарушаете никаких правил вашей компании. Нечего и говорить о том, что ваши системные администраторы начнут на вас охотиться, как только обнаружат такие проделки; сам будучи системным администратором, я получаю невыразимое удовольствие, отлавливая подобных индивидуумов. По крайней мере, предупредите их, чтобы они не были застигнуты врасплох. LinuxJournal.com и я не несут никакой ответственности за ваши нарушения вашей же корпоративной политики:-) Ну, а теперь перейдем к делу.

Создать SSH-туннель довольно просто. А вот решить, что с ним делать, может оказаться немного труднее. Поэтому я приведу несколько примеров, прежде чем мы вдадимся в детали. Я в свое время немного попутешествовал - это было на прежнем месте работы и до того, как у меня родились дети. В поездках мне доводилось останавливаться в самых странных гостиницах (думаю, вы с такими знакомы), оснащенных еще более странными беспроводными точками доступа. Захотите ли вы в гостинице подключиться к точке доступа, у которой SSID написан с орфографическими ошибками? Или в аэропорту, где вы обнаруживаете сразу несколько открытых точек? Если я нахожусь не дома, я пущу HTTP-трафик через туннель между своим устройством на Android (с root-доступом) и домашним сервером. Если же я работаю на ноутбуке, то открою SSH-туннель и пущу HTTP-трафик через Socks5 с тем, чтобы он весь был зашифрован средствами SSH. Я не доверяю открытым точкам доступа настолько, насколько могу. Что еще добавить? Мне приходилось "заворачивать" в туннели SMTP-трафик, когда я попадал в такие места, где блокировались исходящие SMTP-пакеты. То же самое мне приходилось делать и с POP3, с которого я недавно перешел на IMAPS. Другие примеры SSH-туннелей включают в себя проброс приложений X11 и сеансов VNC. Ранее я также упоминал обратные туннели. Они представляют собой... ну, вы сами понимаете - туннели, направленные в обратную сторону. В этом случае вы подключаетесь откуда-либо, где нет сервера SSH, к внешнему SSH-серверу. Потом, зарегистрировавшись на этом сервере, в том числе и локально, вы можете восстановить это подключение. Какая в этом польза, говорите? Ну, например, VPN-сервер вашей компании "упал" или работает только с VPN-клиентами под Windows, но вам совершенно не хочется тащиться с ноутбуком домой, чтобы проверить, работает ли тот или иной процесс. Придя домой, вы можете установить обратный туннель. В этом случае вам следует подключиться с сервера "Икс" к вашей домашней машине. Прибыв домой, вы восстанавливаете подключение к серверу "Икс", таким образом обходя файервол или VPN, и проверяете работу процесса без необходимости подключения по VPN. Я поступаю так очень редко, так как, на мой взгляд, подключение к серверу минуя файервол или VPN - это "плохое кунг-фу" и может использоваться лишь в самом крайнем случае.

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

Перед тем, как мы углубимся в работу на клиенте, немного отредактируем файл sshd_config на сервере. В /etc/ssh/sshd_config я обычно вношу некоторые изменения. Но не забудьте перед началом редактирования сделать его резервную копию на случай, если что-то пойдет наперекосяк.

Cp /etc/ssh/sshd_config /etc/ssh/sshd_config.orig # Используем протокол SSH версии 2 Protocol 2 # Включаем режим Privileged Separation для большей безопасности UsePrivilegeSeparation yes # Запрещаем вход от имени root PermitRootLogin no # Запрещаем пустые пароли PermitEmptyPasswords no # Включаем перенаправление X11 X11Forwarding yes X11DisplayOffset 10 # Терпеть не могу сообщений Motd PrintMotd no # Оно живее всех живых! TCPKeepAlive yes

Не забудьте, что если вы внесли какие-либо изменения в sshd_config, то вам нужно будет перезапустить сервис sshd для того, чтобы эти изменения вступили в силу.

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

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

Ssh -N -p 22 [email protected] -L 2110:localhost:110

Здесь ключи означают следующее:

N - не выполнять команд на удаленной машине
-p 22 - подключаться на внешний порт 22. Я обычно использую другой внешний порт, чтобы избавиться от атак "кулхацкеров" на мой SSH-сервер
[email protected] - имя_пользователя@имя_сервера (или IP-адрес)
-L 2110:localhost:110 - информация о привязке портов. Означает следующее: порт_клиента:имя_сервера:порт_сервера. В данном примере мы перенаправляем 110 порт сервера на 2110 порт вашей машины

Хотите еще немного примеров?

Проброс POP3 и SMTP через SSH:

Ssh -N -p 2022 [email protected] -L 2110:localhost:110 -L 2025:localhost:25

Проброс Google Talk через SSH (ключ -g позволяет удаленным машинам подключаться к проброшенным локальным портам):

Ssh -g -p 2022 -N [email protected] 5223:talk.google.com:5223

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

Шифрование HTTP-трафика

Еще одна вещь, понятная без лишних слов. Но если в вашей компании действует какая-либо политика относительно ИТ, проверьте, не нарушаете ли вы ее. Я пускаю HTTP-трафик через SSH в тех случаях, когда не доверяю точке доступа. Под Android я использую приложение SSHTunnel, а на ноутбуке - такую команду:

Ssh -D 5222 [email protected] -N

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

Перенаправление сеансов X и VNC

Ssh -X -p 2022 [email protected]

Вы угадали, -X пробрасывает X. Но учтите, что это работает только на клиентских машинах с Linux. Если вы вдруг оказались вынуждены работать в Microsoft Windows, а вам нужен SSH-туннель, просто установите пакет Cygwin/X (http://x.cygwin.com/). Я лично не пробовал с ним работать, но, насколько я понимаю, он предоставляет возможность запускать удаленные X-приложения, находясь в Windows.

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

Ssh -p 2022 [email protected] -L 5900:localhost:5900

В данном примере вы подключаетесь по SSH на внешний порт 2022 сервера mylinuxserver.com от имени пользователя bob. Локальный порт 5900 пробрасывается на порт 5900 на сервере. После установления соединения вы можете открыть свой VNC-клиент и направить его на localhost:0 для подключения к удаленной машине. Если вы пробросили порт 5901, указывайте "localhost:1" и так далее.

Обратные SSH-туннели

Ну, вот и настало время для моей любимой разновидности SSH-туннелей. Разумеется, получать доступ к какому-либо сервису через SSH - это здорово, "гонять" веб-трафик по зашифрованным SSH-туннелям - тоже, но самое приятное удивление можно испытать от обратных туннелей. Как я уже говорил ранее, ими приходится пользоваться в ситуации, когда имеется машина без SSH-сервера, а вы испытываете необходимость получить к ней доступ в дальнейшем (через несколько минут, часов или дней), но при этом не хотите или не можете воспользоваться VPN. Вам следует соединиться с SSH-сервером с этой машины, а затем установить обратный SSH-туннель, подключившись к этому соединению. Для чего я это применяю? Время от времени - для того, чтобы поработать с удаленным сервером или просто для того, чтобы помочь друзьям и родственникам по VNC через SSH. В последнем случае они запускают Putty с сохраненными настройками сеанса и подключаются к моему SSH-серверу от имени пользователя, не имеющего никаких прав. После создания туннеля я могу зайти по VNC на их машины. И все, им не нужно настраивать файервол или разбираться с LogMeIn или другими подобными сайтами.

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

    На клиентской машине:

    Ssh -R remoteport:localhost:22 username@servername

    На стороне сервера:

    Ssh -p 2048 localhost

И вот вам обратный туннель! Вуаля!

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

Заключение

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




Top