{ 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"; }; }; }; # Actually start systemd-networkd service systemd.services.systemd-networkd.wantedBy = [ "multi-user.target" ]; microvm = { vcpu = 2; mem = 1024; hypervisor = "qemu"; # Use q35 machine type for proper PCI support instead of microvm qemu.machine = "q35"; 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"; }; }; }