Тариф успешно добавлен в корзину
В корзину
url image

SSH-туннели: настройка и примеры использования

Служба SSH (Secure Shell, безопасная оболочка) — один из главных инструментов администратора, устанавливаемых на сервер под управлением Linux и других Unix-подобных операционных систем. Служба предназначена в первую очередь для управления удалёнными компьютерами. Благодаря надёжности и безопасности одноимённый протокол SSH фактически стал стандартом администрирования узлов сети. Кроме того, SSH позволяет делать и другие полезные вещи, например, безопасно монтировать удалённые файловые системы (SSHFS, Secure SHell FileSystem), передавать файлы по протоколу SFTP (Secure File Transfer Protocol, безопасный протокол передачи файлов) или SCP (Secure CoPy, безопасное копирование). Но сегодня мы поговорим о другой возможности этой программы — создании защищённых туннелей, позволяющих безопасно передавать трафик пользователей через интернет.

Концепция работы SSH-туннеля

SSH-туннелирование позволяет установить зашифрованное соединение между двумя компьютерами через незащищённую сеть. В основе работы SSH-туннеля лежит передача пакетов TCP/IP с порта одного компьютера на порт другого, поэтому эту технологию иногда называют также «пробросом портов» (SSH Port Forwarding).

Важным достоинством SSH-туннелей можно считать простоту настройки — поскольку соединение устанавливается со службой SSH на сервере, которая в большинстве случаев уже работает, никаких дополнительных действий не требуется.

Синтаксис

При создании туннеля можно использовать два основных режима: локальный (Local) и удалённый (Remote).

Для создания локального туннеля используется параметр -L, а команда может выглядеть так:

ssh -L локальный_порт:локальный_хост:удалённый_порт удалённый_хост

Вместо имени удалённого хоста можно использовать пару пользователь_ssh@IP_адреc_сервера, а в случае если команда ssh запускается от имени пользователя, совпадающего с пользователем ssh, достаточно указать только IP-адрес.

Синтаксис команды создания удалённого туннеля выглядит похоже, но использует параметр -R:

ssh -R удалённый_порт:локальный_хост:локальный_порт удалённый_хост

Обратите внимание, что компьютер, на котором запускается удалённый туннель (клиент SSH), может находится за межсетевым экраном или вообще не принимать входящие соединения. Таким образом удалённый туннель может обеспечить подключение к компьютеру, недоступному из глобальной сети. По этой причине удалённые туннели также часто называют реверсивными (Reverse).

Полное описание синтаксиса команды ssh можно получить по команде «man ssh».

Примеры работы с SSH-туннелями

1. Подключение к службе на сервере (локальный SSH-туннель).

Допустим, на сервере c IP-адресом 1.2.3.4 запущена служба базы данных PostgreSQL, слушающая локальный порт 5432. Подключение к этому порту извне невозможно, но на сервере открыт порт 22, который прослушивает служба SSH (sshd). Подключение по SSH открыто для пользователя user. Чтобы получить доступ к базе данных в этом случае можно на локальном компьютере запустить команду

ssh -L 5555:localhost:5432 user@1.2.3.4

Теперь порт 5555 с локального компьютера пробрасывается на порт 5432 на сервере и можно подключиться к удалённой базе данных, выполнив команду

psql -h localhost -p 5555

Наглядно схему подключения с помощью локального SSH-туннеля можно представить так:

Локальный SSH-туннель
Локальный SSH-туннель

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

Теперь давайте немного усложним задачу. Предположим, наша база данных установлена на сервере без доступа из интернета, например, с «серым» IP-адресом, но мы хотим обращаться к ней с локального компьютера с «белым» адресом 6.7.8.9 и запущенной службой SSH. В этом случае на сервере можно выполнить такую команду:

ssh -R 5555:localhost:5432 user@6.7.8.9

После этого порт 5555 на сервере будет пробрасываться на порт 5432 на локальном компьютере, что даст нам возможность выполнять ту же команду psql.

Удалённый SSH-туннель
Удалённый SSH-туннель

Проверить наличие соединения на удалённом сервере можно командой «lsof -i -P -n | grep LISTEN» или «ss -nlpt»:

Проверка соединения на удалённом сервере

