nix-config/modules/nixos-modules/server/crab-hole/crab-hole.nix

144 lines
4.1 KiB
Nix

{
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];
})
];
};
}