通过SSH隧道的UDP流量


66

标题几乎总结了一下。我想通过SSH隧道发送UDP流量。具体来说,我需要能够通过隧道发送UDP数据包,并使服务器能够将它们发送回另一端。我知道如何进行TCP连接。UDP是否可能?

Answers:


36

本小型指南告诉您如何使用大多数类UNIX操作系统的标准工具(ssh,nc,mkfifo)通过SSH通过UDP发送UDP流量。

通过SSH连接执行UDP隧道

逐步使用SSH连接打开TCP转发端口

在本地计算机(本地)上,使用附加的-L选项通过SSH通过SSH连接到远程计算机(服务器),从而使SSH与TCP端口转发:

local# ssh -L 6667:localhost:6667 server.foo.com

这将允许通过安全通道将本地计算机的端口号6667上的TCP连接转发到server.foo.com上的端口号6667。在服务器上将TCP设置为UDP转发

在服务器上,我们在TCP端口6667上打开一个侦听器,该侦听器会将数据转发到指定IP的UDP端口53。如果要像我一样进行DNS转发,则可以使用在/etc/resolv.conf中可以找到的第一个域名服务器的IP。但是首先,我们需要创建一个fifo。fifo对于在两个通道之间进行双向通信是必不可少的。一个简单的外壳管道只能将左过程的标准输出传递到右过程的标准输入。

server# mkfifo /tmp/fifo
server# nc -l -p 6667 < /tmp/fifo | nc -u 192.168.1.1 53 > /tmp/fifo

这将允许将服务器端口6667上的TCP通信转发到192.168.1.1端口53上的UDP通信,并返回响应。在计算机上将UDP设置为TCP转发

现在,我们需要做的与在本地计算机上所做的相反。您需要特权访问才能绑定UDP端口53。

local# mkfifo /tmp/fifo
local# sudo nc -l -u -p 53 < /tmp/fifo | nc localhost 6667 > /tmp/fifo

这将允许将本地计算机端口53上的UDP通信转发到本地计算机端口6667上的TCP通信。享用您的本地DNS服务器:)

您可能已经猜到了,当将在本地计算机(例如本地UDP端口53)上执行DNS查询时,它将转发到本地TCP端口6667,然后转发到服务器的TCP端口6667,再转发到服务器的DNS服务器,192.168.1.1的UDP端口53。要在您的本地计算机上享受DNS服务,请将以下行作为第一名称服务器放入/etc/resolv.conf中:

nameserver 127.0.0.1

28
此解决方案不安全。不能保证TCP流保留消息边界,因此单个UDP数据报可能会分成几部分,从而破坏任何协议。
JuhoÖstman,

2
也可以使用端口1153代替IRC使用的6667(以man SSH为例)。
菲尔·皮罗

1
@JuhoÖstman感谢您指出这个陷阱。意识到了问题...您是否已运行解决方案?足够小的消息是否会使其可行?
humanityANDpeace

4
解决方案是在每个数据包通过TCP流发送之前给它们一个长度,然后从中重建原始数据包。编写C脚本可以很容易地做到这一点,但是我不确定是否存在一个容易获得的解决方案。实际上,在这种情况下,TCP通常似乎保留消息边界,但是随时可能发生奇怪的故障。
JuhoÖstman'13

我遇到了另一个问题:管道和fifo被缓冲,因此丢失了帧边界。如此多的UDP帧可以串联到一个TCP帧中。
Julio Guerra 2015年

26

示例(我认为John的答案将同一事物指向不同的地方),描述了如何通过TCP / SSH连接访问另一台计算机的UDP / DNS服务。

我们将本地UDP / 53流量转发到TCP,然后使用SSH的端口转发机制将TCP流量转发到另一台计算机,然后将TCP转发到另一端的UDP / 53。
通常,您可以使用openvpn做到这一点。
但是在这里,我们将使用更简单的工具(仅openssh和netcat)来实现。

在该页面的最后,是另一条注释,其中引用了“ socat”,
使用相同的UDP / DNS访问,

