forked from jan-leila/nix-config
		
	feat: refactored reverse proxy to be a normally named module
This commit is contained in:
		
							parent
							
								
									466926b919
								
							
						
					
					
						commit
						4dd285c122
					
				
					 29 changed files with 352 additions and 426 deletions
				
			
		|  | @ -4,17 +4,26 @@ | |||
|   ... | ||||
| }: { | ||||
|   options.services.actual = { | ||||
|     subdomain = lib.mkOption { | ||||
|     domain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       default = "actual"; | ||||
|       description = "subdomain of base domain that actual will be hosted at"; | ||||
|       description = "domain that actual will be hosted at"; | ||||
|       default = "actual.arpa"; | ||||
|     }; | ||||
|     extraDomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       description = "extra domains that should be configured for actual"; | ||||
|       default = []; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.actual.enable && config.host.reverse_proxy.enable) { | ||||
|     host = { | ||||
|       reverse_proxy.subdomains.${config.services.actual.subdomain} = { | ||||
|         target = "http://localhost:${toString config.services.actual.settings.port}"; | ||||
|   config = lib.mkIf (config.services.actual.enable && config.services.reverseProxy.enable) { | ||||
|     services.reverseProxy.services.actual = { | ||||
|       target = "http://localhost:${toString config.services.actual.settings.port}"; | ||||
|       domain = config.services.actual.domain; | ||||
|       extraDomains = config.services.actual.extraDomains; | ||||
| 
 | ||||
|       settings = { | ||||
|         forwardHeaders.enable = true; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./proxy.nix | ||||
|     ./impermanence.nix | ||||
|   ]; | ||||
| } | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: { | ||||
|   options.services.bazarr = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.nullOr lib.types.str; | ||||
|       default = null; | ||||
|       description = "Subdomain for reverse proxy. If null, service will be local only."; | ||||
|     }; | ||||
|     extraSubdomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       default = []; | ||||
|       description = "Extra subdomains for reverse proxy."; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.bazarr.enable && config.services.bazarr.subdomain != null) { | ||||
|     host.reverse_proxy.subdomains.bazarr = { | ||||
|       subdomain = config.services.bazarr.subdomain; | ||||
|       extraSubdomains = config.services.bazarr.extraSubdomains; | ||||
|       target = "http://127.0.0.1:6767"; | ||||
|       websockets.enable = true; | ||||
|       forwardHeaders.enable = true; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
|  | @ -1,6 +1,6 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./reverse_proxy.nix | ||||
|     ./reverseProxy | ||||
|     ./fail2ban.nix | ||||
|     ./postgres.nix | ||||
|     ./network_storage | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./proxy.nix | ||||
|     ./impermanence.nix | ||||
|   ]; | ||||
| } | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: { | ||||
|   options.services.flaresolverr = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.nullOr lib.types.str; | ||||
|       default = null; | ||||
|       description = "Subdomain for reverse proxy. If null, service will be local only."; | ||||
|     }; | ||||
|     extraSubdomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       default = []; | ||||
|       description = "Extra subdomains for reverse proxy."; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.flaresolverr.enable && config.services.flaresolverr.subdomain != null) { | ||||
|     host.reverse_proxy.subdomains.flaresolverr = { | ||||
|       subdomain = config.services.flaresolverr.subdomain; | ||||
|       extraSubdomains = config.services.flaresolverr.extraSubdomains; | ||||
|       target = "http://127.0.0.1:${toString config.services.flaresolverr.port}"; | ||||
|       websockets.enable = true; | ||||
|       forwardHeaders.enable = true; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
|  | @ -31,7 +31,7 @@ in { | |||
|       lfs.enable = true; | ||||
|       settings = { | ||||
|         server = { | ||||
|           DOMAIN = "${config.services.forgejo.subdomain}.${config.host.reverse_proxy.hostname}"; | ||||
|           DOMAIN = config.services.forgejo.reverseProxy.domain; | ||||
|           HTTP_PORT = httpPort; | ||||
|           START_SSH_SERVER = true; | ||||
|           SSH_LISTEN_PORT = sshPort; | ||||
|  |  | |||
|  | @ -7,16 +7,29 @@ | |||
|   httpPort = const.httpPort; | ||||
| in { | ||||
|   options.services.forgejo = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "subdomain of base domain that forgejo will be hosted at"; | ||||
|       default = "forgejo"; | ||||
|     reverseProxy = { | ||||
|       domain = lib.mkOption { | ||||
|         type = lib.types.str; | ||||
|         description = "domain that forgejo will be hosted at"; | ||||
|         default = "git.jan-leila.com"; | ||||
|       }; | ||||
|       extraDomains = lib.mkOption { | ||||
|         type = lib.types.listOf lib.types.str; | ||||
|         description = "extra domains that should be configured for forgejo"; | ||||
|         default = []; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.forgejo.enable && config.host.reverse_proxy.enable) { | ||||
|     host.reverse_proxy.subdomains.${config.services.forgejo.subdomain} = { | ||||
|   config = lib.mkIf (config.services.forgejo.enable && config.services.reverseProxy.enable) { | ||||
|     services.reverseProxy.services.forgejo = { | ||||
|       target = "http://localhost:${toString httpPort}"; | ||||
|       domain = config.services.forgejo.reverseProxy.domain; | ||||
|       extraDomains = config.services.forgejo.reverseProxy.extraDomains; | ||||
| 
 | ||||
|       settings = { | ||||
|         forwardHeaders.enable = true; | ||||
|       }; | ||||
|     }; | ||||
| 
 | ||||
|     networking.firewall.allowedTCPPorts = [ | ||||
|  |  | |||
|  | @ -82,7 +82,7 @@ | |||
|             login_attempts_threshold = 10; | ||||
|           }; | ||||
|           homeassistant = { | ||||
|             external_url = "https://${config.services.home-assistant.subdomain}.${config.host.reverse_proxy.hostname}"; | ||||
|             external_url = "https://${config.services.home-assistant.domain}"; | ||||
|             # internal_url = "http://192.168.1.2:8123"; | ||||
|           }; | ||||
|           recorder.db_url = "postgresql://@/${config.services.home-assistant.configDir}"; | ||||
|  |  | |||
|  | @ -4,29 +4,33 @@ | |||
|   ... | ||||
| }: { | ||||
|   options.services.home-assistant = { | ||||
|     subdomain = lib.mkOption { | ||||
|     domain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "subdomain of base domain that home-assistant will be hosted at"; | ||||
|       default = "home-assistant"; | ||||
|       description = "domain that home-assistant will be hosted at"; | ||||
|       default = "home-assistant.arpa"; | ||||
|     }; | ||||
|     extraDomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       description = "extra domains that should be configured for home-assistant"; | ||||
|       default = []; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.host.reverse_proxy.enable && config.services.home-assistant.enable) { | ||||
|     host = { | ||||
|       reverse_proxy.subdomains.${config.services.home-assistant.subdomain} = { | ||||
|         target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; | ||||
|   config = lib.mkIf (config.services.reverseProxy.enable && config.services.home-assistant.enable) { | ||||
|     services.reverseProxy.services.home-assistant = { | ||||
|       target = "http://localhost:${toString config.services.home-assistant.config.http.server_port}"; | ||||
|       domain = config.services.home-assistant.domain; | ||||
|       extraDomains = config.services.home-assistant.extraDomains; | ||||
| 
 | ||||
|         websockets.enable = true; | ||||
|       settings = { | ||||
|         proxyWebsockets.enable = true; | ||||
|         forwardHeaders.enable = true; | ||||
| 
 | ||||
|         extraConfig = '' | ||||
|           add_header Upgrade $http_upgrade; | ||||
|           add_header Connection \"upgrade\"; | ||||
| 
 | ||||
|           proxy_buffering off; | ||||
| 
 | ||||
|           proxy_read_timeout 90; | ||||
|         ''; | ||||
|         # Custom timeout settings | ||||
|         proxyHeaders = { | ||||
|           enable = true; | ||||
|           timeout = 90; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
|  | @ -4,31 +4,34 @@ | |||
|   ... | ||||
| }: { | ||||
|   options.services.immich = { | ||||
|     subdomain = lib.mkOption { | ||||
|     domain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "subdomain of base domain that immich will be hosted at"; | ||||
|       default = "immich"; | ||||
|       description = "domain that immich will be hosted at"; | ||||
|       default = "immich.arpa"; | ||||
|     }; | ||||
|     extraDomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       description = "extra domains that should be configured for immich"; | ||||
|       default = []; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.immich.enable && config.host.reverse_proxy.enable) { | ||||
|     host = { | ||||
|       reverse_proxy.subdomains.${config.services.immich.subdomain} = { | ||||
|         target = "http://localhost:${toString config.services.immich.port}"; | ||||
|   config = lib.mkIf (config.services.immich.enable && config.services.reverseProxy.enable) { | ||||
|     services.reverseProxy.services.immich = { | ||||
|       target = "http://localhost:${toString config.services.immich.port}"; | ||||
|       domain = config.services.immich.domain; | ||||
|       extraDomains = config.services.immich.extraDomains; | ||||
| 
 | ||||
|         websockets.enable = true; | ||||
|       settings = { | ||||
|         proxyWebsockets.enable = true; | ||||
|         forwardHeaders.enable = true; | ||||
|         maxBodySize = 50000; | ||||
| 
 | ||||
|         extraConfig = '' | ||||
|           # allow large file uploads | ||||
|           client_max_body_size 50000M; | ||||
| 
 | ||||
|           # set timeout | ||||
|           proxy_read_timeout 600s; | ||||
|           proxy_send_timeout 600s; | ||||
|           send_timeout       600s; | ||||
|           proxy_redirect     off; | ||||
|         ''; | ||||
|         # Custom timeout settings | ||||
|         proxyHeaders = { | ||||
|           enable = true; | ||||
|           timeout = 600; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./proxy.nix | ||||
|     ./impermanence.nix | ||||
|   ]; | ||||
| } | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: { | ||||
|   options.services.jackett = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.nullOr lib.types.str; | ||||
|       default = null; | ||||
|       description = "Subdomain for reverse proxy. If null, service will be local only."; | ||||
|     }; | ||||
|     extraSubdomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       default = []; | ||||
|       description = "Extra subdomains for reverse proxy."; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.jackett.enable && config.services.jackett.subdomain != null) { | ||||
|     host.reverse_proxy.subdomains.jackett = { | ||||
|       subdomain = config.services.jackett.subdomain; | ||||
|       extraSubdomains = config.services.jackett.extraSubdomains; | ||||
|       target = "http://127.0.0.1:9117"; | ||||
|       websockets.enable = true; | ||||
|       forwardHeaders.enable = true; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
|  | @ -6,33 +6,30 @@ | |||
|   jellyfinPort = 8096; | ||||
| in { | ||||
|   options.services.jellyfin = { | ||||
|     subdomain = lib.mkOption { | ||||
|     domain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "subdomain of base domain that jellyfin will be hosted at"; | ||||
|       default = "jellyfin"; | ||||
|       description = "domain that jellyfin will be hosted at"; | ||||
|       default = "jellyfin.arpa"; | ||||
|     }; | ||||
|     extraSubdomains = lib.mkOption { | ||||
|     extraDomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       description = "ex subdomain of base domain that jellyfin will be hosted at"; | ||||
|       description = "extra domains that should be configured for jellyfin"; | ||||
|       default = []; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.jellyfin.enable && config.host.reverse_proxy.enable) { | ||||
|     host.reverse_proxy.subdomains.jellyfin = { | ||||
|   config = lib.mkIf (config.services.jellyfin.enable && config.services.reverseProxy.enable) { | ||||
|     services.reverseProxy.services.jellyfin = { | ||||
|       target = "http://localhost:${toString jellyfinPort}"; | ||||
|       domain = config.services.jellyfin.domain; | ||||
|       extraDomains = config.services.jellyfin.extraDomains; | ||||
| 
 | ||||
|       subdomain = config.services.jellyfin.subdomain; | ||||
|       extraSubdomains = config.services.jellyfin.extraSubdomains; | ||||
| 
 | ||||
|       forwardHeaders.enable = true; | ||||
| 
 | ||||
|       extraConfig = '' | ||||
|         client_max_body_size 20M; | ||||
|         add_header X-Content-Type-Options "nosniff"; | ||||
| 
 | ||||
|         proxy_buffering off; | ||||
|       ''; | ||||
|       settings = { | ||||
|         forwardHeaders.enable = true; | ||||
|         maxBodySize = 20; | ||||
|         noSniff.enable = true; | ||||
|         proxyBuffering.enable = false; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./proxy.nix | ||||
|     ./impermanence.nix | ||||
|   ]; | ||||
| } | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: { | ||||
|   options.services.lidarr = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.nullOr lib.types.str; | ||||
|       default = null; | ||||
|       description = "Subdomain for reverse proxy. If null, service will be local only."; | ||||
|     }; | ||||
|     extraSubdomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       default = []; | ||||
|       description = "Extra subdomains for reverse proxy."; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.lidarr.enable && config.services.lidarr.subdomain != null) { | ||||
|     host.reverse_proxy.subdomains.lidarr = { | ||||
|       subdomain = config.services.lidarr.subdomain; | ||||
|       extraSubdomains = config.services.lidarr.extraSubdomains; | ||||
|       target = "http://127.0.0.1:8686"; | ||||
|       websockets.enable = true; | ||||
|       forwardHeaders.enable = true; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
|  | @ -4,31 +4,29 @@ | |||
|   ... | ||||
| }: { | ||||
|   options.services.panoramax = { | ||||
|     subdomain = lib.mkOption { | ||||
|     domain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "subdomain of base domain that panoramax will be hosted at"; | ||||
|       default = "panoramax"; | ||||
|       description = "domain that panoramax will be hosted at"; | ||||
|       default = "panoramax.arpa"; | ||||
|     }; | ||||
|     extraDomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       description = "extra domains that should be configured for panoramax"; | ||||
|       default = []; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.panoramax.enable && config.host.reverse_proxy.enable) { | ||||
|     host = { | ||||
|       reverse_proxy.subdomains.${config.services.panoramax.subdomain} = { | ||||
|         target = "http://localhost:${toString config.services.panoramax.port}"; | ||||
|   config = lib.mkIf (config.services.panoramax.enable && config.services.reverseProxy.enable) { | ||||
|     services.reverseProxy.services.panoramax = { | ||||
|       target = "http://localhost:${toString config.services.panoramax.port}"; | ||||
|       domain = config.services.panoramax.domain; | ||||
|       extraDomains = config.services.panoramax.extraDomains; | ||||
| 
 | ||||
|         websockets.enable = true; | ||||
|       settings = { | ||||
|         proxyWebsockets.enable = true; | ||||
|         forwardHeaders.enable = true; | ||||
| 
 | ||||
|         extraConfig = '' | ||||
|           # allow large file uploads for panoramic images | ||||
|           client_max_body_size 100M; | ||||
| 
 | ||||
|           # set timeout for image processing | ||||
|           proxy_read_timeout 300s; | ||||
|           proxy_send_timeout 300s; | ||||
|           send_timeout       300s; | ||||
|           proxy_redirect     off; | ||||
|         ''; | ||||
|         maxBodySize = 100000; | ||||
|         timeout = 300; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ | |||
| 
 | ||||
|   config = lib.mkIf config.services.paperless.enable { | ||||
|     services.paperless = { | ||||
|       domain = "${config.services.paperless.subdomain}.${config.host.reverse_proxy.hostname}"; | ||||
|       configureTika = true; | ||||
|       settings = { | ||||
|         PAPERLESS_DBENGINE = "postgresql"; | ||||
|  |  | |||
|  | @ -4,25 +4,30 @@ | |||
|   ... | ||||
| }: { | ||||
|   options.services.paperless = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "subdomain of base domain that paperless will be hosted at"; | ||||
|       default = "paperless"; | ||||
|     reverseProxy = { | ||||
|       domain = lib.mkOption { | ||||
|         type = lib.types.str; | ||||
|         description = "domain that paperless will be hosted at"; | ||||
|         default = "paperless.arpa"; | ||||
|       }; | ||||
|       extraDomains = lib.mkOption { | ||||
|         type = lib.types.listOf lib.types.str; | ||||
|         description = "extra domains that should be configured for paperless"; | ||||
|         default = []; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.paperless.enable && config.host.reverse_proxy.enable) { | ||||
|     host = { | ||||
|       reverse_proxy.subdomains.${config.services.paperless.subdomain} = { | ||||
|         target = "http://${config.services.paperless.address}:${toString config.services.paperless.port}"; | ||||
|   config = lib.mkIf (config.services.paperless.enable && config.services.reverseProxy.enable) { | ||||
|     services.reverseProxy.services.paperless = { | ||||
|       target = "http://${config.services.paperless.address}:${toString config.services.paperless.port}"; | ||||
|       domain = config.services.paperless.reverseProxy.domain; | ||||
|       extraDomains = config.services.paperless.reverseProxy.extraDomains; | ||||
| 
 | ||||
|         websockets.enable = true; | ||||
|       settings = { | ||||
|         proxyWebsockets.enable = true; | ||||
|         forwardHeaders.enable = true; | ||||
| 
 | ||||
|         extraConfig = '' | ||||
|           # allow large file uploads | ||||
|           client_max_body_size 50000M; | ||||
|         ''; | ||||
|         maxBodySize = 50000; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./proxy.nix | ||||
|     ./impermanence.nix | ||||
|   ]; | ||||
| } | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: { | ||||
|   options.services.radarr = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.nullOr lib.types.str; | ||||
|       default = null; | ||||
|       description = "Subdomain for reverse proxy. If null, service will be local only."; | ||||
|     }; | ||||
|     extraSubdomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       default = []; | ||||
|       description = "Extra subdomains for reverse proxy."; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.radarr.enable && config.services.radarr.subdomain != null) { | ||||
|     host.reverse_proxy.subdomains.radarr = { | ||||
|       subdomain = config.services.radarr.subdomain; | ||||
|       extraSubdomains = config.services.radarr.extraSubdomains; | ||||
|       target = "http://127.0.0.1:7878"; | ||||
|       websockets.enable = true; | ||||
|       forwardHeaders.enable = true; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										6
									
								
								modules/nixos-modules/server/reverseProxy/default.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/nixos-modules/server/reverseProxy/default.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./reverseProxy.nix | ||||
|     ./impermanence.nix | ||||
|   ]; | ||||
| } | ||||
							
								
								
									
										21
									
								
								modules/nixos-modules/server/reverseProxy/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								modules/nixos-modules/server/reverseProxy/impermanence.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: let | ||||
|   dataDir = "/var/lib/acme"; | ||||
| in { | ||||
|   config = lib.mkIf (config.host.impermanence.enable && config.services.reverseProxy.enable) { | ||||
|     environment.persistence."/persist/system/root" = { | ||||
|       enable = true; | ||||
|       hideMounts = true; | ||||
|       directories = [ | ||||
|         { | ||||
|           directory = dataDir; | ||||
|           user = "acme"; | ||||
|           group = "acme"; | ||||
|         } | ||||
|       ]; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
							
								
								
									
										158
									
								
								modules/nixos-modules/server/reverseProxy/reverseProxy.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								modules/nixos-modules/server/reverseProxy/reverseProxy.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,158 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: { | ||||
|   options.services.reverseProxy = { | ||||
|     enable = lib.mkEnableOption "turn on the reverse proxy"; | ||||
|     openFirewall = lib.mkEnableOption "open the firewall"; | ||||
|     ports = { | ||||
|       http = lib.mkOption { | ||||
|         type = lib.types.port; | ||||
|         description = "HTTP port for the reverse proxy"; | ||||
|         default = 80; | ||||
|       }; | ||||
|       https = lib.mkOption { | ||||
|         type = lib.types.port; | ||||
|         description = "HTTPS port for the reverse proxy"; | ||||
|         default = 443; | ||||
|       }; | ||||
|     }; | ||||
|     acme = { | ||||
|       enable = lib.mkOption { | ||||
|         type = lib.types.bool; | ||||
|         description = "enable ACME certificate management"; | ||||
|         default = true; | ||||
|       }; | ||||
|       email = lib.mkOption { | ||||
|         type = lib.types.str; | ||||
|         description = "email address for ACME certificate registration"; | ||||
|       }; | ||||
|     }; | ||||
|     services = lib.mkOption { | ||||
|       type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { | ||||
|         options = { | ||||
|           target = lib.mkOption { | ||||
|             type = lib.types.str; | ||||
|             description = "what url will all traffic to this application be forwarded to"; | ||||
|           }; | ||||
|           domain = lib.mkOption { | ||||
|             type = lib.types.str; | ||||
|             description = "what is the default subdomain to be used for this application to be used for"; | ||||
|             default = name; | ||||
|           }; | ||||
|           extraDomains = lib.mkOption { | ||||
|             type = lib.types.listOf lib.types.str; | ||||
|             description = "extra domains that should be configured for this domain"; | ||||
|             default = []; | ||||
|           }; | ||||
|           settings = { | ||||
|             certificateRenewal.enable = lib.mkOption { | ||||
|               type = lib.types.bool; | ||||
|               description = "auto renew certificates"; | ||||
|               default = true; | ||||
|             }; | ||||
|             forceSSL.enable = lib.mkOption { | ||||
|               type = lib.types.bool; | ||||
|               description = "auto renew certificates"; | ||||
|               default = true; | ||||
|             }; | ||||
|             proxyHeaders = { | ||||
|               enable = lib.mkEnableOption "should we proxy headers"; | ||||
|               timeout = lib.mkOption { | ||||
|                 type = lib.types.int; | ||||
|                 default = 60; | ||||
|               }; | ||||
|             }; | ||||
|             proxyWebsockets.enable = lib.mkEnableOption "should the default config proxy websockets"; | ||||
|             forwardHeaders.enable = lib.mkEnableOption "should the default config contain forward headers"; | ||||
|             noSniff.enable = lib.mkEnableOption "should the no sniff flags be set"; | ||||
|             proxyBuffering.enable = lib.mkOption { | ||||
|               type = lib.types.bool; | ||||
|               description = "should proxy buffering be enabled"; | ||||
|               default = true; | ||||
|             }; | ||||
|             maxBodySize = lib.mkOption { | ||||
|               type = lib.types.nullOr lib.types.int; | ||||
|               description = ""; | ||||
|               default = null; | ||||
|             }; | ||||
|           }; | ||||
|         }; | ||||
|       })); | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = let | ||||
|     httpPort = config.services.reverseProxy.ports.http; | ||||
|     httpsPort = config.services.reverseProxy.ports.https; | ||||
|   in | ||||
|     lib.mkIf config.services.reverseProxy.enable { | ||||
|       security.acme = lib.mkIf config.services.reverseProxy.acme.enable { | ||||
|         acceptTerms = true; | ||||
|         defaults.email = config.services.reverseProxy.acme.email; | ||||
|       }; | ||||
| 
 | ||||
|       services.nginx = { | ||||
|         enable = true; | ||||
|         virtualHosts = lib.mkMerge ( | ||||
|           lib.lists.flatten ( | ||||
|             lib.attrsets.mapAttrsToList ( | ||||
|               name: service: let | ||||
|                 hostConfig = { | ||||
|                   forceSSL = service.settings.forceSSL.enable; | ||||
|                   enableACME = service.settings.certificateRenewal.enable; | ||||
|                   locations = { | ||||
|                     "/" = { | ||||
|                       proxyPass = service.target; | ||||
|                       proxyWebsockets = service.settings.proxyWebsockets.enable; | ||||
|                       recommendedProxySettings = service.settings.forwardHeaders.enable; | ||||
|                       extraConfig = let | ||||
|                         # Client upload size configuration | ||||
|                         maxBodySizeConfig = | ||||
|                           lib.optionalString (service.settings.maxBodySize != null) | ||||
|                           "client_max_body_size ${toString service.settings.maxBodySize}M;"; | ||||
| 
 | ||||
|                         # Security header configuration | ||||
|                         noSniffConfig = | ||||
|                           lib.optionalString service.settings.noSniff.enable | ||||
|                           "add_header X-Content-Type-Options nosniff;"; | ||||
| 
 | ||||
|                         # Proxy buffering configuration | ||||
|                         proxyBufferingConfig = | ||||
|                           lib.optionalString (!service.settings.proxyBuffering.enable) | ||||
|                           "proxy_buffering off;"; | ||||
| 
 | ||||
|                         # Proxy timeout configuration | ||||
|                         proxyTimeoutConfig = | ||||
|                           lib.optionalString service.settings.proxyHeaders.enable | ||||
|                           '' | ||||
|                             proxy_read_timeout ${toString service.settings.proxyHeaders.timeout}s; | ||||
|                             proxy_connect_timeout ${toString service.settings.proxyHeaders.timeout}s; | ||||
|                             proxy_send_timeout ${toString service.settings.proxyHeaders.timeout}s; | ||||
|                           ''; | ||||
|                       in | ||||
|                         maxBodySizeConfig + noSniffConfig + proxyBufferingConfig + proxyTimeoutConfig; | ||||
|                     }; | ||||
|                   }; | ||||
|                 }; | ||||
|               in ( | ||||
|                 [ | ||||
|                   { | ||||
|                     ${service.domain} = hostConfig; | ||||
|                   } | ||||
|                 ] | ||||
|                 ++ builtins.map (domain: {${domain} = hostConfig;}) | ||||
|                 service.extraDomains | ||||
|               ) | ||||
|             ) | ||||
|             config.services.reverseProxy.services | ||||
|           ) | ||||
|         ); | ||||
|       }; | ||||
|       networking.firewall.allowedTCPPorts = lib.mkIf config.services.reverseProxy.openFirewall [ | ||||
|         httpPort | ||||
|         httpsPort | ||||
|       ]; | ||||
|     }; | ||||
| } | ||||
|  | @ -1,128 +0,0 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: let | ||||
|   dataDir = "/var/lib/acme"; | ||||
|   httpPort = 80; | ||||
|   httpsPort = 443; | ||||
| in { | ||||
|   options.host.reverse_proxy = { | ||||
|     enable = lib.mkEnableOption "turn on the reverse proxy"; | ||||
|     hostname = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "what host name are we going to be proxying from"; | ||||
|     }; | ||||
|     forceSSL = lib.mkOption { | ||||
|       type = lib.types.bool; | ||||
|       description = "force connections to use https"; | ||||
|       default = config.host.reverse_proxy.enableACME; | ||||
|     }; | ||||
|     enableACME = lib.mkOption { | ||||
|       type = lib.types.bool; | ||||
|       description = "auto renew certificates"; | ||||
|       default = true; | ||||
|     }; | ||||
|     subdomains = lib.mkOption { | ||||
|       type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { | ||||
|         options = { | ||||
|           subdomain = lib.mkOption { | ||||
|             type = lib.types.str; | ||||
|             description = "what is the default subdomain to be used for this application to be used for"; | ||||
|             default = name; | ||||
|           }; | ||||
|           extraSubdomains = lib.mkOption { | ||||
|             type = lib.types.listOf lib.types.str; | ||||
|             description = "extra domains that should be configured for this domain"; | ||||
|             default = []; | ||||
|           }; | ||||
| 
 | ||||
|           target = lib.mkOption { | ||||
|             type = lib.types.str; | ||||
|             description = "what url will all traffic to this application be forwarded to"; | ||||
|           }; | ||||
| 
 | ||||
|           websockets.enable = lib.mkEnableOption "should the default config proxy websockets"; | ||||
| 
 | ||||
|           forwardHeaders.enable = lib.mkEnableOption "should the default config contain forward headers"; | ||||
| 
 | ||||
|           extraConfig = lib.mkOption { | ||||
|             type = lib.types.lines; | ||||
|             default = ""; | ||||
|             description = '' | ||||
|               These lines go to the end of the upstream verbatim. | ||||
|             ''; | ||||
|           }; | ||||
|         }; | ||||
|       })); | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf config.host.reverse_proxy.enable (lib.mkMerge [ | ||||
|     { | ||||
|       security.acme = lib.mkIf config.host.reverse_proxy.enableACME { | ||||
|         acceptTerms = true; | ||||
|         defaults.email = "jan-leila@protonmail.com"; | ||||
|       }; | ||||
| 
 | ||||
|       services.nginx = { | ||||
|         enable = true; | ||||
|         virtualHosts = lib.mkMerge ( | ||||
|           lib.lists.flatten ( | ||||
|             lib.attrsets.mapAttrsToList ( | ||||
|               name: value: let | ||||
|                 hostConfig = { | ||||
|                   forceSSL = config.host.reverse_proxy.forceSSL; | ||||
|                   enableACME = config.host.reverse_proxy.enableACME; | ||||
|                   locations = { | ||||
|                     "/" = { | ||||
|                       proxyPass = value.target; | ||||
|                       proxyWebsockets = value.websockets.enable; | ||||
|                       recommendedProxySettings = value.forwardHeaders.enable; | ||||
|                       extraConfig = | ||||
|                         value.extraConfig; | ||||
|                     }; | ||||
|                   }; | ||||
|                 }; | ||||
|               in ( | ||||
|                 [ | ||||
|                   { | ||||
|                     ${"${value.subdomain}.${config.host.reverse_proxy.hostname}"} = hostConfig; | ||||
|                   } | ||||
|                 ] | ||||
|                 ++ builtins.map (subdomain: {${"${subdomain}.${config.host.reverse_proxy.hostname}"} = hostConfig;}) | ||||
|                 value.extraSubdomains | ||||
|               ) | ||||
|             ) | ||||
|             config.host.reverse_proxy.subdomains | ||||
|           ) | ||||
|         ); | ||||
|       }; | ||||
| 
 | ||||
|       networking.firewall.allowedTCPPorts = [ | ||||
|         httpPort | ||||
|         httpsPort | ||||
|       ]; | ||||
|     } | ||||
|     (lib.mkIf config.host.impermanence.enable { | ||||
|       # TODO: figure out how to write an assertion for this | ||||
|       # assertions = [ | ||||
|       #   { | ||||
|       #     assertion = security.acme.certs.<name>.directory == dataDir; | ||||
|       #     message = "postgres data directory does not match persistence"; | ||||
|       #   } | ||||
|       # ]; | ||||
|       environment.persistence."/persist/system/root" = { | ||||
|         enable = true; | ||||
|         hideMounts = true; | ||||
|         directories = [ | ||||
|           { | ||||
|             directory = dataDir; | ||||
|             user = "acme"; | ||||
|             group = "acme"; | ||||
|           } | ||||
|         ]; | ||||
|       }; | ||||
|     }) | ||||
|   ]); | ||||
| } | ||||
|  | @ -4,18 +4,28 @@ | |||
|   ... | ||||
| }: { | ||||
|   options.services.searx = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.str; | ||||
|       description = "subdomain of base domain that searx will be hosted at"; | ||||
|       default = "searx"; | ||||
|     reverseProxy = { | ||||
|       domain = lib.mkOption { | ||||
|         type = lib.types.str; | ||||
|         description = "domain that searx will be hosted at"; | ||||
|         default = "searx.arpa"; | ||||
|       }; | ||||
|       extraDomains = lib.mkOption { | ||||
|         type = lib.types.listOf lib.types.str; | ||||
|         description = "extra domains that should be configured for searx"; | ||||
|         default = []; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.searx.enable && config.host.reverse_proxy.enable) { | ||||
|     host = { | ||||
|       reverse_proxy.subdomains.searx = { | ||||
|         subdomain = config.services.searx.subdomain; | ||||
|         target = "http://localhost:${toString config.services.searx.settings.server.port}"; | ||||
|   config = lib.mkIf (config.services.searx.enable && config.services.reverseProxy.enable) { | ||||
|     services.reverseProxy.services.searx = { | ||||
|       target = "http://localhost:${toString config.services.searx.settings.server.port}"; | ||||
|       domain = config.services.searx.reverseProxy.domain; | ||||
|       extraDomains = config.services.searx.reverseProxy.extraDomains; | ||||
| 
 | ||||
|       settings = { | ||||
|         forwardHeaders.enable = true; | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|  |  | |||
|  | @ -1,6 +1,5 @@ | |||
| {...}: { | ||||
|   imports = [ | ||||
|     ./proxy.nix | ||||
|     ./impermanence.nix | ||||
|   ]; | ||||
| } | ||||
|  |  | |||
|  | @ -1,28 +0,0 @@ | |||
| { | ||||
|   lib, | ||||
|   config, | ||||
|   ... | ||||
| }: { | ||||
|   options.services.sonarr = { | ||||
|     subdomain = lib.mkOption { | ||||
|       type = lib.types.nullOr lib.types.str; | ||||
|       default = null; | ||||
|       description = "Subdomain for reverse proxy. If null, service will be local only."; | ||||
|     }; | ||||
|     extraSubdomains = lib.mkOption { | ||||
|       type = lib.types.listOf lib.types.str; | ||||
|       default = []; | ||||
|       description = "Extra subdomains for reverse proxy."; | ||||
|     }; | ||||
|   }; | ||||
| 
 | ||||
|   config = lib.mkIf (config.services.sonarr.enable && config.services.sonarr.subdomain != null) { | ||||
|     host.reverse_proxy.subdomains.sonarr = { | ||||
|       subdomain = config.services.sonarr.subdomain; | ||||
|       extraSubdomains = config.services.sonarr.extraSubdomains; | ||||
|       target = "http://127.0.0.1:8989"; | ||||
|       websockets.enable = true; | ||||
|       forwardHeaders.enable = true; | ||||
|     }; | ||||
|   }; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue