forked from mirrors_public/oddlama_nix-config
263 lines
8.4 KiB
Nix
263 lines
8.4 KiB
Nix
{
|
|
config,
|
|
globals,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
kanidmDomain = "auth.${globals.domains.me}";
|
|
kanidmPort = 8300;
|
|
|
|
mkRandomSecret = {
|
|
generator.script = "alnum";
|
|
mode = "440";
|
|
group = "kanidm";
|
|
};
|
|
in
|
|
{
|
|
globals.wireguard.proxy-sentinel.hosts.${config.node.name}.firewallRuleForNode.sentinel.allowedTCPPorts =
|
|
[ kanidmPort ];
|
|
|
|
age.secrets."kanidm-self-signed.crt" = {
|
|
rekeyFile = config.node.secretsDir + "/kanidm-self-signed.crt.age";
|
|
mode = "440";
|
|
group = "kanidm";
|
|
};
|
|
|
|
age.secrets."kanidm-self-signed.key" = {
|
|
rekeyFile = config.node.secretsDir + "/kanidm-self-signed.key.age";
|
|
mode = "440";
|
|
group = "kanidm";
|
|
};
|
|
|
|
age.secrets.kanidm-admin-password = mkRandomSecret;
|
|
age.secrets.kanidm-idm-admin-password = mkRandomSecret;
|
|
|
|
age.secrets.kanidm-oauth2-forgejo = mkRandomSecret;
|
|
age.secrets.kanidm-oauth2-grafana = mkRandomSecret;
|
|
age.secrets.kanidm-oauth2-immich = mkRandomSecret;
|
|
age.secrets.kanidm-oauth2-firezone = mkRandomSecret;
|
|
age.secrets.kanidm-oauth2-mealie = mkRandomSecret;
|
|
age.secrets.kanidm-oauth2-paperless = mkRandomSecret;
|
|
age.secrets.kanidm-oauth2-web-sentinel = mkRandomSecret;
|
|
|
|
globals.services.kanidm.domain = kanidmDomain;
|
|
globals.monitoring.http.kanidm = {
|
|
url = "https://${kanidmDomain}/status";
|
|
network = "internet";
|
|
expectedBodyRegex = "true";
|
|
skipTlsVerification = true;
|
|
};
|
|
|
|
nodes.sentinel = {
|
|
services.nginx = {
|
|
upstreams.kanidm = {
|
|
servers."${
|
|
globals.wireguard.proxy-sentinel.hosts.${config.node.name}.ipv4
|
|
}:${toString kanidmPort}" =
|
|
{ };
|
|
extraConfig = ''
|
|
zone kanidm 64k;
|
|
keepalive 2;
|
|
'';
|
|
monitoring = {
|
|
enable = true;
|
|
path = "/status";
|
|
expectedBodyRegex = "true";
|
|
skipTlsVerification = true;
|
|
useHttps = true;
|
|
};
|
|
};
|
|
virtualHosts.${kanidmDomain} = {
|
|
forceSSL = true;
|
|
useACMEWildcardHost = true;
|
|
locations."/".proxyPass = "https://kanidm";
|
|
# Allow using self-signed certs to satisfy kanidm's requirement
|
|
# for TLS connections. (Although this is over wireguard anyway)
|
|
extraConfig = ''
|
|
proxy_ssl_verify off;
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
environment.persistence."/persist".directories = [
|
|
{
|
|
directory = "/var/lib/kanidm";
|
|
user = "kanidm";
|
|
group = "kanidm";
|
|
mode = "0700";
|
|
}
|
|
];
|
|
|
|
services.kanidm = {
|
|
package = pkgs.kanidm.withSecretProvisioning;
|
|
enableServer = true;
|
|
serverSettings = {
|
|
domain = kanidmDomain;
|
|
origin = "https://${kanidmDomain}";
|
|
tls_chain = config.age.secrets."kanidm-self-signed.crt".path;
|
|
tls_key = config.age.secrets."kanidm-self-signed.key".path;
|
|
bindaddress = "0.0.0.0:${toString kanidmPort}";
|
|
trust_x_forward_for = true;
|
|
};
|
|
|
|
enableClient = true;
|
|
clientSettings = {
|
|
uri = config.services.kanidm.serverSettings.origin;
|
|
verify_ca = true;
|
|
verify_hostnames = true;
|
|
};
|
|
|
|
provision = {
|
|
enable = true;
|
|
adminPasswordFile = config.age.secrets.kanidm-admin-password.path;
|
|
idmAdminPasswordFile = config.age.secrets.kanidm-idm-admin-password.path;
|
|
|
|
inherit (globals.kanidm) persons;
|
|
|
|
# Immich
|
|
groups."immich.access" = { };
|
|
systems.oauth2.immich = {
|
|
displayName = "Immich";
|
|
originUrl = [
|
|
"https://${globals.services.immich.domain}/auth/login"
|
|
"https://${globals.services.immich.domain}/api/oauth/mobile-redirect"
|
|
];
|
|
originLanding = "https://${globals.services.immich.domain}/";
|
|
basicSecretFile = config.age.secrets.kanidm-oauth2-immich.path;
|
|
preferShortUsername = true;
|
|
scopeMaps."immich.access" = [
|
|
"openid"
|
|
"email"
|
|
"profile"
|
|
];
|
|
};
|
|
|
|
# Firezone
|
|
groups."firezone.access" = { };
|
|
systems.oauth2.firezone = {
|
|
displayName = "Firezone VPN";
|
|
# NOTE: state: both uuids are runtime values
|
|
originUrl = [
|
|
"https://${globals.services.firezone.domain}/50e16678-6e95-49e2-b59e-d70d0e658843/sign_in/providers/fc8afaa3-ce60-4073-9cae-81dec9453a2d/handle_callback"
|
|
"https://${globals.services.firezone.domain}/50e16678-6e95-49e2-b59e-d70d0e658843/settings/identity_providers/openid_connect/fc8afaa3-ce60-4073-9cae-81dec9453a2d/handle_callback"
|
|
];
|
|
originLanding = "https://${globals.services.firezone.domain}/";
|
|
basicSecretFile = config.age.secrets.kanidm-oauth2-firezone.path;
|
|
preferShortUsername = true;
|
|
scopeMaps."firezone.access" = [
|
|
"openid"
|
|
"email"
|
|
"profile"
|
|
];
|
|
};
|
|
|
|
# Mealie
|
|
groups."mealie.access" = { };
|
|
groups."mealie.admins" = { };
|
|
systems.oauth2.mealie = {
|
|
displayName = "Mealie";
|
|
originUrl = "https://${globals.services.mealie.domain}/login";
|
|
originLanding = "https://${globals.services.mealie.domain}/";
|
|
basicSecretFile = config.age.secrets.kanidm-oauth2-mealie.path;
|
|
preferShortUsername = true;
|
|
scopeMaps."mealie.access" = [
|
|
"openid"
|
|
"email"
|
|
"profile"
|
|
"groups"
|
|
];
|
|
};
|
|
|
|
# Paperless
|
|
groups."paperless.access" = { };
|
|
systems.oauth2.paperless = {
|
|
displayName = "Paperless";
|
|
originUrl = "https://${globals.services.paperless.domain}/accounts/oidc/kanidm/login/callback/";
|
|
originLanding = "https://${globals.services.paperless.domain}/";
|
|
basicSecretFile = config.age.secrets.kanidm-oauth2-paperless.path;
|
|
preferShortUsername = true;
|
|
scopeMaps."paperless.access" = [
|
|
"openid"
|
|
"email"
|
|
"profile"
|
|
];
|
|
};
|
|
|
|
# Grafana
|
|
groups."grafana.access" = { };
|
|
groups."grafana.editors" = { };
|
|
groups."grafana.admins" = { };
|
|
groups."grafana.server-admins" = { };
|
|
systems.oauth2.grafana = {
|
|
displayName = "Grafana";
|
|
originUrl = "https://${globals.services.grafana.domain}/login/generic_oauth";
|
|
originLanding = "https://${globals.services.grafana.domain}/";
|
|
basicSecretFile = config.age.secrets.kanidm-oauth2-grafana.path;
|
|
preferShortUsername = true;
|
|
scopeMaps."grafana.access" = [
|
|
"openid"
|
|
"email"
|
|
"profile"
|
|
];
|
|
claimMaps.groups = {
|
|
joinType = "array";
|
|
valuesByGroup = {
|
|
"grafana.editors" = [ "editor" ];
|
|
"grafana.admins" = [ "admin" ];
|
|
"grafana.server-admins" = [ "server_admin" ];
|
|
};
|
|
};
|
|
};
|
|
|
|
# Forgejo
|
|
groups."forgejo.access" = { };
|
|
groups."forgejo.admins" = { };
|
|
systems.oauth2.forgejo = {
|
|
displayName = "Forgejo";
|
|
originUrl = "https://${globals.services.forgejo.domain}/user/oauth2/kanidm/callback";
|
|
originLanding = "https://${globals.services.forgejo.domain}/";
|
|
basicSecretFile = config.age.secrets.kanidm-oauth2-forgejo.path;
|
|
scopeMaps."forgejo.access" = [
|
|
"openid"
|
|
"email"
|
|
"profile"
|
|
];
|
|
# XXX: PKCE is currently not supported by gitea/forgejo,
|
|
# see https://github.com/go-gitea/gitea/issues/21376.
|
|
allowInsecureClientDisablePkce = true;
|
|
preferShortUsername = true;
|
|
claimMaps.groups = {
|
|
joinType = "array";
|
|
valuesByGroup."forgejo.admins" = [ "admin" ];
|
|
};
|
|
};
|
|
|
|
# Web Sentinel
|
|
groups."web-sentinel.access" = { };
|
|
groups."web-sentinel.adguardhome" = { };
|
|
groups."web-sentinel.openwebui" = { };
|
|
groups."web-sentinel.analytics" = { };
|
|
systems.oauth2.web-sentinel = {
|
|
displayName = "Web Sentinel";
|
|
originUrl = "https://oauth2.${globals.domains.me}/oauth2/callback";
|
|
originLanding = "https://oauth2.${globals.domains.me}/";
|
|
basicSecretFile = config.age.secrets.kanidm-oauth2-web-sentinel.path;
|
|
preferShortUsername = true;
|
|
scopeMaps."web-sentinel.access" = [
|
|
"openid"
|
|
"email"
|
|
];
|
|
claimMaps.groups = {
|
|
joinType = "array";
|
|
valuesByGroup."web-sentinel.adguardhome" = [ "access_adguardhome" ];
|
|
valuesByGroup."web-sentinel.openwebui" = [ "access_openwebui" ];
|
|
valuesByGroup."web-sentinel.analytics" = [ "access_analytics" ];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
systemd.services.kanidm.serviceConfig.RestartSec = "60"; # Retry every minute
|
|
}
|