From 4e8d6c128a8ff92e5fe292d3d7d798ad3e0f6b12 Mon Sep 17 00:00:00 2001 From: Lorenzo Good Date: Wed, 31 Dec 2025 20:22:58 -0600 Subject: [PATCH] Add lldap service. Add LDAP service, to allow me to more easily add users to authelia, and other SSO solutions. --- common/services/lldap.nix | 75 ++++++++++++++++++++++ machines/lebesgue/config/configuration.nix | 8 +++ machines/lebesgue/config/secrets.nix | 2 + machines/lebesgue/config/state.nix | 2 + machines/lebesgue/secrets/main.yaml | 7 +- 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 common/services/lldap.nix diff --git a/common/services/lldap.nix b/common/services/lldap.nix new file mode 100644 index 0000000..e71bf9b --- /dev/null +++ b/common/services/lldap.nix @@ -0,0 +1,75 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (lib) mkEnableOption types mkIf mkOption; + + cfg = config.foehammer.services.lldap; +in { + options.foehammer.services.lldap = { + enable = mkEnableOption "Enable LLDAP Server"; + + url = mkOption { + type = types.str; + }; + + port = mkOption { + type = lib.types.port; + default = 8226; + description = '' + What external port to serve over. + ''; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + }; + + jwtSecretFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Path to your JWT secret used during identity verificaton. + ''; + }; + + adminUserPasswordFile = mkOption { + type = types.nullOr types.path; + default = null; + }; + + base_dn = mkOption { + type = types.str; + example = "dc=example,dc=com"; + }; + }; + + config = mkIf cfg.enable { + services.lldap = { + enable = true; + environmentFile = cfg.environmentFile; + + settings = { + # Base setup. + http_port = cfg.port; + http_url = cfg.url; + ldap_base_dn = cfg.base_dn; + jwt_secret_file = cfg.jwtSecretFile; + + # Reproducable admin password. + force_ldap_user_pass_reset = "always"; + ldap_user_pass_file = cfg.adminUserPasswordFile; + }; + }; + + users.users.lldap = { + isSystemUser = true; + createHome = true; + group = "lldap"; + }; + users.groups.lldap = {}; + }; +} diff --git a/machines/lebesgue/config/configuration.nix b/machines/lebesgue/config/configuration.nix index 1c1811c..ddf9a9b 100644 --- a/machines/lebesgue/config/configuration.nix +++ b/machines/lebesgue/config/configuration.nix @@ -33,6 +33,14 @@ storageEncryptionKeyFile = config.sops.secrets.authelia-storage-encryption.path; }; + services.lldap = { + enable = true; + url = "https://lldap.foehammer.me"; + base_dn = "dc=foehammer,dc=me"; + + adminUserPasswordFile = config.sops.secrets.lldap-admin-password.path; + }; + services.vaultwarden = { enable = true; domain = "https://passwords.foehammer.me"; diff --git a/machines/lebesgue/config/secrets.nix b/machines/lebesgue/config/secrets.nix index f8538b9..2cbf4d2 100644 --- a/machines/lebesgue/config/secrets.nix +++ b/machines/lebesgue/config/secrets.nix @@ -18,6 +18,8 @@ restic-password = {owner = "restic";}; restic-repository = {owner = "restic";}; + lldap-admin-password.owner = "lldap"; + authelia-jwtsecret = autheliaSecret; authelia-oidc-privkey = autheliaSecret; authelia-oidc-hmac = autheliaSecret; diff --git a/machines/lebesgue/config/state.nix b/machines/lebesgue/config/state.nix index 26efd42..f593234 100644 --- a/machines/lebesgue/config/state.nix +++ b/machines/lebesgue/config/state.nix @@ -13,6 +13,8 @@ "/var/lib/authelia-main" "/var/lib/caddy/.local/share/caddy" "/var/lib/vaultwarden" + + { directory = "/var/lib/private/lldap"; user = "lldap"; group = "lldap"; mode = "0700"; } ]; files = [ diff --git a/machines/lebesgue/secrets/main.yaml b/machines/lebesgue/secrets/main.yaml index e7208b5..c0e0eeb 100644 --- a/machines/lebesgue/secrets/main.yaml +++ b/machines/lebesgue/secrets/main.yaml @@ -4,6 +4,7 @@ vaultwarden-env: ENC[AES256_GCM,data:A1iRHxFxgI5P8DtsXQa1KvEKKnF+qZY7LVuJba00CLj restic-password: ENC[AES256_GCM,data:Ympe5/hJxOzJp7IeJy5mZy0fMIrnV+3cWJo1uKwbHHDJ0G4TNivMNrHEdff6CjVnAbkVgjkR90z1FJOpExd+KQ==,iv:CRJaA3fTG8B/qBDkwctgma4DaGDjoyk4eX6/SynIcLE=,tag:pJW45ijV+wVTR+4IRnLcsw==,type:str] restic-repository: ENC[AES256_GCM,data:KkFaam8iltY9nz89sVxk4u0xZ46Sq+7UsOY/9wieASD5A2FRruou7BiudX9X4hRA2RMTctO8aqYkrg==,iv:mIZ9z7BJV9s+wSiVMnzYAWM1/zsa6C+RCK1UhSiJVxI=,tag:S7tedxcfd/UaQ5hMEYfBVQ==,type:str] restic-env: ENC[AES256_GCM,data:KW9ma36zmHJF3xBStpoStDRQqg34wlMJMVSYfbLSnWq26R6e6eGf3+kTVkobhn/bqL6ZYi8ctlyvDS8IOz8VveYogsqxZ7/LK62mA0d9I3xEZMG7eNQ8M1PdeZ9RqAUgFJU=,iv:RxwvZ2vNuwmUc3haK2Ub8vHk9UQhjepLCwsfIcSJg9s=,tag:Tvq2RDh8mJ3jGhmpL1uuCA==,type:str] +lldap-admin-password: ENC[AES256_GCM,data:SKs/2iM7J9xzpxCjRnPu23j7UTWtfHbzL/NYcWOv59FUu73cO8i2kR7T4ITFz4JVF7CfSa7WBHL6j1arJeJUOIUjKTZaTVHHjGVT4xROeO04ZZHc8JU23CjRheGqrEftTY+mvmlRIT+SOx48eC25gsu52T4eUTW4JXjT3T5grhw+C2S0A71X7tmRUt0zfzEoavDzF2SDMQXKOrdX9F2Ekyo5kI4Yvn5QH99jWWx6UgJhLpLIwmkJSg+R34UpzPgakz2FAXcW6oId1RMklWJQPtsyO1S/LcWW+E1NETrua5lB08oLm4R3FY7EWl2hOqdTeUGL+IeTSOAuGLRVPTD5Vg==,iv:R8C4sBlAe3+W+IvmEODKMuccSxedmat6OdzTsp0ZUAw=,tag:MutQhUP/0SdopoH8oz465g==,type:str] sops: age: - recipient: age1kjy9wym6cmz6wqmewws4ledsne47c0e4sr0ksmm66rff3u2f6u3qxvnyg9 @@ -15,8 +16,8 @@ sops: L2VhMXV4WityYUFDZytxVTJHOXZGVVkKgbKR56dsru6U7I4KpnxfxQsswFwJsTM7 8dzAaFl30mdRwFIH9kzdY3XxyYsJ0Yr0x3xwJ8mI4rjgpI8S9ihJFw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-06-04T21:04:47Z" - mac: ENC[AES256_GCM,data:fGTVTDhqVNLQJaZyBFhBEauW/Cnb/V57aHOcaeODNeA9g1oZiC3IzUkpRVnEC+gPx4KLDrBwuCk7Au/TarVpFVK+nyqcwrDgr2RsWtVDP0UQH/+8G8PkASxnMnTp/oQnvEKGAbySfGelqEQkDhbMiR7GaP99lJcIoIQ/wG87peA=,iv:+NJnPQmh6VYzDu/UoGv1YHVGfMocKMdX5XxZG6FmS90=,tag:vnHzhvOQOw0U7BwNJKA0kw==,type:str] + lastmodified: "2026-01-01T02:26:01Z" + mac: ENC[AES256_GCM,data:n/cjgg9wTdz6OE5ryijYIdG8f14yB+tBehnGVu+5f8mmQghFo3EdDaYHOQi52i+M6sV7RwdwtZW2qCgLZaqJL/3IAqwDfyoKiyKaovfifJhv3gP3atRMQ4xxd0Ffy7SoQ/NEpknMFJYqyY+fvSCyefbBgzKSpVO9tTixvwuDEsM=,iv:WGoX+46zdcMqkA/thfF0JYm19IqQ85P/2k3W9AWS0Zc=,tag:xDsEK1AEfFWNvNar6M88gQ==,type:str] pgp: - created_at: "2025-02-03T18:58:54Z" enc: |- @@ -30,4 +31,4 @@ sops: -----END PGP MESSAGE----- fp: A972C2063F4F2554 unencrypted_suffix: _unencrypted - version: 3.10.2 + version: 3.11.0