Две последние строки в выводе этой команды означают, что сервер слушает локальные соединения на порту 5555, как и ожидалось.

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

ssh -R 4433:localhost:4430 user@6.7.8.9

Здесь мы предполагаем, что веб-сервер на компьютере с SSH-клиентом слушает порт 4430, на который пробрасывается порт 4433 c удалённого сервера. Обратите внимание, что по умолчанию порт 4433 доступен только с локального IP-адреса 127.0.0.1 (localhost). Чтобы клиенты из интернета могли подключаться к нашему веб-серверу, мы можем в настройках службы SSH (ssh_config) разрешить переадресацию портов на внешние сетевые интерфейсы (GatewayPorts yes). В этом случае для входа на веб-сервер клиентам в адресной строке браузера нужно будет указать номер порта:

https://6.7.8.9:4433

Чтобы воспользоваться стандартным портом 443 и не менять настройки SSH, можно дополнительно пробрасывать внешние соединения с порта 443 на внутренний порт 4433 с помощью проксирующей службы, например, nginx. Тогда наша схема подключения примет такой вид:

Удалённый SSH-туннель для веб-сервера
Удалённый SSH-туннель для веб-сервера

Здесь для организации подключения клиентов мы используем безопасный протокол HTTPS.

Ещё раз обращаем внимание, что во всех рассмотренных вариантах служба SSH запущена только на одном компьютере, для всех остальных участников соединения достаточно иметь клиент SSH.

Для доступа к службе рекомендуется использовать настроенную авторизацию по ключу для пользователя user.

Чтобы сделать SSH-туннель доступным после перезагрузки компьютера, на стороне, вызывающей команду ssh -L или ssh -R, удобно воспользоваться службой systemd. Для того, чтобы создать собственную службу, в директории /etc/systemd/system добавим файл, например, ssh-tunnel.service примерно такого содержания:

[Unit]
Description=SSH tunnel
After=network-online.target
[Service]
ExecStart=/usr/bin/ssh -i /home/user/.ssh/ssh-tunnel-key -NT \
    -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes \
    -R 4433:localhost:4430 user@6.7.8.9
RestartSec=15
Restart=always
[Install]
WantedBy=network-online.target

Здесь мы указали несколько дополнительных параметров запуска туннеля:

  • -i /root/.ssh/ssh-tunnel-key — указывает расположение приватного SSH-ключа ssh-tunnel-key.
  • -N — не выполнять удалённую команду.
  • -T — отключить псевдо-терминал.
  • -o ServerAliveInterval=60 и -o ExitOnForwardFailure=yes — опции, позволяющие перезапустить службу после потери соединения.

Таким образом, служба ssh-tunnel будет автоматически активизирована при запуске сервера после того, как сетевой интерфейс установит соединение (network-online.target) и перезапущена после возможного разрыва соединения.

После создания файла ssh-tunnel нужно последовательно выполнить команды:

sudo systemctl daemon-reload
sudo systemctl start ssh-tunnel.service
sudo systemctl enable ssh-tunnel.service

Проверить состояние службы можно стандартным способом:

sudo systemctl status ssh-tunnel.service

SOCKS-прокси сервер и динамическая переадресация портов

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

Предположим, у нас есть сервер с запущенной службой SSH и IP-адресом 1.2.3.4. Сервер имеет возможность прямого соединения с интересующими нас интернет-ресурсами. В этом случае на локальном компьютере достаточно запустить такую команду:

ssh -D 8888 user@1.2.3.4

Параметр -D здесь означает динамическую переадресацию портов. Когда приложение устанавливает соединение с портом 8888, оно перенаправляется по защищённому каналу на сервер 1.2.3.4, а затем приложение использует протокол SOCKS для создания подключения к нужному узлу с удалённого сервера.

Чтобы воспользоваться созданным таким способом прокси-сервером, нужно настроить приложение. Например, в браузере Firefox настройки соединения находятся в нижней части раздела Настройки — Основные:

Экран основных настроек в браузере Firefox
Firefox, экран основных настроек
Настройки соединения SOCKS в Firefox
Firefox, настройки соединения SOCKS

