{ config, lib, pkgs, ... }: let cfg = config.sydnix.deertopia.lldap.pam; in { options.sydnix.deertopia.lldap.pam = { enable = lib.mkEnableOption "LLDAP PAM integration"; }; # See https://github.com/lldap/lldap/blob/main/example_configs/pam/README.md. # Required imperative configuration: you will need to add the following custom # attributes to the user schema in the LLDAP web UI. # # • uidNumber (integer) # • gidNumber (integer, multiple values) # • homeDirectory (string) # • unixShell (string) # • sshPublicKey (string) (only if you’re setting up SSH Public Key Sync) config = lib.mkIf cfg.enable { sydnix.sops.secrets = let e = { mode = "0440"; owner = "sssd"; group = "sssd"; }; in { sssd-environment = {}; }; # TODO: The existence of a dynamic set of users leads to some complexities # when combined with Impermanence. Static users (i.e. those defined in the # NixOS config) shall opt in to Impermanence via the Home-manager setting, # but "dynamic" users (i.e. those per LDAP/PAM) should be persisted # unconditionally. Implementing this behaviour takes quite the hack: # # • /home is persisted. # # • A impersistent directory /transient-home is created. # # • "Dynamic" users are assigned subdirectories of /home like usual. # Since /home is persisted, so are the users' individual home # directories. # # • The home directories of "static" users (that are opted in to # Impermanence) are created at /transient-home/«user» and bind-mounted # to /home/«user». security.pam.services."ldap".makeHomeDir = true; # For synchronizations of SSH keys. services.openssh.settings = { AuthorizedKeysCommand = lib.getExe' pkgs.sssd "sss_ssh_authorizedkeys"; AuthorizedKeysCommandUser = "nobody"; }; services.sssd = let inherit (config.sydnix.deertopia.lldap) baseDN; ldaps-port = config.services.lldap.settings.ldaps_options.port; in { enable = true; environmentFile = "/run/secrets/sssd-environment"; config = '' [sssd] config_file_version = 2 # Change the domain below. It must match with the one in the [domain/] # part domains = deertopia.net [nss] [pam] # Put the same domain here [domain/deertopia.net] id_provider = ldap auth_provider = ldap chpass_provider = ldap ldap_schema = rfc2307 # Place your LDAP server url here ldap_uri = ldaps://deertopia.net:${builtins.toString ldaps-port}/ # Put your LDAP dc here ldap_search_base = ${baseDN} # Bind credentials # Bind user username (Should be in group lldap_strict_readonly) ldap_default_bind_dn = uid=sssd,ou=people,${baseDN} # Bind user password. Defined by `services.sssd.environmentFile`. ldap_default_authtok = $SSSD_LDAP_DEFAULT_AUTHTOK # TLS settings ldap_tls_reqcert = demand # Put the certificate you generate for LDAPS here ldap_tls_cacert = ${./cert.pem} # User mappings # Put your LDAP dc here ldap_user_search_base = ou=people,${baseDN} ldap_user_object_class = posixAccount ldap_user_name = uid ldap_user_gecos = uid ldap_user_uid_number = uidNumber ldap_user_gid_number = gidNumber ldap_user_home_directory = homeDirectory ldap_user_shell = unixShell # Uncomment for SSH Key Sync setup ldap_user_ssh_public_key = sshPublicKey # Group mappings # Put your LDAP dc here ldap_group_search_base = ou=groups,${baseDN} ldap_group_object_class = groupOfUniqueNames ldap_group_name = cn ldap_group_member = uniqueMember access_provider = permit cache_credentials = true ''; }; }; }