feat: network overhaul

This commit is contained in:
Leon Schwarzäugl 2025-06-15 04:36:40 +02:00
parent 22fe55c284
commit ed15ef02bb
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
34 changed files with 1704 additions and 1037 deletions

1
.envrc
View file

@ -1 +0,0 @@
use flake

View file

@ -22,6 +22,8 @@ creation_rules:
- *toto - *toto
- *surface - *surface
- *nbl - *nbl
- *sync
- *moonside
- path_regex: secrets/repo/[^/]+$ - path_regex: secrets/repo/[^/]+$
key_groups: key_groups:
- pgp: - pgp:
@ -73,6 +75,7 @@ creation_rules:
- *swarsel - *swarsel
age: age:
- *nbl - *nbl
- *moonside
- path_regex: hosts/nixos/winters/secrets/pii.nix.enc - path_regex: hosts/nixos/winters/secrets/pii.nix.enc
key_groups: key_groups:
- pgp: - pgp:

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,19 @@ in
} }
]; ];
options.node = {
name = lib.mkOption {
description = "Node Name.";
type = lib.types.str;
};
secretsDir = lib.mkOption {
description = "Path to the secrets directory for this node.";
type = lib.types.path;
default = ./.;
};
};
config = {
node.name = "drugstore";
home-manager.users."${primaryUser}" = { home-manager.users."${primaryUser}" = {
home = { home = {
stateVersion = "23.05"; stateVersion = "23.05";
@ -112,5 +125,5 @@ in
hostName = "drugstore"; hostName = "drugstore";
wireless.enable = false; wireless.enable = false;
}; };
};
} }

View file

