Простой способ создать туннель от одного локального порта к другому?


76

У меня есть сервер разработки, который доступен только с 127.0.0.1:8000, а не с 192.168.1.x: 8000. Как быстрый взлом, есть ли способ настроить что-то для прослушивания на другом порту (скажем, 8001), чтобы из локальной сети я мог подключить 192.168.1.x: 8001, и это туннелирует трафик между клиентом и 127.0 .0.1: 8000?


4
Netcat может сделать это.
Энди

Ответы:


44

Использование ssh - самое простое решение.

ssh -g -L 8001: локальный хост: 8000 -f -N user@remote-server.com

Это перенаправляет локальный порт 8001 на вашей рабочей станции на адрес localhost на порту 8000 remote-server.com. Это
-gозначает, что другие клиенты в моей сети могут подключаться к порту 8001 на моей рабочей станции. В противном случае только локальные клиенты на вашей рабочей станции могут подключаться к перенаправленному порту.
-Nозначает, что все, что я делаю, это переадресация портов, а не запуск оболочки.
-fозначает переход в фоновый режим после успешного подключения SSH и входа в систему.
Порт 8001 будет оставаться открытым для многих соединений, пока ssh не умрет или не будет убит. Если вы оказались в Windows, превосходный SSH-клиент PuTTY также может это сделать. Используйте 8001 в качестве локального порта и localhost: 8000 и пункт назначения и добавьте переадресацию локального порта в настройках. Вы можете добавить его после успешного соединения с PuTTY.


4
Что делает user@remote-server.com? Это определенно не нужно для переадресации портов, однако ssh требует этого аргумента, более того, он пытается подключиться туда. И после установки этой надоедливой опции на hostname он выводит …port 22: Connection refused (нет, я не использовал 22 порт) . Если я что-то упустил, команда явно не работает.
Привет-ангел

@ Привет, Ангел, user@remote-server.comэто всего лишь пример, и не стоит воспринимать это буквально. Вы должны заменить его именем компьютера, к которому хотите подключиться, и своим именем пользователя на этом компьютере. Эта информация необходима для установки ssh-соединения. Только после установления ssh-соединения порты могут быть перенаправлены через это соединение.
Петр Доброгост

Если вы хотите, чтобы порт был доступен при загрузке, посмотрите «autossh» в сервисе systemd, используя вышеуказанный метод - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Ричард Холлис,

Я также получаю "соединение отказано". И я до сих пор не понимаю, зачем нужен аргумент user@remote-server.com, когда не используется SSH-соединение (согласно -N). Нужно просто пересылать пакеты.
Александр Тейлор

2
@AlexanderTaylor -Nне означает, что нет SSH-соединения. Это просто означает do not execute a remote command(см. Справочную страницу ). <user>@<host>Аргумент необходимо, потому что это делает открыть соединение SSH к <host>(который для случая ФП был бы localhost), и передает требуемый порт через этот туннель SSH. Это одно из решений проблемы ОП, но не самое простое. Чтобы переслать на localhost без использования ssh, вы можете использовать socatили netcatкак в StephaneChazelas и не-пользовательские ответы

94

С socatна сервере:

socat tcp-listen:8001,reuseaddr,fork tcp:localhost:8000

По умолчанию socatбудет прослушивать TCP-порт 8001 на любом IPv4 или IPv6-адресе (если поддерживается) на машине. Вы можете ограничить его IPv4 / 6, заменив tcp-listenна tcp4-listenили tcp6-listen, или указав локальный адрес, добавив a ,bind=that-address.

То же самое для соединительного сокета, к которому вы используете прокси, вы можете использовать любой адрес вместо localhostи заменить tcpна tcp4или, tcp6если вы хотите ограничить разрешение адресов адресами IPv4 или IPv6.

Обратите внимание, что для сервера, прослушивающего порт 8000, соединение будет выглядеть как исходящее от прокси-сервера (в случае localhost, если оно будет localhost), а не от исходного клиента. Вам нужно будет использовать подходы DNAT (но требующие привилегий суперпользователя), чтобы сервер мог определить, кто является клиентом.


1
Спасибо, это здорово, так как вам не нужно запускать локальный ssh-сервер.
Jontro

Могу ли я использовать один и тот же порт, но другой адрес?
Амос

@amos, см. редактировать.
Стефан

Можно ли будет также перенаправлять трафик только с определенных IP-адресов?
Фейт

1
@Phate, см. Скажите socat прослушивать соединения с одного IP-адреса (а также опции rangeи tcpwrapна socatстранице руководства ).
Стефан Шазелас

46

Использование традиционного nc- самое простое решение:

