feat[server]: add firezone
Some checks failed
Build and Deploy / build (push) Has been cancelled
Build and Deploy / deploy (push) Has been cancelled

This commit is contained in:
Leon Schwarzäugl 2026-01-01 02:30:10 +01:00
parent 2d766e8246
commit 2ff914d49d
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
69 changed files with 2415 additions and 1132 deletions

File diff suppressed because it is too large Load diff

31
flake.lock generated
View file

@ -1600,11 +1600,11 @@
},
"nixpkgs-dev": {
"locked": {
"lastModified": 1763648956,
"narHash": "sha256-JBATYs0HPlATioA2kYFwUAsnzWv9Bd2tXqeCOr/ix6I=",
"lastModified": 1767131767,
"narHash": "sha256-APHjXWyLmNKFNXoVU7Z82L8zUeSpR1/owKFryitWSsg=",
"owner": "Swarsel",
"repo": "nixpkgs",
"rev": "230b56741730ede84e7e488d11cb34044f5b54c7",
"rev": "449fa265ea9c67c1ea9b1c3d8121959e2ce348d3",
"type": "github"
},
"original": {
@ -1781,6 +1781,22 @@
"type": "github"
}
},
"nixpkgs-stable25_11": {
"locked": {
"lastModified": 1767047869,
"narHash": "sha256-tzYsEzXEVa7op1LTnrLSiPGrcCY6948iD0EcNLWcmzo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "89dbf01df72eb5ebe3b24a86334b12c27d68016a",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable_2": {
"locked": {
"lastModified": 1763622513,
@ -1799,16 +1815,16 @@
},
"nixpkgs-stable_3": {
"locked": {
"lastModified": 1763622513,
"narHash": "sha256-1jQnuyu82FpiSxowrF/iFK6Toh9BYprfDqfs4BB+19M=",
"lastModified": 1767047869,
"narHash": "sha256-tzYsEzXEVa7op1LTnrLSiPGrcCY6948iD0EcNLWcmzo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c58bc7f5459328e4afac201c5c4feb7c818d604b",
"rev": "89dbf01df72eb5ebe3b24a86334b12c27d68016a",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-25.05",
"ref": "nixos-25.11",
"repo": "nixpkgs",
"type": "github"
}
@ -2653,6 +2669,7 @@
"nixpkgs-stable24_05": "nixpkgs-stable24_05",
"nixpkgs-stable24_11": "nixpkgs-stable24_11",
"nixpkgs-stable25_05": "nixpkgs-stable25_05",
"nixpkgs-stable25_11": "nixpkgs-stable25_11",
"nswitch-rcm-nix": "nswitch-rcm-nix",
"nur": "nur",
"pre-commit-hooks": "pre-commit-hooks_3",

View file

@ -28,10 +28,11 @@
smallpkgs.url = "github:nixos/nixpkgs/08fcb0dcb59df0344652b38ea6326a2d8271baff?narHash=sha256-HXIQzULIG/MEUW2Q/Ss47oE3QrjxvpUX7gUl4Xp6lnc%3D&shallow=1";
nixpkgs-dev.url = "github:Swarsel/nixpkgs/main";
nixpkgs-kernel.url = "github:NixOS/nixpkgs/063f43f2dbdef86376cc29ad646c45c46e93234c?narHash=sha256-6m1Y3/4pVw1RWTsrkAK2VMYSzG4MMIj7sqUy7o8th1o%3D"; #specifically pinned for kernel version
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.05";
nixpkgs-stable.url = "github:NixOS/nixpkgs/nixos-25.11";
nixpkgs-stable24_05.url = "github:NixOS/nixpkgs/nixos-24.05";
nixpkgs-stable24_11.url = "github:NixOS/nixpkgs/nixos-24.11";
nixpkgs-stable25_05.url = "github:NixOS/nixpkgs/nixos-25.05";
nixpkgs-stable25_11.url = "github:NixOS/nixpkgs/nixos-25.11";
home-manager = {
# url = "github:nix-community/home-manager";

View file

@ -62,7 +62,6 @@
attic = true;
garage = true;
hydra = false;
dns-hostrecord = true;
};
}

View file

@ -33,7 +33,6 @@
swarselmodules.server = {
bastion = true;
dns-hostrecord = true;
# ssh = false;
};

View file

@ -108,6 +108,5 @@ in
minecraft = true;
restic = true;
diskEncryption = lib.mkForce false;
dns-hostrecord = true;
};
}

View file

@ -1,4 +1,4 @@
{ self, lib, minimal, ... }:
{ self, config, lib, minimal, ... }:
{
imports = [
./hardware-configuration.nix
@ -25,6 +25,8 @@
isCloud = true;
isBastionTarget = true;
};
globals.general.dnsServer = config.node.name;
} // lib.optionalAttrs (!minimal) {
swarselprofiles = {
server = true;
@ -32,6 +34,7 @@
swarselmodules.server = {
nsd = true;
dns-hostrecord = true;
};
networking.nftables.firewall.zones.untrusted.interfaces = [ "lan" ];
}

View file

@ -1,4 +1,4 @@
{ self, lib, minimal, ... }:
{ self, config, lib, minimal, ... }:
{
imports = [
./hardware-configuration.nix
@ -12,6 +12,8 @@
icon = "devices.cloud-server";
};
globals.general.webProxy = config.node.name;
swarselsystems = {
flakePath = "/root/.dotfiles";
info = "VM.Standard.A1.Flex, 2 vCPUs, 8GB RAM";
@ -27,7 +29,6 @@
server = {
wireguard.interfaces = {
wgProxy = {
# ifName = "wg";
isServer = true;
peers = [
"moonside"
@ -47,8 +48,16 @@
swarselmodules.server = {
nginx = true;
oauth2-proxy = true;
dns-hostrecord = true;
wireguard = true;
firezone = true;
};
networking.nftables = {
firewall.zones.untrusted.interfaces = [ "lan" ];
chains.forward.dnat = {
after = [ "conntrack" ];
rules = [ "ct status dnat accept" ];
};
};
}

View file

@ -1,5 +1,5 @@
{
"data": "ENC[AES256_GCM,data:UKXEKxP1SDqQWktd3eQzkoqsk6k3m9Rj+JNk3xmdZmp5p+pXnY+uDltSIL2PTsOy7wtf4gp16jze1PhHvYojuN2nnou/D1KJALPHBgGiR8CgBlbX5nrCbtHrs4SZq+M7QihRV8lsG8gU0aIm0lDO83cJ0boUfnZdexDPjcuhYJj5nmgOG1bV60LOJNg7yn//hlVhovrf7ygXOk9HirDMmK9MVkKw5utD7iE4Cm7txrK1z9rQLJYM3kzwsWJAGkIc/IbI4Css10ScNK9VMKU4B596Dv2eCHvSIUJ8Y8AJrE/1+jp8XQW4aUMcFsbKpwjL2mOm0DSFupr/D60vJ1j5ovEIT4Vt51H4cpcBduBUCHoRZ1S/fZePxYaPunEI9lJVSQeANGevqXmvd8SSpO8YFN2S06CsFcx8hadQpq79uD7hm4tZzNUFOm2fytY9WMl0YWlSM4g3U30tKVVo+RMmm43oMaStOiyXUyohXjKY5QJqI+rJRRifKUhfze4Z4aGn,iv:nOU57gwkc3hld/+IqqHYtEiJYXzOFwTaG6cNEl7ZNHk=,tag:kRp580c9haQSQmOw2hBvrw==,type:str]",
"data": "ENC[AES256_GCM,data:mQPfK2Dh2ACae0a+1GRHY/CV0JpHH8JO+td+RR17UXyq5v/OF6YDfS7loIpQvImEAs6AvIzIdyq0848Fh/34kh/K2ZAq4AknW9jQx5YyP4nbk8/q1/dk+95c0u98WnN6mw3BFHHesKYCfGy82GMnu00Ffxu7WSYzTKxq6yvROS7ugefRjsoMsuJcEeHmoIBgEIjXntGT4DxJjw4RhWPm+unSmce9SXfqbAuuizHm/S5URYvicIzalSITlfFBrpKWNxNe9fC2etDb/fB+uMpG28rmB98ov1W0X/W3JOUhASXVhB+YCau8XdIRPopEnkR4Wm1HD+exJ3CToJMgrdmv5Cj9rJoFI0jvApRpjBix5qDrTsbn3iWbv/QYuCnL8ulXY7nYtkmFjFCG3fLZ5G+6EVE+bZnh2V8KYAVM9moehNJ9Or4kGST5JWnIizFvAeeYef0xZtBMwv36Yc1JNAh3zlHP26lcXew+Ulxxcv07RmmV52jZMfWweyg4nXNumrbmy/GwingIhqN8wHrOD3Tu0HlvqmX5C5YRZg5iVU4lnAjKJc6XRn7B1GQzKeyE9HKagkrULQKGmqDlqEvEAp/9eW+rTR2Yho1QStK7J2RXFnWwpE4PH3cIfHWtwIv67yw+QWqj+lXMztHaX3RIRXGLyqnWtaLjMG+IIYytzaBt,iv:djDts0mzoVU6Cvf8KJb01CkHO+OrnIJyMhTfgJ8lZEE=,tag:JiZ2t5cBfSAKG0b1wAZCZA==,type:str]",
"sops": {
"age": [
{
@ -7,8 +7,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqdEhDamZTRUhQZFNDTTl4\nVVVNNGZXa2h2THVzY0JWMjE2WjNJT0ZoblV3ClYzeEt4c0dWRzlISnN3NGthR21M\nTEtDQ011dFdhRVdPWlpweS9ma0N3dmsKLS0tIHFPQzQ5VzkyODZyY1JpcE4xR2Nl\nY2MrSERXTWkvNVZCR2xHUGh4ZXMvYTgK7pxPjnh3idl4QzBkR6LHyRskgqA3apS2\nkbg7As6wlEs34TAO8reyZknKTUd3Xif1v9RXiTcu1sEKHqkcqEoDog==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-12-22T01:24:25Z",
"mac": "ENC[AES256_GCM,data:NtGHAadNGMfyCOqiaE/XRZqu4CnQ1IujgI3/IraY6E3luqzFVxJk/CgWD2rjbhLmaL7hd3Tay2LjL5uFxzM7kAE9QaaZtcxYKbudhznUdi/UEZ2ZtqyXqafXfCjEVbETaTAP3YGmQwJ/kAMj+FZp9yx7d6B8SVqWu1PatJGsOIA=,iv:OW6Xsr2MmEJq70TnEIJFgwLi3iMmKFV2Fy05a5G6Ibw=,tag:8KtNH6tEj/rQoht7FRDN3Q==,type:str]",
"lastmodified": "2025-12-30T14:45:29Z",
"mac": "ENC[AES256_GCM,data:/hfp7IopUWZSMequVWcpMup9lM/e5G3Qda+8zz8ecPMdMrbUqpzi43QAbiTvMC1Wa2DKWFOsZPilClJQfG0MMEYD4GWehd2C5psK5HOxS3h9pjE/AjctaCwu8RB71paK940W6NY8sCjOi+zm+Az4KDwkOl0R3ApaUMofV4hsg6M=,iv:d5Zy4HXtoSfRN4E0FHjT2vIWMY8k3G422ygVAZ7gXrc=,tag:a6UZVjb9kTj+8FZG1FIyrg==,type:str]",
"pgp": [
{
"created_at": "2025-12-01T23:06:36Z",

View file

@ -7,6 +7,15 @@ wireguard-private-key: ENC[AES256_GCM,data:m8fL4Y5TusV4imzcVqTmJZB0rlb+ndoH/Bl7K
#ENC[AES256_GCM,data:IpoTYZX4KGjPA+hZ,iv:Hd1V9//M1f/10HQ7ZEEA9ZtuO8EBtY1kn3n28krYxpg=,tag:We6WirbRgSH1qOjC4g7spg==,type:comment]
oauth2-cookie-secret: ENC[AES256_GCM,data:ZN44Kdai0hUgx0GduynlyMHDnZpdnp1SPAGEaNaNFHGMhM9Q5HPzotiNXQM=,iv:vsYhWriY5G4KLiJ12MLm26B7aBzCL5GAr+S15klH4Bc=,tag:t+MsS0Wgo5papvoeK1nk+g==,type:str]
kanidm-oauth2-proxy-client: ENC[AES256_GCM,data:a90dn//LD6tvDYGSNT2neorQRfo0puo7GA==,iv:a/R6xlwGdrwJNc7qBoo0Zmlh7GkZ1+uU+RzOxRE+okc=,tag:3WpAVThFLXZFsCIl5xM0IQ==,type:str]
#ENC[AES256_GCM,data:vm48D/CiRtw=,iv:7Vs8SfqqGEEU64ZqF3uvFIG7DnUfOT3kGqodiIbCwjQ=,tag:hdNZZUMTLIrAGydGSFfP5Q==,type:comment]
kanidm-firezone-client: ENC[AES256_GCM,data:YD1lkGkg+HxqHrGsbIz2GRq/VMIJqOD+VQ==,iv:AJa/sVAC0s4hdfvQYf+/NaYTJaxO0fdwzNmmD7S+kc8=,tag:JSU6aX8kYbr70+YYwRV56Q==,type:str]
#ENC[AES256_GCM,data:XS4Kqba//4tVSj8AzyLY19Milwl0w7UkTM48t8m/wyB/P8TgDerxJwOGJvz3uLZJX/EO0/4rKminMYSoMybRnNn4TVv9pa9uV3JEkUsGkFk2abMfBriAQjQgziwLbDZQJmnJs46YD5s+sYELN4MJtwFNg6NzEDATDMWuE4+loyxoqgF/lzG3OFGkDl1R2JkCIOU6NGRqTn8a4XpX+p8U5QrY2V4iBCXajGXrcqLfINYW508feq1TAUZazaNdA+RC2SMvq6Diy8mysP1p/5mGUpIATjmoDqN74Yc5uZAwaenI6jIsfcE4JP5lFy7dHWOfTQS/9MCsEsRN2LWuP0ivaKOgF79ykd4Tb19EACdhpkip8XV0hKHJMuyEr6zJ23dUNtBE,iv:lpA1sk5y4tSk6iXAjArtF4piJW5af3+tIwMos1BpPEU=,tag:479ZIsnwkSSFq+C2a0jHzQ==,type:comment]
firezone-relay-token: ENC[AES256_GCM,data:QLQ444ocvL1yjXXslo6YzdPUasdt58Qztf6yv4UHh0AZtMVuOcDmUUXdI9Qz0i0J34zGbtcPw/Ac9CzxnF5sRj9v1D6RkfHf642vo2JxcnG+LExHzUFNEhTAXqgLvfdQhi89hQTjSfc/+ryDyf16tTJklX40VitqYLtTEW9CHSHhKrVr7Gx9u5qw1+j0voQbJEs/ojBwsnzNQ4Z7FJgWLBw9FMOQg9sap28m6fBFJNnUGaK2vIUQ1qPXQWyX1YTh6xd0nq/jyB9ctqQczYftgd+wkaEiyMjQJkNk22W/6P1M3biV4L52H7WVVhptB8yWa7TZUXD6GFi3cMTXhn0NhM5FsCJhXeGcnzNmBs8=,iv:RdVXYof5cSMM0WTAoh8SO3jTWyR+XTNmK0U4ezHu76g=,tag:nSw7ykFPYuHq/klTwlNpSQ==,type:str]
firezone-smtp-password: ENC[AES256_GCM,data:WLj+kcidIMQIP6gPuuIrujA+fHypUpGUFg==,iv:kg96vVaGund6HcXoJltIma9ecv6tK9AxZJf8n62+9aE=,tag:g54wHPhD4qnHlKZQd+MPZw==,type:str]
#ENC[AES256_GCM,data:aBNmUs9ZW+h5fDMVKdW3WQebJ8zmbHuYmNK9slZx5tZONTfnfnFRYjbzyqFTBKfC0bYjzLYL8AxXiEiPmBo2yLgbXtsOrVMoML3hD9Oi9T/7++BUBpbBQ31cC/EtnALumpes7+hO3DULm5tzWYc9qIz3yB9/gQzuKCqFOB6TCt/PwAKrVKNbcOihx/5xh04s6WyqfSUjWOOcHSY/ng2G7NeYRInLe6TgM6gGQGe2DjXCmNvgxJV2Mh78IWs3yA3aJ9VtrgF5R0PGoqHHZ8GfRZfYn7MBSW2dHztb0oLWux6bnO61Wnm8iDdR7xguQkNXPO0XXIIIO6AOL9duThXYjwQmieqYEEu1BmrvaQ4/tslLHX77axQCm1miwmZP9DoKor3yAziCBMa/pbU5JFlft4QZ2QGY7EreDfBVoDcPjCgA+gXuvq1VozPTiRH+y1hiulGlbGL0TmA=,iv:nsXYOxnWGceyB0aiv0Db7H+oD4hagzwQi96h4mGWD+o=,tag:n4p5Aoh7lYvCRDWRcc9tbQ==,type:comment]
firezone-adapter-config: ENC[AES256_GCM,data:CPY6DPFJ0OZRJqY0u05rAoc9gfCvHY8fFXkSyKvC+VdjNkC4LwjSJkaBU7aBAyIVsLrLz7cS52fcFfwdnAp/6V7BUDE2qpRdpwuN0ZuTMrnFnmLIi0jy4JXcU5niiClSfulgRfY9Dw9f8oHdYiu+uziVhDdjThx61tNyW+OVMNsKv2avWKqotM/fhBf59hJDS0NwaFi10X4X9Z0Oljd9mHQw+LDJkSTX0dk=,iv:IRn5awskI2mZCzQka6VFvCaNnYATvj6yMH9UWs4vJus=,tag:3gbxkbfwS2mNLkVK9KmTUw==,type:str]
#ENC[AES256_GCM,data:xZvu7VeZ8IVeiR94gfJR1BB34V1z8ou+YKRrIxlK+qJ8idgzEKXRiWCcdwC345UNIEuVShI8CT7+Bno9c2bllkkKwW4RhSEnMOYo3g+iouKB3p2iwRBX+OEZuWbpoZGDr1KpHLP+ypiTekNOAZgx4EmxQWFL78bBMswoPn/Tv5ahN1Gha75A9iO7nNQgjRIn62s4l+U1cMXDBBKUCIwcfg==,iv:V7G6wGFjSoKNGNuwW4i2U8+zKI8AQm+ATbSLls7688s=,tag:jQqxbMGaJ96fHvPj5Y0CTw==,type:comment]
#ENC[AES256_GCM,data:td0zw1WORHtMvBO7IK06Of1PoG1QTMiDeJ8KSa4LpLrIgOPTdIg9TkU7UYPNxFD1bVGpU708Rs8Skmyz0v4y9S9H6PM9+4fVij5GN6uaLH/pfMXzaArD8SHbppYQGgpVqsq4kJ+sk02yAjvEM4BBfTpOEPgnu1CSmwlyjw0ysrCwq5YLOYqAQa9rT9uiVCL3FYWuuUzh7SPuRaZouGX2m/MdtQ==,iv:uetwzIK53P3ja94Jw/QDnrel61ducf907mZwB1yy6cQ=,tag:89IjmIvEQs7ayBmuvw3RFQ==,type:comment]
sops:
age:
- recipient: age1g7atkxdlt4ymeh7v7aa2yzr2hq2qkvzrc4r49ugttm3n582ymv9qrmpk8d
@ -18,8 +27,8 @@ sops:
NmVFamgzKzRlV2oxS0x0UCsrc240eEEKByZ5WYf+QO8T43VLfO2ym4x7TQltS1nS
ckgZLorWZBWQg2vAwQktxQ0WTcjhM6tktZ7zgCIzKBLbQXtSt7VG9Q==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-04T19:12:20Z"
mac: ENC[AES256_GCM,data:WAAHE40CAJgdT1tMYBBuFeSqaziHOvpUKrBlfycHvpXhPZ4Oa8sDElpc1lxp1VY2AVeLkqeAB7bH/HVQYGVJhxbfSVHAXm0kCQTT7yNLW8x7RK8RlwzGq9jDfng5UoA46kP2GWyGbicnaUzaH6gnF0Os3rqAMMhTg8pme7pUVwg=,iv:vJ+XFfGMwmIlgJ9ZSu/+kow4dhVsY5aeB0jPjL4TIpk=,tag:mBZzL2JGFPwIx8hNM09hEw==,type:str]
lastmodified: "2025-12-31T22:00:22Z"
mac: ENC[AES256_GCM,data:wGGou+Jx0BV3fMI8gF3HL6VW05lz4CSBvjQF8WSbIHoykor4uthR0TN4ndanU3ZPjhU+NRNxIxTs2cFGJOH4YMIG6bGH0WIoFIfw3xkSIT/zAmfK33P7AUV8/vA45TZli5VHf6S/4CUqXfN91qezrMUiUVr+AEeqa/hbOMBO3j8=,iv:TRc4ci8KRF3ZHuqtafqP0AaRMHMlqnhB1psGbuL4zms=,tag:aTFxdF5qpkGEYvwwj7Q4SQ==,type:str]
pgp:
- created_at: "2025-12-01T23:06:35Z"
enc: |-

View file

@ -40,7 +40,6 @@
swarselmodules.server = {
mailserver = true;
dns-hostrecord = true;
postgresql = true;
nginx = true;
wireguard = true;
@ -50,4 +49,6 @@
server = true;
};
networking.nftables.firewall.zones.untrusted.interfaces = [ "wan" ];
}

View file

@ -1,5 +1,5 @@
{
"data": "ENC[AES256_GCM,data:GB11Medb866IeeAeZGNRWO7ckMoNO1DACgP3bLgKhJ2ZYZa+Xkl5FUR6sZTBHJInSODpnOIMZWcV+ZjyRbQHJvvYxt1wJxcDC9fBVPnhoJATbQrV0zQ7XQBlfYyUhzvQ0w4lB+G5sbWeBkVQDwGhNoMxLaPt52Vg3uW0Vq42VIZZkpeWaJtGVDXoMIHCTIz2K/sC7JafRoE25a74i5XSrd2hxvvRFDQA1PFzH6JGguRqOXroqS1M1QNF3DEugsNhl3nwgc9bjLeSzvGdc8cCmUsS4LDITjPBJb4F/2mWqC/o1qUA4rEbgM/jTve3NInptgIUQiyPkHxZCtlU6MK5v5K0idI8njSolvqofy8j85YccsPPpOoQ06NPAUMa9hN0Jv+DpnyjUJAuf74JFzFP4kEMh+a9/6nVB/8cMeQATwt5b9Lbvr7zIZA5PMt1wOVDwAosZigMm6oUpDyYOjSlCvOgvEuojHDR7V6HHYd7mzg8AnIQyHa8iWR/A8/h+hzru5elb6H6rTwKaGW+jisDxRrsBsqxOWQrMrHZyhK3ppTc+IIDdIpKfe1QfVGnhH/cWXLE7YlG80fh48PKwp55azKfb76fDxQHJ4mx3PMHf1dF1bM/D6zGvsMcgIjZTO7xoVTZUZ/j7jiKHUpZnkciGfD9mJZKNGP80DMSgVDhVDUVBrZVCVwqbfksUob6bwU5nT5MSrlmY9Wj70uOl+VGLAaD0WF4T01qB/FBxoFBoYQJ+EIG,iv:5ZEu/YUvgNNgmxx9p/zurljFHRVRuKErhGhZpv/9XVk=,tag:ZFpqY1ewgJ8BLg9tnQc35w==,type:str]",
"data": "ENC[AES256_GCM,data:sfFILq+nY2tqP2aHjJZqUZMdk+qQXSsL72ubGsu/U5G8ULqXcq73d69Op1M8ARfLgOrzoBfzyjcxFMUZiVxoSHevEtqoRBq0Yol6S+3m8vXbW6k/4tj7vRTCsnuxEbGgX2MCbpfb8GChkX2xy5ZKdOWTyXNGWIIAOkHj9NAfnKz2ppY8tFPcQseOtfbI7o/MiFtaMzI6HTpbgBqhifJHLvJyIjsFH1ZecyYjYtL6682isMGZwywUdzaE7dH4m8+sFztHiliJaCM/gID+Kl4GsWlIqZuJmCi3Ac6czCCnLf2fXk53YLXawjwkQmNWjSkOVYI5yybonySSzmyjCfB15487E/ScNlG/Cc0GesoaxkJQpgys3rjuyIUwBKhfHa0qsEd5XkUFKemlB3uQTNfst6CQ1WzZYagIGwTM4zB8HjsjG2hRX6Jck7kS+5eQAoxToe5Z/bDGworUYWRhm5To7bbWn6w2AZ0FjWsb/h2lGy3rgCpjtaaKLAcG7kzbXyUW3crjLg0NR7REKYQf/ZLDGs7a0zYiDfGHyh9+krNiZ7c4dAlCh0lwUJuWSLP3VBPlcLqvSoOg8rRvoJwmIwh9rCCuKxhhGHwwL4SiE10Gw+5rajHNfj+ZnjvVXmFdpZRQW73FF8ThVexKu0qtCmzGik8R7wIhI5AW3Pj1wBURftl+jd3vRZkU9isCE3CZit0L536ZJwawoAZ0eU5tYkRjI/7iHXAbyLEILspSdrHDneRiVLh/IYXv6BEtlZFXwQMtPRPAwx9F8JG0zG9iX4Yy,iv:js4R7cAoIFGCgURc2WyiqRwfqLLBKNWCEEAlsRYdUeA=,tag:NZD44GRRgt7B7U2oDBDjyg==,type:str]",
"sops": {
"age": [
{
@ -7,8 +7,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJR1ZPZFUxRTh0QjB6UDJ4\nOFd2c2lFejhHck5UdUxVbmFFbVRYNEJaSzJZCkNxbndVVThObDkxUmx2WW9ESzhh\na2o0LzFCbWdJVlRIV00rTVUwTktoek0KLS0tIC9qalVvZmpGQXZsV3RIYWRPbmRY\nam80NkRkT2l0ak8wV3pTSW9kSC9nZ3cKCH8eEMmku6WMliEDdAiW2Lk1jAGH9SoP\nWQ5Y6e90jEnp8XbGE7KYiG+jy5fHSc6Y5/YyMmi/b9bF9AhmRT6rdw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-12-05T09:21:59Z",
"mac": "ENC[AES256_GCM,data:S0o8zMcZ7cVmhuQ+FyC73T2USIEGryy3v61xXafd63pymEjJiOwgLZk0+nQQii+qKzwFcXNJIOjEjWyHhprcq+2hha79unEH6nfxAFjqyKdhLzFzmP73ML0vB7Fbzl5mEDyc++v2bsH/6J8UakXCkhRTUSjyuotxIChjU0YjTKM=,iv:dzGQH3HyF3lTWYhU6Mv81WcXilYVBMc++ZK5nPSPBVw=,tag:dnsxa1XnUNdZd7XIxmTgWQ==,type:str]",
"lastmodified": "2025-12-25T00:58:02Z",
"mac": "ENC[AES256_GCM,data:AVZqvJDOcRyUKkxxN3QkxFDiPgB7R/yI5cSGrsgZS/T+rcyi9db9fYhS60c7egLpYmO1ieBk59wwykCAP5TdTQoPXm/+O24MCXquEYuY9CR4YjYno/dBnbCWtKvIB7vs/yIyVfKBW4VQYSbnH/LpBSB6RJ0ivLU9S8hrmrgTkDw=,iv:pSbmaXMW7hqxxTNS7n9vDlVlO7zE3rqHnDAP0XaC5xw=,tag:jH1qSjGWX8bwKSk/MFmDQw==,type:str]",
"pgp": [
{
"created_at": "2025-11-23T15:25:41Z",

View file

@ -4,7 +4,8 @@ wireguard-private-key: ENC[AES256_GCM,data:grHYayd0/og7SZhnkemUE9NySA8M2Pev5C/Gg
acme-dns-token: ENC[AES256_GCM,data:5U/74jeGpQH39kyjuVwLU3WBYk5MrCMZSFouRFRVbB5FhOkiJtqYBA==,iv:f1TgdiVVbAB+580AtQAe8mCXU0WuS9JX7AWukKbDYj4=,tag:Ut0tbtiNcV/NxfStyZA9XA==,type:str]
#ENC[AES256_GCM,data:dZiEtGPKsbsd9g==,iv:lNgXQHx/w7pm3EUTBwyFnqv2j0T7zQ59nFLom8F0hQ8=,tag:1cF89QMfjipYZgfl08qSOA==,type:comment]
user1-hashed-pw: ENC[AES256_GCM,data:uPyDpGOVIqE6cCyvhXIM6v8sTqEx9dV96oqMYS7fRMLiR0kYlCmgNBEeDFmTNRskqwW/WGXrOBn555ZH,iv:KbHW2mOGzOw4t9aOrKLOIobkUNLWj69dk7fFuy1x3aQ=,tag:51+qAavIiM6K256MkhBaZw==,type:str]
user2-hashed-pw: ENC[AES256_GCM,data:+BES2HwH+Jj6wl7MVzsdmPGxp6AuiPLx+XuOpJClksm9SlbAyqATAHeNokAHmj7yLS79rJF5C3YBBtT4,iv:bSX0PLcriKal3eir24DTyePfropgVhh83U0JdR6/2Cs=,tag:TiSKjApnJg3di+77vV9l6Q==,type:str]
#ENC[AES256_GCM,data:brmNZZpgXixukd/wVGB+aedAR69Lw97B/vJIJndX6gSZXmv85ioXOE+INhdXFzCjUA2FDZlWOVmBLbtWSsgF9bqV/4WTBOwk8Cy4fInU,iv:x1aYveoBXS48OodS+4MtW74oUdCS9EFdaFZBgpmmfSU=,tag:FlGm89rFi5ZLoRq8Uxnpbg==,type:comment]
user2-hashed-pw: ENC[AES256_GCM,data:B2gK16sr8GqnngSyhG3vdGb9x8M3j0A/KDF6Vak+ZHO8hOsFAriKHnHEyvcJCE9p6oi+9cqPzcbL6VT7gYQf3KJrid+Ejzl4EQ==,iv:PVG04/i7xAokvcjcedXOEYuTwfdt0Jofev0Eit9kD+8=,tag:zCV4JPQHRArqW48lkhCzfw==,type:str]
user3-hashed-pw: ENC[AES256_GCM,data:sr7jv7PppT5Ub8VsvipXdZZWTZ31GFscmZ/CcHzYE4vsfIYYHpFElHGMjlbcTSLjyqfVOcXAKNvabcoO,iv:C22sZLrUUc3G80yyYr1snuwqtAa8USZd8FRtua5hllw=,tag:lu0hPo24CXNI2kE7C8g3Eg==,type:str]
sops:
age:
@ -17,8 +18,8 @@ sops:
SmZrb2xuVW5VVjM0b244U0lkVmlkVGcKin/6A8ONfW72fbQmvJWiNCzAZfGUtxCI
WV0DaPvO7sO5y7q37QxVUOxgJgF0WpKiNel4Y9E06xbl3TK6jXk2MA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-03T16:14:20Z"
mac: ENC[AES256_GCM,data:PrF5wUKzsDuJUCdAvJFKQ/ILxTNyrsHK/tJnN7tM+46gAIsQge2Nzcq7/sRCjBBy5/c0Gyv2XJqlWrO2hNHHkdEqM2NCMosxIhNknjE2znYz5giMRbmNqxR8MLbohXHZ3pgUIKKQnBqPic0T6xEgPuGnt6j0Dwb8rmy4xUByhFQ=,iv:g+iOSoOn+zydHyA56+lqAo7wTXgZ05K1C4H8DNj3MrA=,tag:Zj6a2GESBA755uVHtEpTMQ==,type:str]
lastmodified: "2025-12-25T01:03:31Z"
mac: ENC[AES256_GCM,data:phjkITBZVZ9Mk0y1FL2dZNgrxyIPbLIXmoTYSlRdHslHg0+hBViLnXAvS0QN/HvsvAldzH8THyACQrXDZQSFBHljIy2wqZr5bu7ByIlRc8FhwNePXNOUs7HH7bQISvFuDWrXl2KQn8OirfJjpIpwQIi5d44pa4Fs1+tpWAg+OiI=,iv:k7brMvP64XV5eNYdm1OJqpjEJ3xEhhfOqErBIG7xMNs=,tag:EhXT3gZrZg2QkYzVCUQKlw==,type:str]
pgp:
- created_at: "2025-11-24T12:05:01Z"
enc: |-

View file

@ -20,6 +20,8 @@
};
};
globals.general.homeProxy = config.node.name;
swarselsystems = {
info = "HUNSN RM02, 8GB RAM";
flakePath = "/root/.dotfiles";

View file

@ -1,4 +1,7 @@
wireguard-private-key: ENC[AES256_GCM,data:DBCK92h8mGxDshB5OIEbyUENc6a4jmvzKPvljUn50AM1I5vBm/bSTDRStIM=,iv:K/OiPnAlXNt3RqBiBiiZqIY8vqsIw0kmKE+aeeVhr+Q=,tag:eloCJ7yjI2tpHMxwNxZDDw==,type:str]
#ENC[AES256_GCM,data:3lP1BqtvBwyeOvq4K5HTaQ==,iv:j1xenUUIkyJDaeLlX7LGhjFdhNlfTXF6r6v2+XbJlOU=,tag:TsGKu6VfF6D8I2p4kb63/A==,type:comment]
#ENC[AES256_GCM,data:LItVBIEQVz0x8ZARRlMVRPa0vdEe1Kv0CZaEnauUWw3P+NZv6WZkXw0SjuW+k9oqlDOTPR6gQ0Aa4GoX51NRFFmtlCVU0YL/RmdfrC6nkSea2S5btXCG4pptSusmQx42Rn+RfttcLDIXBAOIDSA/kKiBYvDhsZe0XOHAzj7jTAshSeGlccEOUIs8SctS8b13OAiSs4ceuMRPz6J45f6RVKG6COgiUEav5U6RFa1ZOLv8A/EFsqOsEZ45aYqngLM0/7gZ5Wqwpft8a+7dLRmakUjTOxH+wtVn6CV7wItUJAoz6BjLR/jtDr9EUm/QesZSHhuxs3eu0iXPXzaQgUt5Qz2knxSvzsEKYUx5bPsNBSb4uWgG3b/vKzPUKKYP5CrOwvPxsqI=,iv:z1YrJmuMaiiQpAc8ajoa7A1GH5Z2D2holm3lBCiBqOU=,tag:ghl+1BN9Tyxpwr9KXre5jw==,type:comment]
firezone-gateway-token: ENC[AES256_GCM,data:3vFtknbuAKk4syzNMDBWZegqyjDQWWPYXVJOs40cnEgAYnOWF2svt4mg3ueRH6b3j5E0Mrkv1PJIch5yxu9FYjfcx+jlsrqneJQrHGX3LDcW5JFOwP6H4nb2Oo8Q8BtpbpOdxAdUeFoLjRSFYy3DGzDatLG9CN3AinhIuxrTGM9Dfxvfn5ahkZ/LPLNRsKj6822C6dxSISW5QSGz+I2woyKzVd9hYoyeHzj5PB2WeaP4ty6bdQRwtA22i15ODpjMDt+AwPL9Wv+tzcv8StDpawbLrJ+0vAh8uRrIjka/W731WkAIWsgMr4mDt0dw99VgJ3mixbXEOdQRidVCeDTXwb9N17RQr5Z5pcjWqGU=,iv:+zbkWWlR0FAFIFB73TXuUwhyuhiVzaEhPeYBkJXfbmY=,tag:8NZbeFLv0FiRDVZJtmLmgQ==,type:str]
sops:
age:
- recipient: age1wmx8y2hs83j2u5srdnfxljrzxm8jtxl6fr0mq7xf2ldxyglpzf2qq89rpx
@ -10,8 +13,8 @@ sops:
YWlkK0xrclpXYTkxUXFiNGMxU1NnMGcKCZzLfTPjeeGxyD43dOGDYsQVsw24cyHI
jz0B9VV07p33OP448eLyLgwpVFaNG0q+hXPH+0fb3V3foBT2QSeuPA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-12-22T08:58:44Z"
mac: ENC[AES256_GCM,data:GnnNiw5DwXDCXEWqMa6eGYVNK4GyNvoNf9WK5wYE+uT8nolKD/pFEjqt++vHHlmEbPePhErAAu2vr7QGH/p8c+oEOEjiLJicMxJ72Bx8+5RLe4WuKO3GLTizgCy2f9Fr3gDWaKG8W9XF6xVzwPzzguRpfo1F0fmrPW6/EiGJDJ0=,iv:DWclKhUVp9UYc0F1J1k5+Y80dPK/RXoPDmylYlbmtiE=,tag:VgBHoVWPhOIwn7vuDwxKSw==,type:str]
lastmodified: "2025-12-31T22:06:39Z"
mac: ENC[AES256_GCM,data:BXX6xL5AJ9Ar4le429W86bkCRQkPWiYbJxd+xvp3xfy/T0MptAMsOB7K7dJrtokdXBKK3iPxapgPZCVCSBT49Sj9X2e7wWCJq+olcNTmojMZBtgsDjHgg2rbl8jY7mKeAlGRiImc5iIengJP0cwxF2zplUkZeQmJzXE0+4P8R6c=,iv:63xUQfIl2gpDONSJUrADsRxeSFtBs3h8e8LQs8eQxEE=,tag:vQgKvv8AuW+oEh7dimPhPg==,type:str]
pgp:
- created_at: "2025-12-22T08:56:58Z"
enc: |-

View file

@ -77,4 +77,9 @@ in
swarselprofiles = {
personal = true;
};
networking.nftables = {
enable = lib.mkForce false;
firewall.enable = lib.mkForce false;
};
}

View file

@ -91,7 +91,6 @@
transmission = true;
syncthing = true;
grafana = true;
emacs = true;
freshrss = true;
kanidm = true;
firefly-iii = true;
@ -104,4 +103,6 @@
opkssh = true;
};
networking.nftables.firewall.zones.untrusted.interfaces = [ "lan" "enp3s0" ];
}

View file

@ -1,5 +1,5 @@
{
"data": "ENC[AES256_GCM,data:wKBQGVGzaE1aEt7BTm8tctQkRTf9La+kHnBbWGw+lzZN/IqXTFLg/bPlSWHyswxPYmtU2udFaSVxqWHe3GDv96Y0A5+wDLLI3aH8+3TRkpl3knq0+pBA8JGEXZJvydRyH0pvMIGr5hX8IEfSiDk17cQcUu1XB5l2/1mShnzU2XKXJZYtohIr9UiQoMSkas9FYetrzFDMxjsZy6Nm//w72QeWExo6NhoexZhC8r4Q4uE1QtLdBb0zFY+J4TNxFX11GdkmzNyTak2t1dvJ9i7yIMxVIz9Ykhd0J3LQFd7cpZA9YwvGemIz2Z5yvu0x+H0ZnA+qOfe4M9CfMoQO/N4ww/HdcSg86DRLnZabY8cqapAiXxfU9EaQ5NQTJJv6LFzkNfz+RoQRDDLV4IxW7/Rcmg6F3F4YJAcTwdpHPZXDze5Gk/YWIKHM/7MjUXLFnoWmTMRlmev2z8aAJMbzxczt9CkaPXth9ql8WroV9L7RMmX5sjqM8t3RIa1lDnrS3GGM27bpX7IElagBgzza9wfYfDIoXYEa5a0KPmY8GB+/T7u5GKFdmWmbPPyG9jQiXEmaDNEkjtkqF8PlqheOJSj9PmLvPLC15PkPyg1SFyeX6w5+QCqX7mQHBbtJdbkh/ZkL1Li5H28ffsA/xEXHl7A9ZAsih5hF4th8DNWBtEPsfRWmDzRmDXawJ6EkgB1M546gIHOOPiX+sbmSBbW5s0qgaoEmx8yO5jzJQ782YHLsISz2I2dXYd1fjecDoLdOWGK788t+jAvy4Dycf7JEWOpbgnRuHxx8mHj/GbvPjZ6Np2hXQedTetZCNtsvC3OyCN+hu8PRrcg4vUE8nx0t6jJXMheTuOr0JMNCO8LicBVty1jYetzYZ6ocCzPPqb/Gk1/y+caxWnfrYLTrkeKcxWeclbv8NSFlURs5Zl9OQqiuuP6WJzKkGA2gvrU0UhgY9fQi+INxLDGnLHPzLpHs5OtxalTZdibix/Ed1ISXOuYOPKlQ8B7hMGNluT41kcYAyZusIY9ymIbJylCu+ejXfcUaB3v0LlVEv4uNrf3EnU+tc2GXZdQUz6B83qOnyWX7Re8qUj/dsyFa8biwk7pOAJvZtQq0aTejPEFwPma4rP1wWdm9bepX78ipuLgIYzSMM3HUc2uJ3tgRLdOHXYBo2W7mjZUR7sqT/0eM92bA/Okt/P3DuzOsPqovM5d2GuXd9UzjVXlmeDn9JsWlYbIo6617AmJwmIas6BCpHlTd8nfg5Nqm81OsD49myC4+C8Ck+0Mb2AF1oI4OiOZjCno4DXh2BAPH9I+UeZoJYx5jUU8mVB53ZM8L4H+G/E+cp41KV2fhaJavj0qZ/OuQP6ns4VNoGZx3maYKTtv5dtsQersOGh7Y2ORo8anuzi/0upscRwdNGuhUs3mUBmPT/SkvwUdlTxYAaN71zBkWcae7sii+GtGFY4tBT3qUPmSCkzgUl2SQf6+ff5aZXJTK8mTiyNsKJo190MWe2Qq9OhNNPEmO6npDdspgjc5cW8rom6gBsoUp6GsuGDBDovE218evOpX1JjZ9+UKWb+hpeRmKYxog+cEicgbgwqRmIJmakTwQqeUXDohervTHYkwWeVNcpXH1XbDdiweXWbF6BIZS2CGRY+7Q9L1qMrmMaaDMQezTILMuMyUj1Zcf2MmNW467NOZFSh1EyXWATkpUoxjOBrR1K25jODd5jGKvIr0mw3p0jqlCGhIvPnZHJ6gGRtZgUSnHubV4gdVcutRIJ+3XEurGtDDE29X/+9/KwZmHeGDN35iKzig3wp0NuLNrbp6zSAGCAkECa/f7UXRgt9cpEgT1KeXl/Yn0EFODOKYEjwTZ7E7DdafaoFWBk4lTmICf296fopRUw+V6OIttFmiTqBzJYrTB7/NmYHphiC4naSLtQ9HzVRwKn0aVm3AYf7e3ltqUevlg9z3S8psPw4LOwFsfHRoO/zaq6+V8GoKTivoDX1CoKUnq4c+s0YTYNXwsJMjOcVJHa4wJ1iOC7QnX5jZ+R8ibqG6tOS1at8mZaOPOHHoFhnUs7OpNYEsbEFtnd/cUE9lHOp/CxLyDm0xXJSEVo0tF5CrRQLKr4H2XjoTbJssyI4Oo40QtKpip6uN/LQ==,iv:tRfCSNz1Jm1qQFXt7gVEmd8VxWsqYivXtF/u+J+mnpk=,tag:3V6uLwgc0/XZvk4en2KfIw==,type:str]",
"data": "ENC[AES256_GCM,data:CO0DFhtowaGNNTw7SqskJWbte4LXaEJBhYPSUPTtc3J5TOEqqVgDllFajosQvsPBtoB3pNYVhWTkq341mXoh9Cte8wCbjtpktXPl8NJptazkx9V+nCQq5r39Chdmf+TE5Tirf7KeAL54TEe6yDXWSjDdN55XOgHAaWXCc+gDAFQUPbxNLEIWffqyL3IPTPSfgmj4+XxLiRwuFcbQQtsWjLhyO1yez05+FqZRePpegexuTp/vezk56rUDlOUlVPwdbCNqCX1WF/n7rv3p+Rog/5Bg/18sF+QiwSLLeM2crYlnjemwCRMQSJE8yPKs+EUMWGbgdkbJof9Sl77Bu/O4/OPjqmQM4Oa/ACIxjmeG5DcNnlsYSdBhp2inZnpdJu5n1wolaY94Tt5jeL7mhRvq0JwyAD32fH4hyt7lRS3HUaFP8fCzOitMGNeF3xHxHHu3ph6Ku4DsFLk+xmThWBrifduhjJb5I3aTF6L3MI1eY2bGV3G+uHU6y1To9Vcxey6KYDFG6KhFQImLX7iQG5DMq6FtVR1jLecYrFSFaOd/LL35JnFOhP59gt9oROPBVtrW2qqb4VELOpmvvt+dgYTgBGY5efPnqUsemiwPSt/dq9AdSBzQsBNyoeqWx7WOk5BWvA+y4kWNythnv5XVUvMmWy77plSgNWZ5yioT6wBjevCve9LVW9a4p2EPy1GfNPos02V4BdDJFn2KzEOtsBuZIi1zEhMpWXivfOzgt5uW07Jk8tPqrmyyElltywu5i4GeXLKE7L5jeBRFKbhs5+UHOB7Qfampwt32Xm94pz6yOluSo5e/630E6fLVtExNiuoDsZsM759ciRJrD0eU4dE+UhePeey2fODf9edqbpbSxo92htXy61Y0jS2lwx6uBDiJBg4wEMykHqxcpouFu1opIUkF9rrIPVFfgD5wxi61aILo8XH7oZVN596Hf0jgOaqotUXTNd8m1kCSemA6u0MGRgYe7U1S+etjo88Dz+bJzRRXeSKW1/NFy1y+xXrF4MTwhUltMw3/ptf0a4T3hnOO4s57ZxM8QmJ9UTOgo6mekLwNimZQoFkI6Bjrw1kUn6R/blqIcVhsfhnlG+Qv6YuMvamDfiwGpiRYxeywgxq4lyuY61IyFL2T5JWiTeOftNJeYvObScMKRcAQcd338vok2EnxAcbryT1wvjBPHhbEKE35ppFtgGNe4pKABKtrAP8Ob52OImPfAjU3Wm3bOVUbFJDt0Mv3CxqSd0Rt5bTOdMp1DwsVbFCahwkk2K/jnz0CS0CzJT0ykmVt+qGhp8lFhpNXkFNS8YsmRPovsJTHZxum+Th88uruxey8QqOPu0nQzi6BG8gczC9Or2fFh33yGZWQTlgaDvQqJZR8nm1dZZs+OsK3GWy+SDwFLOtgFxmq8fS3ZLfH9tXL5LiqkhkAg/Clz1wmcDT9FbA/AgZg9SAhb02F3LDlZg+2fBQzuvRIcnNiihZO3FKzbwKZ/Lri8Ola+72WLFTbH3bZBqn6caLLXkLDxi0WDkkRbKzbk20AbLij7hJgnfyOm4WEoON4UOv5Om3Z2iSfk09fS28GAEU/UxTATwqLhv1eBJi614kLxZxv1w0S4loYul68SPafUiuUuMzm36RJv3v3pTTwTWDqqxkfKewOLO6bCTv0Kwi+E3TgNyl4kLu/0EcUjSO+f1JiinTQQnA90neRfvqZe/GMIJY1G5TTNAc3vYEUal6pcp6qVX229Hb+e6kOeqjX0GFo9O8RgFeopxLRFAkEYqCA6USI6c3VBQ5c+JMow2nyrgbDjmEJElhdN7zp3vrXvQ5ed3PmDkB66FKFiYecrxHTXOXnh41H02K7RxuaZDa3ISrmBIvRMdGQxVvEU3B2DJyKpsicu3DT6kjzBf9rwLBm5kh0NvtnZxJskNplGVIHF97l5dELYStC/3Te1MYmWe9IwjgVg5cMjX9MzaTlGWEGkFGYaSb9KJ5Njf1LGj//ouLgrPwd29LNxFTSAO34kN8ySkbvNOHY/cMtwlcLzeFbFEnqLPTsPYPQDWu+MSOCAb4Ro5o21OgQo5zXwhJ5+wFzRvtCbwowiOFdfGefZI622dDQWZ6ofMHJ+3xoDShudH1E10VdIEShcO+Palw1Km1s6t+VLRKU33Rx5dkm0nITaz42bdVO,iv:Wc2rOI9aWgchjFGCl5R8d6E6GmYEKCIkIAZlUIlbE/4=,tag:3p301gA9WrBjwcpXs68ayg==,type:str]",
"sops": {
"age": [
{
@ -7,8 +7,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3UFZTaXFNdjF2UmRFd3VL\nY2pZZ3ZaRkhZSjdVUjIraHV5ZlNaNGtwM3k0CkZ4OVRFcmR3MFBDcmdsbWFId3Iy\nVzQyUGI1eG44d3JFL2NvZEg4NnduT2cKLS0tIEdhOEZETk9nRTlVbmJ5UW9GalVx\nS00yaUpJZVFVNThFei8yRzJYejRkYk0Kf6Z8WnG8phRtFIUWIPys3PW0OImhAcF+\nUFLuL4Qr7zWaeItCRieYCs1yBn7KbUJHZNkJcvnkYW50NYvlEa8wBw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-12-05T10:12:13Z",
"mac": "ENC[AES256_GCM,data:2uJJUnYNM7kNysGtiwmlctwjrE2ZAropTNOcph4K51VUr48UZcwYQTPpdJEqEIGiNq4pcT1W5h/ghYFUAZdZdleOKrh+tLnQ5LIib/A9WGkW44m3i6dCVlTXRt+MhrVfJXffRTMM101JoMCq8V00juuFYcDxNhI3uvKqwxXSbyo=,iv:hjMu3oSlc9gKi8cO0RX4leht40PUthldYpLwZKdX4Xw=,tag:n08RFXUHkXyUgE5jB0KZxw==,type:str]",
"lastmodified": "2025-12-31T12:22:14Z",
"mac": "ENC[AES256_GCM,data:H17OWQwkZaugzTuMM8kBPZLYZs/poaLJt8osoY/gzC2CMpWXUtWpwgJ83CO7GkiPrPN2SZtEiaADP3PvZZqVcV5rDJNhdELmdvZfB14RQDUD9rYfnIX5uuzMMII+kguTkk+Zd1IRWv+MN9y4cdhys0lYJ7Nw1RyEMP9Bxd1zvcA=,iv:01Yode7T/2pUP1dFLyIUoDIfeWRWKf1Qq7pHvUDKQJQ=,tag:Ldxq5cRB2iexLhIrBfqGVQ==,type:str]",
"pgp": [
{
"created_at": "2025-12-02T14:59:33Z",

View file

@ -0,0 +1,29 @@
{ lib, config, pkgs, ... }:
{
options.swarselmodules.firezone-tray = lib.mkEnableOption "enable firezone applet for tray";
config = lib.mkIf config.swarselmodules.firezone-tray {
systemd.user.services.firezone-applet = {
Unit = {
Description = "Firezone applet";
Requires = [
"tray.target"
];
After = [
"graphical-session.target"
"tray.target"
];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
ExecStart = "${pkgs.firezone-gui-client}/bin/firezone-client-gui";
};
};
};
}

View file

@ -61,7 +61,7 @@
nix-visualize
nix-init
nix-inspect
nixpkgs-review
(nixpkgs-review.override { nix = config.nix.package; })
manix
# shellscripts
@ -90,7 +90,7 @@
# element-desktop
nicotine-plus
stable.transmission_3
stable25_05.transmission_3
mktorrent
hugo

View file

@ -0,0 +1,15 @@
{ lib, config, ... }:
let
moduleName = "firezone-client";
inherit (config.swarselsystems) mainUser;
in
{
options.swarselmodules.${moduleName} = lib.mkEnableOption "${moduleName} settings";
config = lib.mkIf config.swarselmodules.${moduleName} {
services.firezone.gui-client = {
enable = true;
inherit (config.node) name;
allowedUsers = [ mainUser ];
};
};
}

View file

@ -47,8 +47,10 @@ in
};
};
services.resolved.enable = true;
networking = {
inherit (config.swarselsystems) hostName;
hostName = config.node.name;
hosts = {
"${globals.networks.home-lan.hosts.winters.ipv4}" = [ globals.services.transmission.domain ];
};
@ -80,9 +82,11 @@ in
];
};
networkmanager = {
enable = true;
wifi.backend = "iwd";
dns = "systemd-resolved";
plugins = [
# list of plugins: https://search.nixos.org/packages?query=networkmanager-
# docs https://networkmanager.dev/docs/vpn/

View file

@ -5,6 +5,29 @@ let
types
;
firewallOptions = {
allowedTCPPorts = mkOption {
type = types.listOf types.port;
default = [ ];
description = "Convenience option to open specific TCP ports for traffic from the network.";
};
allowedUDPPorts = mkOption {
type = types.listOf types.port;
default = [ ];
description = "Convenience option to open specific UDP ports for traffic from the network.";
};
allowedTCPPortRanges = mkOption {
type = lib.types.listOf (lib.types.attrsOf lib.types.port);
default = [ ];
description = "Convenience option to open specific TCP port ranges for traffic from another node.";
};
allowedUDPPortRanges = mkOption {
type = lib.types.listOf (lib.types.attrsOf lib.types.port);
default = [ ];
description = "Convenience option to open specific UDP port ranges for traffic from another node.";
};
};
networkOptions = netSubmod: {
cidrv4 = mkOption {
type = types.nullOr types.net.cidrv4;
@ -25,6 +48,20 @@ let
default = null;
};
firewallRuleForAll = mkOption {
default = { };
description = ''
If this is a wireguard network: Allows you to set specific firewall rules for traffic originating from any participant in this
wireguard network. A corresponding rule `<network-name>-to-<local-zone-name>` will be created to easily expose
services to the network.
'';
type = types.submodule {
options = firewallOptions;
};
};
hosts = mkOption {
default = { };
type = types.attrsOf (
@ -85,6 +122,20 @@ let
# if we use the /32 wan address as local address directly, do not use the network address in ipv6
lib.net.cidr.hostCidr (if hostSubmod.config.id == 0 then 1 else hostSubmod.config.id) netSubmod.config.cidrv6;
};
firewallRuleForNode = mkOption {
default = { };
description = ''
If this is a wireguard network: Allows you to set specific firewall rules just for traffic originating from another network node.
A corresponding rule `<network-name>-node-<node-name>-to-<local-zone-name>` will be created to easily expose
services to that node.
'';
type = types.attrsOf (
types.submodule {
options = firewallOptions;
}
);
};
};
})
);
@ -210,12 +261,14 @@ in
};
};
general = lib.mkOption {
type = types.submodule {
freeformType = types.unspecified;
};
};
};
};
};

View file

@ -1,5 +1,5 @@
# adapted from https://github.com/oddlama/nix-config/blob/main/modules/distributed-config.nix
{ config, lib, outputs, ... }:
{ config, lib, nodes, ... }:
let
nodeName = config.node.name;
mkForwardedOption =
@ -23,23 +23,21 @@ let
'';
};
expandOptions = basePath: optionNames: map (option: basePath ++ [ option ]) optionNames;
splitPath = path: lib.splitString "." path;
forwardedOptions = [
[
"services"
"nginx"
"upstreams"
]
[
"services"
"nginx"
"virtualHosts"
]
[
"swarselsystems"
"server"
"dns"
]
];
(splitPath "boot.kernel.sysctl")
(splitPath "networking.nftables.chains.postrouting")
(splitPath "services.kanidm.provision.groups")
(splitPath "services.kanidm.provision.systems.oauth2")
(splitPath "sops.secrets")
(splitPath "swarselsystems.server.dns")
]
++ expandOptions (splitPath "networking.nftables.firewall") [ "zones" "rules" ]
++ expandOptions (splitPath "services.firezone.gateway") [ "enable" "name" "apiUrl" "tokenFile" "package" "logLevel" ]
++ expandOptions (splitPath "services.nginx") [ "upstreams" "virtualHosts" ]
;
attrsForEachOption =
f: lib.foldl' (acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path (f path))) { } forwardedOptions;
@ -60,10 +58,10 @@ in
getConfig =
path: otherNode:
let
cfg = outputs.nixosConfigurations.${otherNode}.config.nodes.${nodeName} or null;
cfg = nodes.${otherNode}.config.nodes.${nodeName} or null;
in
lib.optionals (cfg != null) (lib.getAttrFromPath path cfg);
mergeConfigFromOthers = path: lib.mkMerge (lib.concatMap (getConfig path) (lib.attrNames outputs.nixosConfigurations));
mergeConfigFromOthers = path: lib.mkMerge (lib.concatMap (getConfig path) (lib.attrNames nodes));
in
attrsForEachOption mergeConfigFromOthers;
}

View file

@ -1,7 +1,7 @@
{ self, lib, config, globals, dns, confLib, ... }:
let
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "ankisync"; port = 27701; }) servicePort serviceName serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "ankisync"; port = 27701; }) servicePort serviceName serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
ankiUser = globals.user.name;
in
@ -9,11 +9,11 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
sops.secrets.anki-pw = { inherit sopsFile; owner = "root"; };
@ -23,16 +23,26 @@ in
info = "https://${serviceDomain}";
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.anki-sync-server = {
enable = true;
port = servicePort;
address = "0.0.0.0";
openFirewall = true;
# openFirewall = true;
users = [
{
username = ankiUser;
@ -41,7 +51,7 @@ in
];
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ lib, config, pkgs, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "attic"; port = 8091; }) serviceName serviceDir servicePort serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "attic"; port = 8091; }) serviceName serviceDir servicePort serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
inherit (config.swarselsystems) mainUser isPublic sopsFile;
serviceDB = "atticd";
in
@ -10,13 +10,23 @@ in
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
sops = lib.mkIf (!isPublic) {
@ -36,7 +46,7 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
services.atticd = {
enable = true;
@ -122,7 +132,7 @@ in
after = [ "garage.service" ];
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,31 +1,41 @@
{ lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "atuin"; port = 8888; }) servicePort serviceName serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "atuin"; port = 8888; }) servicePort serviceName serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
enable = true;
host = "0.0.0.0";
port = servicePort;
openFirewall = true;
# openFirewall = true;
openRegistration = false;
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,7 +1,7 @@
{ self, lib, config, ... }:
{ self, lib, config, withHomeManager, ... }:
{
options.swarselmodules.server.bastion = lib.mkEnableOption "enable bastion on server";
config = lib.mkIf config.swarselmodules.server.bastion {
config = lib.mkIf config.swarselmodules.server.bastion ({
users = {
groups = {
@ -50,6 +50,7 @@
}
];
};
} // lib.optionalAttrs withHomeManager {
home-manager.users.jump.config = {
home.stateVersion = lib.mkDefault "23.05";
@ -63,5 +64,5 @@
} // config.repo.secrets.local.ssh.hosts;
};
};
};
});
}

