From ca0e3fd6295a4008add87879cbfc0ec07c81e676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torjus=20H=C3=A5kestad?= Date: Sun, 8 Feb 2026 00:13:59 +0100 Subject: [PATCH] kanidm01: add kanidm authentication server - New test-tier VM at 10.69.13.23 with role=auth - Kanidm 1.8 server with HTTPS (443) and LDAPS (636) - ACME certificate from internal CA (auth.home.2rjus.net) - Provisioned groups: admins, users, ssh-users - Provisioned user: torjus - Daily backups at 22:00 (7 versions) - Prometheus monitoring scrape target Co-Authored-By: Claude Opus 4.5 --- flake.nix | 9 ++++ hosts/kanidm01/configuration.nix | 77 ++++++++++++++++++++++++++++++ hosts/kanidm01/default.nix | 5 ++ services/kanidm/default.nix | 61 +++++++++++++++++++++++ terraform/vault/hosts-generated.tf | 6 +++ terraform/vault/secrets.tf | 6 +++ terraform/vms.tf | 7 +++ 7 files changed, 171 insertions(+) create mode 100644 hosts/kanidm01/configuration.nix create mode 100644 hosts/kanidm01/default.nix create mode 100644 services/kanidm/default.nix diff --git a/flake.nix b/flake.nix index 7640da0..e19feb7 100644 --- a/flake.nix +++ b/flake.nix @@ -182,6 +182,15 @@ ./hosts/ns1 ]; }; + kanidm01 = nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit inputs self; + }; + modules = commonModules ++ [ + ./hosts/kanidm01 + ]; + }; }; packages = forAllSystems ( { pkgs }: diff --git a/hosts/kanidm01/configuration.nix b/hosts/kanidm01/configuration.nix new file mode 100644 index 0000000..7eca883 --- /dev/null +++ b/hosts/kanidm01/configuration.nix @@ -0,0 +1,77 @@ +{ + config, + lib, + pkgs, + ... +}: + +{ + imports = [ + ../template2/hardware-configuration.nix + + ../../system + ../../common/vm + ../../services/kanidm + ]; + + # Host metadata + homelab.host = { + tier = "test"; + role = "auth"; + }; + + # DNS CNAME for auth.home.2rjus.net + homelab.dns.cnames = [ "auth" ]; + + # Enable Vault integration + vault.enable = true; + + # Enable remote deployment via NATS + homelab.deploy.enable = true; + + nixpkgs.config.allowUnfree = true; + boot.loader.grub.enable = true; + boot.loader.grub.device = "/dev/vda"; + + networking.hostName = "kanidm01"; + networking.domain = "home.2rjus.net"; + networking.useNetworkd = true; + networking.useDHCP = false; + services.resolved.enable = true; + networking.nameservers = [ + "10.69.13.5" + "10.69.13.6" + ]; + + systemd.network.enable = true; + systemd.network.networks."ens18" = { + matchConfig.Name = "ens18"; + address = [ + "10.69.13.23/24" + ]; + routes = [ + { Gateway = "10.69.13.1"; } + ]; + linkConfig.RequiredForOnline = "routable"; + }; + time.timeZone = "Europe/Oslo"; + + nix.settings.experimental-features = [ + "nix-command" + "flakes" + ]; + nix.settings.tarball-ttl = 0; + environment.systemPackages = with pkgs; [ + vim + wget + git + ]; + + # Open ports in the firewall. + # networking.firewall.allowedTCPPorts = [ ... ]; + # networking.firewall.allowedUDPPorts = [ ... ]; + # Or disable the firewall altogether. + networking.firewall.enable = false; + + system.stateVersion = "25.11"; # Did you read the comment? +} \ No newline at end of file diff --git a/hosts/kanidm01/default.nix b/hosts/kanidm01/default.nix new file mode 100644 index 0000000..57ed4b4 --- /dev/null +++ b/hosts/kanidm01/default.nix @@ -0,0 +1,5 @@ +{ ... }: { + imports = [ + ./configuration.nix + ]; +} \ No newline at end of file diff --git a/services/kanidm/default.nix b/services/kanidm/default.nix new file mode 100644 index 0000000..e5cb514 --- /dev/null +++ b/services/kanidm/default.nix @@ -0,0 +1,61 @@ +{ config, lib, pkgs, ... }: +{ + services.kanidm = { + package = pkgs.kanidmWithSecretProvisioning_1_8; + enableServer = true; + serverSettings = { + domain = "home.2rjus.net"; + origin = "https://auth.home.2rjus.net"; + bindaddress = "0.0.0.0:443"; + ldapbindaddress = "0.0.0.0:636"; + tls_chain = "/var/lib/acme/auth.home.2rjus.net/fullchain.pem"; + tls_key = "/var/lib/acme/auth.home.2rjus.net/key.pem"; + online_backup = { + path = "/var/lib/kanidm/backups"; + schedule = "00 22 * * *"; + versions = 7; + }; + }; + + # Provisioning - initial users/groups + provision = { + enable = true; + idmAdminPasswordFile = config.vault.secrets.kanidm-idm-admin.outputDir; + + groups = { + admins = { }; + users = { }; + ssh-users = { }; + }; + + persons.torjus = { + displayName = "Torjus"; + groups = [ "admins" "users" "ssh-users" ]; + }; + }; + }; + + # Grant kanidm access to ACME certificates + users.users.kanidm.extraGroups = [ "acme" ]; + + # ACME certificate from internal CA + security.acme.certs."auth.home.2rjus.net" = { + listenHTTP = ":80"; + reloadServices = [ "kanidm" ]; + }; + + # Vault secret for idm_admin password + vault.secrets.kanidm-idm-admin = { + secretPath = "kanidm/idm-admin-password"; + extractKey = "password"; + }; + + # Monitoring scrape target + homelab.monitoring.scrapeTargets = [ + { + job_name = "kanidm"; + port = 443; + scheme = "https"; + } + ]; +} diff --git a/terraform/vault/hosts-generated.tf b/terraform/vault/hosts-generated.tf index f485f59..6286e1a 100644 --- a/terraform/vault/hosts-generated.tf +++ b/terraform/vault/hosts-generated.tf @@ -33,6 +33,12 @@ locals { "secret/data/shared/homelab-deploy/*", ] } + "kanidm01" = { + paths = [ + "secret/data/hosts/kanidm01/*", + "secret/data/kanidm/*", + ] + } } diff --git a/terraform/vault/secrets.tf b/terraform/vault/secrets.tf index 8f5556f..fcc4228 100644 --- a/terraform/vault/secrets.tf +++ b/terraform/vault/secrets.tf @@ -102,6 +102,12 @@ locals { auto_generate = false data = { nkey = var.homelab_deploy_admin_deployer_nkey } } + + # Kanidm idm_admin password + "kanidm/idm-admin-password" = { + auto_generate = true + password_length = 32 + } } } diff --git a/terraform/vms.tf b/terraform/vms.tf index fdd47be..57db81e 100644 --- a/terraform/vms.tf +++ b/terraform/vms.tf @@ -72,6 +72,13 @@ locals { disk_size = "20G" vault_wrapped_token = "s.b6ge0KMtNQctdKkvm0RNxGdt" } + "kanidm01" = { + ip = "10.69.13.23/24" + cpu_cores = 2 + memory = 2048 + disk_size = "20G" + vault_wrapped_token = "s.OOqjEECeIV7dNgCS6jNmyY3K" + } } # Compute VM configurations with defaults applied