refactor(nginx): proxy options

This commit is contained in:
arcnmx 2024-04-18 10:40:35 -07:00
parent c3f3fe1fed
commit 02508ecbd3
18 changed files with 638 additions and 424 deletions

View file

@ -8,11 +8,11 @@
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkBefore mkAfter mkOptionDefault;
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.strings) toLower replaceStrings;
inherit (lib.strings) toLower replaceStrings removePrefix;
inherit (config) networking;
inherit (config.services) vouch-proxy nginx tailscale;
inherit (nginx) vouch;
locationModule = {config, virtualHost, ...}: {
locationModule = {config, virtualHost, xvars, ...}: {
options.vouch = with lib.types; {
requireAuth = mkEnableOption "require auth to access this location";
setProxyHeader = mkOption {
@ -33,20 +33,19 @@
(mkBefore virtualHost.vouch.auth.lua.accessLogic)
];
};
proxied.xvars.enable = mkIf (enableVouchTail || virtualHost.vouch.auth.lua.enable) true;
xvars.enable = mkIf (enableVouchTail || virtualHost.vouch.auth.lua.enable) true;
proxy.headers.set.X-Vouch-User = mkOptionDefault "$auth_resp_x_vouch_user";
extraConfig = assert virtualHost.vouch.enable; mkMerge [
(mkIf (!virtualHost.vouch.requireAuth) virtualHost.vouch.auth.requestDirective)
(allowOrigin vouch.url)
(allowOrigin vouch.authUrl)
(mkIf enableVouchLocal (allowOrigin vouch.localUrl))
(mkIf enableVouchTail (allowOrigin "$x_scheme://${vouch.tailDomain}"))
(mkIf config.vouch.setProxyHeader ''
proxy_set_header X-Vouch-User $auth_resp_x_vouch_user;
'')
(mkIf enableVouchLocal (allowOrigin "sso.local.${networking.domain}"))
(mkIf enableVouchTail (allowOrigin "${xvars.get.scheme}://${vouch.tailDomain}"))
];
};
};
hostModule = {config, ...}: let
hostModule = {config, xvars, ...}: let
cfg = config.vouch;
mkHeaderVar = header: toLower (replaceStrings [ "-" ] [ "_" ] header);
mkUpstreamVar = header: "\$upstream_http_${mkHeaderVar header}";
@ -113,7 +112,7 @@
if ngx.ctx.auth_res ~= nil and ngx.ctx.auth_res.status == ngx.HTTP_UNAUTHORIZED then
local vouch_url = ngx.var["vouch_url"] or "${vouch.url}"
local query_args = ngx.encode_args {
url = string.format("%s://%s%s", ngx.var.x_scheme, ngx.var.x_forwarded_host, ngx.var.request_uri),
url = string.format("%s://%s%s", ngx.var.${removePrefix "$" xvars.get.scheme}, ngx.var.${removePrefix "$" xvars.get.host}, ngx.var.request_uri),
["X-Vouch-Token"] = ngx.ctx.auth_res.header["X-Vouch-Token"] or "",
error = ngx.ctx.auth_res.header["X-Vouch-Error"] or "",
-- ["vouch-failcount"] is now a session variable and shouldn't be needed anymore
@ -145,13 +144,13 @@
};
extraConfig = let
localVouchUrl = ''
if ($x_forwarded_host ~ "\.local\.${networking.domain}$") {
if (${xvars.get.host} ~ "\.local\.${networking.domain}$") {
set $vouch_url ${vouch.localUrl};
}
'';
tailVouchUrl = ''
if ($x_forwarded_host ~ "\.tail\.${networking.domain}$") {
set $vouch_url $x_scheme://${vouch.tailDomain};
if (${xvars.get.host} ~ "\.tail\.${networking.domain}$") {
set $vouch_url ${xvars.get.scheme}://${vouch.tailDomain};
}
'';
setVouchUrl = [
@ -170,33 +169,32 @@
mkBefore "auth_request_set \$${authVar} ${mkUpstreamVar header};"
)) cfg.auth.variables
));
proxied.xvars.enable = mkIf cfg.enable true;
xvars.enable = mkIf cfg.enable true;
locations = mkIf cfg.enable {
"/" = mkIf cfg.requireAuth {
vouch.requireAuth = mkAlmostOptionDefault true;
};
${cfg.auth.errorLocation} = mkIf (cfg.auth.errorLocation != null) {
proxied.xvars.enable = true;
xvars.enable = true;
extraConfig = ''
return 302 $vouch_url/login?url=$x_scheme://$x_forwarded_host$request_uri&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
return 302 $vouch_url/login?url=${xvars.get.scheme}://${xvars.get.host}$request_uri&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
'';
};
${cfg.auth.requestLocation} = { config, ... }: {
proxyPass = "${vouch.proxyOrigin}/validate";
proxy.headers.enableRecommended = false;
proxied.rewriteReferer = false;
extraConfig = let
${cfg.auth.requestLocation} = { config, xvars, ... }: {
proxy = {
enable = true;
url = vouch.proxyOrigin;
# nginx-proxied vouch must use X-Forwarded-Host, but vanilla vouch requires Host
vouchProxyHost = if vouch.doubleProxy.enable
host = if vouch.doubleProxy.enable
then (if cfg.localSso.enable then vouch.doubleProxy.localServerName else vouch.doubleProxy.serverName)
else "$x_forwarded_host";
in ''
proxy_set_header Host ${vouchProxyHost};
proxy_set_header X-Forwarded-Host $x_forwarded_host;
proxy_set_header Referer $x_referer;
proxy_set_header X-Forwarded-Proto $x_scheme;
else xvars.get.host;
headers = {
set.Content-Length = "";
rewriteReferer.enable = false;
};
};
extraConfig = ''
proxy_pass_request_body off;
proxy_set_header Content-Length "";
'';
};
};