View file

@ -1,6 +1,6 @@
{ self, lib, config, pkgs, dns, globals, confLib, ... }:
let
inherit (confLib.gen { name = "croc"; proxy = config.node.name; }) serviceName serviceDomain proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "croc"; proxy = config.node.name; }) serviceName serviceDomain proxyAddress4 proxyAddress6 isHome dnsServer;
servicePorts = [
9009
9010
@ -17,7 +17,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -44,7 +44,7 @@ in
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
inherit proxyAddress4 proxyAddress6 isHome;
};
services.${serviceName} = {

View file

@ -3,8 +3,8 @@ let
inherit (confLib.gen { name = "dns-hostrecord"; proxy = config.node.name; }) serviceName proxyAddress4 proxyAddress6;
in
{
options. swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf (config.swarselmodules.server.${serviceName} && config.swarselsystems.isCloud) {
nodes.stoicclub.swarselsystems.server.dns.${globals.domains.main}.subdomainRecords = {
"server.${config.node.name}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;

View file

@ -1,6 +1,6 @@
{ self, lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "firefly-iii"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "firefly-iii"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome dnsServer webProxy;
nginxGroup = "nginx";
@ -11,7 +11,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -38,7 +38,7 @@ in
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
inherit proxyAddress4 proxyAddress6 isHome;
};
services = {
@ -81,7 +81,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -0,0 +1,385 @@
{ lib, pkgs, config, globals, confLib, dns, nodes, ... }:
let
inherit (confLib.gen { name = "firezone"; dir = "/var/lib/private/firezone"; }) serviceName serviceDir serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy homeProxyIf webProxyIf idmServer dnsServer;
inherit (config.swarselsystems) sopsFile;
apiPort = 8081;
webPort = 8080;
relayPort = 3478;
domainPort = 9003;
homeServices = lib.attrNames (lib.filterAttrs (_: serviceCfg: serviceCfg.isHome) globals.services);
homeDomains = map (name: globals.services.${name}.domain) homeServices;
allow = group: resource: {
"${group}@${resource}" = {
inherit group resource;
description = "Allow ${group} access to ${resource}";
};
};
in
{
options = {
swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy} = {
allowedTCPPorts = [ apiPort webPort domainPort ];
allowedUDPPorts = [ relayPort ];
allowedUDPPortRanges = [
{
from = config.services.firezone.relay.lowestPort;
to = config.services.firezone.relay.highestPort;
}
];
};
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy} = {
allowedTCPPorts = [ apiPort webPort domainPort ];
allowedUDPPorts = [ relayPort ];
allowedUDPPortRanges = [
{
from = config.services.firezone.relay.lowestPort;
to = config.services.firezone.relay.highestPort;
}
];
};
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
sops = {
secrets = {
kanidm-firezone-client = { inherit sopsFile; mode = "0400"; };
firezone-relay-token = { inherit sopsFile; mode = "0400"; };
firezone-smtp-password = { inherit sopsFile; mode = "0440"; };
firezone-adapter-config = { inherit sopsFile; mode = "0440"; };
};
};
environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
{ directory = serviceDir; mode = "0700"; }
];
services.firezone = {
server = {
enable = true;
enableLocalDB = true;
smtp = {
inherit (config.repo.secrets.local.firezone.mail) from username;
host = globals.services.mailserver.domain;
port = 465;
implicitTls = true;
passwordFile = config.sops.secrets.firezone-smtp-password.path;
};
provision = {
enable = true;
accounts.main = {
name = "Home";
relayGroups.relays.name = "Relays";
gatewayGroups.home.name = "Home";
actors.admin = {
type = "account_admin_user";
name = "Admin";
email = "admin@${globals.domains.main}";
};
groups.anyone = {
name = "anyone";
members = [
"admin"
];
};
auth.oidc =
let
client_id = "firezone";
in
{
name = "Kanidm";
adapter = "openid_connect";
adapter_config = {
scope = "openid email profile";
response_type = "code";
inherit client_id;
discovery_document_uri = "https://${globals.services.kanidm.domain}/oauth2/openid/${client_id}/.well-known/openid-configuration";
clientSecretFile = config.sops.secrets.kanidm-firezone-client.path;
};
};
resources =
lib.genAttrs homeDomains
(domain: {
type = "dns";
name = domain;
address = domain;
gatewayGroups = [ "home" ];
filters = [
{ protocol = "icmp"; }
{
protocol = "tcp";
ports = [
443
80
];
}
{
protocol = "udp";
ports = [ 443 ];
}
];
})
// {
"home.vlan-services.v4" = {
type = "cidr";
name = "home.vlan-services.v4";
address = globals.networks.home-lan.vlans.services.cidrv4;
gatewayGroups = [ "home" ];
};
"home.vlan-services.v6" = {
type = "cidr";
name = "home.vlan-services.v6";
address = globals.networks.home-lan.vlans.services.cidrv6;
gatewayGroups = [ "home" ];
};
};
policies =
{ }
// allow "everyone" "home.vlan-services.v4"
// allow "anyone" "home.vlan-services.v4"
// allow "everyone" "home.vlan-services.v6"
// allow "anyone" "home.vlan-services.v6"
// lib.mergeAttrsList (map (domain: allow "everyone" domain) homeDomains)
// lib.mergeAttrsList (map (domain: allow "anyone" domain) homeDomains);
};
};
domain = {
settings.ERLANG_DISTRIBUTION_PORT = domainPort;
package = pkgs.dev.firezone-server-domain;
};
api = {
externalUrl = "https://${serviceDomain}/api/";
address = "0.0.0.0";
port = apiPort;
package = pkgs.dev.firezone-server-api;
};
web = {
externalUrl = "https://${serviceDomain}/";
address = "0.0.0.0";
port = webPort;
package = pkgs.dev.firezone-server-web;
};
};
relay = {
enable = true;
port = relayPort;
inherit (config.node) name;
apiUrl = "wss://${serviceDomain}/api/";
tokenFile = config.sops.secrets.firezone-relay-token.path;
publicIpv4 = proxyAddress4;
publicIpv6 = proxyAddress6;
openFirewall = lib.mkIf (!isProxied) true;
package = pkgs.dev.firezone-relay;
};
};
# systemd.services.firezone-initialize =
# let
# generateSecrets =
# let
# requiredSecrets = lib.filterAttrs (_: v: v == null) cfg.settingsSecret;
# in
# ''
# mkdir -p secrets
# chmod 700 secrets
# ''
# + lib.concatLines (
# lib.forEach (builtins.attrNames requiredSecrets) (secret: ''
# if [[ ! -e secrets/${secret} ]]; then
# echo "Generating ${secret}"
# # Some secrets like TOKENS_KEY_BASE require a value >=64 bytes.
# head -c 64 /dev/urandom | base64 -w 0 > secrets/${secret}
# chmod 600 secrets/${secret}
# fi
# '')
# );
# loadSecretEnvironment =
# component:
# let
# relevantSecrets = lib.subtractLists (builtins.attrNames cfg.${component}.settings) (
# builtins.attrNames cfg.settingsSecret
# );
# in
# lib.concatLines (
# lib.forEach relevantSecrets (
# secret:
# ''export ${secret}=$(< ${
# if cfg.settingsSecret.${secret} == null then
# "secrets/${secret}"
# else
# "\"$CREDENTIALS_DIRECTORY/${secret}\""
# })''
# )
# );
# in
# {
# script = lib.mkForce ''
# mkdir -p "$TZDATA_DIR"
# # Generate and load secrets
# ${generateSecrets}
# ${loadSecretEnvironment "domain"}
# echo "Running migrations"
# ${lib.getExe cfg.domain.package} eval "Domain.Release.migrate(manual: true)"
# '';
# };
nodes = {
${homeProxy} =
let
nodeCfg = nodes.${homeProxy}.config;
nodePkgs = nodes.${homeProxy}.pkgs;
in
{
sops.secrets.firezone-gateway-token = { inherit (nodeCfg.swarselsystems) sopsFile; mode = "0400"; };
networking.nftables = {
firewall = {
zones.firezone.interfaces = [ "tun-firezone" ];
rules = {
# masquerade firezone traffic
masquerade-firezone = {
from = [ "firezone" ];
to = [ "vlan-services" ];
# masquerade = true; NOTE: custom rule below for ip4 + ip6
late = true; # Only accept after any rejects have been processed
verdict = "accept";
};
# forward firezone traffic
forward-incoming-firezone-traffic = {
from = [ "firezone" ];
to = [ "vlan-services" ];
verdict = "accept";
};
# FIXME: is this needed? conntrack should take care of it and we want to masquerade anyway
forward-outgoing-firezone-traffic = {
from = [ "vlan-services" ];
to = [ "firezone" ];
verdict = "accept";
};
};
};
chains.postrouting = {
masquerade-firezone = {
after = [ "hook" ];
late = true;
rules =
lib.forEach
[
"firezone"
]
(
zone:
lib.concatStringsSep " " [
"meta protocol { ip, ip6 }"
(lib.head nodeCfg.networking.nftables.firewall.zones.${zone}.ingressExpression)
(lib.head nodeCfg.networking.nftables.firewall.zones.vlan-services.egressExpression)
"masquerade random"
]
);
};
};
};
boot.kernel.sysctl = {
"net.core.wmem_max" = 16777216;
"net.core.rmem_max" = 134217728;
};
services.firezone.gateway = {
enable = true;
logLevel = "trace";
inherit (nodeCfg.node) name;
apiUrl = "wss://${globals.services.firezone.domain}/api/";
tokenFile = nodeCfg.sops.secrets.firezone-gateway-token.path;
package = nodePkgs.stable25_05.firezone-gateway; # newer versions of firezone-gateway are not compatible with server package
};
};
${idmServer} =
let
nodeCfg = nodes.${idmServer}.config;
accountId = "6b3c6ba7-5240-4684-95ce-f40fdae45096";
externalId = "08d714e9-1ab9-4133-a39d-00e843a960cc";
in
{
sops.secrets.kanidm-firezone = { inherit (nodeCfg.swarselsystems) sopsFile; owner = "kanidm"; group = "kanidm"; mode = "0440"; };
services.kanidm.provision = {
groups."firezone.access" = { };
systems.oauth2.firezone = {
displayName = "Firezone VPN";
# NOTE: state: both uuids are runtime values
originUrl = [
"https://${globals.services.firezone.domain}/${accountId}/sign_in/providers/${externalId}/handle_callback"
"https://${globals.services.firezone.domain}/${accountId}/settings/identity_providers/openid_connect/${externalId}/handle_callback"
];
originLanding = "https://${globals.services.firezone.domain}/";
basicSecretFile = nodeCfg.sops.secrets.kanidm-firezone.path;
preferShortUsername = true;
scopeMaps."firezone.access" = [
"openid"
"email"
"profile"
];
};
};
};
${webProxy} = {
services.nginx = {
upstreams = {
${serviceName} = {
servers."${serviceAddress}:${builtins.toString webPort}" = { };
};
"${serviceName}-api" = {
servers."${serviceAddress}:${builtins.toString apiPort}" = { };
};
};
virtualHosts = {
${serviceDomain} = {
useACMEHost = globals.domains.main;
forceSSL = true;
acmeRoot = null;
locations."/" = {
# The trailing slash is important to strip the location prefix from the request
proxyPass = "http://${serviceName}/";
proxyWebsockets = true;
};
locations."/api/" = {
# The trailing slash is important to strip the location prefix from the request
proxyPass = "http://${serviceName}-api/";
proxyWebsockets = true;
};
};
};
};
};
};
};
}

View file

@ -1,7 +1,7 @@
{ lib, config, pkgs, globals, dns, confLib, ... }:
let
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "forgejo"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "forgejo"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
kanidmDomain = globals.services.kanidm.domain;
in
@ -9,11 +9,11 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
users.users.${serviceUser} = {
group = serviceGroup;
@ -26,9 +26,19 @@ in
kanidm-forgejo-client = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
@ -130,7 +140,7 @@ in
'';
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ self, lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "freshrss"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "freshrss"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome webProxy dnsServer;
inherit (config.swarselsystems) sopsFile;
in
@ -8,7 +8,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -55,7 +55,7 @@ in
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
inherit proxyAddress4 proxyAddress6 isHome;
};
services.${serviceName} =
@ -76,7 +76,7 @@ in
# config.sops.templates.freshrss-env.path
# ];
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -5,7 +5,7 @@ let
name = "garage";
port = 3900;
domain = config.repo.secrets.common.services.domains."garage-${config.node.name}";
}) servicePort serviceName specificServiceName serviceDomain subDomain baseDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
}) servicePort serviceName specificServiceName serviceDomain subDomain baseDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
cfg = lib.recursiveUpdate config.services.${serviceName} config.swarselsystems.server.${serviceName};
inherit (config.swarselsystems) sopsFile mainUser;
@ -71,9 +71,9 @@ in
}
];
networking.firewall.allowedTCPPorts = [ servicePort 3901 3902 3903 3904 ];
# networking.firewall.allowedTCPPorts = [ servicePort 3901 3902 3903 3904 ];
nodes.stoicclub.swarselsystems.server.dns.${baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${baseDomain}.subdomainRecords = {
"${subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
"${subDomain}-admin" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
"${subDomain}-web" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
@ -102,9 +102,19 @@ in
];
};
globals.services.${specificServiceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort 3901 3902 3903 3904 ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort 3901 3902 3903 3904 ];
};
};
services.${specificServiceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
@ -309,7 +319,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,20 +1,30 @@
{ lib, pkgs, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "homebox"; port = 7745; }) servicePort serviceName serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "homebox"; port = 7745; }) servicePort serviceName serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
@ -29,9 +39,9 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ inputs, lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "hydra"; port = 8002; }) serviceName servicePort serviceUser serviceGroup serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "hydra"; port = 8002; }) serviceName servicePort serviceUser serviceGroup serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
inherit (config.swarselsystems) sopsFile;
in
{
@ -9,13 +9,23 @@ in
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
sops = {
@ -94,7 +104,7 @@ in
];
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
programs.ssh = {
extraConfig = ''
@ -102,7 +112,7 @@ in
'';
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,12 +1,12 @@
{ lib, pkgs, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "immich"; port = 3001; }) servicePort serviceName serviceUser serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "immich"; port = 3001; }) servicePort serviceName serviceUser serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -16,9 +16,20 @@ in
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
# networking.firewall.allowedTCPPorts = [ servicePort ];
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
@ -26,16 +37,15 @@ in
package = pkgs.immich;
host = "0.0.0.0";
port = servicePort;
openFirewall = true;
# openFirewall = true;
mediaLocation = "/Vault/Eternor/Immich"; # dataDir
environment = {
IMMICH_MACHINE_LEARNING_URL = lib.mkForce "http://localhost:3003";
};
};
networking.firewall.allowedTCPPorts = [ servicePort ];
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,12 +1,12 @@
{ pkgs, lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "jellyfin"; port = 8096; }) servicePort serviceName serviceUser serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "jellyfin"; port = 8096; }) servicePort serviceName serviceUser serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -30,18 +30,28 @@ in
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
enable = true;
user = serviceUser;
openFirewall = true; # this works only for the default ports
# openFirewall = true; # this works only for the default ports
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,18 +1,28 @@
{ pkgs, lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "jenkins"; port = 8088; }) servicePort serviceName serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "jenkins"; port = 8088; }) servicePort serviceName serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.jenkins = {
@ -24,7 +34,7 @@ in
home = "/Vault/apps/${serviceName}";
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -2,7 +2,7 @@
let
certsSopsFile = self + /secrets/repo/certs.yaml;
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "kanidm"; port = 8300; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "kanidm"; port = 8300; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy homeProxyIf webProxyIf dnsServer;
oauth2ProxyDomain = globals.services.oauth2-proxy.domain;
immichDomain = globals.services.immich.domain;
@ -31,16 +31,18 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
users.users.${serviceUser} = {
group = serviceGroup;
isSystemUser = true;
};
users = {
users.${serviceUser} = {
group = serviceGroup;
isSystemUser = true;
};
users.groups.${serviceGroup} = { };
groups.${serviceGroup} = { };
};
sops = {
secrets = {
@ -58,11 +60,22 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
general.idmServer = config.node.name;
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
environment.persistence."/persist" = lib.mkIf config.swarselsystems.isImpermanence {
@ -380,7 +393,7 @@ in
${serviceName}.serviceConfig.RestartSec = "30";
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -2,7 +2,7 @@
let
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "kavita"; port = 8080; }) servicePort serviceName serviceUser serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "kavita"; port = 8080; }) servicePort serviceName serviceUser serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
@ -11,7 +11,7 @@ in
calibre
];
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -21,17 +21,26 @@ in
sops.secrets.kavita-token = { inherit sopsFile; owner = serviceUser; };
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
topology.self.services.${serviceName} = {
name = "Kavita";
info = "https://${serviceDomain}";
icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
@ -42,7 +51,7 @@ in
dataDir = "/Vault/data/${serviceName}";
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ self, lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "koillection"; port = 2282; dir = "/Vault/data/koillection"; }) servicePort serviceName serviceUser serviceDir serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "koillection"; port = 2282; dir = "/Vault/data/koillection"; }) servicePort serviceName serviceUser serviceDir serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
serviceDB = "koillection";
postgresUser = config.systemd.services.postgresql.serviceConfig.User; # postgres
@ -14,7 +14,7 @@ in
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
sops.secrets = {
@ -28,9 +28,19 @@ in
icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort postgresPort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort postgresPort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
virtualisation.oci-containers.containers = {
@ -74,7 +84,7 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort postgresPort ];
# networking.firewall.allowedTCPPorts = [ servicePort postgresPort ];
systemd.services.postgresql.postStart =
let
@ -107,7 +117,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,8 +1,8 @@
{ lib, config, globals, dns, confLib, ... }:
let
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "mailserver"; dir = "/var/lib/dovecot"; user = "virtualMail"; group = "virtualMail"; port = 443; }) serviceName serviceDir servicePort serviceUser serviceGroup serviceAddress serviceDomain serviceProxy proxyAddress4 proxyAddress6;
inherit (config.repo.secrets.local.mailserver) user1 alias1_1 alias1_2 alias1_3 alias1_4 user2 alias2_1 alias2_2 user3;
inherit (confLib.gen { name = "mailserver"; dir = "/var/lib/dovecot"; user = "virtualMail"; group = "virtualMail"; port = 443; }) serviceName serviceDir servicePort serviceUser serviceGroup serviceAddress serviceDomain proxyAddress4 proxyAddress6 isHome webProxy dnsServer;
inherit (config.repo.secrets.local.mailserver) user1 alias1_1 alias1_2 alias1_3 alias1_4 user2 alias2_1 alias2_2 alias2_3 user3;
baseDomain = globals.domains.main;
roundcubeDomain = config.repo.secrets.common.services.domains.roundcube;
@ -15,7 +15,7 @@ in
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host endpointAddress4 endpointAddress6;
"${globals.services.roundcube.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -28,7 +28,7 @@ in
};
roundcube = {
domain = roundcubeDomain;
inherit proxyAddress4 proxyAddress6;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
@ -60,6 +60,9 @@ in
openFirewall = true;
certificateScheme = "acme";
dmarcReporting.enable = true;
enableSubmission = true;
enableSubmissionSsl = true;
enableImapSsl = true;
loginAccounts = {
"${user1}@${baseDomain}" = {
@ -76,6 +79,7 @@ in
aliases = [
"${alias2_1}@${baseDomain}"
"${alias2_2}@${baseDomain}"
"${alias2_3}@${baseDomain}"
];
sendOnly = true;
};
@ -125,7 +129,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {
@ -144,6 +148,8 @@ in
proxyPass = "https://${serviceName}";
extraConfig = ''
client_max_body_size 0;
proxy_ssl_server_name on;
proxy_ssl_name ${roundcubeDomain};
'';
};
};

View file

@ -1,7 +1,7 @@
{ lib, config, pkgs, globals, dns, confLib, ... }:
let
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "matrix"; user = "matrix-synapse"; port = 8008; }) servicePort serviceName serviceUser serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "matrix"; user = "matrix-synapse"; port = 8008; }) servicePort serviceName serviceUser serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
federationPort = 8448;
whatsappPort = 29318;
@ -20,7 +20,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -60,7 +60,7 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort federationPort ];
# networking.firewall.allowedTCPPorts = [ servicePort federationPort ];
systemd = {
timers."restart-bridges" = {
@ -91,9 +91,19 @@ in
};
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort federationPort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services = {
@ -293,7 +303,7 @@ in
# messages out after a while.
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ self, lib, config, dns, globals, confLib, ... }:
let
inherit (confLib.gen { name = "microbin"; port = 8777; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "microbin"; port = 8777; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
inherit (config.swarselsystems) sopsFile;
@ -10,7 +10,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -50,9 +50,19 @@ in
icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
@ -99,13 +109,13 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
{ directory = cfg.dataDir; user = serviceUser; group = serviceGroup; mode = "0700"; }
];
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ lib, config, pkgs, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; proxy = config.node.name; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "minecraft"; port = 25565; dir = "/opt/minecraft"; proxy = config.node.name; }) serviceName servicePort serviceDir serviceDomain proxyAddress4 proxyAddress6 isHome dnsServer;
inherit (config.swarselsystems) mainUser;
worldName = "${mainUser}craft";
in
@ -8,7 +8,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -16,7 +16,7 @@ in
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
inherit proxyAddress4 proxyAddress6 isHome;
};
networking.firewall.allowedTCPPorts = [ servicePort ];

