创建从一个本地端口到另一本地端口的隧道的简单方法?


76

我有一个开发服务器,只能从127.0.0.1:8000而不是192.168.1.x:8000进行访问。作为一个快速的技巧,有没有一种方法可以设置一些内容以监听另一个端口(例如8001),以便从本地网络连接192.168.1.x:8001,它将在客户端和127.0之间建立隧道通信。 .0.1:8000?


4
netcat可以做到这一点。
安迪(Andy)

Answers:


44

使用ssh是最简单的解决方案。

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

这会将您工作站上的本地端口8001转发到remote-server.com端口8000上的本地主机地址。这
-g意味着允许网络上的其他客户端连接到工作站上的端口8001。否则,只有工作站上的本地客户端可以连接到转发的端口。
-N意味着我要做的就是转发端口,不要启动shell。
-f表示成功建立SSH连接并登录后进入后台。
端口8001将为许多连接保持打开状态,直到ssh死亡或被杀死。如果您碰巧在Windows上,出色的SSH客户端PuTTY也可以做到这一点。使用8001作为本地端口,使用localhost:8000和目标,并在设置中添加本地端口转发。与PuTTY成功连接后,可以添加它。


4
怎么user@remote-server.com办?绝对不需要端口转发,但是ssh要求使用此参数,而且还要尝试在此处进行连接。并将此讨厌的选项设置为主机名后,它会输出…port 22: Connection refused (不,我没有使用22端口)。除非我丢失了某些内容,否则该命令显然是行不通的。
Hi-Angel

@ Hi-Angel user@remote-server.com只是一个示例,您不应从字面上理解它。您必须用要连接的计算机名称和此计算机上的用户名替换它。建立ssh连接需要此信息。只有在建立ssh连接后,才能通过此连接转发端口。
Piotr Dobrogost'2

如果你想关闭端口,可以从引导,然后用上面的方法请参见“autossh”在systemd服务- everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh
理查德·霍利斯

我也得到“连接被拒绝”。而且我仍然不明白,当不涉及SSH连接时(根据-N),为什么需要user@remote-server.com参数。应该只是转发数据包。
亚历山大·泰勒

2
@AlexanderTaylor -N并不意味着没有SSH连接。它只是意味着do not execute a remote command(请参见手册页)。该<user>@<host>参数是必需的,因为这确实会打开SSH连接<host>(对于OP来说是localhost),并通过该SSH隧道转发所需的端口。这是解决OP问题的一种方法,但不是最简单的方法。要在不使用ssh的情况下转发到localhost,您可以在StephaneChazelas中使用socatnetcat,而不

94

随着socat在服务器上:

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

默认情况下,socat它将在计算机上的任何IPv4或IPv6地址(如果支持)上侦听TCP端口8001。您可以通过将其替换tcp-listentcp4-listen或来将其限制为IPv4 / 6 tcp6-listen,或者通过添加来将其限制为特定的本地地址,bind=that-address

与要代理的连接套接字相同,可以使用任何地址localhost代替tcp,如果希望将地址解析限制为IPv4或IPv6地址,则可以替换为tcp4tcp6

请注意,对于在端口8000上侦听的服务器,连接将显示为来自代理(如果是localhost,则为localhost),而不是来自原始客户端。您需要使用DNAT方法(但是这需要超级用户特权),服务器才能知道谁是客户端。


1
谢谢,这很好,因为您不必运行本地ssh服务器。
jontro 2015年

我可以使用相同的端口但使用不同的地址吗?
阿莫斯

@amos,请参阅编辑。
斯特凡Chazelas

是否还可以仅转发来自特定IP的流量?
Phate

1
@Phate,请参见让socat监听来自单个IP地址的连接(以及手册页中的rangetcpwrap选项socat)。
斯特凡Chazelas

46

使用传统方式nc是最简单的解决方案:

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

此版本的文件nc位于netcat-traditionalUbuntu 的软件包中。(您必须update-alternatives致电或致电nc.traditional。)

请注意,与ssh相比,它未加密。如果您在一台主机之外使用它,请记住这一点。


2
有人知道netcat-openbsd吗?
Sridhar Sarnobat

2
适用于以下netcat版本的模拟版本busyboxnc -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

默认情况下,Linux和OS X上都可以使用OpenBSD netcat。

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上有效的替代方法是使用双向管道。它可能在其他Unix上运行:

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

起初我没有注意到您正在使用openbsd netcat。这比必须从Ubuntu软件包安装另一个netcat更好。
RobertR

OpenBSD示例在Ubuntu 15.04上失败。使用shell重定向时,netcat无法打开端口以进行侦听,如ss -tan或所示netstat -tan
贾斯汀C

⁺¹。FTR:另一种方法可在Ubuntu上使用
Hi-Angel

我不明白您的解决方案。你能解释一下吗?
Trismegistos

@trismegistos在这些示例中,netcat侦听器和客户端将输入重定向到某些共享文件(mkfifo管道..先进先出),并将这些共享文件用作其输入/输出的源/目的地,从而有效地创建了隧道。通常使用客户端/侦听器,但是某些使用客户端+客户端/侦听器+侦听器的技术wiki.securityweekly.com/… 并且必须读取slideshare.net/amiable_indian/secrets-of-top-pentesters
Info5ek

4

在ServerFault上引用David Spillett答案

rinetd应该可以完成工作,并且可以从http://www.boutell.com/rinetd/获得Windows二进制文件(对于在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必须有一个监听应用程序。
Hi-Angel

如果origin-port与目标端口不在同一接口上怎么办?
Trismegistos

0

根据Mark A.的回答,我必须进行一些小调整才能使其在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语句似乎至关重要。否则,连接到端口8000的netcat命令将永远不会真正尝试连接,而侦听端口8001的netcat命令也将永远不会真正侦听端口8001。如果没有printf,我每次尝试连接到端口8001时都会得到拒绝连接。

我的假设是netcat必须在实际执行任何Socket操作之前以某种方式阻塞stdin(也许由于某种原因而试图读取它)。这样,如果没有将printf语句写入fifo a,netcat命令将永远不会开始监听端口8001。

注意:我会在Mark的帖子上留下答案,但是我还没有声誉。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.