diff --git a/nix/manifest.nix b/nix/manifest.nix index b21cf84..ef39862 100644 --- a/nix/manifest.nix +++ b/nix/manifest.nix @@ -40,6 +40,19 @@ }; web-servers = { enableSSL = true; + nginx = { + enable = true; + proxies = [ + { + source = "aenyrathia.wiki"; + target = "http://helios:5896"; + } + { + source = "il.bwfiq.com"; + target = "http://helios:2283"; + } + ]; + }; }; databases = { mongodb.enable = true; diff --git a/nix/modules/server/web-servers.nix b/nix/modules/server/web-servers.nix index 9bcbc4e..1967268 100644 --- a/nix/modules/server/web-servers.nix +++ b/nix/modules/server/web-servers.nix @@ -15,10 +15,54 @@ in { config, ... }: let cfg = config.server.web-servers; + sslCheck = good: bad: if cfg.enableSSL then good else bad; in { options.server.web-servers = { enableSSL = mkEnableOption ""; + nginx = { + enable = mkEnableOption "the Nginx server"; + openFirewall = mkEnableOption "" // { + default = true; + }; + enableDefaultSink = mkEnableOption "" // { + default = true; + }; + pages = mkOption { + default = [ ]; + type = listOf (submodule { + options = { + domain = mkStrOption ""; + root = mkPathOption ""; + extraConfig = mkOption { + type = attrs; + default = { }; + }; + locations = mkOption { + type = attrs; + default = { }; + }; + }; + }); + }; + proxies = mkOption { + default = [ ]; + type = listOf (submodule { + options = { + source = mkStrOption ""; + target = mkStrOption ""; + extraConfig = mkOption { + type = attrs; + default = { }; + }; + locations = mkOption { + type = attrs; + default = { }; + }; + }; + }); + }; + }; }; config = mkMerge [ (mkIf cfg.enableSSL { @@ -38,6 +82,61 @@ in }; }; }) + (mkIf cfg.nginx.enable { + networking.firewall.allowedTCPPorts = mkIf cfg.nginx.openFirewall [ + 443 + 80 + ]; + users.users.nginx.extraGroups = singleton "acme"; + services.nginx = { + enable = true; + recommendedProxySettings = true; + recommendedTlsSettings = true; + recommendedOptimisation = true; + recommendedGzipSettings = true; + virtualHosts = mkMerge [ + (mkIf cfg.nginx.enableDefaultSink { + "_" = { + default = true; + rejectSSL = sslCheck true false; + locations."/" = { + return = "444"; + }; + }; + }) + (listToAttrs ( + map (page: { + name = page.domain; + value = { + addSSL = sslCheck true false; + useACMEHost = sslCheck (mkRootDomain page.domain) null; + acmeRoot = null; # needed for DNS validation + locations = { + "/" = { + inherit (page) root; + } // page.extraConfig; + } // page.locations; + }; + }) cfg.nginx.pages + )) + (listToAttrs ( + map (proxy: { + name = proxy.source; + value = { + addSSL = sslCheck true false; + useACMEHost = sslCheck (mkRootDomain proxy.source) null; + acmeRoot = null; # needed for DNS validation + locations = { + "/" = { + proxyPass = proxy.target; + } // proxy.extraConfig; + } // proxy.locations; + }; + }) cfg.nginx.proxies + )) + ]; + }; + }) ]; }; }