Isolate Session Files with pam_namespace Safely
You will configure a PAM session to give selected directories separate per-user or per-context instances, then verify the configuration without guessing what the mount namespace is doing. The examples target the installed Linux-PAM package libpam-modules 1.5.3-5ubuntu5.7.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about thirty minutes, plus a maintenance window if you are changing a real login service. You need root access, a test account, a PAM service that opens sessions, and a recovery route such as an existing root shell. This is a security-sensitive change: a bad PAM line can stop users opening sessions, and a broad rule can hide files or change how temporary data is shared.
1. Understand the two files involved
pam_namespace is a PAM session module, not a command that you run at a prompt. It reads /etc/security/namespace.conf and files in /etc/security/namespace.d when a session opens. The module must be added to the session group for each PAM service that needs the isolation.
Check the installed module and configuration paths before editing anything:
$ dpkg-query -W -f='${Package} ${Version}\n' libpam-modules:amd64
libpam-modules 1.5.3-5ubuntu5.7
$ ls -l /usr/lib/x86_64-linux-gnu/security/pam_namespace.so /etc/security/namespace.conf
$ ls -ld /etc/security/namespace.d
Checkpoint: confirm that the package version and library path match the system where you will make the change. The option and configuration details below are for this Linux-PAM build.
2. Choose one narrow directory rule
Each non-comment line in namespace.conf has four fields:
polydir instance_prefix method list_of_users
polydir is the directory seen by the session. instance_prefix is where the backing instance is created. method selects the differentiation method. A blank user list applies the rule to everyone; prefixing the list with ~ reverses that and limits the rule to those users.
For a first test, isolate a disposable directory for one named account. Run the following as root, after creating the instance parent with the required restrictive mode:
# install -d -o root -g root -m 000 /srv/pam-namespace/instances
# cp --preserve=mode,ownership /etc/security/namespace.conf /etc/security/namespace.conf.bak
# printf '%s\n' '/srv/pam-test /srv/pam-namespace/instances/ user ~pamtest' >> /etc/security/namespace.conf
The user method differentiates instances by user name. The example therefore gives pamtest its own instance and does not affect other users. The instance parent must exist and, by default, have mode 0000. Do not use ignore_instance_parent_mode to make a convenient but unsafe directory work.
Checkpoint: inspect the last line and its fields before continuing:
# tail -n 1 /etc/security/namespace.conf
/srv/pam-test /srv/pam-namespace/instances/ user ~pamtest
3. Add the module to one test service
Choose a PAM service that you can test without risking your only administrative access. Add the module as the last line in that service's session group:
session required pam_namespace.so
For example, make a backup before editing the service file, then add the line to /etc/pam.d/LOGIN_SERVICE, replacing the placeholder with the real service name:
# cp --preserve=mode,ownership /etc/pam.d/LOGIN_SERVICE /etc/pam.d/LOGIN_SERVICE.bak
# editor /etc/pam.d/LOGIN_SERVICE
Do not paste LOGIN_SERVICE literally. PAM configuration is service-specific, and a line in the wrong file may have no effect or affect more sessions than intended. If the service is used by a display manager, follow that service's own documentation and test from a separate administrative session.
4. Open a fresh session and verify the instance
The namespace is set up when the PAM session opens. Existing shells do not acquire it merely because the files changed. Log in as pamtest through the service you edited, then compare the directory view with an unisolated session:
$ touch /srv/pam-test/created-by-pamtest
$ ls -ld /srv/pam-test
$ findmnt -T /srv/pam-test
$ printf 'session status: %s\n' "$?"
session status: 0
The exact findmnt output depends on the host. The useful evidence is that the path is mounted or otherwise presented through the instance for pamtest, and that a second user's session does not see the same contents. Test the second account with a harmless listing before placing real data in the directory.
Do not interpret a successful login alone as proof of isolation. Confirm the actual path, the instance parent and the visibility from both sessions. If the login fails, keep the recovery shell open and inspect the system log for PAM and namespace errors before trying a wider rule.
5. Use the other methods deliberately
For temporary storage, tmpfs mounts a tmpfs instance and accepts mount options through mntopts=. A conservative example is:
/srv/pam-cache /srv/pam-namespace/cache/ tmpfs:create=0700,owner,group:mntopts=size=64M,nosuid,nodev,noexec ~pamtest
Check the exact field parsing on your target before deploying this form, and remember that noexec, nodev and nosuid change what the instance can do. The tmpdir method creates a temporary instance that is removed when the session closes. Both methods are service-impacting if applications expect shared files.
The level and context methods depend on SELinux. The caller or pam_selinux.so must establish the relevant execution context; otherwise the module falls back to user-based differentiation. The optional shared flag can make context and level instances shared between users, which weakens the separation and should have a specific justification.
If you use an instance initialisation script, the installed documentation describes /etc/security/namespace.init and an iscript= override relative to /etc/security/namespace.d. Make such a script root-owned, non-writable by ordinary users, and test its arguments with a disposable directory. An init script runs as part of session setup, so a failure can become a login failure.
6. Recover from a bad test
Before removing anything, close the test session and ensure no process still uses its private namespace. Then restore the PAM file and remove only the rule you added:
# cp --preserve=mode,ownership /etc/pam.d/LOGIN_SERVICE.bak /etc/pam.d/LOGIN_SERVICE
# editor /etc/security/namespace.conf
# findmnt -T /srv/pam-test
# ls -la /srv/pam-namespace/instances
Removing the PAM line stops new sessions from entering the namespace. It does not rewrite or delete existing instance directories. Keep those directories until you have confirmed that no required data remains, then remove the specific test directory during a reviewed maintenance action. Never use a broad recursive deletion against an instance parent that may contain other users' data.
Done means
- The installed Linux-PAM version and module path were confirmed.
- A single, documented
namespace.confrule targets a disposable directory and test account. - The instance parent exists with the default restrictive mode.
pam_namespace.sois last in the tested service's session group.- A fresh session was checked with
findmntand a second-session visibility test. - A backup and rollback path remain available, and no unreviewed instance data was deleted.