Skip to content

root4root/handshakeless-vpn

Repository files navigation

handshakeless-vpn (Linux)

Tunnel with ECDH session KEX under AES-256-GCM using PSK

Written in Go, has the following features:

  • Underlying protocol: TCP
  • Payload encryption: ChaCha20-Poly1305 and AES-256-GCM - both with authentication (MAC)
  • Headers encryption: ChaCha20 to obfuscate protocol signatures only
  • Key Exchange (KEX): Elliptic Curve Diffie–Hellman (ECDH) based on Curve25519
  • Address management: DHCP-like, based on server's tun interface index
  • Multi-client: supports up to 64 simultaneous connections (limited by 'DHCP')
  • Quite small codebase - easy to review and modifications

Some other details and approaches:

  • Zero bytes unencrypted data from the very first packet, including protocol headers
  • Session keys exchange hardened with random prepend and append wich make packet size unpredictable so as actual payload offset
  • During KEX procedure, server and client exchange Challange Messages to prevent replay attacks
  • In order to work in a Multi Client mode, Server has DHCP-like capability. No manual IP assignments on the client's and server's TUN interfaces
  • AES-256-GCM with pre-shared keys (PSK) used during KEX. When it's done, ChaCha20-Poly1305 with new session keys take place

Usage:

./bin folder contains statically linked binary amd64 (Debian/Ubuntu)

  1. Since service creates, configures, and removes tun interfaces, root privileges required
  2. Start server with IP:PORT of interface to bind to: sudo handshakeless-vpn --listen 0.0.0.0:777
  3. Copy (just) created file 'handshakeless.conf.json' to client side, put it near handshakeless-vpn binary
  4. Start client with server's IP:PORT: sudo handshakeless-vpn --connect X.X.X.X:777
  5. If needed, configure routing and NAT as usual (don't forget to enable ip_forward on server side)

! Notice: handshakeless.conf.json contains randomly generated Pre-shared Keys, therefore must be exactly the same on each side

Data exchange flow:

[WAN/LAN] TCP_SOCKET <-encrypted-> SERVER | CLIENT <-unencrypted-> TUN_IFACE [LOCAL]

Protocol layout (Sep 2025):

--------------------------------------------------------------------------
| enc. packet length (2B) | nonce (12B) | enc. payload (var) | MAC (16B) |
--------------------------------------------------------------------------