Skip to content

ilya1st/wpn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

45 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

VPN over WebSocket

πŸ‡·πŸ‡Ί Русская вСрсия

A PoC VPN service in Go that uses standard communication protocols (HTTP/HTTPS + WebSocket) as a transport for IP/IPv6 packets over a TUN interface.

🎯 What Is This

The client creates a TUN interface on its machine, encapsulates IP packets into a WebSocket connection, and sends them to the server. The server decapsulates packets and forwards them to its own TUN interface β€” and vice versa. Traffic looks like a regular WebSocket connection on port 443.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         WebSocket (ws:// or wss://)         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  vpnclient  β”‚ ──────────────────────────────────────────→│ vpnservice  β”‚
β”‚             β”‚                                             β”‚             β”‚
β”‚  TUN iface  β”‚ ←─── IP/IPv6 packets in binary messages ──→│  TUN iface  β”‚
β”‚  + routes   β”‚         over HTTP/HTTPS transport           β”‚  + routes   β”‚
β”‚  + proxy    β”‚                                             β”‚  + auth     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

⚠️ Project Status

This is a PoC (Proof of Concept). The code compiles and runs but is not ready for production without further development.

Implemented

  • TUN interface for IPv4 and IPv6 (Linux + macOS)
  • WebSocket transport over HTTP/HTTPS (TLS optional)
  • Authentication by username/password from config
  • Protocol with headers (DATA, CONTROL, KEEPALIVE, FRAGMENT)
  • HTTP and SOCKS5 proxy support on the client
  • Route management (server + client, client routes have higher priority)
  • Keepalive mechanism (30s interval, 90s timeout)
  • Packet compression (zlib, per-packet)
  • Large packet fragmentation (>64 KB)
  • Session registry with IPv4/IPv6 address pools
  • Per-session routing (packets routed to specific sessions by IP, not broadcast)
  • Static IPs for clients (auth.users config)
  • Session cleanup and SessionReconnecting state
  • Blocking write with timeout (no silent packet drops)
  • Docker Compose testing (server + N clients)

Planned

  • Reconnect with session restoration β€” client recovers connection after drop without losing IP
  • Camouflage mode β€” server periodically force-disconnects client to imitate browser behavior (DPI evasion)
  • Reconnect buffer β€” packet buffering during connection drop, flush on recovery (0 losses)
  • TLS fingerprinting + SNI spoofing β€” client fingerprint masquerading as a real browser
  • Graceful server shutdown
  • Statistics (STATISTICS), ROUTES_UPDATE from client
  • Full IPv6 support in testing

Full roadmap β€” see RECONNECT-POLITICS-CONCEPTS.md.

πŸš€ Quick Start

Build

CGO_ENABLED=0 go build -o vpnservice ./cmd/vpnservice
CGO_ENABLED=0 go build -o vpnclient ./cmd/vpnclient

Always build statically (CGO_ENABLED=0) β€” required for cross-compilation and dependency-free deployment.

Running the Server

  1. Copy the example config and edit it:
cp server.example.yaml server.yaml
  1. Minimal server.yaml:
server:
  listen: "0.0.0.0"
  port: 8443
  path: "/ws"

auth:
  users:
    - username: "user1"
      password: "password1111"

tun:
  name: "vpnsrv0"
  ip: "10.0.0.1"
  subnet: 24
  1. Start (requires root / CAP_NET_ADMIN for TUN):
sudo ./vpnservice -config server.yaml

Running the Client

  1. Copy the example config and edit it:
cp client.example.yaml client.yaml
  1. Minimal client.yaml:
client:
  server: "10.0.0.1"    # or server domain
  port: 8443
  ws_location: "/ws"

auth:
  username: "user1"
  password: "password1111"

tun:
  name: "vpnclient0"
  ip: ""  # auto β€” gets assigned by server
  1. Start (requires root / CAP_NET_ADMIN):
sudo ./vpnclient -config client.yaml

Verify

After connecting, the client receives an IP from the server pool. Test with ping:

ping 10.0.0.1                    # to server
ping -I vpnclient0 10.0.0.1     # via specific interface

πŸ”§ Configuration

Server (server.example.yaml)

Section Configures
server Listen address, port, WebSocket path, TLS (cert/key)
auth Authentication timeout, user list (username/password/ip4/ip6)
tun TUN interface name, IPv4/IPv6 addresses and subnets
connection_settings Keepalive, fragmentation, compression, write buffer, reconnect timeout

Client (client.example.yaml)

Section Configures
client Server address, port, TLS, WebSocket path
auth Username/password, authentication timeout
proxy HTTP or SOCKS5 proxy for connecting to the server
tun TUN interface name, IP (empty = auto)
connection_settings Keepalive, fragmentation, compression, reconnect delay and max attempts

🐳 Docker Testing

Recommended approach β€” isolated containers with their own network namespaces:

# Start server + 2 clients
./test-docker.sh up

# Automatic test with pings and tcpdump
./test-docker.sh test

# Manual checks
docker exec -it vpn-server     tcpdump -i vpnsrv0 -n
docker exec -it vpn-client-1   ping -c 5 10.0.0.1
docker exec -it vpn-client-2   ping -c 5 10.0.0.1

# Stop
./test-docker.sh down

πŸ“‹ Supported Platforms

OS TUN Routes Notes
Linux syscall.TUNSETIFF netlink Full support
macOS utun control sockets ifconfig / route Full support

πŸ” Security and Censorship Evasion

Baseline (current)

  • TLS optional (wss:// via self-signed or external certificates)
  • Authentication before data transfer
  • Traffic looks like a regular WebSocket connection on port 443
  • Works behind a reverse proxy (nginx, haproxy)

For DPI evasion (planned)

  • TLS fingerprinting β€” masquerade as a real browser (Chrome/Firefox)
  • SNI spoofing
  • Camouflage mode β€” server periodically disconnects client to imitate browser behavior
  • Reconnect buffering β€” 0 packet losses during reconnection

For production, it is recommended to place the server behind a reverse proxy (nginx/haproxy) with a legitimate domain and TLS certificate.

πŸ“‚ Project Structure

cmd/
  vpnservice/main.go      # Server (entry point)
  vpnclient/main.go       # Client (entry point)
internal/
  config/config.go        # YAML configuration
  protocol/message.go     # Encapsulation protocol (serialization)
  tun/                    # TUN interface (cross-platform)
  ws/transport.go         # WebSocket transport + proxy
  routes/routes.go        # Route management
  session/session.go      # Session registry, IP pools
  fragment/fragment.go    # Large packet fragmentation
  compression/comp.go     # Compression (zlib)

Full protocol specification β€” see PROTOCOL.md.

πŸ— Dependencies

Library Purpose
gorilla/websocket v1.5.3 WebSocket
vishvananda/netlink v1.1.0 Routes (Linux)
golang.org/x/net v0.20.0 Proxy (HTTP + SOCKS5)
gopkg.in/yaml.v3 v3.0.1 YAML configuration
google/uuid v1.6.0 Session UUIDs

Minimum Go version: 1.19.

πŸ“ License

LICENSE

About

VPN over websocket

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors