refactor(nginx): proxied xvars defaults

This commit is contained in:
arcnmx 2024-06-24 11:40:44 -07:00
parent b5c1b9de84
commit 1d19f0821d
3 changed files with 70 additions and 30 deletions

View file

@ -1,4 +1,5 @@
let let
xInit = true;
xCloudflared = {virtualHost}: let xCloudflared = {virtualHost}: let
host = if virtualHost.proxied.cloudflared.host == virtualHost.serverName host = if virtualHost.proxied.cloudflared.host == virtualHost.serverName
then "$server_name" then "$server_name"
@ -29,6 +30,23 @@ let
${xvars.init "forwarded_server" "$http_x_forwarded_server"} ${xvars.init "forwarded_server" "$http_x_forwarded_server"}
} }
''; '';
xDefaults = {cfg}: let
defaults = {
${toString true} = {
remote_addr = "$proxied_remote_addr_x";
host = "$proxied_host_x";
forwarded_server = "$proxied_forwarded_server_x";
};
"cloudflared" = {
remote_addr = "$proxied_remote_addr_cf";
host = "$proxied_host_cf";
};
};
in {
forwarded_for = "$proxy_add_x_forwarded_for";
scheme = "$proxied_scheme";
https = "$proxied_https";
} // defaults.${cfg.enable};
locationModule = { locationModule = {
config, config,
virtualHost, virtualHost,
@ -37,7 +55,7 @@ let
lib, lib,
... ...
}: let }: let
inherit (gensokyo-zone.lib) mkJustBefore mkAlmostOptionDefault; inherit (gensokyo-zone.lib) mkJustBefore mkAlmostOptionDefault mapAlmostOptionDefaults;
inherit (lib.options) mkOption; inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault; inherit (lib.modules) mkIf mkMerge mkOptionDefault;
cfg = config.proxied; cfg = config.proxied;
@ -75,12 +93,15 @@ let
X-Accel-Buffering = mkOptionDefault true; X-Accel-Buffering = mkOptionDefault true;
}; };
}; };
xvars.enable = mkIf cfg.enabled true; xvars = mkIf cfg.enabled {
enable = mkIf xInit true;
defaults = mkIf (!xInit && cfg.enable != virtualHost.proxied.enable) (mapAlmostOptionDefaults (xDefaults {inherit cfg;}));
};
extraConfig = mkMerge [ extraConfig = mkMerge [
(mkIf (cfg.enable == "cloudflared" && virtualHost.proxied.enable != "cloudflared") ( (mkIf (cfg.enable == "cloudflared" && virtualHost.proxied.enable != "cloudflared") (
mkJustBefore (xCloudflared {inherit virtualHost;}) mkJustBefore (xCloudflared {inherit virtualHost;})
)) ))
(mkIf emitVars ( (mkIf (xInit && emitVars) (
mkJustBefore (xHeadersProxied {inherit xvars;}) mkJustBefore (xHeadersProxied {inherit xvars;})
)) ))
]; ];
@ -94,7 +115,7 @@ let
lib, lib,
... ...
}: let }: let
inherit (gensokyo-zone.lib) mkAlmostOptionDefault orderJustBefore unmerged; inherit (gensokyo-zone.lib) mkAlmostOptionDefault mapAlmostOptionDefaults orderJustBefore unmerged;
inherit (lib.options) mkOption; inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkOrder mkDefault; inherit (lib.modules) mkIf mkMerge mkOrder mkDefault;
inherit (nixosConfig.services) nginx; inherit (nixosConfig.services) nginx;
@ -115,6 +136,10 @@ let
type = str; type = str;
default = config.serverName; default = config.serverName;
}; };
originHost = mkOption {
type = str;
default = config.serverName;
};
ingressSettings = mkOption { ingressSettings = mkOption {
type = unmerged.types.attrs; type = unmerged.types.attrs;
}; };
@ -143,7 +168,7 @@ let
else "http"; else "http";
in in
mkIf (cfg.enable == "cloudflared") { mkIf (cfg.enable == "cloudflared") {
ingressSettings.${config.serverName} = { ingressSettings.${cfg.cloudflared.host} = {
service = "${scheme}://localhost:${toString listen.port}"; service = "${scheme}://localhost:${toString listen.port}";
originRequest = let originRequest = let
noTLSVerify = noTLSVerify =
@ -151,18 +176,21 @@ let
then "noTLSVerify" then "noTLSVerify"
else null; else null;
httpHostHeader = httpHostHeader =
if cfg.cloudflared.host != config.serverName if cfg.cloudflared.host != cfg.cloudflared.originHost
then "httpHostHeader" then "httpHostHeader"
else null; else null;
in { in {
${noTLSVerify} = true; ${noTLSVerify} = true;
${httpHostHeader} = cfg.cloudflared.host; ${httpHostHeader} = cfg.cloudflared.originHost;
}; };
}; };
getIngress = {}: unmerged.mergeAttrs cfg.cloudflared.ingressSettings; getIngress = {}: unmerged.mergeAttrs cfg.cloudflared.ingressSettings;
}; };
}; };
xvars.enable = mkIf cfg.enabled true; xvars = mkIf cfg.enabled {
enable = mkIf xInit true;
defaults = mkIf (!xInit) (mapAlmostOptionDefaults (xDefaults {inherit cfg;}));
};
local.denyGlobal = mkIf listenProxied (mkDefault true); local.denyGlobal = mkIf listenProxied (mkDefault true);
listen' = mkIf listenProxied { listen' = mkIf listenProxied {
proxied = { proxied = {
@ -181,7 +209,7 @@ let
(mkIf (cfg.enable == "cloudflared") ( (mkIf (cfg.enable == "cloudflared") (
mkOrder orderJustBefore (xCloudflared {virtualHost = config;}) mkOrder orderJustBefore (xCloudflared {virtualHost = config;})
)) ))
(mkIf (cfg.enabled && config.xvars.enable) ( (mkIf (xInit && cfg.enabled && config.xvars.enable) (
mkOrder (orderJustBefore + 25) (xHeadersProxied {inherit xvars;}) mkOrder (orderJustBefore + 25) (xHeadersProxied {inherit xvars;})
)) ))
]; ];

View file

@ -374,12 +374,12 @@ let
in { in {
xvars = { xvars = {
parseReferer = mkIf (anyLocations needsReferer) true; parseReferer = mkIf (anyLocations needsReferer) true;
defaults = mkIf (anyLocations (loc: loc.proxy.enabled)) (mkOptionDefault (mapOptionDefaults rec { defaults = mkIf (anyLocations (loc: loc.proxy.enabled)) (mapOptionDefaults rec {
proxy_scheme = null; proxy_scheme = null;
proxy_host = "$proxy_host"; proxy_host = "$proxy_host";
proxy_port = "$proxy_port"; proxy_port = "$proxy_port";
proxy_hostport = "${proxy_host}:${proxy_port}"; proxy_hostport = "${proxy_host}:${proxy_port}";
})); });
}; };
proxy = mkIf (cfg.copyFromVhost != null) confCopy; proxy = mkIf (cfg.copyFromVhost != null) confCopy;
}; };

View file

@ -2,12 +2,20 @@ let
locationModule = { locationModule = {
config, config,
virtualHost, virtualHost,
gensokyo-zone,
lib, lib,
... ...
}: let }: let
inherit (gensokyo-zone.lib) mkJustBefore;
inherit (lib.options) mkEnableOption mkOption; inherit (lib.options) mkEnableOption mkOption;
inherit (lib.attrsets) mapAttrs; inherit (lib.modules) mkIf;
inherit (lib.attrsets) mapAttrs mapAttrsToList filterAttrs;
inherit (lib.strings) concatStringsSep;
cfg = config.xvars; cfg = config.xvars;
defaultValues = filterAttrs (name: value: value != null && value != virtualHost.xvars.defaults.${name} or null) cfg.defaults;
defaults = concatStringsSep "\n" (mapAttrsToList (
name: value: "set $x_${name} ${virtualHost.xvars.lib.escapeString value};"
) defaultValues);
in { in {
options.xvars = with lib.types; { options.xvars = with lib.types; {
enable = mkEnableOption "$x_variables"; enable = mkEnableOption "$x_variables";
@ -34,6 +42,7 @@ let
get = xvars.get // get; get = xvars.get // get;
}; };
}; };
extraConfig = mkIf (cfg.enable && defaultValues != {}) (mkJustBefore defaults);
_module.args.xvars = config.xvars.lib; _module.args.xvars = config.xvars.lib;
}; };
}; };
@ -45,9 +54,9 @@ let
lib, lib,
... ...
}: let }: let
inherit (gensokyo-zone.lib) mkJustBefore; inherit (gensokyo-zone.lib) mkJustBefore mapOptionDefaults;
inherit (lib.options) mkOption mkEnableOption; inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault; inherit (lib.modules) mkIf mkMerge;
inherit (lib.attrsets) attrValues filterAttrs mapAttrs mapAttrsToList; inherit (lib.attrsets) attrValues filterAttrs mapAttrs mapAttrsToList;
inherit (lib.lists) any; inherit (lib.lists) any;
inherit (lib.strings) concatStringsSep hasPrefix hasInfix; inherit (lib.strings) concatStringsSep hasPrefix hasInfix;
@ -73,15 +82,6 @@ let
parseReferer = mkEnableOption "$x_referer_{scheme,host,path}"; parseReferer = mkEnableOption "$x_referer_{scheme,host,path}";
defaults = mkOption { defaults = mkOption {
type = attrsOf (nullOr str); type = attrsOf (nullOr str);
default = rec {
scheme = "$scheme";
forwarded_for = remote_addr;
remote_addr = "$remote_addr";
forwarded_server = host;
host = "$host";
referer = "$http_referer";
https = "$https";
};
}; };
lib = mkOption { lib = mkOption {
type = attrs; type = attrs;
@ -99,9 +99,10 @@ let
}; };
}; };
config = let config = let
defaultValues = filterAttrs (_: value: value != null) cfg.defaults;
defaults = concatStringsSep "\n" (mapAttrsToList ( defaults = concatStringsSep "\n" (mapAttrsToList (
name: value: "set $x_${name} ${escapeString value};" name: value: "set $x_${name} ${escapeString value};"
) (filterAttrs (_: value: value != null) cfg.defaults)); ) defaultValues);
parseReferer = '' parseReferer = ''
set $hack_referer $http_referer; set $hack_referer $http_referer;
if ($hack_referer ~ "^(https?)://([^/]+)(/.*)$") { if ($hack_referer ~ "^(https?)://([^/]+)(/.*)$") {
@ -116,11 +117,22 @@ let
(mkIf (anyLocations (loc: loc.xvars.enable)) true) (mkIf (anyLocations (loc: loc.xvars.enable)) true)
(mkIf cfg.parseReferer true) (mkIf cfg.parseReferer true)
]; ];
defaults = mkIf cfg.parseReferer (mkOptionDefault { defaults = mkMerge [
referer_scheme = null; (mapOptionDefaults rec {
referer_host = null; scheme = "$scheme";
referer_path = null; forwarded_for = remote_addr;
}); remote_addr = "$remote_addr";
forwarded_server = host;
host = "$host";
referer = "$http_referer";
https = "$https";
})
(mkIf cfg.parseReferer (mapOptionDefaults {
referer_scheme = null;
referer_host = null;
referer_path = null;
}))
];
lib = { lib = {
get = mapAttrs (name: default: get = mapAttrs (name: default:
if cfg.enable if cfg.enable
@ -132,7 +144,7 @@ let
}; };
}; };
extraConfig = mkMerge [ extraConfig = mkMerge [
(mkIf cfg.enable (mkJustBefore defaults)) (mkIf (cfg.enable && defaultValues != {}) (mkJustBefore defaults))
(mkIf (cfg.enable && cfg.parseReferer) (mkJustBefore parseReferer)) (mkIf (cfg.enable && cfg.parseReferer) (mkJustBefore parseReferer))
]; ];
_module.args.xvars = config.xvars.lib; _module.args.xvars = config.xvars.lib;