Getting access to the /tmp of a systemd service with <code>PrivateTmp=yes</code>

Suppose, not hypothetically, that you're doing something inside a systemd service; for example, it runs a script with some environment variables set, and you want to get a full dump of those environment variables. My traditional approach is to write these to /tmp , but this doesn't work if the service is using PrivateTmp=yes ( cf ). Well, doing this doesn't put the resulting files directly in the regular /tmp .

For services specifically using PrivateTmp=yes , systemd puts their /tmp in /tmp/systemd-private-<hex>-<service>-<jumble>/tmp. The large <hex> value seems to be constant across all services, while the <jumble> is random. A service's /var/tmp is handled similarly, with the systemd-private directory in /var/tmp. This is sort of documented in the systemd.exec manual page :

If "true", the backing storage of the private temporary directories will remain on the host's /tmp/ and /var/tmp/ directories. [...]

You can also set ' PrivateTmp=disconnected ' to give the service a completely detached /tmp on a new tmpfs; this is also implied by DynamicUser=yes . If you need to look at the /tmp of such a program (including one that implicitly has this setting by using DynamicUser=yes ), I think the easiest way is ' nsenter -t <pid> -m ' (as root), which will start a shell with that 'mount' namespace so its /tmp is the program's /tmp. I don't believe this disconnected private /tmp is mounted or otherwise available outside of the process's namespace, so you have to enter it with nsenter .

( I like DynamicUser so I'm glad to find ways to make it easier to use.)

One way to see what processes might have things going on is with lsns(8) , which I probably want to use as ' lsns -t mnt '. I don't think there's an easy way to tell whether these have a disconnected /tmp or a merely private /tmp (or perhaps are doing other things with namespaces).

Sidebar: Copying files out of a namespace the hard way

Suppose that you have an entirely locked down systemd service with a disconnected /tmp and that disconnected /tmp contains debugging information you want to copy out. Unless there's a way of accessing a mount namespace from outside of it, this means using nsenter , but that will lock you inside the locked down mount namespace (which may have everything else read-only). The obvious blunt hack to get around this and access the file contents of debugging files is that standard output isn't restricted:

nsenter -t <pid> -m cat /tmp/whatever >/tmp/whatever-out

The shell redirection will be done to the real /tmp since it's set up by the shell before nsenter runs and switches what '/tmp' means. The ' cat ' runs inside the namespace with its /tmp switched, so it reads your disconnected debugging file.

(An enterprising person who needed to do this often enough could turn this into a 'nscp' script, perhaps used as 'nscp <pid>:/tmp/whatever /tmp/out'. For bonus points the script could also support copying things in to a namespace, and by extension copying things between them.)

( 2 comments .)