@ -26,7 +26,19 @@ in
tmp.cleanOnBoot = true; tmp.cleanOnBoot = true;
}; };
environment.etc."issue".text = "\4"; environment = {
etc."issue".text = "\4";
persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
{
directory = "/var/lib/syncthing";
user = "syncthing";
group = "syncthing";
mode = "0700";
}
];
};
networking = { networking = {
nftables.enable = lib.mkForce false; nftables.enable = lib.mkForce false;
@ -41,14 +53,17 @@ in
interfaces = { interfaces = {
home-vpn = { home-vpn = {
privateKeyFile = config.sops.secrets.wireguard-private-key.path; privateKeyFile = config.sops.secrets.wireguard-private-key.path;
ips = [ "192.168.3.4/24" ]; ips = [ "192.168.3.4/32" ];
peers = [ peers = [
{ {
publicKey = "NNGvakADslOTCmN9HJOW/7qiM+oJ3jAlSZGoShg4ZWw="; publicKey = "NNGvakADslOTCmN9HJOW/7qiM+oJ3jAlSZGoShg4ZWw=";
name = "moonside"; name = "moonside";
persistentKeepalive = 25; persistentKeepalive = 25;
endpoint = "${config.repo.secrets.common.ipv4}:51820"; endpoint = "${config.repo.secrets.common.ipv4}:51820";
allowedIPs = [ "192.168.3.0/24" ]; allowedIPs = [
"192.168.3.0/24"
"192.168.1.0/24"
];
} }
]; ];
}; };
@ -62,10 +77,22 @@ in
system.stateVersion = "23.11"; system.stateVersion = "23.11";
node.secretsDir = ./secrets;
services = { services = {
nginx = { nginx = {
virtualHosts = { virtualHosts = {
# "newway.swarsel.win" = {
# enableACME = true;
# forceSSL = true;
# acmeRoot = null;
# locations = {
# "/" = {
# proxyPass = "http://192.168.1.2:8080";
# extraConfig = ''
# client_max_body_size 0;
# '';
# };
# };
# };
"syncthing.swarsel.win" = { "syncthing.swarsel.win" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;

View file

@ -22,7 +22,6 @@ in
]; ];
node.secretsDir = ./secrets;
swarselsystems = lib.recursiveUpdate swarselsystems = lib.recursiveUpdate
{ {
firewall = lib.mkForce true; firewall = lib.mkForce true;

View file

@ -4,15 +4,19 @@
"age": [ "age": [
{ {
"recipient": "age16lnmuuxfuxxtty3atnhut8wseppwnhp7rdhmxqd5tdvs9qnjffjq42sqyy", "recipient": "age16lnmuuxfuxxtty3atnhut8wseppwnhp7rdhmxqd5tdvs9qnjffjq42sqyy",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQVXVBVndUU2tDdnlWd3Bu\ndi9DMzFseEtGUVFEWnVEMndWTk9GSGl2SFFjCk9QbnpYS2dYVElJQ28yWGw4Umd0\nS1k0Wk9Yc2hrUUc3dkpGb05EYkFHdVEKLS0tIDYvMUh3NEtlY3FWYVdJbTFRaXlW\neU80R1B0aHprSlI5NkJzRldOSFNMTmcKD4DCuREVbI/Qy3sEyEEWtjW/KbIPuN76\nqoteCCN4mGIR7241e5NwMRlFqxgHyod5mpJfwnUbkYBZZZ/u9PDGmw==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjb21CZ0tQZlNKZkxKMGEz\nUlpMV3lSa1h5TXFNaEpvbWp3ZzZsMUFLd2hnCm9xQlo5Q3RsdW1tSFMxZjVKbjhM\nLzBaS3E1Z0lSQ2lQZEhtclBocE9CcXMKLS0tIHpaYjFIVVRWc2QyQ3hDWmNPODJR\nOFpPQlcwOERMYzhWV3J4ZmpIVUFXcGMKq/CmiIaBFfcx9Muj5LaTQ//ELHmC6WSG\ncJWyfZfrKcPDlXrz7+o9qufLogw3VIkCsTghqsbK6HOKGC5/FbnGSg==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0Z2tONmQxTUhZUW12Z2Jm\nUnoxSnpYcnZDNGNzSko1ckl2RDh3NG1VS2dFCmIwUXhmSk1OUk02S0JPVDR5UWJ4\na0gwWlg0V005ZWxYa29PZ0laS2VqM0kKLS0tIHN5SU9pQ090eHljeXJGWm5hRFQ4\nZ001Nzkyb29RYkNUMDNDNlo4YnVQeTQK34bNIBgxId2+DHKQNVV3Iro3KGkE03Sp\niB1+dADT6nRvGvoyPqnLq/NYfw7eQ6XqYt55zkdCta8v6L1UNUkw8g==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-06-11T13:48:16Z", "lastmodified": "2025-06-11T13:48:16Z",
"mac": "ENC[AES256_GCM,data:6WiY/gpT7V+xQCuotG41Mh+dTSjYT/sg/14Gt7Z7PsrG+WRR33N1OhBV3EVdXeeE8NXkvvoZL/wypgQTWk7wfWpzwhWH478OXc3yaVx7G/nTsDhX/XjKvajpKnXLdn/s2xt9vhPmYuJidR7JYoHN4iv1Lv1eC1mAYKpW4i+sNJk=,iv:ThUxocoeMC1GAfSSeDF9P+m4BZpNuiyWiBrwDPhvNe0=,tag:AxvMKzkG1HBdUqPbbz4Qqg==,type:str]", "mac": "ENC[AES256_GCM,data:6WiY/gpT7V+xQCuotG41Mh+dTSjYT/sg/14Gt7Z7PsrG+WRR33N1OhBV3EVdXeeE8NXkvvoZL/wypgQTWk7wfWpzwhWH478OXc3yaVx7G/nTsDhX/XjKvajpKnXLdn/s2xt9vhPmYuJidR7JYoHN4iv1Lv1eC1mAYKpW4i+sNJk=,iv:ThUxocoeMC1GAfSSeDF9P+m4BZpNuiyWiBrwDPhvNe0=,tag:AxvMKzkG1HBdUqPbbz4Qqg==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2025-06-11T09:18:35Z", "created_at": "2025-06-14T22:31:01Z",
"enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTARAAzg39i9TFW/qilR+HdUpNlgp3KXnW0kwYk7CI8Ie7RJOz\nAop/ak/nokwooxlLGJOiNsFS1//5PxiwOyxZzPmGvTTH8o8tUNZQSULhDnBKHUWG\n44KkerCk2CjbgOrcL7SzaZsFufGRJRcW1700EGatl8D3U1o94isYbArzQqjVXu7Z\nC3VRE80zV25TO9FzxCWCPOj/ML+vo+gq/rgUNQi4JKKBf01Ti142nlJ8hcMX23cb\n2KZkT0VOTz0uouc1J5hXiYmBLVEfsrKUTcamUE1S/dAGuaMe41F8oHt9Rw0YxP+g\nj1PjVuk/F44CRnVVNo8ScihNmvX+ex6+2n1JWmSFkCHtx054bMHTBiVMf86gYiy6\nUqbhuQw52U4/p3U8h7gYjU8yBuHMnCxxL3u1362lz2fDIOxyKtvMH0NGhw8cp7/+\nZbJ6fAUezn8xCXyzhl88XVYNXvM4Vjq6D3qBjjlyDJe9wXXsoPSAUNuVqBDbfnm0\ngOCnT6yOPj1Zv39IvQR+k73ISwBJySpqGgIYvjRtH0JGkXt2exayvWCqeRArkSQ4\nBITQKHFmSrBxo4ndnsTYWC+5v9VBLSUFEXpwrRZY9L5Zqw9Gyqj6hThzTMJiyaiV\ngMzK1JbGaEOd0f8QDfJfwn6VmmhW67w775V98n2wSejWb4WfogDXKe8DbIqrxp6F\nAgwDC9FRLmchgYQBEACPCA/rrYva4WKx9RrDiVkqi0sUM+xHEC17a9FyVXH+grwK\nwB+7prQjx9P4z2/qqlASuBjBjE8MvG4SIgJ6lziLstqrWpNHDuPJoXCTwdYbiqME\nb2V2VPC+PmulvUNcWDVEv4PWIYnKmvlhC/pxsyGtSfxRWgNYGCCx4eTa2OfYgswd\nnHnS+qT+cC6RTjqyeftJxlII2ocMduNpqFr9pVnPlNq3C++6bw/g/Il/YhGFJmr2\nvOl2WPhExh5CSux+oKjXdzsim1Ltz8KOmkSXNCEdI0v/X6OPNfGhnsKLYxaQMJst\nYfu8PIiVHPOYao2kVMstOeH5d/9LLV8MChKLTUelkZWrl1US0yBoCambl77Ooxx3\n14pTXosVSlShSBTGvGjlQS9Jnp+s75TMr4YoBe9UuK22iwtyq69ZKgNiAv+j0LIA\nOWSazSkbwikPsfFLmBuUWJjb5nvM9TUocDdwQIUE2AmmsXNnhnzd8CMnTRE05Go3\n4IVJXKHlKuiW53ji0b2GjPyT/WR9cLIpXRkh/ruTMQ7unljRLY9Ln92spbipg9wW\n4LXxRQ1pJcSOfMuDspLo12fts+gWaxQnkaHxRFoXORDmUmv1la1fHqFCeJRuNKIl\n+u0a9J2ra5S3f1rN2jsHcX4qLe+uq9rH/hKjPmE3CdMv0m9uifP7DfQiTnJcCdJc\nAR4qlFAxNnJyV3zavOuY410oYQYR9s9lqDWI20k1Gkgf8K668hrIPr9FeTuSCuGf\nCqjQ15D9MmBihKbB2gaMuJ6hV6+cAW6QEqUABMu7jT8oFixTHh42F8PFyxc=\n=lm7F\n-----END PGP MESSAGE-----", "enc": "-----BEGIN PGP MESSAGE-----\n\nhQIMAwDh3VI7VctTARAA3TBZeXf6RLph9szeqCtmoXyXDMS1l7NRjhmM85YyxcRo\nTuJQrXA8gmIAen7iVjO/FnndAqd86ddCirpBr/aEKtB9v7Poxx6A/kubV2/EurY7\ngbjWsvY/x6Cqv8IMCTkVdolZNOIYlw4bK3RqERoeWXnvCEXVK2c8fqxmcVoNv6yR\n5leIyApzs7dihbdhK+8nTunIMFJSfP+HQY/wgyowgp3cFVjPe+eTUk8T1xkrir7+\ngfddOHNKnbQWpZRBVj2NE/0dwcKX/rxPHU1sCxOg1TW05jTxavsf8x1+2ST5VLI8\nvttzB8H58OMpDZ1xgoMN7SGSWdTN7BgNcLG4rsGb/GW4+2bxJQ3hS+4aTa59ugXG\nGpqY4ooUopRyOh/hE9xqZ4CXy7IEAGbiBKnwJH+CFlXNygPSURoz9wCH5sgqQ1eA\nGfHrXcGNe2flx9gHZ3g2FUKeORs45CFQLxn2HDSuzVqn9nZfWUFddk9v7G4jSsRg\ntVrSevOXTSFzaSQr5GTQocQILG8HHkg67gKXWMNnk5CiUMVojTljcCej1F5s4Lwg\nljTfTWJMUXfD3Djc2Ap/L+PfxO/Zr0Z5glAndSFQB7aijFaQOR+TVQznRNv90UOk\nwQdF6XANcFMiK3yKQ3xZ6d7lXNTCPlLi5ngakpXhMM1lP0/xFuMWB15IL4yA1FmF\nAgwDC9FRLmchgYQBEADAz9QQ92i1rObvnk3utRhxqizU1SIKhZHEzkdJ+M/9AUQl\nDqj4ge191QMWlEh9jo5ln1abxfVMEjDbomtniPsM5kxPw9qK20M2873ibkps0yNZ\nTdqI2hhB8qBtdEOD/gKq3M27/0c3O7rpsIv8kxxdnmZ9GlRjG9c+SmVqdmZ+PLcP\nOrC+Fq8kQKhINaYdpPoT6x85FW0YLvNiR72grHOKDofqBrFChxapf4HKK6T44TX4\nPKw9G2o/XtN9Z1sfh/R44XsNwTjG8EHrwQLsFYoH3+L7UoNkkNtcwleAl0tkjyVZ\nkq4g0nJKO0KbB1HAM0opamYKOsCUaXQ1MLbXKAmIKy1wuKJR9ibH7E+2Ne41fHJv\n0v243FBnebJP5wlrDY6aBNBX5lPeJBF2q9njp2OnkHWktQD47EyhPhI0hUxN3vzL\n0dSE9/LFgWtvzXqVWIYBWMHToBBiqJRgspw3Jf4Fg0l7Q9p7u2/rwgqbIWMLIDt+\n4tn0ySuiV9jV9dVG3Ho/X7owgr57PPetTvUcU6Ph8Yiv6riLZ+qBy636iGmQd9Zz\n/8nG0BRAnU0YOdWUtvOvBvI+JC5DIs2Trj7Th0AJvlAVLiiR1+0dKk+BdNo/LGE5\nRNNgJIwGHMOZXJonuYfYe15Qy+Qcx3J/NI9VOOfSmzl7A4s8NqtuAt8FNm1cDNJc\nAZp7gi3i3PxxsEXefNMtbFDLe+5yQ4lHro47BxnNAyvnYwKC/VAiwatow9kZGNWn\nc9J/PZinOYPfalwqOl0Zn+pem0hIestNplin7v6ynxa23Cg4g1xUou0ve14=\n=UG0o\n-----END PGP MESSAGE-----",
"fp": "4BE7925262289B476DBBC17B76FD3810215AE097" "fp": "4BE7925262289B476DBBC17B76FD3810215AE097"
} }
], ],

View file

@ -51,7 +51,6 @@ in
system.stateVersion = "23.11"; system.stateVersion = "23.11";
node.secretsDir = ./secrets;
services = { services = {
nginx = { nginx = {
virtualHosts = { virtualHosts = {

View file

@ -28,7 +28,6 @@ in
}; };
node.secretsDir = ./secrets;
swarselsystems = lib.recursiveUpdate swarselsystems = lib.recursiveUpdate
{ {
isImpermanence = false; isImpermanence = false;

View file

@ -54,6 +54,10 @@ in
systemFunc { systemFunc {
specialArgs = { inherit inputs outputs lib self; }; specialArgs = { inherit inputs outputs lib self; };
modules = [ modules = [
{
node.name = host;
node.secretsDir = ../hosts/${type}/${host}/secrets;
}
# put inports here that are for all hosts # put inports here that are for all hosts
inputs.disko.nixosModules.disko inputs.disko.nixosModules.disko
inputs.sops-nix.nixosModules.sops inputs.sops-nix.nixosModules.sops

View file

@ -5,4 +5,8 @@
type = lib.types.path; type = lib.types.path;
default = ./.; default = ./.;
}; };
options.node.name = lib.mkOption {
description = "Node Name.";
type = lib.types.str;
};
} }

View file

@ -0,0 +1,78 @@
{ config, lib, outputs, ... }:
let
inherit (lib)
attrNames
concatMap
concatStringsSep
foldl'
getAttrFromPath
mkMerge
mkOption
mkOptionType
optionals
recursiveUpdate
setAttrByPath
types
;
nodeName = config.node.name;
mkForwardedOption =
path:
mkOption {
type = mkOptionType {
name = "Same type that the receiving option `${concatStringsSep "." path}` normally accepts.";
merge =
_loc: defs:
builtins.filter (x: builtins.isAttrs x -> ((x._type or "") != "__distributed_config_empty")) (
map (x: x.value) defs
);
};
default = {
_type = "__distributed_config_empty";
};
description = ''
Anything specified here will be forwarded to `${concatStringsSep "." path}`
on the given node. Forwarding happens as-is to the raw values,
so validity can only be checked on the receiving node.
'';
};
forwardedOptions = [
[
"services"
"nginx"
"upstreams"
]
[
"services"
"nginx"
"virtualHosts"
]
];
attrsForEachOption =
f: foldl' (acc: path: recursiveUpdate acc (setAttrByPath path (f path))) { } forwardedOptions;
in
{
options.nodes = mkOption {
description = "Options forwarded to the given node.";
default = { };
type = types.attrsOf (
types.submodule {
options = attrsForEachOption mkForwardedOption;
}
);
};
config =
let
getConfig =
path: otherNode:
let
cfg = outputs.nixosConfigurations.${otherNode}.config.nodes.${nodeName} or null;
in
optionals (cfg != null) (getAttrFromPath path cfg);
mergeConfigFromOthers = path: mkMerge (concatMap (getConfig path) (attrNames outputs.nixosConfigurations));
in
attrsForEachOption mergeConfigFromOthers;
}

View file

@ -23,7 +23,7 @@ in
id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA"; id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA";
}; };
"moonside (@oracle)" = { "moonside (@oracle)" = {
id = "YJLYL4Z-JIYHFKX-554ZR7B-YAF3PNH-CX7JF53-NYUMVGL-4EWWASH-GDAMBQA"; id = "VPCDZB6-MGVGQZD-Q6DIZW3-IZJRJTO-TCC3QUQ-2BNTL7P-AKE7FBO-N55UNQE";
}; };
}; };
folders = { folders = {

View file

@ -1,8 +1,11 @@
{ pkgs, config, lib, ... }: { self, pkgs, config, lib, ... }:
let
sopsFile = self + /secrets/general/secrets.yaml;
in
{ {
options.swarselsystems.modules.users = lib.mkEnableOption "user config"; options.swarselsystems.modules.users = lib.mkEnableOption "user config";
config = lib.mkIf config.swarselsystems.modules.users { config = lib.mkIf config.swarselsystems.modules.users {
sops.secrets.swarseluser = lib.mkIf (!config.swarselsystems.isPublic) { neededForUsers = true; }; sops.secrets.swarseluser = lib.mkIf (!config.swarselsystems.isPublic) { inherit sopsFile; neededForUsers = true; };
users = { users = {
mutableUsers = lib.mkIf (!config.swarselsystems.initialSetup) false; mutableUsers = lib.mkIf (!config.swarselsystems.initialSetup) false;

View file

@ -175,7 +175,7 @@ in
id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA"; id = "O7RWDMD-AEAHPP7-7TAVLKZ-BSWNBTU-2VA44MS-EYGUNBB-SLHKB3C-ZSLMOAA";
}; };
"moonside (@oracle)" = { "moonside (@oracle)" = {
id = "YJLYL4Z-JIYHFKX-554ZR7B-YAF3PNH-CX7JF53-NYUMVGL-4EWWASH-GDAMBQA"; id = "VPCDZB6-MGVGQZD-Q6DIZW3-IZJRJTO-TCC3QUQ-2BNTL7P-AKE7FBO-N55UNQE";
}; };
folders = { folders = {
"Documents" = { "Documents" = {

View file

@ -3,6 +3,7 @@ let
cfg = config.services.firefly-iii; cfg = config.services.firefly-iii;
fireflyDomain = "stonks.swarsel.win"; fireflyDomain = "stonks.swarsel.win";
fireflyUser = "firefly-iii"; fireflyUser = "firefly-iii";
serviceName = "firefly";
in in
{ {
options.swarselsystems.modules.server.firefly = lib.mkEnableOption "enable firefly-iii on server"; options.swarselsystems.modules.server.firefly = lib.mkEnableOption "enable firefly-iii on server";
@ -31,6 +32,7 @@ in
APP_KEY_FILE = config.sops.secrets.firefly-iii-app-key.path; APP_KEY_FILE = config.sops.secrets.firefly-iii-app-key.path;
APP_ENV = "local"; APP_ENV = "local";
DB_CONNECTION = "sqlite"; DB_CONNECTION = "sqlite";
TRUSTED_PROXIES = "**";
# AUTHENTICATION_GUARD = "remote_user_guard"; # AUTHENTICATION_GUARD = "remote_user_guard";
# AUTHENTICATION_GUARD_HEADER = "X-User"; # AUTHENTICATION_GUARD_HEADER = "X-User";
# AUTHENTICATION_GUARD_EMAIL = "X-Email"; # AUTHENTICATION_GUARD_EMAIL = "X-Email";
@ -40,6 +42,32 @@ in
}; };
nginx = { nginx = {
virtualHosts = {
"${fireflyDomain}" = {
locations = {
"/api" = {
extraConfig = ''
index index.php;
try_files $uri $uri/ /index.php?$query_string;
add_header Access-Control-Allow-Methods 'GET, POST, HEAD, OPTIONS';
proxy_set_header X-User "";
proxy_set_header X-Email "";
'';
};
};
};
};
};
};
nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:80" = { };
};
};
};
virtualHosts = { virtualHosts = {
"${fireflyDomain}" = { "${fireflyDomain}" = {
enableACME = true; enableACME = true;
@ -49,6 +77,7 @@ in
# hence, only provide certificate # hence, only provide certificate
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://${serviceName}";
extraConfig = '' extraConfig = ''
auth_request /oauth2/auth; auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in; error_page 401 = /oauth2/sign_in;
@ -89,14 +118,7 @@ in
''; '';
}; };
"/api" = { "/api" = {
extraConfig = '' proxyPass = "http://${serviceName}";
index index.php;
try_files $uri $uri/ /index.php?$query_string;
add_header Access-Control-Allow-Methods 'GET, POST, HEAD, OPTIONS';
proxy_set_header X-User "";
proxy_set_header X-Email "";
'';
};
}; };
}; };
}; };

View file

@ -1,4 +1,7 @@
{ lib, config, ... }: { lib, config, ... }:
let
serviceName = "freshrss";
in
{ {
options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server"; options.swarselsystems.modules.server.freshrss = lib.mkEnableOption "enable freshrss on server";
config = lib.mkIf config.swarselsystems.modules.server.freshrss { config = lib.mkIf config.swarselsystems.modules.server.freshrss {
@ -52,7 +55,14 @@
# config.sops.templates.freshrss-env.path # config.sops.templates.freshrss-env.path
# ]; # ];
services.nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:80" = { };
};
};
};
virtualHosts = { virtualHosts = {
"signpost.swarsel.win" = { "signpost.swarsel.win" = {
enableACME = true; enableACME = true;
@ -60,6 +70,7 @@
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://${serviceName}";
extraConfig = '' extraConfig = ''
auth_request /oauth2/auth; auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in; error_page 401 = /oauth2/sign_in;

View file

@ -1,17 +1,22 @@
{ lib, config, ... }: { lib, config, ... }:
let
serviceDomain = "shots.swarsel.win";
servicePort = 3001;
serviceUser = "immich";
serviceName = "immich";
in
{ {
options.swarselsystems.modules.server.immich = lib.mkEnableOption "enable immich on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.immich { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
users.users.immich = { users.users."${serviceUser}" = {
extraGroups = [ "video" "render" "users" ]; extraGroups = [ "video" "render" "users" ];
}; };
# sops.secrets.nextcloudadminpass = { owner = "nextcloud"; };
services.immich = { services.immich = {
enable = true; enable = true;
port = 3001; host = "0.0.0.0";
port = servicePort;
openFirewall = true; openFirewall = true;
mediaLocation = "/Vault/Eternor/Immich"; mediaLocation = "/Vault/Eternor/Immich";
environment = { environment = {
@ -19,16 +24,24 @@
}; };
}; };
networking.firewall.allowedTCPPorts = [ 3001 ];
services.nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"shots.swarsel.win" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:3001"; proxyPass = "http://${serviceName}";
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;

View file

@ -1,8 +1,14 @@
{ pkgs, lib, config, ... }: { pkgs, lib, config, ... }:
let
serviceDomain = "screen.swarsel.win";
servicePort = 8096;
serviceName = "jellyfin";
serviceUser = "jellyfin";
in
{ {
options.swarselsystems.modules.server.jellyfin = lib.mkEnableOption "enable jellyfin on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.jellyfin { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
users.users.jellyfin = { users.users."${serviceUser}" = {
extraGroups = [ "video" "render" "users" ]; extraGroups = [ "video" "render" "users" ];
}; };
nixpkgs.config.packageOverrides = pkgs: { nixpkgs.config.packageOverrides = pkgs: {
@ -19,19 +25,26 @@
}; };
services.jellyfin = { services.jellyfin = {
enable = true; enable = true;
user = "jellyfin"; user = serviceUser;
openFirewall = true; # this works only for the default ports openFirewall = true; # this works only for the default ports
}; };
services.nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"screen.swarsel.win" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:8096"; proxyPass = "http://${serviceName}";
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;
''; '';

View file

@ -1,62 +1,52 @@
{ self, lib, pkgs, config, ... }: { self, lib, pkgs, config, ... }:
let let
certsSopsFile = self + /secrets/certs/secrets.yaml; certsSopsFile = self + /secrets/certs/secrets.yaml;
kanidmDomain = "sso.swarsel.win"; serviceDomain = "sso.swarsel.win";
servicePort = 8300;
serviceUser = "kanidm";
serviceGroup = serviceUser;
serviceName = "kanidm";
oauth2ProxyDomain = "soauth.swarsel.win"; oauth2ProxyDomain = "soauth.swarsel.win";
kanidmPort = 8300;
oauth2ProxyPort = 3004;
in in
{ {
options.swarselsystems.modules.server.kanidm = lib.mkEnableOption "enable kanidm on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.kanidm { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
users.users.kanidm = { users.users."${serviceUser}" = {
group = "kanidm"; group = serviceGroup;
isSystemUser = true; isSystemUser = true;
}; };
users.groups.kanidm = { }; users.groups."${serviceGroup}" = { };
sops = { sops = {
secrets = { secrets = {
"oauth2-cookie-secret" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; }; "kanidm-self-signed-crt" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-self-signed-crt" = { sopsFile = certsSopsFile; owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-self-signed-key" = { sopsFile = certsSopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-self-signed-key" = { sopsFile = certsSopsFile; owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-admin-pw" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-admin-pw" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-idm-admin-pw" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-idm-admin-pw" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-immich" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-immich" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-paperless" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-paperless" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-forgejo" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-forgejo" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-grafana" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-grafana" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-nextcloud" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-nextcloud" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-freshrss" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-freshrss" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; "kanidm-oauth2-proxy" = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
"kanidm-oauth2-proxy" = { owner = "kanidm"; group = "kanidm"; mode = "0440"; }; };
"kanidm-oauth2-proxy-client" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
}; };
templates = { networking.firewall.allowedTCPPorts = [ servicePort ];
"kanidm-oauth2-proxy-client-env" = {
content = ''
OAUTH2_PROXY_CLIENT_SECRET="${config.sops.placeholder.kanidm-oauth2-proxy-client}"
OAUTH2_PROXY_COOKIE_SECRET=${config.sops.placeholder.oauth2-cookie-secret}
'';
owner = "oauth2-proxy";
group = "oauth2-proxy";
mode = "0440";
};
};
};
services = { services = {
kanidm = { kanidm = {
package = pkgs.kanidmWithSecretProvisioning; package = pkgs.kanidmWithSecretProvisioning;
enableServer = true; enableServer = true;
serverSettings = { serverSettings = {
domain = kanidmDomain; domain = serviceDomain;
origin = "https://${kanidmDomain}"; origin = "https://${serviceDomain}";
tls_chain = config.sops.secrets.kanidm-self-signed-crt.path; tls_chain = config.sops.secrets.kanidm-self-signed-crt.path;
tls_key = config.sops.secrets.kanidm-self-signed-key.path; tls_key = config.sops.secrets.kanidm-self-signed-key.path;
bindaddress = "0.0.0.0:${toString kanidmPort}"; bindaddress = "0.0.0.0:${toString servicePort}";
trust_x_forward_for = true; trust_x_forward_for = true;
}; };
enableClient = true; enableClient = true;
@ -177,19 +167,6 @@ in
}; };
}; };
}; };
# freshrss = {
# displayName = "FreshRSS";
# originUrl = "https://signpost.swarsel.win/apps/sociallogin/custom_oidc/kanidm";
# originLanding = "https://signpost.swarsel.win/";
# basicSecretFile = config.sops.secrets.kanidm-freshrss.path;
# allowInsecureClientDisablePkce = true;
# scopeMaps."freshrss.access" = [
# "openid"
# "email"
# "profile"
# ];
# preferShortUsername = true;
# };
oauth2-proxy = { oauth2-proxy = {
displayName = "Oauth2-Proxy"; displayName = "Oauth2-Proxy";
originUrl = "https://${oauth2ProxyDomain}/oauth2/callback"; originUrl = "https://${oauth2ProxyDomain}/oauth2/callback";
@ -226,96 +203,34 @@ in
}; };
}; };
}; };
oauth2-proxy = {
enable = true;
cookie = {
domain = ".swarsel.win";
secure = true;
expire = "900m";
secret = null; # set by service EnvironmentFile
};
clientSecret = null; # set by service EnvironmentFile
reverseProxy = true;
httpAddress = "0.0.0.0:${builtins.toString oauth2ProxyPort}";
redirectURL = "https://${oauth2ProxyDomain}/oauth2/callback";
setXauthrequest = true;
extraConfig = {
code-challenge-method = "S256";
whitelist-domain = ".swarsel.win";
set-authorization-header = true;
pass-access-token = true;
skip-jwt-bearer-tokens = true;
upstream = "static://202";
oidc-issuer-url = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy";
provider-display-name = "Kanidm";
};
provider = "oidc";
scope = "openid email";
loginURL = "https://${kanidmDomain}/ui/oauth2";
redeemURL = "https://${kanidmDomain}/oauth2/token";
validateURL = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy/userinfo";
clientID = "oauth2-proxy";
email.domains = [ "*" ];
};
}; };
systemd.services = { systemd.services = {
kanidm.serviceConfig.RestartSec = "30"; kanidm.serviceConfig.RestartSec = "30";
oauth2-proxy = {
after = [ "kanidm.service" ];
serviceConfig = {
RuntimeDirectory = "oauth2-proxy";
RuntimeDirectoryMode = "0750";
UMask = "007"; # TODO remove once https://github.com/oauth2-proxy/oauth2-proxy/issues/2141 is fixed
RestartSec = "60"; # Retry every minute
EnvironmentFile = [
config.sops.templates.kanidm-oauth2-proxy-client-env.path
];
};
};
}; };
services.nginx = { nodes.moonside.services.nginx = {
upstreams = { upstreams = {
kanidm = { "${serviceName}" = {
servers = { servers = {
"192.168.1.2:${builtins.toString kanidmPort}" = { }; "192.168.1.2:${builtins.toString servicePort}" = { };
};
};
oauth2-proxy = {
servers = {
"192.168.1.2:${builtins.toString oauth2ProxyPort}" = { };
}; };
}; };
}; };
virtualHosts = { virtualHosts = {
"${kanidmDomain}" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "https://kanidm"; proxyPass = "https://${serviceName}";
}; };
}; };
extraConfig = '' extraConfig = ''
proxy_ssl_verify off; proxy_ssl_verify off;
''; '';
}; };
"${oauth2ProxyDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
proxyPass = "http://oauth2-proxy";
};
};
extraConfig = ''
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
'';
};
}; };
}; };
}; };

View file

@ -1,36 +1,48 @@
{ pkgs, lib, config, ... }: { pkgs, lib, config, ... }:
let
serviceName = "kavita";
serviceUser = "kavita";
serviceDomain = "scroll.swarsel.win";
servicePort = 8080;
in
{ {
options.swarselsystems.modules.server.kavita = lib.mkEnableOption "enable kavita on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.kavita { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
calibre calibre
]; ];
users.users."${serviceUser}" = {
users.users.kavita = {
extraGroups = [ "users" ]; extraGroups = [ "users" ];
}; };
sops.secrets.kavita = { owner = "kavita"; }; sops.secrets.kavita = { owner = serviceUser; };
networking.firewall.allowedTCPPorts = [ 8080 ]; networking.firewall.allowedTCPPorts = [ 8080 ];
services.kavita = { services.kavita = {
enable = true; enable = true;
user = "kavita"; user = serviceUser;
settings.Port = 8080; settings.Port = servicePort;
tokenKeyFile = config.sops.secrets.kavita.path; tokenKeyFile = config.sops.secrets.kavita.path;
}; };
services.nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"scroll.swarsel.win" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:8080"; proxyPass = "http://${serviceName}";
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;
''; '';

View file

@ -55,7 +55,7 @@ in
}; };
}; };
networking.firewall.allowedTCPPorts = [ postgresPort ]; networking.firewall.allowedTCPPorts = [ servicePort postgresPort ];
systemd.services.postgresql.postStart = systemd.services.postgresql.postStart =
let let
@ -86,8 +86,16 @@ in
host ${serviceDB} ${serviceDB} 10.88.0.0/16 scram-sha-256 host ${serviceDB} ${serviceDB} 10.88.0.0/16 scram-sha-256
''; '';
}; };
};
nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"${serviceDomain}" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
@ -95,8 +103,7 @@ in
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:${toString servicePort}"; proxyPass = "http://${serviceName}";
};
}; };
}; };
}; };

