mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 12:29:19 -08:00
refactor(nginx): ssl preread
This commit is contained in:
parent
418caefe64
commit
b0a3da835c
7 changed files with 162 additions and 74 deletions
103
modules/nixos/nginx/preread.nix
Normal file
103
modules/nixos/nginx/preread.nix
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
let
|
||||||
|
serverModule = {config, nixosConfig, name, gensokyo-zone, lib, ...}: let
|
||||||
|
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkBefore mkOptionDefault;
|
||||||
|
inherit (lib.attrsets) mapAttrsToList;
|
||||||
|
inherit (lib.lists) optional;
|
||||||
|
inherit (lib.strings) concatStringsSep replaceStrings;
|
||||||
|
cfg = config.ssl.preread;
|
||||||
|
inherit (nixosConfig.services) nginx;
|
||||||
|
in {
|
||||||
|
options.ssl.preread = with lib.types; {
|
||||||
|
enable = mkEnableOption "ngx_stream_ssl_preread_module";
|
||||||
|
upstream = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "$preread_" + replaceStrings [ "'" ] [ "_" ] name;
|
||||||
|
};
|
||||||
|
upstreams = mkOption {
|
||||||
|
type = nullOr (attrsOf str);
|
||||||
|
};
|
||||||
|
streamConfig = mkOption {
|
||||||
|
type = lines;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = let
|
||||||
|
inherit (nginx.stream) upstreams;
|
||||||
|
mkUpstream = host: upstream: "${host} ${upstreams.${upstream}.name};";
|
||||||
|
upstreams' = removeAttrs cfg.upstreams [ "default" ];
|
||||||
|
upstreamLines = mapAttrsToList mkUpstream upstreams'
|
||||||
|
++ optional (cfg.upstreams ? default) (mkUpstream "default" cfg.upstreams.default);
|
||||||
|
in {
|
||||||
|
ssl.preread = {
|
||||||
|
streamConfig = mkIf (cfg.upstreams != null) ''
|
||||||
|
map $ssl_preread_server_name ${cfg.upstream} {
|
||||||
|
hostnames;
|
||||||
|
${concatStringsSep "\n " upstreamLines}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
proxy = mkIf cfg.enable {
|
||||||
|
ssl.enable = false;
|
||||||
|
upstream = mkAlmostOptionDefault cfg.upstream;
|
||||||
|
};
|
||||||
|
streamConfig = mkIf cfg.enable "ssl_preread on;";
|
||||||
|
serverBlock = mkIf cfg.enable (mkOptionDefault (mkBefore cfg.streamConfig));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {config, gensokyo-zone, lib, ...}: let
|
||||||
|
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||||
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
|
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||||
|
cfg = config.services.nginx.ssl.preread;
|
||||||
|
in {
|
||||||
|
options.services.nginx = with lib.types; {
|
||||||
|
ssl.preread = {
|
||||||
|
enable = mkEnableOption "ssl preread";
|
||||||
|
listenPort = mkOption {
|
||||||
|
type = port;
|
||||||
|
default = 444;
|
||||||
|
};
|
||||||
|
serverPort = mkOption {
|
||||||
|
type = port;
|
||||||
|
default = 443;
|
||||||
|
};
|
||||||
|
serverName = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "preread'https";
|
||||||
|
};
|
||||||
|
upstreamName = mkOption {
|
||||||
|
type = str;
|
||||||
|
default = "preread'nginx";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
stream.servers = mkOption {
|
||||||
|
type = attrsOf (submoduleWith {
|
||||||
|
modules = [serverModule];
|
||||||
|
shorthandOnlyDefinesConfig = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
services.nginx = {
|
||||||
|
defaultSSLListenPort = mkIf cfg.enable cfg.listenPort;
|
||||||
|
stream = {
|
||||||
|
upstreams.${cfg.upstreamName} = mkIf cfg.enable {
|
||||||
|
ssl.enable = true;
|
||||||
|
servers.access = {
|
||||||
|
addr = mkDefault "localhost";
|
||||||
|
port = mkOptionDefault cfg.listenPort;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
servers.${cfg.serverName} = {
|
||||||
|
enable = mkIf (!cfg.enable) (mkAlmostOptionDefault false);
|
||||||
|
listen.https.port = cfg.serverPort;
|
||||||
|
ssl.preread = {
|
||||||
|
enable = true;
|
||||||
|
upstreams.default = mkOptionDefault cfg.upstreamName;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -93,6 +93,8 @@ let
|
||||||
url = parseUrl config.proxyPass;
|
url = parseUrl config.proxyPass;
|
||||||
upstream = nginx.upstreams'.${cfg.upstream};
|
upstream = nginx.upstreams'.${cfg.upstream};
|
||||||
upstreamServer = upstream.servers.${upstream.defaultServerName};
|
upstreamServer = upstream.servers.${upstream.defaultServerName};
|
||||||
|
dynamicUpstream = hasPrefix "$" cfg.upstream;
|
||||||
|
hasUpstream = cfg.upstream != null && !dynamicUpstream && upstream.defaultServerName != null;
|
||||||
recommendedHeaders = {
|
recommendedHeaders = {
|
||||||
Host = if cfg.host == null then xvars.get.proxy_hostport else cfg.host;
|
Host = if cfg.host == null then xvars.get.proxy_hostport else cfg.host;
|
||||||
Referer = xvars.get.referer;
|
Referer = xvars.get.referer;
|
||||||
|
|
@ -209,11 +211,11 @@ let
|
||||||
mapNullable (_: url.path) config.proxyPass
|
mapNullable (_: url.path) config.proxyPass
|
||||||
);
|
);
|
||||||
host = mkOptionDefault (
|
host = mkOptionDefault (
|
||||||
if cfg.upstream != null then assert url.host == upstream.name; upstreamServer.addr
|
if hasUpstream then assert url.host == upstream.name; upstreamServer.addr
|
||||||
else mapNullable (_: url.host) config.proxyPass
|
else mapNullable (_: url.host) config.proxyPass
|
||||||
);
|
);
|
||||||
port = mkOptionDefault (
|
port = mkOptionDefault (
|
||||||
if cfg.upstream != null && url.port == null then assert url.host == upstream.name; upstreamServer.port
|
if hasUpstream && url.port == null then assert url.host == upstream.name; upstreamServer.port
|
||||||
else mapNullable (_: url.port) config.proxyPass
|
else mapNullable (_: url.port) config.proxyPass
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,6 @@
|
||||||
type = lines;
|
type = lines;
|
||||||
internal = true;
|
internal = true;
|
||||||
};
|
};
|
||||||
ssl = {
|
|
||||||
preread.enable = mkEnableOption "ngx_stream_ssl_preread_module";
|
|
||||||
};
|
|
||||||
proxy = {
|
proxy = {
|
||||||
ssl = {
|
ssl = {
|
||||||
enable = mkEnableOption "ssl upstream";
|
enable = mkEnableOption "ssl upstream";
|
||||||
|
|
@ -41,12 +38,8 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
proxy.ssl.enable = mkIf config.ssl.preread.enable false;
|
|
||||||
streamConfig = mkMerge [
|
streamConfig = mkMerge [
|
||||||
config.extraConfig
|
config.extraConfig
|
||||||
(mkIf config.ssl.preread.enable
|
|
||||||
"ssl_preread on;"
|
|
||||||
)
|
|
||||||
(mkIf config.proxy.ssl.enable
|
(mkIf config.proxy.ssl.enable
|
||||||
"proxy_ssl on;"
|
"proxy_ssl on;"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,7 @@ let
|
||||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||||
inherit (lib.options) mkOption;
|
inherit (lib.options) mkOption;
|
||||||
inherit (lib.modules) mkIf;
|
inherit (lib.modules) mkIf;
|
||||||
|
inherit (lib.strings) hasPrefix;
|
||||||
inherit (nixosConfig.services) nginx;
|
inherit (nixosConfig.services) nginx;
|
||||||
in {
|
in {
|
||||||
options = with lib.types; {
|
options = with lib.types; {
|
||||||
|
|
@ -217,12 +218,15 @@ let
|
||||||
|
|
||||||
config = let
|
config = let
|
||||||
proxyUpstream = nginx.stream.upstreams.${config.proxy.upstream};
|
proxyUpstream = nginx.stream.upstreams.${config.proxy.upstream};
|
||||||
|
dynamicUpstream = hasPrefix "$" config.proxy.upstream;
|
||||||
|
hasUpstream = config.proxy.upstream != null && !dynamicUpstream;
|
||||||
|
proxyPass =
|
||||||
|
if dynamicUpstream then config.proxy.upstream
|
||||||
|
else assert proxyUpstream.enable; proxyUpstream.name;
|
||||||
in {
|
in {
|
||||||
proxy = {
|
proxy = {
|
||||||
url = mkIf (config.proxy.upstream != null) (mkAlmostOptionDefault (assert proxyUpstream.enable;
|
url = mkIf (config.proxy.upstream != null) (mkAlmostOptionDefault proxyPass);
|
||||||
proxyUpstream.name
|
ssl.enable = mkIf (hasUpstream && proxyUpstream.ssl.enable) (mkAlmostOptionDefault true);
|
||||||
));
|
|
||||||
ssl.enable = mkIf (config.proxy.upstream != null && proxyUpstream.ssl.enable) (mkAlmostOptionDefault true);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -240,20 +244,27 @@ let
|
||||||
locationModule = {config, nixosConfig, virtualHost, gensokyo-zone, lib, ...}: let
|
locationModule = {config, nixosConfig, virtualHost, gensokyo-zone, lib, ...}: let
|
||||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
inherit (gensokyo-zone.lib) mkAlmostOptionDefault;
|
||||||
inherit (lib.modules) mkIf mkOptionDefault;
|
inherit (lib.modules) mkIf mkOptionDefault;
|
||||||
|
inherit (lib.strings) hasPrefix;
|
||||||
inherit (nixosConfig.services) nginx;
|
inherit (nixosConfig.services) nginx;
|
||||||
in {
|
in {
|
||||||
imports = [ proxyUpstreamModule ];
|
imports = [ proxyUpstreamModule ];
|
||||||
|
|
||||||
config = let
|
config = let
|
||||||
proxyUpstream = nginx.upstreams'.${config.proxy.upstream};
|
proxyUpstream = nginx.upstreams'.${config.proxy.upstream};
|
||||||
proxyScheme = if proxyUpstream.ssl.enable then "https" else "http";
|
proxyScheme = if config.proxy.ssl.enabled then "https" else "http";
|
||||||
|
dynamicUpstream = hasPrefix "$" config.proxy.upstream;
|
||||||
|
hasUpstream = config.proxy.upstream != null && !dynamicUpstream;
|
||||||
|
proxyHost =
|
||||||
|
if dynamicUpstream then config.proxy.upstream
|
||||||
|
else assert proxyUpstream.enable; proxyUpstream.name;
|
||||||
in {
|
in {
|
||||||
proxy = {
|
proxy = {
|
||||||
upstream = mkOptionDefault virtualHost.proxy.upstream;
|
upstream = mkOptionDefault virtualHost.proxy.upstream;
|
||||||
enable = mkIf (config.proxy.upstream != null && virtualHost.proxy.upstream == null) true;
|
enable = mkIf (config.proxy.upstream != null && virtualHost.proxy.upstream == null) true;
|
||||||
url = mkIf (config.proxy.upstream != null) (mkAlmostOptionDefault (assert proxyUpstream.enable;
|
url = mkIf (config.proxy.upstream != null) (mkAlmostOptionDefault
|
||||||
"${proxyScheme}://${proxyUpstream.name}"
|
"${proxyScheme}://${proxyHost}"
|
||||||
));
|
);
|
||||||
|
ssl.enabled = mkAlmostOptionDefault (if hasUpstream then proxyUpstream.ssl.enable else false);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (gensokyo-zone.lib) mkAddress6;
|
inherit (gensokyo-zone.lib) mkAddress6 mapOptionDefaults;
|
||||||
inherit (lib.options) mkOption mkEnableOption;
|
inherit (lib.options) mkOption mkEnableOption;
|
||||||
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
inherit (lib.modules) mkIf mkMerge mkDefault mkOptionDefault;
|
||||||
inherit (config.services) tailscale;
|
inherit (config.services) tailscale;
|
||||||
|
|
@ -52,13 +52,6 @@ in {
|
||||||
type = str;
|
type = str;
|
||||||
};
|
};
|
||||||
preread = {
|
preread = {
|
||||||
enable = mkEnableOption "ssl preread" // {
|
|
||||||
# TODO: default = true;
|
|
||||||
};
|
|
||||||
port = mkOption {
|
|
||||||
type = port;
|
|
||||||
default = 444;
|
|
||||||
};
|
|
||||||
ldapPort = mkOption {
|
ldapPort = mkOption {
|
||||||
type = port;
|
type = port;
|
||||||
default = 637;
|
default = 637;
|
||||||
|
|
@ -104,10 +97,10 @@ in {
|
||||||
};
|
};
|
||||||
config = {
|
config = {
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
|
# TODO: ssl.preread.enable = mkDefault true;
|
||||||
access.freeipa = {
|
access.freeipa = {
|
||||||
host = mkOptionDefault (config.lib.access.getAddressFor (config.lib.access.systemForService "freeipa").name "lan");
|
host = mkOptionDefault (config.lib.access.getAddressFor (config.lib.access.systemForService "freeipa").name "lan");
|
||||||
};
|
};
|
||||||
defaultSSLListenPort = mkIf access.preread.enable access.preread.port;
|
|
||||||
stream = let
|
stream = let
|
||||||
prereadConf = {
|
prereadConf = {
|
||||||
upstreams = {
|
upstreams = {
|
||||||
|
|
@ -128,28 +121,29 @@ in {
|
||||||
port = mkOptionDefault nginx.stream.servers.ldap.listen.ldaps.port;
|
port = mkOptionDefault nginx.stream.servers.ldap.listen.ldaps.port;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
nginx = {
|
|
||||||
ssl.enable = true;
|
|
||||||
servers.access = {
|
|
||||||
addr = mkDefault "localhost";
|
|
||||||
port = mkOptionDefault nginx.defaultSSLListenPort;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
servers = {
|
servers = {
|
||||||
preread'https = {
|
${nginx.ssl.preread.serverName} = {
|
||||||
listen = {
|
ssl.preread.upstreams = mapOptionDefaults {
|
||||||
https.port = 443;
|
${virtualHosts.freeipa.serverName} = "freeipa";
|
||||||
|
${virtualHosts.freeipa'ca.serverName} = "freeipa";
|
||||||
|
${nginx.access.ldap.domain} = "ldaps_access";
|
||||||
|
${nginx.access.ldap.localDomain} = "ldaps_access";
|
||||||
|
${nginx.access.ldap.intDomain} = "ldaps_access";
|
||||||
|
${nginx.access.ldap.tailDomain} = "ldaps_access";
|
||||||
};
|
};
|
||||||
ssl.preread.enable = true;
|
|
||||||
proxy.url = "$https_upstream";
|
|
||||||
};
|
};
|
||||||
preread'ldap = {
|
preread'ldap = {
|
||||||
listen = {
|
listen = {
|
||||||
ldaps.port = 636;
|
ldaps.port = access.ldapPort;
|
||||||
|
};
|
||||||
|
ssl.preread = {
|
||||||
|
enable = true;
|
||||||
|
upstreams = mapOptionDefaults {
|
||||||
|
${virtualHosts.freeipa.serverName} = "ldaps";
|
||||||
|
default = "ldaps_access";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
ssl.preread.enable = true;
|
|
||||||
proxy.url = "$ldap_upstream";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -198,37 +192,16 @@ in {
|
||||||
conf.servers = {
|
conf.servers = {
|
||||||
ldap = {
|
ldap = {
|
||||||
listen = {
|
listen = {
|
||||||
ldaps.port = mkIf access.preread.enable (mkDefault access.preread.ldapPort);
|
ldaps.port = mkIf nginx.ssl.preread.enable (mkDefault access.preread.ldapPort);
|
||||||
};
|
};
|
||||||
ssl.cert.copyFromVhost = mkDefault "freeipa";
|
ssl.cert.copyFromVhost = mkDefault "freeipa";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in mkMerge [
|
in mkMerge [
|
||||||
conf
|
conf
|
||||||
(mkIf access.preread.enable prereadConf)
|
(mkIf nginx.ssl.preread.enable prereadConf)
|
||||||
(mkIf access.kerberos.enable kerberosConf)
|
(mkIf access.kerberos.enable kerberosConf)
|
||||||
];
|
];
|
||||||
streamConfig = let
|
|
||||||
inherit (nginx.stream) upstreams;
|
|
||||||
preread = ''
|
|
||||||
map $ssl_preread_server_name $https_upstream {
|
|
||||||
hostnames;
|
|
||||||
${virtualHosts.freeipa.serverName} ${upstreams.freeipa.name};
|
|
||||||
${virtualHosts.freeipa'ca.serverName} ${upstreams.freeipa.name};
|
|
||||||
${nginx.access.ldap.domain} ${upstreams.ldaps_access.name};
|
|
||||||
${nginx.access.ldap.localDomain} ${upstreams.ldaps_access.name};
|
|
||||||
${nginx.access.ldap.intDomain} ${upstreams.ldaps_access.name};
|
|
||||||
${nginx.access.ldap.tailDomain} ${upstreams.ldaps_access.name};
|
|
||||||
default ${upstreams.nginx.name};
|
|
||||||
}
|
|
||||||
|
|
||||||
map $ssl_preread_server_name $ldap_upstream {
|
|
||||||
hostnames;
|
|
||||||
${virtualHosts.freeipa.serverName} ${upstreams.ldaps.name};
|
|
||||||
default ${upstreams.ldaps_access.name};
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
in mkIf access.preread.enable preread;
|
|
||||||
virtualHosts = let
|
virtualHosts = let
|
||||||
name.shortServer = mkDefault "ipa";
|
name.shortServer = mkDefault "ipa";
|
||||||
in {
|
in {
|
||||||
|
|
@ -292,8 +265,8 @@ in {
|
||||||
access.kerberos.ports.kpasswd
|
access.kerberos.ports.kpasswd
|
||||||
access.kerberos.ports.kadmin
|
access.kerberos.ports.kadmin
|
||||||
])
|
])
|
||||||
(mkIf access.preread.enable [
|
(mkIf nginx.ssl.preread.enable [
|
||||||
636
|
access.ldapPort
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
allowedUDPPorts = mkIf access.kerberos.enable [
|
allowedUDPPorts = mkIf access.kerberos.enable [
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
_: {
|
{config, lib, ...}: let
|
||||||
networking.firewall.allowedTCPPorts = [
|
inherit (lib.modules) mkIf;
|
||||||
|
cfg = config.services.nginx;
|
||||||
|
in {
|
||||||
|
networking.firewall.allowedTCPPorts = mkIf cfg.enable [
|
||||||
443
|
443
|
||||||
80
|
80
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
|
||||||
...
|
...
|
||||||
}:
|
}: let
|
||||||
with lib; {
|
inherit (lib.modules) mkIf mkDefault;
|
||||||
networking.firewall.interfaces.local.allowedTCPPorts = [
|
cfg = config.services.nginx;
|
||||||
443
|
in {
|
||||||
80
|
networking.firewall.interfaces.local.allowedTCPPorts = let
|
||||||
|
inherit (cfg.ssl) preread;
|
||||||
|
in mkIf cfg.enable [
|
||||||
|
(if preread.enable then preread.serverPort else cfg.defaultSSLListenPort)
|
||||||
|
cfg.defaultHTTPListenPort
|
||||||
];
|
];
|
||||||
|
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue