Создать vpn подключение через ssh туннель. Подробный анализ теории и практики использования SSH-туннелей. Локальный проброс порта

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

Что такое SSH туннелирование, для чего оно необходимо

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

А создать SSH туннели вам поможет технология VPN. Суть ее в том, что VPN позволяет создавать частные защищенные сети поверх уже существующих.

Именно таким образом вы и сможете внедрить в сетевой протокол туннель. Но вам для этого понадобится специальная утилита, каких хватает на данный момент в Интернете. Одна из лучших в своем роде — это SSH Tunnel Easy. С ее обзора мы и начнем.

SSH Tunnel Easy

К сожалению, в сети вы не найдете множества обзоров и мануалов по настройке этой программы. Дело в том, что она популярна за рубежом и продается там где-то за 30-50 долларов. Но в Рунете уже давным-давно есть множество «кряков», так что вы обязательно скачаете к себе на компьютер SSH Tunnel Easy.

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

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

Организация туннеля и VPN при помощи OpenSSH

Если вы не хотите искать легких путей, тогда можете воспользоваться стандартной программой OpenSSH для организация туннеля загрузок по сетевому протоколу SSH. Этот способ хорошо подойдет тем, у кого установлена операционная система Ubuntu или Linux. Для начала вам необходимо инсталлировать OpenSSH. Для этого в консоле введите следующую команду: sudo aptitude install openssh-server.

Дело в том, что любой туннель, обратный, прямой и даже многоканальный, можно создать при помощи стандартных возможностей OpenSSH. Но для этого нужно разбираться в возможностях этого приложения и уметь настраивать его конфигурации. Для создания туннеля, вам нужно как минимум дать добро на туннелирование внутри файла config, который определяет настройки SSH протокола. Чтобы разрешить туннелирование, введите следующую строку в файл: PermitTunnel point-to-point. После этого вам нужно будет перезагрузить программу-сервер OpenSSH. Для этого введите следующую команду: service ssh restart.

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

После того, как вы зайдете в root-пользователя, вы сможете создать туннель посредством командной строки. Вам нужно будет прописать команду через sudo или при помощи root-a. А прописать нужно будет действие вида -w локальный_туннель:обратный_туннель. Вместо локального и обратного туннеля укажите цифры. Можно прописать два нуля — тогда будет создан туннель tun0 и для сервера, и для клиента.

Следующим шагом нужно настроить два туннеля, чтобы они могли передавать данные между собой. Вот пример настройки туннелей: для серверного туннеля — ifconfig tun0 10.0.0.1/30 pointopoint 10.0.0.2, и для клиентского — ifconfig tun0 10.0.0.2/30 pointopoint 10.0.0.1.

Но на этом еще не все. Чтобы создать автоматическую загрузку данных через туннель, его нужно указать в настройках, как шлюз по умолчанию. Но в таком случае потеряется путь к DNS и серверу. Потому текущие шлюзы нужно прописать в таблице маршрутизации через команду route add -host XX.XX.XX.XX gw ЧЧ.ЧЧ.ЧЧ.ЧЧ (ХХ — это IP DNS в одной строке, и IP сервера в другой; а ЧЧ — это в обоих командах IP текущего шлюза, который нужно удалить).

Теперь удаляем текущий шлюз и добавляем новый. Удаляем при помощи строки route del default. А прописываем новый при помощи аналогичной функции: route add default gw 10.0.0.1 (в вашем случае IP может быть другим, смотря что указывали при создании туннеля).

После определения таких настроек, все, что идет не по стандартным каналам, автоматически перенаправляется на защищенный сетевой протокол по туннелю. То есть таким образом был создан автоматический туннель, пропускающий через себя все данные и трафик. Но остается еще одна проблема — на сервер трафик попадает, но дальше с ним ничего не происходит. А все потом, что необходимо настроить трансляцию сетевых адресов NAT для SSH клиента. Чтобы это реализовать нужно добавить новое правило: iptables -t nat -A POSTROUTING -s 10.0.0.2 -j MASQUERADE. Теперь осталось всего лишь включить ip-форвардинг через ядро и настроить его активацию каждый раз при запуске. После этого туннелирование можно считать успешным! Как видите, с OpenSSH все гораздо сложнее, но тем не менее, если постараться, то все реально.

Open VPN

Конечно, конкуренция среди программ сделала свое дело — создать VPN канал теперь можно многими средствами. Одно из таких — это Open VPN. Его также можно использовать на Linux. Итак, для того, чтобы инсталлировать Open VPN, вам потребуется зайти в терминал и ввести следующую строку: apt-get install openvpn openvpn-docs, после чего приложение загрузится и установится. Возможно, у вас будет запрошен пароль администратора.

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

Итак, чтобы создать простой туннель между двумя компьютерами, вам нужно будет сгенерировать специальный ключ. Делается это при помощи запроса: openvpn —genkey —secret static.key. Созданный ключ нужно перенести как на сервер, так и на клиент в сгенерированную при инсталляции папку openvpn, размещенную в каталоге Etc. Внутри этой папки вам предстоит создать файл с конфигурациями, который назовете по-разному для сервера и клиента. На сервере сгененрируйте server.conf, а для клиента пропишите client.conf. Стандартные настройки файла конфигураций вы сможете найти на сайте приложения Open VPN.

После добавления специальных конфигураций, которые вы скопируете на официальном сайте Open VPN, вам нужно будет лишь запустить приложение и на сервере, и на компьютере, проверить ping по каналу и активировать постоянный автозапуск приложения после активации системы при помощи кода: chkconfig openvpn on. После этого вы уже сможете обмениваться данными между сервером и клиентом.

С одной стороны, Open VPN — это весьма удобное приложение, которое позволяет быстро сгенерировать туннель между серверами, но с другой — у вас не получится так же легко создать VPN для соединения множества клиентов с хостом. Для этого реально нужно будет прыгнуть выше головы и утонуть в настройках — настолько это сложно. Так что лучше для решения подобных задач используйте другие утилиты.

Какие еще есть способы создания прямого и обратного туннеля через SSH

Описанные методы решения данного вопроса — это не весь перечень средств, которые есть у программиста по умолчанию. Через все тот же Linux можно создать туннель несколькими способами. И сейчас мы разберем очень простой метод, как подключить компьютер к удаленному серверу, а также как настроить подключение другого компьютеру, подключенному в SSHD.

Итак, допустим вам нужно подключиться к интернет-сервису, размещенному по адресу 10.10.2.1:80. При этом хост работает через определенный домен, к примеру, site.ru. Все, что вам нужно сделать — это пробросить туннель через сервер к нужному IP-адресу. И делается это при помощи команду -f, -N и -L. Первая объясняет протоколу, что нужно будет уйти в background после активации соединения, вторая отменяет все последующие команды, третья перенаправляет соединения на определенный хост к нужному нам IP-адресу. И вот как будет звучать команда: ssh -f -N [email protected] -L 8080:10.10.2.1:80.

Как видите, это достаточно простое решение. Какой метод выберите вы — это зависит от поставленных задач и ваших навыков!

На сервере homeserver запустите autossh со следующими аргументами с тем, чтобы создать постоянный туннель SSH, действующий в направлении сервера relayserver .

Homeserver~$ autossh -M 10900 -fN -o "PubkeyAuthentication=yes" -o "StrictHostKeyChecking=false" -o "PasswordAuthentication=no" -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 1.1.1.1:10022:localhost:22 [email protected]

Параметр "-M 10900" указывает порт на сервере relayserver , для которого будет осуществляться мониторинг и который будет использоваться для обмена тестовыми данными при контроле сессии SSH. Этот порт не должен на сервере relayserver использоваться какой-либо другой программой.

Параметр "-fN" перенаправляется в команду ssh , что позволит туннелю SSH работать в фоновом режиме.

Параметр "-o XXXX" сообщает команде ssh следующее:

  • Использовать ключ аутентификации, а не парольную аутентификацию.
  • Автоматически принимать (неизвестные) ключи хоста SSH
  • Каждые 60 секунд обмениваться сообщениями keep-alive.
  • Отправлять до трех сообщений keep-alive без получения каких-либо ответов.

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

Если вы хотите, чтобы туннель SSH автоматически поднимался при загрузке системы, вы можете в /etc/rc.local добавить указанную выше команду autossh .

Заключение

В этой статье было рассказано о том, как можно использовать обратный туннель SSH для доступа к серверу Linux, который находится за брандмауэром или шлюзом NAT, защищающего сеть от внешнего мира. Было продемонстрировано, как это сделать для случая домашней сети с помощью общедоступного виртуального частного сервера VPS. Вы должны быть внимательны при использовании этого приема для корпоративных сетей. Такой туннель может рассматриваться как нарушение корпоративной политики, поскольку он позволяет обойти корпоративные брандмауэры и может открыть корпоративные сети для внешних атак. Существует большая вероятность, что этот подход может использоваться неправильно или с заведомо плохими целями. Так всегда помнить, что прежде всего вы сами ответственны за все настройки, которые вы осуществляете.

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@Прокси

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

