[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6540":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":14,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":16,"compositeScore":18,"rankGlobal":9,"rankLanguage":9,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":9,"pushedAt":9,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":15,"starSnapshotCount":15,"syncStatus":31,"lastSyncTime":32,"discoverSource":33},6540,"dsvpn","jedisct1\u002Fdsvpn","jedisct1","A Dead Simple VPN.",null,"C",5688,452,110,1,0,3,365,38.97,"MIT License",false,"master",true,[24,25,26,27],"privacy","reallysimple","simple","vpn","2026-06-12 02:01:26","# ![DSVPN](https:\u002F\u002Fraw.github.com\u002Fjedisct1\u002Fdsvpn\u002Fmaster\u002Flogo.png)\n\n[![GitHub CI status](https:\u002F\u002Fgithub.com\u002Fjedisct1\u002Fdsvpn\u002Fworkflows\u002FCI\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fjedisct1\u002Fdsvpn\u002Factions)\n![CodeQL scan](https:\u002F\u002Fgithub.com\u002Fjedisct1\u002Fdsvpn\u002Fworkflows\u002FCodeQL%20scan\u002Fbadge.svg)\n\nDSVPN is a Dead Simple VPN, designed to address the most common use case for using a VPN:\n\n```text\n[client device] ---- (untrusted\u002Frestricted network) ---- [vpn server] ---- [the Internet]\n```\n\nFeatures:\n\n* Runs on TCP. Works pretty much everywhere, including on public WiFi where only TCP\u002F443 is open or reliable.\n* Uses only modern cryptography, with formally verified implementations.\n* Small and constant memory footprint. Doesn't perform any heap memory allocations.\n* Small (~25 KB), with an equally small and readable code base. No external dependencies.\n* 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.\n* 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.\n* Doesn't leak between reconnects if the network doesn't change. Blocks IPv6 on the client to prevent IPv6 leaks.\n\n## Installation\n\n```sh\nmake\n```\n\nOn Raspberry Pi 3 and 4, use the following command instead to enable NEON optimizations:\n\n```sh\nenv OPTFLAGS=-mfpu=neon make\n```\n\nAlternatively, if you have [zig](https:\u002F\u002Fziglang.org) installed, it can be used to compile DSVPN:\n\n```sh\nzig build -Drelease\n```\n\nOn macOS, DSVPN can be installed using Homebrew: `brew install dsvpn`.\n\n## Secret key\n\nDSVPN uses a shared secret. Create it with the following command:\n\n```sh\ndd if=\u002Fdev\u002Furandom of=vpn.key count=1 bs=32\n```\n\nAnd copy it on the server and the client.\n\nIf required, keys can be exported and imported in printable form:\n\n```sh\nbase64 \u003C vpn.key\necho 'HK940OkWcFqSmZXnCQ1w6jhQMZm0fZoEhQOOpzJ\u002Fl3w=' | base64 --decode > vpn.key\n```\n\n## Example usage on the server\n\n```sh\nsudo .\u002Fdsvpn server vpn.key auto 1959\n```\n\nHere, 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`\n\n## Example usage on the client\n\n```sh\nsudo .\u002Fdsvpn client vpn.key 34.216.127.34 1959\n```\n\nThis 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.\n\n## That's it\n\nYou are connected. Just hit `Ctrl`-`C` to disconnect.\n\nEvaggelos Balaskas wrote a great blog post walking through the whole procedure: [A Dead Simple VPN](https:\u002F\u002Fbalaskas.gr\u002Fblog\u002F2019\u002F07\u002F20\u002Fa-dead-simple-vpn\u002F).\n\nHe also maintains [systemd service files for DSVPN](https:\u002F\u002Fgithub.com\u002Febal\u002Fscripts\u002Ftree\u002Fmaster\u002Fdsvpn). Thank you Evaggelos!\n\n## A note on DNS\n\nIf 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.\n\nOr 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.\n\n## Advanced configuration\n\n```text\ndsvpn   \"server\"\n        \u003Ckey file>\n        \u003Cvpn server ip or name>|\"auto\"\n        \u003Cvpn server port>|\"auto\"\n        \u003Ctun interface>|\"auto\"\n        \u003Clocal tun ip>|\"auto\"\n        \u003Cremote tun ip>|\"auto\"\n        \u003Cexternal ip>|\"auto\"\n\ndsvpn   \"client\"\n        \u003Ckey file>\n        \u003Cvpn server ip or name>\n        \u003Cvpn server port>|\"auto\"\n        \u003Ctun interface>|\"auto\"\n        \u003Clocal tun ip>|\"auto\"\n        \u003Cremote tun ip>|\"auto\"\n        \u003Cgateway ip>|\"auto\"\n```\n\n* `server`|`client`: use `server` on the server, and `client` on clients.\n* `\u003Ckey file>`: path to the file with the secret key (e.g. `vpn.key`).\n* `\u003Cvpn 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`.\n* `\u003Cvpn server port>`: the TCP port to listen to\u002Fconnect to for the VPN. Use 443 or anything else. `auto` will use `443`.\n* `\u003Ctun 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.\n* `\u003Clocal tun ip>`: local IP address of the tunnel. Use any private IP address that you don't use here.\n* `\u003Cremote 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.\n* `\u003Cexternal ip>` (server only): the external IP address of the server. Can be left to `\"auto\"`.\n* `\u003Cgateway ip>` (client only): the internal router IP address. The first line printed by `netstat -rn` will tell you (`gateway`).\n\nIf all the remaining parameters of a command would be `auto`, they don't have to be specified.\n\n## Related projects\n\n* [dsvpn-ios](https:\u002F\u002Fgithub.com\u002Fjedisct1\u002Fdsvpn-ios) is an iOS client for DSVPN\n* Robert Debock maintains [an Ansible role for DSVPN](https:\u002F\u002Fgithub.com\u002Frobertdebock\u002Fansible-role-dsvpn)\n* [OpenMPTCProuter](http:\u002F\u002Fwww.openmptcprouter.com\u002F) is an OpenWrt-based router OS that supports DSVPN\n* Yecheng Fu maintains a [Docker image for DSVPN](https:\u002F\u002Fgithub.com\u002Fcofyc\u002Fdsvpn-docker)\n\n## Why\n\nI needed a VPN that works in an environment where only TCP\u002F80 and TCP\u002F443 are open.\n\nWireGuard doesn't work over TCP.\n\n[GloryTun](https:\u002F\u002Fgithub.com\u002Fangt\u002Fglorytun) is excellent, but requires post-configuration and the maintained branch uses UDP.\n\nI forgot about [VTUN-libsodium](https:\u002F\u002Fgithub.com\u002Fjedisct1\u002Fvtun). But it would have been too much complexity and attack surface for a simple use case.\n\nOpenVPN is horribly difficult to set up.\n\nSshuttle 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.\n\nEverything 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.\n\nTCP-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.\n\n## Cryptography\n\nThe cryptographic primitives used in DSVPN are available as a standalone project: [Charm](https:\u002F\u002Fgithub.com\u002Fjedisct1\u002Fcharm).\n\n## Guarantees, support, feature additions\n\nNone.\n\nThis 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!\n","DSVPN 是一个极其简单的虚拟私人网络（VPN）解决方案。它基于TCP运行，几乎可以在任何地方使用，包括仅开放或可靠TCP\u002F443端口的公共WiFi环境；采用现代加密技术，并且有正式验证的实现；内存占用小且固定，不进行堆内存分配；代码量少（约25KB），易于阅读理解，无外部依赖；无需复杂配置即可直接使用，支持Linux、macOS及多种BSD系统，增加对其他操作系统支持也很容易；在网络未改变的情况下重连时不会泄露信息，并在客户端阻止IPv6以防止泄漏。适用于需要快速搭建安全连接但又不想处理复杂设置的场景，如个人隐私保护、远程工作等。",2,"2026-06-11 03:07:32","top_language"]