View file

@ -1,6 +1,13 @@
{ config, lib, pkgs, sops, ... }: { config, lib, pkgs, sops, ... }:
let let
matrixDomain = "swatrix.swarsel.win"; matrixDomain = "swatrix.swarsel.win";
serviceName = "matrix";
synapsePort = 8008;
synapseUser = "matrix-synapse";
whatsappPort = 29318;
telegramPort = 29317;
signalPort = 29328;
baseUrl = "https://${matrixDomain}"; baseUrl = "https://${matrixDomain}";
clientConfig."m.homeserver".base_url = baseUrl; clientConfig."m.homeserver".base_url = baseUrl;
serverConfig."m.server" = "${matrixDomain}:443"; serverConfig."m.server" = "${matrixDomain}:443";
@ -11,8 +18,8 @@ let
''; '';
in in
{ {
options.swarselsystems.modules.server.matrix = lib.mkEnableOption "enable matrix on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.matrix { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
matrix-synapse matrix-synapse
lottieconverter lottieconverter
@ -21,24 +28,24 @@ in
sops = { sops = {
secrets = { secrets = {
matrixsharedsecret = { owner = "matrix-synapse"; }; matrixsharedsecret = { owner = synapseUser; };
mautrixtelegram_as = { owner = "matrix-synapse"; }; mautrixtelegram_as = { owner = synapseUser; };
mautrixtelegram_hs = { owner = "matrix-synapse"; }; mautrixtelegram_hs = { owner = synapseUser; };
mautrixtelegram_api_id = { owner = "matrix-synapse"; }; mautrixtelegram_api_id = { owner = synapseUser; };
mautrixtelegram_api_hash = { owner = "matrix-synapse"; }; mautrixtelegram_api_hash = { owner = synapseUser; };
}; };
templates = { templates = {
"matrix_user_register.sh".content = '' "matrix_user_register.sh".content = ''
register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:8008 register_new_matrix_user -k ${config.sops.placeholder.matrixsharedsecret} http://localhost:${builtins.toString synapsePort}
''; '';
matrixshared = { matrixshared = {
owner = "matrix-synapse"; owner = synapseUser;
content = '' content = ''
registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret} registration_shared_secret: ${config.sops.placeholder.matrixsharedsecret}
''; '';
}; };
mautrixtelegram = { mautrixtelegram = {
owner = "matrix-synapse"; owner = synapseUser;
content = '' content = ''
MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as} MAUTRIX_TELEGRAM_APPSERVICE_AS_TOKEN=${config.sops.placeholder.mautrixtelegram_as}
MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs} MAUTRIX_TELEGRAM_APPSERVICE_HS_TOKEN=${config.sops.placeholder.mautrixtelegram_hs}
@ -49,6 +56,8 @@ in
}; };
}; };
networking.firewall.allowedTCPPorts = [ 8008 8448 ];
systemd = { systemd = {
timers."restart-bridges" = { timers."restart-bridges" = {
wantedBy = [ "timers.target" ]; wantedBy = [ "timers.target" ];
@ -118,9 +127,9 @@ in
public_baseurl = "https://${matrixDomain}"; public_baseurl = "https://${matrixDomain}";
listeners = [ listeners = [
{ {
port = 8008; port = synapsePort;
bind_addresses = [ bind_addresses = [
"127.0.0.1" "0.0.0.0"
# "::1" # "::1"
]; ];
type = "http"; type = "http";
@ -146,13 +155,13 @@ in
registerToSynapse = false; registerToSynapse = false;
settings = { settings = {
homeserver = { homeserver = {
address = "http://localhost:8008"; address = "http://localhost:${builtins.toString synapsePort}";
domain = matrixDomain; domain = matrixDomain;
}; };
appservice = { appservice = {
address = "http://localhost:29317"; address = "http://localhost:${builtins.toString telegramPort}";
hostname = "localhost"; hostname = "0.0.0.0";
port = "29317"; port = telegramPort;
provisioning.enabled = true; provisioning.enabled = true;
id = "telegram"; id = "telegram";
# ephemeral_events = true; # not needed due to double puppeting # ephemeral_events = true; # not needed due to double puppeting
@ -192,13 +201,13 @@ in
registerToSynapse = false; registerToSynapse = false;
settings = { settings = {
homeserver = { homeserver = {
address = "http://localhost:8008"; address = "http://localhost:${builtins.toString synapsePort}";
domain = matrixDomain; domain = matrixDomain;
}; };
appservice = { appservice = {
address = "http://localhost:29318"; address = "http://localhost:${builtins.toString whatsappPort}";
hostname = "127.0.0.1"; hostname = "0.0.0.0";
port = 29318; port = whatsappPort;
database = { database = {
type = "postgres"; type = "postgres";
uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql"; uri = "postgresql:///mautrix-whatsapp?host=/run/postgresql";
@ -239,14 +248,13 @@ in
registerToSynapse = false; registerToSynapse = false;
settings = { settings = {
homeserver = { homeserver = {
address = "http://localhost:8008"; address = "http://localhost:${builtins.toString synapsePort}";
domain = matrixDomain; domain = matrixDomain;
}; };
appservice = { appservice = {
address = "http://localhost:${builtins.toString signalPort}";
address = "http://localhost:29328"; hostname = "0.0.0.0";
hostname = "127.0.0.1"; port = signalPort;
port = 29328;
database = { database = {
type = "postgres"; type = "postgres";
uri = "postgresql:///mautrix-signal?host=/run/postgresql"; uri = "postgresql:///mautrix-signal?host=/run/postgresql";
@ -265,14 +273,22 @@ in
}; };
}; };
}; };
};
# restart the bridges daily. this is done for the signal bridge mainly which stops carrying # restart the bridges daily. this is done for the signal bridge mainly which stops carrying
# messages out after a while. # messages out after a while.
nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString synapsePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"swatrix.swarsel.win" = { "${matrixDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
@ -306,8 +322,7 @@ in
]; ];
locations = { locations = {
"~ ^(/_matrix|/_synapse/client)" = { "~ ^(/_matrix|/_synapse/client)" = {
# proxyPass = "http://localhost:8008"; proxyPass = "http://${serviceName}";
proxyPass = "http://localhost:8008";
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;
''; '';
@ -319,7 +334,4 @@ in
}; };
}; };
}; };
};
} }

View file

@ -1,23 +1,23 @@
{ self, lib, config, ... }: { self, lib, config, ... }:
let let
grafanaDomain = "status.swarsel.win"; serviceDomain = "status.swarsel.win";
servicePort = 3000;
serviceUser = "grafana";
serviceGroup = serviceUser;
moduleName = "monitoring";
grafanaUpstream = "grafana";
prometheusUpstream = "prometheus";
prometheusPort = 9090;
prometheusWebRoot = "prometheus";
in in
{ {
options.swarselsystems.modules.server.monitoring = lib.mkEnableOption "enable monitoring on server"; options.swarselsystems.modules.server."${moduleName}" = lib.mkEnableOption "enable ${moduleName} on server";
config = lib.mkIf config.swarselsystems.modules.server.monitoring { config = lib.mkIf config.swarselsystems.modules.server."${moduleName}" {
sops.secrets = { sops.secrets = {
grafanaadminpass = { grafanaadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
owner = "grafana"; prometheusadminpass = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
}; kanidm-grafana-client = { owner = serviceUser; group = serviceGroup; mode = "0440"; };
prometheusadminpass = {
owner = "grafana";
};
kanidm-grafana-client = {
owner = "grafana";
group = "grafana";
mode = "0440";
};
}; };
users = { users = {
@ -26,12 +26,14 @@ in
extraGroups = [ "nextcloud" ]; extraGroups = [ "nextcloud" ];
}; };
grafana = { "${serviceUser}" = {
extraGroups = [ "users" ]; extraGroups = [ "users" ];
}; };
}; };
}; };
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
services = { services = {
grafana = { grafana = {
enable = true; enable = true;
@ -43,7 +45,7 @@ in
{ {
name = "prometheus"; name = "prometheus";
type = "prometheus"; type = "prometheus";
url = "https://${grafanaDomain}/prometheus"; url = "https://${serviceDomain}/prometheus";
editable = false; editable = false;
access = "proxy"; access = "proxy";
basicAuth = true; basicAuth = true;
@ -66,13 +68,21 @@ in
}; };
settings = { settings = {
security.admin_password = "$__file{/run/secrets/grafanaadminpass}"; analytics.reporting_enabled = false;
users.allow_sign_up = false;
security = {
admin_password = "$__file{/run/secrets/grafanaadminpass}";
cookie_secure = true;
disable_gravatar = true;
};
server = { server = {
domain = grafanaDomain; domain = serviceDomain;
root_url = "https://${grafanaDomain}"; root_url = "https://${serviceDomain}";
http_port = 3000; http_port = servicePort;
http_addr = "0.0.0.0"; http_addr = "0.0.0.0";
protocol = "http"; protocol = "http";
enforce_domain = true;
enable_gzip = true;
}; };
"auth.generic_oauth" = { "auth.generic_oauth" = {
enabled = true; enabled = true;
@ -98,9 +108,9 @@ in
prometheus = { prometheus = {
enable = true; enable = true;
webExternalUrl = "https://status.swarsel.win/prometheus"; webExternalUrl = "https://status.swarsel.win/${prometheusWebRoot}";
port = 9090; port = prometheusPort;
listenAddress = "127.0.0.1"; listenAddress = "0.0.0.0";
globalConfig = { globalConfig = {
scrape_interval = "10s"; scrape_interval = "10s";
}; };
@ -164,24 +174,37 @@ in
}; };
}; };
}; };
};
nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${grafanaUpstream}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
"${prometheusUpstream}" = {
servers = {
"192.168.1.2:${builtins.toString prometheusPort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"${grafanaDomain}" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:3000"; proxyPass = "http://${grafanaUpstream}";
proxyWebsockets = true; proxyWebsockets = true;
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;
''; '';
}; };
"/prometheus" = { "/${prometheusWebRoot}" = {
proxyPass = "http://localhost:9090"; proxyPass = "http://${prometheusUpstream}";
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;
''; '';
@ -191,6 +214,4 @@ in
}; };
}; };
}; };
};
} }

View file

@ -1,7 +1,14 @@
{ pkgs, config, lib, ... }: { pkgs, config, lib, ... }:
let
serviceDomain = "sound.swarsel.win";
servicePort = 4040;
serviceName = "navidrome";
serviceUser = "navidrome";
serviceGroup = serviceUser;
in
{ {
options.swarselsystems.modules.server.navidrome = lib.mkEnableOption "enable navidrome on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.navidrome { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
pciutils pciutils
alsa-utils alsa-utils
@ -10,16 +17,16 @@
users = { users = {
groups = { groups = {
navidrome = { "$(serviceGroup}" = {
gid = 61593; gid = 61593;
}; };
}; };
users = { users = {
navidrome = { "${serviceUser}" = {
isSystemUser = true; isSystemUser = true;
uid = 61593; uid = 61593;
group = "navidrome"; group = serviceGroup;
extraGroups = [ "audio" "utmp" "users" "pipewire" ]; extraGroups = [ "audio" "utmp" "users" "pipewire" ];
}; };
}; };
@ -37,8 +44,8 @@
openFirewall = true; openFirewall = true;
settings = { settings = {
LogLevel = "debug"; LogLevel = "debug";
Address = "127.0.0.1"; Address = "0.0.0.0";
Port = 4040; Port = servicePort;
MusicFolder = "/Vault/Eternor/Music"; MusicFolder = "/Vault/Eternor/Music";
PlaylistsPath = "./Playlists"; PlaylistsPath = "./Playlists";
EnableSharing = true; EnableSharing = true;
@ -70,15 +77,22 @@
}; };
}; };
services.nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"sound.swarsel.win" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:4040"; proxyPass = "http://navidrome";
proxyWebsockets = true; proxyWebsockets = true;
extraConfig = '' extraConfig = ''
auth_request /oauth2/auth; auth_request /oauth2/auth;
@ -125,7 +139,7 @@
''; '';
}; };
"/share" = { "/share" = {
proxyPass = "http://localhost:4040"; proxyPass = "http://navidrome";
proxyWebsockets = true; proxyWebsockets = true;
extraConfig = '' extraConfig = ''
proxy_redirect http:// https://; proxy_redirect http:// https://;
@ -139,7 +153,7 @@
''; '';
}; };
"/rest" = { "/rest" = {
proxyPass = "http://localhost:4040"; proxyPass = "http://navidrome";
proxyWebsockets = true; proxyWebsockets = true;
extraConfig = '' extraConfig = ''
proxy_redirect http:// https://; proxy_redirect http:// https://;

View file

@ -1,20 +1,23 @@
{ pkgs, lib, config, ... }: { pkgs, lib, config, ... }:
let let
nextcloudDomain = "stash.swarsel.win"; serviceDomain = "stash.swarsel.win";
serviceUser = "nextcloud";
serviceGroup = serviceUser;
serviceName = "nextcloud";
in in
{ {
options.swarselsystems.modules.server.nextcloud = lib.mkEnableOption "enable nextcloud on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.nextcloud { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
sops.secrets = { sops.secrets = {
nextcloudadminpass = { nextcloudadminpass = {
owner = "nextcloud"; owner = serviceUser;
group = "nextcloud"; group = serviceGroup;
mode = "0440"; mode = "0440";
}; };
kanidm-nextcloud-client = { kanidm-nextcloud-client = {
owner = "nextcloud"; owner = serviceUser;
group = "nextcloud"; group = serviceGroup;
mode = "0440"; mode = "0440";
}; };
}; };
@ -22,8 +25,12 @@ in
services = { services = {
nextcloud = { nextcloud = {
enable = true; enable = true;
settings = {
trusted_proxies = [ "0.0.0.0" ];
overwriteprotocol = "https";
};
package = pkgs.nextcloud31; package = pkgs.nextcloud31;
hostName = nextcloudDomain; hostName = serviceDomain;
home = "/Vault/apps/nextcloud"; home = "/Vault/apps/nextcloud";
datadir = "/Vault/data/nextcloud"; datadir = "/Vault/data/nextcloud";
https = true; https = true;
@ -39,19 +46,28 @@ in
dbtype = "sqlite"; dbtype = "sqlite";
}; };
}; };
};
nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:80" = { };
};
};
};
virtualHosts = { virtualHosts = {
"${nextcloudDomain}" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
# config is automatically added by nixos nextcloud config. locations = {
# hence, only provide certificate "/" = {
proxyPass = "http://${serviceName}";
};
}; };
}; };
}; };
}; };
}; };
} }

