<div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Jul 18, 2024, 15:43 Thomas Köller <<a href="mailto:thomas@koeller.dyndns.org" target="_blank" rel="noreferrer">thomas@koeller.dyndns.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Am 18.07.24 um 14:04 schrieb Mantas Mikulėnas:<br>
> Yes, but namespace persistence actually relies on filesystem access – <br>
> it's implemented as a bind-mount of the namespace file descriptor (onto <br>
> /run/netns for the 'ip netns' tool), as otherwise namespaces only exist <br>
> as long as processes that hold them.<br>
> <br>
> So if you have any service options that cause a new *mount* namespace to <br>
> be created (preventing its filesystem mounts from being visible outside <br>
> the unit), then it cannot pin persistent network namespaces.<br>
<br>
Quoting the manual page:<br>
        ProtectSystem=<br>
            Takes a boolean argument or the special values "full" or <br>
"strict". If true, mounts the /usr/ and the boot loader directories <br>
(/boot and /efi) read-only for processes invoked by this unit. If set<br>
            to "full", the /etc/ directory is mounted read-only, too.<br>
<br>
No mention of /var or /run.</blockquote></div></div><div dir="auto"><br></div><div dir="auto">It still works this way whether it's mentioned or not. Once the unit's process is put in a new mount namespace, the entire `/` is marked private so that any mounts made underneath `/` remain visible only in that namespace. This equally affects the "read-only /etc" mount done by systemd itself as well as the /run/netns mount done by 'ip' or any other mounts done anywhere else.</div><div dir="auto"><br></div><div dir="auto">In theory it would be possible to carve out exceptions such as marking /run shared again, but then /run/systemd would need to be marked private again, etc. – and mount propagation across namespaces is complex enough as it is.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Also, note that the bind mounts in in <br>
/var/run/netns and /run/netns are actually created by 'ip netns add', <br>
they just are't usable.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">No, the mount *points* in /run/netns are created (as regular empty files), but they don't become actual mounts, that's why they're not usable.</div><div dir="auto"><br></div><div dir="auto">There's a distinction between mount points (files or directories seen in `ls`) and mounts (seen in `findmnt`) – make your service script log its findmnt output to a file and compare it to findmnt output seen from the outside.</div><div dir="auto"><br></div><div dir="auto">(ember) /home/grawity                                                                             $ mount | grep netns</div><div dir="auto">tmpfs on /run/netns type tmpfs (rw,nosuid,nodev,size=3268196k,nr_inodes=819200,mode=755,inode64)</div><div dir="auto">(ember) /home/grawity                                                                             $ sudo systemd-run --shell -p ProtectSystem=full</div><div dir="auto">Running as unit: run-u1253.service; invocation ID: 9d4675b9ef7c40d68486b3058ee8a60b</div><div dir="auto">Press ^] three times within 1s to disconnect TTY.</div><div dir="auto">root@ember /home/grawity # mount | grep netns</div><div dir="auto">tmpfs on /run/netns type tmpfs (rw,nosuid,nodev,size=3268196k,nr_inodes=819200,mode=755,inode64)</div><div dir="auto">root@ember /home/grawity # ip netns add foo</div><div dir="auto">root@ember /home/grawity # mount | grep netns</div><div dir="auto">tmpfs on /run/netns type tmpfs (rw,nosuid,nodev,size=3268196k,nr_inodes=819200,mode=755,inode64)</div><div dir="auto">nsfs on /run/netns/foo type nsfs (rw)</div><div dir="auto">root@ember /home/grawity # exit</div><div dir="auto">Finished with result: success</div><div dir="auto">Main processes terminated with: code=exited, status=0/SUCCESS                                     Service runtime: 18.451s</div><div dir="auto">(ember) /home/grawity                                                                             $ mount | grep netns</div><div dir="auto">tmpfs on /run/netns type tmpfs (rw,nosuid,nodev,size=3268196k,nr_inodes=819200,mode=755,inode64)</div><div dir="auto">(ember) /home/grawity $</div><div dir="auto"><br></div><div dir="auto">(The non-systemd rough equivalent is `unshare --mount --propagation=private`, and you can attach to a namespace using `nsenter` – an "ip netns exec" is approximately an `nsenter --net`.)</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
</blockquote></div></div></div>