What do you want from PAM (`security.pam`) in NixOS?

The NixOS security.pam module provides config options for Linux PAM (Pluggable Authentication Modules). PAM is how the authentication stack is configured for login and also programs like sudo, passwd, su, etc. With PAM, you can configure 2FA, LDAP/AD, encrypted home directories, automatic keychain unlock, and more.

The PAM infrastructure in NixOS needs some love. I have done some refactoring and I’m thinking about spinning up an RFC for a bigger design evolution. First, I want to hear from you:

What do YOU want the NixOS PAM module to do for you?

Below is my first stab, broken out by user category. Please comment with any corrections or additions!

NixOS Users

  • Defaults are secure. “I don’t have to think about PAM.”
  • Enabling a feature (e.g. U2F, LDAP) is as easy as configuring a NixOS service.
  • Different PAM features “just work” together by default.

NixOS/PAM Power Users

  • PAM stack can be fine-tuned through NixOS config. (Reorder rules, change arguments, etc.)
  • Never need to manually write PAM config files.
  • New PAMs can be added through NixOS config.
  • Customizing parts of the PAM stack doesn’t require maintaining the whole stack yourself.

NixOS Maintainers

  • PAM options are defined entirely in their own files (NixOS modules).
  • Clear guidance exists for how new PAMs should fit into the stack of PAM rules.
  • Desktop environments and other software don’t need to duplicate the PAM stack.
  • Insecure or unsuitable defaults are fixed without breaking existing users.
18 Likes

There was a conversation started here:

https://github.com/NixOS/nixpkgs/issues/147565

Following a PR that probably looks like what you attempted (sorry I didn’t look at your PR in details): (I realise now that you refer to it in your PR)

https://github.com/NixOS/nixpkgs/pull/105319

If you have any questions on my PR, why I went with that design, etc., don’t hesitate.

Unfortunately their wasn’t much traction to make this happen when I worked on it, but hopefully you’ll have more luck!

@rissson The scope of my PR is more similar to Use structured settings for PAM configuration by kwohlfahrt · Pull Request #105098 · NixOS/nixpkgs · GitHub which you built upon. Since yours was a larger rework, I hadn’t looked at it closely.

Now that I have, I can see that we are thinking similarly about many things! A lot of the changes you made are on my todo list if not already implemented.

So far, I’ve focused on lifting PAM rules into the module system, offering a low-level abstraction for defining rules first. My thinking is that if a user has to use the text escape hatch, then they have to throw away all the benefits of the module system. (Imagine a user using five different security.pam settings happily, only to have to write all their PAM rules manually because one need isn’t met by the modules as defined.) Hence the desire to “never need to manually write PAM config files.”

We also want (and to some extent already have) higher-level abstractions for enabling “features” or “modules” that create many rules. These options can be more opinionated and offer useful defaults, like 2FA modules coming after password login. My hope is that I can defer these higher-level design changes until after reworking the rule generation internals.

It looks like your PR addressed both these needs, and our PRs have fairly minor differences in interface design. One area I’ve neglected that I discovered in testing yesterday is defaults, since it isn’t (AFAIK) possible for a user to extend every value in a config attrset.

Unfortunately their wasn’t much traction to make this happen when I worked on it, but hopefully you’ll have more luck!

My burning question for you is: Where did your PR get stuck? How can I make sure I don’t get similarly stuck? It looks like you did great work and documented it well.

1 Like

I’m a NixOS and home-manager user. My only usage of the NixOS PAM module is this line.

Where did your PR get stuck? How can I make sure I don’t get similarly stuck? It looks like you did great work and documented it well.

I think it’s simply due to its size, and perhaps the lack of “advertising” around it. I think if you manage to make as many small, non-breaking changes as possible (at least to the exposed modules under security.pam like security.pam.yubico.enable) before changing that, you’ll be able to rework the backend and have a proper foundation for moving forward. And with that, try to get as many eyes as you can on the PRs to get traction from core maintainers to make this happen.

I’d also be careful of the timing, no one wants to merge potentially breaking changes before a stable release.

I don’t know if going through the RFC process would be appropriate for those changes, but if you decide to, I’d love to co-author it.

As for use cases, speaking for power users, I think you’re right on the money. The most annoying thing is to have to maintain the stack for ourselves. I’ll leave an example of us doing that, and it’s just the most horrendous thing to maintain. modules/config/users-groups.nix · master · Forge Infra / Infrastructure / Nix PIE · GitLab

Thanks for your thoughts! I made some changes to #255547 to hopefully make things smoother:

  • Cleaned up some inconsistencies in how rules are defined up front. That made the rest of the commits more automated and consistent.
  • Set the new options visible = false and marked them experimental. The idea is to retain the flexibility to rework these options and minimize the impact of getting the design wrong the first time around.

I don’t know yet if an RFC makes sense, but I’d be happy to work with you on one if so. I’ll definitely want to bounce some ideas off you when I get to the user-facing option design regardless.


As for getting more eyes on this work, I’ll start now: this refactor PR is ready for review! :tada: If you believe these PAM changes are important, please take a look through the commits and leave a review. The changes are easy on the eyes, I promise.

Hey, this may be out of scope for the refactor PR, but I’d love to see support for Systemd’s Homed. See also systemd-homed support · Issue #91243 · NixOS/nixpkgs · GitHub .

3 Likes

This would be great!

i feel like more wiki documentation would be nice - right now there is some about u2f/otp on the Yubikey page, while i’m not finding instructions for fido2 (in my case thru a device from Nitrokey).

Wiki documentation is discouraged by the NixOS’ documentation team. The nixos.wiki website is unmaintained (although it still functions).

i have to agree with that, i’d prefer nixos tests over wiki pages…

Because for me at least, a nixos end to end full integration test are documentation.

1 Like

i don’t super mind whether docs go to the wiki or the official manual, but either way some more clarity on how to use this would be nice.
tests are cool too but i’m not sure they’d be as accessible for newer users as a substitute for documentation.

I was trying to figure out a way to get the nextcloud client to work with autologin on SDDM and an empty kwallet password and couldn’t make it work. I found some instructions on how to edit pam.d files to facilitate this but couldn’t try them out because I don’t know how to change pam.d files in NixOS. So that would be my use case.

1 Like

I’d like to be able to easy do something like exposed here:

--- /etc/pam.d/gdm-password
+++ /etc/pam.d/gdm-password
@@ -1,5 +1,6 @@
 auth     [success=done ignore=ignore default=bad] pam_selinux_permit.so
 auth        substack      password-auth
+auth        optional      pam_exec.so /usr/local/sbin/create-local-homedir.sh
 auth        optional      pam_gnome_keyring.so
 auth        include       postlogin

--- /etc/pam.d/sshd
+++ /etc/pam.d/sshd
@@ -15,3 +15,4 @@
 session    optional     pam_motd.so
 session    include      password-auth
 session    include      postlogin
+session    optional     pam_exec.so /usr/local/sbin/create-local-homedir.sh
2 Likes

Something I’ve been doing lately is trying to make kwallet5 unlock automatically with the encryption password. I succeeded, but as far as I can tell, for stuff like autologin where the actual authentication piece is different, but you want to reuse the “stuff that uses PAM_AUTH_TOK” portion of the main config, that’s seems to not be currently possible without, possibly, setting security.pam.rules.sddm-autologin.enableKwallet and similar at every usage site?