Вы можете использовать встроенный OpenSSH сервер в Windows для проброса портов через SSH-туннель (SSH туннелирования). Перенаправление портов в SSH позволяет туннелировать (пробрасывать) порты приложений с локального компьютера на удаленный сервер и наоборот. Проброс портов через SSH туннель широко используется в среде Linux/Unix, а теперь вы можете воспользоваться этим возможностями и в Windows. В этом примере мы покажем, как пробросить RDP подключение через OpenSSH на хосте Windows Server.
Содержание:
- Для чего нужны SSH-туннели?
- Защищенный доступ к RDP через SSH туннель (local TCP forwarding)
- SSH туннель в Windows с помощью Putty
- Переброс удаленного порта на локальную машину (Remote TCP forwarding)
Для чего нужны SSH-туннели?
SSH-туннель обеспечивает защищенное шифрованный TCP соединение локальных хостом и удалённым сервером SSH. SSH Port Forwarding позволяет туннелировать поверх SSH подключение к локальному порту на локальном компьютере к любому TCP порту на удаленном сервере (или наоборот)
Порт форвардинг в SSH-туннелях применяются для:
- Обхода межсетевых экранов;
- Открытия бэкдоров в частные сети;
- Организации простых VPN/прокси сценариев для безопасного удаленного подключения;
- Защиты трафика устаревших приложений (протоколов), которые передают данные в открытом тексте (без шифрования).
Вы можете перенаправить в SSH туннель только TCP трафик/порт (UDP и ICMP протоколы не поддерживаются).
Проброс портов через SSH туннель можно использовать в сценариях, когда нужно подключиться к удаленному компьютеру, который защищен межсетевым экраном. Например, у вас имеется сервер c Windows, на котором наружу открыт только SSH порт (TCP 22). Все остальные порты блокируются аппаратным межсетевым экраном или Windows Defender Firewall Windows. Ваша задача подключиться к рабочему столу этого Windows сервера с помощью клиента RDP. Казалось бы, невозможная задача, т.к. порт RDP 3389 блокируется брандмауэром. Однако вы можете получить доступ к любому открытому порты на удаленном хосте через SSH-тунель.
Чаще всего используются следующие сценарии проброса через SSH:
- Local TCP forwarding — проброс локального порта на удаленный сервер;
- Remote TCP forwarding — проброс удаленного порта на локальный компьютер;
- Двойной SSH туннель – позволяет соединить между собой через SSH сервер компьютеры без выделенных белых IP адресов или находящиеся за NAT (если не подходит решение с OpenVPN)
Защищенный доступ к RDP через SSH туннель (local TCP forwarding)
В этом режиме вы создаете на своем компьютере локальный TCP порт, подключения к которому перенаправляются через SSH туннель на указанный порт удаленного сервера. В этом примере мы создадим локальный порт 8888, при подключении к которому выполняется перенаправление на RDP порт 3389 на удаленном компьютере. Общая схема подключения выглядит так:
Для проброса портов нам потребуется SSH клиент. Можно использовать сторонний клиент (например, Putty), но я буду использовать встроенный SSH клиент в Windows. Чтобы установить клиенте OpenSSH, выполните в консоли PowerShell команду:
Get-WindowsCapability -Online | ? Name -like 'OpenSSH.Client*'
Чтобы создать SSH туннель с удаленным компьютером 192.168.1.90, выполните команду:
ssh -L 8888:192.168.1.90:3389 [email protected]
В этом примере используется формат
LOCAL_PORT:DESTINATION:DESTINATION_PORT
и
USER@DEST_SERVER_IP
(имя пользователя и адрес удаленного SSH сервера)
Чтобы SSH туннель работал в фоновом режиме, нужно добавит параметр –f.
Теперь, чтобы подключится к удаленному компьютеру по RDP через SSH туннель, вам запустить RDP-клиент (mstsc.exe) и подключиться на локальный порт 8888 своего компьютера:
127.0.0.1:8888
Выполните аутентификацию на удаленном компьютере и можете спокойно работать в RDP-сессии. С помощью команды Get-NetTCPConnection или утилиты TCPView вы можете убедиться, что RDP подключение установлено локально (RDP подключение инициировано запущенным локально SSH сервером):
Get-NetTCPConnection -State Established|where {$_.localport -eq "3389"}|fl
При этом порт TCP/3389 на сервере не доступен с удаленного компьютера. Вы можете проверить доступность порта с помощью командлета Test-NetConnection:
Test-NetConnection 192.168.1.90 -port 3389
TcpTestSucceeded : False
Обратите внимание, что если вы перенаправляете таким образом незашифрованный трафик приложения, то по сети он передается в зашифрованном виде. Трафик шифруется на одном конце SSH соединения и расшифровывается на другом.
Другие компьютеры в вашей локальной сети смогут одновременно подключиться к удаленному RDP серверу Windows, даже если у них полностью заблокирован прямой доступ к удаленному серверу (как по SSH, так и по RDP). Для этого, они должны подключиться RDP клиентом к порту 8888 на компьютере, на котором создан SSH туннель:
mstsc.exe /v 10.10.1.220:8888
Защита RDP подключения с помощью SSH туннеля может быть хорошей альтернативой VPN для доступа к публичным Windows хостам в Интернете. В этом случае вам не нужно открывать прямой доступ к порту RDP/3389 из Интернета к хосту Windows. Достаточно открыть только порт SSH/22, что защитит вас от атак подбора пароля по RDP и эксплуатации 0-day RDP уязвимостей.
Для автоматического ввода пароля для подключения к SSH можно использовать утилиту sshpass. Ее можно запустить через подсистему WSL2 для Windows.
Установите sshpass в Ubuntu WSL:
$ sudo apt-get -y install ssphass
Запустите клиент Remote Desktop Connection (mstsc.exe) и сохраните в Windows RDP файл с настройками подключения:
Computer : localhost:8888 User name : remoteusername
Для автоматического подключения к удаленном RDP хосту с сохранённым паролем SSH, используйте такой bat файл:
start /min wsl sshpass -p "password" ssh -L 8888:192.168.31.90:3389 [email protected]
powershell sleep 5
start mstsc C:\rdp\localhost-33389.rdp
Или (предпочтительно) настройте SSH аутентификацию по ключам.
SSH туннель в Windows с помощью Putty
Рассмотрим, как настроить SSH туннель в Windows с помощью популярного SSH клиента Putty.
- Запустите PuTTY и перейдите в раздел Connection -> SSH -> Tunnels;
- В поле Source port укажите локального порта (в нашем примере это 8888);
- Укажите IP адрес сервера SSH и порт на удаленном хосте, на который нужно выполнить переадресацию:
192.168.31.90:3389
- Выберите Local в качестве Destination и нажмите Add;
- Чтобы не открывать shell удаленного хоста при подключении через туннель, включите опцию Don’t start a shell or command at all в разделе SSH;
- Вернитесь на вкладку Session, укажите имя или IP адрес удаленного SSH хоста и порт подключения (по умолчанию порт 22). Чтобы сохранить настройки подключения, укажите имя сессии в поле Saved Session и нажмите Save;
- Теперь вы можете запустить сохраненный SSH туннель в Putty прямо и панели задач Windows.
Переброс удаленного порта на локальную машину (Remote TCP forwarding)
Есть еще один вариант применения SSH туннеля – remote TCP forwarding. Через SSH туннель вы можете открыть доступ удаленному серверу к локальному порту на вашем компьютере или порту на другом компьютере в вашей локальной сети. Например, вы хотите, чтобы внешний сервер (192.168.1.90) получил доступ к вашему Интранет сайту (не опубликованному в Интернете). Для создания обратного туннеля, используйте такую команду:
ssh -R 8080:internalwebsever:80 [email protected]
Теперь, чтобы на удаленном SSH сервер получить доступ к веб серверу internalwebsever достаточно в браузере набрать адрес
http://localhost:8080
.
С помощью SSH туннелей вы можете строить целые цепочки для форвардинга портов. Включить или отключить SSH туннелирование можно в конфигурационном файле OpenSSH (sshd_config) с помощью директив:
AllowStreamLocalForwarding yes
AllowTcpForwarding remote
PermitTunnel no
Данные опции неприменимы для текущей версии OpenSSH в Windows.
SSH-туннели нужны для установки защищенных каналов между локальной машиной и удалённым сервером. Через них можно, например, передавать и редактировать файлы, запускать приложения, сохранять резервные копии.
Как устроен туннель
SSH — это Secure Shell, защищённый сетевой протокол для удалённого управления. Он шифрует трафик и работает со всеми популярными операционными системами.
Для установки безопасного подключения к удалённой машине используется SSH-туннелирование. Однако под туннелем здесь подразумевается не инкапсуляция одного протокола в другом. Речь идёт о том, что администратор выполняет через SSH проброс портов. Технология подразумевает передачу TCP-пакетов и трансляцию IP-заголовков при передаче информации, если соблюдаются правила.
cloud
Как создать туннель
Для идентификации пользователя нужны два ключа — приватный и публичный (открытый). Открытый хранится на сервере, приватный — на локальной машине. Создание безопасного подключения отличается в зависимости от операционной системы.
Ubuntu и другие дистрибутивы Linux/macOS
Запустите терминал и выполните команду:
ssh-keygen -t rsa
В терминале появится диалог:
Enter file in which to save the key (/home/user/.ssh/id_rsa):
По умолчанию приватная часть сохраняется в папку .ssh
в файл id_rsa
. Вы можете указать другие адрес и имя файла.
Затем система предложит создать пароль для дополнительной защиты ключа. Это нужно, чтобы его не могли использовать все, кто имеет доступ к локальной машине. Полезная настройка безопасности, если одним компьютером пользуются несколько человек. Если пароль не нужен, оставьте поле пустым и нажмите Enter.
Enter passphrase (empty for no passphrase):
После успешного создания пары ключей в терминале появится такая запись:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
476:b2:a8:7f:08:b4:c0:af:81:25:7e:21:48:01:0e:98 user@localhost
Теперь нужно скопировать публичный ключ и добавить его на удалённую машину. Можно открыть файл /home/user/.ssh/id_rsa.pub
через любой текстовый редактор или вывести его содержимое в терминале:
cat ~/.ssh/id_rsa.pub
Скопируйте ключ и добавьте его на сервер. Убедитесь, что в нём нет пробелов и переносов.
Можно скопировать открытый ключ автоматически, используя команду:
ssh-copy-id user@remoteserver
Вместо user вы указываете имя пользователя, вместо remoteserver
— хост или IP-адрес удалённой машины на timeweb.cloud или другой платформе.
Создание безопасного подключения завершено. Чтобы подключиться через SSH-port, выполните:
ssh root@HOST
Вместо параметра HOST
укажите публичный IP-адрес сервера, на который вы добавили открытый ключ. Если вы не создавали пароль для дополнительной защиты закрытой части, то вводить ничего больше не нужно. Система сверит открытый и закрытый ключи и при обнаружении соответствия установит защищенное соединение.
При первом подключении система предупредит о неизвестном хосте и уточнит, доверяете ли вы ему. Введите ‘yes’ и нажмите Enter.
Чтобы сделать подключение безопаснее, не стоит использовать аккаунт с правами суперпользователя. Кроме того, можно ограничить связь между консолями локальной машины и удалённого сервера, указав параметр -N
. Пример команды:
ssh -N -L -g 3389:192.168.0.105:3389 user@rt.example.com
Это исключит ситуацию, при которой пользователь случайно выполняет на удалённой машине команды, предназначенные для локального компьютера.
Windows
На Windows создать пару ключей можно двумя способами — через консоль PowerShell и с помощью программы PuTTygen (устанавливается вместе с PuTTy).
Чтобы сгенерировать ключи через PowerShell, откройте терминал и выполните:
ssh-keygen -t rsa
Защитите приватный ключ паролем или оставьте поле пустым и нажмите Enter.
По умолчанию открытый ключ сохраняется в файле ~/.ssh/id_rsa.pub
. Приватный ключ с именем id_rsa
лежит в той же папке. Откройте файл с публичным ключом через текстовый редактор или воспользуйтесь командой cat
в PowerShell:
cat ~/.ssh/id_rsa.pub
Скопируйте публичный ключ и добавьте его на удаленный сервер.
Чтобы подключиться к серверу, выполните:
ssh root@HOST
Вместо параметра HOST
укажите публичный IP-адрес удаленного сервера, на который вы добавили открытый ключ. Если вы не создавали пароль для дополнительной защиты закрытого ключа, то вводить ничего больше не нужно. Система сверит открытый и закрытый ключи и при обнаружении соответствия установит SSH-туннель в Windows.
При первом подключении ОС предупредит о неизвестном хосте и уточнит, доверяете ли вы ему. Введите ‘yes’ и нажмите Enter.
Чтобы сгенерировать пароль с помощью PuTTygen:
- Нажмите кнопку Generate.
- Подвигайте курсором в любом направлении до тех пор, пока строка прогресса не заполнится.
- Сохраните публичный и приватный ключи.
- Откройте файл с публичным ключом.
- Скопируйте публичный ключ и добавьте его на удаленный сервер.
Для подключения к удалённому серверу также можно использовать программу PuTTy. Запустите программу, в поле Host Name введите имя или IP-адрес хоста и нажмите Open.
Настроить в PuTTy SSH tunnel можно во вкладке Connection → SSH → Tunnels. Здесь указывается Source Port, Destination, а также параметры динамического подключения. Что это за настройки и как они влияют на соединение, рассмотрим далее.
Как использовать SSH Proxy
SSH-tunnel Proxy помогает организовать доступ к домашней или корпоративной системе. Важно только, чтобы приложения, которые используются для работы при подключении, поддерживали SOCKS-прокси. Один из вариантов такого использования туннелей — сотрудник подключается к рабочей сети, используя публичную сеть в другом конце мира, при этом вся информация шифруется.
Для туннелирования через прокси достаточно выполнить:
ssh -D 8888 user@remoteserver
Этой командой вы запускаете SOCKS-прокси. Порт — 8888. В этом случае служба работает на localhost. Но можно изменить команду, чтобы прослушивать Ethernet и Wi-Fi. Это позволит приложениям подключаться к прокси-серверу через Secure Shell.
Например, можно запустить браузер Google Chrome:
google-chrome --proxy-server="socks5://192.168.1.10:8888"
Команда создаёт SOCKS-прокси, а также инициирует туннелирование DNS-запросов
Что такое динамический SSH-tunnel
Динамический SSH-tunnel открывает локальный сокет TCP и использует его как SOCKS4/SOCKS5-прокси. Такой туннель отвечает всем требованиям безопасности.
Динамический туннель также подходит для однократного выхода в интернет:
ssh -D 1080 user@vps.example.com
SOCKS-прокси работает через порт 1080. Динамический туннель не предусматривает открытие портов во внешнюю сеть. Весь трафик проходит по нему, скрывая деятельность пользователя.
Для Windows динамический SSH-туннель в PuTTy настраивается на вкладке Connection → SSH → Tunnels.
Примеры использования туннелей
Рассмотрим несколько примеров использования туннелей.
Проброс портов — SSH Port Forwarding
SSH Forwarding — одна из самых распространенных операций, для которой требуется создать туннель. Вы открываете порт на локальной машине и выбираете порт на другом конце — удаленном сервере:
ssh -L 9999:127.0.0.1:80 user@remoteserver
В этой команде вы говорите, что нужно слушать порт 9999. Для проброса используется порт 80.
Обратный туннель
Туннель может работать и в обратном направлении. Для этого достаточно подключить слушающий порт к другому порту на локальной машине:
ssh -v -R 0.0.0.0:1999:127.0.0.1:902 192.168.1.100 user@remoteserver
В этом туннеле соединение идёт от удалённого сервера к порту 1999, затем к порту 902 на локальной машине.
Удалённое выполнение команд
Через Secure Shell можно создать интерфейс для выполнения команд на удалённой машине. Сами команды прописываются в качестве последнего аргумента. Пример:
ssh remoteserver "cat /var/log/nginx/access.log" | grep badstuff.php
После скачивания лога на удалённом сервере выполнится команда grep.
Rsync через SSH
Бэкапы важных данных можно делать с помощью bzip2
. Порядок простой — сначала вы сжимаете каталог на удалённом сервере, а затем распаковываете на другой стороне: на локальной машине или на другом сервере, заведённом под хранение резервных копий. Пример команды:
tar -cvj /datafolder | ssh remoteserver "tar -xj -C /datafolder"
Если бэкапы нужно делать регулярно (обычно так и происходит), то проще использовать команду rsync:
rsync -az /home/testuser/data proglibserver:backup/
Rsync не копирует файлы с нуля, а сравнивает отличия в разных временных точках. Это экономит время на создание бэкапов, а также помогает найти данные для восстановления при утере или повреждении.
Запуск приложений
Через SSH-туннель можно запускать GUI-приложения на удалённом сервере:
ssh -X remoteserver vmware
Несмотря на то, что приложение выполняется на удалённом сервере, его интерфейс доступен на локальной машине. Это удобно если, например, нужно больше ресурсов для работы, а локальная машина уже не справляется.
Прыжки по хостам
Если сеть сегментирована, то при туннелировании придётся пройти через несколько хостов. При этой рабочий сеанс должен быть полностью зашифрованным. Добиться такого результата можно с помощью параметра -J
. Для установления связи с каждым следующим хостом будет использоваться переадресация:
ssh -J host1,host2,host3 user@host4.internal
Локальная папка на удаленной машине
С помощью sshfs можно примонтировать локальный каталог к удалённому серверу.
sshfs user@proglibserver:/media/data ~/data/
Это удобное решение для обмена файлами и выполнения других операций.
Заключение
В этой статье мы узнали, что такое SSH-туннель, как им пользоваться, как его настроить на Linux, macOS и Windows, какие у него есть особенности и параметры конфигурации. Несколько распространенных сценариев также описаны в примерах использования.
Запоминать все команды и аргументы не нужно. Основные операции вы быстро начнёте делать на автомате, а более сложные случаи всегда можно посмотреть в справке или нашем руководстве на timeweb.cloud
SSH-туннелирование устанавливает защищенный канал связи между локальным рабочим узлом и удаленным сервером. Разбираемся, как можно создавать SSH-туннели, какие полезные для системного администратора функции они имеют и почему важно помнить о безопасности интернет-соединения.
Любые важные данные следует передавать по защищенным каналам информации. Но это не всегда легко реализовать, особенно когда пользователю нужно совершить срочные операции на удаленном сервере, а подключиться к интернету можно только через публичный незащищенный Wi-Fi. В таком случае используют SSH-туннелирование, устанавливающее защищенный канал связи между локальным рабочим узлом и удаленным сервером. С помощью него можно не только передавать или редактировать файлы дистанционно, но и запускать GUI-приложения, делать бэкап, передавать пароли и даже организовывать потоковое вещание.
Как устроены SSH-туннели
Создание, условия применения и польза для сисадминов
Ситуация, когда требуется срочный доступ к домашнему компьютеру или внутренней корпоративной сети, знакома каждому. К сожалению, качество и безопасность общественных сетей часто оставляют желать лучшего. Важную информацию по таким сетям лучше не передавать. Кроме того, для организации доступа часто требуется внешнее ПО (Team Viewer и другие). Для системного администрирования существует способ использования публичных сетей и при этом создания безопасного подключения к необходимым узлам без использования того же VPN. Речь о SSH-туннелировании.
SSH (от англ. Secure Shell — «безопасная оболочка») — сетевой протокол, который используется для удаленного управления ОС и проксировании TCP-соединений. Выполняет шифрование всего трафика (сюда же относятся пароли и другие важные для корпоративной безопасности данные). SSH-серверы работают с большинством сетевых операционных систем, представленных на рынке.
Подключиться по этому протоколу можно практически к любому серверу. Для организации безопасного соединения можно использовать так называемые SSH-туннели. Но с точки зрения терминологии — это не те туннели, о которых обычно идет речь, когда говорят о системном администрировании. Само наименование, SSH tunnel, сформировалось среди сисадминов для простоты обозначения технологии — SSH Port Forwarding (проброса портов). В ней реализовано сразу несколько возможностей сетевого протокола SSH, а именно — передача TCP-пакетов и трансляция IP-заголовка во время передачи информации при условии существования заранее заданного правила.
Главное отличие SSH tunnels от их аналогов с VPN — передача информации не происходит в любом направлении. Такой канал связи имеет одну точку входа и работает исключительно с TCP-пакетами. Создание SSH-туннелей скорее напоминает проброс портов поверх протокола, нежели туннелирование в чистом виде.
Как создать SSH-туннель и настроить его параметры
Для того, чтобы идентифицировать пользователя, требуется два ключа. Открытый ключ размещается непосредственно на сервере, а закрытый ключ создается и хранится на компьютере пользователя.
Создание ключа и установление соединения с удаленным сервером занимает несколько минут.
Создание SSH-ключа в Linux (Ubuntu)/MacOS. Пошаговая инструкция:
1. Для создания ключа требуется ввести следующую команду:
ssh-keygen -t rsa
2. После введения команды на экране управляющей консоли появится диалог:
Enter file in which to save the key (/home/user/.ssh/id_rsa):
3. Чтобы дополнительно защитить соединение, система предложит пользователю придумать и ввести специальное кодовое слово (фразу).
Enter passphrase (empty for no passphrase):
4. Разумеется, пункт № 3 можно пропустить, нажав Enter. То же самое следует сделать, отвечая на следующий вопрос.
5. Завершив создание двух типов ключей (публичного и закрытого), можно переходить к установке связи по SSH. На консоли появится сообщение:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
476:b2:a8:7f:08:b4:c0:af:81:25:7e:21:48:01:0e:98 user@localhost
The key's randomart image is:
+---[RSA 2048]----+
| ..o o |
| .. * * = . |
| . o O o B .|
| . . + = = o |
| oo S o = . .|
| .. B . = . . |
| . B o = ..|
| . .o.o.. o .. .|
| .oooE o. |
+----[SHA256]-----+
6. На следующем этапе в терминале необходимо ввести команду, которая покажет открытый ключ:
cat ~/.ssh/id_rsa.pub
7. Публичный ключ необходимо ввести в панели управления. Внимательно проверяйте корректность введения ключа.
8. Остается последний этап. Для создания SSH-туннеля к удаленному серверу достаточно выполнить одну команду:
ssh root@HOST
Параметр HOST ― публичный IP-адрес сервера.
Добавим, что введение дополнительных паролей не требуется. А при использовании сервера Selectel можно использовать свой скрипт (bash) для быстрой настройки.
Для удобства пользователей ОС Windows 10 можно создать SSH-туннель в эмуляторе под Windows (MinGW64).
Инструкция для создания SSH-туннеля в Windows 10 выглядит аналогичным образом:
1. Для генерации пары ключей используется команда:
ssh-keygen -t rsa
2. Желательно защитить приватный ключ паролем (или нажать Enter, если он не нужен):
3. Ключи сгенерированы:
4. Открытый ключ хранится в файле ~/.ssh/id_rsa.pub. Приватный ключ находится в файле id_rsa и должен храниться в секрете:
5. Чтобы посмотреть содержимое публичного ключа, используется команда:
cat ~/.ssh/id_rsa.pub
6. Этот ключ (всю строку, начинающуюся с ssh-rsa) необходимо вставить в панели управления Selectel, в поле Операционная система / SSH-ключ выбранного сервера. При установке ОС он будет скопирован в файл .ssh/authorized_keys. При смене ключа в панели управления Selectel текущий образ ОС будет пересоздан, а данные на сервере — утеряны.
7. Для подключения к серверу по SSH используется команда:
ssh root@84.38.187.48 (IP-адрес сервера будет другим).
8. При первом подключении утилита SSH сообщает о неизвестном хосте и спрашивает, уверены ли вы, что доверяете ему. Если ответ положительный (следует ответить yes), IP-адрес и открытый сертификат этого сервера будут добавлены в файл ~/.ssh/known_hosts на локальной машине:
9. Если ранее при генерации пары ключей был задан пароль, утилита SSH попросит ввести его:
10. После ввода пароля и нажатия Enter устанавливается зашифрованное соединение с сервером:
Еще один вариант, как можно использовать этот тип соединения, — создание канала связи по протоколу RDP. Этот вариант подходит, когда пользователь не может подключиться к узлу из-за отсутствия доступа к нему из сети. Зато у него есть доступ к маршрутизатору. Этого достаточно, чтобы использовать данный тип туннелирования.
Параметры канала связи устанавливает инициатор подключения. На втором конце канала связи всегда расположен целевой сервер. Так, клиентом может оказаться VPS-сервер, а точкой выхода — компьютер сисадмина. Точка входа может быть создана с любой стороны туннеля: именно через нее принимаются подключения. Обратная сторона туннеля — точка выхода — способна лишь на маршрутизацию пакетов информации с учетом установленных правил. Отдельная опция — соединение с удаленной машиной, на которой запущен модуль Docker (SSH Docker). Подробнее об этом мы расскажем в следующих публикациях.
Аналогичным образом проходит процесс установки соединения с определенным сервером. В качестве примера возьмем целевой сервер с адресом 192.168.0.105. При этом для пользователя доступен только маршрутизатор (192.168.0.1). В качестве точки входа прописывается 127.0.0.1:3389. Кроме того, задается правило трансляции, определяющее узел, принимающий данные на выходе из SSH-туннеля. В нашем случае в качестве правила указывается 192.168.0.105:3389. Проследите, чтобы указанный адрес действительно существовал, иначе вам не удастся подключиться к целевому серверу.
После того, как вы зададите исходные данные, появится TCP-сокет, который создает служба SSH. Этот локальный сокет следит за тем, когда начнутся подключения на порт 3389. Точкой назначения прописывается localhost (127.0.0.1). Отметим, что RDP-клиент не владеет информацией о настоящем назначении получателя пакета. Клиент только открывает динамический порт, чтобы отправить пакет данных, у которого задан адрес назначения (точка входа) и источника (127.0.0.1:61256).
Пакет с информацией следует от входной точки SSH tunnel на его противоположный конец. Адрес трансляции поменяется. Теперь там значится 192.168.0.105:3389. На следующем этапе SSH-сервер просто поставит свой адрес вместо адреса источника. Вся информация, которая передается внутри канала, будет отправлена поверх протокола. А RDP-клиент оперирует исключительно локальным сокетом. Важно, что вся информация внутри туннеля защищена — она шифруется. Но соединение между SSH- и RDP-серверами остается обычным. Разумеется, этот фактор стоит учитывать, если пользователь работает с небезопасными протоколами.
SSH Proxy: как организовать доступ к любой системе (обращение к проксируемому серверу)
С помощью SSH-туннеля можно воспользоваться домашней (или корпоративной) сетью, даже используя ненадежный бесплатный Wi-Fi. Для этого пользователю потребуется запустить SSH-прокси, а затем по аналогичному принципу создать туннель в целевую сеть (например, можно подключиться к домашней сети).
Важно, чтобы приложения, которые потребуются инициатору подключения для работы, поддерживали SOCKS-прокси. С помощью туннеля сетевые службы станут доступны для удаленной работы. Другой вариант: пользователь сможет выйти в интернет, используя домашнее подключение, но сидя при этом в другом конце мира и используя публичную сеть. Вся передаваемая через туннель информация будет зашифрована.
Это не единственный способ практического применения SSH-туннелирования. Один из самых популярных кейсов — SSH Proxy — открывает доступ к желаемой системе, если она доступна для удаленного сервера. При этом для туннелирования через прокси-сервер потребуется ввести всего одну команду:
localhost:~$ ssh -D 8888 user@remoteserver
localhost:~$ netstat -pan | grep 8888
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN 23880/ssh
Команда выше показывает, что пользователь запускает SOCKS-прокси. Портом для работы назначается 8888. Кроме того, необходимо проверить, активен ли этот TCP-порт (используется режим прослушивания). Служба работает исключительно на localhost (127.0.0.1). Если немного видоизменить команду, то можно прослушивать все интерфейсы (в том числе ethernet или Wi-Fi). Это позволяет приложениям подключаться к прокси-серверу через SSH-прокси:
localhost:~$ ssh -D 0.0.0.0:8888 user@remoteserver
Чтобы браузер работал корректно, необходимы настройки. Например, чтобы запустить Chrome с активированным SOCKS-прокси, потребуется команда:
localhost:~$ google-chrome --proxy-server="socks5://192.168.1.10:8888"
Она создает SOCKS-прокси, а также инициирует туннелирование DNS-запросов. Утилита tcpdump проверяет, видны DNS-запросы или нет.
Кроме браузеров, многие современные приложения работают с SOCKS-прокси: достаточно изменить их параметры, чтобы активировать прокси-сервер. Отдельно применяются инструменты, которые помогают приложениям использовать эту важную функцию — к примеру, proxychains позволяет запустить через SOCKS-прокси Microsoft RDP.
Зачем нужны динамические SSH tunnels
Динамический SSH tunnel отличается от рассмотренных выше типов соединений. Он открывает локальный TCP-сокет для его использования в качестве SOCKS4/SOCKS5 прокси. Обычно его применяют, когда требуется VPN, а его развертывание невозможно. Такой тип SSH-туннеля также отвечает необходимым требованиям безопасности.
Кроме того, создание динамического туннеля удобно, когда пользователю необходимо выйти в интернет однократно:
ssh -D 1080 user@vps.example.com
SOCKS-прокси работает через порт 1080.
Помимо этого, динамический туннель не предусматривает открытие дополнительных портов во внешнюю сеть. Весь трафик будет проходить исключительно через SSH-соединение, скрывая тем самым характер интернет-деятельности пользователя.
Команды и практическое применения функций SSH-туннелей
Рассмотрим несколько практических примеров применения SSH-туннелирования.
Проброс (перенаправление) портов — Port Forwarding
Чтобы осуществить проброс портов, потребуется создание SSH tunnel. Для этого в локальной системе открывается порт, а для создания канала связи пользователь должен выбрать порт на другом конце туннеля:
localhost:~$ ssh -L 9999:127.0.0.1:80 user@remoteserver
Команда устанавливает прослушку на порт 9999. Порт 80 используется для проброса. Для Port Forwarding также используются прокси-серверы или TCP-службы.
Автоматизация копирования публичного (открытого) ключа
Традиционно пользователю приходится копировать открытые ключи вручную. SSH-протокол существенно ускоряет этот процесс:
localhost:~$ ssh-copy-id user@remoteserver
Эта команда выполняет копирование публичного ключа по умолчанию или из директории ~/.ssh/id_rsa.pub в ~/.ssh/authorized_keys (она находится на удаленном сервере).
Обратный SSH-туннель (SSH reverse tunnel)
Очевидно, что SSH tunnel можно создать и в обратном направлении. Достаточно подключить прослушивающий порт к другому локальному порту:
localhost:~$ ssh -v -R 0.0.0.0:1999:127.0.0.1:902 192.168.1.100 user@remoteserver
Данный туннель работает следующий образом: от порта 1999 к remoteserver, а уже после этого обращается к порту 902 на локальном клиенте.
Удаленное выполнение команд с помощью SSH
SSH-команда позволяет создать интерфейс для работы с командами на удаленном хосте. Они прописываются в качестве последнего параметра:
localhost:~$ ssh remoteserver "cat /var/log/nginx/access.log" | grep badstuff.php
После скачивания лога grep можно запустить на удаленной стороне.
Копирование, функция rsync-копирования (rsync через SSH)
Чтобы создать дубликат папки на удаленном сервере, достаточно сначала сжать папку с помощью bzip2, а после извлечь поток bzip2 на другой стороне. Команда для этой операции следующая:
localhost:~$ tar -cvj /datafolder | ssh remoteserver "tar -xj -C /datafolder"
Для регулярных бэкапов важной информации используется rsync:
localhost:~$ rsync -az /home/testuser/data proglibserver:backup/
Функция rsync позволяет копировать отличия, сравнивая информацию в разных временных точках. Таким образом, можно восстановить важные данные в случае неудачного сеанса передачи.
GUI-приложения: удаленный запуск через SSH
SSH-туннель поддерживает функцию, позволяющую запускать GUI-приложения удаленно:
localhost:~$ ssh -X remoteserver vmware
Отметим: несмотря на то, что GUI выполняется на удаленном сервере, окно отображается на локальном рабочем столе. В примере для работы запущена консоль виртуальной машины VMware Workstation. Но для успешной реализации команды требуются пакеты X11 и YES для X11Forwarding в файле sshd_config.
Редактирование текстовых файлов
Метод редактирования файлов одной командой предусматривает создание файла в /tmp, а затем копирование в заданную директорию:
localhost:~$ vim scp://user@remoteserver//etc/hosts
Прыжки по хостам
Туннелирование предусматривает переход через несколько хостов, если пользователь сталкивается с сегментацией сети:
localhost:~$ ssh -J host1,host2,host3 user@host4.internal
Параметр -J использует переадресацию для установления сеанса с каждым следующим хостом в цепочке. При этом рабочий сеанс полностью зашифрован — от localhost и до host4.
Фильтрация трафика с помощью iptables
Утилита iptables позволяет устанавливать правила для блокировки или разрешения прохождения трафика: INPUT, FORWARD и OUTPUT. В случае если пользователь не задал никаких правил, этот межсетевой экран будет выполнять заданную по умолчанию фильтрацию. Для установления связи с целевым сервером утилита сравнит IP-адрес инициатора подключения с тем списком, что есть в правилах INPUT, а затем либо даст доступ к серверу, либо запретит его.
Однако работа с iptables требует определенной осторожности. Причина проста: если неверно задать правило фильтрации, удаленный доступ может оказаться просто невозможным до тех пор, пока пользователь не снимет ограничения, получив физический доступ к компьютеру.
Реализация SSH tunnels в Windows
Возможности туннелирования доступны и для тех, кто использует Windows 10: под эту ОС существует ряд SSH-клиентов. Один из самых применяемых — PuTTY. Запуск сервера под Windows — более сложная задача, которая требует от пользователя специализированной квалификации.
PuTTY настраивается достаточно просто: для этого во вкладке Connection открываем SSH Tunnels, где необходимо прописать базовые настройки соединения — Source port (точка входа), Destination (назначение); радиопереключатели Local — Remote — Dynamic определяют тип будущего канала связи. Адрес целевого узла указывается в другом разделе — Session.
Открытия дополнительных портов или развертывания VPN не требуется.
Безопасны ли SSH-туннели
Как мы уже отмечали, одна из их задач — создание безопасного соединения с удаленной машиной. Однако не стоит забывать о «побочных эффектах» таких туннелей. Кроме соединения с удаленным сервером, пользователь получает консоль, которая открывается на сервере.
Если пользователь забудет о своем подключении, то может выполнить те команды, которые изначально были предназначены к выполнению на локальном узле. Чтобы избежать подобной ошибки (особенно если пользователь имеет права суперпользователя), при запуске канала связи следует указывать параметр -N:
ssh -N -L -g 3389:192.168.0.105:3389 user@rt.example.com
Кроме того, не стоит использовать при подключении к удаленной машине аккаунт суперпользователя, для этих целей подойдет учетная запись с обычными правами. И не забывайте про то, что по завершении работы требуется удалить SSH-туннель.
SSH Reverse Tunnel Scripts (Windows)
This repository contains everything you need to create self-restarting, fault-tolerant reverse SSH tunnels from Windows machines. If you have a Windows machine in a protected network or under NAT, and you’d like to reach it from the internet using a proxy, this repository will enable you to do just that.
For Linux-based or otherwise systemd
-enabled servers, check out our sister reporitory bindreams/ssh-tunnel-systemd.
Install your first reverse tunnel
After completing this tutorial, you will have a self-restarting SSH reverse tunnel service, controlled by the following files in %ProgramData%/SshReverseTunnel
:
config.d/<tunnel-name>.conf
: SSH configuration file;services/<tunnel-name>.yml
: YAML configuration file with service properties (restart policy, log rotation, etc.);services/<tunnel-name>.exe
: Executable shim that launches the SSH tunnel, based on WinSW;logs/<tunnel-name>.out.log
:stdout
for the SSH process (usually empty);logs/<tunnel-name>.err.log
:stderr
for the SSH process;logs/<tunnel-name>.wrapper.log
: log for the shim executable above.
Note
Every console command in this file is written for PowerShell, notcmd
. This means that environment variables, such asPROGRAMDATA
are written in powershell syntax (${env:ProgramData}
). When referencing paths outside of console, the percent syntax (%ProgramData%
) is used instead so that you may paste this path directly into an explorer window.
1. Bootstrap sshrt.py
Clone this repository or download a zip file. You may delete the folder when you finish installing the service. Open a powershell terminal in the downloaded folder and run the following commands to bootstrap sshrt.py script:
python -m venv .venv # Create a python isolated environment .\.venv\scripts\Activate.ps1 # Activate the environment pip install -r requirements.txt # Install required packages python -m sshrt bootstrap
The last command will do the following important things:
- Enable Windows built-in components for OpenSSH Server and Client;
- Add a firewall rule so that said components may work;
- Create necessary directories and files for SSH Server and the reverse tunnels.
Verify that the SSH Server was succesfully installed by running:
2. Configure public-key based SSH access from A to B
Generate an RSA key pair on machine A. This key will be used to establish an SSH tunnel, but you will need to test your connection first so place it in your user directory for now. The key should be passwordless, because the reverse tunnel start up automatically and there is no way to enter a password. The following command is an example of how to create a passwordless RSA key and store it in %USERPROFILE%/.ssh/
:
# System PowerShell 5.x and old PowerShell Core (https://github.com/PowerShell/PowerShell/issues/6280) ssh-keygen -f "$HOME/.ssh/MachineB.id" -N '""' -t rsa # Up-to-date PowerShell Core ssh-keygen -f "$HOME/.ssh/MachineB.id" -N "" -t rsa
After running ssh-keygen
you will have two key files, with one ending in .pub
. This is your public key, which you need to append to the end of the authorized_keys
file on machine B. This file is probably in the following directories:
Login as: admin | Login as: user | |
---|---|---|
OS: Linux | /root/.ssh/authorized_keys |
/home/<user>/.ssh/authorized_keys |
OS: Windows | %ProgramData%/ssh/administrators_authorized_keys |
C:/Users/<user>/.ssh/authorized_keys |
Once this is done, add a temporary entry in your SSH config file at %USERPROFILE%/.ssh/config
(create a new text file if it does not exist):
Host MachineB
HostName <machine B IP address>
Port <machine B port> # Port where machine B receives SSH connections; likely 22
User <machine B login user>
IdentityFile <path to your private key> # Such as: ~/.ssh/MachineB.id
IdentitiesOnly yes
And connect to machine B manually:
3. Move created config to deployment directories
Now that a key pair and a config entry have been created, you can proceed with creating the actual tunnel service.
First, you will need to move (not copy) your key files and config entry from your local ssh folder to their permanent place. Note that after doing this, you will no longer be able to connect to machine B manually using this key pair. If you need to, create a separate key pair for this.
Move your key files (named MachineB.id
and MachineB.id.pub
in this guide) to one of these two directories:
%ProgramData%/SshReverseTunnel/
— if it’s going to be used for the reverse tunneling only;%ProgramData%/ssh/
— if it’s going to be used as a general admin key for accessing machine B.
Move the entry you made in %USERPROFILE%/.ssh/config
to:
%ProgramData%/SshReverseTunnel/config.d/
(recommended) — if you want to keep configs in separate files;%ProgramData%/SshReverseTunnel/config
— if you only have one tunnel, or plan to keep all configs together in one file. Note thatconfig
is protected from editing by regular users so to open it you will need to runnotepad %ProgramData%/SshReverseTunnel/config
from an admin terminal.
You will also need to do some adjustments to the config entry. First, update it with the new location of the key. To reference the C:/ProgramData
folder use the replacement string __PROGRAMDATA__
, for example:
Host MachineB
...
IdentityFile __PROGRAMDATA__/SshReverseTunnel/MachineB.id
...
Second, add the following line to turn this config into an actual reverse tunnel:
Host MachineB
...
RemoteForward <tunnel port> localhost:<local port>
Explanation:
- Tunnel port: the port on machine B which clients will connect to to reach machine A (go through the tunnel). Ports above 10000 are generally available; consult Wikipedia port number list for more information.
- Local port: the port on machine A which clients will connect to when they exit the tunnel. If you plan to use the tunnel to SSH from machine B to machine A then this port is 22. If you want to reverse-forward something else, such as a website running on machine A, this port is 80 or 443.
If you’d like, here you can also configure the frequency of heartbeat packets that are sent through the tunnel to determine if the connection between machine A and machine B was severed. Heartbeat packets are controlled by three settings:
ServerAliveInterval
(default 10): How often (in seconds) SSH will send a packet to check whether the connection is working. Never disable this by setting it to 0: without this config option the tunnel will never restart.ServerAliveCountMax
(default 3): How many packets need to fail before the tunnel is considered dead and the process terminates (or, in our case, restarts).TCPKeepAlive
(default yes): A secondary method of checking the connection. Seeman ssh_config
for more information.
By default, machine A sends a packet every 10 seconds and restarts after 3 failed packets, so the maximum amount of time between a connection failure and restart is 10*3=30 seconds.
Warning
If you indeed use your tunnel for SSH connections, you may need to update some settings for SSH Server as well. See troubleshooting/ssh connection hangs for more information.
Since the config file will be used by a system user called NT AUTHORITY\NETWORK SERVICE
, you need to make sure that the config file has correct permissions for this. sshrt
has a subcommand fix-permissions
for this. For example:
python -m sshrt fix-permissions "${env:ProgramData}/SshReverseTunnel/config.d/MachineB.conf"
Same goes for the key file as well, for example:
python -m sshrt fix-permissions "${env:ProgramData}/SshReverseTunnel/MachineB.id"
Note
Although the extension of the config file does not matter, we prefer to append.conf
so that it can be configured to be opened as a text file.
Additionally, while you have already connected to this host as your own user, NetworkService account does not know the remote host and will fail unless you add your IP address to the list of known hosts:
ssh-keyscan -t rsa <machine B IP address> >> "${env:ProgramData}/ssh/ssh_known_hosts"
4. Create the tunnel service
Finally, now that every piece is in place, you may create the reverse tunnel service. This service is created using a tool called WinSW from a YAML template file called service-template.yml
in this project’s root directory. You can modify this template if you wish to change some internal service settings like the path to logs (default is %ProgramData%/SshReverseTunnel/logs
), log rotation settings, or how the service behaves when the SSH tunnel fails (by default it restarts the tunnel immediately, unless the tunnel fails to connect, in which case it waits 30 seconds before restarting).
Anyway, run the install
command to create your tunnel service. install
accepts a positional argument tunnel_name
which should be identical to the Host
field in your config
file:
python -m sshrt install MachineB
This command will first perform a test connection to check that everything is configured and works. If you receive the message Service test failed
in console, consult the troubleshooting section.
When the command succeds, it will create the service you requested with the id of SshReverseTunnel-<host>
, where the <host>
is the same string as tunnel_name
in the install command and Host
field in the config file. You may check the status of the service with Get-Service
, for example:
Get-Service SshReverseTunnel-MachineB
You will notice that that the service was not started automatically. You can start it right away by calling Start-Service
, or it will start automatically with system reboot. It’s recommended that you start the service immediately to test for possible problems. If you receive a message Start-Service: Failed to start service
, check for possible causes in %ProgramData%/SshReverseTunnel/logs
and Windows Logs/Application
in the Event Viewer.
5. Connect using the SSH tunnel
The most basic way to check that the SSH tunnel is working is to connect through it via SSH. This is not the same as what was done in step 2: we are now connecting in reverse from machine B to machine A, using the newly established tunnel. Since your tunnel connects localhost
to Machine A using a port you picked as <tunnel port>
in your config, the ssh
command will look something like this:
ssh <machine A username>@localhost -p <tunnel port>
When connecting via SSH to a Windows machine you will likely need to specify a username of the Windows account you are connecting as. If your account has spaces in it you will need to enquote it, both in terminal and in the config
file:
ssh "John Doe@localhost" -p <tunnel port>
# ~/.ssh/config on Machine B
Host MachineA
HostName localhost
Port <tunnel port>
User "John Doe"
Troubleshooting
Failing ssh service test
When the SSH service test fails, you need to look through the script output to figure out what the problem is. The important message is most often at the bottom of the log. Some known problems are listed below.
ssh: Could not resolve hostname hostname
: No such host is known.
SSH could not find your config entry or you have misspelled it. Check the following things:
- The
tunnel_name
argument and theHost
field in your config entry are the same (case-sensitive). - If your config entry is in
config.d
folder and not inconfig
, check thatconfig
includes the line:Include __PROGRAMDATA__/SshReverseTunnel/config.d/*
ssh: connect to hostname
port port
: Connection refused
Your remote server is not running sshd
or is running it on a different port. You can check what ports the host is listening on (if any) by running:
or, on Windows remote machines:
Get-NetTCPConnection -State Listen | Select Local*,Remote*,OwningProcess,@{Name="OwningProcessName";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}} | Format-Table
Can’t open user config file …: Permission denied
You need to fix permissions on the file in question so it’s accessible by the user that runs the remote tunnels, known as NT AUTHORITY\NETWORK SERVICE
. You can either do this manually with icacls
, or by running
python -m sshrt fix-permissions <path>
hostkeys_find_by_key_hostfile: hostkeys_foreach failed for __PROGRAMDATA__/ssh/ssh_known_hosts
: Permission denied
You need to fix permissions on %ProgramData%/ssh/ssh_known_hosts
:
python -m sshrt fix-permissions ${env:ProgramData}/ssh/ssh_known_hosts
Host key verification failed.
SSH refuses to connect to a host whose host key is not in %ProgramData%/ssh/ssh_known_hosts
. If you trust that the IP is correct, you may add the host manually by running this command (from an admin powershell):
ssh-keyscan -t rsa <your-ip-address> >> ${env:ProgramData}/ssh/ssh_known_hosts
Bad owner or permissions on your-keyfile
/ no such identity: your-keyfile
: Permission denied
You need to grant permissions to your keyfile to NT AUTHORITY\NETWORK SERVICE
or run:
python -m sshrt fix-permissions <your-keyfile>
user@hostname
: Permission denied (publickey,…).
SSH server on the remote machine did not accept your key. You may need to look higher in the log to find out why. Best approach is to Ctrl+F for your key file. Reasons could be different depending on what you find:
no such identity: <your-keyfile>: No such file or directory
: your key file does not exist or the path you provided in your ssh config is wrong;offering public key: <your-keyfile>
,receive packet: type 51
: sshd server does not authorize this key. You need to add your public key to your remote server’sauthorized_keys
file (~/.ssh/authorized_keys
on POSIX,%ProgramData%/ssh/administrators_authorized_keys
on Windows).Load key "<your-keyfile>": Permission denied
: you need to grant permissions to your keyfile toNT AUTHORITY\NETWORK SERVICE
or run:python -m sshrt fix-permissions <your-keyfile>
Failing after the service is installed
SSH connection hangs with no output / Error: remote port forwarding failed for listen port port
When using an SSH tunnel to make SSH connection from machine B to machine A, it’s important to configure the SSH Server on machine A so that machine B terminates «zombie» connections when machine A was disconnected without telling (such as during a sudden power loss).
Restart your ssh connection with -vvv
and verify that it hangs on these console messages:
debug1: Connection established.
debug1: identity file /root/.ssh/temp.id type 0
debug1: identity file /root/.ssh/temp.id-cert type -1
debug1: Local version string ...
If yes, it means the connection is a zombie connection. The tunnel was created, but there’s no one on the other side.
You need to add settings that will make SSHD send heartbeat packets, similar to ServerAliveInterval
but the going the opposite direction. Add the following lines to %ProgramData%/ssh/sshd_config
on machine A:
ClientAliveInterval 10
ClientAliveCountMax 3
TCPKeepAlive yes
The first two entries directly mirror ServerAliveInterval
and ServerAliveCountMax
, so in this case the delay between a dead connection and a killed off process is 10*3=30 seconds. The latter, TCPKeepAlive
uses a different mechanism that can be omitted if you’d like. Consult man sshd_config
for more information.
Star History
License
Copyright 2023-2024, Anna Zhukova
This project is licensed under the GNU GPL version 3.0, which means it is free for you to use. You have no requirements to open-source anything if you use these scripts, not your ansible configs, not your Dockerfiles, unless:
- You modify these scripts;
- You distribute these scripts.
If this license prevents you from using these scripts in your environment, please open up an issue and we will figure it out.
SSH туннель представляет собой сетевой протокол, который позволяет удалённо управлять операционной системой и выполнять туннелирование TCP-соединений для передачи данных. В статье расскажем, что такое SSH туннели, как их создавать, настраивать и где применять.
Как устроены SSH-туннели
Туннель через SSH – стандарт, обеспечивающий безопасный удаленный доступ в систему и передачу файлов по защищённым сетям. Кроме того, он защищает трафик данных приложения за счёт переадресации портов, обычно это туннелирование произвольного порта TCP/IP через SSH. То есть трафик направляется на поток внутри зашифрованного SSH-соединения и не может быть перехвачен извне. SSH-туннелирование особенно актуально, если требуется обеспечить безопасность устаревших приложений, которые не поддерживают шифрование.
В рамках SSH-туннелирования устанавливается соединение между клиентом и сервером, оно зашифровывается и тем самым позволяет защитить конфиденциальность и целостность данных.
Приложение соединяется с сервером приложений по SSH, связываясь с портом на локальном хосте. Данные приложения в зашифрованном виде перенаправляются по туннелю на сервер, подключенный к фактическому серверу приложений. Благодаря SSH-туннелированию связь приложения остаётся защищённой, при этом не требуется менять рабочие процессы.
SSH-туннели применяются для:
- Предоставления зашифрованных каналов для протоколов, использующих открытый текст
- Открытия бэкдоров в частные сети
- Обхода сетевых экранов
Создание и настройка SSH-туннеля
Переадресация портов SSH может осуществляться по трём типам:
- Перенаправление локального порта. Соединение перенаправляется с клиентского хоста на SSH-сервер и впоследствии на порт хоста назначения.
- Перенаправление удаленного порта. Соединение перенаправляется с хоста сервера на клиентский хост и впоследствии на порт хоста назначения.
- Динамическая переадресация портов. В данном случае создается прокси-сервер SOCKS, который в свою очередь обеспечивает связь через ряд портов.
Переадресация локального порта
Перенаправление порта SSH-клиента (на локальном компьютере), на порт SSH-сервера (удаленного компьютера) и далее на порт, расположенный на конечном компьютере. Тот в свою очередь может являться удаленным SSH-сервером или каким-либо иным компьютером.
Перенаправление локальных портов требуется для подключения к удаленной службе во внутренней сети. Это может быть, к примеру, база данных или системы удалённого доступа.
В Linux, MacOS и прочих юниксовых системах, для установки локальной переадресации портов нужно использовать следующую команду:
ssh -L [LOCAL_IP:]LOCAL_PORT:DESTINATION:DESTINATION_PORT [USER@]SSH_SERVER
Понадобятся такие параметры:
[LOCAL_IP:]LOCAL_PORT – IP-адрес и номер порта локального компьютера. Если локальный IP не указан, SSH-клиент привязывается к локальному хосту.
DESTINATION:DESTINATION_PORT – IP/имя хоста и порт машины назначения.
[USER@]SERVER_IP – Удаленный пользователь и IP-адрес сервера.
В качестве LOCAL_PORT вы можете использовать любой номер порта больше, чем 1024. Значения меньше 1024 являются привилегированными портами и могут использоваться только пользователем root. Если SSH-сервер прослушивает не 22-й порт, который стоит по умолчанию, используйте опцию -p [PORT_NUMBER].
Имя хоста назначения должно иметь разрешение с сервера SSH.
Переадресация удаленного порта
Перенаправление удаленного порта является противоположным случаю с портом локальным. Здесь можно перенаправить порт на удаленном компьютере (ssh-сервер) на порт локального компьютера (ssh-клиент), а затем на порт конечного компьютера.
Для перенаправления нужно:
ssh -R [REMOTE:]REMOTE_PORT:DESTINATION:DESTINATION_PORT [USER@]SSH_SERVER
Понадобятся такие параметры:
[REMOTE:]REMOTE_PORT – IP-адрес и номер порта удаленного SSH-сервера. Если значение REMOTE не выставлено, удаленный SSH-сервер свяжется сразу со всеми интерфейсами.
DESTINATION:DESTINATION_PORT – IP/имя хоста и порт машины назначения.
[USER@]SERVER_IP – Удаленный пользователь SSH и IP-адрес сервера.
Удаленная переадресация портов в основном используется, чтобы предоставить кому-то извне доступ к одной из внутренних служб.
Аренда облачного сервера для разработки, хостинга, обученияПодробнее
Динамическая переадресация портов
Динамическая переадресация портов даёт возможность создать сокет на локальном компьютере (SSH-клиент), который выступает в качестве прокси-сервера SOCKS. Когда клиент подсоединяется к данному порту, соединение перенаправляется на удаленный компьютер(SSH-сервер), который далее идёт на динамический порт компьютера назначения.
Для создания переадресации динамического порта:
ssh -D [LOCAL_IP:]LOCAL_PORT [USER@]SSH_SERVER
Понадобятся такие параметры:
[LOCAL_IP:]LOCAL_PORT – IP-адрес и номер порта локального компьютера. Если LOCAL_IP не указан, SSH-клиент привязывается к localhost.
[USER@]SERVER_IP – Удаленный пользователь SSH и IP-адрес сервера.
Типовым примером динамической переадресации будет туннелирование трафика браузера через SSH-сервер.
Чтобы создать туннель SOCKS на порту 9090, нужно ввести следующую команду:
ssh -D 9090 -N -f user@remote.host
После установки туннелирования можно настроить приложение для его применения. Перенаправление портов нужно настраивать отдельно для каждого приложения, траффик с которого вы хотите перенаправить по SSH-туннелю.
Настройка SSH-туннелирования в Windows
На Windows туннели SSH создаются с помощью клиента PuTTY. Запустите его и укажите IP-адрес SSH-сервера в поле Host name.
В разделе Connection разверните SSH и выберите Tunnels. Чтобы настроить локальную переадресацию, выберите Local, для удалённой – Remote и Dynamic для динамической переадресации портов.
- При настройке локальной переадресации, введите локальный порт переадресации в поле Source Port field и хост назначения и IP-адрес в поле Destination, например, localhost:5901.
- Для перенаправления удаленного порта введите порт перенапраaвления удаленного SSH-сервера в поле Source Port и целевой хост и IP-адрес в поле Destination, например localhost:3000.
- При настройке динамического перенаправления введите в поле Source Port только локальный порт SOCKS.
Нажмите на кнопку Add
Вернитесь на страницу Session и сохраните настройки, чтобы каждый раз не вводить их заново. Введите имя сеанса в поле Saved Session и нажмите Save. В следующий раз можно будет просто открывать сохраненную сессию.
Практическое применения функций SSH-туннелей
Далее разберём, как можно использовать функции SSH.
Автоматизация копирования ключа SSH
Чтобы не копировать файлы вручную, можно автоматизировать этот процесс с помощью специальной команды. С её помощью можно копировать с вашей системы ключ по умолчанию ~/.ssh/id_rsa.pub в ~/.ssh/authorized_keys
на удалённом сервере.
localhost:~$ ssh-copy-id user@remoteserver
Удалённое выполнение команд
Вы можете связать команду ssh
с другими командам. Для этого вставьте название команды, которую нужно удалённо запустить, вместо последнего параметра в кавычках.
localhost:~$ ssh remoteserver "cat /var/log/nginx/access.log" | grep badstuff.php
Это позволяет выполнить grep
на локальной системе после скачивания лога по ssh-каналу.
Копирование папки по SSH с локального сервера на удалённый
С помощью этой команды можно сжать папку в bzip2
, а затем извлекает данные на удалённом компьютере за счёт создания там дубликата папки:
localhost:~$ tar -cvj /datafolder | ssh remoteserver "tar -xj -C /datafolder"
Редактирование текстовых файлов
Команда, которая понравится пользователям vim. Вы сможете редактировать файлы по scp всего одной командой. Файл создаётся локально в /tmp
, а когда происходит его сохранение из vim, копируется обратно.
localhost:~$ vim scp://user@remoteserver//etc/hosts
Что лучше SSH или VPN
Всё зависит от целей и задач. В целом, оба варианта обеспечивают надёжное шифрование и защиту данных.
VPN сложнее в настройке, но проще в использовании, а SSH – наоборот.
VPN позволяет зашифровать информацию о сетевом трафике, а значит, избежать отслеживания. Туннели SSH для этого нужно каждый раз настраивать вручную.