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
				
			
		
							
								
								
									
										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 | ||||
|       ]; | ||||
|     }; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue