From 1376cdbe7716e1f020d84eb8827dab1e4e457455 Mon Sep 17 00:00:00 2001 From: Nick Date: Thu, 6 Nov 2025 04:08:29 -0600 Subject: [PATCH] test: forgejo microVM --- .../config/instances/config/vaultwarden.nix | 41 +++- modules/nixos/default.nix | 8 +- .../nixos/programs/virtManager/default.nix | 1 + .../nixos/services/acme/acmeCeres/default.nix | 28 +-- .../services/caddy/caddyCeres/default.nix | 17 -- modules/nixos/services/forgejo/default.nix | 11 + .../nixos/services/vaultwarden/default.nix | 232 ++++++++++++------ profiles/user0/default.nix | 54 ++-- systems/mars/config/filesystem.nix | 10 +- 9 files changed, 245 insertions(+), 157 deletions(-) diff --git a/modules/config/instances/config/vaultwarden.nix b/modules/config/instances/config/vaultwarden.nix index f1400ac..76c88c0 100755 --- a/modules/config/instances/config/vaultwarden.nix +++ b/modules/config/instances/config/vaultwarden.nix @@ -2,14 +2,18 @@ let inherit (moduleFunctions.instancesFunctions) domain0 - servicePath sslPath - sopsPath + idPrefix + userPrefix + varPath + mntPath + secretPath ; - label = "Vaultwarden"; name = "vaultwarden"; domain = "${name}.${domain0}"; + secrets = "${secretPath}/${name}"; + ssl = "${sslPath}/${name}.${domain0}"; in { label = label; @@ -18,9 +22,6 @@ in email = { address0 = "noreply@${name}.${domain0}"; }; - sops = { - path0 = "${sopsPath}/${name}"; - }; domains = { url0 = domain; }; @@ -32,14 +33,30 @@ in "bit" "warden" ]; - paths = { - path0 = "${servicePath}/${label}/BackupDir"; - }; ports = { - port0 = 8085; # Vaultwarden WebUI + port0 = 8085; + }; + interface = { + id = "${idPrefix}-${name}"; + mac = "02:00:00:00:00:51"; + idUser = "${userPrefix}-${name}"; + macUser = "02:00:00:00:00:03"; + ip = "192.168.50.51"; + gate = "192.168.50.1"; + ssh = 2201; }; ssl = { - cert = "${sslPath}/${name}.${domain0}/fullchain.pem"; - key = "${sslPath}/${name}.${domain0}/key.pem"; + path = ssl; + cert = "${ssl}/fullchain.pem"; + key = "${ssl}/key.pem"; + }; + varPaths = { + path0 = "${varPath}/${name}"; + }; + mntPaths = { + path0 = "${mntPath}/${name}"; + }; + secretPaths = { + path0 = secrets; }; } diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 198840c..824f3e4 100755 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -45,18 +45,18 @@ in ceres = { imports = builtins.attrValues { inherit (modules) - # acmeCeres + acmeCeres # audiobookshelf - # caddyCeres + caddyCeres # comfyui # filesorter # firefly-iii - # forgejo + forgejo # glance # jellyfin # logrotate # mastodon - # microvm + microvm # minecraft # ollamaCeres # postgresCeres diff --git a/modules/nixos/programs/virtManager/default.nix b/modules/nixos/programs/virtManager/default.nix index 479e95f..fd1b71f 100755 --- a/modules/nixos/programs/virtManager/default.nix +++ b/modules/nixos/programs/virtManager/default.nix @@ -1,4 +1,5 @@ { programs.virt-manager.enable = true; virtualisation.libvirtd.enable = true; + users.groups.kvm = { }; } diff --git a/modules/nixos/services/acme/acmeCeres/default.nix b/modules/nixos/services/acme/acmeCeres/default.nix index 33ff056..693c610 100755 --- a/modules/nixos/services/acme/acmeCeres/default.nix +++ b/modules/nixos/services/acme/acmeCeres/default.nix @@ -31,22 +31,22 @@ in }; in { - "${instances.audiobookshelf.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.glance.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.jellyfin.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.ollama.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.searx.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.syncthing.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.audiobookshelf.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.glance.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.jellyfin.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.ollama.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.searx.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.syncthing.domains.url0}" = dnsConfig dns0Path dns0; "${instances.vaultwarden.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.prompter.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.comfyui.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.firefly-iii.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.opencloud.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.prompter.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.comfyui.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.firefly-iii.domains.url0}" = dnsConfig dns0Path dns0; + # "${instances.opencloud.domains.url0}" = dnsConfig dns0Path dns0; "${instances.forgejo.domains.url0}" = dnsConfig dns0Path dns0; - "${instances.mastodon.domains.url0}" = dnsConfig dns0Path dns0; - "${domain0}" = dnsConfig dns0Path dns0; - "${domain1}" = dnsConfig dns0Path dns0; - "${domain4}" = dnsConfig dns1Path dns1; + # "${instances.mastodon.domains.url0}" = dnsConfig dns0Path dns0; + # "${domain0}" = dnsConfig dns0Path dns0; + # "${domain1}" = dnsConfig dns0Path dns0; + # "${domain4}" = dnsConfig dns1Path dns1; }; }; diff --git a/modules/nixos/services/caddy/caddyCeres/default.nix b/modules/nixos/services/caddy/caddyCeres/default.nix index 131b183..4f7cd1d 100755 --- a/modules/nixos/services/caddy/caddyCeres/default.nix +++ b/modules/nixos/services/caddy/caddyCeres/default.nix @@ -1,29 +1,12 @@ { flake, ... }: let inherit (flake.config.services) instances; - inherit (flake.config.machines) devices; - domain0 = instances.web.domains.url0; service = instances.caddy; - opencloud = instances.opencloud; in { services.caddy = { enable = true; - virtualHosts = { - "${domain0}" = { - extraConfig = '' - tls /var/lib/acme/${domain0}/fullchain.pem /var/lib/acme/${domain0}/key.pem - encode zstd gzip - ''; - }; - # "${opencloud.domains.url0}" = { - # extraConfig = '' - # reverse_proxy http://${devices.eris.ip.address0}:${builtins.toString service.ports.port4} - # tls ${opencloud.ssl.cert} ${opencloud.ssl.key} - # ''; - # }; - }; }; users.users.${service.name}.extraGroups = [ "acme" diff --git a/modules/nixos/services/forgejo/default.nix b/modules/nixos/services/forgejo/default.nix index 01fbbb7..dbe4c2c 100755 --- a/modules/nixos/services/forgejo/default.nix +++ b/modules/nixos/services/forgejo/default.nix @@ -164,6 +164,12 @@ in source = service.ssl.path; tag = "acme_certs"; } + { + mountPoint = "/run/secrets"; + proto = "virtiofs"; + source = "/var/lib/secrets"; + tag = "run_secrets"; + } ]; forwardPorts = [ @@ -179,6 +185,11 @@ in }; }; + systemd.tmpfiles.rules = [ + "d ${service.mntPaths.path0} 0755 root root -" + "d ${service.secretPaths.path0} 0755 root root -" + ]; + services.caddy.virtualHosts."${host}" = { extraConfig = '' reverse_proxy ${service.interface.ip}:${toString service.ports.port0} diff --git a/modules/nixos/services/vaultwarden/default.nix b/modules/nixos/services/vaultwarden/default.nix index 5344629..0a33f11 100755 --- a/modules/nixos/services/vaultwarden/default.nix +++ b/modules/nixos/services/vaultwarden/default.nix @@ -1,76 +1,174 @@ { 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 (flake.config.people) user0; + inherit (flake.config.services.instances) vaultwarden smtp web; + service = vaultwarden; + host = vaultwarden.domains.url0; + secrets = service.secretPaths.path0; + localhost = web.localhost.address0; + sshPort = 22; in { - services = { - vaultwarden = { - backupDir = backupPath; - enable = true; - environmentFile = config.sops.secrets."${service.name}/env".path; - config = { - # Domain Configuration - DOMAIN = "https://${host}"; + microvm = { + vms = { + vaultwarden = { + autostart = true; + config = + { + config, + pkgs, + lib, + ... + }: + { + system.stateVersion = "25.05"; + time.timeZone = "America/Winnipeg"; - # 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; + users.users.root = { + openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys; + }; - # Security Configuration - DISABLE_ADMIN_TOKEN = false; + services = { + vaultwarden = { + 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 = smtp.email.address0; + SMTP_FROM_NAME = service.label; + SMTP_HOST = smtp.hostname; + SMTP_PORT = smtp.ports.port1; + SMTP_SECURITY = smtp.records.record1; + SMTP_USERNAME = 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; + }; + }; - # Event and Backup Management - EVENTS_DAYS_RETAIN = 90; + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "prohibit-password"; + }; + }; + }; - # User Features - SENDS_ALLOWED = true; - SIGNUPS_VERIFY = true; - WEB_VAULT_ENABLED = true; + systemd = { + tmpfiles.rules = [ + "d ${secrets} 0755 ${service.name} ${service.name} -" + ]; - # Rocket (Web Server) Settings - ROCKET_ADDRESS = localhost; - ROCKET_PORT = service.ports.port0; + network = { + enable = true; + networks."10-enp" = { + matchConfig.Name = "enp0s4"; + addresses = [ { Address = "${service.interface.ip}/24"; } ]; + routes = [ + { + Destination = "${localhost}/0"; + Gateway = service.interface.gate; + } + ]; + dns = [ service.interface.gate ]; + }; + }; + }; + + networking.firewall.allowedTCPPorts = [ + sshPort + service.ports.port0 + ]; + + microvm = { + vcpu = 2; + mem = 2048; + hypervisor = "qemu"; + + interfaces = [ + { + type = "tap"; + id = service.interface.id; + mac = service.interface.mac; + } + { + type = "user"; + id = service.interface.idUser; + mac = service.interface.macUser; + } + ]; + + shares = [ + { + mountPoint = "/nix/.ro-store"; + proto = "virtiofs"; + source = "/nix/store"; + tag = "read_only_nix_store"; + } + { + mountPoint = service.varPaths.path0; + proto = "virtiofs"; + source = service.mntPaths.path0; + tag = "${service.name}_data"; + } + { + mountPoint = service.secretPaths.path0; + proto = "virtiofs"; + source = service.secretPaths.path0; + tag = "${service.name}_secrets"; + } + { + mountPoint = service.ssl.path; + proto = "virtiofs"; + source = service.ssl.path; + tag = "acme_certs"; + } + ]; + + forwardPorts = [ + { + from = "host"; + host.port = service.interface.ssh; + guest.port = sshPort; + } + ]; + }; + }; }; }; - 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 - ''; - }; - }; - }; + services.caddy.virtualHosts."${host}" = { + extraConfig = '' + reverse_proxy ${service.interface.ip}:${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; + path = "${secrets}/${service.name}-${secret}"; + owner = "root"; mode = "600"; }; in @@ -78,7 +176,7 @@ in secrets = builtins.listToAttrs ( map (secret: { - name = "${service.name}/${secret}"; + name = "${service.name}-${secret}"; value = sopsPath secret; }) [ @@ -86,30 +184,4 @@ in ] ); }; - - 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 - ]; - }; - }; } diff --git a/profiles/user0/default.nix b/profiles/user0/default.nix index 8dd38c9..e8667c2 100755 --- a/profiles/user0/default.nix +++ b/profiles/user0/default.nix @@ -63,31 +63,35 @@ in home = { username = user0; homeDirectory = "/home/${user0}"; - file = { - "./justfile" = import ./files/misc/justfile.nix { inherit flake config lib; }; - "./.config/scripts/list.sh" = { - source = ./files/scripts/list.sh; - executable = true; - }; - "./.config/scripts/loop.sh" = { - source = ./files/scripts/loop.sh; - executable = true; - }; - "./.config/scripts/get_weather.sh" = { - source = ./files/scripts/get_weather.sh; - executable = true; - }; - ".config/wallpaper" = { - source = ./files/wallpaper; - recursive = true; - }; - "./.config/vesktop/themes/macchiato-theme.css" = { - source = ./files/themes/vesktop/macchiato-theme.css; - }; - "./.config/qBittorrent/themes/catppuccin-mocha.qbtheme" = { - source = ./files/themes/qbittorrent/macchiato.qbtheme; - }; - }; + file = + if hostname == devices.ceres.name then + { } + else + { + "./justfile" = import ./files/misc/justfile.nix { inherit flake config lib; }; + "./.config/scripts/list.sh" = { + source = ./files/scripts/list.sh; + executable = true; + }; + "./.config/scripts/loop.sh" = { + source = ./files/scripts/loop.sh; + executable = true; + }; + "./.config/scripts/get_weather.sh" = { + source = ./files/scripts/get_weather.sh; + executable = true; + }; + ".config/wallpaper" = { + source = ./files/wallpaper; + recursive = true; + }; + "./.config/vesktop/themes/macchiato-theme.css" = { + source = ./files/themes/vesktop/macchiato-theme.css; + }; + "./.config/qBittorrent/themes/catppuccin-mocha.qbtheme" = { + source = ./files/themes/qbittorrent/macchiato.qbtheme; + }; + }; sessionVariables = { VISUAL = lib.getExe pkgs.zed-editor; GTK_THEME = "catppuccin-macchiato-mauve-compact"; diff --git a/systems/mars/config/filesystem.nix b/systems/mars/config/filesystem.nix index 13a3a87..602eaac 100755 --- a/systems/mars/config/filesystem.nix +++ b/systems/mars/config/filesystem.nix @@ -59,11 +59,11 @@ in fsType = "vfat"; options = mars.boot.options; }; - } - // (builtins.listToAttrs (map storageMounts storageDrives)) - // (builtins.listToAttrs ( - builtins.concatMap (drive: map (folder: sambaMounts drive folder) sambaFolders) sambaDrives - )); + }; + # // (builtins.listToAttrs (map storageMounts storageDrives)) + # // (builtins.listToAttrs ( + # builtins.concatMap (drive: map (folder: sambaMounts drive folder) sambaFolders) sambaDrives + # )); swapDevices = [ { device = "/dev/disk/by-uuid/6b56990c-545d-4d00-b93b-8ca1f143882e"; }