{ config, inputs, lib, ... }: with lib; let cfg = config.nixfiles.modules.vaultwarden; in { options.nixfiles.modules.vaultwarden = { enable = mkEnableOption "Vaultwarden"; domain = mkOption { description = "Domain name sans protocol scheme."; type = with types; str; default = "vaultwarden.${config.networking.domain}"; }; }; config = let db = "vaultwarden"; in mkIf cfg.enable { ark.directories = ["/var/lib/bitwarden_rs"]; secrets.vaultwarden-environment = { file = "${inputs.self}/secrets/vaultwarden-environment"; owner = "vaultwarden"; group = "vaultwarden"; }; nixfiles.modules = { nginx = { enable = true; upstreams = with config.services.vaultwarden.config; { vaultwarden_rocket.servers."${ROCKET_ADDRESS}:${toString ROCKET_PORT}" = {}; vaultwarden_websocket.servers."${WEBSOCKET_ADDRESS}:${toString WEBSOCKET_PORT}" = {}; }; virtualHosts.${cfg.domain} = { locations."/" = { proxyPass = "http://vaultwarden_rocket"; proxyWebsockets = true; }; locations."/notifications/hub" = { proxyPass = "http://vaultwarden_websocket"; proxyWebsockets = true; }; locations."/notifications/hub/negotiate" = { proxyPass = "http://vaultwarden_rocket"; proxyWebsockets = true; }; }; }; postgresql = { enable = true; extraPostStart = [ '' $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' '' ]; }; }; services = { vaultwarden = { enable = true; config = { TZ = config.time.timeZone; WEB_VAULT_ENABLED = true; DOMAIN = optionalString (cfg.domain != null) "http://${cfg.domain}"; SIGNUPS_ALLOWED = false; INVITATIONS_ALLOWED = false; ORG_CREATION_USERS = "none"; PASSWORD_HINTS_ALLOWED = false; SHOW_PASSWORD_HINT = false; ROCKET_ADDRESS = "127.0.0.1"; ROCKET_PORT = 8812; WEBSOCKET_ENABLED = true; WEBSOCKET_ADDRESS = "127.0.0.1"; WEBSOCKET_PORT = 8813; LOG_LEVEL = "error"; DATABASE_URL = "postgresql://${db}@/${db}"; }; dbBackend = "postgresql"; environmentFile = config.secrets.vaultwarden-environment.path; }; postgresql = { ensureDatabases = [db]; ensureUsers = [ { name = db; ensurePermissions."DATABASE \"${db}\"" = "ALL"; } ]; }; fail2ban.jails = mkIf config.nixfiles.modules.fail2ban.enable { vaultwarden = '' enabled = true filter = vaultwarden port = http,https ''; vaultwarden-admin = '' enabled = true filter = vaultwarden-admin port = http,https ''; }; }; environment.etc = mkIf config.nixfiles.modules.fail2ban.enable { "fail2ban/filter.d/vaultwarden.conf".text = '' [Definition] failregex = ^.*Username or password is incorrect\. Try again\. IP: \. Username:.*$ ignoreregex = journalmatch = _SYSTEMD_UNIT=vaultwarden.service ''; "fail2ban/filter.d/vaultwarden-admin.conf".text = '' [Definition] failregex = ^.*Invalid admin token\. IP: .*$ ignoreregex = journalmatch = _SYSTEMD_UNIT=vaultwarden.service ''; }; }; }