Cách đơn giản để tạo một đường hầm từ một cổng địa phương đến một cổng khác?


76

Tôi có một máy chủ phát triển, chỉ có thể truy cập từ 127.0.0.1:8000, không phải 192.168.1.x: 8000. Là một cách nhanh chóng, có một cách để thiết lập một cái gì đó để nghe trên một cổng khác (giả sử, 8001) để từ mạng cục bộ tôi có thể kết nối 192.168.1.x: 8001 và nó sẽ tạo đường hầm lưu lượng giữa máy khách và 127.0 .0.1: 8000?


4
netcat có thể làm điều này.
Andy

Câu trả lời:


44

Sử dụng ssh là giải pháp dễ nhất.

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

Điều này chuyển tiếp cổng cục bộ 8001 trên máy trạm của bạn sang địa chỉ localhost trên cổng remote-server.com 8000.
-gcó nghĩa là cho phép các máy khách khác trên mạng của tôi kết nối với cổng 8001 trên máy trạm của tôi. Mặt khác, chỉ các máy khách cục bộ trên máy trạm của bạn có thể kết nối với cổng được chuyển tiếp.
-Ncó nghĩa là tất cả những gì tôi đang làm là chuyển tiếp cổng, không khởi động shell.
-fnghĩa là rẽ nhánh vào nền sau khi kết nối và đăng nhập SSH thành công.
Cổng 8001 sẽ mở cho nhiều kết nối, cho đến khi ssh chết hoặc bị giết. Nếu bạn tình cờ có mặt trên Windows, ứng dụng khách SSH tuyệt vời PuTTY cũng có thể làm điều này. Sử dụng 8001 làm cổng cục bộ và localhost: 8000 và đích và thêm chuyển tiếp cổng cục bộ trong cài đặt. Bạn có thể thêm nó sau khi kết nối thành công với PuTTY.


4
Làm gì user@remote-server.com? Điều này chắc chắn không cần thiết cho việc chuyển tiếp cổng, tuy nhiên ssh bắt buộc phải có đối số này, hơn nữa, nó cố gắng kết nối ở đó. Và khi đặt tùy chọn phiền phức này thành tên máy chủ, nó sẽ xuất ra …port 22: Connection refused (không, tôi đã không sử dụng cổng 22) . Trừ khi tôi thiếu một cái gì đó, lệnh sẽ không hoạt động.
Hi-Angel

@ Hi-Angel user@remote-server.comchỉ là một ví dụ và bạn không nên hiểu theo nghĩa đen. Bạn phải thay thế tên này bằng tên máy tính bạn muốn kết nối và tên người dùng của bạn trên máy tính này. Thông tin này là cần thiết để thiết lập kết nối ssh. Chỉ sau khi kết nối ssh được thiết lập, các cổng mới có thể được chuyển tiếp qua kết nối này.
Piotr Dobrogost

Nếu bạn muốn các cổng để được cung cấp từ khởi động sau đó xem "autossh" trong một dịch vụ systemd sử dụng các phương pháp trên - everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
Richard Hollis

Tôi cũng nhận được "kết nối từ chối". Và tôi vẫn không hiểu tại sao cần phải có đối số user@remote-server.com khi không có kết nối SSH liên quan (theo -N). Chỉ nên chuyển tiếp gói.
Alexander Taylor

2
@AlexanderTaylor -Nkhông có nghĩa là không có kết nối SSH. Nó đơn giản có nghĩa là do not execute a remote command(xem trang người đàn ông ). Đối <user>@<host>số là cần thiết, bởi vì điều này sẽ mở một kết nối SSH tới <host>(đối với trường hợp của OP sẽ là localhost) và chuyển tiếp cổng mong muốn thông qua đường hầm SSH đó. Đây là một giải pháp cho vấn đề của OP, nhưng không đơn giản nhất. Để chuyển tiếp đến localhost mà không cần sử dụng ssh, bạn có thể sử dụng socathoặc netcatnhư trong StephaneChazelas và câu trả lời không dành cho người dùng

94

Với socattrên máy chủ:

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

Theo mặc định, socatsẽ lắng nghe trên cổng TCP 8001 trên bất kỳ địa chỉ IPv4 hoặc IPv6 (nếu được hỗ trợ) trên máy. Bạn có thể giới hạn nó ở IPv4 / 6 bằng cách thay thế tcp-listenbằng tcp4-listenhoặc tcp6-listenhoặc đến một địa chỉ cụ thể bằng cách thêm một ,bind=that-address.

Tương tự đối với ổ cắm kết nối mà bạn đang ủy quyền, bạn có thể sử dụng bất kỳ địa chỉ nào localhostthay thế và thay thế tcpbằng tcp4hoặc tcp6nếu bạn muốn hạn chế độ phân giải địa chỉ đối với địa chỉ IPv4 hoặc IPv6.

Lưu ý rằng đối với máy chủ lắng nghe trên cổng 8000, kết nối sẽ xuất hiện như đến từ proxy (trong trường hợp localhostđó là localhost), không phải máy khách gốc. Bạn cần sử dụng các phương pháp tiếp cận DNAT (nhưng yêu cầu đặc quyền siêu người dùng) để máy chủ có thể cho biết ai là khách hàng.


1
Cảm ơn, điều này thật tuyệt vì bạn không cần phải có máy chủ ssh cục bộ đang chạy.
jontro

Tôi có thể sử dụng cùng một cổng nhưng địa chỉ khác nhau không?
A-mốt

@amos, xem chỉnh sửa.
Stéphane Chazelas

Nó cũng có thể chỉ chuyển tiếp lưu lượng truy cập từ các IP cụ thể?
Phate

