forked from jan-leila/nix-config
		
	feat: created crab-hole service
This commit is contained in:
		
							parent
							
								
									290db94f42
								
							
						
					
					
						commit
						46890110f8
					
				
					 7 changed files with 210 additions and 2 deletions
				
			
		
							
								
								
									
										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 | ||||
|     ./bazarr | ||||
|     ./crab-hole | ||||
|     ./flaresolverr | ||||
|     ./forgejo | ||||
|     ./home-assistant | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ | |||
|     sonarr = 2015; | ||||
|     bazarr = 2016; | ||||
|     lidarr = 2017; | ||||
|     crab-hole = 2018; | ||||
|   }; | ||||
| 
 | ||||
|   gids = { | ||||
|  | @ -52,6 +53,7 @@ | |||
|     sonarr = 2015; | ||||
|     bazarr = 2016; | ||||
|     lidarr = 2017; | ||||
|     crab-hole = 2018; | ||||
|   }; | ||||
| 
 | ||||
|   users = config.users.users; | ||||
|  | @ -229,6 +231,12 @@ in { | |||
|             isSystemUser = true; | ||||
|             group = config.users.users.lidarr.name; | ||||
|           }; | ||||
| 
 | ||||
|           crab-hole = { | ||||
|             uid = lib.mkForce uids.crab-hole; | ||||
|             isSystemUser = true; | ||||
|             group = config.users.users.crab-hole.name; | ||||
|           }; | ||||
|         }; | ||||
| 
 | ||||
|         groups = { | ||||
|  | @ -381,6 +389,13 @@ in { | |||
|               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