pantheon/nix/modules/server/web-servers.nix
Mohammad Rafiq 5f42498a39
feat(nix): add nginx reverse proxy to web-servers module
Adds nginx reverse proxy functionality with SSL support.
2025-07-09 02:59:31 +08:00

142 lines
4.6 KiB
Nix

{ lib, config, ... }:
let
inherit (builtins) listToAttrs map;
inherit (config.flake.lib.options) mkStrOption mkPathOption;
inherit (config.flake.lib.services) mkRootDomain;
inherit (config.flake.paths) secrets;
inherit (config.flake.admin) email;
inherit (lib.types) listOf submodule attrs;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkMerge mkIf;
inherit (lib.lists) singleton;
in
{
flake.modules.nixos.default =
{ 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 {
sops.secrets."keys/cloudflare".sopsFile = secrets + "/keys.yaml";
security.acme = {
acceptTerms = true;
defaults = {
inherit email;
dnsProvider = "cloudflare";
credentialFiles."CLOUDFLARE_DNS_API_TOKEN_FILE" = config.sops.secrets."keys/cloudflare".path;
};
certs = {
"rrv.sh".extraDomainNames = singleton "*.rrv.sh";
"bwfiq.com".extraDomainNames = singleton "*.bwfiq.com";
"slayment.com".extraDomainNames = singleton "*.slayment.com";
"aenyrathia.wiki".extraDomainNames = singleton "*.aenyrathia.wiki";
};
};
})
(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
))
];
};
})
];
};
}