feat: adguard tweaks (#108)

* feat: adguard tweaks

* hacking docs

* chore: update zfs scrib int

* hack

* feat: warning for adguard schema mismatch

---------

Co-authored-by: Truxnell <9149206+truxnell@users.noreply.github.com>
This commit is contained in:
Truxnell 2024-04-18 21:18:37 +10:00 committed by GitHub
parent f64c8aca96
commit 9f7a144459
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 438 additions and 336 deletions

View file

@ -1,8 +1,8 @@
*[CI]: Continuous Integration _[CI]: Continuous Integration
*[PR]: Pull Request _[PR]: Pull Request
*[HASS]: Home-assistant _[HASS]: Home-assistant
*[k8s]: Kubernetes _[k8s]: Kubernetes
*[YAML]: Yet Another Markup Language _[YAML]: Yet Another Markup Language
*[JSON]: JavaScript Object Notation _[JSON]: JavaScript Object Notation
*[ZFS]: Originally 'Zettabyte File System', a COW filesystem. _[ZFS]: Originally 'Zettabyte File System', a COW filesystem.
*[COW]: Copy on Write _[COW]: Copy on Write

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View file

@ -32,11 +32,38 @@ Backups are created per-service in each services module. This is largely done wi
NixOS will create a service + timer for each job - below shows the output for a prowlarr local/remote backup. NixOS will create a service + timer for each job - below shows the output for a prowlarr local/remote backup.
```bash ```bash
truxnell@daedalus ~> systemctl list-unit-files | grep restic-backups-prowlarr # Confirming snapshot taken overnight - we can see 2AM
restic-backups-prowlarr-local.service linked enabled truxnell@daedalus ~> systemctl status restic_nightly_snapshot.service
restic-backups-prowlarr-remote.service linked enabled ○ restic_nightly_snapshot.service - Nightly ZFS snapshot for Restic
restic-backups-prowlarr-local.timer enabled enabled Loaded: loaded (/etc/systemd/system/restic_nightly_snapshot.service; linked; preset: enabled)
restic-backups-prowlarr-remote.timer enabled enabled Active: inactive (dead) since Wed 2024-04-17 02:00:02 AEST; 5h 34min ago
Duration: 61ms
TriggeredBy: ● restic_nightly_snapshot.timer
Process: 606080 ExecStart=/nix/store/vd0pr3la91pi0qhmcn7c80rwrn7jkpx9-unit-script-restic_nightly_snapshot-start/bin/restic_nightly_snapshot-start (code=exited, status=0/SUCCESS)
Main PID: 606080 (code=exited, status=0/SUCCESS)
IP: 0B in, 0B out
CPU: 21ms
# confirming local snapshot occured - we can see 05:05AM
truxnell@daedalus ~ [1]> sudo restic-prowlarr-local snapshots
repository 9d9bf357 opened (version 2, compression level auto)
ID Time Host Tags Paths
---------------------------------------------------------------------------------------------------------------------
293dad23 2024-04-15 19:24:37 daedalus /persist/.zfs/snapshot/restic_nightly_snap/containers/prowlarr
24938fe8 2024-04-16 12:42:50 daedalus /persist/.zfs/snapshot/restic_nightly_snap/containers/prowlarr
442d4de3 2024-04-17 05:05:04 daedalus /persist/.zfs/snapshot/restic_nightly_snap/containers/prowlarr
---------------------------------------------------------------------------------------------------------------------
3 snapshots
# confirming remote snapshot occured - we can see 4:52AM
truxnell@daedalus ~> sudo restic-prowlarr-remote snapshots
repository 30b7eef0 opened (version 2, compression level auto)
ID Time Host Tags Paths
---------------------------------------------------------------------------------------------------------------------
e7d933c4 2024-04-15 22:07:09 daedalus /persist/.zfs/snapshot/restic_nightly_snap/containers/prowlarr
aa605c6b 2024-04-16 02:39:47 daedalus /persist/.zfs/snapshot/restic_nightly_snap/containers/prowlarr
68f91a20 2024-04-17 04:52:59 daedalus /persist/.zfs/snapshot/restic_nightly_snap/containers/prowlarr
---------------------------------------------------------------------------------------------------------------------
3 snapshots
``` ```
NixOS (as of 23.05 IIRC) now provides shims to enable easy access to the restic commands with the correct env vars mounted same as the service. NixOS (as of 23.05 IIRC) now provides shims to enable easy access to the restic commands with the correct env vars mounted same as the service.

View file

@ -5,7 +5,12 @@ Why not include a nice message of the day for each server I log into?
The below gives some insight into what the servers running, status of zpools, usage, etc. The below gives some insight into what the servers running, status of zpools, usage, etc.
While not show below - thankfully - If a zpool error is found the status gives a full `zpool status -x` debrief which is particulary eye-catching upon login. While not show below - thankfully - If a zpool error is found the status gives a full `zpool status -x` debrief which is particulary eye-catching upon login.
![Alt text](motd.png) I've also squeezed in a 'reboot required' flag for when the server had detected its running kernel/init/systemd is a different version to what it booted with - useful to know when long running servers require a reboot to pick up new kernel/etc versions.
<figure markdown="span">
![Screenshot of message of the day prompt on login to server](../includes/assets/motd.png)
<figcaption>Message of the day</figcaption>
</figure>
Code TLDR Code TLDR

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

3
docs/network/dns.md Normal file
View file

@ -0,0 +1,3 @@
2 x adguard -> powerdns (authoritive) -> (quad9 || mullvad)
note reverse dns (in.arpa) and split brain setup.
dnssec

View file

@ -1,3 +1,3 @@
## Why not recurse the module folder ## Why not recurse the module folder
Imports are special in NIX and its important that they are definet at runtime for lazy evaluation - if you do optional/coded imports not everything is avaliable for evaluating. Imports are special in NIX and its important that they are defined at runtime for lazy evaluation - if you do optional/coded imports not everything is available for evaluating.

View file

@ -65,7 +65,7 @@ in
Lidarr = { Lidarr = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Music management"; description = "Music management";
container = "${app}"; container = "${app}";
widget = { widget = {
@ -77,12 +77,12 @@ in
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -62,7 +62,7 @@ in
Prowlarr = { Prowlarr = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Content locator"; description = "Content locator";
container = "${app}"; container = "${app}";
widget = { widget = {
@ -74,12 +74,12 @@ in
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -64,7 +64,7 @@ in
Radarr = { Radarr = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Movie management"; description = "Movie management";
container = "${app}"; container = "${app}";
widget = { widget = {
@ -76,12 +76,12 @@ in
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -63,7 +63,7 @@ in
Readar = { Readar = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Book management"; description = "Book management";
container = "${app}"; container = "${app}";
widget = { widget = {
@ -75,12 +75,12 @@ in
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -66,7 +66,7 @@ in
Sonarr = { Sonarr = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "TV show management"; description = "TV show management";
container = "${app}"; container = "${app}";
widget = { widget = {
@ -78,12 +78,12 @@ in
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -56,19 +56,19 @@ in
Backrest = { Backrest = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Local restic backup browser"; description = "Local restic backup browser";
container = "${app}"; container = "${app}";
}; };
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "infrastructure"; group = "infrastructure";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -1,6 +1,7 @@
{ lib { lib
, config , config
, pkgs , pkgs
, self
, ... , ...
}: }:
with lib; with lib;
@ -15,11 +16,12 @@ let
persistentFolder = "${config.mySystem.persistentFolder}/${appFolder}"; persistentFolder = "${config.mySystem.persistentFolder}/${appFolder}";
containerPersistentFolder = "/config"; containerPersistentFolder = "/config";
extraEndpoints = [ extraEndpoints = [
# TODO refactor these out into their own file or fake host?
{ {
name = "firewall"; name = "firewall";
group = "servers"; group = "servers";
url = "icmp://unifi.${config.mySystem.internalDomain}"; url = "icmp://unifi.${config.mySystem.internalDomain}";
interval = "30s"; interval = "1m";
alerts = [{ type = "pushover"; }]; alerts = [{ type = "pushover"; }];
conditions = [ "[CONNECTED] == true" ]; conditions = [ "[CONNECTED] == true" ];
} }
@ -27,7 +29,7 @@ let
name = "pikvm"; name = "pikvm";
group = "servers"; group = "servers";
url = "icmp://pikvm.${config.mySystem.internalDomain}"; url = "icmp://pikvm.${config.mySystem.internalDomain}";
interval = "30s"; interval = "1m";
alerts = [{ type = "pushover"; }]; alerts = [{ type = "pushover"; }];
conditions = [ "[CONNECTED] == true" ]; conditions = [ "[CONNECTED] == true" ];
} }
@ -35,7 +37,7 @@ let
name = "octoprint"; name = "octoprint";
group = "servers"; group = "servers";
url = "icmp://prusa.${config.mySystem.internalDomain}"; url = "icmp://prusa.${config.mySystem.internalDomain}";
interval = "30s"; interval = "1m";
alerts = [{ type = "pushover"; }]; alerts = [{ type = "pushover"; }];
conditions = [ "[CONNECTED] == true" ]; conditions = [ "[CONNECTED] == true" ];
} }
@ -43,7 +45,7 @@ let
name = "icarus"; name = "icarus";
group = "k8s"; group = "k8s";
url = "icmp://icarus.${config.mySystem.internalDomain}"; url = "icmp://icarus.${config.mySystem.internalDomain}";
interval = "30s"; interval = "1m";
alerts = [{ type = "pushover"; }]; alerts = [{ type = "pushover"; }];
conditions = [ "[CONNECTED] == true" ]; conditions = [ "[CONNECTED] == true" ];
} }
@ -51,7 +53,7 @@ let
name = "xerxes"; name = "xerxes";
group = "k8s"; group = "k8s";
url = "icmp://xerxes.${config.mySystem.internalDomain}"; url = "icmp://xerxes.${config.mySystem.internalDomain}";
interval = "30s"; interval = "1m";
alerts = [{ type = "pushover"; }]; alerts = [{ type = "pushover"; }];
conditions = [ "[CONNECTED] == true" ]; conditions = [ "[CONNECTED] == true" ];
} }
@ -59,96 +61,18 @@ let
name = "shodan"; name = "shodan";
group = "k8s"; group = "k8s";
url = "icmp://shodan.${config.mySystem.internalDomain}"; url = "icmp://shodan.${config.mySystem.internalDomain}";
interval = "30s"; interval = "1m";
alerts = [{ type = "pushover"; }]; alerts = [{ type = "pushover"; }];
conditions = [ "[CONNECTED] == true" ]; conditions = [ "[CONNECTED] == true" ];
} }
{
name = "daedalus";
group = "servers";
url = "icmp://daedalus.${config.mySystem.internalDomain}";
interval = "30s";
alerts = [{ type = "pushover"; }];
conditions = [ "[CONNECTED] == true" ];
}
{
name = "dns01 external dns";
group = "dns";
url = "dns01.${config.mySystem.internalDomain}";
dns = {
query-name = "cloudflare.com";
query-type = "A";
};
interval = "30s";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
{
name = "dns02 external dns";
group = "dns";
url = "dns02.${config.mySystem.internalDomain}";
dns = {
query-name = "cloudflare.com";
query-type = "A";
};
interval = "30s";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
{
name = "dns01 internal dns";
group = "dns";
url = "dns01.${config.mySystem.internalDomain}";
dns = {
query-name = "unifi.${config.mySystem.internalDomain}";
query-type = "A";
};
interval = "30s";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
{
name = "dns02 internal dns";
group = "dns";
url = "dns02.${config.mySystem.internalDomain}";
dns = {
query-name = "unifi.${config.mySystem.internalDomain}";
query-type = "A";
};
interval = "30s";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
{
name = "dns01 split DNS";
group = "dns";
url = "dns01.${config.mySystem.internalDomain}";
dns = {
query-name = "${app}.trux.dev";
query-type = "A";
};
interval = "30s";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
{
name = "dns02 split DNS";
group = "dns";
url = "dns02.${config.mySystem.internalDomain}";
dns = {
query-name = "${app}.trux.dev";
query-type = "A";
};
interval = "30s";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
] ++ config.mySystem.services.gatus.monitors; ] ++ builtins.concatMap (cfg: (cfg.config.mySystem.services.gatus.monitors))
(builtins.attrValues self.nixosConfigurations);
configAlerting = { configAlerting = {
# TODO really should make this libdefault and let modules overwrite failure-threshold etc.
pushover = { pushover = {
title = "${app} Internal"; title = "${app} Internal";
application-token = "$PUSHOVER_APP_TOKEN"; application-token = "$PUSHOVER_APP_TOKEN";

View file

@ -1,6 +1,7 @@
{ lib { lib
, config , config
, pkgs , pkgs
, self
, ... , ...
}: }:
with lib; with lib;
@ -23,7 +24,7 @@ let
showStats = true; showStats = true;
disableCollape = true; disableCollape = true;
cardBlur = "md"; cardBlur = "md";
statusStyle = "dot"; statusStyle = "none";
datetime = { datetime = {
text_size = "l"; text_size = "l";
@ -101,7 +102,7 @@ let
{ {
"UDMP" = { "UDMP" = {
href = "https://unifi.${config.mySystem.internalDomain}"; href = "https://unifi.${config.mySystem.internalDomain}";
ping = "https://unifi.${config.mySystem.internalDomain}";
description = "Unifi Dream Machine Pro"; description = "Unifi Dream Machine Pro";
icon = "ubiquiti"; icon = "ubiquiti";
widget = { widget = {
@ -144,7 +145,7 @@ let
{ {
"Prusa Octoprint" = { "Prusa Octoprint" = {
href = "http://prusa.${config.mySystem.internalDomain}:5000"; href = "http://prusa.${config.mySystem.internalDomain}:5000";
ping = "http://prusa.${config.mySystem.internalDomain}:5000";
description = "Prusa MK3s 3D printer"; description = "Prusa MK3s 3D printer";
icon = "octoprint"; icon = "octoprint";
widget = { widget = {
@ -155,10 +156,20 @@ let
}; };
} }
]; ];
services = [ services = [
{ Infrastructure = cfg.infrastructure-services ++ extraInfrastructure; } {
{ Home = cfg.home-services ++ extraHome; } Infrastructure = builtins.concatMap (cfg: (cfg.config.mySystem.services.homepage.infrastructure-services))
{ Media = cfg.media-services; } (builtins.attrValues self.nixosConfigurations) ++ extraInfrastructure;
}
{
Home = builtins.concatMap (cfg: (cfg.config.mySystem.services.homepage.home-services))
(builtins.attrValues self.nixosConfigurations) ++ extraHome;
}
{
Media = builtins.concatMap (cfg: (cfg.config.mySystem.services.homepage.media-services))
(builtins.attrValues self.nixosConfigurations);
}
]; ];
servicesFile = builtins.toFile "homepage-config.yaml" (builtins.toJSON services); servicesFile = builtins.toFile "homepage-config.yaml" (builtins.toJSON services);
emptyFile = builtins.toFile "docker.yaml" (builtins.toJSON [{ }]); emptyFile = builtins.toFile "docker.yaml" (builtins.toJSON [{ }]);
@ -287,11 +298,11 @@ in
]; ];
}; };
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "infrastructure"; group = "infrastructure";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -1,6 +1,6 @@
services: services:
homepage: homepage:
env: ENC[AES256_GCM,data:Oz5OZipRWFnZx4kEvSSHKEOG8YipOc4m4JMA5fd3RZ7nRwSSotADxM8z/6Va6lsjde2OcN3IckJ09MJYT0+a3+WnWsR48E7Uh9H5617H6bb1a5h0BZaHMKkulLIWsWS1K+qNlt45bGsTeLQNdDJTekcgzzHRB3GGwt0Qj+pmDXyaUmMLFLjdulfT9IlBW3QAjjtZx/jBwzpwNG4kBTuRC9pKik8L/OjqZ2Wrx/TmQ45RLQ4o2Vne86CB2/NBj7xLXH7jE7/UhcJY68Mr6DEevecA0cw0c99Ytble1GdpCcj0mb0pL9aD9USighjtIjhljnFKBx+ZvO1UVqA9L5wlSIQeGrBpn45oHOgKG/KTBYRLgCYSHOfUhAA+Zp3vWdajiQ2LPsLpNp1AGROu7ea2iJuim7AYfaXdO320i8jnZCLSPiBXd2DOo+AeqpV+9kbg3Vx4tt0SgIWtSA88oMzm5Lz4Wd5ddIuvuCBUEMnYcdzXBtOO3DgIOvi4AUcV4l2VHCp4iU+ZSvEybF0M54omYsw/yeXkIeYyTY7SLqKxhenrSkG/KXVdPB50zYpXu19/r2qccgPTFj37kxdDCX4Nz64r9ecikqZu5g2paNMINOV/ha/UbehkzdJY/RsPKgU4GSuHxqWEmPzREcUPHpx4HQP6EvS4IPzelg0ZZ0qe77f6hdQAXDux3WYuvy+00PAN+iIhxy4ozE0y8kKtEyFnfqowlzyrjIAyIN6JDiQzQnJyU7sRu6kMkX4K3zJoIdNKkEthJYeOsrcmB67hWD7INtPCy62gc4mgUVux+huZuBBjqw==,iv:fGF0WzgDIR/Z4s7/njbPtP8kk7h1VGz2g3MLN5v7gSw=,tag:n9NAbizmQh2lDf6B+fDGKw==,type:str] env: ENC[AES256_GCM,data:vFNwH73hmfiyVb2kGS0L+FbJ8RtmFPKdUHtqot3Qah5t9LvD1TsBKGRfmvpqEtEsrOzTs0cexzaSYWk9U32c7DGTZpxOUO4pJf917jX1aE1e2jNd++pO9wve2EvyVTnLFUQPzY1c5oYQZlS7EpNAB4pbZowqVRlElDuuiXd4Z78lhQXoUUEcpQo7nCJ2eSj6cmiHEleuE2Kgik2RcWPzsWdR2X/OppZHCI29s/RzuXtt4/J2GcaQrvYwtmejn2GmKwD5HqQMZfJZJjcjO30RzFiFumPfMytK+lmAfohvTztfl7denu1pAQzriSUZ4UYUDmfGXAs+19Ttby7yCB1W3/Hu444PRAUmE5qn2EQhWe8BZ9UgUhfJ9yFPYcMO9fiLNRfF6PnGPQRqoKx+OIAe80tjXZAF600yvvrzXvAoFIxuViMyqk6fth7lo/VKA/sWgZPQayMJ4v69845MAT/Prlc0FGg6f/LYJLRDX+7C5JRo/ZXFaAjwPFB5nLfPkHNWIvowWfALJVparX6mmmF8VynDxwXQ0dDszanr9bzjTiMG6VyshdHUjufzUxYExFOR2869LKHGxIadnMvtWUVvfTKe4BtXKGp5tpi07Bo5kMyva0UEpGBxGQVp656i9OqD6ulT0xWsC5nyfsq7+3RACrBqvGen9AME5+xrz4zaditXp8s+irKTrq3Q5Ge9cV2a9qIJ/LlBnNGjfcM9Mh7xs3pw9pnhF1r9nxcfinPL82JsLXourWS2/s7Nzl/p1VxFCic70k6Y1Ym+meYwdsy+YCJlQfMmMZcuqbhe9yAdwtcvPQRJnIDW9Qy04AK/KUcVryC4acPb7MsiwxvUjfrf/8cU7dWQcf9voF4K7HgjGsBAjE4dzRqAPANIVUgYaZfaQPI=,iv:V4Kwqmt0WwYJZ9LDp4DpTuddpi4Zses57cM+gHfB+tA=,tag:iV7QW1A2kCrUA7pzmVoerg==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
@ -10,59 +10,59 @@ sops:
- recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u - recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwb2JCV1BpWXMrWXdxaElB YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6ZDJpS01TWmMxMGp3eHAr
TDBrb0UxVXBxaHhWNDdPVUt6dk9lOVYxYmxjCit3OGVvVytmM0xoMUgyL0pYU3VW aWpWWi9OREV4L3M4N1JhMC9zdHBqaHZjWjJBCmlUNWordUNkVk5NUmMyLy9wQUVL
engydEpENEJpdGJGMFBiWTcyWGtpeFEKLS0tIDJPMjM2cnFSdDVoWU1mMEl0bHZX WU8rUE44Y0VXdngrUlg1S1RaQWxPOU0KLS0tIGozK3JsZUlqQkpjandXVDBvMGVx
YUEwR2hmNHdDZDdxcmc3OW9rN0J5Q1UK7YIJgv4mNUUJZd+1jJBcYdBLB/g+NEJW NUl2enFMcW9zc0hWUXdrUUNzUzEzYzQKI2U2w5DipoczfO9NeMcLr57KZ2QqtLLa
8nLi1IgSHRMryYOviyu1lJ7zd27pMhjjTkajaIymwi2T1txug7xwAQ== V5q/Wiy3F/+OIxWNBupG6UZLj6N1x3aVw3Qe1FzQGnDaiKy/y8tI1Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c - recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3b0RTRHd0enhXcEFtZXZ5 YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuVXQ1eW5SSnFmd0FGbHlM
Tk8zRWRYbm1UOHRjMFgyRGRQb016bzYzWVRJCjFWbVhZT3p2ZjhCcjFRR05TZnRK emJCK05kemRkdll4TzlpUHRMcDYxNnpVd1JFCnd5MElKbE9IV2o4dFFZYVhQOGdW
KzkxT1plTWVzSythQWFsZXh1Z0ZzRjAKLS0tIEU1cWxZcWg1bTRrYkpWSFFNUkJ2 SXZwUmtaTWo1Y0VSV2F6NFROS1ErVEEKLS0tIDFHeGwyMFI0cmtkQllkM1ZnRDh2
NlROTG9YZWhZeTQ1djEvaUw3NWpKZWsKvWkqBd2nMSnSlwsMf9Y/H/7lZu3TYR6C akVGZVRlM2xlcExEQWJWMml0K0dGWUkKJ7rcTIfMQvO0n4zMkTt3G0toRxhamtxM
S2DayCyLe6JfE3sgTIDiFo9awwTZYM9z+HXdMffnlKdBd1UTGRvH0Q== zZvl67/U32na4ypKe70+L7GrEppUcb7ovr45fFoBE07lmJHpp1AQ8Q==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk - recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvQS9jQUJDU2xHVFM5YXFU YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0N3N0bDRTdmI5OUJieHdk
alBvZjh0TnZEb2ZRTnNHazFEcU9JOHRGWFhnCnpWYlhpVWZHTFQ4S2k5NERNNDE1 amh5MVE5bVRkWDU1STBScTFITWlUSk5veUI4CnFGNi9CaG1zQ0VHZldVWjEzUi9S
bTF5U1htYTRtQjFmclJCNXhCcnFlS0UKLS0tIHpGaE1odmJCSWdRWU1zWnpxRFJo aXZ2OTlpcmpjMExvS0ZYNXQzdEtuQVUKLS0tIFo0QXdyL0s0RmZhVFI0SXU5U0Qr
cWJXQWpFWVk1N3JFeS9zZkt3RGRlMHcKieWN/vbbTCscmY+jAoY2qU46+N+susmN SERFVWFuVHpZeFpjNUM1YkVtS2ZkdWcKVMlnbImup10EOwcboHs4eUyUA21HIevR
AlIHI5B65LlHZ8oAVsfGDrSb4u81dM2sPqg28iY+Ij32AuWBCTWfIQ== uU2YkJiu3jH9QK+iyRz6MNI1ykKQKKCeic3Y+38YVLwGhOy/Fy0cEQ==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc - recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTMFZLS1IrT3BzelZYVlAw YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJNU1MbWhnd2lNbUVML1Jx
M1ExNXVPcDlqNzIvREFOMDVzYk82L0h5YUNBClVvWkxDdnFrU2RDSTBWOWNiVWVL MHRBakJwN29iM08vMlV5S1J2TmgwZnlJM204CnBxRUZMTE1BamhHYTM2dzFlZ3pN
bmprdEJsT2Yvcnc2cGdpUEllYS9adDQKLS0tIHdxT3JPd0tkakNpalVKU2NMUjln QkpFTUhteFNPdklHcGk3YXZWc3FLR2cKLS0tIEV0S05yM09LTkhKZHN0UzRaaWVZ
bCs4S2ZyZDJZRUFqY3JRcHI1UDZGTzAKlW2nKct0J9LpE1WNE73fp0OUpLXesgNx Qm9PeWQvcHVmRlhTMXBhK1BkaUJBUm8Kbjf/8SPQuVDzUKBtFaYH7dDCvBJG1eJc
V8QJ4cNix3V1TX7pPsGOt+driC83kGEjj/jukvrUCiT9IHscDOpY3A== RP6GTA5X3yMetkmOCmFqwMsPlglDrXdPhgDlEr21jkrKrmPz+depmg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw - recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAySG54VVEzOVY2TGNGTGdn YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlaE5rSU0weTVUMHArRzdU
bVVaMUtqamwwamRRQk9qYmpzdk9YbzEvYTAwCkpIb1pXb3VKdUxPNUdyRnZVNWJU MU50UGh4QUsrUDFaYTcxV1hVWTR4UlV4TUg4CjRXWVRRaGkrOThXN2RMNFZJK3cw
cGIzVDNHQWlSSkkxMXJ0RGp1MFNRckEKLS0tIHNSQ0t6SkJYVWZramkwZkUxRGpw VzI5SjZyU3hxZnVQRVdyMmdjTTNEWUUKLS0tIEdOajN0RTY5U2YvNm1BaDFNaU0r
SnZRYUJzMGJwZTFYc0J3Slcrd2ZPYVEKfQ263loKlS0MGe/CCgAiu29trQbR0z/9 UjAxcGhXVXF3U2J5UVJZZUw2RE1STVkKoHLeXECXccCV54SMMC6DCMgT3/x52948
l7ehDvRN+POsckFL12xs/gapkOFIuY9MJ5ngibKVUqVWwGG8cedkRA== x2KSBJ6s33JaIUX8l/Q53NjIOvE9PtevPVT88y+xrdoWccvvGV4yfg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
- recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl - recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl
enc: | enc: |
-----BEGIN AGE ENCRYPTED FILE----- -----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUcmN3UXRGRlJrODQ3MEpr YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXZGlJeVU3UCtjOFFQUXRv
SkdaWUJENXVmRG9tZ2I4ZEVXUTJQOVlrRkdFCk5TUWNtZFk4L0MxeVhvQW1sMllP T1ZWOCtFc1d2Wk0rTmRiNkFXcTlQSnBOTFdzCmFOVHU0RnZpVHliNXNlSnRKa1kx
bHp2cyt2V1R0UmJOQ0laSUpqWEtZcFkKLS0tIGU4c0s5blJPRWIvU1JZTGtURkZh d1dMamMrZzRJQXB6Z2JJZ0FzY1VwTFUKLS0tIHUzV2IzN1BHSlVrNlVpaGhnOUFP
U2NXcDlaWUNJbm5lV0lVQklwTXowajQK3Sdo0OcVXThYTWBZMd/t7hey2ITfKIDT Rnp2UG1IYTk0RWZjY2luTkpyR2JsNGMKUkm0/xUg3yjq44AYxgSZHgon8sMBSn0N
pyKaJc2xDzsgKx/bc2DxjElsROPBF+7Z0gYMv7/aOIhkcGEU3lPKsA== xEdGlN2gpdVTM7ivB4FJrOqalT5KogZc8PQKsAxyja48wv7WXeyS2w==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2024-04-15T06:36:15Z" lastmodified: "2024-04-17T08:04:55Z"
mac: ENC[AES256_GCM,data:AeluQaUlgrC4iYyG/Yqjk4bVv3TWmFYy2uRRN/kFuytjN+TmDlevkWAbQpg9rtJn0f0FohWYvsDB/NNF5uvbDrwwMCqqcUUNs581fxa6QQr89IfXCIlSOCgBKVUtAqH/M1SjHh6K0LxVAlDW5mvr0OvW2WFURDBo45YMMfvoPVs=,iv:1ia1N+rkoTKXmtvEuVyKtZ758PDOfh7FuKOMaoxq49o=,tag:Au6rcmAKcYLzCvEkWiC2Qg==,type:str] mac: ENC[AES256_GCM,data:F2m/YpyHn+BkDm5W6j3O7GAiD/fqiz58tHX2Bo7rrhHz+nhf+3MhqEBLZm9OoGxpDGgDo1D6VBwNcSCY5Q97NDcum/B2v1CHFVMDRm+/nR6L0lnjtObhOsABtZyxzwyzllHOGJtQSen72wc2lYg0EQYod0xYquCa/dLWD5Ce8hw=,iv:zL9zcUVqR61/87ZfkQ54nLzPT6GNkbTvIXpf+46psxg=,tag:NabVmlZgrANHh9rXi+Tc+Q==,type:str]
pgp: [] pgp: []
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.8.1 version: 3.8.1

View file

@ -57,24 +57,24 @@ in
Plex = { Plex = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Media streaming service"; description = "Media streaming service";
container = "${app}"; container = "${app}";
widget = { widget = {
type = "${app}"; type = "tautulli";
url = "https://${app}.${config.mySystem.domain}"; url = "https://tautulli.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_LIDARR__API_KEY}}"; key = "{{HOMEPAGE_VAR_TAUTULLI__API_KEY}}";
}; };
}; };
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}/web/";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -62,7 +62,7 @@ in
Qbittorrent = { Qbittorrent = {
icon = "${app}.png"; icon = "${app}.png";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Torrent Downloader"; description = "Torrent Downloader";
container = "${app}"; container = "${app}";
widget = { widget = {
@ -73,12 +73,12 @@ in
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -60,13 +60,13 @@ in
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -45,26 +45,21 @@ in
mySystem.services.homepage.media-services = mkIf cfg.addToHomepage [ mySystem.services.homepage.media-services = mkIf cfg.addToHomepage [
{ {
Tautulli = { Tautulli = {
icon = "${app}.png"; icon = "${app}.svg";
href = "https://${app}.${config.mySystem.domain}"; href = "https://${app}.${config.mySystem.domain}";
ping = "https://${app}.${config.mySystem.domain}";
description = "Plex Monitoring & Stats"; description = "Plex Monitoring & Stats";
container = "${app}"; container = "${app}";
widget = {
type = "${app}";
url = "https://${app}.${config.mySystem.domain}";
key = "{{HOMEPAGE_VAR_LIDARR__API_KEY}}";
};
}; };
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = app; name = app;
group = "media"; group = "media";
url = "https://${app}.${config.mySystem.domain}"; url = "https://${app}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -75,4 +75,25 @@ with lib;
} }
); );
# Will be v. useful when i grok
# https://github.com/ahbk/my-nixos/blob/5fe1521b11422c66fd823b442393b3b044a5a5b8/lib.nix#L5
# pick a list of attributes from an attrSet
lib.mySystem.pick = attrNames: attrSet: lib.filterAttrs (name: value: lib.elem name attrNames) attrSet;
# create an env-file (package) that can be sourced to set environment variables
lib.mySystem.mkEnv = name: value: pkgs.writeText "${name}-env" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n}=${v}") value));
# loop over an attrSet and merge the attrSets returned from f into one (latter override the former in case of conflict)
lib.mySystem.mergeAttrs = f: attrs: foldlAttrs (acc: name: value: (recursiveUpdate acc (f name value))) { } attrs;
# Iterate all attrs in base and return
# the merged set from all iterated keys in base from
# return path
# lib.mySystem.mkMergeMap = base: return: builtins.concatMap (cfg: (cfg.return)) (builtins.attrValues base);
} }
# # useful?
# foldlAttrs
# # attrbypath?
# let

View file

@ -6,85 +6,198 @@
with lib; with lib;
let let
cfg = config.mySystem.services.adguardhome; cfg = config.mySystem.services.adguardhome;
app = "adguard-home";
yaml_schema_version=23;
port = 53; port = 53;
port_webui = 3000; port_webui = 3000;
in in
{ {
options.mySystem.services.adguardhome = { options.mySystem.services.adguardhome = {
enable = mkEnableOption "Adguard Home"; enable = mkEnableOption "Adguard Home";
addToHomepage = mkEnableOption "Add ${app} to homepage" // { default = true; };
openFirewall = mkEnableOption "Open firewall for ${app}" // { openFirewall = mkEnableOption "Open firewall for ${app}" // {
default = true; default = true;
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.adguardhome = {
enable = true;
mutableSettings = false; # Warn if backups are disable and machine isnt a dev box
settings = { warnings = mkIf (yaml_schema_version != pkgs.adguardhome.schema_version) [ "WARNING: Adguard upstream YAML schema is version ${builtins.toString pkgs.adguardhome.schema_version}, this config is set to ${builtins.toString config.services.adguardhome.settings.schema_version}"];
bind_host = "0.0.0.0";
bind_port = port_webui; sops.secrets = {
auth_attempts = 3; "system/networking/bind/trux.dev".sopsFile = ./secrets.sops.yaml;
block_auth_min = 3600; "system/networking/bind/trux.dev".restartUnits = [ "bind.service" ];
dns = { };
bind_host = "127.0.0.1";
port = port; services.adguardhome = {
upstream_dns = [ enable = true;
"https://dns10.quad9.net/dns-query"
"https://doh.mullvad.net/dns-query" mutableSettings = false;
]; settings = {
fallback_dns = [ "https://dns.cloudflare.com/dns-query" ]; bind_host = "0.0.0.0";
bootstrap_dns = [ bind_port = port_webui;
# quad9 schema_version=yaml_schema_version; # Just to be cautious, defualt is pkgs.adguardhome.schema_version.
"9.9.9.10"
"149.112.112.10" auth_attempts = 3;
"2620:fe::10" block_auth_min = 3600;
"2620:fe::fe:10"
# cloudflare dns = {
"1.1.1.1" # dns server bind deets
"2606:4700:4700::1111" bind_host = "127.0.0.1";
]; port = port;
upstream_mode = "load_balance";
cache_size = 4194304; # bootstrap DNS - used for resolving upstream dns deets
cache_ttl_min = 60; bootstrap_dns = [
cache_optimistic = true; # quad9
use_private_ptr_resolvers = true; "9.9.9.10"
local_ptr_upstreams = [ "localhost:5353" ]; "149.112.112.10"
"2620:fe::10"
"2620:fe::fe:10"
# cloudflare
"1.1.1.1"
"2606:4700:4700::1111"
];
# upstream DNS
upstream_dns = [
# split brain dns - forward to local powerdns
"[/trux.dev/]127.0.0.1:5353"
"[/natallan.com/]127.0.0.1:5353"
# resolve fqdn for local ip's
"[/l.voltaicforge.com/]10.8.10.1"
# reverse dns setup
"[/in-addr.arpa/]10.8.10.1" # reverse dns lookup to UDMP
"[/ip6.arpa/]10.8.10.1" # reverse dns lookup to UDMP
# primary dns - quad9
"https://dns10.quad9.net/dns-query"
];
upstream_mode = "load_balance";
# fallback dns - cloudflare and mullvad
fallback_dns = [
"https://dns.cloudflare.com/dns-query"
"https://doh.mullvad.net/dns-query"
];
# resolving local addresses
local_ptr_upstreams = [ "10.8.10.1" ]; # UDMP router
use_private_ptr_resolvers = true;
# security
enable_dnssec = true;
# local cache settings
cache_size = 100000000; # 100MB - unnessecary but hey
cache_ttl_min = 60;
cache_optimistic = true;
theme = "auto";
};
rewrites = [{
domain = "*.${config.networking.domain}";
answer = "10.8.10.1"; # UDMP router
}];
filters = [ filters = [
{ {
# AdGuard Base filter, Social media filter, Spyware filter, Mobile ads filter, EasyList and EasyPrivacy
enabled = true;
id = 1;
name = "AdGuard DNS filter"; name = "AdGuard DNS filter";
url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"; url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt";
enabled = true;
} }
{ {
# AdAway default blocklist
enabled = true;
id = 2;
name = "AdAway Default Blocklist"; name = "AdAway Default Blocklist";
url = "https://adaway.org/hosts.txt"; url = "https://adaway.org/hosts.txt";
enabled = true;
} }
{ {
name = "OISD (Big)"; # Big OSID
url = "https://big.oisd.nl";
enabled = true; enabled = true;
id = 3;
name = "Big OSID";
url = "https://big.oisd.nl";
} }
{
# 1Hosts Lite
enabled = true;
id = 4;
name = "1Hosts Lite";
url = "https://o0.pages.dev/Lite/adblock.txt";
}
{
# HAGEZI Multi Pro
enabled = true;
id = 4;
name = "hagezi multi pro";
url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/adblock/pro.txt";
}
]; ];
}; };
}; };
};
networking.firewall = mkIf cfg.openFirewall { networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ port port_webui ];
allowedUDPPorts = [ port port_webui ];
};
mySystem.services.gatus.monitors = [
{
name = "${config.networking.hostName} external dns";
group = "dns";
url = "${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port}";
dns = {
query-name = "cloudflare.com";
query-type = "A";
};
interval = "1m";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
{
name = "${config.networking.hostName} internal dns";
group = "dns";
url = "${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port}";
dns = {
query-name = "unifi.${config.mySystem.internalDomain}";
query-type = "A";
};
interval = "1m";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
];
mySystem.services.homepage.infrastructure-services = mkIf cfg.addToHomepage [
{
"Adguard ${config.networking.hostName}" = {
icon = "${app}.svg";
href = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port_webui}";
description = "DNS Ad blocking";
container = "Infrastructure";
widget =
{
type = "adguard";
url = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString port_webui}";
# username = "";
# password = "";
};
};
}
];
allowedTCPPorts = [ port port_webui ];
allowedUDPPorts = [ port port_webui ];
}; };
};
} }

View file

@ -0,0 +1,71 @@
system:
networking:
bind:
key: ENC[AES256_GCM,data:43QoyVqdwHO6eSgjbjgl28FSlD2xaoNxWpnc5D7g7jj6HaMwkz0tAnmg+g1fxEj1m826wxxqtgBjbMaDPj/hHtqYrgXsIvPShBSUDAyjoLcNFcsr0BhFVQ/ZWCCiI95SScbMTBJVcegf,iv:/R/7Qb+xPQXjYaQbF3NLeA63XAvdctayO5G8pE9bCE4=,tag:roNy7HNjWrIwZjy3BDAedw==,type:str]
trux.dev: ENC[AES256_GCM,data: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,iv:MEA1aXQR/4LFrVOrJmWWwXkbT3FWR8Hp2c4kiw4yv7Y=,tag:FufABt/+oXZCXXw55hvuwA==,type:str]
natallan.com: ENC[AES256_GCM,data:nsivV8P1dSHSN/ty7tvBciKz/9xslQFohHh8fYkgoMy2dRoywaxT4+S3/tl499KP1mepw6E0z8SC3vnj5XzT4kFPEcSoUk6OpZTaqNWlwIU7PsaPys41uK9wszkj4W0J1BdbExC9hn4IkwXJ7iRlMqwSlTc2VlNiu+nhiuixvSdsYWqzGpXFzWzd0oPphq/PmJCM2ZQMbVKTnFSer9oeQBRxJ6lj4XYxO6HxT2XNPkXBnx8dr7vgLSANN8GwdnYHbIZ9XWDhaVw+VY21pXyF0I9tnbuZ5oherqTO9cbZ6NGpYeschs3ep9tpoC7QLnJwbOncfCcCvbKxjbdfRzJ+8Mjv16jAmDyFjQII9tvW7NtJtV1zWM59l62u2d7NAHuaEYE2Gr+UES4+DDKw5n6SoYAgHw6k9jMmrtSUKI8TRaBDBTrbuvnhbZOaYF0kLV2De5HWs2wvR7W58tWkmKejI2xYinpkXjtdF8zESdPjgDImnDobQX03GF7HY7tdbZ0ZtdWMI7fud66Db8TumXN3bbQAx9nOFTaNba49jKjVybwVMeOVKrYbbh3X9SpM+REh6fDN0a4iEgrP4I8YF+PqeAxVFlmHWe8JAICLR3JhU75mVYve3u27XGxX3DhGzvIM/JiifcpOg3Lg1rn1RhWt3Zq+H9ygo4N9Sigk/pT7pBhlm548uibYi7/TFe1I5CXkGGQ+I47CKUJzK934EqN9zZ80qDdQS0AN7cI8hXCXgc7+nVBNc/5cu3y9ubKF7xWyhL3RgwdSbCnthG2EQ7GEMZnhDRdazYtdmZhoJw6MyL/AFVZgbHfAyg==,iv:TLCkT60LTZ2m3gYCz4YQ/XYhvbdZJApoW3OekEVjULI=,tag:ZlxHEZQa/pUwjQF3HdqYdw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1lj5vmr02qkudvv2xedfj5tq8x93gllgpr6tzylwdlt7lud4tfv5qfqsd5u
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6cW5zMXc2Skc0S0lvWXF2
NE0za1kyOU5GY0Z0QW9hTDVuTWRPd2pTcTBjClhOT0xrYUo4Y2Rtd0dyQU9MeWtq
dHZMWGZhbWtTOUVPMDlhWUdhVEhIZVEKLS0tIG12Ujh6WEVNeUdvVmtuYmZJdVJG
bWZxWXU5TzlYNDZnY1Fua3RGUEJnNUkKMC/png4A565h/S3B2ZVce7LJi1SMDS5n
aYx/nrPTktIe8bCvwF300tNZoZolXONR4awJ9e88uw84t8GYjlNNPw==
-----END AGE ENCRYPTED FILE-----
- recipient: age17edew3aahg3t5nte5g0a505sn96vnj8g8gqse8q06ccrrn2n3uysyshu2c
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGVmkxam5MVW1FSEo4QjB4
c0VKUDJIVDI1WkFOYmJ2TEcrWGlqQVFGQm1RClBxSjRjSGd3SkRIbUc4OUdhT0F2
WVJoUlR0amdOcTE4YUMwR1JjTGlBRUkKLS0tIHZFKy9XWnVoQUJLTzZGclp6Y0tQ
cUVoQk9JMEpRNUNQbjcxbnFiUDNmbFUKIBJcq8uJCIhdMv5e79K66Qrxlg88K/Gb
MT1h2v6h5uiYm6JaspSqz9Hqx9YfRocl/kJmVy/QdeIGPVzm24dnIQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1u4tht685sqg6dkmjyer96r93pl425u6353md6fphpd84jh3jwcusvm7mgk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1Sy85ZVA3WGVhVWlSZmhy
VDBDK2dZYmR6djlQYkhhQ25zeWdxM1JpMEg0Ck5hZm12ZmtkQmJLUmdMNm94WnZL
NnY1eG1neEpLSEVkRGhkY2FHUFhTWVkKLS0tIGVpNlZrRGtqRFR1OVc3enpRUVQ2
N2swa1BIellpbjBUbmsyc2NnYmphOU0Kx/4I/zjyi3GlYMgcNIb7sYufLfvJ9Xny
HeR7r03YuHu5dOQ1T8iFigXUhy/2DkdW8kWtKlpuT0qg35dKqjCi/w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1cp6vegrmqfkuj8nmt2u3z0sur7n0f7e9x9zmdv4zygp8j2pnucpsdkgagc
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyVjBXb2EzM3U0MDRnRGV6
YWJieTFHaXFFOEhFdjJNU2x3VVlSOEpBNFFjCkpNZWpxa3ZRRFVabXd5enFqenZY
aXpqOC90YXB2aTR5K1FFQ2dnNXVCZlUKLS0tIGkvTmpLeFNGdWpaRU9CaGtLcWgr
d09aV285U3YrNjY2VVpFaGtFS1B3bUUKRL1dsEHuWbEjRaKqd2F6xrhC7htNo0hw
fItd7J3gccRP5jUTzJ0QZBJvsj9wCAQU1iJfv14zcO6TzOB5B4jW7w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1j2r8mypw44uvqhfs53424h6fu2rkr5m7asl7rl3zn3xzva9m3dcqpa97gw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2WE5LVEFIdVFXT3I1Znk1
NmJzWWZHQ05GclNuMFUvZE9PazdFYmZVWmlNClpHVVB1bFhUU3phUjlhQTBDTENq
QkNFMTc3VTU1SkxtK0x3SnFzYm90aTgKLS0tIHJHc3NXekM4Ly9SSEFydFZrTk9l
MVUxcEpUemlmWmRvQThUdTdkQ2svNHcK0WyOuWbv+eyYWLFsKBl+K+/n9QCfehqQ
0hC0SY2Nf+9YHMDXrSse44NPs/ucOPlYRFV/HbPNvfEF62K7Gt79lA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jpeh4s553taxkyxhzlshzqjfrtvmmp5lw0hmpgn3mdnmgzku332qe082dl
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3SHFQQUIzQXlqZFFnTWNt
YVJIb0MzTFM2NENpNFFiaHFmaU95K3VLNGdZCkFyMEFHZjhZclJMTE4yRWNJQnJR
T25yTWZQOFE5L011M3FnMUxPb3hPbVEKLS0tIElzYlpHUEQwejlDNTFmK3R1dU0r
RzJ5UGIvUUluZXNzRzlXRWl5aGdmaUUKObqo2Wj62ZcK0qMcsttRHphWTgkPOTz4
NkvAvOaSX2wJHRhH9SHGhkPwEhsgdmaagsVpwpLPrOCRlWI/bd1Qhg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-04-16T06:30:13Z"
mac: ENC[AES256_GCM,data:PsD5hu5nyjPY9/bgLTiTReqoT+hwlJx8A5pOkCTcPNQs63So4GM5mDDTuWG8u1WlBOEdKEDqVefVMtCiwOsC6xIVM8AHCGOcad2j4qQbHR+2lc8nMZE8R7ceJc2ZeLBPlD5/BQ2R5XiQ+NXu0qypHjYkVwnkI62nPSXALSd9btg=,iv:cy7slD5dcfTEeObWraswcghwhgAe1RylU4aafXezEYU=,tag:/nSCQJDYfrWpfpfdkigV7w==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1

View file

@ -28,7 +28,7 @@ with lib;
}; };
}; };
config = { config = mkIf cfg.enable {
environment.systemPackages = with pkgs; environment.systemPackages = with pkgs;
[ glances python310Packages.psutil hddtemp ]; [ glances python310Packages.psutil hddtemp ];
@ -74,16 +74,16 @@ with lib;
name = "${app} ${config.networking.hostName}"; name = "${app} ${config.networking.hostName}";
group = "${app}"; group = "${app}";
url = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:61208"; url = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:61208:/api/3/status";
ping = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:61208";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];
mySystem.services.homepage.infrastructure-services = mkIf cfg.addToHomepage [ mySystem.services.homepage.infrastructure-services = mkIf cfg.addToHomepage [
{ {
"Glances ${config.networking.hostName}" = { "Glances ${config.networking.hostName}" = {
icon = "${app}.png"; icon = "${app}.svg";
href = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:61208"; href = "http://${config.networking.hostName}.${config.mySystem.internalDomain}:61208";
description = "System Monitoring"; description = "System Monitoring";
container = "Infrastructure"; container = "Infrastructure";

View file

@ -9,17 +9,19 @@ let
persistentFolder = "${config.mySystem.persistentFolder}/nixos/pdns"; persistentFolder = "${config.mySystem.persistentFolder}/nixos/pdns";
user = "pdns"; user = "pdns";
group = "pdns"; group = "pdns";
portDns = 5353; # avoiding conflict with adguardhome
portWebUI = 8081;
configDir = pkgs.writeTextDir "pdns.conf" "${pdnsConfig}"; configDir = pkgs.writeTextDir "pdns.conf" "${pdnsConfig}";
# $APIKEY is replaced via envsubst in the pdns module # $APIKEY is replaced via envsubst in the pdns module
pdnsConfig = '' pdnsConfig = ''
expand-alias=yes expand-alias=yes
resolver=9.9.9.9:53 resolver=9.9.9.9:53
local-address=0.0.0.0:5353 local-address=0.0.0.0:${builtins.toString portDns}
launch=gsqlite3 launch=gsqlite3
gsqlite3-database=${persistentFolder}/pdns.sqlite3 gsqlite3-database=${persistentFolder}/pdns.sqlite3
webserver=yes webserver=yes
webserver-address=0.0.0.0:8081 webserver-address=0.0.0.0:${builtins.toString portWebUI}
webserver-allow-from=10.8.10.0/20 webserver-allow-from=10.8.10.0/20
api=yes api=yes
api-key=$APIKEY api-key=$APIKEY
@ -81,11 +83,28 @@ in
networking.firewall = mkIf cfg.openFirewall { networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ 8081 5353 ]; allowedTCPPorts = [ portWebUI portDns ];
allowedUDPPorts = [ 8081 5353 ]; allowedUDPPorts = [ portDns ];
}; };
mySystem.services.gatus.monitors = [
{
name = "${config.networking.hostName} split DNS";
group = "dns";
url = "${config.networking.hostName}.${config.mySystem.internalDomain}:${builtins.toString portDns}";
dns = {
query-name = "canary.trux.dev"; # special domain always present for testing
query-type = "A";
};
interval = "1m";
alerts = [{ type = "pushover"; }];
conditions = [ "[DNS_RCODE] == NOERROR" ];
}
];
}; };
} }

View file

@ -181,23 +181,23 @@ in
{ {
Traefik = { Traefik = {
icon = "traefik.png"; icon = "traefik.png";
href = "https://traefik.${config.mySystem.domain}/dashboard/"; href = "https://traefik-${config.networking.hostName}.${config.mySystem.domain}/dashboard/";
ping = "https://traefik.${config.mySystem.domain}/dashboard/";
description = "Reverse Proxy"; description = "Reverse Proxy";
widget = { widget = {
type = "traefik"; type = "traefik";
url = "https://traefik.${config.mySystem.domain}"; url = "https://traefik-${config.networking.hostName}.${config.mySystem.domain}";
}; };
}; };
} }
]; ];
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = "traefik"; name = "Traefik ${config.networking.hostName}";
group = "infrastructure"; group = "infrastructure";
url = "https://traefik.${config.mySystem.domain}"; url = "https://traefik-${config.networking.hostName}.${config.mySystem.domain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ]; conditions = [ "[CONNECTED] == true" "[STATUS] == 200" "[RESPONSE_TIME] < 50" ];
}]; }];

View file

@ -9,6 +9,5 @@
./nfs ./nfs
./motd ./motd
./pushover ./pushover
./technitium-dns
]; ];
} }

View file

@ -1,86 +0,0 @@
{ lib
, config
, pkgs
, ...
}:
with lib;
let
stateDir = "/var/lib/technitium-dns-server";
cfg = config.mySystem.system.technitium-dns;
in
{
options.mySystem.system.technitium-dns.enable = mkEnableOption "technitium-dns";
config = mkIf cfg.enable {
networking.firewall = {
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [
53
80
443
5380
53443
];
};
systemd.services.technitium-dns-server = {
description = "Technitium DNS Server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${pkgs.unstable.technitium-dns-server}/bin/technitium-dns-server ${stateDir}";
User = "technitiumdns";
Group = "technitiumdns";
StateDirectory = "technitium-dns-server";
WorkingDirectory = stateDir;
BindPaths = stateDir;
Restart = "always";
RestartSec = 10;
TimeoutStopSec = 10;
KillSignal = "SIGINT";
# Harden the service
LockPersonality = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX AF_NETLINK";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ];
};
};
users = {
users = {
technitiumdns = {
group = "technitiumdns";
isSystemUser = true;
};
};
groups = {
technitiumdns = { };
};
};
};
}

View file

@ -34,6 +34,8 @@ with lib;
services.zfs = { services.zfs = {
autoScrub.enable = true; autoScrub.enable = true;
# Defaults to weekly and is a bit too regular for my NAS
autoScrub.interval = "monthly";
trim.enable = true; trim.enable = true;
}; };

View file

@ -16,13 +16,11 @@ with lib;
mySystem.security.wheelNeedsSudoPassword = false; mySystem.security.wheelNeedsSudoPassword = false;
mySystem.services.cockpit.enable = true; mySystem.services.cockpit.enable = true;
mySystem.system.motd.enable = true; mySystem.system.motd.enable = true;
mySystem.services.gatus.monitors = mkIf config.mySystem.services.gatus.enable [{ mySystem.services.gatus.monitors = [{
name = config.networking.hostName; name = config.networking.hostName;
group = "servers"; group = "servers";
url = "icmp://${config.networking.hostName}.${config.mySystem.internalDomain}"; url = "icmp://${config.networking.hostName}.${config.mySystem.internalDomain}";
interval = "30s"; interval = "1m";
conditions = [ "[CONNECTED] == true" ]; conditions = [ "[CONNECTED] == true" ];
}]; }];