2023-12-24 19:38:04 +01:00
|
|
|
{ config, lib, options, pkgs, ... }:
|
2022-12-22 21:58:24 +01:00
|
|
|
|
2022-12-22 22:01:28 +01:00
|
|
|
let
|
2022-12-22 21:58:24 +01:00
|
|
|
cfg = config.services.portunus;
|
2023-07-01 23:53:42 +02:00
|
|
|
inherit (config.security) ldap;
|
2022-12-22 21:58:24 +01:00
|
|
|
in
|
|
|
|
{
|
|
|
|
options.services.portunus = {
|
2023-03-25 16:23:48 +01:00
|
|
|
# maybe based on $service.ldap.enable && services.portunus.enable?
|
2023-01-17 00:23:31 +01:00
|
|
|
addToHosts = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = false;
|
2023-01-17 02:14:18 +01:00
|
|
|
description = lib.mdDoc "Whether to add a hosts entry for the portunus domain pointing to externalIp";
|
2023-01-17 00:23:31 +01:00
|
|
|
};
|
|
|
|
|
2023-12-05 02:52:30 +01:00
|
|
|
configureOAuth2Proxy = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = false;
|
|
|
|
description = lib.mdDoc ''
|
|
|
|
Wether to configure OAuth2 Proxy with Portunus' Dex.
|
|
|
|
|
|
|
|
Use `services.oauth2_proxy.nginx.virtualHosts` to configure the nginx virtual hosts that should require authentication.
|
2023-12-24 19:38:04 +01:00
|
|
|
|
|
|
|
To properly function this requires the services.oauth2_proxy.nginx.domain option from <https://github.com/NixOS/nixpkgs/pull/273234>.
|
2023-12-05 02:52:30 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2023-02-23 00:34:37 +01:00
|
|
|
internalIp4 = lib.mkOption {
|
2022-12-22 21:58:24 +01:00
|
|
|
type = with lib.types; nullOr str;
|
|
|
|
default = null;
|
|
|
|
description = lib.mdDoc "Internal IPv4 of portunus instance. This is used in the addToHosts option.";
|
|
|
|
};
|
|
|
|
|
2023-02-23 00:34:37 +01:00
|
|
|
internalIp6 = lib.mkOption {
|
2022-12-22 21:58:24 +01:00
|
|
|
type = with lib.types; nullOr str;
|
|
|
|
default = null;
|
|
|
|
description = lib.mdDoc "Internal IPv6 of portunus instance. This is used in the addToHosts option.";
|
|
|
|
};
|
|
|
|
|
2023-01-17 00:23:31 +01:00
|
|
|
ldapPreset = lib.mkOption {
|
2022-12-22 21:58:24 +01:00
|
|
|
type = lib.types.bool;
|
2023-01-17 00:56:46 +01:00
|
|
|
default = false;
|
2023-01-17 02:14:18 +01:00
|
|
|
description = lib.mdDoc "Whether to set config.security.ldap to portunus specific settings.";
|
2022-12-22 21:58:24 +01:00
|
|
|
};
|
2023-07-01 23:53:42 +02:00
|
|
|
|
|
|
|
removeAddGroup = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = false;
|
|
|
|
description = lib.mdDoc "When enabled, remove the function to add new Groups via the web ui, to enforce seeding usage.";
|
|
|
|
};
|
|
|
|
|
|
|
|
seedGroups = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
|
|
|
default = false;
|
|
|
|
description = lib.mdDoc "Wether to seed groups configured in services as not member managed groups.";
|
|
|
|
};
|
2022-12-22 21:58:24 +01:00
|
|
|
};
|
|
|
|
|
2023-12-07 01:30:35 +01:00
|
|
|
config = {
|
2023-12-05 02:52:30 +01:00
|
|
|
assertions = [
|
|
|
|
{
|
|
|
|
assertion = cfg.configureOAuth2Proxy -> config.services.oauth2_proxy.keyFile != null;
|
|
|
|
message = ''
|
|
|
|
Setting services.portunus.configureOAuth2Proxy to true requires to set service.oauth2_proxy.keyFile
|
|
|
|
to a file that contains `OAUTH2_PROXY_CLIENT_SECRET` and `OAUTH2_PROXY_COOKIE_SECRET`.
|
|
|
|
'';
|
|
|
|
}
|
2024-01-06 02:32:11 +01:00
|
|
|
{
|
2024-01-06 02:48:38 +01:00
|
|
|
assertion = cfg.enable -> lib.versionAtLeast config.services.portunus.package.version "2.0.0";
|
2024-01-06 02:32:11 +01:00
|
|
|
message = "Portunus 2.0.0 is required for this module!";
|
|
|
|
}
|
2023-12-05 02:52:30 +01:00
|
|
|
];
|
|
|
|
|
2023-01-17 00:23:31 +01:00
|
|
|
networking.hosts = lib.mkIf cfg.addToHosts {
|
2023-02-23 00:34:37 +01:00
|
|
|
${cfg.internalIp4} = [ cfg.domain ];
|
|
|
|
${cfg.internalIp6} = [ cfg.domain ];
|
2023-01-17 00:23:31 +01:00
|
|
|
};
|
|
|
|
|
2023-12-07 01:30:35 +01:00
|
|
|
nixpkgs.overlays = lib.mkIf cfg.enable [
|
2023-04-04 20:52:33 +02:00
|
|
|
(final: prev: with final; {
|
2023-12-03 21:46:45 +01:00
|
|
|
dex-oidc = prev.dex-oidc.override {
|
|
|
|
buildGoModule = args: buildGoModule (args // {
|
2024-03-31 16:21:18 +02:00
|
|
|
patches = args.patches or [ ] ++ [
|
2023-12-03 21:46:45 +01:00
|
|
|
# remember session
|
2024-03-31 16:21:18 +02:00
|
|
|
(if (lib.versionAtLeast prev.dex-oidc.version "2.39") then
|
|
|
|
(fetchpatch {
|
|
|
|
url = "https://github.com/SuperSandro2000/dex/commit/b1cecedb6dba9027679b0a0fcd0a2863dece2e8d.patch";
|
|
|
|
hash = "sha256-2k5ulZ6sh1g0u3cAGnsL3O6m4vX0NBnpjgDSagMobx8=";
|
|
|
|
})
|
|
|
|
else if (lib.versionAtLeast prev.dex-oidc.version "2.38") then
|
|
|
|
(fetchpatch {
|
|
|
|
url = "https://github.com/SuperSandro2000/dex/commit/c1b2ac971920f1e07ce0e3d5890fe4f5d4e6207a.patch";
|
|
|
|
hash = "sha256-UVlA9sJrjg05tlqd3ELPB1OZtWlRXSvKTYPiz9oIuc0=";
|
|
|
|
})
|
|
|
|
else
|
|
|
|
(fetchpatch {
|
|
|
|
url = "https://github.com/SuperSandro2000/dex/commit/d2fb6cdf8188e6973721ddac657a7c5d3daf6955.patch";
|
|
|
|
hash = "sha256-PKC7jsNyFN28qFZ7SLYgnd0s09G2cb+vBeFvRzyyLGQ=";
|
|
|
|
})
|
|
|
|
)
|
2024-02-05 00:45:18 +01:00
|
|
|
] ++ [
|
2023-12-10 00:54:46 +01:00
|
|
|
# Complain if the env set in SecretEnv cannot be found
|
|
|
|
(fetchpatch {
|
|
|
|
url = "https://github.com/dexidp/dex/commit/f25f72053c9282cfe22521cd508698a07dc5190f.patch";
|
|
|
|
hash = "sha256-dyo+UPpceHxL3gcBQaGaDAHJqmysDJw051gMG1aeh5o=";
|
|
|
|
})
|
2023-12-03 21:46:45 +01:00
|
|
|
];
|
|
|
|
|
2024-03-31 16:21:18 +02:00
|
|
|
vendorHash = if lib.versionAtLeast prev.dex-oidc.version "2.39" then
|
2024-04-13 23:05:21 +02:00
|
|
|
"sha256-NgKZb2Oi4BInO/dSLzSUK722L/3pWQFWSNynjSj5sEE="
|
2024-03-31 16:21:18 +02:00
|
|
|
else if lib.versionAtLeast prev.dex-oidc.version "2.38" then
|
|
|
|
"sha256-f0b4z+Li0nspdWQyg4DPv6kFCO9xzO8IZBScSX2DoIs="
|
2024-02-05 00:45:18 +01:00
|
|
|
else
|
2024-03-31 16:21:18 +02:00
|
|
|
"sha256-YIi67pPIcVndIjWk94ckv6X4WLELUe/J/03e+XWIdHE=";
|
2023-12-03 21:46:45 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2024-01-06 02:32:04 +01:00
|
|
|
portunus = prev.portunus.overrideAttrs ({ patches ? [ ], ... }: {
|
2023-11-26 22:31:32 +01:00
|
|
|
patches = patches
|
|
|
|
++ lib.optional cfg.removeAddGroup ./portunus-remove-add-group.diff;
|
2023-04-04 00:05:25 +02:00
|
|
|
});
|
|
|
|
})
|
|
|
|
];
|
|
|
|
|
2023-12-05 02:52:30 +01:00
|
|
|
services = let
|
|
|
|
callbackURL = "https://${cfg.domain}/oauth2/callback";
|
2023-12-10 00:55:54 +01:00
|
|
|
clientID = "oauth2_proxy"; # - is not allowed in environment variables
|
2023-12-05 02:52:30 +01:00
|
|
|
in {
|
2024-04-28 21:40:20 +02:00
|
|
|
# the user has no other option to accept this and all clients are internal anyway
|
|
|
|
dex.settings.oauth2.skipApprovalScreen = true;
|
2023-12-05 02:52:30 +01:00
|
|
|
|
|
|
|
oauth2_proxy = lib.mkIf cfg.configureOAuth2Proxy {
|
|
|
|
enable = true;
|
2023-12-10 00:55:54 +01:00
|
|
|
inherit clientID;
|
2023-12-26 00:06:56 +01:00
|
|
|
nginx = lib.optionalAttrs (options.services.oauth2-proxy.nginx.domain or null != null) {
|
2023-12-10 00:56:05 +01:00
|
|
|
inherit (config.services.portunus) domain;
|
|
|
|
};
|
2023-12-05 02:52:30 +01:00
|
|
|
provider = "oidc";
|
|
|
|
redirectURL = callbackURL;
|
|
|
|
reverseProxy = true;
|
|
|
|
upstream = "http://127.0.0.1:4181";
|
|
|
|
extraConfig = {
|
|
|
|
oidc-issuer-url = config.services.dex.settings.issuer;
|
|
|
|
provider-display-name = "Portunus";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-04-28 21:40:20 +02:00
|
|
|
portunus.dex = lib.mkIf cfg.configureOAuth2Proxy {
|
|
|
|
enable = true;
|
|
|
|
oidcClients = [{
|
|
|
|
inherit callbackURL;
|
|
|
|
id = clientID;
|
|
|
|
}];
|
|
|
|
};
|
2023-12-03 23:19:30 +01:00
|
|
|
};
|
2023-07-01 23:53:42 +02:00
|
|
|
|
2023-01-17 00:23:31 +01:00
|
|
|
security.ldap = lib.mkIf cfg.ldapPreset {
|
2023-03-17 01:49:31 +01:00
|
|
|
domainName = cfg.domain;
|
2023-03-17 01:50:30 +01:00
|
|
|
givenNameField = "givenName";
|
2023-07-01 23:53:42 +02:00
|
|
|
groupFilter = group: "(&(objectclass=person)(isMemberOf=cn=${group},${ldap.roleBaseDN}))";
|
2023-03-17 01:50:30 +01:00
|
|
|
mailField = "mail";
|
|
|
|
port = 636;
|
2023-01-17 00:23:31 +01:00
|
|
|
roleBaseDN = "ou=groups";
|
|
|
|
roleField = "cn";
|
|
|
|
roleFilter = "(&(objectclass=groupOfNames)(member=%s))";
|
|
|
|
roleValue = "dn";
|
2023-07-02 19:30:24 +02:00
|
|
|
searchFilterWithGroupFilter = userFilterGroup: userFilter: if (userFilterGroup != null) then "(&${ldap.groupFilter userFilterGroup}${userFilter})" else userFilter;
|
2023-03-18 01:24:55 +01:00
|
|
|
sshPublicKeyField = "sshPublicKey";
|
2023-01-17 00:23:31 +01:00
|
|
|
searchUID = "search";
|
2023-03-17 01:50:30 +01:00
|
|
|
surnameField = "sn";
|
2023-01-17 00:23:31 +01:00
|
|
|
userField = "uid";
|
2023-07-01 23:53:42 +02:00
|
|
|
userFilter = replaceStr: "(&(objectclass=person)(|(uid=${replaceStr})(mail=${replaceStr})))";
|
2023-01-17 00:23:31 +01:00
|
|
|
userBaseDN = "ou=users";
|
|
|
|
};
|
2022-12-22 21:58:24 +01:00
|
|
|
};
|
|
|
|
}
|