144 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			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];
 | |
|       })
 | |
|     ];
 | |
|   };
 | |
| }
 |