DSVPN provides encrypted, authenticated tunneling based on a 32-byte pre-shared key. This page documents what DSVPN protects against, what it doesn’t, and the security properties of its design. Understanding the model clearly is essential before deploying DSVPN in any environment.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/jedisct1/dsvpn/llms.txt
Use this file to discover all available pages before exploring further.
Threat Model
DSVPN is designed for a specific, well-defined use case: routing traffic from a client device through a trusted server over an untrusted network. Within that scope, the following security properties hold when the pre-shared key remains confidential. Confidentiality All traffic sent over the tunnel is encrypted with the Charm AEAD stream cipher. An attacker observing the TCP stream sees only ciphertext of fixed overhead (2-byte length + 6-byte tag per packet). Authentication Both endpoints must possess the shared key to complete the handshake. The server verifies the client’s hash before accepting a connection, and the client verifies the server’s hash before sending any data. A party without the key cannot complete the key exchange. Integrity Every packet carries a 6-byte authentication tag computed by the Charm cipher. Any modification to the ciphertext or tag causesuc_decrypt to return a non-zero error code, which DSVPN treats as a "Corrupted stream" event and responds to by tearing down the connection and reconnecting.
Anti-Replay
Replay protection operates at two levels:
- The 8-byte timestamp in the client’s handshake challenge prevents replay of captured handshake packets outside the
TS_TOLERANCE = 7200second (2-hour) window. - The Charm stream cipher state advances monotonically per packet. A replayed packet decrypts to incorrect plaintext and fails tag verification.
What DSVPN Does NOT Provide
No Perfect Forward Secrecy (PFS) Session keys are derived from the static shared key viauc_hash. If the key file is compromised, an attacker who recorded past sessions can decrypt them. There is no ephemeral Diffie-Hellman or similar mechanism to protect historical traffic.
No Certificate Infrastructure
DSVPN uses a single shared secret for all clients. There is no per-user identity, no certificate chain, no revocation mechanism. Every party that holds the key is indistinguishable from any other.
No Multi-Peer Support
The server maintains one active session at a time. A second connection attempt from a different IP address while a session is active is rejected with "a session from [ip] is already active".
No Access Control Beyond Key Possession
Once a client authenticates, all of its traffic is forwarded without further inspection or filtering. There are no ACLs, no split-tunnel policies, and no per-user bandwidth or destination rules.
No Anonymity
The server records and logs the client’s IP address. DSVPN shifts the point at which your IP is visible (from the destination server to the VPN server), but does not hide it from the VPN server operator.
Operating System Hardening
DSVPN applies platform-specific sandboxing where available. OpenBSD —pledge(2)
After the TUN interface is created, DSVPN drops capabilities using OpenBSD’s pledge(2) system call:
Attack Surface
DSVPN is deliberately minimal to keep the auditable surface area small.- Binary size: approximately 25 KB stripped
- No heap allocations:
BufandContextstructs are stack-allocated inmain(), eliminating heap-spray, use-after-free, and double-free attack vectors - No external dependencies: no OpenSSL, no libsodium, no protocol parsers beyond simple length-prefixed framing
- No configuration file parser: all parameters are positional command-line arguments
- Compiler hardening: built with
-march=native -mtune=native -O3 -Wall -W -Wshadow -Wmissing-prototypes - CodeQL analysis: static analysis scans run automatically in CI on every commit
src/os.c.
Pre-Shared Key Security
The 32-byte key file is the single secret protecting the tunnel. Its confidentiality is the foundation of every security property described above. Generating a keyls -la vpn.key.
Transferring the key
Only transfer the key over an already-encrypted channel:
- Generating a new key on one endpoint
- Securely transferring it to the other endpoint
- Restarting DSVPN on both ends simultaneously (or within the handshake retry window)
Signal Handling and Clean Shutdown
DSVPN installs handlers forSIGINT and SIGTERM that set a volatile sig_atomic_t exit_signal_received flag:
Ctrl-C triggers this path.
On unclean disconnects (network failure, authentication error), the client attempts to reconnect up to RECONNECT_ATTEMPTS = 100 times with a backoff of up to 3 seconds between attempts before giving up.
No Guarantees
DSVPN’s author is explicit about the project’s scope and support posture. From the README:“Guarantees, support, feature additions — None. This is what I use, because it solves a problem I had.”