mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 20:39:18 -08:00
refactor(nginx): proxy.ssl options
This commit is contained in:
parent
12671b3539
commit
1f9e9acde4
3 changed files with 176 additions and 135 deletions
|
|
@ -1,16 +1,19 @@
|
|||
let
|
||||
serverModule = {config, name, options, gensokyo-zone, lib, ...}: let
|
||||
proxyModule = {config, name, options, gensokyo-zone, lib, ...}: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkAfter;
|
||||
inherit (lib.modules) mkIf mkMerge mkAfter mkOptionDefault;
|
||||
inherit (lib.strings) optionalString;
|
||||
cfg = config.proxy;
|
||||
in {
|
||||
options = with lib.types; {
|
||||
proxy = {
|
||||
enable = mkEnableOption "proxy_pass";
|
||||
transparent.enable = mkEnableOption "proxy_bind transparent";
|
||||
ssl = {
|
||||
enable = mkEnableOption "ssl upstream";
|
||||
verify = mkEnableOption "proxy_ssl_verify";
|
||||
bind = {
|
||||
enable = mkEnableOption "proxy_bind";
|
||||
transparent = mkEnableOption "proxy_bind transparent";
|
||||
address = mkOption {
|
||||
type = str;
|
||||
};
|
||||
};
|
||||
url = mkOption {
|
||||
type = str;
|
||||
|
|
@ -18,23 +21,29 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
proxy = {
|
||||
bind.address = mkIf cfg.bind.transparent (mkOptionDefault "$remote_addr");
|
||||
};
|
||||
extraConfig = mkIf cfg.enable (mkMerge [
|
||||
(mkIf cfg.bind.enable (mkAfter (
|
||||
"proxy_bind ${cfg.bind.address}" + optionalString cfg.bind.transparent " transparent" + ";"
|
||||
)))
|
||||
]);
|
||||
};
|
||||
};
|
||||
serverModule = {config, name, options, gensokyo-zone, lib, ...}: let
|
||||
inherit (lib.modules) mkIf mkAfter;
|
||||
cfg = config.proxy;
|
||||
in {
|
||||
imports = [ proxyModule ];
|
||||
|
||||
config = let
|
||||
warnProxy = lib.warnIf (!cfg.enable && options.proxy.url.isDefined) "nginx.stream.servers.${name}.proxy.url set without proxy.enable";
|
||||
in {
|
||||
streamConfig = warnProxy (mkMerge [
|
||||
(mkIf cfg.transparent.enable ''
|
||||
proxy_bind $remote_addr transparent;
|
||||
'')
|
||||
(mkIf cfg.ssl.enable
|
||||
"proxy_ssl on;"
|
||||
)
|
||||
(mkIf (cfg.ssl.enable && cfg.ssl.verify)
|
||||
"proxy_ssl_verify on;"
|
||||
)
|
||||
(mkIf cfg.enable (mkAfter
|
||||
"proxy_pass ${cfg.url};"
|
||||
))
|
||||
]);
|
||||
streamConfig = warnProxy (mkIf cfg.enable (mkAfter
|
||||
"proxy_pass ${cfg.url};"
|
||||
));
|
||||
};
|
||||
};
|
||||
locationModule = { config, nixosConfig, name, virtualHost, xvars, gensokyo-zone, lib, ... }: let
|
||||
|
|
@ -47,9 +56,10 @@ let
|
|||
inherit (nixosConfig.services) nginx;
|
||||
cfg = config.proxy;
|
||||
in {
|
||||
imports = [ proxyModule ];
|
||||
|
||||
options = with lib.types; {
|
||||
proxy = {
|
||||
enable = mkEnableOption "proxy";
|
||||
enabled = mkOption {
|
||||
type = bool;
|
||||
readOnly = true;
|
||||
|
|
@ -58,9 +68,6 @@ let
|
|||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
url = mkOption {
|
||||
type = str;
|
||||
};
|
||||
path = mkOption {
|
||||
type = str;
|
||||
};
|
||||
|
|
@ -70,21 +77,6 @@ let
|
|||
websocket.enable = mkEnableOption "websocket proxy" // {
|
||||
default = cfg.inheritServerDefaults && virtualHost.proxy.websocket.enable;
|
||||
};
|
||||
ssl = {
|
||||
enabled = mkOption {
|
||||
type = bool;
|
||||
};
|
||||
verify = mkEnableOption "proxy_ssl_verify";
|
||||
sni = mkEnableOption "proxy_ssl_server_name" // {
|
||||
default = cfg.ssl.host != null;
|
||||
};
|
||||
host = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
example = "xvars.get.proxy_host";
|
||||
# $upstream_last_server_name is commercial-only :<
|
||||
};
|
||||
};
|
||||
parsed = {
|
||||
scheme = mkOption {
|
||||
type = nullOr str;
|
||||
|
|
@ -213,9 +205,6 @@ let
|
|||
enabled = mkOptionDefault (config.proxyPass != null);
|
||||
path = mkIf (hasPrefix "/" name) (mkOptionDefault name);
|
||||
url = mkIf (cfg.inheritServerDefaults && virtualHost.proxy.url != null) (mkOptionDefault virtualHost.proxy.url);
|
||||
ssl = {
|
||||
enabled = mkOptionDefault (cfg.parsed.scheme == "https");
|
||||
};
|
||||
headers = {
|
||||
enableRecommended = mkOptionDefault (
|
||||
if cfg.enable && (!cfg.inheritServerDefaults || virtualHost.proxy.headers.enableRecommended != false) then true
|
||||
|
|
@ -266,9 +255,6 @@ let
|
|||
(mkIf (cfg.headers.rewriteReferer.enable) (mkJustBefore rewriteReferer))
|
||||
(mkIf (cfg.redirect.enable) (mkBefore redirect))
|
||||
(mkIf (emitHeaders) (mkJustAfter setHeaders))
|
||||
(mkIf (cfg.ssl.enabled && cfg.ssl.sni) "proxy_ssl_server_name on;")
|
||||
(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));
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,68 +1,50 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
inherit (inputs.self.lib.lib) mkAlmostOptionDefault mkAlmostDefault;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.trivial) warnIf;
|
||||
inherit (config.services) nginx;
|
||||
forceRedirectConfig = { virtualHost, xvars }: ''
|
||||
if (${xvars.get.scheme} = http) {
|
||||
return ${toString virtualHost.redirectCode} https://${xvars.get.host}$request_uri;
|
||||
}
|
||||
'';
|
||||
locationModule = { config, virtualHost, xvars, ... }: let
|
||||
cfg = config.ssl;
|
||||
emitForce = cfg.force && !virtualHost.ssl.forced;
|
||||
in {
|
||||
options.ssl = {
|
||||
force = mkEnableOption "redirect to SSL";
|
||||
};
|
||||
config = {
|
||||
xvars.enable = mkIf emitForce true;
|
||||
extraConfig = mkIf emitForce (forceRedirectConfig { inherit xvars virtualHost; });
|
||||
};
|
||||
};
|
||||
sslModule = { config, name, ... }: let
|
||||
let
|
||||
sslModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
|
||||
inherit (lib.options) mkOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||
inherit (nixosConfig.services) nginx;
|
||||
cfg = config.ssl;
|
||||
in {
|
||||
options.ssl = with lib.types; {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
options = with lib.types; {
|
||||
ssl = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
};
|
||||
force = mkOption {
|
||||
# TODO: "force-nonlocal"? exceptions for tailscale?
|
||||
type = enum [ false true "only" "reject" ];
|
||||
default = false;
|
||||
};
|
||||
forced = mkOption {
|
||||
type = bool;
|
||||
readOnly = true;
|
||||
};
|
||||
cert = {
|
||||
name = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
keyPath = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
path = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
copyFromVhost = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
copyFromStreamServer = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
force = mkOption {
|
||||
# TODO: "force-nonlocal"? exceptions for tailscale?
|
||||
type = enum [ false true "only" "reject" ];
|
||||
default = false;
|
||||
};
|
||||
forced = mkOption {
|
||||
type = bool;
|
||||
readOnly = true;
|
||||
};
|
||||
cert = {
|
||||
name = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
keyPath = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
path = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
copyFromVhost = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
copyFromStreamServer = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
proxy.ssl = {
|
||||
enabled = mkOption {
|
||||
type = bool;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -85,7 +67,104 @@
|
|||
};
|
||||
};
|
||||
};
|
||||
hostModule = { config, name, xvars, ... }: let
|
||||
sslProxyModule = { config, lib, ... }: let
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkAfter;
|
||||
inherit (config) proxy;
|
||||
cfg = proxy.ssl;
|
||||
in {
|
||||
options.proxy.ssl = with lib.types; {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
};
|
||||
verify = mkEnableOption "proxy_ssl_verify";
|
||||
sni = mkEnableOption "proxy_ssl_server_name" // {
|
||||
default = cfg.host != null;
|
||||
};
|
||||
host = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
example = "xvars.get.proxy_host";
|
||||
description = "proxy_ssl_name";
|
||||
# $upstream_last_server_name is commercial-only :<
|
||||
};
|
||||
};
|
||||
config = {
|
||||
extraConfig = mkIf (proxy.enable && cfg.enable) (mkMerge [
|
||||
(mkIf cfg.verify "proxy_ssl_verify on;")
|
||||
(mkIf cfg.sni "proxy_ssl_server_name on;")
|
||||
(mkIf (cfg.host != null) (mkAfter "proxy_ssl_name ${cfg.host};"))
|
||||
]);
|
||||
};
|
||||
};
|
||||
streamServerModule = { config, nixosConfig, gensokyo-zone, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mkAlmostDefault;
|
||||
inherit (lib.options) mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
|
||||
cfg = config.ssl;
|
||||
in {
|
||||
imports = [ sslModule sslProxyModule ];
|
||||
options = with lib.types; {
|
||||
ssl = {
|
||||
kTLS = mkEnableOption "kTLS support" // {
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
config = let
|
||||
inherit (config) proxy;
|
||||
cert = nixosConfig.security.acme.certs.${cfg.cert.name};
|
||||
conf.ssl.cert = {
|
||||
path = mkIf (cfg.cert.name != null) (mkAlmostDefault "${cert.directory}/fullchain.pem");
|
||||
keyPath = mkIf (cfg.cert.name != null) (mkAlmostDefault "${cert.directory}/key.pem");
|
||||
};
|
||||
conf.proxy.ssl.enable = mkOptionDefault false;
|
||||
#confSsl.listen.ssl = { ssl = true; };
|
||||
confSsl.extraConfig = mkMerge [
|
||||
(mkIf (cfg.cert.path != null) "ssl_certificate ${cfg.cert.path};")
|
||||
(mkIf (cfg.cert.keyPath != null) "ssl_certificate_key ${cfg.cert.keyPath};")
|
||||
(mkIf cfg.kTLS "ssl_conf_command Options KTLS;")
|
||||
];
|
||||
confProxy.extraConfig = mkIf proxy.ssl.enable "proxy_ssl on;";
|
||||
in mkMerge [
|
||||
conf
|
||||
(mkIf cfg.enable confSsl)
|
||||
(mkIf proxy.enable confProxy)
|
||||
];
|
||||
};
|
||||
in {
|
||||
config,
|
||||
gensokyo-zone,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.trivial) warnIf;
|
||||
inherit (lib.strings) hasPrefix;
|
||||
inherit (config.services) nginx;
|
||||
forceRedirectConfig = { virtualHost, xvars }: ''
|
||||
if (${xvars.get.scheme} = http) {
|
||||
return ${toString virtualHost.redirectCode} https://${xvars.get.host}$request_uri;
|
||||
}
|
||||
'';
|
||||
locationModule = { config, virtualHost, xvars, ... }: let
|
||||
cfg = config.ssl;
|
||||
emitForce = cfg.force && !virtualHost.ssl.forced;
|
||||
in {
|
||||
imports = [ sslProxyModule ];
|
||||
options.ssl = {
|
||||
force = mkEnableOption "redirect to SSL";
|
||||
};
|
||||
config = {
|
||||
proxy.ssl.enable = mkOptionDefault (hasPrefix "https://" config.proxyPass);
|
||||
xvars.enable = mkIf emitForce true;
|
||||
extraConfig = mkIf emitForce (forceRedirectConfig { inherit xvars virtualHost; });
|
||||
};
|
||||
};
|
||||
hostModule = { config, xvars, ... }: let
|
||||
cfg = config.ssl;
|
||||
emitForce = cfg.forced && config.proxied.enabled;
|
||||
in {
|
||||
|
|
@ -124,30 +203,6 @@
|
|||
extraConfig = mkIf emitForce (forceRedirectConfig { virtualHost = config; inherit xvars; });
|
||||
};
|
||||
};
|
||||
upstreamServerModule = { config, nixosConfig, ... }: let
|
||||
cfg = config.ssl;
|
||||
in {
|
||||
imports = [ sslModule ];
|
||||
options.ssl = with lib.types; {
|
||||
kTLS = mkEnableOption "kTLS support" // {
|
||||
default = true;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
ssl.cert = let
|
||||
cert = nixosConfig.security.acme.certs.${cfg.cert.name};
|
||||
in {
|
||||
path = mkIf (cfg.cert.name != null) (mkAlmostDefault "${cert.directory}/fullchain.pem");
|
||||
keyPath = mkIf (cfg.cert.name != null) (mkAlmostDefault "${cert.directory}/key.pem");
|
||||
};
|
||||
#listen.ssl = mkIf cfg.enable { ssl = true; };
|
||||
extraConfig = mkIf cfg.enable (mkMerge [
|
||||
(mkIf (cfg.cert.path != null) "ssl_certificate ${cfg.cert.path};")
|
||||
(mkIf (cfg.cert.keyPath != null) "ssl_certificate_key ${cfg.cert.keyPath};")
|
||||
(mkIf cfg.kTLS "ssl_conf_command Options KTLS;")
|
||||
]);
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.services.nginx = with lib.types; {
|
||||
virtualHosts = mkOption {
|
||||
|
|
@ -158,7 +213,7 @@ in {
|
|||
};
|
||||
stream.servers = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [ upstreamServerModule ];
|
||||
modules = [ streamServerModule ];
|
||||
shorthandOnlyDefinesConfig = false;
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ let
|
|||
|
||||
config = let
|
||||
proxyUpstream = nginx.upstreams'.${config.proxy.upstream};
|
||||
proxyScheme = if config.proxy.ssl.enabled then "https" else "http";
|
||||
proxyScheme = if config.proxy.ssl.enable then "https" else "http";
|
||||
dynamicUpstream = hasPrefix "$" config.proxy.upstream;
|
||||
hasUpstream = config.proxy.upstream != null && !dynamicUpstream;
|
||||
proxyHost =
|
||||
|
|
@ -265,7 +265,7 @@ let
|
|||
url = mkIf (config.proxy.upstream != null) (mkAlmostOptionDefault
|
||||
"${proxyScheme}://${proxyHost}"
|
||||
);
|
||||
ssl.enabled = mkAlmostOptionDefault (if hasUpstream then proxyUpstream.ssl.enable else false);
|
||||
ssl.enable = mkAlmostOptionDefault (if hasUpstream then proxyUpstream.ssl.enable else false);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue