长亭百川云 - 文章详情

一款可绕过防火墙/DPI的隧道工具

suntiger

121

2024-06-19

摘要

在通常情况下, 当我们访问公网时, 都会处于某种防火墙或代理之后。它们的目的是限制使用者只能使用某些特定类型的协议,并只能访问网络中的一部分内容。如今,使用最广泛的协议是HTTP协议, 且只能在被第三方设备允许的前提下正常使用。

Wstunnel是一款使用Rust语言编写的开源隧道程序, 稳定且强大。该工具使用与http兼容的websocket协议来绕过防火墙和代理。Wstunnel允许使用者在创建的隧道中传输任何流量, 并访问所需的任何资源或网站。

Wstunnel功能

Wstunnel功能特点包含以下几方面:

(1). 使用便捷, 具备良好的错误信息和调试信息。

(2). 支持静态正向和反向隧道, 包括: TCP、UDP、Unix套接字、Stdio。

(3). 支持动态隧道, 包括: TCP、UDP Socks5代理和透明代理。

(4). 支持HTTP代理及代理协议。

(5). 支持tls/https服务器, 并支持证书自动重新加载。(包括带有嵌入的自签名证书或自己的证书)

(6). 支持mTLS, 并支持证书自动重新加载。

(7). 支持IPv6。

(8). 支持Websocket和HTTP2传输协议。(Websocket性能更好)

(9). 具备独立的二进制程序文件, 只需复制到目标位置运行即可。

开源地址: https://github.com/erebe/wstunnel

Wstunnel安装

首先需要安装Rust环境: https://www.rust-lang.org/tools/install , 或者直接使用以下命令安装环境:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

接着clone项目到本地, 并在项目根目录下通过以下命令编译执行:

cargo build  
target/debug/wstunnel ...

Wstunnel简单使用

完成后, 在远程主机上, 通过在终端输入以下命令来启动wstunnel服务器:

wstunnel server wss://[::]:8080

这将创建一个在8080端口监听的websocket服务器。在客户端,使用以下命令通过 websocket 隧道转发流量:

wstunnel client -L socks5://127.0.0.1:8888 --connection-min-idle 5 wss://myRemoteHost:8080

该命令将创建一个在本地 8888 端口上监听的 socks5 服务器,并将动态转发流量。connection-min-idle 10
将进行优化以创建一个连接到服务器的 10 个连接池,以加快新隧道的建立。

在浏览器中, 可以通过此隧道设置代理, 只需在网络首选项中设置127.0.0.1:8888并选择socks5代理。也可以使用以下命令达到同等效果:

curl -x socks5h://127.0.0.1:8888 http://google.com/

作为SSH代理命令使用

如果希望使用wstunnel作为ssh代理命令的一部分,可以在客户端指定源端口,命令如下:

ssh -o ProxyCommand="wstunnel client --log-lvl=off -L stdio://%h:%p ws://myRemoteHost:8080" my-server

绕过公司代理

当需要绕过公司的http代理时, 最可靠的方法是使用wstunnel, 以下命令启动wstunnel服务器并激活tls:

wstunnel server wss://[::]:443 --restrict-to 127.0.0.1:22

服务器将使用监听443(https)端口,并限制流量仅转发到 ssh 守护程序。

注意: 服务器将使用弱加密算法的自签名证书。这样做是为了兼容 TLS 的同时尽可能减少开销。不要依赖 wstunnel 来保护自己的隐私,而是只转发安全的流量(如:https 或 vpn 流量)

下面启动客户端:

wstunnel client -L tcp://9999:127.0.0.1:22 -p http://mycorporateproxy:8080 wss://myRemoteHost:443

它将在端口 9999 上启动一个 tcp 服务器,该服务器将联系公司代理,与远程主机协商 tls 连接,并将流量转发到远程主机上的 ssh 守护程序。现在便可以使用ssh 从本地计算机访问服务器:

ssh -p 9999 login@127.0.0.1

透明代理(仅限Linux)

透明代理可以轻松代理任何程序。使用以下命令启动 wstunnel:

sudo wstunnel client -L 'tproxy+tcp://1080' -L 'tproxy+udp://1080' wss://my.server.com:443

使用该项目无缝路由流量:https://github.com/NOBLES5E/cproxy , 它适用于任何程序:

cproxy --port 1080 --mode tproxy -- curl https://google.com

甚至可以启动一个新的 shell,所有命令都将被代理:

cproxy --port 1080 --mode tproxy -- bash

反向隧道

使用以下命令启动 wstunnel:

sudo wstunnel client -R 'tcp://[::]:8000:localhost:8000' wss://my.server.com:443

在另一个终端中,在本地机器上启动一个简单的网络服务器:

python3 -m http.server

现在可以从 my.server.com 机器/网络执行此操作:

curl http://localhost:8000

保护wstunnel 服务器的访问安全

假如生成了一个密钥:h3GywpDrP6gJEdZ6xbJbZZVFmvFZDCa4KcRd

现在使用以下命令启动服务器:

wstunnel server --restrict-http-upgrade-path-prefix h3GywpDrP6gJEdZ6xbJbZZVFmvFZDCa4KcRd wss://[::]:443

并开始使用:

wstunnel client --http-upgrade-path-prefix h3GywpDrP6gJEdZ6xbJbZZVFmvFZDCa4KcRd ... wss://myRemoteHost

现在,wstunnel 服务器只有在客户端在升级请求期间指定正确的路径前缀时才会接受连接。

如果需要更多自定义,可以使用配置文件来指定特定规则。限制规则示例如下:

