dsvpn

jedisct1MIT活跃维护

极简 VPN 实现,用 C 语言写成,代码量小、配置简单,适合快速搭建点对点加密隧道来保护网络流量。

A Dead Simple VPN.

0.1.5发布于 2025-12-19 14:17 UTC5,825star467fork同步于 2026-11-10 17:36 UTC

怎么上手

由 README 提炼,执行前请确认
make
sudo ./dsvpn server vpn.key auto 1959
sudo ./dsvpn client vpn.key 34.216.127.34 1959
硬件要求按 README 说明

README 未说明显存或 GPU 要求;支持 Linux(内核 >= 3.17)、macOS、OpenBSD,以及 DragonFly BSD、FreeBSD、NetBSD 的客户端和点对点模式。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

一个极简 TCP VPN,专为只有 TCP/443 可用的受限网络打通到公网的隧道

极简 VPN 实现,用 C 语言写成,代码量小、配置简单,适合快速搭建点对点加密隧道来保护网络流量。

核心能力

  • 基于 TCP 传输,可在仅开放 TCP/443 的公共 WiFi 下工作
  • 使用经形式化验证的现代密码学实现
  • 内存占用小且恒定,运行时不进行堆内存分配
  • 约 25 KB 单文件,无外部依赖,无需配置文件
  • 客户端阻断 IPv6 以防止重连时泄漏

容易踩的坑

需先用 dd if=/dev/urandom of=vpn.key count=1 bs=32 生成共享密钥并复制到服务端和客户端;默认端口为 443,客户端与服务端的隧道 IP 必须互为反向;原先仅内网可用的 DNS 解析器将无法通过 VPN 访问,需改用公共解析器。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本0.1.5
  1. 0.1.5最新正式版2025-12-19 · 2025-12-19 14:17 UTC
    • Now available in Homebrew - install with brew install dsvpn
    • Install target now automatically creates the sbin directory if needed
    • Added Zig build support
    • Replaced deprecated -Ofast with standard optimization flags
    • Improved documentation

    No major changes, since dsvpn remains secure and rock solid.

  2. 0.1.42019-12-05 · 2019-12-05 23:45 UTC
    查看更新说明
    • Linux: non-local packets for the local VPN IP address are now ignored.
    • If a new client tries to connect while a session is already established, the new session will only replace the current one if it comes from the same IP address.
    • If CFLAGS is empty, supported compilation flags are now automatically detected.
    • Improved help message.
    • If NO_DEFAULT_ROUTES has been defined, default routes will not be installed.
  3. 0.1.32019-08-07 · 2019-08-07 22:27 UTC
    查看更新说明
    • Improved handling of network changes
  4. 0.1.22019-08-04 · 2019-08-04 18:41 UTC
    查看更新说明
    • This should fix reconnection on Linux clients.
  5. 0.1.12019-08-03 · 2019-08-03 21:30 UTC
    查看更新说明
    • Improved client-side firewall rules on Linux
    • Support for DragonFly BSD, FreeBSD and NetBSD

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    DSVPN

    GitHub CI status CodeQL scan

    DSVPN is a Dead Simple VPN, designed to address the most common use case for using a VPN:

    [client device] ---- (untrusted/restricted network) ---- [vpn server] ---- [the Internet]
    

    Features:

    • Runs on TCP. Works pretty much everywhere, including on public WiFi where only TCP/443 is open or reliable.
    • Uses only modern cryptography, with formally verified implementations.
    • Small and constant memory footprint. Doesn't perform any heap memory allocations.
    • Small (~25 KB), with an equally small and readable code base. No external dependencies.
    • Works out of the box. No lousy documentation to read. No configuration file. No post-configuration. Run a single-line command on the server, a similar one on the client and you're done. No firewall and routing rules to manually mess with.
    • Works on Linux (kernel >= 3.17), macOS and OpenBSD, as well as DragonFly BSD, FreeBSD and NetBSD in client and point-to-point modes. Adding support for other operating systems is trivial.
    • Doesn't leak between reconnects if the network doesn't change. Blocks IPv6 on the client to prevent IPv6 leaks.

    Installation

    make
    

    On Raspberry Pi 3 and 4, use the following command instead to enable NEON optimizations:

    env OPTFLAGS=-mfpu=neon make
    

    Alternatively, if you have zig installed, it can be used to compile DSVPN:

    zig build -Drelease
    

    On macOS, DSVPN can be installed using Homebrew: brew install dsvpn.

    Secret key

    DSVPN uses a shared secret. Create it with the following command:

    dd if=/dev/urandom of=vpn.key count=1 bs=32
    

    And copy it on the server and the client.

    If required, keys can be exported and imported in printable form:

    base64 < vpn.key
    echo 'HK940OkWcFqSmZXnCQ1w6jhQMZm0fZoEhQOOpzJ/l3w=' | base64 --decode > vpn.key
    

    Example usage on the server

    sudo ./dsvpn server vpn.key auto 1959
    

    Here, I use port 1959. Everything else is set to the default values. If you want to use the default port (443), it doesn't even have to be specified, so the parameters can just be server vpn.key

    Example usage on the client

    sudo ./dsvpn client vpn.key 34.216.127.34 1959
    

    This is a macOS client, connecting to the VPN server 34.216.127.34 on port 1959. The port number is optional here as well. And the IP can be replaced by a host name.

    That's it

    You are connected. Just hit Ctrl-C to disconnect.

    Evaggelos Balaskas wrote a great blog post walking through the whole procedure: A Dead Simple VPN.

    He also maintains systemd service files for DSVPN. Thank you Evaggelos!

    A note on DNS

    If you were previously using a DNS resolver only accessible from the local network, it won't be accessible through the VPN. That might be the only thing you may have to change. Use a public resolver, a local resolver, or DNSCrypt.

    Or send a pull request implementing the required commands to change and revert the DNS settings, or redirect DNS queries to another resolver, for all supported operating systems.

    Advanced configuration

    dsvpn   "server"
            <key file>
            <vpn server ip or name>|"auto"
            <vpn server port>|"auto"
            <tun interface>|"auto"
            <local tun ip>|"auto"
            <remote tun ip>|"auto"
            <external ip>|"auto"
    
    dsvpn   "client"
            <key file>
            <vpn server ip or name>
            <vpn server port>|"auto"
            <tun interface>|"auto"
            <local tun ip>|"auto"
            <remote tun ip>|"auto"
            <gateway ip>|"auto"
    
    • server|client: use server on the server, and client on clients.
    • <key file>: path to the file with the secret key (e.g. vpn.key).
    • <vpn server ip or name>: on the client, it should be the IP address or the hostname of the server. On the server, it doesn't matter, so you can just use auto.
    • <vpn server port>: the TCP port to listen to/connect to for the VPN. Use 443 or anything else. auto will use 443.
    • <tun interface>: this is the name of the VPN interface. On Linux, you can set it to anything. Or macOS, it has to follow a more boring pattern. If you feel lazy, just use auto here.
    • <local tun ip>: local IP address of the tunnel. Use any private IP address that you don't use here.
    • <remote tun ip>: remote IP address of the tunnel. See above. The local and remote tunnel IPs must the same on the client and on the server, just reversed. For some reason, I tend to pick 192.168.192.254 for the server, and 192.168.192.1 for the client. These values will be used if you put auto for the local and remote tunnel IPs.
    • <external ip> (server only): the external IP address of the server. Can be left to "auto".
    • <gateway ip> (client only): the internal router IP address. The first line printed by netstat -rn will tell you (gateway).

    If all the remaining parameters of a command would be auto, they don't have to be specified.

    Related projects

    Why

    I needed a VPN that works in an environment where only TCP/80 and TCP/443 are open.

    WireGuard doesn't work over TCP.

    GloryTun is excellent, but requires post-configuration and the maintained branch uses UDP.

    I forgot about VTUN-libsodium. But it would have been too much complexity and attack surface for a simple use case.

    OpenVPN is horribly difficult to set up.

    Sshuttle is very nice and I've been using it a lot in the past, but it's not a VPN. It doesn't tunnel non-TCP traffic. It also requires a full Python install, which I'd rather avoid on my router.

    Everything else I looked at was either too difficult to use, slow, bloated, didn't work on macOS, didn't work on small devices, was complicated to cross-compile due to dependencies, wasn't maintained, or didn't feel secure.

    TCP-over-TCP is not as bad as some documents describe. It works surprisingly well in practice, especially with modern congestion control algorithms (BBR). For traditional algorithms that rely on packet loss, DSVPN couples the inner and outer congestion controllers by lowering TCP_NOTSENT_LOWAT and dropping packets when congestion is detected at the outer layer.

    Cryptography

    The cryptographic primitives used in DSVPN are available as a standalone project: Charm.

    Guarantees, support, feature additions

    None.

    This is what I use, because it solves a problem I had. Extending it to solve different problems is not planned, but feel free to fork it and tailor it to your needs!