View file

@ -0,0 +1,107 @@
{ lib, config, ... }:
let
kanidmDomain = "sso.swarsel.win";
oauth2ProxyDomain = "soauth.swarsel.win";
oauth2ProxyPort = 3004;
in
{
options.swarselsystems.modules.server.oauth2Proxy = lib.mkEnableOption "enable oauth2-proxy on server";
config = lib.mkIf config.swarselsystems.modules.server.oauth2Proxy {
sops = {
secrets = {
"oauth2-cookie-secret" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
"kanidm-oauth2-proxy-client" = { owner = "oauth2-proxy"; group = "oauth2-proxy"; mode = "0440"; };
};
templates = {
"kanidm-oauth2-proxy-client-env" = {
content = ''
OAUTH2_PROXY_CLIENT_SECRET="${config.sops.placeholder.kanidm-oauth2-proxy-client}"
OAUTH2_PROXY_COOKIE_SECRET=${config.sops.placeholder.oauth2-cookie-secret}
'';
owner = "oauth2-proxy";
group = "oauth2-proxy";
mode = "0440";
};
};
};
networking.firewall.allowedTCPPorts = [ oauth2ProxyPort ];
services = {
oauth2-proxy = {
enable = true;
cookie = {
domain = ".swarsel.win";
secure = true;
expire = "900m";
secret = null; # set by service EnvironmentFile
};
clientSecret = null; # set by service EnvironmentFile
reverseProxy = true;
httpAddress = "0.0.0.0:${builtins.toString oauth2ProxyPort}";
redirectURL = "https://${oauth2ProxyDomain}/oauth2/callback";
setXauthrequest = true;
extraConfig = {
code-challenge-method = "S256";
whitelist-domain = ".swarsel.win";
set-authorization-header = true;
pass-access-token = true;
skip-jwt-bearer-tokens = true;
upstream = "static://202";
oidc-issuer-url = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy";
provider-display-name = "Kanidm";
};
provider = "oidc";
scope = "openid email";
loginURL = "https://${kanidmDomain}/ui/oauth2";
redeemURL = "https://${kanidmDomain}/oauth2/token";
validateURL = "https://${kanidmDomain}/oauth2/openid/oauth2-proxy/userinfo";
clientID = "oauth2-proxy";
email.domains = [ "*" ];
};
};
systemd.services = {
oauth2-proxy = {
# after = [ "kanidm.service" ];
serviceConfig = {
RuntimeDirectory = "oauth2-proxy";
RuntimeDirectoryMode = "0750";
UMask = "007"; # TODO remove once https://github.com/oauth2-proxy/oauth2-proxy/issues/2141 is fixed
RestartSec = "60"; # Retry every minute
EnvironmentFile = [
config.sops.templates.kanidm-oauth2-proxy-client-env.path
];
};
};
};
services.nginx = {
upstreams = {
oauth2-proxy = {
servers = {
"localhost:${builtins.toString oauth2ProxyPort}" = { };
};
};
};
virtualHosts = {
"${oauth2ProxyDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
locations = {
"/" = {
proxyPass = "http://oauth2-proxy";
};
};
extraConfig = ''
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
'';
};
};
};
};
}

