Простий спосіб створити тунель від одного локального порту до іншого?


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: localhost: 8000 -f -N user@remote-server.com

Це пересилає локальний порт 8001 на вашій робочій станції до адреси localhost на порту віддаленого сервера 8000.
-gозначає, що дозволяють іншим клієнтам у моїй мережі підключатися до порту 8001 на моїй робочій станції. Інакше лише локальні клієнти на вашій робочій станції можуть підключитися до переадресованого порту.
-Nозначає, що все, що я роблю, - це переадресація портів, не запускайте оболонку.
-fозначає розщеплення у фоновий режим після успішного підключення SSH та входу.
Порт 8001 залишатиметься відкритим для багатьох з'єднань, поки ssh не помре або не буде вбито. Якщо у вас є Windows, відмінний SSH-клієнт PuTTY може це зробити також. Використовуйте 8001 як локальний порт і localhost: 8000 та місце призначення та додайте переадресацію локального порту в налаштуваннях. Ви можете додати його після успішного з'єднання з PuTTY.


4
Що робить user@remote-server.com? Це, безумовно, непотрібне для переадресації портів, однак ssh мандати, маючи цей аргумент, більше, він намагається підключитися там. І встановивши цю прискіпливу опцію для імені хоста, вона виводить …port 22: Connection refused (ні, я не використовував 22 порт) . Якщо я щось не пропускаю, команда просто не працює.
Привіт-Ангел

@ Hi-Angel user@remote-server.com- це лише приклад, і ти не повинен сприймати це буквально. Ви повинні замінити це ім'ям комп'ютера, до якого ви хочете підключитися, та своїм ім'ям користувача на цьому комп’ютері. Ця інформація потрібна для встановлення ssh-зв’язку. Тільки після того, як встановлено ssh-з'єднання, порти можуть бути переслані через це з'єднання.
Пьотр Доброгост

Якщо ви хочете, щоб порт був доступний під час завантаження, перегляньте "autossh" в системній службі, використовуючи описаний вище метод - 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, або до конкретного локальномуадресою, додавши ,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сторінці "man").
Стефан Шазелас

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якщо вам потрібно продовжувати працювати.
Sopalajo de Arrierez

Я отримую цю помилку: nc: cannot use -p and -lна CentOS 6.4. Чи є робота навколо?
Nick Predey

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

24

OpenBSD 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, є використання двоспрямованої труби . Він може працювати на інших 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..перше), і використовують ті спільні файли як їх джерело / призначення вводу / виводу, ефективно створюючи тунель. Зазвичай клієнт / слухач використовується, але деякі методи використовують клієнт + клієнт / слухач + слухач - wiki.securityweekly.com/… і слід прочитати слайдша.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, але я думаю, що в депорті має бути програма для прослуховування.
Привіт-Ангел

Що робити, якщо вихідний порт знаходиться на іншому інтерфейсі, ніж порт призначення?
Трисмегістос

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 повинен якось блокуватися на stdin (можливо, він намагається прочитати його чомусь), перш ніж робити фактично будь-які операції Socket. Таким чином, без запису printf, записаного на fifo a, команда netcat ніколи не почне слухати на порт 8001.

Примітка. Я б залишив відповідь на пошті Марка, але репутації у мене поки немає.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.