2020 年及以后的蹩脚 UDP 路由器。
所以我正在和 Roon 一起玩,我有一个复杂的家庭网络,这让 Roon 陷入困境。我开始调试,结果发现 Roon 向 UDP/9003 发送广播消息。我的防火墙/路由器当然不会转发这些消息,因为这是正确的做法。
不幸的是,我真的希望将这些广播消息转发到本地网络上的其他 VLAN/子网。我开始使用 udp-proxy-relay-redux,一开始效果很好。
但我也非常喜欢通过 OpenVPN 连接转发的这些消息,这些消息利用tun
驱动程序,这是一个点对点接口,并且明确不支持广播。这对于 udp-proxy-relay-redux 效果不佳,因为 Roon 表现不佳,仍然尝试向 .255 地址发送“广播”,然后这些广播被丢弃在地板上,因为我的 VPN 服务器没有地址 xxx255。基本上,在点对点接口上,这些“广播”被视为发往另一台主机的数据包并被理所当然地忽略。
udp-proxy-2020
不使用普通的 UDP 套接字来侦听广播消息,而是使用 libpcap 来“嗅探”UDP 广播消息。这意味着它对于“看到”的数据包可以更加灵活,因此它可以通过 libpcap/数据包注入将它们发送到所有其他配置的接口。如果这让你感到“奇怪”,那么,欢迎来到 2020 年。
我是用 GoLang 编写的,因此至少交叉编译到随机的 Linux/FreeBSD 路由器/防火墙上相当容易。没有丑陋的交叉编译 C 或尝试安装 Python/Ruby 和一堆库。
还有:哈哈哈哈哈哈哈哈哈!这些都不是真的!需要使用 libpcap 意味着我必须使用 CGO 进行交叉编译,因为 gopacket/pcapgo 仅支持 Linux 读取和写入(以太网?)网络接口。
几乎所有类 Unix 系统都受支持,因为依赖项列表只有libpcap
和golang
。我在 MacOS 上进行开发,特别针对 pfSense/FreeBSD 和 Ubiquiti USG、EdgeRouter 和 DreamMachine/Pro,因为这些在 Roon 用户社区中很常见。
如果您使用的是基于 Linux RedHat 或 Debian 的发行版,最简单的安装方法是获取适当的.rpm
或.deb
文件并使用包管理器进行安装。然后编辑/etc/udp-proxy-2020.conf
并通过以下方式启动: systemctl start udp-proxy-2020
。
还有一个适用于 AMD64 和 ARM64 上的 Linux 的 docker 映像(如 Ubiquiti UDM)。
请注意,对于 Docker 部署,您应该使用主机网络。
我发布了适用于 Intel、ARM 和 MIPS 硬件的 Linux、FreeBSD (pfSense) 和 MacOS 的二进制文件。
现在启动脚本目录中提供了说明和启动脚本。如果您知道如何添加对另一个平台的支持,请向我发送拉取请求!
运行udp-proxy-2020 --help
以获取当前命令行选项列表。
另外,请注意,在许多操作系统上,您需要以root
用户身份运行它。 Linux 系统可以选择授予CAP_NET_RAW
功能。
目前您可能只需要担心几个标志:
--interface
-- 指定要侦听的两个或多个网络接口。--port
-- 指定一个或多个要监控的 UDP 端口。--level
-- 指定日志级别:[trace|debug|warn|info|error]高级选项:
--fixed-ip
-- 硬编码@以始终向其发送流量。对于站点到站点模式下的 OpenVPN 等非常有用。--timeout
-- pcap 超时值的毫秒数。 (默认为250毫秒)--cache-ttl
-- 缓存 IP 的分钟数。 (默认值为 180 分钟/3 小时)如果您在 OpenVPN 隧道上将流量传递到客户端时遇到问题,并且由于客户端没有固定 IP 而无法使用--fixed-ip
则可能需要增加此值。--no-listen
-- 不监听指定的 UDP 端口以避免冲突--deliver-local
-- 在环回接口上本地传送数据包当然还有其他标志,运行./udp-proxy-2020 --help
以获得完整列表。
例子:
udp-proxy-2020 --port 9003 --interface eth0,eth0.100,eth1,tun0 --cache-ttl 300
将在四个接口上转发 udp/9003 数据包:eth0、eth1、eth0 和 tun0 上的 VLAN100。 tun0 上的客户端 IP 一旦获知就会被记住 5 分钟。
注意:“学习”需要客户端先发送udp/9003报文!如果您的应用程序需要首先向客户端发送消息,那么您需要指定--fixed-ip=1.2.3.4@tun0
,其中1.2.3.4
是 tun0 上客户端的 IP 地址。
我已经测试了两种“公路战士”VPN 配置,其中 Roon 客户端在我的笔记本电脑上运行,并通过 OpenVPN 和 Wireguard 连接回我的家庭防火墙。我个人使用 Wireguard 而不是 OpenVPN,因为它更安全并且性能更好。
我还使用 Wireguard + pfSense 测试了站点到站点 VPN。我按照 pfSense 站点到站点 Wireguard VPN 说明进行操作,并在两个防火墙上安装了udp-proxy-2020
。您必须配置--interface
选项以包括 LAN 和 Wireguard 网络接口。
如果您正在为打算运行udp-proxy-2020
同一平台进行构建,那么您只需确保拥有libpcap
和必要的标头(您可能需要一个-dev
包)并根据需要运行make
或gmake
(我们需要 GNU Make,而不是 BSD Make)。
如果您需要构建跨平台,那么以下目标之一可能会帮助您:
make linux-amd64
make linux-mips64
(适用于 Ubiquiti USG/EdgeRouter 的 Linux/MIPS64 big-endian)make linux-arm
:make freebsd
(pfSense 2.6)make docker
您可以通过运行make help
来获取 make 目标的完整列表以及有关它们的基本信息。
从 v0.0.11 开始, udp-proxy-2020
现在默认在指定的--port
上创建 UDP 侦听套接字。这可以防止底层操作系统发出 ICMP 端口不可达消息,该消息可能会破坏某些客户端(特别是 Roon iOS 客户端)。
您唯一需要使用--no-listen
标志的情况是,如果有另一个软件与udp-proxy-2020
在同一主机上运行。
从 v0.1.0 开始,是的。您需要指定--deliver-local
和--no-listen
选项,以便它通过环回接口传送数据包。
这些标志用于调试udp-proxy-2020
的问题。当我指示您这样做时,您应该使用这些标志作为您为udp-proxy-2020
开立的票证的一部分。
来自 Github 上的发布页面。
不,这不是代理。它更像是一个路由器。除了在家庭路由器/防火墙上运行之外,您不需要进行任何更改。
老实说,我并没有对这个名字想太多,这是我首先想到的。另外,命名也很难。
tun
接口,如 OpenVPN 使用的接口raw
接口,例如 Wireguard 使用的接口vti
接口请注意,Linux 上的 L2TP VPN 隧道与 udp-proxy-2020 不兼容,因为 Linux 内核将这些接口公开为 Linux SLL,而 Linux SLL 不提供数据包的准确解码。
所以我自己还没有这样做,但是 Bart Verhoeven 在 Roon 社区论坛上写了这个非常详细的操作方法。
udp-proxy-2020 是为多个操作系统和硬件平台构建的:
darwin-amd64
linux-amd64
linux-arm64
(RasPi 2 V1.2及以上版本、Ubiquiti UniFi Dream Machine)linux-armv7
(RasPi 2 V1.1及以下版本)linux-armv6
linux-armv5
linux-mips64
(Ubiquiti USG/EdgeRouter)freebsd-amd64
(与 x86 上的 pfSense 配合使用)freebsd-arm64
(Netgate SG-1100 和 SG-2100)freebsd-armv7
(Netgate SG-3100)老实说,只要给我发一封电子邮件表示感谢或在 GitHub 上“星标”这个项目就足够了,谢谢。
偶尔会有人问要不要给我几块钱,但我真的不需要钱。如果你仍然愿意为我捐几块钱,我宁愿你捐给我当地的第二丰收食品银行,它可以让你的钱比我更好地发挥作用。