View file

@ -1,30 +1,39 @@
{ lib, pkgs, config, ... }: { lib, pkgs, config, ... }:
let
serviceDomain = "scan.swarsel.win";
servicePort = 28981;
serviceUser = "paperless";
serviceGroup = serviceUser;
serviceName = "paperless";
in
{ {
options.swarselsystems.modules.server.paperless = lib.mkEnableOption "enable paperless on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.paperless { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
users.users.paperless = { users.users."${serviceUser}" = {
extraGroups = [ "users" ]; extraGroups = [ "users" ];
}; };
sops.secrets = { sops.secrets = {
paperless_admin = { owner = "paperless"; }; paperless_admin = { owner = serviceUser; };
kanidm-paperless-client = { kanidm-paperless-client = {
owner = "paperless"; owner = serviceUser;
group = "paperless"; group = serviceGroup;
mode = "0440"; mode = "0440";
}; };
}; };
networking.firewall.allowedTCPPorts = [ servicePort ];
services = { services = {
paperless = { paperless = {
enable = true; enable = true;
mediaDir = "/Vault/Eternor/Paperless"; mediaDir = "/Vault/Eternor/Paperless";
dataDir = "/Vault/data/paperless"; dataDir = "/Vault/data/paperless";
user = "paperless"; user = serviceUser;
port = 28981; port = servicePort;
passwordFile = config.sops.secrets.paperless_admin.path; passwordFile = config.sops.secrets.paperless_admin.path;
address = "127.0.0.1"; address = "0.0.0.0";
settings = { settings = {
PAPERLESS_OCR_LANGUAGE = "deu+eng"; PAPERLESS_OCR_LANGUAGE = "deu+eng";
PAPERLESS_URL = "https://scan.swarsel.win"; PAPERLESS_URL = "https://scan.swarsel.win";
@ -84,15 +93,22 @@
) )
''; '';
services.nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"scan.swarsel.win" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:28981"; proxyPass = "http://${serviceName}";
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;
proxy_connect_timeout 300; proxy_connect_timeout 300;

View file

@ -1,26 +1,34 @@
{ lib, config, ... }: { lib, config, ... }:
let let
inherit (config.repo.secrets.common) workHostName; inherit (config.repo.secrets.common) workHostName;
serviceDomain = "storync.swarsel.win";
servicePort = 8384;
serviceUser = "syncthing";
serviceGroup = serviceUser;
serviceName = "syncthing";
in in
{ {
options.swarselsystems.modules.server.syncthing = lib.mkEnableOption "enable syncthing on server"; options.swarselsystems.modules.server."${serviceName}" = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselsystems.modules.server.syncthing { config = lib.mkIf config.swarselsystems.modules.server."${serviceName}" {
users.users.syncthing = { users.users."${serviceUser}" = {
extraGroups = [ "users" ]; extraGroups = [ "users" ];
group = "syncthing"; group = serviceGroup;
isSystemUser = true; isSystemUser = true;
}; };
users.groups.syncthing = { }; users.groups."${serviceGroup}" = { };
networking.firewall.allowedTCPPorts = [ servicePort ];
services.syncthing = { services.syncthing = {
enable = true; enable = true;
user = "swarsel"; user = serviceUser;
group = serviceGroup;
dataDir = "/Vault/data/syncthing"; dataDir = "/Vault/data/syncthing";
configDir = "/Vault/apps/syncthing"; configDir = "/Vault/apps/syncthing";
guiAddress = "0.0.0.0:8384"; guiAddress = "0.0.0.0:${builtins.toString servicePort}";
openDefaultPorts = true; openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
relay.enable = false; relay.enable = false;
settings = { settings = {
urAccepted = -1; urAccepted = -1;
@ -34,13 +42,16 @@ in
"${workHostName}" = { "${workHostName}" = {
id = "YAPV4BV-I26WPTN-SIP32MV-SQP5TBZ-3CHMTCI-Z3D6EP2-MNDQGLP-53FT3AB"; id = "YAPV4BV-I26WPTN-SIP32MV-SQP5TBZ-3CHMTCI-Z3D6EP2-MNDQGLP-53FT3AB";
}; };
"moonside (@oracle)" = {
id = "VPCDZB6-MGVGQZD-Q6DIZW3-IZJRJTO-TCC3QUQ-2BNTL7P-AKE7FBO-N55UNQE";
};
}; };
folders = { folders = {
"Default Folder" = lib.mkForce { "Default Folder" = lib.mkForce {
path = "/Vault/data/syncthing/Sync"; path = "/Vault/data/syncthing/Sync";
type = "receiveonly"; type = "receiveonly";
versioning = null; versioning = null;
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ]; devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
id = "default"; id = "default";
}; };
"Obsidian" = { "Obsidian" = {
@ -50,7 +61,7 @@ in
type = "simple"; type = "simple";
params.keep = "5"; params.keep = "5";
}; };
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ]; devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
id = "yjvni-9eaa7"; id = "yjvni-9eaa7";
}; };
"Org" = { "Org" = {
@ -60,7 +71,7 @@ in
type = "simple"; type = "simple";
params.keep = "5"; params.keep = "5";
}; };
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ]; devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
id = "a7xnl-zjj3d"; id = "a7xnl-zjj3d";
}; };
"Vpn" = { "Vpn" = {
@ -70,7 +81,7 @@ in
type = "simple"; type = "simple";
params.keep = "5"; params.keep = "5";
}; };
devices = [ "sync (@oracle)" "magicant" "${workHostName}" ]; devices = [ "sync (@oracle)" "magicant" "${workHostName}" "moonside (@oracle)" ];
id = "hgp9s-fyq3p"; id = "hgp9s-fyq3p";
}; };
"Documents" = { "Documents" = {
@ -80,27 +91,29 @@ in
type = "simple"; type = "simple";
params.keep = "5"; params.keep = "5";
}; };
devices = [ "magicant" "${workHostName}" ]; devices = [ "magicant" "${workHostName}" "moonside (@oracle)" ];
id = "hgr3d-pfu3w"; id = "hgr3d-pfu3w";
}; };
# ".elfeed" = {
# path = "/Vault/data/syncthing/.elfeed";
# devices = [ "sync (@oracle)" "magicant" "${workHostName}" ];
# id = "h7xbs-fs9v1";
# };
}; };
}; };
}; };
services.nginx = { nodes.moonside.services.nginx = {
upstreams = {
"${serviceName}" = {
servers = {
"192.168.1.2:${builtins.toString servicePort}" = { };
};
};
};
virtualHosts = { virtualHosts = {
"storync.swarsel.win" = { "${serviceDomain}" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
acmeRoot = null; acmeRoot = null;
locations = { locations = {
"/" = { "/" = {
proxyPass = "http://localhost:8384"; proxyPass = "http://${serviceName}";
extraConfig = '' extraConfig = ''
client_max_body_size 0; client_max_body_size 0;
''; '';
@ -110,5 +123,4 @@ in
}; };
}; };
}; };
} }

View file

@ -28,7 +28,6 @@ mkdir -p "$(dirname "$out")"
# Decrypt only if necessary # Decrypt only if necessary
if [[ ! -e $out ]]; then if [[ ! -e $out ]]; then
echo "authenticate:"
agekey=$(sudo ssh-to-age -private-key -i /etc/ssh/sops || sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key) agekey=$(sudo ssh-to-age -private-key -i /etc/ssh/sops || sudo ssh-to-age -private-key -i /etc/ssh/ssh_host_ed25519_key)
SOPS_AGE_KEY="$agekey" sops decrypt --output "$out" "$file" SOPS_AGE_KEY="$agekey" sops decrypt --output "$out" "$file"
fi fi

View file

@ -18,6 +18,7 @@
sops = lib.mkDefault true; sops = lib.mkDefault true;
nginx = lib.mkDefault true; nginx = lib.mkDefault true;
ssh = lib.mkDefault true; ssh = lib.mkDefault true;
oauth2Proxy = lib.mkDefault true;
}; };
}; };
}; };

