Skip to main content

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.

DSVPN supports several Unix-like operating systems out of the box. Linux and macOS have full server and client support with automatic firewall and routing configuration. BSD variants support client and point-to-point modes, with OpenBSD additionally supporting full server mode.

Linux

Linux has full server and client support, including automatic iptables rules, policy routing, and NAT masquerading.Requirements
  • Kernel version 3.17 or later
  • TUN/TAP support compiled in or loaded as a module (CONFIG_TUN)
  • iptables available in $PATH (for server mode)
  • ip (iproute2) available in $PATH
TUN deviceDSVPN opens /dev/net/tun and uses the TUNSETIFF ioctl with IFF_TUN | IFF_NO_PI to create the interface. If the device node does not exist, load the kernel module first:
sudo modprobe tun
Interface namingOn Linux any valid interface name is accepted (e.g., tun0, vpn0, myvpn). Using auto lets the kernel assign the next available name.Automatic firewall and routing (server)When running as a server, DSVPN executes the following commands automatically:
sysctl net.ipv4.ip_forward=1
ip addr add $LOCAL_TUN_IP peer $REMOTE_TUN_IP dev $IF_NAME
ip -6 addr add $LOCAL_TUN_IP6 peer $REMOTE_TUN_IP6/96 dev $IF_NAME
ip link set dev $IF_NAME up
iptables -t raw -I PREROUTING ! -i $IF_NAME -d $LOCAL_TUN_IP -m addrtype ! --src-type LOCAL -j DROP
iptables -t nat -A POSTROUTING -o $EXT_IF_NAME -s $REMOTE_TUN_IP -j MASQUERADE
iptables -t filter -A FORWARD -i $EXT_IF_NAME -o $IF_NAME -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A FORWARD -i $IF_NAME -o $EXT_IF_NAME -j ACCEPT
Automatic firewall and routing (client)On the client side, DSVPN uses policy routing table 42069 and marks the VPN TCP socket with SO_MARK=42069 to avoid routing loops:
sysctl net.ipv4.tcp_congestion_control=bbr
ip link set dev $IF_NAME up
iptables -t raw -I PREROUTING ! -i $IF_NAME -d $LOCAL_TUN_IP -m addrtype ! --src-type LOCAL -j DROP
ip addr add $LOCAL_TUN_IP peer $REMOTE_TUN_IP dev $IF_NAME
ip -6 addr add $LOCAL_TUN_IP6 peer $REMOTE_TUN_IP6/96 dev $IF_NAME
ip route add default dev $IF_NAME table 42069
ip -6 route add default dev $IF_NAME table 42069
ip rule add not fwmark 42069 table 42069
ip -6 rule add not fwmark 42069 table 42069
ip rule add table main suppress_prefixlength 0
ip -6 rule add table main suppress_prefixlength 0
All rules are automatically removed when DSVPN exits.

Adding support for other platforms

As the DSVPN README notes: “Adding support for other operating systems is trivial.” All platform-specific code is isolated in src/os.c. The two functions to implement are:
  • tun_create() — opens or creates the TUN device and returns a file descriptor. Each platform’s TUN interface has a different device path or socket API, but the interface is a simple int fd in every case.
  • firewall_rules_cmds() — returns two arrays of shell command strings (set and unset) that configure the interface addresses and routing. The strings use substitution tokens such as $IF_NAME, $LOCAL_TUN_IP, and $REMOTE_TUN_IP that DSVPN fills in at runtime.
No changes to the core VPN logic in src/vpn.c are needed for a new platform.
On any BSD platform without full automatic routing support, compile with -DNO_DEFAULT_ROUTES to put DSVPN into point-to-point mode. The TUN interface addresses will still be configured automatically; you can then add whatever routing rules your network topology requires without conflicting with DSVPN’s teardown logic.

Build docs developers (and LLMs) love