mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 20:39:18 -08:00
refactor(nginx): headers and proxy vars
This commit is contained in:
parent
692d3aacbd
commit
418caefe64
6 changed files with 154 additions and 37 deletions
76
modules/nixos/nginx/headers.nix
Normal file
76
modules/nixos/nginx/headers.nix
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
let
|
||||
locationModule = { config, virtualHost, xvars, gensokyo-zone, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mapOptionDefaults;
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkAfter mkOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.lists) isList;
|
||||
cfg = config.headers;
|
||||
in {
|
||||
options.headers = with lib.types; {
|
||||
inheritServerDefaults = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
set = mkOption {
|
||||
type = attrsOf (nullOr (oneOf [ str (listOf str) ]));
|
||||
};
|
||||
};
|
||||
config = let
|
||||
mkHeader = name: value:
|
||||
if isList value then mkMerge (map (mkHeader name) value)
|
||||
else mkAfter "add_header ${name} ${xvars.escapeString value};";
|
||||
setHeaders = mapAttrsToList (name: value: mkIf (value != null) (mkHeader name value)) cfg.set;
|
||||
in {
|
||||
headers = {
|
||||
set = mkMerge [
|
||||
(mkOptionDefault { })
|
||||
(mkIf cfg.inheritServerDefaults (mapOptionDefaults virtualHost.headers.set))
|
||||
];
|
||||
};
|
||||
extraConfig = mkMerge setHeaders;
|
||||
};
|
||||
};
|
||||
hostModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mapOptionDefaults;
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (nixosConfig.services) nginx;
|
||||
in {
|
||||
options = with lib.types; {
|
||||
headers = {
|
||||
set = mkOption {
|
||||
type = attrsOf (nullOr (oneOf [ str (listOf str) ]));
|
||||
};
|
||||
};
|
||||
locations = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [ locationModule ];
|
||||
shorthandOnlyDefinesConfig = true;
|
||||
});
|
||||
};
|
||||
};
|
||||
config = {
|
||||
headers = {
|
||||
set = mapOptionDefaults nginx.headers.set;
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (lib.options) mkOption;
|
||||
in {
|
||||
options.services.nginx = with lib.types; {
|
||||
headers = {
|
||||
set = mkOption {
|
||||
type = attrsOf (nullOr (oneOf [ str (listOf str) ]));
|
||||
default = {
|
||||
};
|
||||
};
|
||||
};
|
||||
virtualHosts = mkOption {
|
||||
type = attrsOf (submodule [hostModule]);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -68,6 +68,10 @@ let
|
|||
set = mkOption {
|
||||
type = attrsOf (nullOr str);
|
||||
};
|
||||
hide = mkOption {
|
||||
type = attrsOf bool;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
redirect = {
|
||||
enable = mkEnableOption "proxy_redirect";
|
||||
|
|
@ -103,12 +107,12 @@ let
|
|||
https = 443;
|
||||
}.${cfg.parsed.scheme} or (throw "unsupported proxy_scheme ${toString cfg.parsed.scheme}");
|
||||
port = coalesce [ cfg.parsed.port schemePort ];
|
||||
hostport = cfg.parsed.host + optionalString (port != schemePort) ":${toString cfg.parsed.port}";
|
||||
hostport = cfg.parsed.host + optionalString (port != schemePort) ":${toString port}";
|
||||
initProxyVars = let
|
||||
initScheme = xvars.init "proxy_scheme" cfg.parsed.scheme;
|
||||
initHost = xvars.init "proxy_host" cfg.parsed.host;
|
||||
initPort = xvars.init "proxy_port" port;
|
||||
initHostPort = xvars.init "proxy_hostport" hostport;
|
||||
initScheme = xvars.init "proxy_scheme" config.xvars.defaults.proxy_scheme;
|
||||
initHost = xvars.init "proxy_host" config.xvars.defaults.proxy_host;
|
||||
initPort = xvars.init "proxy_port" config.xvars.defaults.proxy_port;
|
||||
initHostPort = xvars.init "proxy_hostport" config.xvars.defaults.proxy_hostport;
|
||||
initUpstream = ''
|
||||
${initScheme}
|
||||
${initHost}
|
||||
|
|
@ -153,8 +157,17 @@ let
|
|||
setHeaders = concatStringsSep "\n" (mapAttrsToList (
|
||||
name: value: "proxy_set_header ${name} ${xvars.escapeString value};"
|
||||
) setHeaders');
|
||||
hideHeaders = mapAttrsToList (header: hide: mkIf hide "proxy_hide_header ${xvars.escapeString header};") cfg.headers.hide;
|
||||
in {
|
||||
xvars.enable = mkIf (cfg.headers.rewriteReferer.enable || (cfg.enable && cfg.upstream != null)) true;
|
||||
xvars = {
|
||||
enable = mkIf cfg.headers.rewriteReferer.enable true;
|
||||
defaults = mkIf cfg.enabled (mapOptionDefaults {
|
||||
proxy_scheme = cfg.parsed.scheme;
|
||||
proxy_host = cfg.parsed.host;
|
||||
proxy_port = toString port;
|
||||
proxy_hostport = hostport;
|
||||
});
|
||||
};
|
||||
proxy = {
|
||||
enabled = mkOptionDefault (config.proxyPass != null);
|
||||
path = mkIf (hasPrefix "/" name) (mkOptionDefault name);
|
||||
|
|
@ -207,8 +220,8 @@ let
|
|||
};
|
||||
proxyPass = mkIf cfg.enable (mkAlmostOptionDefault (removeSuffix "/" cfg.url + cfg.path));
|
||||
recommendedProxySettings = mkAlmostOptionDefault (cfg.headers.enableRecommended == "nixpkgs");
|
||||
extraConfig = mkIf cfg.enabled (mkMerge [
|
||||
(mkIf (virtualHost.xvars.enable) (mkJustBefore initProxyVars))
|
||||
extraConfig = mkIf cfg.enabled (mkMerge ([
|
||||
(mkIf virtualHost.xvars.enable (mkJustBefore initProxyVars))
|
||||
(mkIf (cfg.headers.rewriteReferer.enable) (mkJustBefore rewriteReferer))
|
||||
(mkIf (cfg.redirect.enable) (mkBefore redirect))
|
||||
(mkIf (emitHeaders) (mkJustAfter setHeaders))
|
||||
|
|
@ -216,17 +229,18 @@ let
|
|||
(mkIf (cfg.ssl.enabled && cfg.ssl.host != null) "proxy_ssl_name ${cfg.ssl.host};")
|
||||
(mkIf (cfg.ssl.enabled && cfg.ssl.verify) "proxy_ssl_verify on;")
|
||||
(mkIf cfg.websocket.enable "proxy_cache_bypass $http_upgrade;")
|
||||
]);
|
||||
] ++ hideHeaders));
|
||||
};
|
||||
};
|
||||
hostModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mapAlmostOptionDefaults;
|
||||
inherit (gensokyo-zone.lib) mapOptionDefaults mapAlmostOptionDefaults;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge;
|
||||
inherit (lib.modules) mkIf mkOptionDefault;
|
||||
inherit (lib.attrsets) attrValues;
|
||||
inherit (lib.lists) any;
|
||||
inherit (nixosConfig.services) nginx;
|
||||
cfg = config.proxy;
|
||||
anyLocations = f: any (loc: loc.enable && f loc) (attrValues config.locations);
|
||||
in {
|
||||
options = with lib.types; {
|
||||
proxy = {
|
||||
|
|
@ -270,7 +284,15 @@ let
|
|||
};
|
||||
};
|
||||
in {
|
||||
xvars.parseReferer = mkIf (any needsReferer (attrValues config.locations)) true;
|
||||
xvars = {
|
||||
parseReferer = mkIf (anyLocations needsReferer) true;
|
||||
defaults = mkIf (anyLocations (loc: loc.proxy.enabled)) (mkOptionDefault (mapOptionDefaults rec {
|
||||
proxy_scheme = null;
|
||||
proxy_host = "$proxy_host";
|
||||
proxy_port = "$proxy_port";
|
||||
proxy_hostport = "${proxy_host}:${proxy_port}";
|
||||
}));
|
||||
};
|
||||
proxy = mkIf (cfg.copyFromVhost != null) confCopy;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,24 +1,48 @@
|
|||
let
|
||||
locationModule = { config, virtualHost, lib, ... }: let
|
||||
inherit (lib.options) mkEnableOption;
|
||||
inherit (lib.options) mkEnableOption mkOption;
|
||||
inherit (lib.attrsets) mapAttrs;
|
||||
cfg = config.xvars;
|
||||
in {
|
||||
options.xvars = with lib.types; {
|
||||
enable = mkEnableOption "$x_variables";
|
||||
defaults = mkOption {
|
||||
type = attrsOf (nullOr str);
|
||||
default = { };
|
||||
};
|
||||
lib = mkOption {
|
||||
type = attrs;
|
||||
};
|
||||
};
|
||||
config = let
|
||||
in {
|
||||
config = {
|
||||
xvars = {
|
||||
lib = let
|
||||
xvars = virtualHost.xvars.lib;
|
||||
get = mapAttrs (name: default: if virtualHost.xvars.enable then "$x_${name}" else assert default != null; default) cfg.defaults;
|
||||
in xvars // {
|
||||
get = xvars.get // get;
|
||||
};
|
||||
};
|
||||
_module.args.xvars = config.xvars.lib;
|
||||
};
|
||||
};
|
||||
hostModule = { config, nixosConfig, gensokyo-zone, xvars, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mkJustBefore;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
||||
inherit (lib.strings) concatStringsSep;
|
||||
inherit (lib.attrsets) attrValues filterAttrs mapAttrs mapAttrsToList;
|
||||
inherit (lib.lists) any;
|
||||
inherit (lib.strings) concatStringsSep hasPrefix hasInfix;
|
||||
inherit (lib.trivial) isInt;
|
||||
cfg = config.xvars;
|
||||
escapeString = value: if value == "" then ''""'' else toString value;
|
||||
escapeString = value:
|
||||
if value == "" then ''""''
|
||||
else if isInt value then toString value
|
||||
else if hasPrefix ''"'' value || hasPrefix "'" value then value # already escaped, may include trailing arguments
|
||||
else if hasInfix ''"'' value then "'${value}'"
|
||||
else if hasInfix " " value || hasInfix ";" value || hasInfix "'" value then ''"${value}"''
|
||||
else value;
|
||||
anyLocations = f: any (loc: loc.enable && f loc) (attrValues config.locations);
|
||||
in {
|
||||
options = with lib.types; {
|
||||
xvars = {
|
||||
|
|
@ -34,10 +58,6 @@ let
|
|||
host = "$host";
|
||||
referer = "$http_referer";
|
||||
https = "$https";
|
||||
proxy_host = "$proxy_host";
|
||||
proxy_port = "$proxy_port";
|
||||
proxy_hostport = "${proxy_host}:${proxy_port}";
|
||||
proxy_scheme = null;
|
||||
};
|
||||
};
|
||||
lib = mkOption {
|
||||
|
|
@ -49,7 +69,7 @@ let
|
|||
modules = [ locationModule ];
|
||||
shorthandOnlyDefinesConfig = true;
|
||||
specialArgs = {
|
||||
inherit nixosConfig gensokyo-zone xvars;
|
||||
inherit nixosConfig gensokyo-zone;
|
||||
virtualHost = config;
|
||||
};
|
||||
});
|
||||
|
|
@ -70,7 +90,7 @@ let
|
|||
in {
|
||||
xvars = {
|
||||
enable = mkMerge [
|
||||
(mkIf (any (loc: loc.xvars.enable) (attrValues config.locations)) true)
|
||||
(mkIf (anyLocations (loc: loc.xvars.enable)) true)
|
||||
(mkIf cfg.parseReferer true)
|
||||
];
|
||||
defaults = mkIf cfg.parseReferer (mkOptionDefault {
|
||||
|
|
|
|||
|
|
@ -37,11 +37,9 @@ in {
|
|||
proxy = {
|
||||
enable = true;
|
||||
websocket.enable = true;
|
||||
headers.hide.Access-Control-Allow-Origin = true;
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_hide_header Access-Control-Allow-Origin;
|
||||
add_header Access-Control-Allow-Origin ${xvars.get.scheme}://${virtualHost.serverName};
|
||||
'';
|
||||
headers.set.Access-Control-Allow-Origin = "${xvars.get.scheme}://${virtualHost.serverName}";
|
||||
};
|
||||
};
|
||||
allLocations = mkMerge [
|
||||
|
|
|
|||
|
|
@ -40,11 +40,10 @@ in {
|
|||
proxy = {
|
||||
enable = true;
|
||||
websocket.enable = true;
|
||||
headers.enableRecommended = true;
|
||||
headers.hide.content-security-policy = true;
|
||||
};
|
||||
headers.set.content-security-policy = contentSecurityPolicy;
|
||||
extraConfig = ''
|
||||
proxy_hide_header content-security-policy;
|
||||
add_header content-security-policy "${contentSecurityPolicy}";
|
||||
proxy_cookie_domain ${virtualHosts.invidious.serverName} ${xvars.get.host};
|
||||
'';
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,19 +16,21 @@ with lib; {
|
|||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = false;
|
||||
headers.set = {
|
||||
Referrer-Policy = mkDefault "origin-when-cross-origin";
|
||||
#Strict-Transport-Security = "$hsts_header";
|
||||
#Content-Security-Policy = ''"script-src 'self'; object-src 'none'; base-uri 'none';" always'';
|
||||
#X-Frame-Options = "DENY";
|
||||
#X-Content-Type-Options = "nosniff";
|
||||
#X-XSS-Protection = "1; mode=block";
|
||||
};
|
||||
commonHttpConfig = ''
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=31536000; includeSubdomains; preload";
|
||||
}
|
||||
#add_header Strict-Transport-Security $hsts_header;
|
||||
#add_header Content-Security-Policy "script-src 'self'; object-src 'none'; base-uri 'none';" always;
|
||||
add_header 'Referrer-Policy' 'origin-when-cross-origin';
|
||||
#add_header X-Frame-Options DENY;
|
||||
#add_header X-Content-Type-Options nosniff;
|
||||
#add_header X-XSS-Protection "1; mode=block";
|
||||
#proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
|
||||
'';
|
||||
clientMaxBodySize = "512m";
|
||||
clientMaxBodySize = mkDefault "512m";
|
||||
virtualHosts.fallback = {
|
||||
serverName = null;
|
||||
default = mkDefault true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue