Separate configs into a1d2 and fix related issues

This commit was made while a1d1's drive failed. This means there's a lot of
changes that may initially seem unrelated to separating configurations and that
this change has been deployed for several days before being pushed. It's also
expected to bypass review.

Here's a full list of changes:
- All modules have been moved from modules to modules/common
- Hardware configuration is now on a per-server basis, by Clicks device ID
  - For the uninformed, everything is given an 'area' and a 'device'. As an
    example, my house is 'Area 2'. My Mac is 'Device 1' in 'Area 2'. An ID is an
    'a' followed by the area number then 'd' followed by the device number. For
    example, my Mac is 'a2d1'.
- A 'backups' user has been provisioned. This user must have full root
  permissions. On a1d2 this user has been given an ssh key which the a1d2 user
  on a1d3 ('chickadee') has been given. When a1d1 is restored, a similar key
  will be provisioned for it.
- The port of gerrit has been changed to conform to the normal minimum of 1024.
  Note that when deploying gerrit, running its init script is required. Changing
  the port will not fix this
- Due to redeployment, keycloak client secrets have changed
- Vaultwarden extra paths have been removed, due to needing to create them on
  launch and this not happening by default
- A HIBP license has been bought and related options have been enabled in
  vaultwarden
- Collabora has been setup in docker, as the built-in code server was not
  working and the standalone nix module I've been working on is not ready
- ACME now registers certificates for mailcow, and moves its certificates into
  mailcow directories after renewal. This avoids mailcow having to use its own
  ACME
- Gerrit has been allowed to send and receive email. Feel free to mail in your
  patches, and you'll also be able to receive mail notifications about changes
  you should review

Change-Id: Ie4d50fb8f16da193195beb139922a366b72b0b0a
Reviewed-on: https://git.clicks.codes/c/Clicks/NixFiles/+/1
Tested-by: Skyler Grey <minion@clicks.codes>
Reviewed-by: Samuel Shuert <coded@clicks.codes>
diff --git a/modules/common/cloudflare-ddns.nix b/modules/common/cloudflare-ddns.nix
index a1ebb61..e199f16 100644
--- a/modules/common/cloudflare-ddns.nix
+++ b/modules/common/cloudflare-ddns.nix
@@ -4,7 +4,7 @@
     proxied = false;
     ipv4 = true;
     ipv6 = false;
-    domains = [ "d1.a1.crawling.us" ];
+    domains = [ "a1.crawling.us" ];
     apiTokenFile = config.sops.secrets.cloudflare_ddns__api_token.path;
   };
 
