move bitwarden to SP module

This commit is contained in:
Alexander Tomokhov 2023-12-03 12:29:01 +04:00 committed by Alexander Tomokhov
parent ade4dc08b1
commit c0aa73ca1b
10 changed files with 103 additions and 60 deletions

View file

@ -7,7 +7,6 @@
./users.nix ./users.nix
./letsencrypt/acme.nix ./letsencrypt/acme.nix
./letsencrypt/resolve.nix ./letsencrypt/resolve.nix
./passmgr/bitwarden.nix
./webserver/nginx.nix ./webserver/nginx.nix
./webserver/memcached.nix ./webserver/memcached.nix
# ./resources/limits.nix # ./resources/limits.nix

View file

@ -18,10 +18,7 @@ in
domain = builtins.replaceStrings [ "\n" "\"" "\\" "%" ] [ "\\n" "\\\"" "\\\\" "%%" ] cfg.domain; domain = builtins.replaceStrings [ "\n" "\"" "\\" "%" ] [ "\\n" "\\\"" "\\\\" "%%" ] cfg.domain;
in in
[ [
(if cfg.bitwarden.enable then "d /var/lib/bitwarden 0777 vaultwarden vaultwarden -" else "")
(if cfg.bitwarden.enable then "d /var/lib/bitwarden/backup 0777 vaultwarden vaultwarden -" else "")
"f+ /var/domain 0444 selfprivacy-api selfprivacy-api - ${domain}" "f+ /var/domain 0444 selfprivacy-api selfprivacy-api - ${domain}"
(if cfg.bitwarden.enable then "f /var/lib/bitwarden/.env 0640 vaultwarden vaultwarden - -" else "")
]; ];
system.activationScripts = system.activationScripts =
let let
@ -41,20 +38,5 @@ in
chmod 0440 /var/lib/cloudflare/Credentials.ini chmod 0440 /var/lib/cloudflare/Credentials.ini
chown nginx:acmereceivers /var/lib/cloudflare/Credentials.ini chown nginx:acmereceivers /var/lib/cloudflare/Credentials.ini
''; '';
bitwardenCredentials =
if cfg.bitwarden.enable then ''
mkdir -p /var/lib/bitwarden
token=$(cat /etc/selfprivacy/secrets.json | ${jq} -r '.bitwarden.adminToken')
if [ "$token" == "null" ]; then
# If it's null, delete the contents of the file
> /var/lib/bitwarden/.env
else
echo "ADMIN_TOKEN=$token" > /var/lib/bitwarden/.env
fi
chmod 0640 /var/lib/bitwarden/.env
chown vaultwarden:vaultwarden /var/lib/bitwarden/.env
'' else ''
rm -f /var/lib/bitwarden/.env
'';
}; };
} }

View file

@ -1,27 +0,0 @@
{ pkgs, lib, config, ... }:
let
cfg = config.selfprivacy;
in
{
fileSystems = lib.mkIf cfg.useBinds {
"/var/lib/bitwarden" = {
device = "/volumes/${cfg.bitwarden.location}/bitwarden";
options = [ "bind" ];
};
"/var/lib/bitwarden_rs" = {
device = "/volumes/${cfg.bitwarden.location}/bitwarden_rs";
options = [ "bind" ];
};
};
services.vaultwarden = {
enable = cfg.bitwarden.enable;
dbBackend = "sqlite";
backupDir = "/var/lib/bitwarden/backup";
environmentFile = "/var/lib/bitwarden/.env";
config = {
domain = "https://password.${cfg.domain}/";
signupsAllowed = true;
rocketPort = 8222;
};
};
}

View file

@ -0,0 +1,17 @@
{ config, lib, ... }:
let
inherit (import ./common.nix config) bitwarden-env sp;
in
# FIXME do we really want to delete passwords on module deactivation!?
{
config = lib.mkIf (!sp.modules.bitwarden.enable) {
system.activationScripts.bitwarden =
lib.trivial.warn
(
"bitwarden service is disabled, ${bitwarden-env} will be removed!"
)
''
rm -f -v ${bitwarden-env}
'';
};
}

View file

