Cara sederhana untuk membuat terowongan dari satu port lokal ke yang lain?


76

Saya memiliki server pengembangan, yang hanya dapat diakses dari 127.0.0.1:8000, bukan 192.168.1.x: 8000. Sebagai peretasan cepat, apakah ada cara untuk mengatur sesuatu untuk mendengarkan pada port lain (katakanlah, 8001) sehingga dari jaringan lokal saya dapat menghubungkan 192.168.1.x: 8001 dan itu akan menyalurkan lalu lintas antara klien dan 127.0 .0.1: 8000?


4
netcat dapat melakukan ini.
Andy

Jawaban:


44

Menggunakan ssh adalah solusi termudah.

ssh -g -L 8001: localhost: 8000 -f -N user@remote-server.com

Ini meneruskan port lokal 8001 pada workstation Anda ke alamat localhost pada port remote-server.com 8000.
-gberarti mengizinkan klien lain di jaringan saya untuk terhubung ke port 8001 pada workstation saya. Kalau tidak, hanya klien lokal di workstation Anda yang dapat terhubung ke port yang diteruskan.
-Nberarti semua yang saya lakukan adalah meneruskan port, jangan memulai shell.
-fberarti bercabang menjadi latar belakang setelah koneksi SSH berhasil dan masuk.
Port 8001 akan tetap terbuka untuk banyak koneksi, sampai ssh mati atau terbunuh. Jika Anda kebetulan menggunakan Windows, klien SSH Putty yang sangat baik dapat melakukan ini juga. Gunakan 8001 sebagai port lokal dan localhost: 8000 dan tujuan dan tambahkan penerusan port lokal di pengaturan. Anda dapat menambahkannya setelah berhasil terhubung dengan Putty.


4
Apa yang user@remote-server.comdilakukan? Ini jelas tidak diperlukan untuk penerusan port, namun ssh mengamanatkan argumen ini, terlebih lagi, ia mencoba untuk terhubung di sana. Dan setelah mengatur opsi sial ini untuk hostname itu output …port 22: Connection refused (tidak, saya tidak menggunakan port 22) . Kecuali saya kehilangan sesuatu, perintahnya jelas tidak akan berhasil.
Hi-Angel

@ Hi-Angel user@remote-server.comhanyalah sebuah contoh dan Anda tidak harus menerimanya secara harfiah. Anda harus mengganti ini dengan nama komputer yang ingin Anda sambungkan dan nama pengguna Anda di komputer ini. Informasi ini diperlukan untuk membuat koneksi ssh. Hanya setelah koneksi ssh terbentuk, port dapat diteruskan melalui koneksi ini.
Piotr Dobrogost

Jika Anda ingin port tersedia dari boot kemudian lihat "autossh" di layanan systemd menggunakan metode di atas - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Richard Hollis

Saya juga mendapatkan "koneksi ditolak". Dan saya masih tidak mengerti mengapa argumen user@remote-server.com diperlukan ketika tidak ada koneksi SSH yang terlibat (menurut -N). Haruskah hanya meneruskan paket.
Alexander Taylor

2
@AlexanderTaylor -Ntidak berarti tidak ada koneksi SSH. Itu hanya berarti do not execute a remote command(lihat halaman manual ). The <user>@<host>Argumen ini diperlukan, karena ini tidak membuka koneksi SSH ke <host>(yang untuk kasus OP akan localhost), dan meneruskan port yang diinginkan melalui bahwa SSH tunnel. Ini adalah salah satu solusi untuk masalah OP, tetapi bukan yang paling sederhana. Untuk meneruskan ke localhost tanpa menggunakan ssh, Anda dapat menggunakan socatatau netcatseperti di StephaneChazelas dan bukan jawaban pengguna

94

Dengan socatdi server:

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

Secara default, socatakan mendengarkan pada port TCP 8001 pada alamat IPv4 atau IPv6 (jika didukung) pada mesin. Anda dapat membatasi ke IPv4 / 6 dengan mengganti tcp-listendengan tcp4-listenatau tcp6-listen, atau ke alamat lokal tertentu dengan menambahkan a ,bind=that-address.

Sama dengan soket penghubung yang Anda gunakan untuk proxy, Anda dapat menggunakan alamat apa saja di tempat localhost, dan ganti tcpdengan tcp4atau tcp6jika Anda ingin membatasi resolusi alamat ke alamat IPv4 atau IPv6.

Perhatikan bahwa untuk server mendengarkan pada port 8000, koneksi akan muncul sebagai berasal dari proksi (dalam kasus localhost, yang akan terjadi localhost), bukan klien asli. Anda harus menggunakan pendekatan DNAT (tetapi yang membutuhkan hak superuser) agar server dapat mengetahui siapa kliennya.


1
Terima kasih, ini bagus karena Anda tidak harus menjalankan server ssh lokal.
jontro

Bisakah saya menggunakan port yang sama tetapi alamat yang berbeda?
Amos

@amos, lihat edit.
Stéphane Chazelas

