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
				
			
		|  | @ -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