Переадресация портов SSH: объяснение локальных, удаленных и динамических туннелей.
Изучите локальное, удаленное и динамическое SSH-туннелирование с практическими командами для баз данных, веб-приложений и SOCKS-прокси.
Разбираемся с SSH-туннелированием: локальные, удаленные и динамические туннели
SSH-туннелирование позволяет получить доступ к сетевому сервису через зашифрованное SSH-соединение, не открывая этот сервис напрямую. Обычно это используется, когда база данных, панель управления или сервер разработки доступны с SSH-хоста, но не с вашего ноутбука.
Существует три распространенных типа: локальное, удаленное и динамическое туннелирование. Они используют схожий синтаксис, но прослушивающий порт находится в разных местах.
Что такое SSH-туннелирование
SSH-туннелирование (также известное как SSH-прокси) перенаправляет трафик с одного хоста и порта на другой хост и порт через вашу SSH-сессию. Конечный адрес определяется на стороне, которая устанавливает финальное соединение. При локальном туннелировании SSH-сервер подключается к цели. При удаленном туннелировании ваш SSH-клиент подключается к цели.
Это дает несколько преимуществ:
- Безопасность: Шифрует трафик, который в противном случае передавался бы незашифрованным между вашим клиентом и целевым сервисом.
- Контроль доступа: Позволяет получить доступ к сервисам, работающим в частных сетях или за файрволами, которые недоступны напрямую из вашего текущего местоположения.
- Объединение сетей: Безопасно соединяет различные сегменты сети.
Локальное туннелирование (-L)
Локальное туннелирование — самый распространенный тип. Оно позволяет перенаправлять соединения с порта на вашей локальной машине на порт на удаленной машине через SSH-сервер. По сути, вы делаете сервис, работающий в удаленной сети, доступным так, как если бы он работал на вашей локальной машине.
Как это работает:
- Вы запускаете SSH-клиент на своей локальной машине.
- Вы указываете локальный порт (
local_port), который будет прослушивать SSH. - Любое соединение, установленное с
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-сервере на порт на вашей локальной машине или другой машине, доступной с вашей локальной машины. Это полезно для того, чтобы сделать сервис, работающий на вашей локальной машине, доступным для удаленного сервера или его сети.
Как это работает:
- Вы запускаете SSH-клиент на своей локальной машине.
- Вы указываете удаленный порт (
remote_port) на SSH-сервере, который будет прослушивать SSH. - Любое соединение, установленное с
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-прокси-сервер.
Как это работает:
- Вы запускаете SSH-клиент на своей локальной машине.
- Вы указываете локальный порт (
local_port), который SSH будет прослушивать как SOCKS-прокси. - Вы настраиваете свои приложения (веб-браузер и т.д.) на использование
localhost:local_portв качестве SOCKS-прокси. - Когда приложение отправляет запрос через этот прокси, 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-сервер. Держите привязки строгими, проверяйте политику сервера и относитесь к каждому туннелю как к временному открытию сети.