Вы можете использовать встроенный OpenSSH сервер в Windows для проброса портов через SSH-туннель (SSH туннелирования). Перенаправление портов в SSH позволяет туннелировать (пробрасывать) порты приложений с локального компьютера на удаленный сервер и наоборот. Проброс портов через SSH туннель широко используется в среде Linux/Unix, а теперь вы можете воспользоваться этим возможностями и в Windows. В этом примере мы покажем, как пробросить RDP подключение через OpenSSH на хосте Windows Server.
Для чего нужны SSH-туннели?
SSH-туннель обеспечивает защищенное шифрованный TCP соединение локальных хостом и удалённым сервером SSH. SSH Port Forwarding позволяет туннелировать поверх SSH подключение к локальному порту на локальном компьютере к любому TCP порту на удаленном сервере (или наоборот)
Порт форвардинг в SSH-туннелях применяются для:
- Обхода межсетевых экранов;
- Открытия бэкдоров в частные сети;
- Организации простых VPN/прокси сценариев для безопасного удаленного подключения;
- Защиты трафика устаревших приложений (протоколов), которые передают данные в открытом тексте (без шифрования).
Проброс портов через 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 сервера)
Теперь, чтобы подключится к удаленному компьютеру по 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
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 уязвимостей.
Установите 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
.
netsh interface portproxy
.С помощью SSH туннелей вы можете строить целые цепочки для форвардинга портов. Включить или отключить SSH туннелирование можно в конфигурационном файле OpenSSH (sshd_config) с помощью директив:
AllowStreamLocalForwarding yes
AllowTcpForwarding remote
PermitTunnel no
Продолжение про генерацию клиентских ключей будет?
Ага, черновик уже есть. Все работает 🙂
На след. неделе наверно опубликую.
Продолжение: аутентфикация в Windows по SSH ключам.
https://winitpro.ru/index.php/2019/11/13/autentifikaciya-po-ssh-klyucham-v-windows/
Очень интересная тема. Продолжай
Для запрета тунелирования трафика нужно еще в sshd_config добавить директиву:
PermitTunnel no
Я много лет пользуюсь CygWIn SSH. Настроил проброс 3389 порта, но год-полтора назад столкнулся с проблемой — не запускается 1C. Не видит в сети HASP. Я не шибко парился по этому поводу, потому что оно надо очень редко и всегда есть варианты обхода проблемы. Насколько я понял, при RDP подключении через проброшенный порт 1с не ищет ключ в сети или не видит. При «обычном» RDP подключении по сети 1с всё работает нормально. Интересно будет проверить OpenSSH на работоспособность с RDP+1c+HASP.
А так то удобно на флешке держать plink с ключами и подключаться удаленному рабочему столу хоть из кафешки не заморачиваясь с установкой vpn.
Что делать, если наш Windows сервер находится за неуправляемым NAT (нельзя перенаправить порты) ? Я знаю, что используют промежуточный Linux сервер с SSH и белым IP. Наш сервер держит исходящее SSH соединение на этот промежуточный сервер. Клиенты также подключаются к этому промежуточному серверу, который уже связывает их с нашим сервером за NAT. Все бы ничего, но существующие гайды подразумевают, что сервер за NAT также на Linux. Как быть в нашем случае (Windows сервером) ? Интересует решение именно с помощью SSH, не VPN.
У меня такой вопрос. Есть значит сервер на ubuntu на нём приложение , которым можно управлять через rpc порт 9009. Есть сервер , windows , на котором через putty настроен тунель для подключения к серверу на ubuntu через localhost:9999. Есть ПК подключенный к интернет, на котором установлена клиентская часть для общения с серверной частью , которая поднята на ubuntu. Как ПК подключенному к интернет обеспечить доступ к тунелю, который находится на сервере с windows?
Спасибо за статью. Всё отлично. Интересует как сделать тунель на андроиде.
Подскажите плииз.
Заворот RDP через SSH тунель _https://it-infra-ya.com/en/ssh-pf_en/
Отличная статья, взял на заметку
Запретить SSH перенаправление TCP:
AllowTcpForwarding (set YES to NO)
Спасибо, помогло с пробросом
Большое спасибо за статьи по настройке SSH.
Сейчас есть настроенный доступ на удаленный сервер по SSH с помощью Putty, с ключом.
Далее настроенный тунель для подключения по RDP.
Вопрос. Подскажите как такой тунель настроить и такое соединение на Андроиде?
Насколько я помню, ssh клиент ConnectBot для андроида умел использовать аутентификацию по ключам. Насчет тунелей — не знаю, не нужно было никогда. Попробуйте его или возможно есть и другие клиенты.
Ну или может проще настроить подключение через VPN тунель?
Подскажите как настроить.
Возможно я не правильно выразил мысль.
Сейчас на Винде запускаю Putty с ключем. Дале, как в инструкции создается тунель на 3389 порт.
И уже потом подключаюсь к серверу по RDP.
Вот ищу такой вариант для Андроида.
ConnectBot для Android умеет в перенаправление портов. Настройте подключение, а потом в его свойствах откройте меню port forwards. Там можно указать какие порты нужно перенаправлять.
Большое спасибо. Буду изучать.
Пару дней потратил на настройки и тесты. У меня с PuTTY не работает с реверсом. Просто при попытке использовать проброс PuTTY (версия 0.81), она выдает ошибку(после авторизации). Старые версии PuTTY не работают из-за разницы в ключах. Кто-нибудь знает, как ограничить подключение только для использования тунеля? Без shell/sftp и желательно со стороны сервера. Сервер Win OpenSSH.
Как вариант через sshd_config добавить ForceCommand logoff.exe. Но не знаю, будет ли это рвать сессию.
Либо изменить стандартный shell на что-то левое:
New-ItemProperty -Path «HKLM:\SOFTWARE\OpenSSH» -Name DefaultShell -Value «C:\Windows\System32\sfc.exe» -PropertyType String -Force
Как насчет двойного туннеля? Прямой и обратный. Мозг уже сломал как на микротике такое сделать. Есть микротик с белым адресом, с рабочего компа запускаю обратный туннель на микротик и с удаленного клиента прямой туннель на микротик. ssh forward на микротике включен. По идее два туннеля должны соединиться, но этого не происходит. Предполагаю какие-то особенности работы ssh сервера микротика. При этом оба туннеля сами по себе работают и порты пробрасывают.
На микротике даже нельзя посмотреть открыт ли порт. Разве что через с консоли запустить /system telnet , но это мало что дает.
На сколько я знаю, SSH в Mikrotik обрезан. У него отсутствует часть функционала. Возможно, проблема в этом.