443 端口 TCP 隧道上的 Wireguard、阻塞端口绕过、OpenWRT 解决方案

443 端口 TCP 隧道上的 Wireguard、阻塞端口绕过、OpenWRT 解决方案

我面临一个问题 - 我想使用 OpenWRT 将许多嵌入式设备连接到我的 Wireguard 服务器,但除了 80、443 和其他一些端口之外的所有端口都被阻止。此外,网络中只允许使用 TCP。

看来我需要将 UDP 的 WireGuard 隧道传输到 TCP 中。在我的服务器上,我想使用 SSHL(端口共享)服务在 443(或防火墙允许的其他端口)上同时运行 HTTPS 服务器和 WireGuard 隧道。我希望拥有支持多用户的隧道,因此我怀疑快速的 socat hacks 不适用于更多的客户端。

  • 我尝试过wireguard-proxy,它可以完美地通过 SSLH 进行端口共享,但它是用 Rust 编写的,我无法将它部署在 OpenWRT 上(我尝试过,但出现了编译错误)。 -我也测试过udp2raw,它在专用端口上也运行良好,但在使用 SSLH 端口多路复用器时无法连接到它。

我正在寻找一些用 C/C++ 编写的隧道软件,我可以在 OpenWRT 构建系统中交叉编译,并与我的修改后的网络设备一起使用。

答案1

您可以使用socat作为隧道软件。

这是一个典型的设置(以交互方式完成),WireGuard 侦听端口 51820。您仍然需要在启动服务中进行充分的集成。

OpenWRT(但实际在其他 Linux 上测试过)

  • 照常启用 Wireguard 接口

    ... 除了 MTU:请参阅下面注释中的描述。让我们使用 1420-64=1356 的 MTU。示例(实际应在wg0.conf使用时完成wg-quick):

    ip link set wg0 mtu 1356
    
  • 1号航站楼:

    sslh -n --listen 0.0.0.0:443 \
        --tls 127.0.0.1:8443 \
        --anyprot 127.0.0.1:51820 \
        -f
    

    sslh无法识别 WireGuard 的协议,因此它将前往--anyprot目的地。

  • 航站楼2:

    socat -T 120 \
        tcp4-listen:51820,bind=127.0.0.1,reuseaddr,nodelay,fork \
        udp4-connect:127.0.0.1:51820
    

    作为socat建议对于另一种情况:

    注意:如果您打算在两个 Socat“线路端”之间传输数据包,您需要一个保持数据包边界的协议,例如 UDP;TCP 可能与选项 Nodelay 一起使用

    虽然sslh没有专门使用节点布局,两者socat都会,希望对这部分有所帮助。

    这是分叉结束-T 120之前不活动的延迟。socat如果客户端漫游并失去连接,则很有用。应设置为高于预期客户端 WireGuard 持久保持活动的值。无论如何,在非 TLS DDoS 情况下不会有太大帮助:会有多个分叉socat,这只能帮助 DoS(WireGuard 本身会忽略此类流量)。

客户

  • 1号航站楼:

    socat -T 120 \
        udp4-listen:51821,bind=127.0.0.1,fork \
        tcp4:public-endpoint:51820,nodelay
    

    实际上,如果客户端漫游,该socat命令可能必须重新启动,因为它的 TCP 部分可能需要一段时间才能正常失败。

  • 线卫接口

    和以前一样,降低 MTU。在 Linux 上又会是:

    ip link set wg0 mtu 1356
    

    并更改对等端点以切换到现在位于本地系统上的隧道入口(同样,应该在客户端中完成wg0.conf):

    wg set wg0 peer XXXXXXXXX= endpoint 127.0.0.1:51821
    

现在,一旦客户端在隧道内发送任何数据包并通过身份验证,服务器的 WireGuard 将更新其客户端端点(从本地更新为 127.0.0.1:randomport socat)并可以回复。这使得全双工通信:

client ⟺ WG ⟺ UDP ⟺ socat ⟺ TCP over Internet 
server ⟺ WG ⟺ UDP ⟺ socat ⟺ TCP ⟺ sslh

笔记

  • MTU注意事项

    除了通常的 80 字节开销 (1500-80=1420) WireGuard 保留之外,还必须添加 TCP 开销。这是为了避免外部隧道层:socat+sslh不知道底层协议在两个 TCP 数据包中获得太大的有效负载:这可能会至少破坏第二个封装的 UDP 有效负载,从而导致重新传输。

    这个开销实际上是动态的。对于 IPv4,IP 至少为 20,TCP 至少为 20。那么任何现代 TCP 连接都使用 2+8+2=12 字节作为时间戳,并且当数据包丢失时必须使用随机数量的 SACK。让我们考虑一个 (2+2*4+2=12):20+20+12+12=64。确切的值并不重要(这两个 TCP 选项之间实际上是否有两个 TCP NOP 来对齐每个选项?我不知道)。所以最终我选择WireGuard MTU为1420-64=1356。

    在实际物理 LAN 上进行的一些测试ping -M do -s $MTU-28 -f 10.x.x.x表明,在接口上保持 MTU=1420 会丢失约 40% 的数据包,而 MTU=1356 不会丢失任何数据包,即使较高的 MTU 似乎也足够了。

  • 端口 443 受到限制也需要 SSL

    如果限制到端口 443 的防火墙只期望该端口上有 SSL 流量,那么事情会变得更加复杂。一个应该替换sslhhaproxy或者nginx(两者似乎都打包在 OpenWRT 上,我不知道所需的功能是否可用)并使用其 TLS 直通功能根据收到的 ClientHello 来路由 TLS 连接神经网络研究所。然后,两个socats 将用tcp-listen/tcp替换openssl-listen/openssl进行通信,但我不确定在这种情况下 MTU 会受到怎样的影响。

相关内容