服务器端:socat tcp4-listen:5353,reuseaddr,fork UDP:nameserver:53
客户端:socat udp4-listen:53,reuseaddr,fork tcp:localhost:5353

请参阅socat示例以获取更多信息。


3
对于我来说,这似乎比接受的答案有用得多。我需要视频流(TS / UDP)的单向重定向... ssh orig_strm_src socat udp4-listen:4003,reuseaddr,fork STDOUT| socat STDIN udp-sendto:localhost:4003
nhed 2012年

FWIW,我在主页上写了更详细的指南,描述了如何通过SSH设置socat来进行UDP转发。以SNMP为例。
2013年

20

SSH(至少是OpenSSH)支持简单的VPN。使用客户端中的-wTunnel选项ssh,可以tun在两端创建一个设备,该设备可用于转发任何类型的IP流量。(另请参见Tunnel的手册页ssh_config(5)。)请注意,这两端都需要OpenSSH(可能还需要root特权)。


即使对于非特权端口的UDP隧道传输,并且PermitRootLogin设置为“ no”,这也要求远程计算机具有root特权。太糟糕了。
菲尔·皮罗

@grawity感谢您指出此选项,即使philpirozhkov指出该选项也需要root用户登录。我想知道是否有办法欺骗它不需要根?
humanityANDpeace

4
@humanityANDpeace:您可以使用来预先创建tun / tap设备,并使它们归特定用户所有ip tuntap add
grawity 2013年

嗨@grawity。我喜欢您的解决方案,但无法使其正常工作。我预先创建了tun设备,如下所示:sudo ip tuntap add mode tun但是当使用如下所示的-w选项时:ssh $Server -w $port我得到了Tunnel device open failed. Could not request tunnel forwarding.我做错了什么?
卢卡斯·艾玛雷托

16

或者,您可以通过简单的命令简单地使用ssf(旨在处理此用例):


客户端:

#>./ssfc -U 53:192.168.1.1:53 server.foo.com

该命令通过本地主机和server.foo.com之间的安全隧道将本地端口53(dns)重定向到192.168.1.1端口53。


您将需要一个ssf服务器(而不是ssh服务器-或-旁边):

#>./ssfs

顺便说一下,ssf的客户端和服务器端都可以在Windows / Linux / Mac上运行。这是一个Userland应用程序,因此您不需要tun / tap或VPN。

要重定向端口53,您将需要管理权限-不管使用什么工具。

有关更多信息,详细信息,用例或下载:https : //securesocketfunneling.github.io/ssf/


请谨慎回答“这是我的产品”,这是边缘垃圾邮件。我建议阅读并遵循帮助中心提供指南
2015年

7
最多,这是一个无耻的插件。无论如何,该解决方案可能适合您的要求。顺便说一句,SSF是开源的并且是非盈利的。
ssf-developers

11
@heavyd:如果他发布了一堆hacky脚本,那是可以接受的,但是因为他开发了成熟的开源工具,不是吗?它完美地回答了原始问题。
Synthead '16

我不得不勉强承认这正是我一直在寻找的工具,即使它是一个无耻的插件。
therealrootuser

9

我无法nc使用SNMP,因为SNMP客户端一直在选择新的源UDP端口,并且其中几个可以同时处于活动状态。

取而代之的是,我socat在此博客文章中以SNMP为例,描述了如何使用它。本质上,使用两个终端,从概述开始:

概观

第一航站楼:

client$ ssh -L 10000:localhost:10000 server
server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161

这将创建TCP端口10000的SSH转发,并在服务器上运行socat。注意,在socat命令行中如何将交换机的IP地址称为“ switch”。

第二航站楼:

client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000

这在客户端上设置了socat。那应该做。


这对我
有用

4

如果您可以访问UDP端口,则VPN是更好的解决方案。

如果您只能访问TCP SSH端口,则SSH隧道与VPN一样好,至少在ping和数据包回溯方面如此。

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.