zaphyra's git: nixfiles

zaphyra and void's nixfiles

commit 6c3504d66899ee499532852c67e0af64a3be9ae5
parent 67264c1fd2b51ca51ce685df8ccce817d8601f8e
Author: Katja (zaphyra) <git@ctu.cx>
Date: Sun, 25 May 2025 18:37:25 +0200

config/nixos/modules/websites: add `vault.zaphyra.eu` (and enable on host `morio`)
4 files changed, 115 insertions(+), 2 deletions(-)
M
config/nixos/modules/presets/katja/mailServer.nix
|
5
+++++
A
config/nixos/modules/websites/vault.zaphyra.eu.nix
|
103
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M
hosts/morio/default.nix
|
1
+
M
secrets/morio.yaml
|
8
++++++--
diff --git a/config/nixos/modules/presets/katja/mailServer.nix b/config/nixos/modules/presets/katja/mailServer.nix
@@ -119,6 +119,7 @@ in
       sops.secrets = {
         "mailPasswords/katja@zaphyra.eu" = { };
         "mailPasswords/gts@zaphyra.eu" = { };
+        "mailPasswords/vaultwarden@zaphyra.eu" = { };
         "resticPasswords/mail" = { };
         "sieveScripts/katja@zaphyra.eu.sieve" = {
           sopsFile = inputs.self.sopsSecrets.zaphyra.sieve;

@@ -194,6 +195,10 @@ in
             hashedPasswordFile = config.sops.secrets."mailPasswords/gts@zaphyra.eu".path;
             sendOnly = true;
           };
+          "vaultwarden@zaphyra.eu" = {
+            hashedPasswordFile = config.sops.secrets."mailPasswords/vaultwarden@zaphyra.eu".path;
+            sendOnly = true;
+          };
         };
       };
 
diff --git a/config/nixos/modules/websites/vault.zaphyra.eu.nix b/config/nixos/modules/websites/vault.zaphyra.eu.nix
@@ -0,0 +1,103 @@
+{
+  povSelf,
+  hostConfig,
+  config,
+  pkgs,
+  lib,
+  ...
+}:
+
+let
+  inherit (lib) types;
+  cfg = lib.getAttrFromPath povSelf config;
+
+in
+{
+
+  options = {
+    enable = {
+      type = types.bool;
+      default = false;
+    };
+    domain = {
+      type = types.str;
+      default = "zaphyra.eu";
+    };
+    subdomain = {
+      type = types.str;
+      default = "vault";
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    dns.zones."${cfg.domain}".subdomains."${cfg.subdomain}".CNAME = [ "${config.networking.fqdn}." ];
+
+    sops.secrets = {
+      "resticPasswords/vaultwarden" = { };
+      "environments/vaultwarden" = {
+        owner = config.systemd.services.vaultwarden.serviceConfig.User;
+        group = config.systemd.services.vaultwarden.serviceConfig.Group;
+        restartUnits = [ "vaultwarden.service" ];
+      };
+    };
+
+    systemd.tmpfiles.settings.vaultwarden = {
+      "${config.services.vaultwarden.backupDir}".d = {
+        user = config.systemd.services.vaultwarden.serviceConfig.User;
+        group = config.systemd.services.vaultwarden.serviceConfig.Group;
+        mode = "750";
+        age = "-";
+      };
+    };
+
+    modules.services.resticBackup.paths = {
+      vaultwarden = {
+        enable = true;
+        passwordFile = config.sops.secrets."resticPasswords/vaultwarden".path;
+        paths = [ config.services.vaultwarden.backupDir ];
+        runBeforeBackup = ''
+          ${pkgs.systemd}/bin/systemctl start backup-vaultwarden.service
+        '';
+      };
+    };
+
+    services = {
+      vaultwarden = {
+        enable = true;
+        dbBackend = "sqlite";
+        backupDir = "/var/backups/vaultwarden";
+        environmentFile = config.sops.secrets."environments/vaultwarden".path;
+        config = {
+          DOMAIN = "https://${cfg.subdomain}.${cfg.domain}";
+          SIGNUPS_ALLOWED = false;
+
+          PUSH_ENABLED = true;
+
+          SMTP_HOST = "morio.infra.zaphyra.eu";
+          SMTP_FROM = "vaultwarden@zaphyra.eu";
+          SMTP_USERNAME = "vaultwarden@zaphyra.eu";
+          SMTP_PORT = 465;
+          SMTP_SECURITY = "force_tls";
+
+          ROCKET_ADDRESS = "::1";
+          ROCKET_PORT = 8582;
+        };
+      };
+      nginx = {
+        enable = true;
+        virtualHosts."${cfg.subdomain}.${cfg.domain}" = {
+          useACMEHost = "${config.networking.fqdn}";
+          forceSSL = true;
+          kTLS = true;
+          locations = {
+            "/" = {
+              proxyPass = "http://[::1]:${toString config.services.vaultwarden.config.ROCKET_PORT}/";
+              proxyWebsockets = true;
+            };
+          };
+        };
+      };
+    };
+  };
+
+}
diff --git a/hosts/morio/default.nix b/hosts/morio/default.nix
@@ -84,6 +84,7 @@
           "dav.zaphyra.eu".enable = true;
           "gts.zaphyra.eu".enable = true;
           "grapevine.zaphyra.eu".enable = true;
+          "vault.zaphyra.eu".enable = true;
         };
 
         users.katja.enable = true;
