It appears I can get app passwords with kanidm and ldap so just going to a more stable, probably supported setup, should be good.
341 lines
11 KiB
Nix
341 lines
11 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
domain = "login.kaareskovgaard.net";
|
|
bootstrapping = config.khscodes."security.kaareskovgaard.net".bootstrap.enable;
|
|
openbaoDomain = config.khscodes.infrastructure.openbao.domain;
|
|
openbaoAllowedRedirectUrls = [
|
|
"https://${openbaoDomain}/ui/vault/auth/kanidm/oidc/callback"
|
|
"https://${openbaoDomain}/kanidm/callback"
|
|
];
|
|
kanidm-reset-password = pkgs.writeShellApplication {
|
|
name = "kanidm-reset-password";
|
|
runtimeInputs = [
|
|
config.services.kanidm.package
|
|
pkgs.jq
|
|
pkgs.gnugrep
|
|
pkgs.expect
|
|
];
|
|
text = ''
|
|
username="''${1:-}"
|
|
if [[ "$username" == "" ]]; then
|
|
>&2 echo "Usage kanidm-reset-password <username>"
|
|
exit 1
|
|
fi
|
|
echo "Resetting password for idm_admin, please provide sudo password"
|
|
password="$(sudo -u kanidm kanidmd recover-account -c /etc/kanidm/server.toml -o json idm_admin 2> /dev/null | grep '^{' | jq --raw-output '.password')"
|
|
expect <<EOD
|
|
spawn kanidm login --url https://login.kaareskovgaard.net --name idm_admin
|
|
expect "Enter password"
|
|
send "$password\n"
|
|
expect eof
|
|
EOD
|
|
kanidm person credential create-reset-token --url https://login.kaareskovgaard.net "$username"
|
|
trap "kanidm logout --url https://login.kaareskovgaard.net" EXIT
|
|
'';
|
|
|
|
};
|
|
in
|
|
{
|
|
imports = [ ./kanidm_application.nix ];
|
|
config = {
|
|
khscodes.security.kanidm.applications = {
|
|
openbao = {
|
|
allowedRedirectUris = openbaoAllowedRedirectUrls;
|
|
landingUri = "https://${openbaoDomain}";
|
|
displayName = "OpenBAO";
|
|
scopeMaps = {
|
|
"openbao_admin" = [
|
|
"profile"
|
|
"email"
|
|
"openid"
|
|
];
|
|
};
|
|
claimMaps.groups = {
|
|
joinType = "array";
|
|
valuesByGroup = {
|
|
"openbao_admin" = [
|
|
"openbao_writer"
|
|
"openbao_cli_writer"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
openbao-cli = {
|
|
terranixName = "openbao_cli";
|
|
allowedRedirectUris = [ "http://localhost:8250/oidc/callback" ];
|
|
landingUri = "http://localhost:8250";
|
|
displayName = "OpenBAO CLI";
|
|
scopeMaps = {
|
|
"openbao_admin" = [
|
|
"profile"
|
|
"email"
|
|
"openid"
|
|
];
|
|
};
|
|
claimMaps.groups = {
|
|
joinType = "array";
|
|
valuesByGroup = {
|
|
"openbao_admin" = [
|
|
"openbao_writer"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
monitoring = {
|
|
allowedRedirectUris = [ "https://monitoring.kaareskovgaard.net/login/generic_oauth" ];
|
|
landingUri = "http://monitoring.kaareskovgaard.net";
|
|
displayName = "Monitoring";
|
|
scopeMaps = {
|
|
"openbao_admin" = [
|
|
"profile"
|
|
"email"
|
|
"openid"
|
|
];
|
|
};
|
|
};
|
|
forgejo = {
|
|
allowedRedirectUris = [ "https://kas.codes/user/oauth2/Kanidm/callback" ];
|
|
landingUri = "http://kas.codes";
|
|
displayName = "KAS: Codes";
|
|
scopeMaps = {
|
|
"forgejo_user" = [
|
|
"profile"
|
|
"email"
|
|
"openid"
|
|
];
|
|
};
|
|
claimMaps.groups = {
|
|
joinType = "array";
|
|
valuesByGroup = {
|
|
"forgejo_comitter" = [
|
|
"comitter"
|
|
];
|
|
"forgejo_admin" = [
|
|
"admin"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
stalwart = {
|
|
allowedRedirectUris = [ "https://mail.kaareskovgaard.net/index.php/login/oauth" ];
|
|
landingUri = "https://mail.kaareskovgaard.net";
|
|
displayName = "Mail";
|
|
allowInsecureClientDisablePkce = true;
|
|
scopeMaps = {
|
|
"mail_user" = [
|
|
"profile"
|
|
"email"
|
|
"openid"
|
|
];
|
|
};
|
|
};
|
|
};
|
|
services.kanidm = {
|
|
enableServer = true;
|
|
# Verify upgrade will be successful by running `kanidmd domain upgrade-check` before bumping package version.
|
|
package = pkgs.kanidmWithSecretProvisioning_1_6;
|
|
serverSettings = {
|
|
inherit domain;
|
|
tls_chain = "${config.security.acme.certs.${domain}.directory}/fullchain.pem";
|
|
tls_key = "${config.security.acme.certs.${domain}.directory}/key.pem";
|
|
origin = "https://${domain}";
|
|
trust_x_forward_for = true;
|
|
};
|
|
provision = {
|
|
enable = true;
|
|
idmAdminPasswordFile = null;
|
|
adminPasswordFile = null;
|
|
acceptInvalidCerts = true;
|
|
persons.khs = {
|
|
present = true;
|
|
mailAddresses = [
|
|
"kaare@kaareskovgaard.net"
|
|
"kaare@agerlin-skovgaard.dk"
|
|
"kaare@agerlinskovgaard.dk"
|
|
];
|
|
legalName = "Kaare Skovgaard";
|
|
displayName = "khs";
|
|
};
|
|
groups.openbao_admin = {
|
|
present = true;
|
|
members = [ "khs" ];
|
|
};
|
|
groups.forgejo_user = {
|
|
present = true;
|
|
members = [ "khs" ];
|
|
};
|
|
groups.forgejo_comitter = {
|
|
present = true;
|
|
members = [ "khs" ];
|
|
};
|
|
groups.forgejo_admin = {
|
|
present = true;
|
|
members = [ "khs" ];
|
|
};
|
|
groups.mail_user = {
|
|
present = true;
|
|
members = [ "khs" ];
|
|
};
|
|
};
|
|
};
|
|
|
|
khscodes.infrastructure.provisioning.post.modules = [
|
|
(
|
|
{ ... }:
|
|
{
|
|
khscodes.vault = {
|
|
enable = true;
|
|
mount.kanidm = {
|
|
path = "kanidm";
|
|
type = "kv";
|
|
options = {
|
|
version = "2";
|
|
};
|
|
description = "Secrets used for kanidm";
|
|
};
|
|
};
|
|
}
|
|
)
|
|
# Sets up OIDC authentication within OpenBAO.
|
|
# OpenBAO queries the openid url for its configuration when adding it, so it is not possible,
|
|
# to add this before
|
|
(
|
|
if bootstrapping then
|
|
{ }
|
|
else
|
|
{
|
|
resource.vault_jwt_auth_backend.kanidm_cli = {
|
|
description = "Kanidm cli auth backend";
|
|
path = "oidc";
|
|
type = "oidc";
|
|
oidc_discovery_url = "https://${domain}/oauth2/openid/openbao-cli";
|
|
oidc_client_id = "openbao-cli";
|
|
oidc_client_secret = "\${ resource.random_password.openbao_cli_secret.result }";
|
|
default_role = "kanidm_cli_writer";
|
|
jwt_supported_algs = [
|
|
"ES256"
|
|
];
|
|
tune = [
|
|
{
|
|
listing_visibility = "hidden";
|
|
default_lease_ttl = "2h";
|
|
max_lease_ttl = "2h";
|
|
token_type = "default-service";
|
|
passthrough_request_headers = [ ];
|
|
allowed_response_headers = [ ];
|
|
audit_non_hmac_request_keys = [ ];
|
|
audit_non_hmac_response_keys = [ ];
|
|
}
|
|
];
|
|
};
|
|
resource.vault_jwt_auth_backend.kanidm = {
|
|
description = "Kanidm auth backend";
|
|
path = "kanidm";
|
|
type = "oidc";
|
|
oidc_discovery_url = "https://${domain}/oauth2/openid/openbao";
|
|
oidc_client_id = "openbao";
|
|
oidc_client_secret = "\${ resource.random_password.openbao_secret.result }";
|
|
default_role = "kanidm_writer";
|
|
jwt_supported_algs = [
|
|
"ES256"
|
|
];
|
|
tune = [
|
|
{
|
|
listing_visibility = "unauth";
|
|
default_lease_ttl = "2h";
|
|
max_lease_ttl = "2h";
|
|
token_type = "default-service";
|
|
passthrough_request_headers = [ ];
|
|
allowed_response_headers = [ ];
|
|
audit_non_hmac_request_keys = [ ];
|
|
audit_non_hmac_response_keys = [ ];
|
|
}
|
|
];
|
|
};
|
|
|
|
resource.vault_jwt_auth_backend_role.kanidm_cli_writer = {
|
|
backend = "\${ resource.vault_jwt_auth_backend.kanidm_cli.path }";
|
|
role_name = "kanidm_cli_writer";
|
|
bound_audiences = [ "openbao-cli" ];
|
|
allowed_redirect_uris = [ "http://localhost:8250/oidc/callback" ];
|
|
user_claim = "sub";
|
|
token_policies = [ "writer" ];
|
|
groups_claim = "groups";
|
|
oidc_scopes = [
|
|
"openid"
|
|
"profile"
|
|
"email"
|
|
];
|
|
};
|
|
|
|
resource.vault_jwt_auth_backend_role.kanidm_writer = {
|
|
backend = "\${ resource.vault_jwt_auth_backend.kanidm.path }";
|
|
role_name = "kanidm_writer";
|
|
bound_audiences = [ "openbao" ];
|
|
allowed_redirect_uris = openbaoAllowedRedirectUrls;
|
|
user_claim = "sub";
|
|
token_policies = [ "writer" ];
|
|
groups_claim = "groups";
|
|
oidc_scopes = [
|
|
"openid"
|
|
"profile"
|
|
"email"
|
|
];
|
|
};
|
|
|
|
resource.vault_identity_group.kanidm_writer = {
|
|
name = "kanidm_writer";
|
|
policies = [ "writer" ];
|
|
type = "external";
|
|
};
|
|
|
|
resource.vault_identity_group.kanidm_cli_writer = {
|
|
name = "kanidm_cli_writer";
|
|
policies = [ "writer" ];
|
|
type = "external";
|
|
};
|
|
|
|
resource.vault_identity_group_alias.oidc_writer = {
|
|
name = "openbao_cli_writer";
|
|
mount_accessor = "\${ vault_jwt_auth_backend.kanidm_cli.accessor }";
|
|
canonical_id = "\${ vault_identity_group.kanidm_cli_writer.id }";
|
|
};
|
|
|
|
resource.vault_identity_group_alias.kanidm_writer = {
|
|
name = "openbao_writer";
|
|
mount_accessor = "\${ vault_jwt_auth_backend.kanidm.accessor }";
|
|
canonical_id = "\${ vault_identity_group.kanidm_writer.id }";
|
|
};
|
|
|
|
resource.vault_policy.writer = {
|
|
name = "writer";
|
|
|
|
policy = ''
|
|
path "*" {
|
|
capabilities = ["create", "update", "patch", "read", "delete", "list"]
|
|
}
|
|
'';
|
|
};
|
|
}
|
|
)
|
|
];
|
|
security.acme.certs.${domain}.reloadServices = [ "kanidm.service" ];
|
|
# Allow kanidm to read the certificate file
|
|
users.groups.nginx.members = [ "kanidm" ];
|
|
|
|
khscodes.services.nginx.virtualHosts.${domain} = {
|
|
locations."/" = {
|
|
proxyPass = "https://${config.services.kanidm.serverSettings.bindaddress}/";
|
|
recommendedProxySettings = true;
|
|
};
|
|
};
|
|
|
|
environment.systemPackages = [
|
|
kanidm-reset-password
|
|
];
|
|
};
|
|
}
|