From b4191c56aa7d6926e1dbce1a3901158e7caea4b2 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Thu, 1 Jan 2026 23:46:15 +0100 Subject: [PATCH 1/4] nebula: Configure ssh server --- modules/system/services/nebula/default.nix | 8 +++-- modules/system/services/nebula/sshd.nix | 34 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 modules/system/services/nebula/sshd.nix diff --git a/modules/system/services/nebula/default.nix b/modules/system/services/nebula/default.nix index 54c0884..eb080dc 100644 --- a/modules/system/services/nebula/default.nix +++ b/modules/system/services/nebula/default.nix @@ -61,11 +61,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; @@ -106,5 +106,7 @@ in logging.level = "warning"; }; }; + + 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..857611f --- /dev/null +++ b/modules/system/services/nebula/sshd.nix @@ -0,0 +1,34 @@ +{ 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; + }; + }; + + systemd.services.sshd = { + requires = [ "nebula@mesh.service" ]; + after = [ "nebula@mesh.service" ]; + }; + }; +} From 382dae6cbbb004529273049cb4340e60bc9d52fe Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Fri, 2 Jan 2026 13:12:49 +0100 Subject: [PATCH 2/4] flake.lock: Update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'firefox-addons': 'gitlab:rycee/nur-expressions/e55ad9427895bc94e55b2cb6474ca46773816885?dir=pkgs/firefox-addons&narHash=sha256-D7XoHk5/daZt3E0K6uCueVxpDYp%2BcIoCctoTsz5mjfk%3D' (2025-12-27) → 'gitlab:rycee/nur-expressions/bc31b4b6220009dc5fda6082496b9d97b1e855ee?dir=pkgs/firefox-addons&narHash=sha256-XKeo9F/AB%2BAyzgR2xaoxyLpI2sRJiu60f9etGJymyMk%3D' (2026-01-02) • Updated input 'home-manager': 'github:nix-community/home-manager/e298a148013c980e3c8c0ac075295fab5074d643?narHash=sha256-VvZeAKyB3vhyHStSO8ACKzWRKNQPmVWktjfuSVdvtUA%3D' (2025-12-28) → 'github:nix-community/home-manager/d49d2543f02dbd789ed032188c84570d929223cb?narHash=sha256-YmaYMduV5ko8zURUT1VLGDbVC1L/bxHS0NsiPoZ6bBM%3D' (2026-01-01) • Updated input 'nixos-hardware': 'github:NixOS/nixos-hardware/c5db9569ac9cc70929c268ac461f4003e3e5ca80?narHash=sha256-UXVtN77D7pzKmzOotFTStgZBqpOcf8cO95FcupWp4Zo%3D' (2025-12-24) → 'github:NixOS/nixos-hardware/40b1a28dce561bea34858287fbb23052c3ee63fe?narHash=sha256-ljDBUDpD1Cg5n3mJI81Hz5qeZAwCGxon4kQW3Ho3%2B6Q%3D' (2025-12-31) • Updated input 'nixpkgs': 'github:nixos/nixpkgs/f560ccec6b1116b22e6ed15f4c510997d99d5852?narHash=sha256-BASnpCLodmgiVn0M1MU2Pqyoz0aHwar/0qLkp7CjvSQ%3D' (2025-12-26) → 'github:nixos/nixpkgs/89dbf01df72eb5ebe3b24a86334b12c27d68016a?narHash=sha256-tzYsEzXEVa7op1LTnrLSiPGrcCY6948iD0EcNLWcmzo%3D' (2025-12-29) • Updated input 'nixpkgs-unstable': 'github:nixos/nixpkgs/3e2499d5539c16d0d173ba53552a4ff8547f4539?narHash=sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU%3D' (2025-12-25) → 'github:nixos/nixpkgs/cad22e7d996aea55ecab064e84834289143e44a0?narHash=sha256-5vKw92l1GyTnjoLzEagJy5V5mDFck72LiQWZSOnSicw%3D' (2025-12-30) • Updated input 'treefmt': 'github:numtide/treefmt-nix/42d96e75aa56a3f70cab7e7dc4a32868db28e8fd?narHash=sha256-%2BcqN4PJz9y0JQXfAK5J1drd0U05D5fcAGhzhfVrDlsI%3D' (2025-12-17) → 'github:numtide/treefmt-nix/dec15f37015ac2e774c84d0952d57fcdf169b54d?narHash=sha256-yOt/FTB7oSEKQH9EZMFMeuldK1HGpQs2eAzdS9hNS/o%3D' (2025-12-30) • Updated input 'vscode-extensions': 'github:nix-community/nix-vscode-extensions/2b8957cca4532b30e06c1cbd0386ec4fbf3b16fa?narHash=sha256-BA%2BgbbAFYY%2Bz0WvIWu8nwOZYzHuzHbnnIH%2BR6vjSanI%3D' (2025-12-28) → 'github:nix-community/nix-vscode-extensions/2a8c99844e9e65f6deeee8f1d7e8194998795b41?narHash=sha256-YXKjuWf/f6Smvv8qEmSSNpXIV%2BEXllglMZaMVuChT2Q%3D' (2026-01-02) --- flake.lock | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) 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": { From 61f5c541967326366bd41fc8d5a5e59c8d787141 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Sat, 3 Jan 2026 00:41:13 +0100 Subject: [PATCH 3/4] nebula: Enable firewall and restrict ssh access by role --- hosts/desktop/default.nix | 1 + hosts/laptop/default.nix | 1 + hosts/vps-private/default.nix | 3 +- modules/system/services/nebula/default.nix | 85 ++++++++++++---------- modules/system/services/nebula/sshd.nix | 25 +++++-- 5 files changed, 69 insertions(+), 46 deletions(-) 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 eb080dc..f31502c 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; }; }; @@ -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"; }; }; diff --git a/modules/system/services/nebula/sshd.nix b/modules/system/services/nebula/sshd.nix index 857611f..3164c45 100644 --- a/modules/system/services/nebula/sshd.nix +++ b/modules/system/services/nebula/sshd.nix @@ -16,14 +16,25 @@ in 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; + 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 = { From 2978d2c1a5de76d2f5c0322bc234e87b01c84a27 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Sat, 3 Jan 2026 00:42:02 +0100 Subject: [PATCH 4/4] nebula: Fix tailscale ssh disconnects --- modules/system/services/nebula/default.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/system/services/nebula/default.nix b/modules/system/services/nebula/default.nix index f31502c..37aa9db 100644 --- a/modules/system/services/nebula/default.nix +++ b/modules/system/services/nebula/default.nix @@ -113,6 +113,7 @@ in pki.disconnect_invalid = true; cipher = "aes"; logging.level = "warning"; + lighthouse.local_allow_list.interfaces.tailscale0 = false; }; };