Использование, собственного SOCKS-прокси сервера имеет cерьёзное преимущество: работая через SSH, можно безопасно вводить пароли, коды доступа, номера кредитных карт и другие чувствительные данные, что настоятельно не рекомендуется делать при использовании публичных прокси-серверов.

Несколько туннелей и переключение нескольких хостов

Чтобы не создавать отдельные подключения с одним и тем же сервером, через одно соединение можно создать несколько туннелей, указав несколько параметров -L, например:

ssh -L 5555:server1:5432 -L 4433:server2:4430 user@server3

В этом случае при обращении к адресу localhost:5555 мы попадём на адрес server1:5432, а при обращении к localhost:4433 соединение пробросится на server2:4430. В обоих случаях целевые серверы находятся за узлом server3.

Прыжки по хостам

Если ваша сеть разделена на сегменты (подсети), для соединения с компьютером, не входящим в вашу подсеть, вы можете воспользоваться параметром -J (Proxy Jump, проксирующий прыжок). Этот параметр также удобен, например, для доступа к серверам в облаке, находящимися за NAT и не имеющим доступа из интернета.

Синтаксис команды очень простой:

ssh -J <jump-сервер> <удалённая цель>

Поскольку jump-сервер используется для доступа к закрытой подсети, его часто называют «бастионом». В крупных инфраструктурах по соображениям безопасности в качестве бастиона используется отдельный сервер, который выполняет только одну задачу — проксирование обращений к внутренним службам. Такими службами могут быть веб-серверы, DNS-серверы, почтовые, FTP и VPN серверы и так далее.

При необходимости jump-серверов может быть несколько, например:

ssh -J хост1,хост2,хост3 пользователь@хост4

В этом случае SSH создаст туннель до сервера хост4 через цепочку серверов хост1...хост3.

Стоит обратить внимание, что при подключении через промежуточный сервер используются ключи авторизации этого сервера, а не компьютера, с которого вы подключились к нему. Чтобы пробросить ключи с вашего компьютера на сервер, можно использовать технологию SSH Agent Forwarding, например, с помощью параметра -A (проброс агента аутентификации ssh-agent):

ssh -A пользователь@хост

Замечание по безопасности: при пробросе ключей локальные данные авторизации не хранятся в файловой системе промежуточного сервера, но всё же доступны в переменных окружения. Поэтому не рекомендуем использовать ForwardAgent на серверах, которые вы не контролируете. Также не рекомендуем использовать параметр «ForwardAgent yes» в локальном файле конфигурации ~/.ssh/config на постоянной основе.

Безопасность SSH-туннелей

В основе работы SSH лежит криптография — алгоритм шифрования трафика, для расшифровки которого требуются специальные ключи. Несмотря на высокую надёжность этого метода, можно порекомендовать некоторые дополнительные меры усиления безопасности:

  • Отключение входа по паролю. Настоятельно рекомендуем вместо входа с открытым паролем использовать вход по ключу.
  • Отключение root-доступа. Удалённый доступ суперпользователя в случае компрометации открывает злоумышленнику неограниченный доступ к серверу. Именно поэтому роботы, выполняющие атаки методом «брутфорс» (Brute Force, грубая сила), первым делом пытаются подобрать пароль к учётной записи root. В этом легко убедиться, просматривая записи журнала службы SSH о попытках неудачного входа практически на любом сервере с выходом в интернет. Поэтому вместо root-доступа рекомендуем использовать соединение от имени непривилегированного пользователя, при необходимости входящего в группу wheel, заданную в файле sudoers.
  • Ограничение попыток входа в SSH. Для снижения риска успешного проведения атаки сервера методом грубой силы рекомендуется использовать нестандартные имена пользователей, а также ограничить число попыток авторизации. Это можно сделать встроенными средствами SHH, например, уменьшив значение MaxAuthTries в файле конфигурации /etc/ssh/sshd_config, или с использованием внешних инструментов, таких как fail2ban.

Заключение

Мы рассмотрели некоторые возможности службы SSH по созданию защищённых туннелей и проксированию трафика пользователя. Надеемся, эта информация поможет вам организовать надёжную связь в интернете в случае проблем с доступом к отдельным узлам сети.

Этот материал был полезен?

Скидка 25% новым клиентам!
Закажи сервер сегодня и получи скидку на первый месяц аренды!