# Restrictions are whitelist rules for the tunnels  
# By default, all requests are denied and only if a restriction match, the request is allowed  
restrictions:  
  - name: "Allow all"  
    description: "This restriction allows all requests"  
    # This restriction apply only and only if all matchers match/are evaluated to true  
    # It is a logical AND  
    match:  
      # This match apply only if it succeeds to match the path prefix with the given regex  
      # The regex does a match, so if you want to match exactly you need to bound the pattern with ^ $  
      # I.e: "tesotron" is going to match "XXXtesotronXXX", but "^tesotron$" is going to match only "tesotron"  
      - !PathPrefix "^.*$"  
      # The only other possible match type for now is !Any, that match everything/any request  
      # - !Any  
  
    # This is the list of tunnels your restriction is going to allow  
    # The list is checked in order, the first match is going to allow the request  
    allow:  
      # !Tunnel allows forward tunnels  
      - !Tunnel  
        # Protocol that are allowed. Empty list means all protocols are allowed  
        # Logical OR  
        protocol:  
          - Tcp  
          - Udp  
        # Port that are allowed. Can be a single port or an inclusive range (i.e. 80..90)  
        # Logical OR  
        port:  
          - 80  
          - 443  
          - 8080..8089  
  
        # if the tunnel wants to connect to a specific host, this regex must match  
        host: ^.*$  
        # if the tunnel wants to connect to a specific IP, it must be included in one of the network cidr  
        # Logical OR  
        cidr:  
          - 0.0.0.0/0  
          - ::/0  
  
      # !ReverseTunnel allows reverse tunnels  
      # Not specifying anything means all reverse tunnels are allowed  
      - !ReverseTunnel  
        protocol:  
          - Tcp  
          - Udp  
          - Socks5  
          - Unix  
        port:  
          - 1..65535  
        # Maps ports on the server side from X to Y (X:Y). For example with 10001:8080 configured and a client  
        # which connects using '-R tcp://10001:localhost:80' the server will listen on port 8080 instead of 10001.  
        # The originally requested ports (NOT the mapped ports) need to be allowed via the 'ports' directive.  
        port_mapping:  
          - 10001:8080  
        cidr:  
          - 0.0.0.0/0  
          - ::/0  
  
---  
# Examples  
restrictions:  
  - name: "example 1"  
    description: "Only allow forward tunnels to port 443 and forbid reverse tunnels"  
    match:  
      - !PathPrefix "^.*$"  
    allow:  
      - !Tunnel  
        port:  
          - 443  
---  
restrictions:  
  - name: "example 2"  
    description: "Only allow forward tunnels to local ssh and forbid reverse tunnels"  
    match:  
      - !PathPrefix "^.*$"  
    allow:  
      - !Tunnel  
        protocol:  
          - Tcp  
        port:  
          - 22  
        host: ^localhost$  
        cidr:  
          - 127.0.0.1/32  
---  
restrictions:  
  - name: "example 3"  
    description: "Only allow socks5 reverse tunnels listening on port between 1080..1443 on lan network"  
    match:  
      - !PathPrefix "^.*$"  
    allow:  
      - !ReverseTunnel  
        protocol:  
          - Socks5  
        port:  
          - 1080..1443  
        cidr:  
          - 192.168.0.0/16  
---  
restrictions:  
  - name: "example 4"  
    description: "Allow everything for client using path prefix my-super-secret-path"  
    match:  
      - !PathPrefix "^my-super-secret-path$"  
    allow:  
      - !Tunnel  
      - !ReverseTunnel  
---  
restrictions:  
  - name: "example 5"  
    description: "Forbid everything ..."  
    match:  
      - !Any  
    allow: []

使用HTTP2 代替 websocket 作为传输协议

仅当防火墙/代理阻止 websocket 时才使用此选项。否则,它的性能不如 websocket。

像往常一样启动 wstunnel 服务器:

wstunnel server wss://[::]:8080

在客户端上,唯一的区别是指定 https:// 而不是 wss://

wstunnel client -L socks5://127.0.0.1:8888 https://myRemoteHost:8080

警告:

HTTP2 作为传输协议更难正常工作,因为:

  • 如果使用(反向)代理/CDN,它们可能会缓冲整个请求,然后再将其转发到服务器。Cloudflare 就是这样做的,显然,这对于隧道流量不起作用

  • 如果在反向代理后面有 wstunnel,那么大多数(即 nginx)都会将 http2 请求转换为 http1。这是行不通的,因为http1本身不支持流式传输

使其与 HTTP2兼容的唯一方法是将wstunnel服务器直接暴露在互联网上,而不需要在其前面使用任何反向代理。

此外,你可能还想使用请求标头(即内容长度和内容类型),使其看起来像正常流量,以绕过防火墙/代理。某些防火墙可能不喜欢看到未设置内容长度的请求,或将内容类型设置为 application/octet-stream

如何最大程度提高隐蔽性

  • 使用已激活 TLS 的 wstunnel(wss://)并使用自己的证书

  • 嵌入式证书是自签名的,对每个人都一样,因此可以轻松进行指纹识别/标记

  • 使用有效证书(例如:使用 Let's Encrypt),自签名证书是可疑的

  • 使用自定义 http 路径前缀(参见--http-upgrade-path-prefix
    选项)

  • 为了避免与其他 wstunnel 用户拥有相同的 URL

  • 将tls-sni-override 更改为已知允许的域(即:google.com、baidu.com 等...)

  • 如果wstunnel服务器位于反向代理后面(即:Nginx、Cloudflare、HAProxy 等),则此方法将不起作用。

点个在看你最好看

东 WHAT HAPPENED IN MAY 西

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2