nixos/middleman: Add nginx-sso
This commit is contained in:
@@ -13,5 +13,6 @@
|
||||
vms = ./vms.nix;
|
||||
network = ./network.nix;
|
||||
pdns = ./pdns.nix;
|
||||
nginx-sso = ./nginx-sso.nix;
|
||||
};
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ in
|
||||
config = mkMerge [
|
||||
{
|
||||
networking = {
|
||||
domain = mkDefault "int.nul.ie";
|
||||
domain = mkDefault "int.${lib.my.pubDomain}";
|
||||
useDHCP = false;
|
||||
enableIPv6 = mkDefault true;
|
||||
useNetworkd = mkDefault true;
|
||||
|
127
nixos/modules/nginx-sso.nix
Normal file
127
nixos/modules/nginx-sso.nix
Normal file
@@ -0,0 +1,127 @@
|
||||
{ lib, pkgs, config, ... }:
|
||||
let
|
||||
inherit (lib) mkIf mkMerge getBin mapAttrsToList;
|
||||
inherit (lib.my) mkOpt' mkBoolOpt';
|
||||
|
||||
includeOpts = { ... }: {
|
||||
options = with lib.types; {
|
||||
auth = {
|
||||
path = mkOpt' str "/sso-auth" "HTTP path for SSO auth.";
|
||||
redirect = mkOpt' str "$scheme://$http_host$request_uri" "URL to redirect to upon successful login.";
|
||||
};
|
||||
logout = {
|
||||
path = mkOpt' str "/sso-logout" "HTTP path for SSO logout.";
|
||||
redirect = mkOpt' str "$scheme://$http_host/" "URL to redirect to upon successful logout.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cfg = config.my.nginx-sso;
|
||||
|
||||
pkg = getBin cfg.package;
|
||||
baseConfig = pkgs.writeText "nginx-sso.yaml" (builtins.toJSON cfg.configuration);
|
||||
runCfg = "/run/nginx-sso/config.yaml";
|
||||
in
|
||||
{
|
||||
options.my.nginx-sso = with lib.types; {
|
||||
enable = mkBoolOpt' true "Whether to enable custom nginx-sso.";
|
||||
package = mkOpt' package pkgs.nginx-sso "nginx-sso package to use.";
|
||||
configuration = mkOpt' (attrsOf unspecified) { } "nginx-sso configuration.";
|
||||
extraConfigFile = mkOpt' (nullOr str) null "Path to configuration (e.g. for secrets).";
|
||||
|
||||
includes = {
|
||||
endpoint = mkOpt' str "http://localhost:8082" "Upstream for proxied auth requests.";
|
||||
baseURL = mkOpt' str null "Base URL for redirects.";
|
||||
|
||||
instances = mkOpt' (attrsOf (submodule includeOpts)) { } "nginx includes instances.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !config.services.nginx.sso.enable;
|
||||
message = "Stock nginx-sso cannot be used with this module.";
|
||||
}
|
||||
];
|
||||
|
||||
environment.etc = with cfg.includes; mkMerge (mapAttrsToList (n: i: {
|
||||
"nginx/includes/sso/server-${n}.conf".text = ''
|
||||
location ${i.auth.path} {
|
||||
# Do not allow requests from outside
|
||||
internal;
|
||||
|
||||
# Access /auth endpoint to query login state
|
||||
proxy_pass ${endpoint}/auth;
|
||||
|
||||
# Do not forward the request body (nginx-sso does not care about it)
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_header Content-Length "";
|
||||
|
||||
# Set custom information for ACL matching: Each one is available as
|
||||
# a field for matching: X-Host = x-host, ...
|
||||
proxy_set_header X-Origin-URI $request_uri;
|
||||
proxy_set_header X-Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Define where to send the user to login and specify how to get back
|
||||
location @error401 {
|
||||
return 302 ${baseURL}/login?go=${i.auth.redirect};
|
||||
}
|
||||
|
||||
# If the user is lead to /logout redirect them to the logout endpoint
|
||||
# of ngninx-sso which then will redirect the user to / on the current host
|
||||
location ${i.logout.path} {
|
||||
return 302 ${baseURL}/logout?go=${i.logout.redirect};
|
||||
}
|
||||
'';
|
||||
"nginx/includes/sso/location-${n}.conf".text = ''
|
||||
# Protect this location using the auth_request
|
||||
auth_request ${i.auth.path};
|
||||
|
||||
# Redirect the user to the login page when they are not logged in
|
||||
error_page 401 = @error401;
|
||||
|
||||
# Automatically renew SSO cookie on request
|
||||
auth_request_set $cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $cookie;
|
||||
'';
|
||||
}) instances);
|
||||
|
||||
users = {
|
||||
groups.nginx-sso = {};
|
||||
users.nginx-sso = {
|
||||
group = "nginx-sso";
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.nginx-sso = {
|
||||
description = "Nginx SSO Backend";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
preStart = ''
|
||||
umask 066
|
||||
${if (cfg.extraConfigFile != null) then ''
|
||||
${pkgs.yq-go}/bin/yq -P '. *= load("${cfg.extraConfigFile}")' "${baseConfig}" > ${runCfg}
|
||||
'' else ''
|
||||
${pkgs.yq-go}/bin/yq -P "${baseConfig}" > ${runCfg}
|
||||
''}
|
||||
'';
|
||||
serviceConfig = {
|
||||
RuntimeDirectory = "nginx-sso";
|
||||
User = "nginx-sso";
|
||||
Group = "nginx-sso";
|
||||
ExecStart = [
|
||||
# Specify twice to clear original value
|
||||
""
|
||||
''${pkg}/bin/nginx-sso --frontend-dir ${pkg}/share/frontend --config ${runCfg}''
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user