From 28e4999ebd9221a71488d715d9f1182b494216d8 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 8 Mar 2021 15:20:08 -0800 Subject: pam_fscrypt: decide cache dropping behavior automatically Configuring whether pam_fscrypt drops caches or not isn't really something the user should have to do, and it's also irrelevant for v2 encryption policies (the default on newer systems). It's better to have pam_fscrypt automatically decide whether it needs to drop caches or not. Do this by making pam_fscrypt check whether any encryption policy keys are being removed from a user keyring (rather than from a filesystem keyring). If so, it drops caches; otherwise it doesn't. This supersedes the "drop_caches" option, which won't do anything anymore. --- README.md | 9 +++------ pam_fscrypt/config | 2 +- pam_fscrypt/pam_fscrypt.go | 42 +++++++++++++++++++++++++++++------------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 73153ed..4a59535 100644 --- a/README.md +++ b/README.md @@ -415,15 +415,12 @@ auth optional pam_fscrypt.so after `pam_unix.so` in `/etc/pam.d/common-auth` or similar, and to add the line: ``` -session optional pam_fscrypt.so drop_caches lock_policies +session optional pam_fscrypt.so lock_policies ``` after `pam_unix.so` in `/etc/pam.d/common-session` or similar. The `lock_policies` option locks the directories protected with the user's login -passphrase when the last session ends. The `drop_caches` option tells `fscrypt` -to clear the filesystem caches when the last session closes, ensuring all the -locked data is inaccessible; this only needed for v1 encryption policies. All -the types also support the `debug` option which prints additional debug -information to the syslog. +passphrase when the last session ends. All the types also support the `debug` +option which prints additional debug information to the syslog. ### Allowing `fscrypt` to check your login passphrase diff --git a/pam_fscrypt/config b/pam_fscrypt/config index 9b2eb8f..d2fbf68 100644 --- a/pam_fscrypt/config +++ b/pam_fscrypt/config @@ -7,7 +7,7 @@ Auth-Final: Session-Type: Additional Session-Interactive-Only: yes Session-Final: - optional PAM_INSTALL_PATH drop_caches lock_policies + optional PAM_INSTALL_PATH lock_policies Password-Type: Additional Password-Final: optional PAM_INSTALL_PATH diff --git a/pam_fscrypt/pam_fscrypt.go b/pam_fscrypt/pam_fscrypt.go index a7582cc..195ba43 100644 --- a/pam_fscrypt/pam_fscrypt.go +++ b/pam_fscrypt/pam_fscrypt.go @@ -48,7 +48,12 @@ const ( // These flags are used to toggle behavior of the PAM module. debugFlag = "debug" lockFlag = "lock_policies" - cacheFlag = "drop_caches" + + // This option is accepted for compatibility with existing config files, + // but it no longer does anything. pam_fscrypt now drops caches if and + // only if it is needed. (Usually it is not needed anymore, as the + // FS_IOC_REMOVE_ENCRYPTION_KEY ioctl handles this automatically.) + dropCachesFlag = "drop_caches" ) var ( @@ -213,15 +218,20 @@ func CloseSession(handle *pam.Handle, args map[string]bool) error { return err } + if args[dropCachesFlag] { + log.Print("ignoring deprecated 'drop_caches' option (now auto-detected)") + } + + needDropCaches := false var errLock, errCache error // Don't automatically drop privileges, since we may need them to // deprovision policies or to drop caches. if args[lockFlag] { log.Print("locking polices protected with login protector") - errLock = lockLoginPolicies(handle) + needDropCaches, errLock = lockLoginPolicies(handle) } - if args[cacheFlag] { + if needDropCaches { log.Print("dropping appropriate filesystem caches at session close") errCache = security.DropFilesystemCache() } @@ -232,11 +242,14 @@ func CloseSession(handle *pam.Handle, args map[string]bool) error { return errCache } -// lockLoginPolicies deprovisions all policy keys that are protected by -// the user's login protector. -func lockLoginPolicies(handle *pam.Handle) error { +// lockLoginPolicies deprovisions all policy keys that are protected by the +// user's login protector. It returns true if dropping filesystem caches will +// be needed afterwards to completely lock the relevant directories. +func lockLoginPolicies(handle *pam.Handle) (bool, error) { + needDropCaches := false + if err := handle.StartAsPamUser(); err != nil { - return err + return needDropCaches, err } defer handle.StopAsPamUser() @@ -244,16 +257,16 @@ func lockLoginPolicies(handle *pam.Handle) error { protector, err := loginProtector(handle) if err != nil { log.Printf("nothing to lock: %s", err) - return nil + return needDropCaches, nil } policies := policiesUsingProtector(protector) if len(policies) == 0 { log.Print("no policies to lock") - return nil + return needDropCaches, nil } if err = setupUserKeyringIfNeeded(handle, policies); err != nil { - return errors.Wrapf(err, "setting up user keyring") + return needDropCaches, errors.Wrapf(err, "setting up user keyring") } // We will try to deprovision all of the policies. @@ -263,12 +276,15 @@ func lockLoginPolicies(handle *pam.Handle) error { policy.Descriptor(), handle.PamUser.Username) continue } + if policy.NeedsUserKeyring() { + needDropCaches = true + } if err := beginProvisioningOp(handle, policy); err != nil { - return err + return needDropCaches, err } deprovisionErr := policy.Deprovision(false) if err := endProvisioningOp(handle, policy); err != nil { - return err + return needDropCaches, err } if deprovisionErr != nil { log.Printf("deprovisioning policy %s: %s", policy.Descriptor(), deprovisionErr) @@ -276,7 +292,7 @@ func lockLoginPolicies(handle *pam.Handle) error { } log.Printf("policy %s deprovisioned by %v", policy.Descriptor(), handle.PamUser.Username) } - return nil + return needDropCaches, nil } // Chauthtok rewraps the login protector when the passphrase changes. -- cgit v1.2.3 From b7e898f01bcae17174fcd928599d0d933655db9b Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 8 Mar 2021 15:20:08 -0800 Subject: pam_fscrypt: make "lock_policies" the default behavior All pam_fscrypt configuration guides that I'm aware of say to use the "lock_policies" option for the pam_fscrypt.so session hook. The Debian/Ubuntu pam-config-framework config file has it too. Make locking the default behavior, since this is what everyone wants. Existing configuration files that contain the "lock_policies" option will continue to work, but that option won't do anything anymore. (We could add an option "unlock_only" to restore the old default behavior, but it's not clear that it would be useful. So for simplicity, leave it out for now.) --- README.md | 10 +++++----- pam_fscrypt/config | 2 +- pam_fscrypt/pam_fscrypt.go | 19 ++++++++++++------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 4a59535..97caed2 100644 --- a/README.md +++ b/README.md @@ -415,12 +415,12 @@ auth optional pam_fscrypt.so after `pam_unix.so` in `/etc/pam.d/common-auth` or similar, and to add the line: ``` -session optional pam_fscrypt.so lock_policies +session optional pam_fscrypt.so ``` -after `pam_unix.so` in `/etc/pam.d/common-session` or similar. The -`lock_policies` option locks the directories protected with the user's login -passphrase when the last session ends. All the types also support the `debug` -option which prints additional debug information to the syslog. +after `pam_unix.so` in `/etc/pam.d/common-session` or similar. + +To make `pam_fscrypt.so` print debugging messages to the system log, add the +`debug` option. All hook types accept this option. ### Allowing `fscrypt` to check your login passphrase diff --git a/pam_fscrypt/config b/pam_fscrypt/config index d2fbf68..f83dab2 100644 --- a/pam_fscrypt/config +++ b/pam_fscrypt/config @@ -7,7 +7,7 @@ Auth-Final: Session-Type: Additional Session-Interactive-Only: yes Session-Final: - optional PAM_INSTALL_PATH lock_policies + optional PAM_INSTALL_PATH Password-Type: Additional Password-Final: optional PAM_INSTALL_PATH diff --git a/pam_fscrypt/pam_fscrypt.go b/pam_fscrypt/pam_fscrypt.go index 195ba43..2e31af9 100644 --- a/pam_fscrypt/pam_fscrypt.go +++ b/pam_fscrypt/pam_fscrypt.go @@ -47,7 +47,10 @@ const ( authtokLabel = "fscrypt_authtok" // These flags are used to toggle behavior of the PAM module. debugFlag = "debug" - lockFlag = "lock_policies" + + // This option is accepted for compatibility with existing config files, + // but now we lock policies unconditionally and this option is a no-op. + lockPoliciesFlag = "lock_policies" // This option is accepted for compatibility with existing config files, // but it no longer does anything. pam_fscrypt now drops caches if and @@ -218,19 +221,21 @@ func CloseSession(handle *pam.Handle, args map[string]bool) error { return err } + if args[lockPoliciesFlag] { + log.Print("ignoring deprecated 'lock_policies' option (now the default)") + } + if args[dropCachesFlag] { log.Print("ignoring deprecated 'drop_caches' option (now auto-detected)") } - needDropCaches := false - var errLock, errCache error // Don't automatically drop privileges, since we may need them to // deprovision policies or to drop caches. - if args[lockFlag] { - log.Print("locking polices protected with login protector") - needDropCaches, errLock = lockLoginPolicies(handle) - } + log.Print("locking policies protected with login protector") + needDropCaches, errLock := lockLoginPolicies(handle) + + var errCache error if needDropCaches { log.Print("dropping appropriate filesystem caches at session close") errCache = security.DropFilesystemCache() -- cgit v1.2.3 From cf19ab80b0eb24859494b3c12a43873d8eec3d73 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 8 Mar 2021 15:20:08 -0800 Subject: README: make it clear that pam_fscrypt also handles locking There are several mentions of pam_fscrypt handling unlocking directories. Make sure to mention locking alongside this. --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 97caed2..5cc789f 100644 --- a/README.md +++ b/README.md @@ -104,9 +104,10 @@ secret or information used to protect the confidentiality of your data. The three currently supported protector types are: 1. Your login passphrase, through [PAM](http://www.linux-pam.org/Linux-PAM-html). - The included PAM module (`pam_fscrypt.so`) can automatically unlock login - protectors when you log in. __IMPORTANT:__ before using a login protector, - follow [Setting up for login protectors](#setting-up-for-login-protectors). + The included PAM module (`pam_fscrypt.so`) can automatically unlock + directories protected by your login passphrase when you log in, and lock them + when you log out. __IMPORTANT:__ before using a login protector, follow + [Setting up for login protectors](#setting-up-for-login-protectors). 2. A custom passphrase. This passphrase is hashed with [Argon2id](https://en.wikipedia.org/wiki/Argon2), by default calibrated to @@ -363,9 +364,9 @@ existing passphrase with the new `rounds`. To enable the PAM module `pam_fscrypt.so`, follow the directions for your Linux distro below. Enabling the PAM module is needed for login passphrase-protected -directories to be automatically unlocked when you log in, and for login -passphrase-protected directories to remain accessible when you change your login -passphrase. +directories to be automatically unlocked when you log in (and be automatically +locked when you log out), and for login passphrase-protected directories to +remain accessible when you change your login passphrase. #### Enabling the PAM module on Ubuntu @@ -407,8 +408,8 @@ password optional pam_fscrypt.so after `pam_unix.so` in `/etc/pam.d/common-password` or similar. The Auth and Session functionality of `pam_fscrypt.so` are used to automatically -unlock directories when logging in as a user. An easy way to get this working is -to add the line: +unlock directories when logging in as a user, and lock them when logging out. +An easy way to get this working is to add the line: ``` auth optional pam_fscrypt.so ``` -- cgit v1.2.3 From 36d7ec1c2ddd367865a7438b8c602ad37fb229e8 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 8 Mar 2021 15:20:08 -0800 Subject: README: improve PAM configuration documentation (again) Make some more corrections: - pam-config-framework isn't actually Ubuntu-specific but actually applies to Debian and any Debian derivative. - The pam-config-framework file is indeed installed by `make install`, just not into the correct location. - On Debian (and Debian derivatives), the PAM configuration isn't actually part of the 'fscrypt' package but rather 'libpam-fscrypt'. - Clarify where to add the pam_fscrypt.so session hook. --- README.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5cc789f..3cf20bb 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ native encryption. See [Runtime Dependencies](#runtime-dependencies). - [Setting up for login protectors](#setting-up-for-login-protectors) - [Securing your login passphrase](#securing-your-login-passphrase) - [Enabling the PAM module](#enabling-the-pam-module) - - [Enabling the PAM module on Ubuntu](#enabling-the-pam-module-on-ubuntu) + - [Enabling the PAM module on Debian or Ubuntu](#enabling-the-pam-module-on-debian-or-ubuntu) - [Enabling the PAM module on Arch Linux](#enabling-the-pam-module-on-arch-linux) - [Enabling the PAM module on other Linux distros](#enabling-the-pam-module-on-other-linux-distros) - [Allowing `fscrypt` to check your login passphrase](#allowing-fscrypt-to-check-your-login-passphrase) @@ -169,13 +169,14 @@ Running `sudo make install` installs `fscrypt` into `/usr/local/bin`, `pam_fscrypt.so` into `/usr/local/lib/security`, and `pam_fscrypt/config` into `/usr/local/share/pam-configs`. -For Ubuntu, use `sudo make install PREFIX=/usr` to install into `/usr` instead -of the default of `/usr/local`. Ordinarily you shouldn't manually install -software into `/usr`, since `/usr` is reserved for Ubuntu's own packages. -However, Ubuntu only recognizes PAM configuration files in `/usr`, not in -`/usr/local`. This means that the PAM module will only work if you install into -`/usr`. Note: if you later decide to switch to using the Ubuntu package for -`fscrypt`, you'll have to first manually run `sudo make uninstall PREFIX=/usr`. +On Debian (and Debian derivatives such as Ubuntu), use `sudo make install +PREFIX=/usr` to install into `/usr` instead of the default of `/usr/local`. +Ordinarily you shouldn't manually install software into `/usr`, since `/usr` is +reserved for Debian's own packages. However, Debian's PAM configuration +framework only recognizes configuration files in `/usr`, not in `/usr/local`. +Therefore, the PAM module will only work if you install into `/usr`. Note: if +you later decide to switch to using the Debian package `libpam-fscrypt`, you'll +have to first manually run `sudo make uninstall PREFIX=/usr`. It is also possible to use `make install-bin` to only install the `fscrypt` binary, or `make install-pam` to only install the PAM files. @@ -368,18 +369,18 @@ directories to be automatically unlocked when you log in (and be automatically locked when you log out), and for login passphrase-protected directories to remain accessible when you change your login passphrase. -#### Enabling the PAM module on Ubuntu +#### Enabling the PAM module on Debian or Ubuntu -The official `fscrypt` package for Ubuntu will install a configuration file for -[Ubuntu's PAM configuration +The official `libpam-fscrypt` package for Debian (and Debian derivatives such as +Ubuntu) will install a configuration file for [Debian's PAM configuration framework](https://wiki.ubuntu.com/PAMConfigFrameworkSpec) to `/usr/share/pam-configs/fscrypt`. This file contains reasonable defaults for -the PAM module. To automatically apply these defaults, run `sudo -pam-auth-update` and follow the on-screen instructions. +the PAM module. To automatically apply these defaults, run +`sudo pam-auth-update` and follow the on-screen instructions. This file also gets installed if you build and install `fscrypt` from source, -but only if you use `make install PREFIX=/usr` to install into `/usr` instead of -the default of `/usr/local`. +but it is only installed to the correct location if you use `make install +PREFIX=/usr` to install into `/usr` instead of the default of `/usr/local`. #### Enabling the PAM module on Arch Linux @@ -418,7 +419,10 @@ line: ``` session optional pam_fscrypt.so ``` -after `pam_unix.so` in `/etc/pam.d/common-session` or similar. +after `pam_unix.so` in `/etc/pam.d/common-session` or similar, but before +`pam_systemd.so` or any other module that accesses the user's home directory or +which starts processes that access the user's home directory during their +session. To make `pam_fscrypt.so` print debugging messages to the system log, add the `debug` option. All hook types accept this option. -- cgit v1.2.3