Переадресация портов SSH: объяснение локальных, удаленных и динамических туннелей.

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

Разбираемся с SSH-туннелированием: локальные, удаленные и динамические туннели

SSH-туннелирование позволяет получить доступ к сетевому сервису через зашифрованное SSH-соединение, не открывая этот сервис напрямую. Обычно это используется, когда база данных, панель управления или сервер разработки доступны с SSH-хоста, но не с вашего ноутбука.

Существует три распространенных типа: локальное, удаленное и динамическое туннелирование. Они используют схожий синтаксис, но прослушивающий порт находится в разных местах.

Что такое SSH-туннелирование

SSH-туннелирование (также известное как SSH-прокси) перенаправляет трафик с одного хоста и порта на другой хост и порт через вашу SSH-сессию. Конечный адрес определяется на стороне, которая устанавливает финальное соединение. При локальном туннелировании SSH-сервер подключается к цели. При удаленном туннелировании ваш SSH-клиент подключается к цели.

Это дает несколько преимуществ:

  • Безопасность: Шифрует трафик, который в противном случае передавался бы незашифрованным между вашим клиентом и целевым сервисом.
  • Контроль доступа: Позволяет получить доступ к сервисам, работающим в частных сетях или за файрволами, которые недоступны напрямую из вашего текущего местоположения.
  • Объединение сетей: Безопасно соединяет различные сегменты сети.

Локальное туннелирование (-L)

Локальное туннелирование — самый распространенный тип. Оно позволяет перенаправлять соединения с порта на вашей локальной машине на порт на удаленной машине через SSH-сервер. По сути, вы делаете сервис, работающий в удаленной сети, доступным так, как если бы он работал на вашей локальной машине.

Как это работает:

  1. Вы запускаете SSH-клиент на своей локальной машине.
  2. Вы указываете локальный порт (local_port), который будет прослушивать SSH.
  3. Любое соединение, установленное с local_port на вашей локальной машине, перенаправляется через SSH-соединение на remote_host и remote_port.

Синтаксис:

ssh -L [local_bind_address:]local_port:remote_host:remote_port [user@]ssh_server_host
  • local_bind_address: Необязательный адрес на вашей локальной машине для привязки. Если опущен, OpenSSH обычно привязывается к адресам loopback, если конфигурация клиента не указывает иное.
  • local_port: Порт на вашей локальной машине, который будет прослушивать SSH.
  • remote_host: Имя хоста или IP-адрес целевой машины, к которой подключится SSH-сервер.
  • remote_port: Порт на remote_host, на который будет направлен трафик.
  • user@ssh_server_host: Ваше имя пользователя и имя хоста/IP-адрес SSH-сервера, к которому вы подключаетесь.

Практический пример: Доступ к серверу базы данных, работающему на частном IP-адресе удаленного сервера.

Представьте сервер базы данных (например, PostgreSQL на 192.168.1.100:5432), доступный только из внутренней сети вашей компании. Вы можете использовать локальное туннелирование для доступа к нему со своего ноутбука дома:

ssh -L 5433:192.168.1.100:5432 your_user@your_ssh_server.com
  • Эта команда подключает вас к your_ssh_server.com.
  • Она открывает порт 5433 на вашей локальной машине (по умолчанию localhost).
  • Любое соединение с localhost:5433 будет перенаправлено через your_ssh_server.com на 192.168.1.100:5432.

Теперь вы можете настроить свой локальный клиент базы данных на подключение к localhost:5433, и трафик будет безопасно туннелирован к удаленному серверу базы данных.

Совет: Используйте ssh -N для создания туннеля без выполнения удаленной команды. Это полезно для фоновых туннелей.

ssh -N -L 5433:192.168.1.100:5432 your_user@your_ssh_server.com

Удаленное туннелирование (-R)

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

Как это работает:

  1. Вы запускаете SSH-клиент на своей локальной машине.
  2. Вы указываете удаленный порт (remote_port) на SSH-сервере, который будет прослушивать SSH.
  3. Любое соединение, установленное с remote_port на SSH-сервере, перенаправляется через SSH-соединение обратно на вашу локальную машину, а затем на указанный destination_host и destination_port.

Синтаксис:

ssh -R [remote_bind_address:]remote_port:destination_host:destination_port [user@]ssh_server_host
  • remote_bind_address: (Необязательно) Адрес на SSH-сервере для привязки прослушивающего порта. По умолчанию — localhost (это означает, что только сам SSH-сервер может подключаться к этому порту). Используйте 0.0.0.0 или *, чтобы разрешить другим машинам в удаленной сети подключаться.
  • remote_port: Порт на SSH-сервере, который будет прослушивать SSH.
  • destination_host: Имя хоста или IP-адрес целевой машины, к которой подключится ваш SSH-клиент (часто localhost, если сервис находится на вашей локальной машине).
  • destination_port: Порт на destination_host, на который будет направлен трафик.
  • user@ssh_server_host: Ваше имя пользователя и имя хоста/IP-адрес SSH-сервера, к которому вы подключаетесь.

Практический пример: Предоставление доступа к локальному веб-серверу из удаленной сети.