Apakah mungkin untuk meneruskan traffic hanya dari IP tertentu?
Phate

1
@Phate, lihat Tell socat untuk mendengarkan koneksi dari satu alamat IP ( rangedan tcpwrapopsi di socathalaman manual).
Stéphane Chazelas

46

Menggunakan tradisional ncadalah solusi termudah:

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

Versi ini ncada dalam netcat-traditionalpaket di Ubuntu. (Anda harus update-alternativesatau menyebutnya nc.traditional.)

Perhatikan bahwa berbeda dengan ssh ini tidak dienkripsi. Ingatlah itu jika Anda menggunakannya di luar satu host.


2
ada yang tahu yang setara netcat-openbsd?
Sridhar Sarnobat

2
Analog untuk netcatversi yang termasuk dalam busybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( Deskripsi params )
Ivan Kolmychek

2
Bekerja, tetapi ncperintah berakhir setelah koneksi jarak jauh pertama. Tambahkan -kjika Anda harus tetap menjalankannya.
Sopalajo de Arrierez

Saya mendapatkan kesalahan ini: nc: cannot use -p and -lpada CentOS 6.4. Apakah ada pekerjaan?
Nick Predey

Saya lebih suka solusi ini daripada ssh karena membuatnya lebih mudah untuk digunakan sebagai root, ketika seseorang perlu secara lokal meneruskan port istimewa.
Christian

24

OpenBSD netcat tersedia secara default di Linux dan juga pada 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

Alternatif yang bekerja pada OS X bash adalah menggunakan pipa dua arah . Ini dapat bekerja pada Unix lain:

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

Pada awalnya saya tidak memperhatikan bahwa Anda menggunakan netbat openbsd. Ini lebih baik daripada harus menginstal netcat lain dari paket Ubuntu.
RobertR

Contoh OpenBSD gagal pada Ubuntu 15.04. Dengan pengalihan shell, netcat gagal membuka port untuk mendengarkan seperti yang dilihat oleh ss -tanatau netstat -tan.
Justin C

⁺¹. FTR: cara alternatif bekerja di Ubuntu
Hi-Angel

Saya tidak mengerti solusi Anda. Bisakah Anda menjelaskannya?
Trismegistos

@trismegistos Dalam contoh ini pendengar netcat dan klien mengarahkan ulang input ke beberapa file bersama (mkfifo pipes..first in first out), dan menggunakan file-file yang dibagikan tersebut sebagai sumber / tujuan input / output, secara efektif membuat terowongan. Biasanya klien / pendengar digunakan, tetapi beberapa teknik menggunakan klien + klien / pendengar + pendengar- wiki.securityweekly.com/... dan slideshare.net/amiable_indian/secrets-of-top-pentesters harus dibaca.
Info5ek

4

Mengutip jawaban David Spillett di ServerFault

rinetd harus melakukan pekerjaannya, dan sebuah binary Windows untuk itu dapat diperoleh dari http://www.boutell.com/rinetd/ (bagi siapa pun yang mencari hal yang sama di Linux, rinetd berada dalam repositori standar hampir di setiap distro jadi dapat diinstal dengan "apt-get install rinetd" atau "yum install rinetd" atau serupa)

Ini adalah biner sederhana yang mengambil file konfigurasi dalam format

bindaddress bindport connectaddress connectport

Sebagai contoh:

192.168.1.1 8001 127.0.0.1 8000

atau

0.0.0.0 8001 127.0.0.1 8000

jika Anda ingin mengikat port yang masuk ke semua antarmuka.


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

service iptables save
service iptables restart

Setelah mencoba terhubung ke dport, seperti pada nc -v localhost 2345, saya mengerti Connection refused. Saya tidak terlalu bagus dalam iptables, tapi saya kira dport harus memiliki aplikasi mendengarkan.
Hi-Angel

Bagaimana jika port asal berada pada antarmuka yang berbeda dari port tujuan?
Trismegistos

0

Berdasarkan jawaban Mark A. , saya harus membuat sedikit penyesuaian untuk membuatnya berfungsi untuk Mac saya (setidaknya pada macOS Mojave Versi 10.14.4)

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

Pernyataan printf itu tampaknya sangat penting. Kalau tidak, perintah netcat untuk terhubung ke port 8000 tidak akan pernah benar-benar mencoba untuk terhubung, dan perintah netcat untuk mendengarkan pada port 8001 tidak akan pernah benar-benar mendengarkan pada port 8001. Tanpa printf, setiap kali saya akan mencoba untuk terhubung ke port 8001 saya akan mendapatkan koneksi ditolak.

Asumsi saya adalah bahwa netcat entah bagaimana harus memblokir stdin (mungkin ia mencoba membacanya untuk beberapa alasan) sebelum benar-benar melakukan operasi Socket. Dengan demikian, tanpa pernyataan printf menulis ke fifo a, perintah netcat tidak akan pernah mulai mendengarkan pada port 8001.

Catatan: Saya akan meninggalkan jawaban pada posting Markus, tetapi saya belum memiliki reputasi.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.