eae5eade56
I want to show how composable this project is. For example, you could just use the Authelia module to add SSO to any service, not just those provided here.
213 lines
6.5 KiB
Nix
213 lines
6.5 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
|
|
let
|
|
cfg = config.shb.vaultwarden;
|
|
|
|
fqdn = "${cfg.subdomain}.${cfg.domain}";
|
|
|
|
template = file: newPath: replacements:
|
|
let
|
|
templatePath = newPath + ".template";
|
|
|
|
sedPatterns = lib.strings.concatStringsSep " " (lib.attrsets.mapAttrsToList (from: to: "-e \"s|${from}|${to}|\"") replacements);
|
|
in
|
|
''
|
|
ln -fs ${file} ${templatePath}
|
|
rm ${newPath} || :
|
|
sed ${sedPatterns} ${templatePath} > ${newPath}
|
|
'';
|
|
in
|
|
{
|
|
options.shb.vaultwarden = {
|
|
enable = lib.mkEnableOption "selfhostblocks.vaultwarden";
|
|
|
|
subdomain = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Subdomain under which Authelia will be served.";
|
|
example = "ha";
|
|
};
|
|
|
|
domain = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "domain under which Authelia will be served.";
|
|
example = "mydomain.com";
|
|
};
|
|
|
|
port = lib.mkOption {
|
|
type = lib.types.port;
|
|
description = "Port on which vaultwarden service listens.";
|
|
default = 8222;
|
|
};
|
|
|
|
ldapEndpoint = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Endpoint for LDAP authentication backend.";
|
|
example = "ldap.example.com";
|
|
};
|
|
|
|
oidcEndpoint = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "OIDC endpoint for SSO";
|
|
example = "https://authelia.example.com";
|
|
};
|
|
|
|
databasePasswordFile = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "File containing the password to connect to the postgresql database.";
|
|
};
|
|
|
|
smtp = lib.mkOption {
|
|
type = lib.types.submodule {
|
|
options = {
|
|
from_address = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "SMTP address from which the emails originate.";
|
|
example = "vaultwarden@mydomain.com";
|
|
};
|
|
from_name = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "SMTP name from which the emails originate.";
|
|
default = "Vaultwarden";
|
|
};
|
|
host = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "SMTP host to send the emails to.";
|
|
};
|
|
security = lib.mkOption {
|
|
type = lib.types.enum [ "starttls" "force_tls" "off" ];
|
|
description = "Security expected by SMTP host.";
|
|
default = "starttls";
|
|
};
|
|
port = lib.mkOption {
|
|
type = lib.types.port;
|
|
description = "SMTP port to send the emails to.";
|
|
default = 25;
|
|
};
|
|
username = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Username to connect to the SMTP host.";
|
|
};
|
|
auth_mechanism = lib.mkOption {
|
|
type = lib.types.enum [ "Login" ];
|
|
description = "Auth mechanism.";
|
|
default = "Login";
|
|
};
|
|
passwordFile = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "File containing the password to connect to the SMTP host.";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
backupConfig = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.anything;
|
|
default = null;
|
|
};
|
|
|
|
debug = lib.mkOption {
|
|
type = lib.types.bool;
|
|
description = "Set to true to enable debug logging.";
|
|
default = false;
|
|
example = true;
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
services.vaultwarden = {
|
|
enable = true;
|
|
dbBackend = "postgresql";
|
|
config = {
|
|
DATA_FOLDER = "/var/lib/bitwarden_rs";
|
|
IP_HEADER = "X-Real-IP";
|
|
SIGNUPS_ALLOWED = false;
|
|
# Disabled because the /admin path is protected by SSO
|
|
DISABLE_ADMIN_TOKEN = true;
|
|
INVITATIONS_ALLOWED = true;
|
|
DOMAIN = "https://${fqdn}";
|
|
USE_SYSLOG = true;
|
|
EXTENDED_LOGGING = cfg.debug;
|
|
LOG_LEVEL = if cfg.debug then "trace" else "info";
|
|
ROCKET_LOG = if cfg.debug then "trace" else "info";
|
|
ROCKET_ADDRESS = "127.0.0.1";
|
|
ROCKET_PORT = cfg.port;
|
|
|
|
SMTP_FROM = cfg.smtp.from_address;
|
|
SMTP_FROM_NAME = cfg.smtp.from_name;
|
|
SMTP_HOST = cfg.smtp.host;
|
|
SMTP_SECURITY = cfg.smtp.security;
|
|
SMTP_USERNAME = cfg.smtp.username;
|
|
SMTP_PORT = cfg.smtp.port;
|
|
SMTP_AUTH_MECHANISM = cfg.smtp.auth_mechanism;
|
|
};
|
|
environmentFile = "/var/lib/bitwarden_rs/vaultwarden.env";
|
|
};
|
|
# We create a blank environment file for the service to start. Then, ExecPreStart kicks in and
|
|
# fills out the environment file for ExecStart to pick it up.
|
|
systemd.tmpfiles.rules = [
|
|
"d /var/lib/bitwarden_rs 0750 vaultwarden vaultwarden"
|
|
"f /var/lib/bitwarden_rs/vaultwarden.env 0640 vaultwarden vaultwarden"
|
|
];
|
|
systemd.services.vaultwarden.preStart =
|
|
let
|
|
envFile = pkgs.writeText "vaultwarden.env" ''
|
|
DATABASE_URL=postgresql://vaultwarden:%DB_PASSWORD%@127.0.0.1:5432/vaultwarden
|
|
SMTP_PASSWORD=%SMTP_PASSWORD%
|
|
'';
|
|
in
|
|
template envFile "/var/lib/bitwarden_rs/vaultwarden.env" {
|
|
"%DB_PASSWORD%" = "$(cat ${cfg.databasePasswordFile})";
|
|
"%SMTP_PASSWORD%" = "$(cat ${cfg.smtp.passwordFile})";
|
|
};
|
|
|
|
shb.nginx.autheliaProtect = [
|
|
{
|
|
inherit (cfg) subdomain domain oidcEndpoint;
|
|
upstream = "http://127.0.0.1:${toString config.services.vaultwarden.config.ROCKET_PORT}";
|
|
autheliaRules = [
|
|
{
|
|
domain = "${fqdn}";
|
|
policy = "two_factor";
|
|
subject = ["group:vaultwarden_admin"];
|
|
resources = [
|
|
"^/admin"
|
|
];
|
|
}
|
|
# There's no way to protect the webapp using Authelia this way, see
|
|
# https://github.com/dani-garcia/vaultwarden/discussions/3188
|
|
{
|
|
domain = fqdn;
|
|
policy = "bypass";
|
|
}
|
|
];
|
|
}
|
|
];
|
|
|
|
shb.postgresql.tcpIPPort= 5432;
|
|
shb.postgresql.passwords = [
|
|
{
|
|
username = "vaultwarden";
|
|
database = "vaultwarden";
|
|
passwordFile = cfg.databasePasswordFile;
|
|
}
|
|
];
|
|
|
|
systemd.services.vaultwarden.serviceConfig.UMask = lib.mkForce "0027";
|
|
# systemd.services.vaultwarden.serviceConfig.Group = lib.mkForce "media";
|
|
users.users.deluge = {
|
|
extraGroups = [ "media" ];
|
|
};
|
|
|
|
users.groups.vaultwarden = {
|
|
members = [ "backup" ];
|
|
};
|
|
|
|
shb.backup.instances.vaultwarden =
|
|
cfg.backupConfig //
|
|
{
|
|
sourceDirectories = [
|
|
config.services.vaultwarden.config.DATA_FOLDER
|
|
];
|
|
};
|
|
};
|
|
}
|