OpenSSH: демонстрация фокусов с их последующим разоблачением
Хакеров и опытных админов отличает способность находить изящные решения поставленных задач. Как ты смотришь на то, чтобы использовать OpenSSH для создания виртуальных частных сетей? Причем, без применения SSH-перенаправлений, соксификации и сторонних разработок, таких как, например, OpenVPN.
VPN на базе SSH
В последнее время технология VPN получила завидное распространение. Обычно, упоминая ее, подразумевают либо стандартные протоколы туннелирования PPTP и L2TP/IPsec, либо специализированные решения, вроде OpenVPN, и лишь немногие знают о более простой альтернативе – SSH-туннелинг. Поднятые на втором или третьем уровне OSI зашифрованные туннели обеспечат приложениям полноценный и прозрачный доступ к любым ресурсам удаленной сети. А учитывая, что SSH-сессии не только шифруются (по умолчанию задействован алгоритм AES), но и сжимаются, мы, кроме приватности, получим небольшой прирост в скорости и экономию драгоценных мегабайтов. Немаловажно, что такой подход не требует знания протоколов защиты сетевого трафика, вмешательства в ядро операционной системы, заморочек с фильтрацией пакетов или наличия особых программ.
Для примера возьмем два сервера: srv1 с IP-адресами 212.34.XX.YY и 192.168.2.1 подключен к сегменту внутренней сети 192.168.2.0/24, а srv2 с 213.167.XX.YY и 192.168.1.1 шефствует над подопечными из 192.168.1.0/24. Настроим VPN-туннель средствами OpenSSH, в котором будут использоваться адреса 10.0.0.1 и 10.0.0.2. Для наглядности сценарий можно представить следующим образом:
Стоит отметить, с помощью OpenSSH возможно построение не только Site-to-Site VPN (межсайтовое подключение, в котором два маршрутизатора создают туннель в интернете), но и Client-to-Site (VPN-подключение удаленного доступа для проводных и беспроводных клиентов).
Ключевые элементы сетевой конфигурации рассмотрены, теперь приступаем к настройкам. Логинимся на srv1 и правим главный конфигурационный файл sshd:
srv1% sudo vim /etc/ssh/sshd_config
По окончании настроек не забываем отправить демону сигнал SIGHUP, чтобы он смог перечитать свой конфиг:
srv1% sudo sh -c "kill -HUP `sed q /var/run/sshd.pid`"
Далее разрешаем прохождение пакетов на используемых туннельных псевдоустройствах (на tun0 у меня висит OpenVPN, tun1 – для OpenSSH; tun представляет собой нечто вроде драйвера IP-туннелей):
srv1% sudo vim /etc/pf.conf
pass quick on { tun0, tun1 } inet all
Загружаем правила из конфига:
srv1% sudo pfctl -f /etc/pf.conf
При помощи команды ifconfig проверяем его состояние:
srv1% ifconfig tun1
Не забываем добавить в таблицу маршрутизации удаленную подсеть:
srv1% sudo route add 192.168.1.0/24 10.0.0.2
Второй сервер выступает в роли SSH-клиента, поэтому процедура конфигурирования здесь чуть проще:
srv2% sudo sh -c "echo 'Tunnel point-to-point' \
>> /etc/ssh/ssh_config"
Остальные настройки и действия практически идентичны описанным выше: правим и активируем рулесеты файрвола, поднимаем tun1, присваиваем ему сетевой адрес (обрати внимание, порядок следования IP-адресов изменен) и добавляем статический маршрут:
srv2% sudo vim /etc/pf.conf
И, наконец, самый ответственный момент – устанавливаем защищенное соединение между двумя сетями:
srv2% sudo ssh -f -w 1:1 212.34.XX.YY true
Чтобы снизить накладные расходы, к списку аргументов имеет смысл добавить: «-o Compression=yes -x -a –n» (сжимать передаваемые данные, отключить пересылку пакетов X11, запретить аутентификацию с помощью агента и направить /dev/null на стандартный входной поток STDIN).
Теперь проверим доступность удаленного узла, находящегося «за первым сервером»:
srv2% ping 192.168.2.101
Если все ОК, то можно и дальше развивать предложенную схему, упрощая или, наоборот, усложняя настройки. Например, применить беспарольную аутентификацию на базе ключей, нарисовать конфигурационный файл для автоматического создания псевдоустройства tun1:
srv2% sudo sh -c "echo '10.0.0.2 10.0.0.1 netmask 0xfffffffc' \
> /etc/hostname.tun1"
Занести необходимые статические маршруты и запуск «ssh -f –w» в один из сценариев начальной загрузки (/etc/rc.local). Или в отдельный скрипт, чтобы все выполнялось одной командой, без дополнительных телодвижений.
Чтобы использовать OpenSSH на уровне OSI 2, нужно в качестве значения директив PermitTunnel и Tunnel использовать ethernet, а затем объединить в мост внешний сетевой интерфейс и псевдоустройство tunX (см. bridge(4)).
Управляющие последовательности SSH
Продолжим фокусничать. Таинство магии управляющих последовательностей откроется, если в SSH-сессии сначала нажать <Enter>, затем – управляющий символ сеанса (по умолчанию тильда, задается директивой EscapeChar) и специальную клавишу, которая указывает, какую именно функцию следует выполнить. Проще всего это показать на конкретных примерах.
ssh> -R 8110:mail.domain.ru:110
Forwarding port.
Проверяем работу созданного почтового туннеля:
bastion% telnet localhost 8110
+OK Dovecot ready.
В ответ получен баннер от Dovecot. Значит, все в порядке.
Кстати, обратившись к подсказке, получим список всех доступных ключей и дополнительных параметров:
bastion% <Enter>~C
ssh> help
Commands:
-L[bind_address:]port:host:hostport Request local forward
-R[bind_address:]port:host:hostport Request remote forward
-KR[bind_address:]port Cancel remote forward
Если в ~/.ssh/config установить значение директивы PermitLocalCommand в yes, то мы сможем выполнять команды в локальном шелле (то есть на хосте, с которого зашли):
ssh> !uptime /* команда выполняется на хосте ns */
7:02PM up 100 days, 11 mins, 1 user, load averages: 0.13, 0.21, 0.23
<Enter>
mx3% uptime /* команда выполняется на хосте mx3 */
7:02PM up 4 days, 7:34, 1 user, load averages: 0.21, 0.23, 0.19
Если на предыдущем узле требуется выполнить сразу несколько команд, то SSH-сессию лучше временно «засуспендить» (приостановить выполнение программы ssh):
mx3% <Enter>~<Ctrl-Z>
[1] + Suspended "ssh" "$@"
Чтобы перевести SSH-сессию из остановленного режима в активный, воспользуйся командой fg.
Список текущих SSH-соединений можно просмотреть комбинацией:
mx3% <Enter>~#
А для быстрого завершения SSH-сессии ставим точку:
mx3% <Enter>~.
Connection to 213.167.XX.YY closed.
Админ должен быть ленив!
Чтобы в консоли не вводить полное доменное имя, порт и учетную запись для подключения к удаленной системе, стоит заручиться поддержкой директивы Host:
% vim ~/.ssh/config
Таким образом, нам достаточно ввести «ssh mx2», – и мы попадем на заветный сервер. Уже не плохо, однако каждый раз приходится набирать четыре «лишних» символа (ssh и пробел). Лень сподвигает на написание двухстрочного сценария, «съедающего» ssh, но сохраняющего все переданные в командной строке аргументы, пробелы и кавычки:
Наделяем скрипт атрибутом исполнения и создаем символическую ссылку на псевдоним удаленного сервера:
Вводить ssh больше не требуется (P.S. подкаталог bin должен быть прописан в переменной окружения PATH):
% mx2 uptime
5:16PM up 45 days, 8:40, 0 users, load averages: 0.55, 0.40, 0.35
Если узлов несколько, то для каждого создаем аналогичную символическую ссылку, выбрав в качестве имени его hostname.
Небольшой оптимизации можно достигнуть, отказавшись от вызова утилиты basename(1) и применив встроенные возможности командной оболочки:
% vim myssh
#!/bin/sh
exec /usr/bin/ssh ${0##*/} $@
Обходим файрволы
Соединяемся с узлом gate и проверяем возможность подключения к локальному порту 8022:
SSH-2.0-VShell_3_0_4_656 VShell
Теперь можно логиниться на файловый сервер, который находится за NAT'ом, в обход рулесетов, установленных на шлюзе:
% ssh fileserver
Microsoft Windows [Version 5.2.3790]
C:\Documents and Settings\Smelaya\My Documents>
Как видишь, SSH-туннель – это самый простой способ, позволяющий обойти файрвол и получить доступ к закрытому админом сервису. Есть и специализированные приложения, предназначенные для более удобной организации SSH-туннелей. Например, RSTunnel (Reliable SSH Tunnel, rstunnel.sf.net), Corkscrew (www.agroman.net/corkscrew) и другие.
Безопасный SFTP
Многие хостинговые компании предоставляют своим пользователям доступ по FTP. Назначение каталогов может быть разное, но нас интересует, как сделать доступ безопаснее. Здесь на помощь также может прийти SSH:
% sudo vim /etc/ssh/sshd_config
Subsystem sftp internal-sftp
Теперь зарегистрированные пользователи будут допущены только к «своему» каталогу, при подключении модификатор «%u» будет заменен именем пользователя. При необходимости можно использовать «%h», который соответствует домашнему каталогу юзера.
Ограничение подключений к SSH
Так мы разрешили три подключения к 8022 порту в течение пяти минут. В PF не сложнее:
% sudo vim /etc/pf.conf
Здесь фильтр пакетов не допустит более пять одновременных соединений к 22 порту за 60 секунд. При желании правила можно ужесточить.
Заключение
С помощью семейства команд SSH можно не только обеспечить аутентификацию и шифрование данных между хостами, существенно затрудняя перехват со стороны других узлов, но и создать виртуальную частную сеть, объединяющую несколько компьютеров или сетей, обойти эшелонированные заслоны, заботливо выставленные админом, и наделить различные приложения новым функционалом. Набор сетевых инструментов OpenSSH обладает чрезвычайно богатыми возможностями, и с ними стоит познакомиться поближе.
Для перенаправления X11-подключений следует использовать ключ '–Y':
$ ssh -Y user@domain.com
Причем в конфиге /etc/ssh/sshd_config параметр «X11Forwarding» должен быть установлен в yes. Если X-сервер запущен на локальной системе, то активируем и «X11UseLocalhost».
INFO
Аутентификация и последующее шифрование SSH-сессии выполняется незаметно для пользователей.
Управляющая последовательность использует специальный управляющий символ (escape-символ), чтобы идентифицировать начало команды.
Некоторые примеры продвинутой работы с OpenSSH смотри в предыдущем номере журнала, в статье «Калейдоскоп тайных знаний».
WWW
Для борьбы с перебором пароля можно использовать специальные приложения: DenySSH (wiki.wonko.com/software/denyssh), pam-abl (pam-abl.sf.net), DenyHosts (denyhosts.sf.net) и другие.
VShell Server для Windows: www.vandyke.com/products/vshell/.