Серверная (www.it-simple.ru)

Туннель по ssh


Допустим, у нас есть удалённая локальная сеть. Локальная сеть состоит из компьютеров с Windows XP или какого-либо другого сорта Windows. На этих компьютерах разрешено удалённое управление рабочим столом.

Все компьютеры локальной сети выходят в интернет через шлюз на Linux. На нём работает ssh-сервер, через который мы успешно админим собственно сам шлюз, а заодно и другие линуксовые сервера, если они есть. Единственный открытый порт - номер 22 (SSH).

Как в таких условиях подключиться к удалённому рабочему столу произвольного виндового клиента этой сети?

Как вариант, используя доступ по ssh, можно настроить проброс портов (http://www.it-simple.ru/?p=2250) на самом шлюзе, например средствами iptables. После чего зайти на внешний адрес по выбранному порту и творить свои ч0рные дела. Главное не забыть потом вернуть таблицы iptables в исходное состояние, чтоб не создавать дополнительные угрозы безопасности.

А можно использовать средства самого ssh.

Подключение к одному компьютеру

Делаем в консоли:

ssh user@$EXT_IP -L 3389:$LAN_IP:3389

Здесь:
user - пользователь на шлюзе с правом подключения по ssh
$EXT_IP - внешний IP-адрес шлюза
$LAN_IP - IP-адрес целевого компьютера в локальной сети
3389 - порт протокола RDP (протокола удалённого рабочего стола)

После ввода команды окажемся в консоли шлюза, как будто ключ -L и не использовали. Теперь открываем у себя любой клиент терминального сервера (tsclient, rdesktop и т.д.) и подключаемся к адресу localhost (!).

Почему так?

После ввода команды все подключения к нашему локальному адресу на порт 3389 будут отправляться в ssh, а на той стороне переправляться на адрес $LAN_IP и на тот же порт 3389. Поэтому попытка подключения к localhost по RDP приведёт к тому, что мы окажемся на целевой машине в удалённой сети.

Пример для закрепления

Внешний адрес шлюза - 194.87.0.50. В локальной сети 192.168.1.0/24 нас интересует доступ по RDP (порт 3389) к компьютеру с адресом 192.168.1.111. Но на своей стороне мы хотим использовать порт 1234! Делаем так:

ssh user@194.87.0.50 -L 1234:192.168.1.111:3389

После попадания в консоль шлюза подключаемся нашим терминальным клиентом на адрес localhost:1234. Всё, мы на месте.

Одновременное подключение к нескольким удалённым компьютерам

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

user - пользователь на шлюзе
$EXT_IP - внешний IP-адрес шлюза
$LAN_IP1 - IP-адрес первого компьютера в локальной сети
$LAN_IP2 - IP-адрес второго компьютера в локальной сети

Вариант 1. Разные локальные порты

В первой локальной консоли:

ssh user@$EXT_IP -L 1234:$LAN_IP1:3389

Во второй локальной консоли:

ssh user@$EXT_IP -L 5432:$LAN_IP2:3389

Теперь при подключении к localhost:1234 мы попадём на первый компьютер, к localhost:5432 - на второй.

Играясь с портами надо быть предельно внимательным: если у нас стоит PostgreSQL, то в последнем примере он отвалится, потому что сидит как раз на 5432 порту. Запросы к нему будут долбиться в RDP $LAN_IP2.

Вариант 2. Разные локальные интерфейсы

Полная запись параметров ключа -L такая:

-L [наш_адрес]:[наш_порт]:[удалённый_адрес]:[удалённый_порт]

То есть нашим адресом может быть не только localhost, а вообще произвольный.

Поднимаем виртуальный сетевой интерфейс и делаем ssh-канал через него:

ifconfig eth0:0 $ANY_IP up
ssh user@$EXT_IP -L $ANY_IP:3389:$LAN_IP2:3389

$ANY_IP - любой IP-адрес

Теперь надо следить, чтоб не законфликтовали айпи адреса :). Для подключения к удалённому рабочему столу используем $ANY_IP.

Можно использовать виртуальный интерфейс eth0:0 с IP-аресом $ANY_IP для всех удалённых подключений, разделяя их номерами портов.

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

P.S. Огромная благодарность Евгению Короткову за пинки в правильном направлении.