From db081fad0e3b3933ca963fae085fd0c5c0764f80 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 19 Apr 2022 22:03:58 +0200 Subject: First working Wesher configuration --- nix/configuration.nix | 8 ++++ nix/wesher_service.nix | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 nix/wesher_service.nix (limited to 'nix') diff --git a/nix/configuration.nix b/nix/configuration.nix index 2255d7d..8af35e9 100644 --- a/nix/configuration.nix +++ b/nix/configuration.nix @@ -11,6 +11,8 @@ ./hardware-configuration.nix # Include generic Deuxfleurs module ./deuxfleurs.nix + # Wesher module + ./wesher_service.nix # Configuration for this deployment (a cluster) ./cluster.nix # Configuration local for this Deuxfleurs site (set of nodes) @@ -79,6 +81,12 @@ SystemMaxUse=1G services.openssh.enable = true; services.openssh.passwordAuthentication = false; + services.wesher = { + enable = true; + join = [ "192.168.1.22" "192.168.1.23" ]; + bindAddr = config.deuxfleurs.lan_ip; # for now + }; + # ---- CONFIG FOR DEUXFLEURS CLUSTER ---- # Open ports in the firewall. diff --git a/nix/wesher_service.nix b/nix/wesher_service.nix new file mode 100644 index 0000000..be33a76 --- /dev/null +++ b/nix/wesher_service.nix @@ -0,0 +1,122 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.wesher; + +in { + options = with types; { + services.wesher = { + enable = mkEnableOption "wesher wireguard overlay mesh network manager"; + + package = mkOption { + type = package; + default = pkgs.wesher; + defaultText = literalExpression "pkgs.wesher"; + description = "Wesher package to use."; + }; + + clusterKey = mkOption { + type = nullOr str; + default = null; + description = "shared key for cluster membership; must be 32 bytes base64 encoded; will be generated if not provided"; + }; + + bindAddr = mkOption { + type = nullOr str; + default = null; + description = "IP address to bind to for cluster membership (cannot be used with --bind-iface)"; + }; + + bindIface = mkOption { + type = nullOr str; + default = null; + description = "Interface to bind to for cluster membership (cannot be used with --bind-addr)"; + }; + + join = mkOption { + type = listOf str; + default = []; + description = "list of hostnames or IP addresses to existing cluster members; if not provided, will attempt resuming any known state or otherwise wait for further members"; + }; + + clusterPort = mkOption { + type = port; + default = 7946; + description = "port used for membership gossip traffic (both TCP and UDP); must be the same accross cluster"; + }; + + wireguardPort = mkOption { + type = port; + default = 51820; + description = "port used for wireguard traffic (UDP); must be the same accross cluster"; + }; + + overlayNet = mkOption { + type = str; + default = "10.0.0.0/8"; + description = "the network in which to allocate addresses for the overlay mesh network (CIDR format); smaller networks increase the chance of IP collision"; + }; + + interface = mkOption { + type = str; + default = "wgoverlay"; + description = "name of the wireguard interface to create and manage"; + }; + + logLevel = mkOption { + type = str; + default = "warn"; + description = "set the verbosity (one of debug/info/warn/error)"; + }; + + }; + }; + + config = mkIf cfg.enable (let binWesher = cfg.package + "/bin/wesher"; + in { + systemd.services.wesher = { + description = "wesher wireguard overlay mesh network manager"; + bindsTo = [ "network-online.target" ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + + environment = { + WESHER_JOIN = builtins.concatStringsSep "," cfg.join; + WESHER_CLUSTER_PORT = builtins.toString cfg.clusterPort; + WESHER_WIREGUARD_PORT = builtins.toString cfg.wireguardPort; + WESHER_OVERLAY_NET = cfg.overlayNet; + WESHER_INTERFACE = cfg.interface; + WESHER_LOG_LEVEL = cfg.logLevel; + WESHER_NO_ETC_HOSTS = "true"; + } + // (if (cfg.clusterKey != null) then { WESHER_CLUSTER_KEY = cfg.clusterKey; } else {}) + // (if (cfg.bindAddr != null) then { WESHER_BIND_ADDR = cfg.bindAddr; } else {}) + // (if (cfg.bindIface != null) then { WESHER_BIND_IFACE = cfg.bindIface; } else {}) + ; + + serviceConfig = { + ExecStart = "${binWesher}"; + Restart = "always"; + + User = "wesher"; + DynamicUser = true; + StateDirectory = "wesher"; + + AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE"; + CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE"; + MemoryDenyWriteExecute = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK"; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + SystemCallFilter = "~@clock @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @resources"; + }; + }; + + networking.firewall.allowedUDPPorts = mkIf cfg.enable [ cfg.clusterPort cfg.wireguardPort ]; + networking.firewall.allowedTCPPorts = mkIf cfg.enable [ cfg.clusterPort ]; + }); +} -- cgit v1.2.3