You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
5.2 KiB
Nix
165 lines
5.2 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
with lib;
|
|
let
|
|
has-rekey = config ? rekey;
|
|
peerOpts = {
|
|
options = {
|
|
subnets = mkOption {
|
|
default = [];
|
|
type = with types; listOf str;
|
|
description = ''
|
|
subnets the peer belongs to
|
|
'';
|
|
};
|
|
groups = mkOption {
|
|
default = true;
|
|
type = with types; listOf str;
|
|
description = ''
|
|
groups the peer belongs to
|
|
'';
|
|
};
|
|
peers = {
|
|
default = true;
|
|
type = with types; listOf set;
|
|
description = mdDoc ''
|
|
Peers the peer is connected to, can be one of `{ peer = "peerName"; }`
|
|
or `{ group = "groupname"; }`. Remember to configure this for *both* peers.
|
|
The best way to do this is with a simple full mesh network, where all peers
|
|
belong to one group ("groupA"), and their peers are `{ group = "groupA"}`.
|
|
'';
|
|
};
|
|
privateKeyFile = mkOption {
|
|
example = "/private/wireguard_key";
|
|
type = with types; nullOr str;
|
|
default = null;
|
|
description = mdDoc ''
|
|
Private key file as generated by {command}`wg genkey`.
|
|
'';
|
|
};
|
|
name = mkOption {
|
|
example = "bernd";
|
|
type = types.str;
|
|
description = mdDoc "Unique name for the peer (must be unique for all subdomains this peer is a member of)";
|
|
};
|
|
endpoints = mkOption {
|
|
example = ''
|
|
[
|
|
{match = {}; ip = "192.168.1.10"; port = 51820;} # default case
|
|
{match = {group = "location1"; subnet = "lanNet";}; ip = "192.168.1.10"; port = 51820; }
|
|
{match = {peer = "offSitePeer1";}; ip = "123.123.123.123"; port = 51825; persistentKeepalive = 15;}
|
|
];
|
|
'';
|
|
type = with types; listOf attrset;
|
|
description = mdDoc ''
|
|
The endpoints clients use to reach this host with rules to match by
|
|
group name `match = {group = "groupName";};`
|
|
peer name `match = {peer = "peerName";};`
|
|
or a default match at the end `match = {};`
|
|
All rules in `match` must be true for a match to happen.
|
|
Multiple matches will be merged top to bottom, so rules at the top
|
|
should be your most general rules which get overridden.
|
|
Values other than `match` specify options for the connection,
|
|
possible values are:
|
|
- ip
|
|
- port
|
|
- persistentKeepalive
|
|
- dynamicEndpointRefreshSeconds
|
|
- dynamicEndpointRefreshRestartSeconds
|
|
'';
|
|
};
|
|
publicKey = mkOption {
|
|
example = "xTIBA5rboUvnH4htodjb6e697QjLERt1NAB4mZqp8Dg=";
|
|
type = types.singleLineStr;
|
|
description = mdDoc "The base64 public key of the peer.";
|
|
};
|
|
presharedKeyFile = mkOption {
|
|
default = null;
|
|
example = "/private/wireguard_psk";
|
|
type = with types; nullOr str;
|
|
description = mdDoc ''
|
|
File pointing to preshared key as generated by {command}`wg genpsk`.
|
|
Optional, and may be omitted. This option adds an additional layer of
|
|
symmetric-key cryptography to be mixed into the already existing
|
|
public-key cryptography, for post-quantum resistance.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
subnetOpts = {
|
|
options = {
|
|
name = mkOption {
|
|
default = "wireguard";
|
|
example = "mySubnet.myDomain.me";
|
|
type = types.str;
|
|
description = mdDoc "Unique name for the subnet";
|
|
};
|
|
defaultPort = mkOption {
|
|
example = 51820;
|
|
type = types.int;
|
|
description = mdDoc ''
|
|
The port peers will use when communicating over this subnet.
|
|
Currently there is no way to set the ports for peers individually.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
configOpts = {
|
|
options = {
|
|
subnets = mkOption {
|
|
default = {};
|
|
type = with types; listOf (submodule subnetOpts);
|
|
description = ''
|
|
Subnets in the mesh network(s)
|
|
'';
|
|
};
|
|
peers = mkOption {
|
|
default = {};
|
|
type = with types; listOf (submodule peerOpts);
|
|
description = ''
|
|
Peers in the mesh network(s)
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
in
|
|
{
|
|
options = {
|
|
wirenix = {
|
|
enable = mkOption {
|
|
default = true;
|
|
type = with lib.types; bool;
|
|
description = ''
|
|
Wirenix
|
|
'';
|
|
};
|
|
peerName = mkOption {
|
|
default = config.networking.hostName;
|
|
defaultText = literalExpression "hostName";
|
|
example = "bernd";
|
|
type = types.str;
|
|
description = mdDoc ''
|
|
Name of the peer using this module, to match the name in
|
|
`wirenix.config.peers.*.name`
|
|
'';
|
|
};
|
|
config = mkOption {
|
|
default = {};
|
|
type = with types; setOf (submodule configOpts);
|
|
description = ''
|
|
Shared configuration file that describes all clients
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
# --------------------------------------------------------------- #
|
|
|
|
config = lib.mkIf (config.modules.wirenix.enable) (lib.mkMerge [
|
|
(lib.mkIf (has-rekey) {
|
|
environment.etc.rekey.text = "yes";
|
|
})
|
|
(lib.mkIf (!has-rekey ) {
|
|
environment.etc.rekey.text = "no";
|
|
})
|
|
]);
|
|
} |