1
@Phate, xem Tell socat để nghe các kết nối từ một địa chỉ IP duy nhất (và các tùy chọn rangetcpwraptrong socattrang man).
Stéphane Chazelas

46

Sử dụng truyền thống nclà giải pháp dễ nhất:

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

Phiên bản ncnày nằm trong netcat-traditionalgói trên Ubuntu. (Bạn phải update-alternativeshoặc gọi nó nc.traditional.)

Lưu ý rằng trái ngược với ssh, điều này không được mã hóa. Hãy ghi nhớ điều đó nếu bạn sử dụng nó bên ngoài một máy chủ.


2
có ai biết tương đương netcat-openbsdkhông?
Sridhar Sarnobat

2
Analog cho netcatphiên bản được bao gồm trong busybox: nc -v -lk -p 8001 -e /usr/bin/nc 127.0.0.1 8000. ( Mô tả các thông số )
Ivan Kolmychek 16/03/18

2
Làm việc, nhưng nclệnh kết thúc sau kết nối từ xa đầu tiên. Thêm -knếu bạn cần giữ cho nó chạy.
Sopalajo de Arrierez

Tôi đang gặp lỗi này: nc: cannot use -p and -ltrên CentOS 6.4. Có một công việc xung quanh?
Nick Predey

Tôi thích giải pháp này hơn ssh một vì nó giúp sử dụng như root dễ dàng hơn, khi người ta cần chuyển tiếp cục bộ một cổng đặc quyền.
Christian

24

OpenBSD netcat có sẵn theo mặc định trên Linux và cả trên 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

Một thay thế hoạt động trên bash OS X là sử dụng ống hai chiều . Nó có thể hoạt động trên các Unix khác:

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

Lúc đầu tôi không để ý rằng bạn đang sử dụng netcat openbsd. Điều này tốt hơn là phải cài đặt một netcat khác từ gói Ubuntu.
RobertR

Ví dụ OpenBSD không thành công trên Ubuntu 15.04. Với các chuyển hướng shell, netcat không thể mở cổng để nghe khi nhìn thấy ss -tanhoặc netstat -tan.
Justin C

⁺¹. FTR: cách khác hoạt động trên Ubuntu
Hi-Angel

Tôi không hiểu giải pháp của bạn. Bạn có thể giải thích nó được không?
Trismegistos

@trismegistos Trong các ví dụ này, trình nghe netcat và máy khách chuyển hướng đầu vào vào một số tệp được chia sẻ (mkfifo pipe..first in First out) và sử dụng các tệp được chia sẻ này làm nguồn / đích của đầu vào / đầu ra, tạo hiệu quả đường hầm. Thông thường khách hàng / người nghe được sử dụng, nhưng một số kỹ thuật sử dụng của khách hàng + khách hàng / người nghe + listener- wiki.securityweekly.com/... slideshare.net/amiable_indian/secrets-of-top-pentesters là phải đọc.
Info5ek

4

Trích dẫn câu trả lời của David Spillett trên ServerFault

rinetd nên thực hiện công việc và có thể có tệp nhị phân Windows từ http://www.boutell.com/rinetd/ (đối với bất kỳ ai đang tìm kiếm điều tương tự trong Linux, rinetd nằm trong kho lưu trữ tiêu chuẩn của mọi phân phối vì vậy có thể được cài đặt với "apt-get install rinetd" hoặc "yum install rinetd" hoặc tương tự)

Nó là một nhị phân đơn giản có một tệp cấu hình ở định dạng

bindaddress bindport connectaddress connectport

Ví dụ:

192.168.1.1 8001 127.0.0.1 8000

hoặc là

0.0.0.0 8001 127.0.0.1 8000

nếu bạn muốn liên kết cổng đến với tất cả các giao diện.


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

service iptables save
service iptables restart

Khi cố gắng kết nối dport, như trong nc -v localhost 2345, tôi nhận được Connection refused. Tôi không giỏi về iptables, nhưng tôi đoán rằng dport phải có ứng dụng nghe.
Hi-Angel

Điều gì xảy ra nếu cổng gốc nằm trên giao diện khác với cổng đích?
Trismegistos

0

Dựa trên câu trả lời của Mark A. , tôi đã phải thực hiện một tinh chỉnh nhỏ để làm cho nó hoạt động cho máy Mac của tôi (ít nhất là trên macOS Mojave Phiên bản 10.14.4)

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

Đó là tuyên bố printf có vẻ rất quan trọng. Nếu không, lệnh netcat để kết nối với cổng 8000 sẽ không bao giờ thực sự cố gắng kết nối và lệnh netcat để nghe trên cổng 8001 sẽ không bao giờ thực sự nghe trên cổng 8001. Nếu không có printf, mỗi khi tôi cố gắng kết nối với cổng 8001 tôi sẽ nhận được kết nối từ chối.

Giả định của tôi là netcat bằng cách nào đó phải chặn stdin (có thể nó đang cố đọc nó vì lý do nào đó) trước khi thực sự thực hiện bất kỳ hoạt động nào của Socket. Như vậy, nếu không có câu lệnh printf ghi đến fifo a, lệnh netcat sẽ không bao giờ bắt đầu nghe trên cổng 8001.

Lưu ý: Tôi đã để lại câu trả lời trên bài đăng của Mark, nhưng tôi chưa có danh tiếng.


0

Đây là một cách mới để tạo đường hầm hai cổng udp trên máy chủ: https://github.com/9crk/udpeer

udpeer 8001 8002

Để kiểm tra:

nc -u xxxx.com 8001
nc -u xxxx.com 8002
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.