wstunnel

repository·main·Indexed 27 days ago

https://github.com/erebe/wstunnel

A Rust-based tunneling tool designed to bypass firewalls and proxies by masking traffic as standard HTTP/S traffic using WebSockets, HTTP2, or WebTransport. It supports static forward/reverse tunneling for TCP, UDP, Unix sockets, and Stdio, as well as dynamic tunneling via Socks5, HTTP, and Transparent Proxies. Features include TLS/HTTPS with mTLS, IPv6 support, and custom DNS resolvers.

Tokens
9.9K
Snippets
21
Records
78
Agent score
89%

What's inside wstunnel

  1. Overview of wstunnel

    main

    wstunnel is a tool designed to bypass firewalls and proxies by tunneling various types of traffic through the WebSocket protocol, which is highly compatible with HTTP and widely allowed on public networks. It is written in Rust and provides standalone binaries for easy deployment.

    Key Features:

    • Tunneling Types: Static forward/reverse tunneling (TCP, UDP, Unix socket, Stdio) and Dynamic (reverse) tunneling (Socks5, HTTP proxy, Transparent Proxy).
    • Transport Protocols: Supports WebSocket, HTTP2, and WebTransport (WebSocket is recommended for performance).
    • Security: Supports TLS/HTTPS with certificate auto-reload, mTLS, and the Proxy Protocol.
    • Connectivity: Supports IPv6 and can use an existing HTTP proxy as a gateway.
  2. Bypass a corporate HTTP proxy

    main
    To bypass a corporate HTTP proxy, run the wstunnel server with TLS enabled and restrict it to a specific destination (e.g., the remote SSH daemon). On the client side, use the -p flag to specify the corporate proxy address.
  3. Use HTTP2 as a transport protocol

    main

    If WebSockets are blocked by your firewall, you can use HTTP2 as the transport protocol by using the https:// scheme instead of wss:// on the client.

    Important Limitations:

    • The wstunnel server must be directly exposed to the internet.
    • It will not work behind most reverse proxies (like Nginx) because they often convert HTTP2 requests to HTTP1, which lacks the necessary streaming support.
  4. Secure wstunnel server with path prefix restrictions

    main
    To prevent unauthorized users from connecting to your wstunnel server, you can require a secret path prefix. Both the server and the client must use the same prefix via the --http-upgrade-path-prefix option.
  5. Build wstunnel-cli from source

    main
    To build the wstunnel-cli package, you must have the Rust toolchain installed. You can install Rust using rustup via the official shell script. Once Rust is installed, navigate to the root of the project and use cargo build targeting the wstunnel-cli package.
  6. Use WebTransport (HTTP/3) as a transport protocol

    main

    WebTransport runs on QUIC (UDP) and is useful if TCP is throttled or if you experience head-of-line blocking on lossy links.

    Setup:

    1. Server: Enable it using --enable-webtransport or use the wts:// shorthand. This causes the server to listen on UDP on the same port as the TCP listener.
    2. Client: Use the wts:// scheme.

    Warnings:

    • UDP must be reachable end-to-end on the target port.
    • --http-proxy is not supported because QUIC is UDP-based.
    • The server should be directly exposed; reverse proxies often do not forward QUIC/UDP correctly.
  7. Tunnel Wireguard traffic via wstunnel

    main

    You can obfuscate Wireguard traffic by wrapping its UDP packets in a websocket tunnel.

    Key Configuration Steps:

    1. Server: Start the server with --restrict-to targeting the Wireguard port.
    2. Client: Use the udp:// protocol in the -L flag. To prevent the tunnel from closing automatically, set timeout_sec=0 in the connection string.
    3. Wireguard Config: Set the Endpoint to localhost:[PORT] where the wstunnel client is listening. Set a manual MTU (e.g., 1400) to avoid fragmentation.
    4. Routing: Add a static route for the wstunnel server's IP via your main gateway to prevent routing loops (Wireguard -> wstunnel -> Wireguard).
    # Server side
    wstunnel server --restrict-to localhost:51820 wss://[::]:443
    
    # Client side
    wstunnel client -L 'udp://51820:localhost:51820?timeout_sec=0' wss://my.server.com:443
    
    # Wireguard Client Config snippet
    [Interface]
    Address = 10.200.0.2/32
    # ...
    MTU = 1400
    
    [Peer]
    Endpoint = localhost:51820
    # ...
  8. Configure WebTransport (wts://) transport

    main

    WebTransport (wts://) runs on HTTP/3 over QUIC. When using this protocol:

    • UDP Requirement: UDP must be reachable end-to-end on the target port. If firewalls or container mappings only forward TCP, the handshake will timeout after 10s.
    • Server Setup: The server must be started with --enable-webtransport or using the wts:// scheme.
    • TLS: TLS 1.3 is mandatory; there is no cleartext variant.
    • Unsupported Options: --http-proxy, --tls-sni-disable, and --tls-ech-enable are not supported with WebTransport.
  9. Maximize traffic stealthiness

    main

    To make wstunnel traffic look like legitimate web traffic and avoid fingerprinting:

    1. Use valid TLS certificates: Instead of the default self-signed certificate, use a valid certificate (e.g., from Let's Encrypt).
    2. Use a custom path prefix: Use --http-upgrade-path-prefix to avoid using the default wstunnel URL patterns.
    3. Override TLS SNI: Use --tls-sni-override to make the connection appear to be going to a common domain (e.g., google.com). Note: This only works if the server is not behind a reverse proxy like Nginx or Cloudflare.
  10. Generate mTLS certificates and CA using OpenSSL

    main

    To enable mutual TLS (mTLS) in wstunnel, you must set up a Certificate Authority (CA) to sign both server and client certificates.

    WARNING: The following steps are intended for development/testing environments only. For production, use a dedicated PKI solution like OpenBao, EJBCA, or Dogtag PKI.

    1. Setup CA Directory Structure

    Create a directory to hold the CA files:

    $ mkdir -p $HOME/wstunnel/ca/{certs,csr,crl,newcerts,private}
    $ cd $HOME/wstunnel/ca/
    $ echo 1000 > serial
    $ touch index.txt

    2. Create OpenSSL Configuration

    Create an openssl.cnf file in your CA directory. This configuration defines the directory locations, the root key/certificate, CRL settings, and specific extensions for server_cert and client_cert.

    3. Generate CA Root

    Generate an unencrypted private key and a self-signed root certificate:

    $ openssl genrsa -out private/ca.key.pem 4096
    $ openssl req -config openssl.cnf \
          -key private/ca.key.pem \
          -new -x509 -days 7300 -sha256 -extensions v3_ca \
          -out certs/ca.cert.pem

    4. Generate Server Certificate

    Generate a key, a Certificate Signing Request (CSR), and sign it with your CA:

    $ openssl genrsa -out private/wstunnel-server.pem 2048
    $ openssl req -config openssl.cnf \
          -key private/wstunnel-server.pem \
          -new -sha256 -out csr/wstunnel-server.csr.pem
    $ openssl ca -config openssl.cnf \
          -extensions server_cert -days 375 -notext -md sha256 \
          -in csr/wstunnel-server.csr.pem \
          -out certs/wstunnel-server.cert.pem

    5. Generate Client Certificate

    Repeat the process for the client. Note that the Common Name (CN) must contain only valid URL characters:

    $ openssl genrsa -out private/wstunnel-client-1.pem 2048
    $ openssl req -config openssl.cnf \
          -key private/wstunnel-client-1.pem \
          -new -sha256 -out csr/wstunnel-client-1.csr.pem
    $ openssl ca -config openssl.cnf \
          -extensions client_cert -days 375 -notext -md sha256 \
          -in csr/wstunnel-client-1.csr.pem \
          -out certs/wstunnel-client-1.cert.pem