View file

@ -1,6 +1,6 @@
{ lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "grafana"; port = 3000; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "grafana"; port = 3000; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
prometheusPort = 9090;
prometheusUser = "prometheus";
@ -18,7 +18,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -56,13 +56,23 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
# networking.firewall.allowedTCPPorts = [ servicePort prometheusPort ];
topology.self.services.prometheus.info = "https://${serviceDomain}/${prometheusWebRoot}";
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort prometheusPort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort prometheusPort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services = {
@ -212,7 +222,7 @@ in
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
"${grafanaUpstream}" = {
servers = {

View file

@ -1,12 +1,12 @@
{ pkgs, config, lib, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "navidrome"; port = 4040; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "navidrome"; port = 4040; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -37,11 +37,21 @@ in
enableAllFirmware = lib.mkForce true;
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.snapserver = {
@ -67,7 +77,7 @@ in
services.${serviceName} = {
enable = true;
openFirewall = true;
# openFirewall = true;
settings = {
LogLevel = "debug";
Address = "0.0.0.0";
@ -106,7 +116,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -48,6 +48,7 @@ in
inherit (config.repo.secrets.local.networking) defaultGateway4;
wanAddress4 = netConfig.wanAddress4 or null;
wanAddress6 = netConfig.wanAddress6 or null;
isHome = if (netPrefix == "home") then true else false;
};
networking = {

View file

@ -2,7 +2,7 @@
let
inherit (config.repo.secrets.local.nextcloud) adminuser;
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "nextcloud"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "nextcloud"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome dnsServer webProxy;
nextcloudVersion = "32";
in
@ -10,7 +10,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -21,7 +21,7 @@ in
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
inherit proxyAddress4 proxyAddress6 isHome;
};
services = {
@ -50,7 +50,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -3,7 +3,7 @@ with dns.lib.combinators; {
SOA = {
nameServer = "soa";
adminEmail = "admin@${globals.domains.main}"; # this option is not parsed as domain (we cannot just write "admin")
serial = 2025122204; # update this on changes for secondary dns
serial = 2025122401; # update this on changes for secondary dns
};
useOrigin = false;

View file

@ -1,6 +1,6 @@
{ lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "oauth2-proxy"; port = 3004; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
kanidmDomain = globals.services.kanidm.domain;
mainDomain = globals.domains.main;
@ -119,7 +119,7 @@ in
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -142,11 +142,21 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services = {
@ -198,7 +208,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,7 +1,7 @@
{ lib, pkgs, config, dns, globals, confLib, ... }:
let
inherit (config.swarselsystems) sopsFile;
inherit (confLib.gen { name = "paperless"; port = 28981; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "paperless"; port = 28981; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
tikaPort = 9998;
gotenbergPort = 3002;
@ -11,7 +11,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -24,11 +24,21 @@ in
kanidm-paperless-client = { inherit sopsFile; owner = serviceUser; group = serviceGroup; mode = "0440"; };
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services = {
@ -99,7 +109,7 @@ in
)
'';
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,7 +1,6 @@
{ lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "radicale"; port = 8000; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
# sopsFile = config.node.secretsDir + "/secrets2.yaml";
inherit (confLib.gen { name = "radicale"; port = 8000; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
inherit (config.swarselsystems) sopsFile;
cfg = config.services.${serviceName};
@ -10,7 +9,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -35,9 +34,19 @@ in
topology.self.services.${serviceName}.info = "https://${serviceDomain}";
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = {
@ -89,9 +98,9 @@ in
};
};
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -23,7 +23,7 @@ in
config.swarselsystems.shellAliases;
nixpkgs.config = lib.mkIf (!config.swarselsystems.isMicroVM) {
perittedInsecurePackages = [
permittedInsecurePackages = [
# matrix
"olm-3.2.16"
# sonarr

View file

@ -1,6 +1,6 @@
{ self, lib, config, dns, globals, confLib, ... }:
let
inherit (confLib.gen { name = "shlink"; port = 8081; dir = "/var/lib/shlink"; }) servicePort serviceName serviceDomain serviceDir serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "shlink"; port = 8081; dir = "/var/lib/shlink"; }) servicePort serviceName serviceDomain serviceDir serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
containerRev = "sha256:1a697baca56ab8821783e0ce53eb4fb22e51bb66749ec50581adc0cb6d031d7a";
@ -12,7 +12,7 @@ in
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -69,7 +69,7 @@ in
]
);
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
{ directory = serviceDir; }
@ -82,12 +82,22 @@ in
icon = "${self}/files/topology-images/${serviceName}.png";
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ self, lib, config, dns, globals, confLib, ... }:
let
inherit (confLib.gen { name = "slink"; port = 3000; dir = "/var/lib/slink"; }) servicePort serviceName serviceDomain serviceDir serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "slink"; port = 3000; dir = "/var/lib/slink"; }) servicePort serviceName serviceDomain serviceDir serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
containerRev = "sha256:98b9442696f0a8cbc92f0447f54fa4bad227af5dcfd6680545fedab2ed28ddd9";
in
@ -10,7 +10,7 @@ in
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -47,7 +47,7 @@ in
]
);
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
environment.persistence."/persist".directories = lib.mkIf config.swarselsystems.isImpermanence [
{ directory = serviceDir; }
@ -59,12 +59,22 @@ in
icon = "${self}/files/topology-images/shlink.png";
};
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy}.allowedTCPPorts = [ servicePort ];
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy}.allowedTCPPorts = [ servicePort ];
};
};
services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ lib, config, globals, dns, confLib, ... }:
let
inherit (confLib.gen { name = "snipeit"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "snipeit"; port = 80; }) servicePort serviceName serviceUser serviceGroup serviceDomain serviceAddress proxyAddress4 proxyAddress6 isHome webProxy dnsServer;
# sopsFile = config.node.secretsDir + "/secrets2.yaml";
inherit (config.swarselsystems) sopsFile;
@ -12,7 +12,7 @@ in
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${serviceName}.baseDomain}.subdomainRecords = {
"${globals.services.${serviceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -26,7 +26,7 @@ in
globals.services.${serviceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
inherit proxyAddress4 proxyAddress6 isHome;
};
services.snipe-it = {
@ -46,7 +46,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${serviceName} = {
servers = {

View file

@ -1,7 +1,7 @@
{ lib, config, globals, dns, confLib, ... }:
let
inherit (config.swarselsystems.syncthing) serviceDomain;
inherit (confLib.gen { name = "syncthing"; port = 8384; }) servicePort serviceName serviceUser serviceGroup serviceAddress serviceProxy proxyAddress4 proxyAddress6;
inherit (confLib.gen { name = "syncthing"; port = 8384; }) servicePort serviceName serviceUser serviceGroup serviceAddress proxyAddress4 proxyAddress6 isHome isProxied homeProxy webProxy dnsServer homeProxyIf webProxyIf;
specificServiceName = "${serviceName}-${config.node.name}";
@ -42,7 +42,7 @@ in
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
nodes.stoicclub.swarselsystems.server.dns.${globals.services.${specificServiceName}.baseDomain}.subdomainRecords = {
nodes.${dnsServer}.swarselsystems.server.dns.${globals.services.${specificServiceName}.baseDomain}.subdomainRecords = {
"${globals.services.${specificServiceName}.subDomain}" = dns.lib.combinators.host proxyAddress4 proxyAddress6;
};
@ -54,11 +54,27 @@ in
users.groups.${serviceGroup} = { };
networking.firewall.allowedTCPPorts = [ servicePort ];
# networking.firewall.allowedTCPPorts = [ servicePort ];
globals.services.${specificServiceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6;
globals = {
networks = {
${webProxyIf}.hosts = lib.mkIf isProxied {
${config.node.name}.firewallRuleForNode.${webProxy} = {
allowedTCPPorts = [ servicePort 22000 ];
allowedUDPPorts = [ 20000 21027 ];
};
};
${homeProxyIf}.hosts = lib.mkIf isHome {
${config.node.name}.firewallRuleForNode.${homeProxy} = {
allowedTCPPorts = [ servicePort 20000 ];
allowedUDPPorts = [ 20000 21027 ];
};
};
};
services.${specificServiceName} = {
domain = serviceDomain;
inherit proxyAddress4 proxyAddress6 isHome;
};
};
services.${serviceName} = rec {
@ -68,7 +84,7 @@ in
dataDir = lib.mkDefault "/Vault/data/${serviceName}";
configDir = "${cfg.dataDir}/.config/${serviceName}";
guiAddress = "0.0.0.0:${builtins.toString servicePort}";
openDefaultPorts = true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
openDefaultPorts = lib.mkIf (!isProxied) true; # opens ports TCP/UDP 22000 and UDP 21027 for discovery
relay.enable = false;
settings = {
urAccepted = -1;
@ -115,7 +131,7 @@ in
};
};
nodes.${serviceProxy}.services.nginx = {
nodes.${webProxy}.services.nginx = {
upstreams = {
${specificServiceName} = {
servers = {

View file

@ -1,6 +1,6 @@
{ self, pkgs, lib, config, confLib, ... }:
let
inherit (confLib.gen { name = "transmission"; }) serviceName serviceDomain;
inherit (confLib.gen { name = "transmission"; }) serviceName serviceDomain isHome;
lidarrUser = "lidarr";
lidarrGroup = lidarrUser;
@ -86,7 +86,10 @@ in
prowlarr.info = "https://${serviceDomain}/prowlarr";
};
globals.services.transmission.domain = serviceDomain;
globals.services.transmission = {
domain = serviceDomain;
inherit isHome;
};
services = {
radarr = {

View file

@ -20,52 +20,81 @@ in
lib.mkEnableOption "enable ${serviceName} settings";
swarselsystems.server.wireguard = {
interfaces = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({ name, config, ... }: {
options = {
isServer = lib.mkEnableOption "set this interface as a wireguard server";
isClient = lib.mkEnableOption "set this interface as a wireguard client";
interfaces =
let
topConfig = config;
in
lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: {
options = {
isServer = lib.mkEnableOption "set this interface as a wireguard server";
isClient = lib.mkEnableOption "set this interface as a wireguard client";
serverName = lib.mkOption {
type = lib.types.str;
default = "";
description = "Hostname of the WireGuard server this interface connects to (when isClient = true).";
};
serverName = lib.mkOption {
type = lib.types.str;
default = if config.isServer then topConfig.node.name else "";
description = "Hostname of the WireGuard server this interface connects to (when isClient = true).";
};
serverNetConfigPrefix = lib.mkOption {
type = lib.types.str;
default =
let
serverCfg = nodes.${config.serverName}.config;
in
if serverCfg.swarselsystems.isCloud
then serverCfg.node.name
else "home";
readOnly = true;
description = "Prefix used to look up the server network in globals.networks.\"<prefix>-wg\".";
};
serverNetConfigPrefix = lib.mkOption {
type = lib.types.str;
default =
let
serverCfg = nodes.${config.serverName}.config;
in
if serverCfg.swarselsystems.isCloud
then serverCfg.node.name
else "home";
readOnly = true;
description = "Prefix used to look up the server network in globals.networks.\"<prefix>-wg\".";
};
ifName = lib.mkOption {
type = lib.types.str;
default = name;
description = "Name of the WireGuard interface.";
};
ifName = lib.mkOption {
type = lib.types.str;
default = name;
description = "Name of the WireGuard interface.";
};
peers = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "WireGuard peer config names (clients when this host is server, or additional peers).";
port = lib.mkOption {
type = lib.types.int;
default = servicePort;
description = "Port of the WireGuard interface.";
};
peers = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = lib.attrNames (lib.filterAttrs (name: _: name != topConfig.node.name) globals.networks."${config.serverNetConfigPrefix}-${config.ifName}".hosts);
description = "WireGuard peer config names of this wireguardinterface.";
};
};
};
}));
default = { };
description = "WireGuard interfaces defined on this host.";
};
}));
default = { };
description = "WireGuard interfaces defined on this host.";
};
};
};
config = lib.mkIf config.swarselmodules.server.${serviceName} {
assertions = lib.concatLists (
lib.flip lib.mapAttrsToList interfaces (
ifName: ifCfg:
let
assertionPrefix = "While evaluating the wireguard network ${ifName}:";
in
[
{
assertion = ifCfg.isServer || (ifCfg.isClient && ifCfg.serverName != "");
message = "${assertionPrefix}: This node must either be a server for the wireguard network or a client with serverName set.";
}
{
assertion = lib.stringLength ifName < 16;
message = "${assertionPrefix}: The specified linkName '${ifName}' is too long (must be max 15 characters).";
}
]
)
);
environment.systemPackages = with pkgs; [
wireguard-tools
];
@ -74,7 +103,6 @@ in
lib.mkMerge (
[
{
# shared host private key
wireguard-private-key = {
inherit sopsFile;
owner = serviceUser;
@ -85,8 +113,8 @@ in
] ++ (map
(i:
let
simpleClientSecrets =
lib.optionalAttrs (i.isClient && i.peers == [ ]) {
clientSecrets =
lib.optionalAttrs i.isClient {
"wireguard-${i.serverName}-${config.node.name}-${i.ifName}-presharedKey" = {
sopsFile = wgSopsFile;
owner = serviceUser;
@ -95,8 +123,8 @@ in
};
};
multiPeerSecrets =
lib.optionalAttrs (i.peers != [ ]) (builtins.listToAttrs (map
serverSecrets =
lib.optionalAttrs i.isServer (builtins.listToAttrs (map
(clientName: {
name = "wireguard-${config.node.name}-${clientName}-${i.ifName}-presharedKey";
value = {
@ -108,17 +136,72 @@ in
})
i.peers));
in
simpleClientSecrets // multiPeerSecrets
clientSecrets // serverSecrets
)
ifaceList)
);
networking = {
firewall.checkReversePath =
lib.mkIf (lib.any (i: i.isClient) ifaceList) "loose";
networking.firewall = {
checkReversePath = lib.mkIf (lib.any (i: i.isClient) ifaceList) "loose";
allowedUDPPorts = lib.mkMerge (
lib.flip lib.mapAttrsToList interfaces (
_: ifCfg:
lib.optional ifCfg.isServer ifCfg.port
)
);
};
firewall.allowedUDPPorts =
lib.mkIf (lib.any (i: i.isServer) ifaceList) [ servicePort ];
networking.nftables.firewall = {
zones = lib.mkMerge
(
lib.flip lib.mapAttrsToList interfaces (
ifName: ifCfg:
{
${ifName}.interfaces = [ ifName ];
}
// lib.listToAttrs (map
(peer:
let
peerNet = globals.networks."${ifCfg.serverNetConfigPrefix}-${ifName}".hosts.${peer};
in
lib.nameValuePair "${ifName}-node-${peer}" {
parent = ifName;
ipv4Addresses = lib.optional (peerNet.ipv4 != null) peerNet.ipv4;
ipv6Addresses = lib.optional (peerNet.ipv6 != null) peerNet.ipv6;
}
)
ifCfg.peers)
)
);
rules = lib.mkMerge (
lib.flip lib.mapAttrsToList interfaces (
ifName: ifCfg:
let
inherit (config.networking.nftables.firewall) localZoneName;
netCfg = globals.networks."${ifCfg.serverNetConfigPrefix}-${ifName}";
in
{
"${ifName}-to-${localZoneName}" = {
inherit (netCfg.firewallRuleForAll) allowedTCPPorts allowedUDPPorts allowedTCPPortRanges allowedUDPPortRanges;
from = [ ifName ];
to = [ localZoneName ];
ignoreEmptyRule = true;
};
}
// lib.listToAttrs (map
(peer:
lib.nameValuePair "${ifName}-node-${peer}-to-${localZoneName}" (
lib.mkIf (netCfg.hosts.${config.node.name}.firewallRuleForNode ? ${peer}) {
inherit (netCfg.hosts.${config.node.name}.firewallRuleForNode.${peer}) allowedTCPPorts allowedTCPPortRanges allowedUDPPorts allowedUDPPortRanges;
from = [ "${ifName}-node-${peer}" ];
to = [ localZoneName ];
ignoreEmptyRule = true;
}
)
)
ifCfg.peers)
)
);
};
systemd.network = {
@ -136,14 +219,10 @@ in
MTUBytes = 1408; # TODO: figure out where we lose those 12 bits (8 from pppoe maybe + ???)
};
address =
if i.isServer then [
globals.networks."${config.swarselsystems.server.netConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv4
globals.networks."${config.swarselsystems.server.netConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv6
] else [
globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv4
globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv6
];
address = [
globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv4
globals.networks."${i.serverNetConfigPrefix}-${ifName}".hosts.${config.node.name}.cidrv6
];
};
})
ifaceList);
@ -196,12 +275,12 @@ in
builtins.readFile "${self}/secrets/public/wg/${clientName}.pub";
PresharedKeyFile =
config.sops.secrets."wireguard-${config.node.name}-${clientName}-${i.ifName}-presharedKey".path;
config.sops.secrets."wireguard-${i.serverName}-${clientName}-${i.ifName}-presharedKey".path;
AllowedIPs =
let
clientInWgNetwork =
globals.networks."${config.swarselsystems.server.netConfigPrefix}-${i.ifName}".hosts.${clientName};
globals.networks."${i.serverNetConfigPrefix}-${i.ifName}".hosts.${clientName};
in
(lib.optional (clientInWgNetwork.ipv4 != null)
(lib.net.cidr.make 32 clientInWgNetwork.ipv4))

View file

@ -35,6 +35,11 @@
serviceProxy = proxy;
proxyAddress4 = globals.hosts.${proxy}.wanAddress4 or null;
proxyAddress6 = globals.hosts.${proxy}.wanAddress6 or null;
inherit (globals.hosts.${config.node.name}) isHome;
inherit (globals.general) homeProxy webProxy dnsServer idmServer;
webProxyIf = "${webProxy}-wgProxy";
homeProxyIf = "home-wgHome";
isProxied = config.node.name != webProxy;
};
mkMicrovm =

View file

@ -67,6 +67,7 @@
hosts
user
root
general
;
};
};

View file

@ -18,6 +18,7 @@
env = lib.mkDefault true;
eza = lib.mkDefault true;
firefox = lib.mkDefault true;
firezone-tray = lib.mkDefault true;
fuzzel = lib.mkDefault true;
gammastep = lib.mkDefault true;
general = lib.mkDefault true;

View file

@ -22,6 +22,7 @@
packages = lib.mkDefault true;
ssh = lib.mkDefault true;
attic-setup = lib.mkDefault true;
dns-hostrecord = lib.mkDefault true;
};
};
};

View file

@ -11,6 +11,7 @@
btrfs = lib.mkDefault true;
distrobox = lib.mkDefault true;
env = lib.mkDefault true;
firezone-client = lib.mkDefault true;
general = lib.mkDefault true;
gnome-keyring = lib.mkDefault true;
gvfs = lib.mkDefault true;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long