Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NixOS, Home-Manager, and Kanidm Unixd #2698

Open
TheRealGramdalf opened this issue Apr 8, 2024 · 4 comments
Open

NixOS, Home-Manager, and Kanidm Unixd #2698

TheRealGramdalf opened this issue Apr 8, 2024 · 4 comments

Comments

@TheRealGramdalf
Copy link

TheRealGramdalf commented Apr 8, 2024

Is your feature request related to a problem? Please describe.

Using kanidm-unixd on NixOS is generally pretty great, but there are a couple gaps that I believe require some changes/information from Kanidm. These are primarily:

  • Exposing a UUID to unix based systems
  • Clear separation between state managed by Kanidm vs. state managed elsewhere

Describe the solution you'd like

Exposing a UUID

Exposing a UUID should solve the following:

  • Using systemd-homed (I believe?) to
    • Create a ZFS dataset upon logging in to a k-unixd client, if the dataset doesn't exist
    • Use the users' UUID as the dataset name, and instead of using symlinks to solve the username -> UUID mapping, use mountpoints
      • Mounting the dataset zroot/home/UUID to /home/current-username is perfect for this, since the mount only survives as long as the user's session, which should be fine in about 99% of the time. NixOS already has a module that integrates systemd-homed and zfs together, so the main difference is mapping the Kanidm UUID in there.
    • Optionally encrypt users' home dataset using ZFS encryption
  • Using UUIDs with the home-manager NixOS module
    • home-manager can be used as a NixOS module, which essentially allows a system administrator to write a users' configuration using home-manager, and have that configuration activated when they log in to the system. This is useful for things like preconfiguring a web browser, enforcing policy, and managing what software the user runs.

I am aware that it is possible to get a users' UUID via API requests or such, but (whether it exists already or not) I would like to be able to (if possible) transparently query through PAM (for improved compatibility with e.g. home-manager/sytemd-homed), or the kanidm-unixd daemon, so it can continue to work offline. I'm unsure as to how exactly this would function, I'm not super familiar with PAM etc.

The issue with systemd-homed should be pretty self explanatory - I need a method to get a users' UUID in order to create the dataset, as well as a method to get the username currently correlated to said UUID at mount time. I have yet to track down how exactly this functions in a "typical" scenario (with local users/groups), I'll update when that happens.

The issue with home-manager is a little more complex. To avoid going too far into detail with the specifics of home-manager, it basically boils down to three main points where HM interacts with UUIDs:

  • In the HM configuration files, where users are typically referenced by username (which is mutable)
  • On system rebuild, where HM takes the configuration files and prepares a profile for each user specified in /etc/nix-profile
  • On user login, where HM matches the username of the user logging in to a profile in /etc/nix-profile, and activates said configuration (places symlinks in their home directory)

The first point is most likely just a case of "Use the UUID instead of the username", thus not really concerning Kanidm. This should also pave the way for the next two steps.
Step two should be solved by step one using UUIDs; each is Unique and immutable.
Step three is the main issue - while I have yet to track down the exact source code, HM needs to be able to activate the profile prepared in /etc/nix-profile/hm-uuid-or-username, which is typically handled by grabbing the uuid/username from said profile, and adding it to /home/ (or whatever the user has set as the home prefix). There needs to be a way for HM to query Kanidm for the current username the UUID refers to, so it can select the correct /home/ directory after systemd-homed does it's mounting.

As an alternative, it is technically possible to just set the SPN field in Kanidm to the UUID directly, avoiding many of the issues - but that messes with how permissions are resolved in graphical applications like the file manager - viewing permissions on a network share would show a UUID instead of a username, which is arguably unusable and could result in nasty consequences.
One other solution I thought of was to mount the users' home directory twice; once via username and once via UUID. This would allow HM to keep its' default behavior of concatenation, but again could very well introduce some other unwanted side effects.

Separation of state

Kanidm, by it's own definition, is meant to be the source of truth. Mixed in with that, however, are some other less clear examples of "state" which could technically be managed by Kanidm, but in actuality shouldn't be. I've split the relevant details I have so far into three groups based on what I think the separation should look like, but feel free to make changes or tweaks.

Kanidm State

  • UID/GID and membership information (specifically for kanidm-managed POSIX groups)
  • First factor authentication (Passwords, passkeys, etc)

Device-local (maybe TPM?) state

  • Second factor authentication (TOTP, hardware-backed passkey second factors like biometric authentication)
  • Biometric (fingerprint/face) authentication (specifically registered after authenticating to a device locally with kanidm-unixd, and only valid on that specific device - again, probably backed by the TPM)

Unsure

  • Additional (potentially) machine-specific groups (such as networkmanager, wireshark, adb etc)
  • ZFS Home dataset encryption keys (are these kept device-local and thus under control of the devices' system administrator, or are they linked to the individual user via Kanidm, thus being under the control of the Kanidm administrator, or are they kept like SSH private keys, beholden to none but the bearer?)

I'm starting to run out of capacity to think now, so I'll add revisions via comments later on should I think of anything else to add.

For reference:
#1747
#2251 (comment)
https://nix-community.github.io/home-manager/index.xhtml#sec-install-nixos-module
https://nix-community.github.io/home-manager/index.xhtml#_how_to_set_up_a_configuration_for_multiple_users_machines
https://nix-community.github.io/home-manager/nixos-options.xhtml#nixos-opt-home-manager.useUserPackages

@Firstyear
Copy link
Member

This seems less like an issue, and more like some braindumps about things.

  1. I don't want to integrate with systemd-homed
  2. If we were to mount arbitrary filesystems or create them on login, then that would be part of kanidm-unixd-tasks, which already exists
  3. For authentication with TPM, we have plans for this already.
  4. Local querying of user detais would be possible with some pretty basic extensions to the unix socket api.

@TheRealGramdalf
Copy link
Author

This seems less like an issue, and more like some braindumps about things.

Perhaps - it wasn't my intention. I believe it does concern Kanidm in some way (if not exactly via features, at least via intended usage). At the very least I wanted to get an idea of the Kanidm teams' thoughts when it comes to the concept behind what I'm trying to achieve.

I don't want to integrate with systemd-homed

I don't mean for the whole homectl thing, if that's what you're referring to - I merely meant that there is an existing implementation that (as far as I'm aware) uses systemd-homed under the hood to accomplish creation/mounting/encryption of home directories on login (which, as you said, might end up being part of kanidm-unixd-tasks - I believe creating home directories and the relevant symlinks is already handled by it).
So if you would prefer to implement this directly rather than me creating a third-party configuration which leverages systemd-homed, consider it a feature request.

For authentication with TPM, we have plans for this already.

I am still interested about machine-specific groups - is the idea that Kanidm is used for all groups (including system-specific ones like networkmanager etc), or is kanidm-unixd intended to be primarily an extension that provides user authentication alongside preexisting groups?

Local querying of user detais would be possible with some pretty basic extensions to the unix socket api.

Correct me if I'm wrong, but I gather this refers to changes on the Kanidm side in order to expose this functionality, not something that is already possible with the current release candidate

@TheRealGramdalf
Copy link
Author

One other alternative that I hadn't thought of - it looks like it's possible to use the kanidm UUID in places like e.g. chown uuid:uuid test.txt while still having the uid_attr_map set to spn - it might be possible to leverage that in the cases above.

@Firstyear
Copy link
Member

Yes, we resolve anything that uniquely identifies the account, even if we only present the spn/name.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 📋 Backlog
Development

No branches or pull requests

2 participants