feat: created crab-hole service
This commit is contained in:
parent
290db94f42
commit
46890110f8
7 changed files with 210 additions and 2 deletions
|
|
@ -46,6 +46,10 @@ nix multi user, multi system, configuration with `sops` secret management, `home
|
||||||
|
|
||||||
# Tasks:
|
# Tasks:
|
||||||
|
|
||||||
|
## Chores:
|
||||||
|
- [ ] test out crab hole service
|
||||||
|
- [ ] learn how to use actual
|
||||||
|
|
||||||
## Tech Debt
|
## Tech Debt
|
||||||
- [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/)
|
- [ ] monitor configuration in `~/.config/monitors.xml` should be sym linked to `/run/gdm/.config/monitors.xml` (https://www.reddit.com/r/NixOS/comments/u09cz9/home_manager_create_my_own_symlinks_automatically/)
|
||||||
- [ ] migrate away from flakes and move to npins
|
- [ ] migrate away from flakes and move to npins
|
||||||
|
|
@ -72,8 +76,6 @@ nix multi user, multi system, configuration with `sops` secret management, `home
|
||||||
- [ ] move searx, home-assistant, actual, jellyfin, paperless, and immich to only be accessible via vpn
|
- [ ] move searx, home-assistant, actual, jellyfin, paperless, and immich to only be accessible via vpn
|
||||||
|
|
||||||
## Services
|
## Services
|
||||||
- [ ] crab-hole for ad block
|
|
||||||
- [ ] enable and learn actual for budgeting
|
|
||||||
- [ ] vikunja service for project management
|
- [ ] vikunja service for project management
|
||||||
- [ ] Create Tor guard/relay server
|
- [ ] Create Tor guard/relay server
|
||||||
- [ ] mastodon instance
|
- [ ] mastodon instance
|
||||||
|
|
|
||||||
|
|
@ -342,6 +342,20 @@
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
crab-hole = {
|
||||||
|
enable = true;
|
||||||
|
port = 8085;
|
||||||
|
openFirewall = true;
|
||||||
|
show_doc = true;
|
||||||
|
downstreams = {
|
||||||
|
loopback = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
upstreams.cloudFlare.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
qbittorrent = {
|
qbittorrent = {
|
||||||
enable = true;
|
enable = true;
|
||||||
mediaDir = "/srv/qbittorent";
|
mediaDir = "/srv/qbittorent";
|
||||||
|
|
|
||||||
144
modules/nixos-modules/server/crab-hole/crab-hole.nix
Normal file
144
modules/nixos-modules/server/crab-hole/crab-hole.nix
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
cfg = config.services.crab-hole;
|
||||||
|
in {
|
||||||
|
options.services.crab-hole = {
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
default = 8080;
|
||||||
|
description = "Port for the crab-hole API to listen on.";
|
||||||
|
};
|
||||||
|
|
||||||
|
openFirewall = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether to open the firewall for the crab-hole API port.";
|
||||||
|
};
|
||||||
|
|
||||||
|
listen = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = "0.0.0.0";
|
||||||
|
description = "Address for the crab-hole API to listen on.";
|
||||||
|
};
|
||||||
|
|
||||||
|
show_doc = lib.mkEnableOption "OpenAPI documentation (loads content from third party websites)";
|
||||||
|
|
||||||
|
downstreams = {
|
||||||
|
loopback = {
|
||||||
|
enable = lib.mkEnableOption "loopback downstream DNS server on localhost:53";
|
||||||
|
openFirewall = lib.mkEnableOption "automatic port forwarding for the loopback downstream";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraDownstreams = lib.mkOption {
|
||||||
|
type = lib.types.listOf (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
protocol = lib.mkOption {
|
||||||
|
type = lib.types.enum ["udp" "tcp" "tls" "https" "quic"];
|
||||||
|
description = "Protocol for the downstream server.";
|
||||||
|
};
|
||||||
|
|
||||||
|
listen = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Address to listen on for downstream connections.";
|
||||||
|
};
|
||||||
|
|
||||||
|
port = lib.mkOption {
|
||||||
|
type = lib.types.port;
|
||||||
|
description = "Port to listen on for downstream connections.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = [];
|
||||||
|
description = "List of additional downstream DNS server configurations.";
|
||||||
|
};
|
||||||
|
|
||||||
|
upstreams = {
|
||||||
|
cloudFlare = {
|
||||||
|
enable = lib.mkEnableOption "Cloudflare DNS over TLS upstream servers (1.1.1.1 and 1.0.0.1)";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
extraUpstreams = lib.mkOption {
|
||||||
|
type = lib.types.listOf (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
socket_addr = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Socket address of the upstream DNS server (e.g., \"1.1.1.1:853\" or \"[2606:4700:4700::1111]:853\").";
|
||||||
|
};
|
||||||
|
|
||||||
|
protocol = lib.mkOption {
|
||||||
|
type = lib.types.enum ["udp" "tcp" "tls" "https" "quic"];
|
||||||
|
description = "Protocol to use for upstream DNS queries.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
default = [];
|
||||||
|
description = "List of additional upstream DNS server configurations.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.crab-hole.settings = lib.mkMerge [
|
||||||
|
{
|
||||||
|
api = {
|
||||||
|
port = cfg.port;
|
||||||
|
listen = cfg.listen;
|
||||||
|
show_doc = cfg.show_doc;
|
||||||
|
};
|
||||||
|
downstream = cfg.extraDownstreams;
|
||||||
|
upstream.name_servers = cfg.extraUpstreams;
|
||||||
|
}
|
||||||
|
(lib.mkIf cfg.downstreams.loopback.enable {
|
||||||
|
downstream = [
|
||||||
|
{
|
||||||
|
protocol = "udp";
|
||||||
|
listen = "localhost";
|
||||||
|
port = 53;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
})
|
||||||
|
(lib.mkIf cfg.upstreams.cloudFlare.enable {
|
||||||
|
upstream.name_servers = [
|
||||||
|
{
|
||||||
|
socket_addr = "1.1.1.1:853";
|
||||||
|
protocol = "tls";
|
||||||
|
tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com";
|
||||||
|
trust_nx_responses = false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
socket_addr = "1.0.0.1:853";
|
||||||
|
protocol = "tls";
|
||||||
|
tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com";
|
||||||
|
trust_nx_responses = false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
socket_addr = "[2606:4700:4700::1111]:853";
|
||||||
|
protocol = "tls";
|
||||||
|
tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com";
|
||||||
|
trust_nx_responses = false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
socket_addr = "[2606:4700:4700::1001]:853";
|
||||||
|
protocol = "tls";
|
||||||
|
tls_dns_name = "1dot1dot1dot1.cloudflare-dns.com";
|
||||||
|
trust_nx_responses = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
# Open firewall if requested
|
||||||
|
networking.firewall = lib.mkMerge [
|
||||||
|
(lib.mkIf cfg.openFirewall {
|
||||||
|
allowedTCPPorts = [cfg.port];
|
||||||
|
})
|
||||||
|
(lib.mkIf (cfg.downstreams.loopback.enable && cfg.downstreams.loopback.openFirewall) {
|
||||||
|
allowedUDPPorts = [53];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
6
modules/nixos-modules/server/crab-hole/default.nix
Normal file
6
modules/nixos-modules/server/crab-hole/default.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{...}: {
|
||||||
|
imports = [
|
||||||
|
./crab-hole.nix
|
||||||
|
./impermanence.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
26
modules/nixos-modules/server/crab-hole/impermanence.nix
Normal file
26
modules/nixos-modules/server/crab-hole/impermanence.nix
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
workingDirectory = "/var/lib/private/crab-hole";
|
||||||
|
in {
|
||||||
|
config = lib.mkIf (config.services.immich.enable && config.host.impermanence.enable) {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion =
|
||||||
|
config.systemd.services.crab-hole.serviceConfig.WorkingDirectory == (builtins.replaceStrings ["/private"] [""] workingDirectory);
|
||||||
|
message = "crab-hole working directory does not match persistence";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
environment.persistence."/persist/system/root" = {
|
||||||
|
directories = [
|
||||||
|
{
|
||||||
|
directory = workingDirectory;
|
||||||
|
user = "crab-hole";
|
||||||
|
group = "crab-hole";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
./actual
|
./actual
|
||||||
./bazarr
|
./bazarr
|
||||||
|
./crab-hole
|
||||||
./flaresolverr
|
./flaresolverr
|
||||||
./forgejo
|
./forgejo
|
||||||
./home-assistant
|
./home-assistant
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
sonarr = 2015;
|
sonarr = 2015;
|
||||||
bazarr = 2016;
|
bazarr = 2016;
|
||||||
lidarr = 2017;
|
lidarr = 2017;
|
||||||
|
crab-hole = 2018;
|
||||||
};
|
};
|
||||||
|
|
||||||
gids = {
|
gids = {
|
||||||
|
|
@ -52,6 +53,7 @@
|
||||||
sonarr = 2015;
|
sonarr = 2015;
|
||||||
bazarr = 2016;
|
bazarr = 2016;
|
||||||
lidarr = 2017;
|
lidarr = 2017;
|
||||||
|
crab-hole = 2018;
|
||||||
};
|
};
|
||||||
|
|
||||||
users = config.users.users;
|
users = config.users.users;
|
||||||
|
|
@ -229,6 +231,12 @@ in {
|
||||||
isSystemUser = true;
|
isSystemUser = true;
|
||||||
group = config.users.users.lidarr.name;
|
group = config.users.users.lidarr.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
crab-hole = {
|
||||||
|
uid = lib.mkForce uids.crab-hole;
|
||||||
|
isSystemUser = true;
|
||||||
|
group = config.users.users.crab-hole.name;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
groups = {
|
groups = {
|
||||||
|
|
@ -381,6 +389,13 @@ in {
|
||||||
users.lidarr.name
|
users.lidarr.name
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
crab-hole = {
|
||||||
|
gid = lib.mkForce gids.crab-hole;
|
||||||
|
members = [
|
||||||
|
users.crab-hole.name
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue