mirror of
https://github.com/nmasur/dotfiles
synced 2024-11-24 15:35:36 +00:00
130 lines
3.8 KiB
Nix
130 lines
3.8 KiB
Nix
# Vaultwarden is an implementation of the Bitwarden password manager backend
|
|
# service, which allows for self-hosting the synchronization of a Bitwarden
|
|
# password manager client.
|
|
|
|
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
...
|
|
}:
|
|
|
|
let
|
|
vaultwardenPath = "/var/lib/bitwarden_rs"; # Default service directory
|
|
in
|
|
{
|
|
|
|
config = lib.mkIf config.services.vaultwarden.enable {
|
|
services.vaultwarden = {
|
|
config = {
|
|
DOMAIN = "https://${config.hostnames.secrets}";
|
|
SIGNUPS_ALLOWED = false;
|
|
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;
|
|
};
|
|
environmentFile = config.secrets.vaultwarden.dest;
|
|
dbBackend = "sqlite";
|
|
};
|
|
|
|
secrets.vaultwarden = {
|
|
source = ../../../private/vaultwarden.age;
|
|
dest = "${config.secretsDirectory}/vaultwarden";
|
|
owner = "vaultwarden";
|
|
group = "vaultwarden";
|
|
};
|
|
|
|
networking.firewall.allowedTCPPorts = [ 3012 ];
|
|
|
|
caddy.routes = [
|
|
{
|
|
match = [ { host = [ config.hostnames.secrets ]; } ];
|
|
handle = [
|
|
{
|
|
handler = "reverse_proxy";
|
|
upstreams = [
|
|
{ dial = "localhost:${builtins.toString config.services.vaultwarden.config.ROCKET_PORT}"; }
|
|
];
|
|
headers.request.add."X-Real-IP" = [ "{http.request.remote.host}" ];
|
|
}
|
|
];
|
|
}
|
|
];
|
|
|
|
# Configure Cloudflare DNS to point to this machine
|
|
services.cloudflare-dyndns.domains = [ config.hostnames.secrets ];
|
|
|
|
## 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"
|
|
];
|
|
|
|
# Allow litestream and vaultwarden to share a sqlite database
|
|
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 = "s3://${config.backup.s3.bucket}.${config.backup.s3.endpoint}/vaultwarden"; }
|
|
];
|
|
}
|
|
];
|
|
};
|
|
};
|
|
|
|
# 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";
|
|
environment.AWS_ACCESS_KEY_ID = config.backup.s3.accessKeyId;
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
User = "vaultwarden";
|
|
Group = "backup";
|
|
EnvironmentFile = config.secrets.backup.dest;
|
|
};
|
|
script = ''
|
|
${pkgs.awscli2}/bin/aws s3 sync \
|
|
${vaultwardenPath}/ \
|
|
s3://${config.backup.s3.bucket}/vaultwarden/ \
|
|
--endpoint-url=https://${config.backup.s3.endpoint} \
|
|
--exclude "*db.sqlite3*" \
|
|
--exclude ".db.sqlite3*"
|
|
'';
|
|
};
|
|
};
|
|
}
|