Как сделать ssh туннель открытым для общественности?

174

Ну, возвращаясь к этому вопросу, я запускаю команду

ssh -R 8080:localhost:80 -N root@example.com

на Mac. Тем не менее, порт, который туннелируется, не работает публично. Я запускаю такую ​​команду, чтобы сделать так, чтобы локальный порт можно было открыть на удаленном компьютере. И он работает при открытии порта на локальном хосте на удаленном компьютере, но когда я пытаюсь получить доступ к общедоступному IP-адресу удаленного компьютера с моего локального компьютера, порт не открывается. Как бы я сделал общедоступный туннель на IP для любого доступа?

РЕДАКТИРОВАТЬ: Кажется, что удаленная сторона привязывается только на локальном хосте, а не ко всем интерфейсам.

РЕДАКТИРОВАТЬ 2: клиент Mac OS X 10.6 и сервер Linux Mint, но оба они OpenSSH.

Тревор Рудольф
источник
Что означает публичный IP? Если вы пытаетесь подключиться к локальному компьютеру через маршрутизатор и через Интернет, большинство маршрутизаторов не допустят такой обратной связи.
harrymc

Ответы:

351

Если вы проверите справочную страницу для ssh, вы обнаружите, что синтаксис для -Rчтения:

-R [ bind_address :] порт : хост : хост

Когда bind_addressопущен (как в вашем примере), порт привязан только к интерфейсу обратной связи. Чтобы связать его со всеми интерфейсами, используйте

ssh -R \*:8080:localhost:80 -N root@example.com

или же

ssh -R 0.0.0.0:8080:localhost:80 -N root@example.com

или же

ssh -R "[::]:8080:localhost:80" -N root@example.com

Первая версия привязывается ко всем интерфейсам индивидуально. Вторая версия создает общую привязку только для IPv4, что означает, что порт доступен на всех интерфейсах через IPv4. Третья версия, вероятно, технически эквивалентна первой, но, опять же, она создает только одну привязку ::, что означает, что порт доступен через IPv6 изначально и через IPv4 через IPv4-сопоставленные адреса IPv6 (не работает в Windows, OpenBSD) , (Вам нужны кавычки, потому [::]что в противном случае можно было бы интерпретировать как глобус.)

Обратите внимание, что если вы используете sshdсервер OpenSSH , GatewayPortsнеобходимо включить опцию сервера (установить на yesили clientspecified), чтобы это работало (проверьте файл /etc/ssh/sshd_configна сервере). В противном случае (значение по умолчанию для этой опции - no), сервер всегда будет принудительно привязывать порт только к интерфейсу обратной связи.

Стефан Зайдель
источник
12
О Боже мой, он работал !!!!! Я сделал именно это 1 миллион раз! Я просто забыл, что *в bash будут выдавать файлы и мне это нужно\*
Тревор Рудольф
4
Да, именно поэтому я всегда предпочитаю 0.0.0.0- это только IPv4, но это будет происходить большую часть времени :)
Stefan Seidel
34
GatewayPorts да решил мою проблему.
Sunry
4
GatewayPorts = yes (в удаленном конфиге sshd) исправил это и для меня
Phil_1984_
3
«GatewayPorts yes» сделал мой день, спасибо @StefanSeidel
karser
37

Редактировать:

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

То, что вы хотите, это .

По сути, на example.com, установить GatewayPorts=clientspecifiedв /etc/ssh/sshd_config.

--- предыдущий (неправильный) ответ ---

Используйте опцию -g. Со страницы руководства ssh:

-g     Allows remote hosts to connect to local forwarded ports.
snapshoe
источник
кажется, не работает ... он запускается, но я не могу подключиться удаленно
Тревор Рудольф
2
Попробуйте запустить netstat -elnptиз отдельного tty, чтобы выяснить, какие порты связаны с каким адресом. Без -g, порт должен быть привязан к 127.0.0.1:PORT. С -g, он должен быть связан 0.0.0.0:PORT, что делает его доступным удаленно.
Snapshoe
pastebin.com/q6f4kJyd
Тревор Рудольф
2
GatewayPorts=clientspecifiedилиGatewayPorts clientspecified
Тревор Рудольф
и я добавляю это к клиенту или удаленному?
Тревор Рудольф
14