diff --git a/secrets/morio.yaml b/secrets/morio.yaml
@@ -2,15 +2,19 @@ acmeTSIGKey: ENC[AES256_GCM,data:XbTSbHisL5ZszYY4hvKplyWG98eK4DUeiSpA24Am/QPjEw8
 mailPasswords:
     katja@zaphyra.eu: ENC[AES256_GCM,data:BSNsU+TBqGcprevSiTRvtzCxi8FbsBrLItrgwwYZAvJ8HhDXW9xgL9AX9mDi59Z8gcPhSWGhdOOfYGfp,iv:nSDOguVcatHJzAFim+bpiy9SV024MuTYcUHqgSNdkhA=,tag:kJ622f4I5pGhBltj466qIw==,type:str]
     gts@zaphyra.eu: ENC[AES256_GCM,data:z+4Ha58AHS6q8n9ke77LoocEmNbASL+EBTptUZNrpUDRq8ypM8wHGl+J4uMhrJIQzpGYGQBxO+x4vCMp,iv:3wvvmJ1+Ui3xT4SSYw9blJ/1tjc7KKYhc26nP3IdlwY=,tag:9SAGK4c1n5f65bP7CxPF8A==,type:str]
+    vaultwarden@zaphyra.eu: ENC[AES256_GCM,data:AQpLgmtDOEMpapJDleaYHIb3BEh9R8zuAGLuP0AKkFmiR9zf0l2KBKKYi4Utcgonag66qVgR08Y2fHR9,iv:V5tVnan369MPu/KLZ1GBu3wXfObQh45pKpASf3br7Ww=,tag:/qR7nnRAqT60m6Qix3URJw==,type:str]
 resticPasswords:
     gitolite: ENC[AES256_GCM,data:g28//NtKEYL+Dh0+Ws73ZKySl1L0avxqNXVn5lKaj1U=,iv:mGQ7pYjeMEGTCS1l6H/h043M2oAhgMOAlUHkgDir03E=,tag:E/ps0EZmlMEm+ziWzXzQPQ==,type:str]
     mail: ENC[AES256_GCM,data:wag5v/l0kQrhStO9P3ibtRtkReslszu4IfTEL8Ls4Pc=,iv:QCSveMAylefSBeb8Eaw6Av+1cA6lAvhtv1jNT8QUvIM=,tag:Y+HKURnEXPxKUSvGwaJAjA==,type:str]
     radicale: ENC[AES256_GCM,data:GsAXncF4JRHaNe0Tkv6PucJpwFFu9cfHo3INIBjc24I=,iv:XVvx9UOGIcC94uh3LnwOFs6g8Zy2YHjodCp0RNWcFrQ=,tag:ekUjoM/fbsmST2KDPNf/VA==,type:str]
     gotosocial: ENC[AES256_GCM,data:8zc4JZVTyPZQADDUrobjAOuRr/3CpfNROO8edY63nk4=,iv:nxfSNSw+aypsTKXJO68B6SkqFfBbfWFARfcNTPODSBA=,tag:ozsw8R6xbpS8E+fNzCosUQ==,type:str]
     grapevine: ENC[AES256_GCM,data:ElNtJC2elPstqJ1vTJRJpNr0OyhTuTxCulh22qq459c=,iv:sgQCekPMcnyFzir/fISJAQZvV91e+43z9D9xShAz4Pg=,tag:LVjr6ZxFO9VmPXZWtz20Uw==,type:str]
+    vaultwarden: ENC[AES256_GCM,data:MmXXWit37MC4dpJG1654IpxfRdw0b+2mpfu7K80ZTRQ=,iv:4wRi3ovrLrzCkUjiGpEpWWPSDkHUdpI82joofhoIP8U=,tag:zgTTK+h/vqLmxCNNtfrxwg==,type:str]
 knotKeys: ENC[AES256_GCM,data:rlTFDvonfEQFST1eSHHcaG3e1CSt5paDUTvfoYmInBV7mjqe7PwT5dtg01W2ANZJYl+SN/cdI3eEvAdJvwYR6FK+7g1LPwn6G1coE68a/XwzsWM5WpSemmDfTykoUiguEUfRCZ0Q3M7YqV0/jDWrKMaH0iKqKqvlv7nEy6VXB5SZBX+aN18KvPVygw5FixQ/kD3XFI2HTTST4vqlMma3CTsjnK6Uwf1421JOIe3JR32qd0V7IfhFvL0mErMIRhLnITO9uJ//t1HJoeaOV7FEY4K6Ohacng1c68fkUjVX5wYBTd6X657nFqevvLiMRDiQnASOJrAJUAeq4Kwf5R7C/I/MeVh+1Hq/U+z4ZQKh/DViEE8+TkJwDMBAWarzlyOz7xDF8O+fj4iH5jTX8H3FmJLU/TVU0QXqnwjcAAVs/YNARNVt0wGdWTb9iyvD7vEIZE57wIp+TIGE8XFjOO11/DRC/0kC8HFkvoXke9IRrTIj1pCP1VIrv31v7aIyphWa5hBuBHfVb0f8g5eaqyKumM03Rge+Fo+jtM/NP7H2gao6uaZM/K4a625nVx+M1lUpW+1c0sIAME2SlDjSyuhTkMknOPGAAYXMwVQGazoOJna6sEBl6jYcgn31w3dHtJXGKyAB0eqELxjt5b0tzcBfJ4pXi7HO7w2yhKrqyL7GuE5LtLp5mkguC5eZbiX+VlGTLX6V2z1kDRUdYDDZMMh3cYGBIrGVoJhWx8xLWrLGm7TrvifiwYJq5Mq13tt2hS7HpY8T8YGBD2x3IdPAHtikZUYgv5cQxs7drSJi8zFQAwDUKofxhJQUvqrnmvNf+eiGkfgI7lQ0//NLg9o4t+5g+T3mV8IUkW4nbJsP46k6azQGBt3udYAVhgrFy/jTE++KrA==,iv:+5NBUUC1QhPjN+6E8nWhzd2SNuH9mLbhsFwDTm8Hy+U=,tag:RtSO5Rmb0wNR9ovtpwJIIg==,type:str]
 radicaleUsers: ENC[AES256_GCM,data:kH5XW/Gr2xMJWm68unKtZ+L19S74gOf1YXw5QtPcBnp8jJrQsc3mHX5GPOJafuNa23Tnt9BHTFmuO3e5bEzhBcVm8GdoMR/Wz4B0y0W5,iv:Frc4ukXwdWZuWNgauLUyz4ErFKFUvoYoTMN9eZNWAGg=,tag:PLVaetT3syVGR4Ox3AYhUA==,type:str]
 gotosocialEnv: ENC[AES256_GCM,data:5hvURqX+EqN8zpjirBmh5TIWWgaCga9QxnAfyW1rwOXELnM9ZBJAmqwLdxUa2j2DGrXsqw==,iv:nhVyiAoOJY0HtjB13FnmnQyLB+BWSRwDVrwUiFHBrE4=,tag:P207zPou7yXJKJBf+pxlHg==,type:str]
+environments:
+    vaultwarden: ENC[AES256_GCM,data:kIFPmYWNZ/n+azRhLFUA+AbBH4QpV1qOvRBVRB7RcxPmntqJuXQR1/7bqIjTGKc6H6Xzh4nhXtrHIBusF4IMz4vRa47ZQ35Kkuj+VVRXTx6KebFQSsN0PggvSsDQHtjInXge3KbszTSmptm58O2hLTznln7220vvWTJw+zIZZPhnwCc61sa+6BcakUmm2Mvv9DsO3TRzO6de94DiRpFrohBDOmszfDKPvURKW+QWnL+242H4NxttvzwhSN2dCyECTfbFhpVbK9aDjhI9Sl1pX4lwYZgtg2VbiVr61iNter+q6cLzWe6sOKCoCONO79DENKnsMoDa693rF1vQoPP1QVKsuWc+uxXFxfArZzmHLcxMJTo=,iv:dhV8x1ckZgpjZLs2r+X3Dqks5RXJMxfxAhff6MmQUBM=,tag:lSgrK+T0CqJCe/idwuG37A==,type:str]
 sops:
     kms: []
     gcp_kms: []

@@ -26,8 +30,8 @@ sops:
             bDRhUEtDdmlZa0ZENFhSVnNqVjFCR1UKEIkSg3tKFkwlnNXFFqCBtdZBGz1bEmWl
             wghkTtqTl++759zZAAmjdnFFQWs/AoCZ5g/GUidz6HHcFdxMpGVmiA==
             -----END AGE ENCRYPTED FILE-----
-    lastmodified: "2025-05-25T11:39:45Z"
-    mac: ENC[AES256_GCM,data:WFvxVYrf/PfAj3pt7xi8+/2FH+LEj3Slz5bYIIt7Tvhz5rX8JDbEscuk+7OophbOP4iFuJV4W+tLmUULTgarWamqI0UEIZij/SVLDQEbvm3i6+n5rEx31re4VcLjmdmLRoplmiSAAClYuk7Tn/12zaiyA1TxA7WW/xaSTCe3V18=,iv:lQJ2vH6RYyIs0aX1gEv7lHm1vtTdJY5iQWOcCNxPTpI=,tag:UNcOCvtx6qNir1+7q59+sA==,type:str]
+    lastmodified: "2025-05-25T16:33:00Z"
+    mac: ENC[AES256_GCM,data:DDfRoe1mhUZtCqx1yxkBI7Dw2dCQLtqJEnII+IID4I+dFS2V+tyrF+bG9NppUgDXIRS5FH6yUFCfQ3/VHZycYKpHZWIi5EChafdvsv7u96PF5IJp9ZSiv99snmvUf591qzCN4I+Coz/QBKkXW8GRDHyKU2WJWr6q/TrA7ql/F+0=,iv:a5hfsPn9cPh3M4tf+oU0zEi1rP2UgJEYAOgEXLEQUOM=,tag:4aZunkYyNTnCrHZJhF7Q8A==,type:str]
     pgp:
         - created_at: "2025-05-21T08:09:28Z"
           enc: |-