我正在尝试设置一个TeamSpeak3我的家庭网络“net1.mydomain”上的服务器。它在 LAN 中使用 IPv4 子网 10.0.0.0/8;可以通过 CGN 使用 IPv4 访问互联网。这会导致 IPv4-only 侦听器(如 TeamSpeak)对于“net1.mydomain”之外的客户端无法访问。
为了避免这个缺点,我发现socat
(SOcket CAT;多用途中继。)很有帮助,因为我也可以访问fwbox.net2.mydomain
具有完整 IPv4 和 IPv6 双栈连接的机器。
让服务器在机器tsbox.net1.mydomain
、端口1234/UDP4
(语音)、1234/TCP4
(查询)、1235/TCP
(文件)上运行。运行以下命令集后,我可以使用 TS3 客户端进行连接,fwbox.net2.mydomain:1234
就像我的 TS3 服务器在那里运行一样。
ldericher@fwbox$ socat TCP4-LISTEN:1234,fork TCP6:tsbox.net1.mydomain:61234 &# queryport
ldericher@fwbox$ socat TCP4-LISTEN:1235,fork TCP6:tsbox.net1.mydomain:61235 &# fileport
ldericher@fwbox$ socat UDP4-LISTEN:1234,fork TCP6:tsbox.net1.mydomain:61236 &# voiceport
ldericher@tsbox$ socat TCP6-LISTEN:61234,fork TCP4:localhost:1234 &# queryport
ldericher@tsbox$ socat TCP6-LISTEN:61235,fork TCP4:localhost:1235 &# fileport
ldericher@tsbox$ socat TCP6-LISTEN:61236,fork UDP4:localhost:1234 &# voiceport
嗯,差不多。
由于语音 (UDP) 流的 FIFO 化,大量数据包被丢弃,连接不可用。因此,理想情况下,它只会通过 IPv6 传递 UDP 数据包 - 但使用以下命令只会在tsbox
...上产生“权限被拒绝”
ldericher@fwbox$ socat UDP4-LISTEN:1234,reuseaddr,fork UDP6:tsbox.net1.mydomain:61234 &# voiceport
ldericher@tsbox$ socat UDP6-LISTEN:61234,reuseaddr,fork UDP4:localhost:1234 &# voiceport
…我认为这是 UDP 无连接特性造成的。我尝试修改 的选项socat
,但无济于事。“UDP-RECVFROM”/“UDP-SENDTO”不会产生错误,但似乎只能单向转发。我读到stone
(应用程序 TCP/IP 中继器)已经存在,可以作为替代方案,但socat
对我来说却没有那么方便。
要么是我完全错过了关于 UDP 的某些要点,要么根本无法进行 UDP 转发,要么是我的工具集。
socat
那么,是否有任何方法、任何工具或任何代码片段可以满足我的需求?甚至可能是我尚未想到的一组选项?
添加 03/06/2015
它是可以按我想要的方式转发 UDP 流量。即使使用 socat,是一种方法。我使用另一个盒子成功测试了这一点testbox.net1.mydomain
:
# File- and Query- portforwards omitted for irrelevance
ldericher@testbox$ socat UDP4-LISTEN:1234,fork UDP4:tsbox:61234 &
ldericher@tsbox$ socat UDP4-LISTEN:61234,fork UDP4:localhost:1234 &
这作品没有任何性能损失,但它并不能解决我无法从外部使用 IPv4 的问题。
# File- and Query- portforwards omitted for irrelevance
ldericher@testbox$ socat UDP4-LISTEN:1234,fork UDP6:tsbox:61234 &
ldericher@tsbox$ socat UDP6-LISTEN:61234,fork UDP4:localhost:1234 &
这与通过 进行转发的方式不同fwbox
。
那么,我是不是错过了有关 IPv6 的一个重要点?
这是一个 bug 吗?在 socat 中?还是在 Linux 中?!
答案1
你可能会发现这不可能实现,因为TeamSpeak 协议将 IP 地址嵌入(加密性较差的)有效载荷中因此,将数据转发到其他主机可能会导致连接失败,因为客户端、服务器或两者完全忽略数据的来源并尝试使用他们认为数据应该来自的 IP 地址。
答案2
添加-T
选项可以以socat
某种方式解决问题。
-T<timeout>
Total inactivity timeout: when socat is already in the transfer
loop and nothing has happened for <timeout> [timeval] seconds
(no data arrived, no interrupt occurred...) then it terminates.
Useful with protocols like UDP that cannot transfer EOF.
更新的命令:
ldericher@fwbox$ socat TCP4-LISTEN:1234,reuseaddr,fork TCP6:tsbox.net1.mydomain:61234 &# queryport
ldericher@fwbox$ socat TCP4-LISTEN:1235,reuseaddr,fork TCP6:tsbox.net1.mydomain:61235 &# fileport
ldericher@fwbox$ socat -T15 UDP4-LISTEN:1234,reuseaddr,fork UDP6:tsbox.net1.mydomain:61234 &# voiceport
ldericher@tsbox$ socat TCP6-LISTEN:61234,reuseaddr,fork TCP4:localhost:1234 &# queryport
ldericher@tsbox$ socat TCP6-LISTEN:61235,reuseaddr,fork TCP4:localhost:1235 &# fileport
ldericher@tsbox$ socat -T15 UDP6-LISTEN:61234,reuseaddr,fork UDP4:localhost:1234 &# voiceport
我不完全理解为什么这样做有效(因为显然不会超过 15 秒),但我很高兴它确实有效。