- Вопрос или проблема
- Редактировать:
- — предыдущий (неправильный) ответ —
- Ответ или решение
- Как сделать SSH-туннель общедоступным
- 1. Основы SSH-туннелирования
- 2. Команда для создания удаленного туннеля
- 3. Проблема с доступностью порта
- 4. Включение GatewayPorts
- 5. Примеры команд для создания доступного туннеля
- 6. Дополнительные действия
- 7. Альтернативные методы использования socat
- Заключение
Вопрос или проблема
Ссылаясь на этот вопрос, я выполняю команду ниже через OpenSSH (Клиент: Mac OS X 10.6 | Сервер: Linux Mint), однако проксируемый порт не работает публично:
ssh -R 8080:localhost:80 -N [email protected]
- Цель состоит в том, чтобы локальный порт можно было открыть на удалённом компьютере
- Казалось бы, что удалённая сторона привязывается только к
localhost
, а не ко всем интерфейсам - Это работает, когда открываешь порт на
localhost
на удалённом компьютере, но при попытке доступа к публичному IP-адресу удалённого компьютера с моего локального компьютера, порт, похоже, не открыт
Как мне сделать туннель публичным для доступа к IP любому пользователю?
Если вы посмотрите страницы man для ssh, вы обнаружите, что синтаксис для -R
выглядит так:
-R [bind_address:]port:host:hostport
Когда bind_address
опущен (как в вашем примере), порт привязывается только к интерфейсу обратной связи. Для того чтобы привязать его ко всем интерфейсам, используйте
ssh -R \*:8080:localhost:80 -N [email protected]
или
ssh -R 0.0.0.0:8080:localhost:80 -N [email protected]
или
ssh -R "[::]:8080:localhost:80" -N [email protected]
Первая версия привязывает ко всем интерфейсам индивидуально. Вторая версия создаёт общую привязку только для IPv4, что означает, что порт доступен на всех интерфейсах через IPv4. Третья версия, вероятно, технически эквивалентна первой, но снова создаёт только одну привязку к ::
, что означает, что порт доступен через IPv6 и через IPv4 с помощью IPv4-отображаемых IPv6-адресов (не работает на Windows, OpenBSD). (Вам нужны кавычки, потому что [::]
иначе может быть интерпретировано как шаблон.)
Обратите внимание, что если вы используете сервер OpenSSH sshd
, то опция сервера GatewayPorts
должна быть включена (clientspecified
, или, в редких случаях, yes
) для того, чтобы это работало (проверьте файл /etc/ssh/sshd_config
на сервере). В противном случае (значение по умолчанию для этой опции – no
), сервер всегда будет заставлять порт быть привязанным только к интерфейсу обратной связи.
Редактировать:
-g
работает для локально перенаправленных портов, но то, что вам нужно, это обратный/удалённый перенаправленный порт, что отличается.
То, что вам нужно, это это.
По сути, на example.com
установите GatewayPorts=clientspecified
в /etc/ssh/sshd_config
.
— предыдущий (неправильный) ответ —
Используйте опцию -g. Из страницы man для ssh:
-g Позволяет удалённым хостам подключаться к локально перенаправленным портам.
Вот мой ответ для полноты:
Я в конечном итоге использовал ssh -R ...
для туннелирования и использовал socat
для перенаправления сетевого трафика на 127.0.0.1
:
туннель, привязанный к 127.0.0.1:
ssh -R mitm:9999:<my.ip>:8084 me@mitm
socat:
mitm$ socat TCP-LISTEN:9090,fork TCP:127.0.0.1:9999
Другой вариант – сделать туннель, работающий только локально, но я считаю это гораздо медленнее
mitm$ ssh -L<mitm.ip.address>:9090:localhost:9999 localhost
Вы также можете использовать двойное перенаправление, если не хотите или не можете изменить /etc/ssh/sshd_config.
Сначала перенаправьте на временный порт (например, 10080) на устройстве обратной связи на удалённом компьютере, затем используйте локальное перенаправление, чтобы перенаправить порт 10080 на 80 на всех интерфейсах:
ssh -A -R 10080:localhost_or_machine_from:80 [email protected] "ssh -g -N -L 80:localhost:10080 localhost"
Используйте опцию “gateway ports”.
ssh -g -R REMOTE_PORT:HOST:PORT ...
Чтобы использовать это, вам, возможно, нужно добавить “GatewayPorts yes
” в конфигурацию /etc/ssh/sshd_config
вашего сервера.
У меня недостаточно репутации, чтобы комментировать в соответствующих разделах, поэтому я добавляю новый ответ.
Предупреждение: если вы установите GatewayPorts
на yes
, это заставит sshd
привязывать ваши перенаправления к любому интерфейсу – независимо от конфигурации клиента (-R
и т.д.). Это может стать довольно серьёзной проблемой безопасности, если клиент предполагает, что она ограничила свои перенаправления, например, до localhost. Поэтому настройка GatewayPorts
на clientspecified
обычно то, что вам нужно.
Прыгающие хосты являются довольно недавним дополнением к OpenSSH. Это требует доступа SSH к промежуточному хосту, но должно работать без дополнительной конфигурации.
ssh -J [email protected] remoteuser@localhost -p 8080
Эта команда инструктирует SSH сначала подключиться к [email protected]
, а затем, с этого компьютера инициировать подключение к порту 8080 на localhost
(т.е. порт, который проксируется с хоста-переключателя на удалённый хост) под именем пользователя remoteuser
.
Если вы хотите сохранить конфигурацию в вашем ~/.ssh/config
вместо использования параметров командной строки, вы можете попробовать что-то вроде
Host REMOTE_HOST_NAME
RemoteForward \*:8080 127.0.0.1:80
Не забудьте настроить межсетевой экран вашего удалённого хоста, чтобы разрешить подключения к 8080 и убедитесь, что опция GatewayPorts
в вашей конфигурации /etc/ssh/sshd
не установлена на no
Как выполнить это туннелирование на Python?
Ответ или решение
Как сделать SSH-туннель общедоступным
Создание SSH-туннеля, доступного для общего использования, является распространенной задачей в администрировании серверов и облачных сервисов. В данной статье мы подробно рассмотрим, как правильно настроить SSH-туннель, чтобы он был доступен извне, используя примеры и важные моменты, на которые стоит обратить внимание.
1. Основы SSH-туннелирования
SSH-туннелирование позволяет безопасно передавать данные между локальной и удаленной машинами, шифруя их. Существует несколько типов туннелей: локальные, удаленные и динамические. В данном случае мы сосредоточимся на удаленном туннеле (reverse tunnel), который позволяет вам перенаправить порты с вашего локального компьютера на удаленный сервер.
2. Команда для создания удаленного туннеля
Для создания удаленного туннеля на сервере необходимо использовать команду ssh -R
. Вот основной синтаксис:
ssh -R <публичный_порт>:localhost:<локальный_порт> -N <пользователь>@<сервер>
Например, чтобы сделать локальный порт 80 общедоступным на удаленном сервере через порт 8080, можно использовать следующую команду:
ssh -R 8080:localhost:80 -N user@remote-server.com
3. Проблема с доступностью порта
По умолчанию, порт, перенаправленный с помощью -R
, будет слушать только на интерфейсе localhost
удаленного сервера. Это означает, что он недоступен извне. Чтобы решить эту проблему, необходимо использовать опцию GatewayPorts
.
4. Включение GatewayPorts
Чтобы ваши порты были доступны на всех интерфейсах удаленного сервера, откройте файл конфигурации SSH-сервера /etc/ssh/sshd_config
и измените настройку GatewayPorts
. Убедитесь, что она выглядит следующим образом:
GatewayPorts clientspecified
Вариант clientspecified
позволяет управлять этим параметром на стороне клиента, оставляя возможность ограничения доступа, а настройка yes
делает порты доступными на всех интерфейсах, что потенциально может быть небезопасным.
После внесения изменений не забудьте перезапустить SSH-сервер:
sudo systemctl restart sshd
5. Примеры команд для создания доступного туннеля
Теперь, когда GatewayPorts
настроен, измените вашу исходную команду для создания туннеля:
ssh -R *:8080:localhost:80 -N user@remote-server.com
Или:
ssh -R 0.0.0.0:8080:localhost:80 -N user@remote-server.com
Эти команды позволяют вашему SSH-туннелю слушать на всех интерфейсах удаленного сервера.
6. Дополнительные действия
-
Проверка Firewall: Убедитесь, что фаервол на удаленном сервере позволяет доступ к порту 8080. Вы можете использовать команду
ufw
для управления правилами фаервола:sudo ufw allow 8080
-
Проверка подключения: После настройки туннеля и фаервола проверьте, доступен ли порт извне, используя команды типа
curl
илиtelnet
:curl http://<публичный_IP>:8080
7. Альтернативные методы использования socat
Если вы хотите использовать более продвинутые методы перенаправления трафика, можно воспользоваться утилитой socat
. Например, вы можете запустить socat
на удаленном сервере для перенаправления трафика с порта 9999 на локальный порт 80:
socat TCP-LISTEN:9999,fork TCP:localhost:80
А затем установить удаленный SSH-туннель на тот же сервер:
ssh -R 9999:localhost:80 user@remote-server.com
Заключение
Следуя вышеописанным шагам, вы сможете правильно настроить SSH-туннель, который будет доступен на публичном IP адресе вашего удаленного сервера. Убедитесь в том, что вы соблюдаете весы безопасности, прежде чем открывать порты для доступа извне. Надеемся, данная инструкция была полезной и поможет вам в вашей работе с SSH и удаленными серверами.