dsnet: Wireguard Peers With Key Generation and Address Allocation Done
FAST command to manage a centralised wireguard VPN. Think wg-quick but quicker: key generation + address allocation.
At a glance
- What is it?
- dsnet is a MIT licensed Go tool that manages a centralised Wireguard VPN from one JSON file, generating keys, allocating addresses and syncing the interface so a new peer can connect immediately. It suits a small network operator who wants wg-quick without hand-editing peer configs.
- Who is it for?
- dsnet fits an operator of a small Wireguard network who wants adding a peer to be one command rather than a key exchange and a config edit, and who is happy to have the peer private key generated on the server. It is the wrong choice if you need the private key generated on the client, since the documentation is explicit that the server generates it, and the wrong choice for a mesh where no single peer is central.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 159 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem: wg-quick without the manual steps
dsnet is described as a fast command to manage a centralised Wireguard VPN, with the framing that it is like wg-quick but quicker, key generation plus address allocation. The gap it fills is real. In a plain Wireguard setup, adding a peer means generating a key pair, deciding which address to hand out, editing the server configuration, generating a client configuration file, and sending that file to the other person over a channel you trust. dsnet collapses that into a single command, and the readme leads with the outcome rather than the mechanism: set up a VPN in one minute, where the server peer is listening and a client peer config has been generated and added to the server peer. More client peers can then be added with the same command, and they connect immediately.
Installing the binary and bringing the interface up
The quick start assumes AMD64 Linux, wireguard installed, and /usr/local/bin on the path.
sudo wget https://github.com/naggie/dsnet/releases/latest/download/dsnet-linux-amd64 -O /usr/local/bin/dsnet
sudo chmod +x /usr/local/bin/dsnet
sudo dsnet init
# edit /etc/dsnetconfig.json to taste
sudo dsnet upThe init command creates /etc/dsnetconfig.json containing the default configuration plus new keys without loading anything, and the up command creates the interface, runs the pre and post up hooks and syncs. You edit the configuration file between those two steps, which is the one manual moment in the process. The tool also works on ARMv5 as well as AMD64 Linux, and there is a release binary download rather than a build from source, with the source build using a Makefile that produces a static binary with CGO disabled and stripped symbols.
Adding peers and the IP forwarding gotcha
Once the interface is up, adding a peer writes the client configuration to standard output.
sudo dsnet add banana > dsnet-banana.conf
sudo dsnet add apple > dsnet-apple.confThe names are the hostnames, and the generated file is what you send to the device. The documentation adds one operational warning that is easy to skip and that produces a confusing failure: you have to enable IP forwarding to allow peers to talk to one another, and the fix is a sysctl setting.
sudo sysctl -w net.ipv4.ip_forward=1 # edit /etc/sysctl.conf to make this persistent across rebootsWithout it the peers can reach the server but not each other, which looks like a routing fault rather than a missing kernel setting. The command list also shows the full surface, with regenerate for keys and config for a peer, remove by hostname, sync to update the Wireguard configuration from the JSON file after validating, down to destroy the interface, and report to generate a JSON status report.
One JSON file is the whole configuration
The configuration is a single JSON file, and beyond possible initial customisations it is managed entirely by dsnet. dsnetconfig.json is the only file the server needs to run the VPN, and it contains the server keys, peer public and shared keys, and IP settings. A working version is automatically generated by dsnet init and can be modified as required. The top-level fields are the external hostname, the external IPv4 and IPv6 addresses, the listen port, a domain, the interface name, the IPv4 and IPv6 networks, the server's own addresses, an optional DNS setting, a list of extra networks, the server private key, and the PostUp and PostDown hook strings. The peers array holds one object per peer with hostname, owner, description, addresses, an added timestamp, the networks, the public key and a preshared key.
The key generation trade-off, stated plainly
There is one security compromise in the design and the documentation is upfront about it. The peer private key is generated on the server, which is technically not as secure as generating it on the client peer and then providing the server the public key. The tool does provide for specifying a public key in the code when adding a peer, to avoid the server generating the private key, but the feature is described as one that will be added when requested. So today, the convenience of a one-command onboarding means the server briefly holds a private key it does not need to hold. For a network of friends or a small company that is usually an acceptable trade, and for a larger deployment with a real key management policy it is the thing to work around first. The document also notes that named arguments can be specified on the command line as well as entered by prompt, which allows for unattended usage.
Sending configurations without a trusted channel
The generated configuration contains a private key, so how it reaches the device matters, and the readme offers three suggestions with different properties. ffsend is the most straightforward option, magic wormhole is a more advanced one where the file never passes through another server, and wormhole-william is a Go implementation of that approach. The instruction that follows applies to all of them: the password should be transferred separately. A local QR code generator such as qrencode can also be used to produce a QR code of the configuration, for instance by piping the add command into it.
dsnet add | qrencode -t ansiutf8That works because the dsnet prompts are written to standard error and are not passed to qrencode, so the code contains only the configuration and not the text of the questions. That separation of streams is a small implementation detail that makes the whole trick work, and it is the kind of thing worth checking in your own tooling if you plan to pipe dsnet output somewhere.
The report file, the config formats and the GUI
A separate report command generates a JSON status report to stdout, and a suggested location is /var/lib/dsnetreport.json. The example shows the external address, interface, port, domain, server address, network, DNS, and a peers count with the online and total figures, plus receive and transmit byte counters in both raw and human-readable units, and then a per-peer array with hostname, owner, description, an online flag, a dormant flag, the added timestamp, the addresses and the external IP. The command line also has an --output flag choosing the config file format, with vyatta, wg-quick and nixos as the options and wg-quick as the default, which is what makes the tool usable on EdgeOS and Vyatta routers, since the topic tags include edgeos, edgerouter and vyatta. Dsnet itself does not include or require a GUI, though there is a separate official monitoring GUI at the dsnet-gui repository.
Maintenance, packaging and the project's own reach
The project is a Go module requiring Go 1.16, with the dependency list showing the shape of the work: cobra and viper for the command line and configuration, netlink for talking to the kernel, wgctrl for controlling Wireguard, the go-playground validator for checking the configuration file, and a wireguard-go module. The repository has a cmd/ directory for the command tree, a lib/ directory, an etc/ directory holding the logo and images, a contrib/ directory, a utils/ directory, a shell.nix for a Nix shell, and CONFIG.md as the field-by-field reference. There is a repology badge showing the packaging status across distributions, which is the practical way to install it if you would rather not run a downloaded binary. The releases are v0.7.3 from 2022, then v0.8.0 and v0.8.1 in May 2025, and the last push was on 2026-05-17, so the tool is maintained but releases slowly.
Editorial conclusion
dsnet fits an operator of a small Wireguard network who wants adding a peer to be one command rather than a key exchange and a config edit, and who is happy to have the peer private key generated on the server. It is the wrong choice if you need the private key generated on the client, since the documentation is explicit that the server generates it, and the wrong choice for a mesh where no single peer is central. Before you onboard anyone, read the key generation note and the IP forwarding requirement, since both change what your users have to do.
Frequently asked questions
What does dsnet do that wg-quick does not?
It handles key generation and address allocation along with the configuration, so adding a peer is one command that writes a client config to standard output and adds the peer to the server, and the new peer can connect immediately.
How do I install and start dsnet?
Download the release binary to /usr/local/bin and make it executable, then run dsnet init to create /etc/dsnetconfig.json, edit that file, and run dsnet up to create the interface and sync. It works on AMD64 Linux and also ARMv5.
What must I configure for peers to reach each other?
IP forwarding has to be enabled on the server with sysctl -w net.ipv4.ip_forward=1, made persistent in /etc/sysctl.conf. Without it peers can reach the server but not each other.
Where is the peer private key generated?
On the server, which the documentation says is technically not as secure as generating it on the client peer and providing the server the public key. There is provision to specify a public key in the code when adding a peer to avoid this.
Which configuration file formats does dsnet output?
The --output flag chooses between vyatta, wg-quick and nixos, with wg-quick as the default. There is also a report command that writes a JSON status report with peer counts, byte counters and per-peer state.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/naggie-dsnet)Was this useful?