diff --git a/modules/common/collabora.nix b/modules/common/collabora.nix
new file mode 100644
index 0000000..a746962
--- /dev/null
+++ b/modules/common/collabora.nix
@@ -0,0 +1,77 @@
+{ config, ... }: {
+  #Collabora Containers
+  virtualisation.oci-containers.containers.collabora = {
+    image = "collabora/code:latest";
+    ports = [ "9980:9980/tcp" ];
+    environment = {
+      server_name = "collabora.clicks.codes";
+      aliasgroup1 = "https://nextcloud.clicks.codes:443";
+      aliasgroup2 = "https://cloud.clicks.codes:443";
+      aliasgroup3 = "https://docs.clicks.codes:443";
+      dictionaries = "en_US";
+      extra_params = "--o:ssl.enable=false --o:ssl.termination=true";
+    };
+    extraOptions = [ 
+      "--pull=newer"
+    ];
+  };
+  virtualisation.oci-containers.backend = "docker";
+
+  #Collabora Virtual Hosts
+  services.nginx.virtualHosts.${config.virtualisation.oci-containers.containers.collabora.environment.server_name} = {
+    serverAliases = [ "www.${config.virtualisation.oci-containers.containers.collabora.environment.server_name}" "docs.clicks.codes" "www.clicks.codes" ];
+    enableACME = true;
+    forceSSL = true;
+    addSSL = false;
+    listenAddresses = [ "0.0.0.0" ];
+
+    extraConfig = ''
+      location = / {
+        proxy_pass http://standard:9980;
+        proxy_set_header Host $host;
+      }
+
+      # static files
+      location ^~ /browser {
+        proxy_pass http://standard:9980;
+        proxy_set_header Host $host;
+      }
+
+      # WOPI discovery URL
+      location ^~ /hosting/discovery {
+        proxy_pass http://standard:9980;
+        proxy_set_header Host $host;
+      }
+
+      # Capabilities
+      location ^~ /hosting/capabilities {
+        proxy_pass http://standard:9980;
+        proxy_set_header Host $host;
+     }
+
+     # main websocket
+     location ~ ^/cool/(.*)/ws$ {
+       proxy_pass http://standard:9980;
+       proxy_set_header Upgrade $http_upgrade;
+       proxy_set_header Connection "Upgrade";
+       proxy_set_header Host $host;
+       proxy_read_timeout 36000s;
+     }
+
+     # download, presentation and image upload
+     location ~ ^/(c|l)ool {
+       proxy_pass http://standard:9980;
+       proxy_set_header Host $host;
+     }
+
+     # Admin Console websocket
+     location ^~ /cool/adminws {
+       proxy_pass http://standard:9980;
+       proxy_set_header Upgrade $http_upgrade;
+       proxy_set_header Connection "Upgrade";
+       proxy_set_header Host $host;
+       proxy_read_timeout 36000s;
+     }
+    '';
+  };
+}
diff --git a/modules/common/dmarc.nix b/modules/common/dmarc.nix
index 3266214..62d847c 100644
--- a/modules/common/dmarc.nix
+++ b/modules/common/dmarc.nix
@@ -21,7 +21,7 @@
   ];
 
   services.parsedmarc = {
-    enable = true;
+    enable = false;
     settings.imap = {
       host = "mail.clicks.codes";
       user = "dmarc@clicks.codes";
diff --git a/modules/common/docker.nix b/modules/common/docker.nix
index a1b4e8c..78c7f20 100644
--- a/modules/common/docker.nix
+++ b/modules/common/docker.nix
@@ -1,6 +1,5 @@
 { pkgs, ... }: {
   environment.systemPackages = [ pkgs.docker-compose ];
   virtualisation.docker.enable = true;
-  users.users.mailu.extraGroups = [ "docker" ];
   users.users.kavita.extraGroups = [ "docker" ];
 }
diff --git a/modules/common/gerrit.nix b/modules/common/gerrit.nix
index d7a780e..2cadb1b 100644
--- a/modules/common/gerrit.nix
+++ b/modules/common/gerrit.nix
@@ -34,7 +34,7 @@
       };
       plugin."gerrit-oauth-provider-keycloak-oauth" = {
         root-url = "https://login.clicks.codes";
-        realm = "clicks";
+        realm = "master";
         client-id = "git";
         client-secret = "!!gerrit_oauth_client_secret!!";
         use-preferred-username = true;
@@ -79,8 +79,8 @@
         reportBugUrl =
           "https://discord.gg/bPaNnxe"; # TODO: kinda obnoxious, better to setup openproject
         enablePeerIPInReflogRecord = true;
-        instanceId = "a1d1";
-        instanceName = "a1d1.clicks";
+        instanceId = "clicks";
+        instanceName = "Clicks Gerrit";
       };
       mimetype = lib.pipe [ "image/*" "video/*" "application/pdf" ] [
         (map (name: {
@@ -89,8 +89,21 @@
         }))
         builtins.listToAttrs
       ];
-      receive.enableSignedPush = true;
-      sendemail.enable = false; # TODO: add credentials to git@clicks.codes
+      sendemail = {
+        enable = true;
+        smtpServer = "mail.clicks.codes";
+        smtpUser = "git";
+        smtpPass = "!!gerrit_email_password!!";
+      };
+      receiveemail = {
+        enable = true;
+        protocol = "IMAP";
+        host = "mail.clicks.codes";
+        username = "git@clicks.codes";
+        password = "!!gerrit_email_password!!";
+        encryption = "SSL";
+        enableImapIdle = true;
+      };
       sshd.advertisedAddress = "ssh.clicks.codes:29418";
       user = {
         name = "Clicks Gerrit";
@@ -119,7 +132,7 @@
     ];
     serverId = "45f277d0-fce7-43b7-9eb3-2e3234e0110f";
 
-    listenAddress = "127.0.0.255:1000";
+    listenAddress = "127.0.0.255:1024";
   };
 
   sops.secrets = {
@@ -137,6 +150,13 @@
       sopsFile = ../../secrets/gerrit.json;
       format = "json";
     };
+    gerrit_email_password = {
+      mode = "0400";
+      owner = config.users.users.root.name;
+      group = config.users.users.root.group;
+      sopsFile = ../../secrets/gerrit.json;
+      format = "json";
+    };
   };
 } (let isDerived = base != null;
 in if isDerived then
@@ -150,6 +170,8 @@
         config.sops.secrets.gerrit_email_private_key.path;
       matchers."gerrit_oauth_client_secret".secret =
         config.sops.secrets.gerrit_oauth_client_secret.path;
+      matchers."gerrit_email_password".secret =
+        config.sops.secrets.gerrit_email_password.path;
       owner = config.users.users.root.name;
       group = "gerrit";
       mode = "0040";
diff --git a/modules/common/keycloak.nix b/modules/common/keycloak.nix
index 30e078b..e158825 100644
--- a/modules/common/keycloak.nix
+++ b/modules/common/keycloak.nix
@@ -1,4 +1,21 @@
-{ config, ... }: {
+{ config, lib, ... }: {
+  sops.secrets.keycloak_rsa_private_key = {
+    mode = "0600";
+    owner = "keycloak";
+    group = "keycloak";
+    sopsFile = ../../secrets/keycloak_rsa_private_key.pem;
+    format = "binary";
+  };
+
+  users.users.keycloak = {
+    isSystemUser = true;
+    createHome = true;
+    home = "/var/keycloak";
+    group = "keycloak";
+  };
+  users.groups.keycloak = {};
+  systemd.services.keycloak.serviceConfig.DynamicUser = lib.mkForce false;
+
   services.keycloak = {
     enable = true;
     settings = {
@@ -13,9 +30,8 @@
       hostname = "login.clicks.codes";
       hostname-strict = false;
 
-      https-certificate-file = "/var/keycloak/login.clicks.codes.rsa.cert.pem";
-      https-certificate-key-file =
-        "/var/keycloak/login.clicks.codes.rsa.private.pem";
+      https-certificate-file = "${./keycloak/login.clicks.codes.rsa.cert.pem}";
+      https-certificate-key-file = config.sops.secrets.keycloak_rsa_private_key.path;
     };
     database = {
       createLocally = false;
@@ -23,4 +39,5 @@
       passwordFile = config.sops.secrets.clicks_keycloak_db_password.path;
     };
   };
+  
 }
diff --git a/modules/common/keycloak/login.clicks.codes.rsa.cert.pem b/modules/common/keycloak/login.clicks.codes.rsa.cert.pem
new file mode 100644
index 0000000..8beffce
--- /dev/null
+++ b/modules/common/keycloak/login.clicks.codes.rsa.cert.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+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
+-----END CERTIFICATE-----
diff --git a/modules/common/mailcow.nix b/modules/common/mailcow.nix
new file mode 100644
index 0000000..681573f
--- /dev/null
+++ b/modules/common/mailcow.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }: let
+  mailDomains = [
+    "clicks.codes"
+    "coded.codes"
+    "hopescaramels.com"
+    "trans.gg"
+  ];
+  mailACMEHosts = [
+    "mail.clicks.codes"
+    "mail.coded.codes"
+    "mail.trans.gg"
+    "mail.hopescaramels.com"
+  ] ++ (
+    builtins.concatMap
+      (domain: [ domain "mail.${domain}" "imap.${domain}" "smtp.${domain}" ])
+      mailDomains
+  );
+in {
+  security.acme = {
+    certs = lib.pipe mailACMEHosts [
+      (map (name: { inherit name; value = {}; }))
+      builtins.listToAttrs
+    ];
+    defaults.postRun = "cp -r $(pwd) /opt/mailcow-dockerized/data/assets/ssl/";
+  };
+}
diff --git a/modules/common/matrix.nix b/modules/common/matrix.nix
index c71ba37..5e865bd 100644
--- a/modules/common/matrix.nix
+++ b/modules/common/matrix.nix
@@ -8,14 +8,14 @@
       [ matrix-synapse-mjolnir-antispam ];
 
     settings = rec {
-      server_name = "coded.codes";
+      server_name = "clicks.codes";
       auto_join_rooms = [ "#general:${server_name}" ];
       enable_registration = true;
       registration_requires_token = true;
       allow_public_rooms_over_federation = true;
       allow_device_name_lookup_over_federation = true;
       registration_shared_secret = "!!registration_shared_secret!!";
-      public_baseurl = "https://matrix-backend.coded.codes/";
+      public_baseurl = "https://matrix-backend.clicks.codes/";
       max_upload_size = "100M";
       listeners = [{
         x_forwarded = true;
@@ -28,12 +28,31 @@
       }];
       enable_metrics = true;
       database.args.database = "synapse";
+
+      oidc_providers = [
+        {
+          idp_id = "keycloak";
+          idp_name = "Clicks Keycloak";
+          issuer = "https://login.clicks.codes/realms/master";
+          client_id = "matrix";
+          client_secret = "!!matrix_keycloak_client_secret!!";
+          scopes = [ "openid" "profile" ];
+          user_mapping_provider = {
+            config = {
+              localpart_template = "{{ user.preferred_username }}";
+              display_name_template = "{{ user.name }}";
+            };
+          };
+          backchannel_logout_enabled = true;
+        }
+      ];
+
       turn_uris = [
 
-        /* "turn:turn.coded.codes:3478?transport=udp"
-           "turn:turn.coded.codes:3478?transport=tcp"
-           "turns:turn.coded.codes:5349?transport=udp"
-           "turns:turn.coded.codes:5349?transport=tcp"
+        /* "turn:turn.clicks.codes:3478?transport=udp"
+           "turn:turn.clicks.codes:3478?transport=tcp"
+           "turns:turn.clicks.codes:5349?transport=udp"
+           "turns:turn.clicks.codes:5349?transport=tcp"
         */
       ]; # Please use matrix.org turn
       # turn_shared_secret = "!!turn_shared_secret!!";
@@ -66,7 +85,7 @@
   networking.firewall.allowedUDPPorts = [ 3478 5349 ];
 
   services.mjolnir = {
-    enable = true;
+    enable = false;
 
     settings = {
       autojoinOnlyIfManager = true;
@@ -76,7 +95,7 @@
       admin.enableMakeRoomAdminCommand = true;
       allowNoPrefix = true;
       protections.wordlist.words = [ ];
-      protectedRooms = [ "https://matrix.to/#/#global:coded.codes" ];
+      protectedRooms = [ "https://matrix.to/#/#global:clicks.codes" ];
     };
 
     pantalaimon = {
@@ -91,7 +110,7 @@
 
     homeserverUrl = "http://localhost:4527";
 
-    managementRoom = "#moderation-commands:coded.codes";
+    managementRoom = "#moderation-commands:clicks.codes";
   };
 
   services.coturn = {
@@ -100,14 +119,14 @@
     use-auth-secret = true;
     # static-auth-secret-file = config.sops.secrets.turn_shared_secret.path;
 
-    realm = "turn.coded.codes";
+    realm = "turn.clicks.codes";
 
     no-tcp-relay = true;
 
     no-cli = true;
 
     extraConfig = ''
-      external-ip=turn.coded.codes
+      external-ip=turn.clicks.codes
     '';
   };
 
@@ -119,6 +138,13 @@
     #  sopsFile = ../../secrets/matrix.json;
     #  format = "json";
     #};
+    matrix_keycloak_client_secret = {
+      mode = "0400";
+      owner = config.users.users.matrix-synapse.name;
+      group = config.users.users.matrix-synapse.group;
+      sopsFile = ../../secrets/matrix.json;
+      format = "json";
+    };
     registration_shared_secret = {
       mode = "0400";
       owner = config.users.users.root.name;
@@ -134,13 +160,13 @@
       format = "binary";
       path = config.services.matrix-synapse.settings.signing_key_path;
     };
-    mjolnir_password = {
+    /*mjolnir_password = {
       mode = "0600";
       owner = config.users.users.mjolnir.name;
       group = config.users.users.mjolnir.group;
       sopsFile = ../../secrets/matrix.json;
       format = "json";
-    };
+    };*/
   };
 } (let isDerived = base != null;
 in if isDerived
@@ -153,6 +179,8 @@
       source = toString synapse_cfgfile;
       matchers."registration_shared_secret".secret =
         config.sops.secrets.registration_shared_secret.path;
+      matchers."matrix_keycloak_client_secret".secret =
+        config.sops.secrets.matrix_keycloak_client_secret.path;
       # matchers."turn_shared_secret".secret =
       #   config.sops.secrets.turn_shared_secret.path;
       owner = config.users.users.matrix-synapse.name;
diff --git a/modules/common/networking.nix b/modules/common/networking.nix
index e546db9..a19223c 100644
--- a/modules/common/networking.nix
+++ b/modules/common/networking.nix
@@ -10,5 +10,6 @@
 
     "192.168.0.4" = [ "CodedPi" ];
     "192.168.0.5" = [ "SamuelDesktop" ];
+    "192.168.0.6" = [ "d2.a1.clicks" "a1d2.clicks" "a1d2" ];
   };
 }
diff --git a/modules/common/nginx-routes.nix b/modules/common/nginx-routes.nix
index 9a8534e..024dc98 100644
--- a/modules/common/nginx-routes.nix
+++ b/modules/common/nginx-routes.nix
@@ -7,8 +7,12 @@
     (Host "testing.coded.codes" (ReverseProxy "SamuelDesktop:3000"))
     (Hosts [ "kavita.coded.codes" "reading.coded.codes" ]
       (ReverseProxy "127.0.0.1:5000"))
-    (Host "clicks.codes" (ReverseProxy "127.0.0.1:3000"))
-    (Host "passwords.clicks.codes" (ReverseProxy "127.0.0.1:8452"))
+    (Host "clicks.codes" (Compose [
+      (Path "/.well-known/matrix/"
+        (File ./nginx/clicks.codes/.well-known/matrix))
+      (ReverseProxy "127.0.0.1:3000")
+    ]))
+    (Hosts [ "vaultwarden.clicks.codes" "passwords.clicks.codes" ] (ReverseProxy "generic:1028"))
     (Host "login.clicks.codes" (ReverseProxy "127.0.0.1:9083"))
     (Hosts [
       "syncthing.clicks.codes"
@@ -17,7 +21,7 @@
       "syncthing.hopescaramels.com"
     ] (ReverseProxy "127.0.0.1:8384"))
     (Hosts [ "gerrit.clicks.codes" "git.clicks.codes" ]
-      (ReverseProxy "127.0.0.255:1000"))
+      (ReverseProxy "generic:1024"))
     (Hosts [ "grafana.clicks.codes" "logs.clicks.codes" ]
       (ReverseProxy "127.0.0.1:9052"))
     (InsecureHosts [
@@ -36,12 +40,12 @@
       "smtp.coded.codes"
       "smtp.clicks.codes"
       "smtp.hopescaramels.com"
-    ] (ReverseProxy "127.0.0.1:1080"))
-    (Host "matrix.coded.codes" (Directory "${builtins.toString
+    ] (ReverseProxy "generic:1026"))
+    (Hosts ["matrix.clicks.codes" "matrix.coded.codes"] (Directory "${builtins.toString
       (pkgs.schildichat-web.override {
         conf = {
           default_server_config =
-            lib.pipe ./nginx/coded.codes/.well-known/matrix [
+            lib.pipe ./nginx/clicks.codes/.well-known/matrix [
               builtins.readFile
               builtins.fromJSON
             ];
@@ -56,7 +60,7 @@
           };
           setting_defaults = { "fallbackICEServerAllowed" = true; };
           default_theme = "dark";
-          permalink_prefix = "https://matrix.coded.codes";
+          permalink_prefix = "https://matrix.clicks.codes";
           disable_guests = true;
           disable_3pid_login = true;
         };
@@ -67,10 +71,10 @@
       (Path "/nucleus/" (ReverseProxy "SamuelDesktop:10000")))
     (Host "coded.codes" (Compose [
       (Path "/.well-known/matrix/"
-        (File ./nginx/coded.codes/.well-known/matrix))
+        (File ./nginx/clicks.codes/.well-known/matrix))
       (Redirect "https://clicks.codes$request_uri")
     ]))
-    (Host "matrix-backend.coded.codes" (Compose [
+    (Host "matrix-backend.clicks.codes" (Compose [
       (Path "/_synapse/admin/" (Status 403))
       (ReverseProxy "127.0.0.1:4527")
     ]))
@@ -78,9 +82,7 @@
   clicks.nginx.serviceAliases = with helpers.nginx; [
     (Aliases "nextcloud.clicks.codes" [
       "cloud.clicks.codes"
-      "docs.clicks.codes"
       "www.cloud.clicks.codes"
-      "www.docs.clicks.codes"
       "www.nextcloud.clicks.codes"
     ])
     (Aliases "privatebin" [
@@ -95,13 +97,4 @@
       "www.privatebin.clicks.codes"
     ])
   ];
-  clicks.nginx.streams = with helpers.nginx; [
-    (ProxyStream 143 "127.0.0.1:1143" "tcp") # imap
-    (ProxyStream 993 "127.0.0.1:1993" "tcp") # imap
-    (ProxyStream 110 "127.0.0.1:1110" "tcp") # pop3
-    (ProxyStream 995 "127.0.0.1:1995" "tcp") # pop3
-    (ProxyStream 25 "127.0.0.1:1025" "tcp") # smtp
-    (ProxyStream 465 "127.0.0.1:1465" "tcp") # smtp
-    (ProxyStream 587 "127.0.0.1:1587" "tcp") # smtp
-  ];
 }
diff --git a/modules/common/nginx/clicks.codes/.well-known/matrix b/modules/common/nginx/clicks.codes/.well-known/matrix
new file mode 100644
index 0000000..c7ba524
--- /dev/null
+++ b/modules/common/nginx/clicks.codes/.well-known/matrix
@@ -0,0 +1,7 @@
+{
+  "m.server": "matrix-backend.clicks.codes:443",
+  "m.homeserver": {
+    "base_url": "https://matrix-backend.clicks.codes:443",
+    "server_name": "clicks.codes"
+  }
+}
diff --git a/modules/common/nginx/coded.codes/.well-known/matrix b/modules/common/nginx/coded.codes/.well-known/matrix
deleted file mode 100644
index 9c679da..0000000
--- a/modules/common/nginx/coded.codes/.well-known/matrix
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "m.server": "matrix-backend.coded.codes:443",
-  "m.homeserver": {
-    "base_url": "https://matrix-backend.coded.codes:443",
-    "server_name": "coded.codes"
-  }
-}
diff --git a/modules/common/postgres.nix b/modules/common/postgres.nix
index 397a377..c138511 100644
--- a/modules/common/postgres.nix
+++ b/modules/common/postgres.nix
@@ -11,7 +11,7 @@
     };
 
     ensureDatabases =
-      [ "vaultwarden" "gerrit" "privatebin" "keycloak" "nextcloud" ];
+      [ "vaultwarden" "gerrit" "privatebin" "keycloak" "nextcloud" "synapse" ];
 
     ensureUsers = [
       {
@@ -22,7 +22,7 @@
         };
       }
       {
-        name = "synapse";
+        name = "matrix-synapse";
         ensurePermissions = { "DATABASE synapse" = "ALL PRIVILEGES"; };
       }
       {
@@ -74,7 +74,7 @@
       }
       {
         user = "vaultwarden";
-        passwordFile = config.sops.secrets.clicks_bitwarden_db_password.path;
+        passwordFile = config.sops.secrets.clicks_vaultwarden_db_password.path;
       }
       {
         user = "privatebin";
@@ -95,7 +95,7 @@
   sops.secrets = lib.pipe [
     "clicks_grafana_db_password"
     "clicks_keycloak_db_password"
-    "clicks_bitwarden_db_password"
+    "clicks_vaultwarden_db_password"
     "clicks_privatebin_db_password"
     "clicks_nextcloud_db_password"
   ] [
diff --git a/modules/common/syncthing.nix b/modules/common/syncthing.nix
deleted file mode 100644
index cea1012..0000000
--- a/modules/common/syncthing.nix
+++ /dev/null
@@ -1,6 +0,0 @@
-{ pkgs, ... }: {
-  services.syncthing.enable = true;
-  services.syncthing.openDefaultPorts = true;
-
-  services.syncthing.guiAddress = "0.0.0.0:8384";
-}
diff --git a/modules/common/users.nix b/modules/common/users.nix
index 58dc7d3..b15feae 100644
--- a/modules/common/users.nix
+++ b/modules/common/users.nix
@@ -44,5 +44,14 @@
     group = "clicks";
     shell = pkgs.bashInteractive;
   };
+  users.users.backups = {
+    isSystemUser = true;
+    createHome = true;
+    home = "/backups";
+    group = "backups";
+    shell = pkgs.bashInteractive;
+    extraGroups = [ "wheel" ]; # needed so we can create snapshots of everything
+  };
   users.groups.clicks = { };
+  users.groups.backups = { };
 }
diff --git a/modules/common/vaultwarden.nix b/modules/common/vaultwarden.nix
index 40047dd..7ccc3a1 100644
--- a/modules/common/vaultwarden.nix
+++ b/modules/common/vaultwarden.nix
@@ -1,7 +1,5 @@
-{ base, pkgs, drive_paths, lib, config, ... }:
-if drive_paths == null
-then {}
-else lib.recursiveUpdate {
+{ base, pkgs, lib, config, ... }:
+lib.recursiveUpdate {
   environment.systemPackages = with pkgs; [ vaultwarden ];
 
   services.vaultwarden.enable = true;
@@ -36,9 +34,9 @@
 
     vaultwarden_config = {
       # Server Settings
-      DOMAIN = "https://passwords.clicks.codes";
-      ROCKET_ADDRESS = "127.0.0.1";
-      ROCKET_PORT = 8452;
+      DOMAIN = "https://vaultwarden.clicks.codes";
+      ROCKET_ADDRESS = "127.0.0.255";
+      ROCKET_PORT = 1028;
 
       # General Settings
       SIGNUPS_ALLOWED = false;
@@ -47,15 +45,6 @@
         "clicks.codes,coded.codes,thecoded.prof,starrysky.fyi,hopescaramels.com,pinea.dev,trans.gg";
       SIGNUPS_VERIFY = true;
 
-      RSA_KEY_FILENAME =
-        "${drive_paths.External1000SSD.path}/bitwarden/rsa_key";
-      ICON_CACHE_FOLDER =
-        "${drive_paths.External1000SSD.path}/bitwarden/icon_cache";
-      ATTACHMENTS_FOLDER =
-        "${drive_paths.External4000HDD.path}/bitwarden/attachments";
-      SENDS_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/sends";
-      TMP_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/tmp";
-
       DISABLE_2FA_REMEMBER = true;
 
       # Admin Account
@@ -63,18 +52,18 @@
 
       # Database Settings
       DATABASE_URL =
-        "postgresql://vaultwarden:!!clicks_bitwarden_db_secret!!@127.0.0.1:${
+        "postgresql://vaultwarden:!!clicks_vaultwarden_db_secret!!@127.0.0.1:${
           toString config.services.postgresql.port
         }/vaultwarden";
 
       # Mail Settings
       SMTP_HOST = "mail.clicks.codes";
-      SMTP_FROM = "bitwarden@clicks.codes";
-      SMTP_FROM_NAME = "Clicks Bitwarden";
+      SMTP_FROM = "vaultwarden@clicks.codes";
+      SMTP_FROM_NAME = "Clicks vaultwarden";
       SMTP_SECURITY = "starttls";
       SMTP_PORT = 587;
 
-      SMTP_USERNAME = "bitwarden@clicks.codes";
+      SMTP_USERNAME = "vaultwarden@clicks.codes";
       SMTP_PASSWORD = "!!SMTP_PASSWORD!!";
 
       REQUIRE_DEVICE_EMAIL = true;
@@ -85,9 +74,8 @@
       YUBICO_CLIENT_ID = "89788";
       YUBICO_SECRET_KEY = "!!YUBICO_SECRET_KEY!!";
 
-      # TODO: Buy a license
       # HIBP Settings
-      # HIBP_API_KEY="!!HIBP_API_KEY!!";
+      HIBP_API_KEY="!!HIBP_API_KEY!!";
 
       ORG_ENABLE_GROUPS = true;
       # I have looked at the risks. They seem relatively small in comparison to the utility
@@ -147,8 +135,8 @@
       matchers."YUBICO_SECRET_KEY".secret =
         config.sops.secrets.YUBICO_SECRET_KEY.path;
       matchers."HIBP_API_KEY".secret = config.sops.secrets.HIBP_API_KEY.path;
-      matchers."clicks_bitwarden_db_secret".secret =
-        config.sops.secrets.clicks_bitwarden_db_password.path;
+      matchers."clicks_vaultwarden_db_secret".secret =
+        config.sops.secrets.clicks_vaultwarden_db_password.path;
       owner = config.users.users.vaultwarden.name;
       group = config.users.groups.vaultwarden.name;
       mode = "0400";