2022-10-16 19:06:56 +00:00
|
|
|
{ config, pkgs, lib, ... }:
|
|
|
|
|
|
|
|
let vaultwardenPath = "/var/lib/bitwarden_rs"; # Default service directory
|
|
|
|
|
|
|
|
in {
|
|
|
|
|
2022-10-07 00:44:06 +00:00
|
|
|
options = {
|
|
|
|
|
|
|
|
vaultwardenServer = lib.mkOption {
|
|
|
|
description = "Hostname for Vaultwarden.";
|
|
|
|
type = lib.types.str;
|
2022-12-21 21:18:03 +00:00
|
|
|
default = null;
|
2022-10-07 00:44:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2022-12-21 21:38:34 +00:00
|
|
|
config = lib.mkIf (config.vaultwardenServer != null) {
|
2022-10-07 00:44:06 +00:00
|
|
|
services.vaultwarden = {
|
|
|
|
enable = true;
|
|
|
|
config = {
|
2022-10-16 18:10:11 +00:00
|
|
|
DOMAIN = "https://${config.vaultwardenServer}";
|
2022-10-07 00:44:06 +00:00
|
|
|
SIGNUPS_ALLOWED = false;
|
2022-10-16 18:10:11 +00:00
|
|
|
SIGNUPS_VERIFY = true;
|
|
|
|
INVITATIONS_ALLOWED = true;
|
|
|
|
WEB_VAULT_ENABLED = true;
|
|
|
|
ROCKET_ADDRESS = "127.0.0.1";
|
|
|
|
ROCKET_PORT = 8222;
|
|
|
|
WEBSOCKET_ENABLED = true;
|
|
|
|
WEBSOCKET_ADDRESS = "0.0.0.0";
|
|
|
|
WEBSOCKET_PORT = 3012;
|
|
|
|
LOGIN_RATELIMIT_SECONDS = 60;
|
|
|
|
LOGIN_RATELIMIT_MAX_BURST = 10;
|
|
|
|
ADMIN_RATELIMIT_SECONDS = 300;
|
|
|
|
ADMIN_RATELIMIT_MAX_BURST = 3;
|
2022-10-07 00:44:06 +00:00
|
|
|
};
|
2022-10-16 18:10:11 +00:00
|
|
|
environmentFile = config.secrets.vaultwarden.dest;
|
2022-10-07 00:44:06 +00:00
|
|
|
dbBackend = "sqlite";
|
|
|
|
};
|
2022-10-16 18:10:11 +00:00
|
|
|
|
|
|
|
secrets.vaultwarden = {
|
|
|
|
source = ../../private/vaultwarden.age;
|
|
|
|
dest = "${config.secretsDirectory}/vaultwarden";
|
|
|
|
owner = "vaultwarden";
|
|
|
|
group = "vaultwarden";
|
|
|
|
};
|
|
|
|
|
|
|
|
networking.firewall.allowedTCPPorts = [ 3012 ];
|
|
|
|
|
2022-12-21 21:38:34 +00:00
|
|
|
caddy.routes = [{
|
2022-10-16 18:10:11 +00:00
|
|
|
match = [{ host = [ config.vaultwardenServer ]; }];
|
|
|
|
handle = [{
|
|
|
|
handler = "reverse_proxy";
|
|
|
|
upstreams = [{ dial = "localhost:8222"; }];
|
2022-12-06 17:56:29 +00:00
|
|
|
headers.request.add."X-Real-IP" = [ "{http.request.remote.host}" ];
|
2022-10-16 18:10:11 +00:00
|
|
|
}];
|
|
|
|
}];
|
2022-10-07 00:44:06 +00:00
|
|
|
|
2022-10-16 19:06:56 +00:00
|
|
|
## Backup config
|
|
|
|
|
|
|
|
# Open to groups, allowing for backups
|
|
|
|
systemd.services.vaultwarden.serviceConfig.StateDirectoryMode =
|
|
|
|
lib.mkForce "0770";
|
|
|
|
systemd.tmpfiles.rules = [
|
|
|
|
"f ${vaultwardenPath}/db.sqlite3 0660 vaultwarden vaultwarden"
|
|
|
|
"f ${vaultwardenPath}/db.sqlite3-shm 0660 vaultwarden vaultwarden"
|
|
|
|
"f ${vaultwardenPath}/db.sqlite3-wal 0660 vaultwarden vaultwarden"
|
|
|
|
];
|
|
|
|
|
2022-10-16 20:21:25 +00:00
|
|
|
# Allow litestream and vaultwarden to share a sqlite database
|
2022-10-16 19:06:56 +00:00
|
|
|
users.users.litestream.extraGroups = [ "vaultwarden" ];
|
|
|
|
users.users.vaultwarden.extraGroups = [ "litestream" ];
|
|
|
|
|
|
|
|
# Backup sqlite database with litestream
|
|
|
|
services.litestream = {
|
|
|
|
settings = {
|
|
|
|
dbs = [{
|
|
|
|
path = "${vaultwardenPath}/db.sqlite3";
|
|
|
|
replicas = [{
|
|
|
|
url =
|
2022-12-22 00:31:25 +00:00
|
|
|
"s3://${config.backup.s3.bucket}.${config.backup.s3.endpoint}/vaultwarden";
|
2022-10-16 19:06:56 +00:00
|
|
|
}];
|
|
|
|
}];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
# Don't start litestream unless vaultwarden is up
|
|
|
|
systemd.services.litestream = {
|
|
|
|
after = [ "vaultwarden.service" ];
|
|
|
|
requires = [ "vaultwarden.service" ];
|
|
|
|
};
|
|
|
|
|
|
|
|
# Run a separate file backup on a schedule
|
|
|
|
systemd.timers.vaultwarden-backup = {
|
|
|
|
timerConfig = {
|
|
|
|
OnCalendar = "*-*-* 06:00:00"; # Once per day
|
|
|
|
Unit = "vaultwarden-backup.service";
|
|
|
|
};
|
|
|
|
wantedBy = [ "timers.target" ];
|
|
|
|
};
|
|
|
|
|
|
|
|
# Backup other Vaultwarden data to object storage
|
|
|
|
systemd.services.vaultwarden-backup = {
|
|
|
|
description = "Backup Vaultwarden files";
|
2022-12-22 00:31:25 +00:00
|
|
|
environment.AWS_ACCESS_KEY_ID = config.backup.s3.accessKeyId;
|
2022-10-16 19:06:56 +00:00
|
|
|
serviceConfig = {
|
|
|
|
Type = "oneshot";
|
|
|
|
User = "vaultwarden";
|
|
|
|
Group = "backup";
|
|
|
|
EnvironmentFile = config.secrets.backup.dest;
|
|
|
|
};
|
|
|
|
script = ''
|
|
|
|
${pkgs.awscli2}/bin/aws s3 sync \
|
|
|
|
${vaultwardenPath}/ \
|
2022-12-22 00:31:25 +00:00
|
|
|
s3://${config.backup.s3.bucket}/vaultwarden/ \
|
|
|
|
--endpoint-url=https://${config.backup.s3.endpoint} \
|
2022-10-16 19:06:56 +00:00
|
|
|
--exclude "*db.sqlite3*" \
|
|
|
|
--exclude ".db.sqlite3*"
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2022-10-07 00:44:06 +00:00
|
|
|
}
|