blob: 4d76a324cddecd85fc7a1a56b97d573c67e796b1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
{ config, lib, ... }:
let
cfg = config.services.codewreck.wireguard;
in {
options.services.codewreck.wireguard = {
enabled = lib.mkOption {
description = "enabled (on by default if local machine description is found, don't blame me if you enable it without one)";
default = builtins.hasAttr cfg.hostname cfg.machines;
type = lib.types.bool;
};
domain = lib.mkOption {
description = "domain (used to shorten hosts for config and /etc/hosts";
default = config.networking.domain;
type = lib.types.str;
};
hostname = lib.mkOption {
description = "short part of the hostname (select wireguard config from configs)";
default = lib.removeSuffix ".${config.networking.domain}" config.networking.hostName;
type = lib.types.str;
};
machines = lib.mkOption {
description = "attr of machine configuration";
default = {};
example = {
jormungand = {
ip = "fd13:537e:dbbf:1210::1";
endpoint = "jormungand.codewreck.org";
listenPort = 51733;
publicKey = "Hx5RnhfyP91LEgXAn4pLiOm4nMRZvVx+rsX0YhVzqAQ=";
};
odin = {
ip = "fd13:537e:dbbf:1210::2";
allowedIPs = [ "fd13:537e:dbbf:1211::/64" "10.17.42.0/24" ];
endpoint = "gaia.codewreck.org";
listenPort = 51432;
publicKey = "7YALjkbDv6iId1VHJu4uTgVAj41VvAoQfaiVChJdZQ8=";
};
fenrir = {
ip = "fd13:537e:dbbf:1210::3";
allowedIPs = [ "fd13:537e:dbbf:1213::/64" "10.42.17.0/24" ];
publicKey = "SrLUKqoxYxFriLDenMwNHLqetxVCLmyCG606hg3h9mQ=";
listenPort = 51123;
keepalive = 55;
};
};
type = lib.types.attrsOf (lib.types.submodule { options = {
ip = lib.mkOption {
description = "ip is used both to configure interface if target and for allowed IPs";
type = lib.types.str;
};
allowedIPs = lib.mkOption {
description = "extra list of allowed IPs for wg";
default = [];
type = lib.types.listOf lib.types.str;
};
publicKey = lib.mkOption {
description = "wg public key";
type = lib.types.str;
};
listenPort = lib.mkOption {
description = "wg port (actual listen-port, firewall and endpoint)";
type = lib.types.int;
};
endpoint = lib.mkOption {
description = "wg endpoint without port component (taken from mandatory listenPort)";
default = null;
type = lib.types.nullOr lib.types.str;
};
keepalive = lib.mkOption {
description = "wg keepalive for all peers if present on current machine";
default = null;
type = lib.types.nullOr lib.types.int;
};
only = lib.mkOption {
description = "limit to single server";
default = null;
type = lib.types.nullOr lib.types.str;
};
};});
};
};
config = let
current = builtins.getAttr cfg.hostname cfg.machines;
others = builtins.removeAttrs cfg.machines [ cfg.hostname ];
peers = lib.mapAttrsToList (name: value: {
allowedIPs = [ value.ip ] ++ value.allowedIPs;
publicKey = value.publicKey;
endpoint = (if value.endpoint != null then value.endpoint + ":" + (toString value.listenPort) else null);
persistentKeepalive = current.keepalive;
}) (lib.filterAttrs (n: v:
current.only == n
|| (current.only == null &&
(v.endpoint != null ||
(current.endpoint != null && (v.only == null || v.only == cfg.hostname))
)
))
others);
hosts = lib.mapAttrs' (name: value: lib.attrsets.nameValuePair
(builtins.head (builtins.split "/" value.ip)) [ (name + ".wg.${cfg.domain}") (name + ".wg") ]
) others;
in
lib.mkIf cfg.enabled {
networking.wireguard.interfaces.wg0 = {
ips = [ current.ip ];
listenPort = current.listenPort;
privateKeyFile = "/etc/nixos/secrets/wg0.key";
peers = peers;
};
networking.hosts = hosts;
networking.firewall.allowedUDPPorts = [ current.listenPort ];
};
}
|