Re: bind-mount of /run/systemd for chrooted bind9/named

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Lennart,

thanks for this helpful answer.

On Tue, Jul 04, 2023 at 10:37:55AM +0200, Lennart Poettering wrote:
> On Mo, 03.07.23 20:52, Marc Haber (mh+systemd-devel@xxxxxxxxxxxx) wrote:
> > (1) go fully systemd
> > That would mean to get rid of bind's -t option completely but use
> > systemd's RootDirectory directive instead. I have not tried this but I
> > think that the bind community might be reluctant to support a setup like
> > that. In advantage, I could use the BindReadOnlyPaths directive to
> > directly manage the necessary bind mount to make the notify socket
> > accessible.
> 
> I'd generally advise this, as it means you can drop caps like
> CAP_SYS_ADMIN and so on right-away, i.e. all the stuff that chroot()
> means.

That would, however, mean to have the bind binary and all libraries in
the chroot as well, which means either a lot of copying or a lot of bind
mounting into the chroot, introducing a number of challenges regarding
updates etc.

Using bind's -t option is charming here because it just needs
configuration, persistent data and a few auxillary files in the chroot.
This has become harder nowadays since bind loads some libraries with
dlopen() after the chroot, so at least those .so files need to be in the
chroot.

> You don't need to explicitly mount the notify socket if you use this
> btw, systemd will do this for you automatically if you combined
> RootDirectory= and Type=notify.

That is nice to know.

> > (2) try to preserve the classic setup
> > That would probably mean having a
> > /etc/systemd/system/var-local-bind-run-systemd.mount with the contents:
> > | [Mount]
> > | What=/run/systemd
> > | Where=/var/local/bind/run/systemd
> > | Type=none
> > | Options=bind
> > |
> > | [Install]
> > | WantedBy=bind9.service
> > and adding a RequiresMountsFor=/var/local/bind/run/systemd to the
> > bind9.service.
> 
> It should suffice bind mounting just the notify socket, not the full
> dir.

Is it intended behavior that an empty file is left at the "mount point"
(what Where= points to) after the unit was stopped?

> You could also use a hybrid approach: let systemd bind mount this for
> your service (and thus set up a minimal namespaced env for your
> service, but with the root where it normally is), and then still let
> bind do its own chroot() thing inside of it).

I do not quite understand exactly what that means, how would I do that?
What is "this" in the "mount this" part of sentence?

> Generally speaking: its typically a better idea to rely on proper fs
> mount namespacing (i.e. decoupling mount tables of services and host)
> rather than plain chroot() (where they aren't decoupled). If bind only
> does chroot(), then I think using systemd's namespacing is the much
> better choice.

Where would I read up on systemd namespacing? Are you refering to what
is explained in the "Sandboxing" chapter of systemd.exec(5), like
ProtectSystem, ReadWritePaths etc?

So I would basically set
ProtectSystem=strict
ReadWritePaths=/var/local/chroot/bind/pathlist (all paths that bind
needs to actually write to) and then finally
ExecStart=/path/to/bind -f -t /var/local/chroot/bind ?

Is that what you mean?

If I set ProtectHome=yes, how do I give the user that bind runs as
access to its homedir? Is ReadWritePaths= the solution?

> > This works as intended when I start up bind9, but when stopping the name
> > daemon, the bind mount still lingers around. I have not fully understood
> > the necessary systemd magic to have var-local-bind-run-systemd.mount
> > stopped whenever bind9.service stops. How would I do that?
> 
> You can do Wants= from bind to the mount unit. And then do
> StopWhenUnneeded= in the mount unit, to release it when not needed.

StopWhenUnneeded was what I needed. So I currently have:

[7/5031]mh@drop:~ $ sudo systemctl cat named
# /lib/systemd/system/named.service
[Unit]
Description=BIND Domain Name Server
Documentation=man:named(8)
After=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
RequiresMountsFor=/var/local/chroot/bind/run/systemd

[Service]
Type=notify
EnvironmentFile=-/etc/default/named
ExecStart=/usr/sbin/named -f $OPTIONS
ExecReload=/usr/sbin/rndc reload
ExecStop=/usr/sbin/rndc stop
Restart=on-failure

[Install]
WantedBy=multi-user.target
Alias=bind9.service
[8/5030]mh@drop:~ $ 

and

1 [9/5031]mh@drop:~ $ sudo systemctl cat var-local-chroot-bind-run-systemd.mount
# /etc/systemd/system/var-local-chroot-bind-run-systemd.mount
[Unit]
StopWhenUnneeded=true

[Mount]
What=/run/systemd
Where=/var/local/chroot/bind/run/systemd
Type=none
Options=bind
[10/5032]mh@drop:~ $ 

(test system, I don't usually edit files in /lib/systemd, I know about the
override mechanisms).

Again, thanks for helping, that is highly appreciated.

Greetings
Marc

-- 
-----------------------------------------------------------------------------
Marc Haber         | "I don't trust Computers. They | Mailadresse im Header
Leimen, Germany    |  lose things."    Winona Ryder | Fon: *49 6224 1600402
Nordisch by Nature |  How to make an American Quilt | Fax: *49 6224 1600421



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux