SSH туннель — способы создания. Подключение к базе данных за брандмауэром

Помимо своей основной функции, протокол 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-соединение будет разорвано.

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 туннелей.

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

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

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

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

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

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

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

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

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

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

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

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

3. Socks–proxy

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

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

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

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

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

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

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

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

Please enable JavaScript

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

SSH тунель в PuTTY

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

Source port: 4444 Destination: localhost:4444

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

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

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

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

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

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

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

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

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

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

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

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

И так, у нас имеется сервер, назовём его 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.