View file

@ -26,79 +26,93 @@ gitlabforgeuser: ENC[AES256_GCM,data:SrQw69bvtYUcVSePCg==,iv:PlaTHDWJRMtf0HQCG/f
gitlabforgepass: ENC[AES256_GCM,data:WvUFqQtBqqlWvUWhF7x46RcjqA3RPnKSgbd3ZIr1kHO+Vmh5zUh+LA==,iv:+n2VPdLdxFFVHlzRdMCi1lyqGLH+U3RRZX/qfs42I0s=,tag:1iBorR1N1HDRtrqcAcSmvA==,type:str] gitlabforgepass: ENC[AES256_GCM,data:WvUFqQtBqqlWvUWhF7x46RcjqA3RPnKSgbd3ZIr1kHO+Vmh5zUh+LA==,iv:+n2VPdLdxFFVHlzRdMCi1lyqGLH+U3RRZX/qfs42I0s=,tag:1iBorR1N1HDRtrqcAcSmvA==,type:str]
u2f_keys: ENC[AES256_GCM,data:jk1IDfO778V3MCQ8fGoO87lCmqj2Dw+vNRfT4JuWXZ6cB/ARYblnGIpEfogciXJbmYWc4MiKHcO2PkXFdCynpniU3pf3stvNYjTV/TdUpNXkAyho1OjBXwisOMFMcqF3I8yI/XpaMr+5aL6tyMLZ4wIsa0tP4FH74BxCt426uhH8YKLCXREaLRy2PFEQS2MVwKL8i41LDhrkVaJIEMZJ34rvHQqsjckjvwEtCHzBh8XVqdJXAKPq1EgR+9gTVhixwvceDsoSAC0/q2RkSfKhqhOFnj6e09GM7i+o1e98INyABHmd3OHxzTydYk6nrcJHFWIBZlushSgVI0qn+JL+e+2CF8NFtshHH7CGI7ws23n1DZz/BkjQtcfjZEnJv5uAZ9oOt4R0hOSpXn0rGQRNgo5JSMGR37ywyJlaDHmRolS6lRk/7pEdO3jCEMSwjjitWK1/iNDSgEExclQZ/cSL2svPZmwiTKrf0wm/+gbGrd+BxzJmHCopFyNG47kweyR7iMcknF/4+iJj9t2Mi+xOxYdqmQB+I6140DOqcMz9sA0tzqV+Ou6Jf4H4w9sqvI10pnw2sK7OuvFZQ442H+iLelRiZLA/ZCzDCieddLJBtqSsmgEJtJpRsiJXUzDn4CzaAFWrNvNaU/MKAAZwsPeJywmwKgjOUSdHz3YKVDhP/TDqvlzvjKYDte7+6baAYKjVNPJpMy4aQ4/m2FnUEcgRdwct3G8JCe1CORIZSFbO9fkgEgJK6WN3XyQn1nAcDGZdmS95O5Ajmj6a1f5nZQ==,iv:B/Nf1lS0gKW43Nq8QuwJD6GCzzvx35LBw1q1OmZMfF8=,tag:gVNKbyq514J1eoM03JoQYg==,type:str] u2f_keys: ENC[AES256_GCM,data:jk1IDfO778V3MCQ8fGoO87lCmqj2Dw+vNRfT4JuWXZ6cB/ARYblnGIpEfogciXJbmYWc4MiKHcO2PkXFdCynpniU3pf3stvNYjTV/TdUpNXkAyho1OjBXwisOMFMcqF3I8yI/XpaMr+5aL6tyMLZ4wIsa0tP4FH74BxCt426uhH8YKLCXREaLRy2PFEQS2MVwKL8i41LDhrkVaJIEMZJ34rvHQqsjckjvwEtCHzBh8XVqdJXAKPq1EgR+9gTVhixwvceDsoSAC0/q2RkSfKhqhOFnj6e09GM7i+o1e98INyABHmd3OHxzTydYk6nrcJHFWIBZlushSgVI0qn+JL+e+2CF8NFtshHH7CGI7ws23n1DZz/BkjQtcfjZEnJv5uAZ9oOt4R0hOSpXn0rGQRNgo5JSMGR37ywyJlaDHmRolS6lRk/7pEdO3jCEMSwjjitWK1/iNDSgEExclQZ/cSL2svPZmwiTKrf0wm/+gbGrd+BxzJmHCopFyNG47kweyR7iMcknF/4+iJj9t2Mi+xOxYdqmQB+I6140DOqcMz9sA0tzqV+Ou6Jf4H4w9sqvI10pnw2sK7OuvFZQ442H+iLelRiZLA/ZCzDCieddLJBtqSsmgEJtJpRsiJXUzDn4CzaAFWrNvNaU/MKAAZwsPeJywmwKgjOUSdHz3YKVDhP/TDqvlzvjKYDte7+6baAYKjVNPJpMy4aQ4/m2FnUEcgRdwct3G8JCe1CORIZSFbO9fkgEgJK6WN3XyQn1nAcDGZdmS95O5Ajmj6a1f5nZQ==,iv:B/Nf1lS0gKW43Nq8QuwJD6GCzzvx35LBw1q1OmZMfF8=,tag:gVNKbyq514J1eoM03JoQYg==,type:str]
sops: sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: age:
- recipient: age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63 - recipient: age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLbm9WeGd0U0NEMzhpTDhE YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAybmk3azNkM1A0MHBJZElF
SzBpRG5Xc1VUeFdSaXRjMHBKNVltNTY4dHcwCm5DRzFSdG9ML2h2QVlYNm5pUC9Z Y244UzIvQmtSWThPbksrVmNnVEErSldLM3hFCmUxZ3hNaTkxQStNNkwxV2pkdWEr
TTh4TDB2bjhWdWFNQ2ozN09sZWw1WTAKLS0tIDUrcHVmWUc3dkxSS3MrZXB6ZHNi bVQ3U2kzL0ZlOGp1NDJIaTNMYVRZd28KLS0tIFFZUENYdkRIVW1Gb2pjMjdFcG5h
QzZVR3p2VlRyZjNqZk9ZTDBXOWdxYnMK3ZT951oj6lSP+3a1sQL88GUE/jlhfoWy TGRYcFpicXpFdjU4ZEk4RVpnODdBVE0Kq/i8NDtYB3L+kBs0q3NYlzRa22mWG7hi
tkoKh2wNofg3BX9jMCgWm2LFcYxX1fMOoxhXxK2XNEV5et8gxHIxEw== lZZtwXjxTpoWacZgkNnxr/YjiOZLV7wt22TpFSKew1sfs77HvosPRw==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl - recipient: age16vzhcvz8tyxj8e0f47fy0z4p3dsg0ak4vl52ut3l07a0tz465cxslmhevl
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiZTlsOG02b2h3a1FaVW03 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoQmFSM3lPRHN3eE9Gd0Jr
RTFHOXhnaU94elNxNU5jV3hYUWczS25NOGdNClFRYUdoN2pDeEQyenhyYTNDMGxE T2hVb2t2NTEwbVVlNGNhZFZCekRrOEVSbmlvClAra2pnS0NPTXE5aTArZnQrcXNQ
U3Z1elFwVlRXNCtpSlF6TmNYMEgyem8KLS0tIHYrZjB2NVhUdFFXcmFVNnJyd3NM bVY2cnhUeCt0N1ZQRGNDYTZETDFMVmsKLS0tIDRsV1hDM05KcWRFbE5ITGttVk9u
eHpZOStRRWZROU9qd3FZUXU5amhsWjgKIx6s5IpwAkcdRgqjlmMqQTGgx7abZ7OU ek8rTHZYenNzbXVVYnhIUU1DY3h3VEUK5iRHq7pIa4tbYo4mrFUwPT50CWzCLnqK
C5BWpFIARLNUcBOKdORT8fT1m1EnmXKawxitVPHrhAJibvi9XuZIWw== X8Je+8lzkrVZ/M4RNXlgFxyD62LHycOZx342KVVdgl2b8w83xVud1Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1zlnxraee6tddr07xn59mx5rdexw8qxryd53eqlsajasfhfy78fkq705dfg - recipient: age1zlnxraee6tddr07xn59mx5rdexw8qxryd53eqlsajasfhfy78fkq705dfg
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsNm5GWTZabmx0Lzd4VFNH YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoNGxsQU1wcFpIYUxLcnFK
cFRRYUpCeTMxQ01LOThNRzY1T1FiWmt2TUVjClNWbDBnQk9lSmE1MVhieXh0ZENw bjhubFRxMGwzQlpqeWpIbnZBNTQ1cGxVb1M4CmNFTFlCczJMUXJpd09zT3phMHRm
TjN0NnZlTlFMYmoyRTh0NDJHWTRUU2sKLS0tIEVCZElydnI3V0pBQ205b1hqV1U3 OE9sRC8zQ3FDUXoraG9jNUFITHVOYzAKLS0tIEtPSmhVVFNRdEd3d1RobEZMUlhV
aDdsUWc0bkdrcFBZeHhFc3hHeGhvL3MKt1sJlwjY4zc07tIp6qihcGu8UMdgr968 OU9tWkNlSTZWcVZZbk00SjkxSEFZeGMK9Uq8oBYa7TJiaSOv5AIfPqnfH+lM8jeY
KYSO3fGr6XfRWwfzVb9h7FBsWK8ttar0tCK1JF9Hjjp0W9Oqu+AQGA== QEvT/llQqNHo2h1PbzoCd0W+WN81/yVvWhweJUO5GcA4cqE0Ed15yQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age16lnmuuxfuxxtty3atnhut8wseppwnhp7rdhmxqd5tdvs9qnjffjq42sqyy - recipient: age16lnmuuxfuxxtty3atnhut8wseppwnhp7rdhmxqd5tdvs9qnjffjq42sqyy
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2cFFqMDJ5SUQrT1c0VHRH YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYK3FyVzkwZEZLNU5hamMr
MmhYbFJBcjZJTjlFNHBtTk9uWTl0dnNud0Q0ClJBVkhzWXNqdGZIWE9DR3pzMDdq d0ViS3FnVHVjcEtYVlM3VFp5S2dlNXQwQ1EwCjQ5dmhJenpFZmt3aUZsM0J0UFJY
cXBwWWJKWlhwM2RVTCtHbU4yZjdCdVEKLS0tIEFwZFIzakNHT2ovNmoxUGtXTUFD SXhNdHVRbjNYZ2YrYmF1QVVMS1hBbnMKLS0tIDUyRkhTSjVhUnhBTEdtNGNqS2Vi
RVdWbGt0aHcrUGlNWTdUZ2xMa25mYlUKY6AOmHg9+ApJXeoyliXxvqtjwaVLSjH0 cWIrcmxRUFpKM3V3d2ZwVm1STGlpSFkK+VMJXgzdehOUhdevVIfO68wo6VF0Lfj1
6cuZSd05iOSHpR2vbg9jvRiXKXBS6DSN/BoIn+JUif8jY8cTQCMqDQ== gsHJHH6GmQbUsCt+F+fPaXUlrdN+BlCnk4ZMNKutTm2g4thAeiAeng==
-----END AGE ENCRYPTED FILE-----
- recipient: age1glge4e97vgqzh332mqs5990vteezu2m8k4wq3z35jk0q8czw3gks2d7a3h
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4RVRBOHo0ekVGakVadHBZ
SWhKcDVjNHNUcGhlYkxkenovcDdpWUpwdFNzCkt6SlVCaHgxK28xQmtrR045T3Br
MEJjbXhKUTRSREV6YUo5d1RKenR2TUkKLS0tIHhnZW85VHRraWRXZjhWMHI4SUpD
SUp3cUNwN1NXaXpjSm05UkFCcGw2d00K7Ai/uCOnqonQCy20hNjV8YALVlFZFbac
C8QIpfo5FEiONRZNOB2tlr7+ziGC+1ia1DXRvobHOKzgVfmW0VP86A==
-----END AGE ENCRYPTED FILE-----
- recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzeUVtUXZuTVl2SEhVMWdl
RTNsNU1pWmZVeTZ4YzR6RkVwSUc0YVo1VzE0CjNvKzl0QTROUEVnOWNObnFNLzRm
aStSOVIvNC8rOEE4WnRoUHlwV29hTFEKLS0tIG5NM1F5OVIwQUtraURRdW1hT0Ji
azY5dGFTUWhiQ083VlBzdVRrSmZFNTQKqoJy8eP+beb/86Dg7BLaYEmZJG2oMS/I
y1tSw+Ij5TfghzbtKcK++88L7ZPJLRocnKXftFbjutHNKmWW3+oW7Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2024-12-18T22:08:25Z" lastmodified: "2024-12-18T22:08:25Z"
mac: ENC[AES256_GCM,data:vU+7/VLEzwDOrScD/HTo9JBf4ixtmcBmjtSUEtaVHwZuPMJ0OpydwcBPYKvhvU6z9xNecCcuiY7beJ5sq7fnv8XY66TOZWq/2tTZPXdJwpfAyHqBhf7uoCiOmSl53tpWzUFbfT8fQQwjKmBO1079Op24WNWzG3w0i9BsoYTYrpY=,iv:9bLlRg28paoitcK1lFc4ipsgMVvr/zECNozwXU2qJTM=,tag:uRviXeIlwUnvJqHwWuoYcA==,type:str] mac: ENC[AES256_GCM,data:vU+7/VLEzwDOrScD/HTo9JBf4ixtmcBmjtSUEtaVHwZuPMJ0OpydwcBPYKvhvU6z9xNecCcuiY7beJ5sq7fnv8XY66TOZWq/2tTZPXdJwpfAyHqBhf7uoCiOmSl53tpWzUFbfT8fQQwjKmBO1079Op24WNWzG3w0i9BsoYTYrpY=,iv:9bLlRg28paoitcK1lFc4ipsgMVvr/zECNozwXU2qJTM=,tag:uRviXeIlwUnvJqHwWuoYcA==,type:str]
pgp: pgp:
- created_at: "2024-12-24T14:59:46Z" - created_at: "2025-06-14T18:15:57Z"
enc: |- enc: |-
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----
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
=pQM4 =NdF8
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
fp: 4BE7925262289B476DBBC17B76FD3810215AE097 fp: 4BE7925262289B476DBBC17B76FD3810215AE097
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted

View file

@ -2,6 +2,9 @@ swarsel: ENC[AES256_GCM,data:AnxZLN+3ta2Dmg0=,iv:S25Xbbj5K3tWynO4/7XGRp/+XexxoUo
dnstokenfull: ENC[AES256_GCM,data:z9gi0pwfbDyHkKw8rhiGOIlaLUzepAAxQfAH4esla2NkSCx/S0VAiQ==,iv:qtCE+V4vHImViCquHwUEADEzl6dj7PB16PoRqYEgQ6o=,tag:jVfWgt3cx+bpYeMuyesjrA==,type:str] dnstokenfull: ENC[AES256_GCM,data:z9gi0pwfbDyHkKw8rhiGOIlaLUzepAAxQfAH4esla2NkSCx/S0VAiQ==,iv:qtCE+V4vHImViCquHwUEADEzl6dj7PB16PoRqYEgQ6o=,tag:jVfWgt3cx+bpYeMuyesjrA==,type:str]
swarseluser: ENC[AES256_GCM,data:s09lyp9yRPJaSsDXj19s1mosF3O39Fk7Eg==,iv:tVBEFqTQPreul617EU6CfBUhz3Fmt37VAi3GzezeEmA=,tag:9sbJ465VxKoW3/q6ju7hpg==,type:str] swarseluser: ENC[AES256_GCM,data:s09lyp9yRPJaSsDXj19s1mosF3O39Fk7Eg==,iv:tVBEFqTQPreul617EU6CfBUhz3Fmt37VAi3GzezeEmA=,tag:9sbJ465VxKoW3/q6ju7hpg==,type:str]
wireguard-private-key: ENC[AES256_GCM,data:z5TV66YW4FqBVi/3uyE+r9Nkx9vVUOEgwVBXxqi32pecR9dQyLHW9QtFF/A=,iv:+qpRvDlF5v7hQo/S2oYGQ1MDHnxT3yHny1S1SVCainw=,tag:90pIiVx1lSXsin0b2M2SeA==,type:str] wireguard-private-key: ENC[AES256_GCM,data:z5TV66YW4FqBVi/3uyE+r9Nkx9vVUOEgwVBXxqi32pecR9dQyLHW9QtFF/A=,iv:+qpRvDlF5v7hQo/S2oYGQ1MDHnxT3yHny1S1SVCainw=,tag:90pIiVx1lSXsin0b2M2SeA==,type:str]
#ENC[AES256_GCM,data:u/O2rHXqOoTNpOSm,iv:hqhZC9R76P3sPkpQMximrvcTC15IM99QaRZErC9AIc4=,tag:wc2w7iwtfazlwWpnQJV63w==,type:comment]
oauth2-cookie-secret: ENC[AES256_GCM,data:cbNVAkBAWJCN4fLmkYUFhy8v9iE5fB30hFI3nTpZuVIFCnmXPBtlftI58Zg=,iv:q9xjUDOH9M4pW+9YB9dEYSqEu9gpsezbxcGbpORNljU=,tag:KoGNcssD608huewmHeJOxw==,type:str]
kanidm-oauth2-proxy-client: ENC[AES256_GCM,data:wUTfb0r9d7nRb1wmQEOjXwDTM8V56DmOGw==,iv:OMXiObgt4AbKmovT62+P99r0UzGELj37FX+lqW38F0g=,tag:lksIWm0cSLydTZvlxliXgA==,type:str]
sops: sops:
age: age:
- recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh - recipient: age18quey88vge7xytclg2nuq4ncme86dg04lxwczqxczmdchnjg3p0saehsnh
@ -13,8 +16,8 @@ sops:
bURRem1aY203VW0ya0tZWUY3WTJLQ3MKonflaevgNP91G1cVgzoE6/K800kyG6BK bURRem1aY203VW0ya0tZWUY3WTJLQ3MKonflaevgNP91G1cVgzoE6/K800kyG6BK
Goe81HCYFfm86pzv5wV3/38j7fTZNeZnKwPFkMgEUueF1kA8J9V5CA== Goe81HCYFfm86pzv5wV3/38j7fTZNeZnKwPFkMgEUueF1kA8J9V5CA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-13T22:13:23Z" lastmodified: "2025-06-15T09:26:29Z"
mac: ENC[AES256_GCM,data:5iAnRO8VNMf9lg9vrxFROKlMBYOavxND0m7tY91IY7TNy3Hegms72iwFYsRYagOsdNj5udD+jLGGuJTS1thSzpeZJIzDRW8p+Lzr2KNk94aGJKGNnlKPDpthryDJJ/xLonTfovIpJQHPwG26FI2eIVGp1CUh9UXKGOqqZUDMwNQ=,iv:AzZsgeIbmd0xN8adj/hs+VtEFXYaKiXXeQi5kqRQ4E4=,tag:tG5/O4RPcy7wmsu0C2iQ/w==,type:str] mac: ENC[AES256_GCM,data:IcDG5eTj7QQQdsQ7/lhHpJL+L6s0XJltng5yvyG6/sEIRzy4lrUMeR/9BcEiAw0vgz1jWlZR8pNaWZJHc4lEOmMax8rfEhz/3IrWh7MxvCkSSp1Y+JE8xewxzDE57+tR7BxYXjyjmrbQ0C1kiDfUAMVrkXTmV7hA/eY2xFezxXg=,iv:mfyVv5QyRWbCFOmYDsdcmnb7TBFD+5RE84UYc9+j4Yk=,tag:47XAmRcoI2XdQNb2tsL/4Q==,type:str]
pgp: pgp:
- created_at: "2025-06-13T21:18:31Z" - created_at: "2025-06-13T21:18:31Z"
enc: |- enc: |-

View file

@ -1,5 +1,5 @@
{ {
"data": "ENC[AES256_GCM,data:1+srGBXtYZCAsE32yEhH+1Ab3uebTDITbY8oQDIDkrqNMSGpfFH8i9nS0gmGHD35CKxn+2da+LxzWd7cjDwPre92D5+1K55RzrvWHwnq/0gYdNqvJZGKyJ71HJyr0wPSjK5Ne+fOPiYw+L4vwVukPTJcJHhe7H58Ia6rItnvdBe/RmUbVkTuVB1WEG9AYN1paQorNobSdNTTSCSXRIGTSaQfjk0xJ8B2wOALOXHoxBFUGR0SXIdk9M1CJ48uYU4JQ/RQguB3fG+PAbFYwm8B53SCo9zEnfonwmnFVe27Qm3Lz275stI0NuQiHuSJrcaXVyBX+So7xKPAMI2AyzPVhCukanPZxYwWMtFBYn5jgGL4P3aidsoqo0u0+PdIAr7U3dcDrpTnCQHiX71mG5h3CpKIs2yRhHmcnI27EEpVQv6LilZBHjT8tMUeS7H0UJlWsyj7lDzVl2WO6d7TeA8nnrNH5YWVzsAKCIsjvFYwwIJhdLWaVK9aI2VXJQEJAhQLbBKZ5pJwajw4GpeFu0ISyqo/foIzvaGvnW2fuxWwLYeGDlzPrqogT5433kFEambwXbdHGGdzuYqiWMLrysE+3AEPpOhwFuDpncFgGkHoZV+gZVcpG8TRTmKD9W4IK37sJqDrGGeWxvB2+/HE6ZbQqU05tdbyjXdHsXvAXSnSrLwqXVrds1zYk3g0bKjlZSwCBwKOhGU7JKsq1eBvJ1NgvBl7+JWtpCYBjCGaWM5whqxEkW0MR/7Xxkf0d5X5SDJEVUC8zAABiagNRfbyH8uix4NZCQyJeSFqeYMMWbXr3Z2XGyPXuKKwZC+vK6Kd,iv:D3wUi87sNqZG33GGlDnB1msJF3xvy7dMqQ/8gE5fpZU=,tag:cBqADzZhfiMGMKCUGTpHUg==,type:str]", "data": "ENC[AES256_GCM,data:+CYlqWYF5RJ8/uzhGEG5uA638DmLc9vCMwRBiBZVFkUzb7Ja+jAZ5GVy6Sxw5SwqJsmZEdqKdGCV2TzTO1vcDBixJlwQlCQcwFDdi3W7ZokzEMdOP03vgx5qgd3kwwe0fEuBS7byragm6rt4Vg3bkBa4uwq1cnQEjKmGa69UTaG0FScKHBeFkEHLBUwIPgH0H52JRQurd8eCF1MPYKNTulpta8pDFb/OuM11zjdNfxJaoqtTN7I0PvS/RHTTuLtuNOi3vv8rJ+PeR3xj3B6mgBwWAews7MdlyfTrgOMd9BWFgnRrWBK4WcPa9gfOgEF4A1jkrh7l23lRo1xpWZFYhGEOl/zVQn6KsPwKtS8VU1e7gLi8EOSUMMkBPyAMfGu0SpRDUwISU0joVzeEvOZ5CrteB683qUYf16jWWfAx1v/7/gr2H01UGOpUsc/z4CPv5jeYzr2mBEa76wSBqSm9KjDS4uea6bHMFvLyVGDwg+ljzM+L5sAMEOoBSY2Pojb3lZuOwve6NI9R6aRRoKbuhLyHgcIH6dk1Dc9+scvrOeDMbzp2oppqLfW2uiG6mTcfvE5leJxQeeUV23LXhZsCkK2+UU5JfVj9JWLp6EBZWZdpTjOHDrMUdPBJtXvrirUu4W1s3Ny36o05d0esav4m+qEhwJEO3iDSAMRzQMFGdZhQOKgAgqCXyg3wUh47qdx54SMeyyLhQIHkz9AmeCeYmALnOxGrUrNGfnytNvPOA41qlmwD4e4yLeiwAowuWnVfw7GC5UGU9O5/B42VWN4WdsNgY6SdjBaRUaotil/UuDVISTczcwI3+NWqLtC5,iv:WmrLJN951DRaXKDVi7KHURWRRRusPisETUy+BH5U6/s=,tag:u36D+o4sA94D5W7CmjAizw==,type:str]",
"sops": { "sops": {
"age": [ "age": [
{ {
@ -27,8 +27,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtU240VjVRZmJ5TGsrclJF\nRXRLbTRCZURtR0Z3d2E2eDNNeGRDODlXVEY4CllTeVFYbDJQWlRSS1RFLzAxSnlM\nZi9NU1c3cWo3YWRLcUJ2U2ZFWFBBVEEKLS0tIGtmZU9qSWdBT3RDeStaaFFDSWtk\ndkUzZXJwZUl4LzVxYXdidmxXRnNnclUKyAMZqCKSY/RQvTR4bbjLaPnGKwdBcHXc\nvtiVSrLdIdzMa6id/J07TJH5UesUmcp0wjU41MDa4aMBLy+cXhuBHA==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtU240VjVRZmJ5TGsrclJF\nRXRLbTRCZURtR0Z3d2E2eDNNeGRDODlXVEY4CllTeVFYbDJQWlRSS1RFLzAxSnlM\nZi9NU1c3cWo3YWRLcUJ2U2ZFWFBBVEEKLS0tIGtmZU9qSWdBT3RDeStaaFFDSWtk\ndkUzZXJwZUl4LzVxYXdidmxXRnNnclUKyAMZqCKSY/RQvTR4bbjLaPnGKwdBcHXc\nvtiVSrLdIdzMa6id/J07TJH5UesUmcp0wjU41MDa4aMBLy+cXhuBHA==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-06-13T22:20:13Z", "lastmodified": "2025-06-14T20:56:55Z",
"mac": "ENC[AES256_GCM,data:W+k2UGDwWcS7/rBZQZE8ruU7ma429CdzmbtINtLF2DGz7Ofzj2EwkrVQeEtbUt9k+psSzsxnXD9hnrPzjgId7DGXlKPG55kwL++zuPvAe6qvJ05UhRahJfxBgpD+xcBHkCkQjgQcafOXha+BRKq2u5iSbB6aLxHq0i30xOq/n0E=,iv:g8xtWd6nDCs6WWx1CQRQAFExGFH9YQmgGBzyQNS9q2I=,tag:b9tLJz/JOFnegPQR8h5Zuw==,type:str]", "mac": "ENC[AES256_GCM,data:03b5V3zO7mmoP050rrgBaZqR7ik3eioW3PJt0dKab85zOaOXwyq22Ps7vftRV6tQ5S83dSXsAnXvYmdUQ3F3h0Z4zqHB680r1uJG24kJLik+9Pl1a8SwQFB0/yWCaXfKqCZhXIoektl83oBaoWFoCpTuOtYmdoF3rt2mVounIHM=,iv:vAzVQRgQyIMUbwWCG/r4n/QXP/67QN7B651tIzU4TpU=,tag:zcgKO/8g1VmhXHfU7XyeYA==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2025-06-13T20:13:06Z", "created_at": "2025-06-13T20:13:06Z",