{ config, lib, my, secrets, ... }: let fqdn = "vault.${my.domain}"; in { sops.secrets."vaultwarden/env" = { sopsFile = ../secrets/sops/vaultwarden.yaml; owner = "vaultwarden"; restartUnits = [ "vaultwarden.service" ]; }; services.vaultwarden = { enable = true; environmentFile = secrets."vaultwarden/env".path; dbBackend = "sqlite"; config = { DOMAIN = "https://${fqdn}"; DATA_FOLDER = "/var/lib/vaultwarden"; SIGNUPS_ALLOWED = false; INVITATIONS_ALLOWED = false; SHOW_PASSWORD_HINT = false; ROCKET_ADDRESS = "::1"; ROCKET_PORT = 8222; ROCKET_WORKERS = 4; # more than enough }; }; systemd.services.vaultwarden.serviceConfig.StateDirectory = lib.mkForce "vaultwarden"; services.nginx.virtualHosts.${fqdn} = let inherit (config.services.vaultwarden.config) ROCKET_ADDRESS ROCKET_PORT; in { forceSSL = true; useACMEHost = my.domain; kTLS = true; locations."/" = { proxyPass = "http://[${ROCKET_ADDRESS}]:${toString ROCKET_PORT}"; proxyWebsockets = true; extraConfig = '' client_max_body_size 256M; ''; }; }; services.fail2ban.jails.vaultwarden = lib.mkIf config.services.fail2ban.enable { filter = { INCLUDES.before = "common.conf"; Definition = { failregex = "^.*?Username or password is incorrect. Try again. IP: . Username:.*$"; ignoreregex = ""; }; }; settings = { enabled = true; backend = "systemd"; journalmatch = "_SYSTEMD_UNIT=vaultwarden.service + _COMM=vaultwarden"; port = "http,https"; filter = "vaultwarden"; bantime = "48h"; findtime = "4h"; }; }; }