189 lines
5.8 KiB
Nix
189 lines
5.8 KiB
Nix
# Helper module to configure multiple services with onion and clearnet access, as well as optional backups.
|
|
# Each service can specify its own URL, onion settings, data directory, and backup options.
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
...
|
|
}: let
|
|
cfg = config.distrust.services;
|
|
backup_cfg = config.distrust.backups;
|
|
in {
|
|
options = {
|
|
distrust = {
|
|
services = lib.mkOption {
|
|
description = "Services configuration map";
|
|
type = lib.types.attrsOf (
|
|
lib.types.submodule {
|
|
options = {
|
|
url = lib.mkOption {
|
|
description = "Clearnet URL";
|
|
type = lib.types.str;
|
|
};
|
|
dataDir = lib.mkOption {
|
|
description = "Path to stateful storage for service";
|
|
type = lib.types.nullOr lib.types.path;
|
|
};
|
|
onion = lib.mkOption {
|
|
description = "Onion service settings";
|
|
type = lib.types.submodule {
|
|
options = {
|
|
url = lib.mkOption {
|
|
description = ".onion URL";
|
|
type = lib.types.str;
|
|
};
|
|
secretKey = lib.mkOption {
|
|
description = "Path to onion secret key file";
|
|
type = lib.types.path;
|
|
};
|
|
};
|
|
};
|
|
default = {};
|
|
};
|
|
backup = lib.mkOption {
|
|
description = "Backup configuration";
|
|
type = lib.types.submodule {
|
|
options = {
|
|
enable = lib.mkOption {
|
|
description = "Enable backups for this service";
|
|
type = lib.types.bool;
|
|
default = false;
|
|
};
|
|
paths = lib.mkOption {
|
|
description = "Paths to back up";
|
|
type = lib.types.listOf lib.types.str;
|
|
default = [];
|
|
};
|
|
database = lib.mkOption {
|
|
description = "Database to back up";
|
|
type = lib.types.nullOr lib.types.str;
|
|
default = null;
|
|
};
|
|
};
|
|
};
|
|
default = {};
|
|
};
|
|
virtualHostConfig = lib.mkOption {
|
|
description = "Caddy virtual host config";
|
|
type = lib.types.str;
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = {};
|
|
};
|
|
backups = lib.mkOption {
|
|
description = "Global backup configuration";
|
|
type = lib.types.submodule {
|
|
options = {
|
|
borgRepository = lib.mkOption {
|
|
description = "Borg backup repository URL";
|
|
type = lib.types.str;
|
|
};
|
|
borgSSHKey = lib.mkOption {
|
|
description = "Path to SSH key for Borg backup repository";
|
|
type = lib.types.path;
|
|
};
|
|
borgPassCommand = lib.mkOption {
|
|
description = "Command to retrieve Borg repository passphrase";
|
|
type = lib.types.str;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
config = {
|
|
services = {
|
|
tor.relay.onionServices =
|
|
builtins.foldl'
|
|
(acc: key:
|
|
acc
|
|
// {
|
|
"${key}" = {
|
|
map = [80];
|
|
inherit (cfg.${key}.onion) secretKey;
|
|
};
|
|
})
|
|
{}
|
|
(builtins.attrNames cfg);
|
|
|
|
caddy = {
|
|
enable = true;
|
|
virtualHosts = builtins.foldl' (acc: key: let
|
|
site = cfg.${key};
|
|
vhostKey = "${site.url} ${site.onion.url}";
|
|
extraCfg = ''
|
|
${site.virtualHostConfig or ""}
|
|
header Onion-Location ${site.onion.url}
|
|
'';
|
|
in
|
|
acc
|
|
// {
|
|
"${vhostKey}" = {
|
|
extraConfig = extraCfg;
|
|
};
|
|
}) {} (builtins.attrNames cfg);
|
|
};
|
|
|
|
borgbackup.jobs =
|
|
builtins.foldl'
|
|
(acc: key: let
|
|
site = cfg.${key};
|
|
dump = site.backup.database;
|
|
paths = builtins.concatLists [
|
|
site.backup.paths
|
|
(
|
|
if dump != null
|
|
then ["/var/backup/${key}.sql"]
|
|
else []
|
|
)
|
|
];
|
|
readWritePaths = lib.mkIf (dump != null) [ "/var/backup/postgres/" ];
|
|
preHook = lib.mkIf (dump != null) ''
|
|
mkdir -p /var/backup/postgres
|
|
${pkgs.sudo}/bin/sudo -u postgres ${pkgs.postgresql}/bin/pg_dump ${dump} > /var/backup/postgres/${key}.sql
|
|
'';
|
|
postHook = lib.mkIf (dump != null) ''
|
|
rm -f /var/backup/postgres/${key}.sql
|
|
'';
|
|
in
|
|
if site.backup.enable
|
|
then
|
|
acc
|
|
// {
|
|
"${key}" = {
|
|
repo = lib.strings.concatStrings [backup_cfg.borgRepository "/./${key}"];
|
|
environment = {
|
|
BORG_RSH = "ssh -i ${backup_cfg.borgSSHKey} -o 'StrictHostKeyChecking=no'";
|
|
};
|
|
inherit paths;
|
|
encryption = {
|
|
mode = "keyfile";
|
|
passCommand = backup_cfg.borgPassCommand;
|
|
};
|
|
compression = "auto,lzma";
|
|
startAt = "daily";
|
|
prune.keep = {
|
|
daily = 7;
|
|
weekly = 4;
|
|
monthly = -1;
|
|
};
|
|
inherit readWritePaths;
|
|
inherit preHook;
|
|
inherit postHook;
|
|
};
|
|
}
|
|
else acc) {} (builtins.attrNames cfg);
|
|
};
|
|
|
|
systemd.tmpfiles.settings = {
|
|
"99-borgdatabasebackups"."/var/backup/postgres".d = {
|
|
user = "root";
|
|
group = "root";
|
|
mode = "0755";
|
|
};
|
|
};
|
|
};
|
|
}
|