dsnet: init at 0.8.1 and init module

Changed files
+262
nixos
modules
services
networking
pkgs
by-name
ds
dsnet
+31
nixos/modules/services/networking/dsnet.md
···
+
# dsnet {#module-services-dsnet}
+
+
dsnet is a CLI tool to manage a centralised wireguard server. It allows easy
+
generation of client configuration, handling key generation, IP allocation etc.
+
+
It keeps its own configuration at `/etc/dsnetconfig.json`, which is more of a
+
database. It contains key material too.
+
+
The way this module works is to patch this database with whatever is configured
+
in the nix service instantiation. This happens automatically when required.
+
+
This way it is possible to decide what to let dnset manage and what parts you
+
want to keep declaratively.
+
+
```
+
services.dsnet = {
+
enable = true;
+
settings = {
+
ExternalHostname = "vpn.example.com";
+
Network = "10.171.90.0/24";
+
Network6 = "";
+
IP = "10.171.90.1";
+
IP6 = "";
+
DNS = "10.171.90.1";
+
Networks = [ "0.0.0.0/0" ];
+
};
+
+
```
+
+
+
See <https://github.com/naggie/dsnet> for more information.
+184
nixos/modules/services/networking/dsnet.nix
···
+
{
+
config,
+
lib,
+
pkgs,
+
...
+
}:
+
+
let
+
cfg = config.services.dsnet;
+
settingsFormat = pkgs.formats.json { };
+
patchFile = settingsFormat.generate "dsnet-patch.json" cfg.settings;
+
in
+
{
+
options.services.dsnet = {
+
enable = lib.mkEnableOption "dsnet, a centralised Wireguard VPN manager";
+
+
package = lib.mkPackageOption pkgs "dsnet" { };
+
+
settings = lib.mkOption {
+
type = lib.types.submodule {
+
+
freeformType = settingsFormat.type;
+
+
options = {
+
ExternalHostname = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
example = "vpn.example.com";
+
description = ''
+
The hostname that clients should use to connect to this server.
+
This is used to generate the client configuration files.
+
+
This is preferred over ExternalIP, as it allows for IPv4 and
+
IPv6, as well as enabling the ability tp change IP.
+
'';
+
};
+
+
ExternalIP = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
example = "192.0.2.1";
+
description = ''
+
The external IP address of the server. This is used to generate
+
the client configuration files for when an ExternalHostname is not set.
+
+
Leaving this empty will cause dsnet to use the IP address of
+
what looks like the WAN interface.
+
'';
+
};
+
+
ExternalIP6 = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
example = "2001:db8::1";
+
description = ''
+
The external IPv6 address of the server. This is used to generate
+
the client configuration files for when an ExternalHostname is
+
not set. Used in preference to ExternalIP.
+
+
Leaving this empty will cause dsnet to use the IP address of
+
what looks like the WAN interface.
+
'';
+
};
+
+
Network = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
example = "172.18.0.0/24";
+
description = ''
+
The IPv4 network that the server will use to allocate IPs on the network.
+
Leave this empty to let dsnet choose a network.
+
'';
+
};
+
+
Network6 = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
example = "2001:db8::1/64";
+
description = ''
+
The IPv6 network that the server will use to allocate IPs on the
+
network.
+
Leave this empty to let dsnet choose a network.
+
'';
+
};
+
+
IP = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
example = "172.18.0.1";
+
description = ''
+
The IPv4 address that the server will use on the network.
+
Leave this empty to let dsnet choose an address.
+
'';
+
};
+
+
IP6 = lib.mkOption {
+
type = lib.types.nullOr lib.types.str;
+
default = null;
+
example = "2001:db8::1";
+
description = ''
+
The IPv6 address that the server will use on the network
+
Leave this empty to let dsnet choose an address.
+
'';
+
};
+
+
Networks = lib.mkOption {
+
type = lib.types.nullOr (lib.types.listOf lib.types.str);
+
default = null;
+
example = [
+
"0.0.0.0/0"
+
"192.168.0.0/24"
+
];
+
description = ''
+
The CIDR networks that should route through this server. Clients
+
will be configured to route traffic for these networks through
+
the server peer.
+
'';
+
};
+
};
+
};
+
+
default = { };
+
description = ''
+
The settings to use for dsnet. This will be converted to a JSON
+
object that will be passed to dsnet as a patch, using the patch
+
command when the service is started. See the dsnet documentation for
+
more information on the additional options.
+
+
Note that the resulting /etc/dsnetconfg.json is more of a database
+
than it is a configuration file. It is therefore recommended that
+
system specific values are configured here, rather than the full
+
configuration including peers.
+
+
Peers may be managed via the dsnet add/remove commands, negating the
+
need to manage key material and cumbersom configuration with nix. If
+
you want peer configuration in nix, you may as well use the regular
+
wireguard module.
+
'';
+
example = {
+
ExternalHostname = "vpn.example.com";
+
ExternalIP = "127.0.0.1";
+
ExternalIP6 = "";
+
ListenPort = 51820;
+
Network = "10.3.148.0/22";
+
Network6 = "";
+
IP = "10.3.148.1";
+
IP6 = "";
+
DNS = "8.8.8.8";
+
Networks = [ "0.0.0.0/0" ];
+
};
+
};
+
};
+
+
config = lib.mkIf cfg.enable {
+
environment.systemPackages = [ cfg.package ];
+
+
systemd.services.dsnet = {
+
description = "dsnet VPN Management";
+
after = [ "network-online.target" ];
+
wants = [ "network-online.target" ];
+
wantedBy = [ "multi-user.target" ];
+
preStart = ''
+
test ! -f /etc/dsnetconfig.json && ${lib.getExe cfg.package} init
+
${lib.getExe cfg.package} patch < ${patchFile}
+
'';
+
serviceConfig = {
+
ExecStart = "${lib.getExe cfg.package} up";
+
ExecStop = "${lib.getExe cfg.package} down";
+
Type = "oneshot";
+
# consider the service to be active after process exits, so it can be
+
# reloaded
+
RemainAfterExit = true;
+
};
+
+
reload = ''
+
${lib.getExe cfg.package} patch < ${patchFile}
+
${lib.getExe cfg.package} sync < ${patchFile}
+
'';
+
+
# reload _instead_ of restarting on change
+
reloadIfChanged = true;
+
};
+
};
+
}
+47
pkgs/by-name/ds/dsnet/package.nix
···
+
{
+
lib,
+
stdenv,
+
fetchFromGitHub,
+
buildGoModule,
+
}:
+
+
buildGoModule (finalAttrs: {
+
pname = "dsnet";
+
version = "0.8.1";
+
+
src = fetchFromGitHub {
+
owner = "naggie";
+
repo = "dsnet";
+
tag = "v${finalAttrs.version}";
+
hash = "sha256-CKDtILZMWFeSU5nTSguM2fi0BCFdvR2LqELIZ6LYOMk=";
+
};
+
vendorHash = "sha256-Q2Ipj9yZ+/GUBEmDvgwFLLww7EXnbvdvj/shGQnh1G8=";
+
+
subPackages = [ "cmd" ];
+
+
postInstall = ''
+
mv $out/bin/cmd $out/bin/dsnet
+
'';
+
+
# The ldflags reduce the executable size by stripping some debug stuff.
+
# The other variables are set so that the output of dsnet version shows the
+
# git ref and the release version from github.
+
# Ref <https://github.com/NixOS/nixpkgs/pull/87383#discussion_r432097657>
+
ldflags = [
+
"-w"
+
"-s"
+
"-X github.com/naggie/dsnet.VERSION=${finalAttrs.src.tag}"
+
"-X github.com/naggie/dsnet.GIT_COMMIT=${finalAttrs.src.tag}"
+
];
+
+
meta = {
+
description = "Fast command to manage a centralised Wireguard VPN";
+
homepage = "https://github.com/naggie/dsnet";
+
changelog = "https://github.com/naggie/dsnet/releases/tag/${finalAttrs.src.tag}";
+
license = lib.licenses.mit;
+
platforms = lib.platforms.linux;
+
maintainers = [ lib.maintainers.naggie ];
+
mainProgram = "dsnet";
+
};
+
+
})