GNU bug report logs - #75810
[PATCH 0/6] Rootless guix-daemon

Previous Next

Package: guix-patches;

Reported by: Ludovic Courtès <ludo <at> gnu.org>

Date: Fri, 24 Jan 2025 17:24:02 UTC

Severity: normal

Tags: patch

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: help-debbugs <at> gnu.org (GNU bug Tracking System)
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: tracker <at> debbugs.gnu.org
Subject: bug#75810: closed ([PATCH 0/6] Rootless guix-daemon)
Date: Wed, 26 Mar 2025 17:08:04 +0000
[Message part 1 (text/plain, inline)]
Your message dated Wed, 26 Mar 2025 18:07:13 +0100
with message-id <87v7rvk9fi.fsf <at> gnu.org>
and subject line Re: [bug#75810] [PATCH v8 07/16] daemon: Allow running as non-root with unprivileged user namespaces.
has caused the debbugs.gnu.org bug report #75810,
regarding [PATCH 0/6] Rootless guix-daemon
to be marked as done.

(If you believe you have received this mail in error, please contact
help-debbugs <at> gnu.org.)


-- 
75810: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=75810
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
From: Ludovic Courtès <ludo <at> gnu.org>
To: guix-patches <at> gnu.org
Cc: Ludovic Courtès <ludovic.courtes <at> inria.fr>
Subject: [PATCH 0/6] Rootless guix-daemon
Date: Fri, 24 Jan 2025 18:23:08 +0100
From: Ludovic Courtès <ludovic.courtes <at> inria.fr>

Hello Guix!

That guix-daemon runs as root is not confidence-inspiring for many.
Initially, the main reason for running it as root was, in the absence
of user namespaces, the fact that builders would be started under one
of the build user accounts, which only root can do.  Now that
unprivileged user namespaces are almost ubiquitous (even on HPC
clusters), this is no longer a good reason.

This patch changes guix-daemon so it can run as an unprivileged
user, using unprivileged user namespaces to still support isolated
builds.  There’s a couple of cases where root is/was still necessary:

  1. To create /var/guix/profiles/per-user/$USER and chown it
     as $USER (see CVE-2019-18192).

  2. To chown /tmp/guix-build-* when using ‘--keep-failed’.

Both can be addressed by giving CAP_CHOWN to guix-daemon, and this is
what this patch series does on distros using systemd.  (For some
reason CAP_CHOWN had to be added to the set of “ambient capabilities”,
which are inherited by child processes; this is why there’s a patch
to drop ambient capabilities in build processes.)

On Guix System (not implemented here), we could address (1) by
creating /var/guix/profiles/per-user/$USER upfront for all the
user accounts.  We could leave (2) unaddressed (so failed build
directories would be owned by guix-daemon:guix-daemon) or we’d
have to pass CAP_CHOWN as well.

There’s another issue: /gnu/store can no longer be remounted
read-only (like we do on Guix System and on systemd with
‘gnu-store.mount’) because then unprivileged guix-daemon would
be unable to remount it read-write (or at least I couldn’t find
a way to do that).  Thus ‘guix-install.sh’ no longer installs
‘gnu-store.mount’ in that case.  It’s a bit sad to lose that
so if anyone can think of a way to achieve it, that’d be great.

I tested all this in a Debian VM¹, along these lines:

  1. GUIX_ALLOW_ME_TO_USE_PRIVATE_COMMIT=yes make update-guix-package
  2. ./pre-inst-env guix pack -C zstd guix --without-tests=guix \
        --localstatedir --profile-name=current-guix
  3. Copy ‘guix-install.sh’ and the tarball to the VM over SSH.
  4. In the VM: GUIX_BINARY_FILE_NAME=pack.tar.zst ./guix-install.sh

The next step (in another patch series) would be Guix System support
with automatic transition (essentially “chown -R
guix-daemon:guix-daemon /gnu/store”).

Thoughts?

Ludo’.

¹ https://cdimage.debian.org/debian-cd/current-live/amd64/iso-hybrid/debian-live-12.9.0-amd64-standard.iso

Ludovic Courtès (6):
  daemon: Allow running as non-root with unprivileged user namespaces.
  DRAFT tests: Run in a chroot and unprivileged user namespaces.
  daemon: Create /var/guix/profiles/per-user unconditionally.
  daemon: Drop Linux ambient capabilities before executing builder.
  etc: systemd services: Run ‘guix-daemon’ as an unprivileged user.
  guix-install.sh: Support the unprivileged daemon where possible.

 build-aux/test-env.in       |  14 +++-
 config-daemon.ac            |   2 +-
 etc/guix-daemon.service.in  |  12 +++-
 etc/guix-install.sh         | 114 ++++++++++++++++++++++++-------
 guix/substitutes.scm        |   4 +-
 nix/libstore/build.cc       | 132 ++++++++++++++++++++++++++++++------
 nix/libstore/local-store.cc |  30 +++++---
 tests/store.scm             |  89 ++++++++++++++----------
 8 files changed, 300 insertions(+), 97 deletions(-)


base-commit: bc6769f1211104dbc9341c064275cd930f5dfa3a
-- 
2.47.1



[Message part 3 (message/rfc822, inline)]
From: Ludovic Courtès <ludo <at> gnu.org>
To: Reepca Russelstein <reepca <at> russelstein.xyz>
Cc: 75810-done <at> debbugs.gnu.org
Subject: Re: [bug#75810] [PATCH v8 07/16] daemon: Allow running as non-root
 with unprivileged user namespaces.
Date: Wed, 26 Mar 2025 18:07:13 +0100
Reepca Russelstein <reepca <at> russelstein.xyz> skribis:

> Looks good to me.

Pushed as a9239a769c5611f12061c9a895e4e218b3445e2f.

  a9239a769c * guix-install.sh: Support the unprivileged daemon where possible.
  107eb8ee8f * etc: systemd services: Run ‘guix-daemon’ as an unprivileged user.
  2f65438eba * tests: Run in a chroot and unprivileged user namespaces.
  f854095b6f * tests: Add missing derivation inputs.
  29164192e9 * linux-container: ‘unprivileged-user-namespace-supported?’ returns #f on non-Linux.
  bdd7b9a45d * daemon: Move comments where they belong.
  0163c732a1 * daemon: Drop Linux ambient capabilities before executing builder.
  a3d6f5ae70 * daemon: Create /var/guix/profiles/per-user unconditionally.
  ae18b3d9e6 * daemon: Allow running as non-root with unprivileged user namespaces.
  40f69b586a * daemon: Remount root directory as read-only.
  93474f9288 * daemon: Remount inputs as read-only.
  550ca89744 * daemon: Bind-mount all the inputs, not just directories.
  5c0b93b244 * daemon: Bind-mount /etc/nsswitch.conf & co. only if it exists.
  7bad04fac0 * daemon: Close the read end of the logging pipe.
  f03e6eff2f * daemon: Use ‘close_range’ where available.

Thanks a *lot*, Reepca.

If you liked this patch series, surely you’ll enjoy this followup:

  https://issues.guix.gnu.org/77288

:-)

Ludo’.


This bug report was last modified 56 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.