nc -l -p 8001 -c "nc 127.0.0.1 8000"

Эта версия ncнаходится в netcat-traditionalпакете на Ubuntu. (Вы должны update-alternativesили позвоните nc.traditional.)

Обратите внимание, что в отличие от ssh это не зашифровано. Имейте это в виду, если вы используете его за пределами одного хоста.


2
кто-нибудь знает эквивалент netcat-openbsd?
Шридхар Сарнобат

2
Аналого для netcatверсии , которая входит в busybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( Описание параметров )
Иван Колмычек

2
Работает, но ncкоманда заканчивается после первого удаленного подключения. Добавьте, -kесли вам нужно, чтобы он работал.
Сопалахо де Арриерес

Я получаю эту ошибку: nc: cannot use -p and -lна CentOS 6.4. Есть ли работа вокруг?
Ник Преди,

Я предпочитаю это решение по сравнению с ssh, потому что оно упрощает использование в качестве пользователя root, когда нужно локально перенаправить привилегированный порт.
Кристиан

24

NetBSD Netcat доступен по умолчанию в Linux, а также в OS X.

OSX:

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &

Linux:

mkfifo backpipe
nc -l 12345 0<backpipe | nc www.google.com 80 1>backpipe

Альтернатива, которая работает на OS X Bash, - это использовать двунаправленный канал . Может работать на других Unixes:

nc 127.0.0.1 8000 <&1 | nc -l 8001 >&0

Сначала я не заметил, что вы используете openbsd netcat. Это лучше, чем устанавливать другой netcat из пакета Ubuntu.
RobertR

Пример OpenBSD не удалось в Ubuntu 15.04. При перенаправлении оболочки netcat не может открыть порт для прослушивания, как видно ss -tanили netstat -tan.
Джастин C

⁺¹. FTR: альтернативный способ работает на Ubuntu
Hi-Angel

Я не понимаю вашего решения. Вы можете это объяснить?
Трисмегистос

@trismegistos В этих примерах слушатель netcat и клиент перенаправляют ввод в некоторые общие файлы (mkfifo pipe..first in first out) и используют эти общие файлы в качестве источника / назначения ввода / вывода, эффективно создавая туннель. Обычно используются клиент / слушатель, но некоторые методы используют клиент + клиент / слушатель + слушатель - wiki.securityweekly.com/… и slideshare.net/amiable_indian/secrets-of-top-pentesters должны быть прочитаны.
Info5ek

4

Процитировать Дэвида Spillett «сек ответ на ServerFault

rinetd должен выполнить эту работу, и бинарный файл Windows для него можно получить по адресу http://www.boutell.com/rinetd/ (для тех, кто ищет то же самое в Linux, rinetd находится в стандартных репозиториях практически всех дистрибутивов). поэтому можно установить с помощью «apt-get install rinetd» или «yum install rinetd» или аналогичных)

Это простой двоичный файл, который принимает файл конфигурации в формате

bindaddress bindport connectaddress connectport

Например:

192.168.1.1 8001 127.0.0.1 8000

или же

0.0.0.0 8001 127.0.0.1 8000

если вы хотите привязать входящий порт ко всем интерфейсам.


3
iptables -t nat -A PREROUTING -p tcp --dport <origin-port> -j REDIRECT --to-port <destination-port>

service iptables save
service iptables restart

При попытке подключиться dport, как в nc -v localhost 2345, я получаю Connection refused. Я не очень хорош в iptables, но, думаю, у dport должно быть приложение для прослушивания.
Привет-ангел

Что если origin-port находится на другом интерфейсе, чем порт назначения?
Трисмегистос

0

Основываясь на ответе Марка А. , мне пришлось сделать небольшую настройку, чтобы заставить его работать на моем Mac (по крайней мере, на MacOS Mojave версии 10.14.4)

mkfifo a
mkfifo b
nc 127.0.0.1 8000 < b > a &
nc -l 8001 < a > b &
printf "" > a

Это заявление printf кажется решающим. В противном случае команда netcat для подключения к порту 8000 фактически никогда не попытается подключиться, а команда netcat для прослушивания порта 8001 никогда не будет прослушивать порт 8001. Без printf каждый раз, когда я пытаюсь подключиться к порту 8001, я получаю В соединении отказано.

Я предполагаю, что netcat должен каким-то образом блокировать стандартный ввод (может быть, он пытается прочитать его по какой-то причине) перед выполнением каких-либо операций с сокетом. Таким образом, без записи оператора printf в fifo a команда netcat никогда не начнет прослушивать порт 8001.

Примечание: я бы оставил ответ на пост Марка, но у меня пока нет репутации.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.