Такой туннель является простым, но не является надёжным, т.к. использует TCP-соединение и не содержит встроенных механизмов для восстановления соединения после разрыва.
SSH-туннель лучше использовать для тестирования (например, если вам нужно передавать UDP-пакеты на удалённый сервер, проброс портов по SSH в этом случае не поможет), а для постоянных туннелей использовать протоколы, специально разработанные для этого, такие как OpenVPN, PPTP, L2TP, IPSec, GRE и т.д. (Все примеры команд в статье верны для CentOS 6)

Установка и настройка

Устанавливаем пакет OpenSSH из репозиториев, если он всё ещё не установлен:

yum install openssh openssh-server openssh-clients

Для того, чтобы сервер разрешал использование туннелей, нужно включить в файле настроек OpenSSH-сервера (обычно /etc/ssh/sshd_config) опцию PermitTunnel и перезапустить OpenSSH-сервер (service sshd restart).

PermitTunnel yes

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

Host ...
или
Match ...

Опцию PermitTunnel нужно добавлять до описанных разделов.

Использование SSH-туннелей

Для всех примеров будет использоваться OpenSSH-сервер доступный по адресу 192.168.1.100.

Простой SSH-туннель

Для создания самого простого SSH-туннеля можно выполнить команду

sudo ssh -w 7:7 -l root 192.168.1.100

За создание туннеля отвечает опция

W <номер_локального_интерфейса>:<номер_удалённого_интерфейса>

Вместо номера локального и/или удалённого интерфейса можно использовать значение «any», тогда будет создан следующий по порядку незанятый TUN-интерфейс.

После прохождения аутентификации sudo и SSH на локальном и на удалённом хостах должен появиться отключенный интерфейс tun7.

Для использования туннеля нужно включить интерфейсы и настроить на них IP-адреса из одной подсети, например, так:

# на локальном хосте
# на удалённом хосте

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

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

SSH-туннель с правами непривилегированного пользователя

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

Если команда выдаст ошибку

Object "tuntap" is unknown, try "ip help".

Значит нужно использовать инструмент tunctl, предварительно установив его (yum install tunctl), в противном случае, команда должна выдать список TUN/TAP-интерфейсов на хосте.

Переходим к настройке .

Создаём непривилегированного пользователя на удалённом хосте:

useradd ssh_tunnel

Создаём TUN-интерфейс, принадлежащий этому пользователю

С помощью tunctl:

tunctl -n -t tun7 -u ssh_tunnel -g ssh_tunnel

С помощью iproute2:

ip tuntap add dev tun7 mode tun user ssh_tunnel group ssh_tunnel

Подключение SSH-туннеля выполняется аналогично предыдущему примеру:

# на локальном хосте
sudo ssh -w 7:7 -l ssh_tunnel 192.168.1.100
ifconfig tun7 up 10.255.255.2 pointopoint 10.255.255.1
# на удалённом хосте
ifconfig tun7 up 10.255.255.1 pointopoint 10.255.255.2

Создание пользователя только для SSH-туннелирования

В данном пункте будет рассмотрен запрет использования консоли непривилегированным пользователем в то время, как SSH-туннелирование для этого пользователя будет разрешено. Установить для пользователя оболочку «/bin/false» или «/sbin/nologin» не получится, т.к. в этом случае пользователь вообще не сможет установить SSH-соединение.

Для ввода описанных ограничений нужно добавить в конец файла настроек OpenSSH-сервера (/etc/ssh/sshd_config) указанные ниже строки и перезагрузить OpenSSH-сервер (service sshd restart)

Match User ssh_tunnel
X11Forwarding no
AllowTcpForwarding yes
AllowAgentForwarding no
GatewayPorts no
ForceCommand echo "This account can only be used for tunneling"; cat

Ограничение в этом примере вводится для созданного ранее пользователя ssh_tunnel. Параметр ForceCommand заставляет пользователя автоматически выполнять команду «echo "This account can only be used for tunneling"; cat» сразу после подключения. Это не даст пользователю использовать консоль нормальным образом, т.к., если убить процесс cat нажатием Ctrl+C, SSH-соединение будет разорвано.