diff --git a/flake.lock b/flake.lock index add0a56..44eed20 100644 --- a/flake.lock +++ b/flake.lock @@ -88,11 +88,11 @@ }, "locked": { "dir": "pkgs/firefox-addons", - "lastModified": 1766846533, - "narHash": "sha256-D7XoHk5/daZt3E0K6uCueVxpDYp+cIoCctoTsz5mjfk=", + "lastModified": 1767326613, + "narHash": "sha256-XKeo9F/AB+AyzgR2xaoxyLpI2sRJiu60f9etGJymyMk=", "owner": "rycee", "repo": "nur-expressions", - "rev": "e55ad9427895bc94e55b2cb6474ca46773816885", + "rev": "bc31b4b6220009dc5fda6082496b9d97b1e855ee", "type": "gitlab" }, "original": { @@ -160,11 +160,11 @@ ] }, "locked": { - "lastModified": 1766939458, - "narHash": "sha256-VvZeAKyB3vhyHStSO8ACKzWRKNQPmVWktjfuSVdvtUA=", + "lastModified": 1767280655, + "narHash": "sha256-YmaYMduV5ko8zURUT1VLGDbVC1L/bxHS0NsiPoZ6bBM=", "owner": "nix-community", "repo": "home-manager", - "rev": "e298a148013c980e3c8c0ac075295fab5074d643", + "rev": "d49d2543f02dbd789ed032188c84570d929223cb", "type": "github" }, "original": { @@ -191,11 +191,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1766568855, - "narHash": "sha256-UXVtN77D7pzKmzOotFTStgZBqpOcf8cO95FcupWp4Zo=", + "lastModified": 1767185284, + "narHash": "sha256-ljDBUDpD1Cg5n3mJI81Hz5qeZAwCGxon4kQW3Ho3+6Q=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "c5db9569ac9cc70929c268ac461f4003e3e5ca80", + "rev": "40b1a28dce561bea34858287fbb23052c3ee63fe", "type": "github" }, "original": { @@ -207,11 +207,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1766736597, - "narHash": "sha256-BASnpCLodmgiVn0M1MU2Pqyoz0aHwar/0qLkp7CjvSQ=", + "lastModified": 1767047869, + "narHash": "sha256-tzYsEzXEVa7op1LTnrLSiPGrcCY6948iD0EcNLWcmzo=", "owner": "nixos", "repo": "nixpkgs", - "rev": "f560ccec6b1116b22e6ed15f4c510997d99d5852", + "rev": "89dbf01df72eb5ebe3b24a86334b12c27d68016a", "type": "github" }, "original": { @@ -238,11 +238,11 @@ }, "nixpkgs-unstable": { "locked": { - "lastModified": 1766651565, - "narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=", + "lastModified": 1767116409, + "narHash": "sha256-5vKw92l1GyTnjoLzEagJy5V5mDFck72LiQWZSOnSicw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539", + "rev": "cad22e7d996aea55ecab064e84834289143e44a0", "type": "github" }, "original": { @@ -344,11 +344,11 @@ ] }, "locked": { - "lastModified": 1766000401, - "narHash": "sha256-+cqN4PJz9y0JQXfAK5J1drd0U05D5fcAGhzhfVrDlsI=", + "lastModified": 1767122417, + "narHash": "sha256-yOt/FTB7oSEKQH9EZMFMeuldK1HGpQs2eAzdS9hNS/o=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "42d96e75aa56a3f70cab7e7dc4a32868db28e8fd", + "rev": "dec15f37015ac2e774c84d0952d57fcdf169b54d", "type": "github" }, "original": { @@ -382,11 +382,11 @@ ] }, "locked": { - "lastModified": 1766888861, - "narHash": "sha256-BA+gbbAFYY+z0WvIWu8nwOZYzHuzHbnnIH+R6vjSanI=", + "lastModified": 1767319998, + "narHash": "sha256-YXKjuWf/f6Smvv8qEmSSNpXIV+EXllglMZaMVuChT2Q=", "owner": "nix-community", "repo": "nix-vscode-extensions", - "rev": "2b8957cca4532b30e06c1cbd0386ec4fbf3b16fa", + "rev": "2a8c99844e9e65f6deeee8f1d7e8194998795b41", "type": "github" }, "original": { diff --git a/hosts/desktop/default.nix b/hosts/desktop/default.nix index 1a3f192..503f282 100644 --- a/hosts/desktop/default.nix +++ b/hosts/desktop/default.nix @@ -33,6 +33,7 @@ nebula.node = { enable = true; address = "10.254.250.1"; + isClient = true; }; syncthing = { enable = true; diff --git a/hosts/laptop/default.nix b/hosts/laptop/default.nix index 4eabbf8..73a6c22 100644 --- a/hosts/laptop/default.nix +++ b/hosts/laptop/default.nix @@ -36,6 +36,7 @@ nebula.node = { enable = true; address = "10.254.250.3"; + isClient = true; }; syncthing = { enable = true; diff --git a/hosts/vps-private/default.nix b/hosts/vps-private/default.nix index e63db19..7b2c95d 100644 --- a/hosts/vps-private/default.nix +++ b/hosts/vps-private/default.nix @@ -34,8 +34,9 @@ nebula.node = { enable = true; address = "10.254.250.2"; - isLighthouse = true; routableAddress = "49.13.231.235"; + isLighthouse = true; + isServer = true; }; syncthing = { diff --git a/modules/system/services/nebula/default.nix b/modules/system/services/nebula/default.nix index 54c0884..37aa9db 100644 --- a/modules/system/services/nebula/default.nix +++ b/modules/system/services/nebula/default.nix @@ -6,49 +6,58 @@ }: let cfg = config.custom.services.nebula.node; + peers = config.custom.services.nebula.peers; hostname = config.networking.hostName; - nodes = - self.nixosConfigurations - |> lib.filterAttrs (name: _: name != hostname) - |> lib.attrValues - |> lib.map (value: value.config.custom.services.nebula.node) - |> lib.filter (node: node.enable); + lighthouses = peers |> lib.filter (node: node.isLighthouse); - lighthouses = nodes |> lib.filter (node: node.isLighthouse); - - routableNodes = nodes |> lib.filter (node: node.routableAddress != null); + routablePeers = peers |> lib.filter (node: node.routableAddress != null); in { - options.custom.services.nebula.node = { - enable = lib.mkEnableOption ""; - name = lib.mkOption { - type = lib.types.nonEmptyStr; - default = config.networking.hostName; - }; - address = lib.mkOption { - type = lib.types.nonEmptyStr; - default = ""; - }; - isLighthouse = lib.mkEnableOption ""; + options.custom.services.nebula = { + node = { + enable = lib.mkEnableOption ""; + name = lib.mkOption { + type = lib.types.nonEmptyStr; + default = hostname; + }; + address = lib.mkOption { + type = lib.types.nonEmptyStr; + default = ""; + }; + isLighthouse = lib.mkEnableOption ""; + isServer = lib.mkEnableOption ""; + isClient = lib.mkEnableOption ""; - routableAddress = lib.mkOption { - type = lib.types.nullOr lib.types.nonEmptyStr; - default = null; - }; - routablePort = lib.mkOption { - type = lib.types.nullOr lib.types.port; - default = if cfg.routableAddress != null then 47141 else null; + routableAddress = lib.mkOption { + type = lib.types.nullOr lib.types.nonEmptyStr; + default = null; + }; + routablePort = lib.mkOption { + type = lib.types.nullOr lib.types.port; + default = if cfg.routableAddress != null then 47141 else null; + }; + + publicKeyPath = lib.mkOption { + type = lib.types.path; + default = "${self}/hosts/${hostname}/keys/nebula.pub"; + }; + certificatePath = lib.mkOption { + type = lib.types.path; + default = "${self}/hosts/${hostname}/keys/nebula.crt"; + }; }; - publicKeyPath = lib.mkOption { - type = lib.types.path; - default = "${self}/hosts/${hostname}/keys/nebula.pub"; - }; - certificatePath = lib.mkOption { - type = lib.types.path; - default = "${self}/hosts/${hostname}/keys/nebula.crt"; + peers = lib.mkOption { + type = lib.types.anything; + default = + self.nixosConfigurations + |> lib.filterAttrs (name: _: name != hostname) + |> lib.attrValues + |> lib.map (value: value.config.custom.services.nebula.node) + |> lib.filter (node: node.enable); + readOnly = true; }; }; @@ -61,11 +70,11 @@ in }; sops.secrets."nebula/host-key" = { - owner = config.users.users.nebula-main.name; - restartUnits = [ "nebula@main.service" ]; + owner = config.users.users.nebula-mesh.name; + restartUnits = [ "nebula@mesh.service" ]; }; - services.nebula.networks.main = { + services.nebula.networks.mesh = { enable = true; ca = ./ca.crt; @@ -80,7 +89,7 @@ in ); staticHostMap = - routableNodes + routablePeers |> lib.map (lighthouse: { name = lighthouse.address; value = lib.singleton "${lighthouse.routableAddress}:${toString lighthouse.routablePort}"; @@ -89,14 +98,14 @@ in firewall = { outbound = lib.singleton { - host = "any"; port = "any"; proto = "any"; + host = "any"; }; inbound = lib.singleton { - host = "any"; port = "any"; - proto = "any"; + proto = "icmp"; + host = "any"; }; }; @@ -104,7 +113,10 @@ in pki.disconnect_invalid = true; cipher = "aes"; logging.level = "warning"; + lighthouse.local_allow_list.interfaces.tailscale0 = false; }; }; + + networking.firewall.trustedInterfaces = [ "nebula.mesh" ]; }; } diff --git a/modules/system/services/nebula/sshd.nix b/modules/system/services/nebula/sshd.nix new file mode 100644 index 0000000..3164c45 --- /dev/null +++ b/modules/system/services/nebula/sshd.nix @@ -0,0 +1,45 @@ +{ config, lib, ... }: +let + cfg = config.custom.services.nebula.node; +in +{ + options.custom.services.nebula.node.sshd = { + enable = lib.mkEnableOption "" // { + default = true; + }; + port = lib.mkOption { + type = lib.types.port; + default = 22; + }; + }; + + config = lib.mkIf (cfg.enable && cfg.sshd.enable) { + meta.ports.tcp = [ cfg.sshd.port ]; + + services = { + openssh = { + enable = true; + openFirewall = false; + ports = [ ]; + listenAddresses = lib.singleton { + addr = cfg.address; + inherit (cfg.sshd) port; + }; + }; + + nebula.networks.mesh.firewall.inbound = + config.custom.services.nebula.peers + |> lib.filter (node: node.isClient) + |> lib.map (nebula: { + port = "22"; + proto = "tcp"; + host = nebula.name; + }); + }; + + systemd.services.sshd = { + requires = [ "nebula@mesh.service" ]; + after = [ "nebula@mesh.service" ]; + }; + }; +}