diff options
-rwxr-xr-x | deploy.sh | 3 | ||||
-rw-r--r-- | nix/configuration.nix | 8 | ||||
-rw-r--r-- | nix/wesher_service.nix | 122 |
3 files changed, 132 insertions, 1 deletions
@@ -42,6 +42,7 @@ for NIXHOST in $NIXHOSTLIST; do cat nix/deuxfleurs.nix | ssh -F $SSH_CONFIG $SSH_DEST tee $TMP_PATH/deuxfleurs.nix > /dev/null cat nix/remote-unlock.nix | ssh -F $SSH_CONFIG $SSH_DEST tee $TMP_PATH/remote-unlock.nix > /dev/null cat nix/wesher.nix | ssh -F $SSH_CONFIG $SSH_DEST tee $TMP_PATH/wesher.nix > /dev/null + cat nix/wesher_service.nix | ssh -F $SSH_CONFIG $SSH_DEST tee $TMP_PATH/wesher_service.nix > /dev/null cat cluster/$CLUSTER/cluster.nix | ssh -F $SSH_CONFIG $SSH_DEST tee $TMP_PATH/cluster.nix > /dev/null cat cluster/$CLUSTER/node/$NIXHOST.nix | ssh -F $SSH_CONFIG $SSH_DEST tee $TMP_PATH/node.nix > /dev/null cat cluster/$CLUSTER/node/$NIXHOST.site.nix | ssh -F $SSH_CONFIG $SSH_DEST tee $TMP_PATH/site.nix > /dev/null @@ -59,7 +60,7 @@ for NIXHOST in $NIXHOSTLIST; do set -ex cd $TMP_PATH -mv deuxfleurs.nix remote-unlock.nix wesher.nix configuration.nix cluster.nix node.nix site.nix /etc/nixos +mv deuxfleurs.nix remote-unlock.nix wesher.nix wesher_service.nix configuration.nix cluster.nix node.nix site.nix /etc/nixos nixos-rebuild switch 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 ]; + }); +} |