@ -0,0 +1,5 @@
config:
{
sp = config.selfprivacy;
bitwarden-env = "/var/lib/bitwarden/.env";
}

View file

@ -0,0 +1,5 @@
[
[ "selfprivacy", "domain" ],
[ "selfprivacy", "useBinds" ],
[ "selfprivacy", "modules", "bitwarden" ]
]

View file

@ -0,0 +1,10 @@
{
description = "PoC SP module for Bitwarden password management solution";
outputs = { self }: {
nixosModules.default = _:
{ imports = [ ./module.nix ./cleanup-module.nix ]; };
configPathsNeeded =
builtins.fromJSON (builtins.readFile ./config-paths-needed.json);
};
}

View file

@ -0,0 +1,66 @@
{ config, lib, pkgs, ... }:
let
secrets-filepath = "/etc/selfprivacy/secrets.json";
inherit (import ./common.nix config) bitwarden-env sp;
in
{
options.selfprivacy.modules.bitwarden = {
enable = lib.mkOption {
default = false;
type = with lib.types; nullOr bool;
};
location = lib.mkOption {
default = "sda1";
type = with lib.types; nullOr str;
};
};
config = lib.mkIf config.selfprivacy.modules.bitwarden.enable {
fileSystems = lib.mkIf sp.useBinds {
"/var/lib/bitwarden" = {
device = "/volumes/${sp.modules.bitwarden.location}/bitwarden";
options = [ "bind" ];
};
"/var/lib/bitwarden_rs" = {
device = "/volumes/${sp.modules.bitwarden.location}/bitwarden_rs";
options = [ "bind" ];
};
};
services.vaultwarden = {
enable = true;
dbBackend = "sqlite";
backupDir = "/var/lib/bitwarden/backup";
environmentFile = "${bitwarden-env}";
config = {
domain = "https://password.${sp.domain}/";
signupsAllowed = true;
rocketPort = 8222;
};
};
systemd.services.bitwarden-secrets = {
before = [ "vaultwarden.service" ];
requiredBy = [ "vaultwarden.service" ];
serviceConfig.Type = "oneshot";
path = with pkgs; [ coreutils jq ];
script = ''
set -o nounset
token="$(jq -r '.bitwarden.adminToken' ${secrets-filepath})"
if [ "$token" == "null" ]; then
# If it's null, empty the contents of the file
bitwarden_env=""
else
bitwarden_env="ADMIN_TOKEN=$token"
fi
# TODO revise this permissions mode
install -m 0640 -o vaultwarden -g vaultwarden -DT \
<(printf "%s" "$bitwarden_env") ${bitwarden-env}
'';
};
systemd.tmpfiles.rules = [
"d /var/lib/bitwarden 0777 vaultwarden vaultwarden -"
"d /var/lib/bitwarden/backup 0777 vaultwarden vaultwarden -"
"f ${bitwarden-env} 0640 vaultwarden vaultwarden - -"
];
};
}

View file

@ -18,10 +18,6 @@ jsonData: { lib, ... }:
server = { server = {
provider = lib.attrsets.attrByPath [ "server" "provider" ] "HETZNER" jsonData; provider = lib.attrsets.attrByPath [ "server" "provider" ] "HETZNER" jsonData;
}; };
bitwarden = {
enable = lib.attrsets.attrByPath [ "bitwarden" "enable" ] false jsonData;
location = lib.attrsets.attrByPath [ "bitwarden" "location" ] "sda1" jsonData;
};
gitea = { gitea = {
enable = lib.attrsets.attrByPath [ "gitea" "enable" ] false jsonData; enable = lib.attrsets.attrByPath [ "gitea" "enable" ] false jsonData;
location = lib.attrsets.attrByPath [ "gitea" "location" ] "sda1" jsonData; location = lib.attrsets.attrByPath [ "gitea" "location" ] "sda1" jsonData;

View file

@ -109,16 +109,6 @@ with lib;
############## ##############
# Services # # Services #
############## ##############
bitwarden = {
enable = mkOption {
default = false;
type = types.nullOr types.bool;
};
location = mkOption {
default = "sda1";
type = types.nullOr types.str;
};
};
email = { email = {
location = mkOption { location = mkOption {
default = "sda1"; default = "sda1";