From 1ef584f8005dfdd1ca2be35f58c53668fa0d5e17 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 7 Nov 2025 23:54:02 -0600 Subject: [PATCH] test: vaultwarden microVM --- flake.nix | 1 + .../config/instances/config/vaultwarden.nix | 2 +- modules/nixos/services/forgejo/default.nix | 2 +- .../nixos/services/vaultwarden/default.nix | 116 +------------ .../vaultwarden/vaultwardenCeres/default.nix | 5 + systems/ceres/config/networking.nix | 36 ++++ systems/ceres/default.nix | 11 +- systems/ceres/microvms/vaultwarden.nix | 158 ++++++++++++++++++ 8 files changed, 218 insertions(+), 113 deletions(-) create mode 100755 modules/nixos/services/vaultwarden/vaultwardenCeres/default.nix create mode 100755 systems/ceres/microvms/vaultwarden.nix diff --git a/flake.nix b/flake.nix index 2b892b4..b8db17b 100755 --- a/flake.nix +++ b/flake.nix @@ -153,6 +153,7 @@ inputs.home-manager.nixosModules.home-manager inputs.impermanence.nixosModules.impermanence # inputs.lix-module.nixosModules.default + inputs.microvm.nixosModules.host inputs.sops-nix.nixosModules.sops ]; eris = inputs.self.lib.mkLinuxSystem [ diff --git a/modules/config/instances/config/vaultwarden.nix b/modules/config/instances/config/vaultwarden.nix index c530caf..d7cbaab 100755 --- a/modules/config/instances/config/vaultwarden.nix +++ b/modules/config/instances/config/vaultwarden.nix @@ -39,7 +39,7 @@ in mac = "02:00:00:00:00:51"; idUser = "vmuser-vault"; macUser = "02:00:00:00:00:03"; - ip = "192.168.50.51"; + ip = "192.168.50.151"; gate = "192.168.50.1"; ssh = 2201; }; diff --git a/modules/nixos/services/forgejo/default.nix b/modules/nixos/services/forgejo/default.nix index c26f677..fa78f3f 100755 --- a/modules/nixos/services/forgejo/default.nix +++ b/modules/nixos/services/forgejo/default.nix @@ -236,7 +236,7 @@ in secrets = builtins.listToAttrs ( map (secret: { - name = "${service.name}-${secret}"; + name = "${service.name}/${secret}"; # it's vaultwarden/env, not vaultwarden-env value = sopsPath secret; }) [ diff --git a/modules/nixos/services/vaultwarden/default.nix b/modules/nixos/services/vaultwarden/default.nix index 5344629..4dafdfa 100755 --- a/modules/nixos/services/vaultwarden/default.nix +++ b/modules/nixos/services/vaultwarden/default.nix @@ -1,115 +1,11 @@ -{ - flake, - config, - lib, - ... -}: let - inherit (flake.config.services) instances; - service = instances.vaultwarden; - localhost = instances.web.localhost.address0; - host = service.domains.url0; - syncthing = instances.syncthing; - - backupPath = "${syncthing.paths.path1}/${service.name}"; + inherit (import ../../../helpers.nix) directoryImport; + modules = directoryImport ./.; in { - services = { - vaultwarden = { - backupDir = backupPath; - enable = true; - environmentFile = config.sops.secrets."${service.name}/env".path; - config = { - # Domain Configuration - DOMAIN = "https://${host}"; - - # Email Configuration - SMTP_AUTH_MECHANISM = "Plain"; - SMTP_EMBED_IMAGES = true; - SMTP_FROM = instances.smtp.email.address0; - SMTP_FROM_NAME = service.label; - SMTP_HOST = instances.smtp.hostname; - SMTP_PORT = instances.smtp.ports.port1; - SMTP_SECURITY = instances.smtp.records.record1; - SMTP_USERNAME = instances.smtp.email.address0; - - # Security Configuration - DISABLE_ADMIN_TOKEN = false; - - # Event and Backup Management - EVENTS_DAYS_RETAIN = 90; - - # User Features - SENDS_ALLOWED = true; - SIGNUPS_VERIFY = true; - WEB_VAULT_ENABLED = true; - - # Rocket (Web Server) Settings - ROCKET_ADDRESS = localhost; - ROCKET_PORT = service.ports.port0; - }; - }; - caddy = { - virtualHosts = { - "${host}" = { - extraConfig = '' - reverse_proxy ${localhost}:${toString service.ports.port0} { - header_up X-Real-IP {remote_host} - } - - tls ${service.ssl.cert} ${service.ssl.key} - - encode zstd gzip - ''; - }; - }; - }; - }; - - sops = - let - sopsPath = secret: { - path = "${service.sops.path0}/${service.name}-${secret}"; - owner = service.name; - mode = "600"; - }; - in - { - secrets = builtins.listToAttrs ( - map - (secret: { - name = "${service.name}/${secret}"; - value = sopsPath secret; - }) - [ - "env" - ] - ); - }; - - systemd = { - tmpfiles.rules = [ - "Z ${service.paths.path0} 0755 ${service.name} ${service.name} -" - "Z ${service.sops.path0} 755 ${service.name} ${service.name} -" - ]; - services.backup-vaultwarden = { - serviceConfig = { - Group = lib.mkForce syncthing.name; - }; - wantedBy = lib.mkForce [ ]; - after = [ "${service.name}.service" ]; - }; - }; - - users.users.${service.name}.extraGroups = [ - syncthing.name - ]; - - networking = { - firewall = { - allowedTCPPorts = [ - service.ports.port0 - ]; - }; + imports = builtins.attrValues { + inherit (modules) + vaultwardenCeres + ; }; } diff --git a/modules/nixos/services/vaultwarden/vaultwardenCeres/default.nix b/modules/nixos/services/vaultwarden/vaultwardenCeres/default.nix new file mode 100755 index 0000000..fb758a6 --- /dev/null +++ b/modules/nixos/services/vaultwarden/vaultwardenCeres/default.nix @@ -0,0 +1,5 @@ +{ ... }: +{ + # Ensure Caddy can access the ACME certificates + users.users.caddy.extraGroups = [ "acme" ]; +} diff --git a/systems/ceres/config/networking.nix b/systems/ceres/config/networking.nix index 5e51bdf..14c9e78 100755 --- a/systems/ceres/config/networking.nix +++ b/systems/ceres/config/networking.nix @@ -9,6 +9,42 @@ let wireguardService = instances.wireGuard; in { + # Enable microVM host + microvm.host.enable = true; + + # systemd-networkd for bridge management + systemd.network.enable = true; + + # Bridge configuration for microVMs + systemd.network.netdevs."10-br-vms" = { + netdevConfig = { + Name = "br-vms"; + Kind = "bridge"; + }; + }; + + # Attach physical interface and tap interfaces to bridge + systemd.network.networks."20-lan" = { + matchConfig.Name = [ + "enp10s0" + "vm-*" + ]; + networkConfig = { + Bridge = "br-vms"; + }; + }; + + # Bridge gets the host IP + systemd.network.networks."30-br-vms" = { + matchConfig.Name = "br-vms"; + networkConfig = { + Address = "192.168.50.240/24"; + Gateway = "192.168.50.1"; + DNS = [ "192.168.50.1" ]; + }; + linkConfig.RequiredForOnline = "routable"; + }; + networking = { hostName = ceres.name; # NetworkManager disabled - using systemd-networkd for bridge management diff --git a/systems/ceres/default.nix b/systems/ceres/default.nix index d1f0003..74ed872 100755 --- a/systems/ceres/default.nix +++ b/systems/ceres/default.nix @@ -1,6 +1,7 @@ { lib, ... }: let configPath = ./config; + microVMsPath = ./microvms; ceresImports = let @@ -9,9 +10,17 @@ let map (name: configPath + "/${name}") ( builtins.filter (name: builtins.match ".*\\.nix$" name != null) files ); + + microVMImports = + let + files = builtins.attrNames (builtins.readDir microVMsPath); + in + map (name: microVMsPath + "/${name}") ( + builtins.filter (name: builtins.match ".*\\.nix$" name != null) files + ); in { - imports = ceresImports; + imports = ceresImports ++ microVMImports; nixpkgs.hostPlatform = lib.mkForce "x86_64-linux"; system.stateVersion = lib.mkForce "24.05"; } diff --git a/systems/ceres/microvms/vaultwarden.nix b/systems/ceres/microvms/vaultwarden.nix new file mode 100755 index 0000000..1bf7998 --- /dev/null +++ b/systems/ceres/microvms/vaultwarden.nix @@ -0,0 +1,158 @@ +{ + config, + lib, + pkgs, + flake, + ... +}: +let + vaultwardenCfg = flake.config.services.instances.vaultwarden; + smtpCfg = flake.config.services.instances.smtp; + inherit (flake.config.people) user0; +in +{ + microvm.vms.vaultwarden = { + autostart = true; + restartIfChanged = true; + + config = { + system.stateVersion = "24.05"; + time.timeZone = "America/Winnipeg"; + + users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys; + + # Vaultwarden service configuration + services.vaultwarden = { + enable = true; + dbBackend = "sqlite"; + + config = { + # Domain Configuration + DOMAIN = "https://${vaultwardenCfg.domains.url0}"; + + # Email Configuration + SMTP_AUTH_MECHANISM = "Plain"; + SMTP_EMBED_IMAGES = true; + SMTP_FROM = vaultwardenCfg.email.address0; + SMTP_FROM_NAME = vaultwardenCfg.label; + SMTP_HOST = smtpCfg.hostname; + SMTP_PORT = smtpCfg.ports.port1; + SMTP_SECURITY = smtpCfg.records.record1; + SMTP_USERNAME = smtpCfg.email.address0; + + # Security Configuration + DISABLE_ADMIN_TOKEN = false; + + # Event and Backup Management + EVENTS_DAYS_RETAIN = 90; + + # User Features + SENDS_ALLOWED = true; + SIGNUPS_VERIFY = true; + WEB_VAULT_ENABLED = true; + + # Rocket (Web Server) Settings + ROCKET_ADDRESS = "0.0.0.0"; + ROCKET_PORT = vaultwardenCfg.ports.port0; + }; + + # Environment file with secrets (mounted from host) + environmentFile = "/run/secrets/vaultwarden/env"; + }; + + # SSH access + services.openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "prohibit-password"; + }; + }; + + networking.firewall.allowedTCPPorts = [ + 22 + vaultwardenCfg.ports.port0 + ]; + + systemd.network = { + enable = true; + networks."20-lan" = { + matchConfig.Type = "ether"; + networkConfig = { + Address = [ "${vaultwardenCfg.interface.ip}/24" ]; + Gateway = vaultwardenCfg.interface.gate; + DNS = [ + "1.1.1.1" + "8.8.8.8" + ]; + DHCP = "no"; + }; + }; + }; + + microvm = { + vcpu = 2; + mem = 1024; + hypervisor = "qemu"; + + interfaces = [ + { + type = "macvtap"; + id = vaultwardenCfg.interface.id; + mac = vaultwardenCfg.interface.mac; + macvtap = { + link = "enp10s0"; + mode = "bridge"; + }; + } + ]; + + shares = [ + { + mountPoint = "/nix/.ro-store"; + proto = "virtiofs"; + source = "/nix/store"; + tag = "read_only_nix_store"; + } + { + mountPoint = "/var/lib/bitwarden_rs"; + proto = "virtiofs"; + source = vaultwardenCfg.mntPaths.path0; + tag = "vaultwarden_data"; + } + { + mountPoint = "/run/secrets"; + proto = "virtiofs"; + source = "/run/secrets"; + tag = "host_secrets"; + } + ]; + + }; + }; + }; + + # Host-side configuration + systemd.tmpfiles.rules = [ + "d ${vaultwardenCfg.mntPaths.path0} 0755 root root -" + ]; + + services.caddy.virtualHosts."${vaultwardenCfg.domains.url0}" = { + extraConfig = '' + reverse_proxy ${vaultwardenCfg.interface.ip}:${toString vaultwardenCfg.ports.port0} { + header_up X-Real-IP {remote_host} + } + + tls ${vaultwardenCfg.ssl.cert} ${vaultwardenCfg.ssl.key} + + encode zstd gzip + ''; + }; + + sops.secrets = { + "vaultwarden/env" = { + owner = "root"; + mode = "0600"; + }; + }; +}