Вот мой ответ для завершения:

В конечном итоге я использовал ssh -R ...для туннелирования, а также socatдля перенаправления сетевого трафика на 127.0.0.1:

туннель привязан к 127.0.0.1: ssh -R mitm:9999:<my.ip>:8084 me@mitm

Сокат: mitm$ socat TCP-LISTEN:9090,fork TCP:127.0.0.1:9999

Другой вариант - создать локальный туннель, но я нахожу это намного медленнее.

mitm$ ssh -L<mitm.ip.address>:9090:localhost:9999 localhost

Мигель Пинг
источник
Мне нравится тот факт, что мне не нужно иметь дело с конфигурацией sshd и что я могу делать все это без sudo. Плюс я узнаю, что сокат существует. Спасибо!
BrutusCat
+ Вы идете хорошо, сэр. Я попытался сказать ssh, чтобы он связывался с 0.0.0.0 безуспешно .. Затем увидел синтаксис *, попробовал это, без игры в кости. Я предполагаю, что это может быть какая-то функция безопасности в конфигурации sshd или что-то, что не позволяет этого. Наконец увидел этот пост и socatработал потрясающе. Супер полезно, положив это в мой задний карман;]
Хайме
10

Вы также можете использовать двойную переадресацию, если вы не хотите или можете изменить / etc / ssh / sshd_config.

Сначала перенаправьте на временный порт (например, 10080) на устройстве обратной связи на удаленном компьютере, затем используйте локальную переадресацию туда, чтобы перенаправить порт 10080 на 80 на всех интерфейсах:

ssh -A -R 10080:localhost_or_machine_from:80 user@remote.tld "ssh -g -N -L 80:localhost:10080 localhost"
panticz.de
источник
1
Это на самом деле работает, чтобы обойти правила пересылки!
Михаэль Шуберт
Люблю это решение. Большой обходной путь , когда вы не хотите изменять настройки на машине
Grezzo
8

Используйте опцию «порты шлюза».

ssh -g -R REMOTE_PORT:HOST:PORT ...

Чтобы использовать это, вам, вероятно, нужно добавить " GatewayPorts yes" к вашему серверу /etc/ssh/sshd_config.

Рауль Салинас-Монтеагудо
источник
На самом деле это сработало. Я использую экземпляр EC2 в качестве сервера пересылки для моего REST-сервера. Таким образом, мне не нужно вставлять свой сервер в DMZ, и мне не нужен публичный IP. Как ни странно, с первым созданным мной экземпляром EC2 ssh -R remote_port: localhost: port xxx @ ec2xxx работал просто отлично, но потом мне пришлось по какой-то причине позже создать другой экземпляр, и с этого момента я всегда получал: соединение отказался. Использовал tcpdump, чтобы посмотреть, что я получаю, и там было мало информации. -g плюс GatewayPorts да сделали свое дело.
ET
1

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

ssh -J root@example.com remoteuser@localhost -p 8080

Эта команда инструктирует SSH сначала подключиться root@example.com, а затем с этого компьютера инициировать подключение к порту 8080 в localhost(т. Е. К порту, который туннелируется от промежуточного хоста к удаленному хосту) под remoteuserименем пользователя.

krlmlr
источник
0

Если вы хотите поместить конфигурацию в вас, ~/.ssh/configа не использовать параметры командной строки, вы можете попробовать что-то вроде

Host REMOTE_HOST_NAME RemoteForward \*:8080 127.0.0.1:80

Помните, что брандмауэр удаленного хоста разрешает подключения к 8080 и гарантирует, что для GatewayPortsпараметра вашей /etc/ssh/sshdконфигурации не установлено значениеno

Брэд Мостерт
источник