feat: add Vaultwarden module
- Add native NixOS Vaultwarden service module - Supports WebSocket for real-time sync notifications - Integrates with nginx via extraLocations for /notifications/hub - Configurable signup, invitations, and SMTP settings - Uses SOPS for admin token secret management Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
cbce4aa228
commit
e2facd1fa9
2 changed files with 138 additions and 0 deletions
137
modules/vaultwarden.nix
Normal file
137
modules/vaultwarden.nix
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
# Vaultwarden Module
|
||||
# Provides: Lightweight Bitwarden-compatible password manager
|
||||
#
|
||||
# Usage:
|
||||
# myModules.vaultwarden = {
|
||||
# enable = true;
|
||||
# port = 8222;
|
||||
# domain = "vault.example.com";
|
||||
# };
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.vaultwarden;
|
||||
in
|
||||
{
|
||||
options.myModules.vaultwarden = {
|
||||
enable = lib.mkEnableOption "Vaultwarden password manager";
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8222;
|
||||
description = "Port to expose Vaultwarden on localhost";
|
||||
};
|
||||
|
||||
websocketPort = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 3012;
|
||||
description = "Port for WebSocket notifications";
|
||||
};
|
||||
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "vault.example.com";
|
||||
description = "Public domain name for Vaultwarden";
|
||||
};
|
||||
|
||||
signupAllowed = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Whether to allow new user signups";
|
||||
};
|
||||
|
||||
invitationsAllowed = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to allow organization invitations";
|
||||
};
|
||||
|
||||
showPasswordHint = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to show password hints on login";
|
||||
};
|
||||
|
||||
smtpHost = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
example = "smtp.example.com";
|
||||
description = "SMTP server hostname for email notifications";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
dbBackend = "sqlite";
|
||||
backupDir = "/var/backup/vaultwarden";
|
||||
|
||||
environmentFile = config.sops.templates."vaultwarden.env".path;
|
||||
|
||||
config = {
|
||||
DOMAIN = "https://${cfg.domain}";
|
||||
ROCKET_ADDRESS = "127.0.0.1";
|
||||
ROCKET_PORT = cfg.port;
|
||||
WEBSOCKET_ENABLED = true;
|
||||
WEBSOCKET_ADDRESS = "127.0.0.1";
|
||||
WEBSOCKET_PORT = cfg.websocketPort;
|
||||
|
||||
SIGNUPS_ALLOWED = cfg.signupAllowed;
|
||||
INVITATIONS_ALLOWED = cfg.invitationsAllowed;
|
||||
SHOW_PASSWORD_HINT = cfg.showPasswordHint;
|
||||
|
||||
# SMTP settings (optional)
|
||||
SMTP_HOST = lib.mkIf (cfg.smtpHost != null) cfg.smtpHost;
|
||||
SMTP_FROM = lib.mkIf (cfg.smtpHost != null) "vaultwarden@${cfg.domain}";
|
||||
SMTP_PORT = lib.mkIf (cfg.smtpHost != null) 587;
|
||||
SMTP_SECURITY = lib.mkIf (cfg.smtpHost != null) "starttls";
|
||||
};
|
||||
};
|
||||
|
||||
# SOPS templates
|
||||
sops.templates."vaultwarden.env" = {
|
||||
content = ''
|
||||
ADMIN_TOKEN=${config.sops.placeholder.vaultwarden_admin_token}
|
||||
'' + lib.optionalString (cfg.smtpHost != null) ''
|
||||
SMTP_USERNAME=${config.sops.placeholder.vaultwarden_smtp_user}
|
||||
SMTP_PASSWORD=${config.sops.placeholder.vaultwarden_smtp_password}
|
||||
'';
|
||||
};
|
||||
|
||||
# Secret definitions
|
||||
sops.secrets.vaultwarden_admin_token = { };
|
||||
sops.secrets.vaultwarden_smtp_user = lib.mkIf (cfg.smtpHost != null) { };
|
||||
sops.secrets.vaultwarden_smtp_password = lib.mkIf (cfg.smtpHost != null) { };
|
||||
|
||||
# Add nginx configuration for WebSocket support
|
||||
myModules.nginx.domains.${cfg.domain} = {
|
||||
port = cfg.port;
|
||||
extraConfig = ''
|
||||
client_max_body_size 128M;
|
||||
'';
|
||||
extraLocations."/notifications/hub" = {
|
||||
proxyPass = "http://127.0.0.1:${toString cfg.websocketPort}";
|
||||
extraConfig = ''
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
'';
|
||||
};
|
||||
extraLocations."/notifications/hub/negotiate" = {
|
||||
proxyPass = "http://127.0.0.1:${toString cfg.port}";
|
||||
extraConfig = "";
|
||||
};
|
||||
};
|
||||
|
||||
# Ensure backups directory exists
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/backup/vaultwarden 0750 vaultwarden vaultwarden -"
|
||||
];
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue