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/tpm2: init #72029

Merged
merged 1 commit into from Mar 15, 2020
Merged

nixos/tpm2: init #72029

merged 1 commit into from Mar 15, 2020

Conversation

lschuermann
Copy link
Member

@lschuermann lschuermann commented Oct 26, 2019

Motivation for this change

The TPM2 device files should be owned by a specific user. In addition to that, the TPM2 kernel resource manager (/dev/tpmrm*) should be owned by a specific group, such that an unprivileged user is able to access this device.

Furthermore, this commit adds a systemd service for the tpm2-abrmd userspace resource manager (merged in #72018), on which many applications still rely.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nix-review --run "nix-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@Lassulus

Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know much about TPM, but I'm wondering whether it's worth having some of these options. In particular I can't see a use case for changing tssUser and tssGroup, a fixed value will probably work fine, same for abrmd.user. applyUdevRules seems also like it could be an unconfigurable true, would anybody want to turn that off? Same for setEnvironmentVariables. What do you think?

nixos/modules/security/tpm2.nix Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
@lschuermann
Copy link
Member Author

@infinisil Regarding your comments on the different (configurable) options:

  • tssUser / tssGroup: I'd almost say that we could hardcode tss in here, but AFAIK TPM software is pretty fragile, and while I haven't seen an example where tss doesn't work yet, I'd rather be prepared. Configurable users / groups are the norm across NixOS modules. Also, AFAIK tss is more of a convention than a standard here, so I'd rather leave it that way.
  • applyUdevRules: The udev rules are sensible, but quite opinionated (only the tss user can access the device, only the group the resource manager, permissions, etc.). I could imagine a few very valid scenarios where a user would opt out of those, but instead configure their own.
  • setEnvironmentVariables: Just enabling the userspace resource manager should never influence the behaviour of TPM applications implicitly. Setting the environment variables doesn't work for all TPM tools (just tpm2-tools and tpm2-pkcs11 for now), and changes the default behaviour to always use the userspace resource manager. That is why it's in default - despite being quite useful - disabled. There are many other ways a user might want to interface their TPM(s), and with multiple they could even opt in to use different resource managers. Unsetting some environment variables is not a solution here.

I thereby conclude, that unfortunately the complexity of this module cannot be reduced significantly without trade offs.

@infinisil
Copy link
Member

  • tss{User,Group}: I think configurable user/group makes sense where there's a reason to change it, such as when the service creates files which need to be owned by the main system user. In this case however I can't see this being necessary. If at some later point we discover that this indeed needs to be configurable I'll be happy to merge additional options for it.
  • applyUdevRules: Can you explain how you arrived at these udev rules? I don't quite get what they do, and also what tmp and tmprm are used for and when they're needed. I think usually permissions to devices are handled with a group users can add themselves to to allow them to use it, why is this not the case for tmp but for tmprm?
  • setEnvironmentVariables: Alright that sounds reasonable. Though why should the rm never influence TPM applications implicitly?

@lschuermann
Copy link
Member Author

Extending my points above:

  • tss{User,Group}: Actually, considering the udev rules, the files /dev/tpm{[0-9],rm[0-9]} will be owned by the user / group respectively. I have an application which would like exclusive ownership of the /dev/tpm[0-9] device, and as such I'd change the tssUser option to the application's user. I could hack my way around this, or even run the application as tss (not knowing what other implications that'll have), but changing device ownership appears to be the cleanest solution. Also, this way, other services could rely on the configured user/group. If you are still not convinced, I will remove the options. This implies, that with a hard-coded user and group, there must be a way to disable setting the udev rules.
  • applyUdevRules: As clearly stated above the udevRules function, these are taken from the tpm2-tss package. Without going too much into detail, a TPM has limited resources, and the /dev/tpm[0-9] provides a vastly unmanaged interface to the TPM. As an exclusive owner of this file, you'd have full control and responsibility over resource management of the TPM. It therefore doesn't make sense to use groups here, so the group will be root. The /dev/tpmrm[0-9] is a resource manager implemented in the kernel. While not having full control, multiple application can simultaneously use the device without blocking each other. As this new (AFAIK kernel 4.x) device is not always supported, the userspace resource manager (using DBus as transport) should still be provided.
  • setEnvironmentVariables: Each application may implement this differently, but most try to automatically detect the device to use. On my system, most try to use the /dev/tpm0 device, although they don't have the required permissions. When using the userspace resource manager, and having only one TPM, this option provides an override for some TPM applications. It helps me, likely helps others, but should be opt-in as it is opinionated.

@infinisil
Copy link
Member

Alright I see, you convinced me :)

Looks ready to merge then after the adjustments above

@lschuermann
Copy link
Member Author

lschuermann commented Jan 21, 2020

Okay, so this has been a long time coming.

I've finally addressed your concerns @infinisil and used this module in a working production setup, polishing one or the other thing. The behaviour now comes as close to "working out of the box" and "confirming to the TPM2 TSS desired setup" as I can think of.

The default configuration now leads to the following device ownership:

crw-rw---- 1 root root  10,   224 Jan 20 19:47 /dev/tpm0
crw-rw---- 1 root tss  246, 65536 Jan 20 19:47 /dev/tpmrm0

This works for most use cases (where the "device" TCTI is used), however breaks the userspace resource manager, which must run as non-root, but still have access to the TPM device and ships only with D-Bus rules for "tss". Therefore, when using the userspace resource manager, the device is instead owned by "tss", which is then automatically set as the device owner per udev rule. If you want to, you can still override most things.

Quite confusing, but should cause the least troubles.

However, this module is now dependent on #72374 which should be ready too.
Let me know what you think.

@lschuermann
Copy link
Member Author

Now that #72374 is done, this one should be ready again. Could you remove the "blocked" label, @infinisil?

Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still some things to improve, I hope you don't mind!

nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
@lschuermann
Copy link
Member Author

There's always room for improvement - I'm willing to invest more time. Unfortunately, I got sick, hence the delay.

@infinisil
Copy link
Member

I saw some interest for this PR on IRC by @danderson, so here I am with a ping :)

@lschuermann
Copy link
Member Author

lschuermann commented Mar 13, 2020

I saw some interest for this PR on IRC by @danderson, so here I am with a ping :)

Glad to know there's interest. It'll be a big step if NixOS will support TPM2 modules without much hassle and manual setup. There's great potential, as long as the TPM is not an Intel fTPM.

I've tried to address all your change requests and they did improve the module quite a lot. Maybe this will be the last iteration? :) Feel free to "resolve" the conversations if you feel I've sufficiently addressed the underlying issues.

When this is merged I can finally write my blog post on how to do TPM-based SSH using the PKCS#11 module.

nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
nixos/modules/security/tpm2.nix Outdated Show resolved Hide resolved
@lschuermann
Copy link
Member Author

Ready for another review round I guess.

This commit adds udev rules, the userspace resource manager and
PKCS#11 module support.
Copy link
Member

@infinisil infinisil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good!

@infinisil infinisil merged commit 7c3f3e9 into NixOS:master Mar 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants