108 lines
3.2 KiB
Nix
108 lines
3.2 KiB
Nix
|
let
|
||
|
src = builtins.fetchGit {
|
||
|
url = "https://git.deuxfleurs.fr/lx/wgautomesh";
|
||
|
rev = "43eced6e9aa5935b4553251604207f72bf0214c1";
|
||
|
};
|
||
|
wgautomesh = (import src).packages.x86_64-linux.default;
|
||
|
in
|
||
|
|
||
|
{ lib, config, pkgs, ... }:
|
||
|
with lib;
|
||
|
let
|
||
|
cfg = config.services.wgautomesh;
|
||
|
in
|
||
|
with builtins;
|
||
|
{
|
||
|
options.services.wgautomesh = {
|
||
|
enable = mkEnableOption "wgautomesh";
|
||
|
interface = mkOption {
|
||
|
type = types.str;
|
||
|
description = "Wireguard interface to manage";
|
||
|
};
|
||
|
gossipPort = mkOption {
|
||
|
type = types.port;
|
||
|
description = "wgautomesh gossip port";
|
||
|
};
|
||
|
lanDiscovery = mkOption {
|
||
|
type = types.bool;
|
||
|
default = true;
|
||
|
description = "Enable discovery using LAN broadcast";
|
||
|
};
|
||
|
openFirewall = mkOption {
|
||
|
type = types.bool;
|
||
|
default = true;
|
||
|
description = "Automatically open gossip port in firewall";
|
||
|
};
|
||
|
upnpForwardPublicPort = mkOption {
|
||
|
type = types.nullOr types.port;
|
||
|
default = null;
|
||
|
description = "Public port number to try to redirect to this machine using UPnP IGD";
|
||
|
};
|
||
|
peers = mkOption {
|
||
|
type = types.listOf (types.submodule {
|
||
|
options = {
|
||
|
pubkey = mkOption {
|
||
|
type = types.str;
|
||
|
description = "Wireguard public key";
|
||
|
};
|
||
|
address = mkOption {
|
||
|
type = types.str;
|
||
|
description = "Wireguard peer address";
|
||
|
};
|
||
|
endpoint = mkOption {
|
||
|
type = types.nullOr types.str;
|
||
|
description = "bootstrap endpoint";
|
||
|
};
|
||
|
};
|
||
|
});
|
||
|
description = "wgautomesh peer list";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = mkIf cfg.enable (
|
||
|
let
|
||
|
peerDefs = map (peer:
|
||
|
let endpointDef = if peer.endpoint == null then ""
|
||
|
else ''endpoint = "${peer.endpoint}"'';
|
||
|
in
|
||
|
''
|
||
|
[[peers]]
|
||
|
pubkey = "${peer.pubkey}"
|
||
|
address = "${peer.address}"
|
||
|
${endpointDef}
|
||
|
'') cfg.peers;
|
||
|
extraDefs = (if cfg.lanDiscovery then ["lan_discovery = true"] else [])
|
||
|
++ (if (cfg.upnpForwardPublicPort != null)
|
||
|
then [''upnp_forward_external_port = ${toString cfg.upnpForwardPublicPort}''] else []);
|
||
|
configfile = pkgs.writeText "wgautomesh.toml" ''
|
||
|
interface = "${cfg.interface}"
|
||
|
gossip_port = ${toString cfg.gossipPort}
|
||
|
|
||
|
${concatStringsSep "\n" (extraDefs ++ peerDefs)}
|
||
|
'';
|
||
|
in {
|
||
|
systemd.services.wgautomesh = {
|
||
|
enable = true;
|
||
|
path = [ pkgs.wireguard-tools ];
|
||
|
environment = {
|
||
|
RUST_LOG = "wgautomesh=info";
|
||
|
};
|
||
|
description = "wgautomesh";
|
||
|
serviceConfig = {
|
||
|
Type = "simple";
|
||
|
|
||
|
ExecStart = "${wgautomesh}/bin/wgautomesh ${configfile}";
|
||
|
Restart = "always";
|
||
|
RestartSec = "30";
|
||
|
|
||
|
DynamicUser = true;
|
||
|
AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||
|
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE";
|
||
|
};
|
||
|
wantedBy = [ "multi-user.target" ];
|
||
|
};
|
||
|
networking.firewall.allowedUDPPorts = mkIf cfg.openFirewall [ cfg.gossipPort ];
|
||
|
});
|
||
|
}
|
||
|
|