Предположим, вы разрабатываете веб-приложение на своем ноутбуке и хотите продемонстрировать его коллеге, у которого есть доступ только к внутренней сети вашей компании, и у вас есть SSH-сервер (your_ssh_server.com), доступный из этой сети.

На вашем ноутбуке вы запускаете:

ssh -R 8080:localhost:3000 your_user@your_ssh_server.com
  • Эта команда подключает вас к your_ssh_server.com.
  • Она указывает your_ssh_server.com прослушивать порт 8080.
  • Любое соединение с your_ssh_server.com:8080 будет перенаправлено обратно через SSH-туннель на ваш ноутбук (localhost) на порт 3000 (где работает ваш веб-сервер).

Теперь ваш коллега может получить доступ к вашему веб-приложению, перейдя в браузере по адресу http://your_ssh_server.com:8080. Трафик идет от его браузера к SSH-серверу, через туннель к вашему ноутбуку, а затем к вашему веб-серверу.

Предупреждение: В типичных конфигурациях OpenSSH remote_port доступен только с самого SSH-сервера. Чтобы разрешить другим машинам в удаленной сети доступ к перенаправленному порту, явно укажите remote_bind_address как 0.0.0.0 или * и убедитесь, что SSH-сервер разрешает это с помощью настройки GatewayPorts, такой как clientspecified или yes.

ssh -R 0.0.0.0:8080:localhost:3000 your_user@your_ssh_server.com

Динамическое туннелирование (-D)

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

Как это работает:

  1. Вы запускаете SSH-клиент на своей локальной машине.
  2. Вы указываете локальный порт (local_port), который SSH будет прослушивать как SOCKS-прокси.
  3. Вы настраиваете свои приложения (веб-браузер и т.д.) на использование localhost:local_port в качестве SOCKS-прокси.
  4. Когда приложение отправляет запрос через этот прокси, SSH перенаправляет трафик на SSH-сервер, который затем устанавливает соединение с конечным пунктом назначения от имени вашего приложения.

Синтаксис:

ssh -D [local_bind_address:]local_port [user@]ssh_server_host
  • local_bind_address: (Необязательно) Адрес на вашей локальной машине для привязки прослушивающего порта SOCKS-прокси. По умолчанию — localhost.
  • local_port: Порт на вашей локальной машине, который SSH будет прослушивать как SOCKS-прокси.
  • user@ssh_server_host: Ваше имя пользователя и имя хоста/IP-адрес SSH-сервера, к которому вы подключаетесь.

Практический пример: Безопасный просмотр веб-страниц из общедоступной Wi-Fi сети.

При подключении к ненадежной общедоступной Wi-Fi сети ваш трафик уязвим. Вы можете использовать динамическое туннелирование для туннелирования всего трафика веб-браузера через зашифрованное SSH-соединение к доверенному серверу.

На вашем ноутбуке запустите:

ssh -D 1080 your_user@your_trusted_server.com
  • Эта команда подключает вас к your_trusted_server.com.
  • Она открывает порт 1080 на вашей локальной машине, действуя как SOCKS-прокси.

Затем настройте свой веб-браузер или другое приложение на использование SOCKS-прокси по адресу localhost на порту 1080. Если в приложении есть опция удаленного DNS для SOCKS5, используйте ее, если вы не хотите, чтобы DNS-запросы выполнялись в вашей локальной сети.

Трафик вашего браузера отправляется на ваш SSH-сервер, который затем подключается к целевому сайту. HTTPS по-прежнему важен; SSH-туннель защищает путь к вашему SSH-серверу, но не каждый последующий переход.

Совет: Вы можете комбинировать -D с -C для сжатия, что может быть полезно на медленных сетевых соединениях.

ssh -C -D 1080 your_user@your_trusted_server.com

Дополнительные соображения и лучшие практики

  • Конфигурация SSH-сервера (sshd_config): Некоторые функции туннелирования требуют разрешения на стороне сервера. Проверьте AllowTcpForwarding, PermitOpen, PermitListen и GatewayPorts, прежде чем предполагать, что туннель может прослушивать или подключаться где угодно.
  • Файрволы: Помните, что файрволы на клиенте, сервере или промежуточных сетях могут блокировать SSH-соединения или порты, используемые для туннелирования. Убедитесь, что необходимые порты (обычно 22 для самого SSH) открыты.
  • Безопасность: Хотя туннелирование шифрует трафик, безопасность туннеля зависит от безопасности вашего SSH-сервера. Используйте надежные SSH-ключи, отключите аутентификацию по паролю и регулярно обновляйте SSH-сервер.
  • Надежность: Для скриптов добавьте -o ExitOnForwardFailure=yes, чтобы SSH завершал работу, если не может создать запрошенное перенаправление. Для долго работающих туннелей рассмотрите autossh или управляемый сервис.

Вывод

Используйте -L, когда вашему ноутбуку нужен доступ к частному удаленному сервису. Используйте -R, когда удаленному хосту нужен доступ к чему-то рядом с вашим ноутбуком. Используйте -D, когда вам нужен SOCKS-прокси через доверенный SSH-сервер. Держите привязки строгими, проверяйте политику сервера и относитесь к каждому туннелю как к временному открытию сети.