etc: Add AppArmor profile for the daemon.

* .gitignore: Add etc/apparmor.d/tunables/guix.
* Makefile.am (nodist_apparmor_profile_DATA)
(nodist_apparmor_profile_tunables_DATA): Define it.
* configure.ac: Generate etc/apparmor.d/tunables/guix. Add
--with-apparmor-profile-dir option.
* etc/apparmor.d/guix-daemon: New file.
* etc/apparmor.d/tunables/guix.in: New file.
* doc/guix.texi: Document AppArmor profiles.
* gnu/packages/package-management.scm (guix): Add future changes commented.

Change-Id: Iac7df9d642383cc46a2d450c3badef31199ab041
Signed-off-by: Rutherther <rutherther@ditigal.xyz>
This commit is contained in:
Noé Lopez 2025-12-08 16:39:11 +01:00 committed by Rutherther
parent 9a78e76076
commit 587fd2dad4
No known key found for this signature in database
GPG key ID: 0322798269E471C3
7 changed files with 156 additions and 0 deletions

1
.gitignore vendored
View file

@ -68,6 +68,7 @@
/doc/stamp-vti /doc/stamp-vti
/doc/version.texi /doc/version.texi
/doc/version-*.texi /doc/version-*.texi
/etc/apparmor.d/tunables/guix
/etc/committer.scm /etc/committer.scm
/etc/gnu-store.mount /etc/gnu-store.mount
/etc/guix-daemon.cil /etc/guix-daemon.cil

View file

@ -746,6 +746,13 @@ dist_fishcompletion_DATA = etc/completion/fish/guix.fish
# SELinux policy # SELinux policy
nodist_selinux_policy_DATA = etc/guix-daemon.cil nodist_selinux_policy_DATA = etc/guix-daemon.cil
# AppArmor profiles.
nodist_apparmor_profile_DATA = \
etc/apparmor.d/guix-daemon
nodist_apparmor_profile_tunables_DATA = \
etc/apparmor.d/tunables/guix
EXTRA_DIST += \ EXTRA_DIST += \
.dir-locals.el \ .dir-locals.el \
.guix-authorizations \ .guix-authorizations \

View file

@ -81,6 +81,15 @@ AC_ARG_WITH([selinux-policy-dir],
[selinux_policydir='${datadir}/selinux/']) [selinux_policydir='${datadir}/selinux/'])
AC_SUBST([selinux_policydir]) AC_SUBST([selinux_policydir])
AC_ARG_WITH([apparmor-profile-dir],
AS_HELP_STRING([--with-apparmor-profile-dir=DIR],
[name of the AppArmor profile directory]),
[apparmor_profiledir="$withval"],
[apparmor_profiledir='${sysconfdir}/apparmor.d'])
AC_SUBST([apparmor_profiledir])
apparmor_profile_tunablesdir='${apparmor_profiledir}/tunables'
AC_SUBST([apparmor_profile_tunablesdir])
dnl Better be verbose. dnl Better be verbose.
AC_MSG_CHECKING([for the store directory]) AC_MSG_CHECKING([for the store directory])
AC_MSG_RESULT([$storedir]) AC_MSG_RESULT([$storedir])
@ -308,6 +317,7 @@ AC_CONFIG_FILES([Makefile
po/guix/Makefile.in po/guix/Makefile.in
po/packages/Makefile.in po/packages/Makefile.in
etc/guix-daemon.cil etc/guix-daemon.cil
etc/apparmor.d/tunables/guix
guix/config.scm]) guix/config.scm])
AC_CONFIG_FILES([etc/committer.scm], [chmod +x etc/committer.scm]) AC_CONFIG_FILES([etc/committer.scm], [chmod +x etc/committer.scm])

View file

@ -146,6 +146,7 @@ Copyright @copyright{} 2025 Artur Wroblewski@*
Copyright @copyright{} 2025 Edouard Klein@* Copyright @copyright{} 2025 Edouard Klein@*
Copyright @copyright{} 2025 Rodion Goritskov@* Copyright @copyright{} 2025 Rodion Goritskov@*
Copyright @copyright{} 2025 dan@* Copyright @copyright{} 2025 dan@*
Copyright @copyright{} 2025 Noé Lopez@*
Permission is granted to copy, distribute and/or modify this document Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or under the terms of the GNU Free Documentation License, Version 1.3 or
@ -919,6 +920,7 @@ pre-built binaries.
* Build Environment Setup:: Preparing the isolated build environment. * Build Environment Setup:: Preparing the isolated build environment.
* Daemon Offload Setup:: Offloading builds to remote machines. * Daemon Offload Setup:: Offloading builds to remote machines.
* SELinux Support:: Using an SELinux policy for the daemon. * SELinux Support:: Using an SELinux policy for the daemon.
* AppArmor Support:: Using an AppArmor profile for the daemon.
@end menu @end menu
@node Build Environment Setup @node Build Environment Setup
@ -1097,6 +1099,8 @@ systemctl daemon-reload
systemctl start guix-daemon systemctl start guix-daemon
@end example @end example
If your system has AppArmor enabled, @pxref{AppArmor Support}.
@quotation Warning @quotation Warning
The commands above assume that @command{guix pull} was run for the root The commands above assume that @command{guix pull} was run for the root
user. You can check whether this is the case by running this command: user. You can check whether this is the case by running this command:
@ -1526,6 +1530,43 @@ installation time whenever the Guix package that provides the
effectively running @code{guix-daemon} executable is upgraded. effectively running @code{guix-daemon} executable is upgraded.
@end enumerate @end enumerate
@node AppArmor Support
@subsection AppArmor Support
@cindex AppArmor
Guix includes an AppArmor profile for the build daemon in
@file{etc/apparmor.d/guix-daemon} that can be installed on systems with
strict AppArmor policies to allow it to run unprivileged
(@pxref{Build Environment Setup}). Indeed, the unprivileged daemon makes
use of Linux user namespaces but these are disallowed
without an AppArmor policy on some systems like Ubuntu.
To know if this applies to you, check if the
@code{kernel.apparmor_restrict_unprivileged_userns} kernel parameter is
enabled.
@subsubsection Installing the AppArmor profile
@cindex AppArmor, profile installation
@quotation Note
The @code{guix-install.sh} binary installation script offers to perform
the steps below for you (@pxref{Binary Installation}).
@end quotation
Run these commands as root to install the profile:
@example
export apparmor_sources=/var/guix/profiles/per-user/root/current-guix/etc/apparmor.d
cp -f -t /etc/apparmor.d/tunables "$apparmor_sources/tunables/guix"
cp -f -t /etc/apparmor.d "$apparmor_sources/guix-daemon"
cp -f -t /etc/apparmor.d "$apparmor_sources/guix"
apparmor_parser -r /etc/apparmor.d/guix-daemon
apparmor_parser -r /etc/apparmor.d/guix
@end example
After this, the build daemon will be able to function correctly.
@node Invoking guix-daemon @node Invoking guix-daemon
@section Invoking @command{guix-daemon} @section Invoking @command{guix-daemon}
@cindex @command{guix-daemon} @cindex @command{guix-daemon}

View file

@ -0,0 +1,88 @@
abi <abi/4.0>,
include <tunables/global>
include <tunables/guix>
profile guix-daemon @{guix_storedir}/*-{guix-daemon,guix}-*/bin/guix-daemon flags=(enforce,attach_disconnected.path=/disconnected) {
include <abstractions/base>
userns,
signal,
capability sys_admin,
capability net_admin,
capability sys_chroot,
capability setgid,
capability chown,
network dgram,
umount,
mount,
pivot_root,
# Paths inside build chroot
/real-root/ w,
/ w,
@{guix_localstatedir}/guix/** rwk,
/var/log/guix/** w,
owner @{PROC}/@{pid}/{fd/,environ} r,
owner @{PROC}/@{pid}/oom_score_adj w,
owner @{PROC}/@{pid}/uid_map rw,
owner @{PROC}/@{pid}/gid_map rw,
owner @{PROC}/@{pid}/setgroups w,
@{guix_storedir}/ r,
@{guix_storedir}/** rwlmk,
@{guix_storedir}/*/bin/guile cx -> guix-builder,
@{guix_storedir}/*-guix-command cx -> guix-helper,
@{guix_storedir}/*-guix-*/bin/guix cx -> guix-helper,
@{etc_rw}/nsswitch.conf r,
@{etc_rw}/passwd r,
@{etc_rw}/group r,
owner /tmp/** rwl,
owner /var/tmp/** rwl,
/usr/bin/newgidmap Ux,
# Site-specific additions and overrides. See local/README for details.
include if exists <local/guix-daemon>
profile guix-builder flags=(enforce,attach_disconnected.path=/disconnected) {
include <abstractions/base>
signal (receive),
@{guix_storedir}/** rwlmkux,
owner /tmp/** rw,
@{PROC}/@{pid}/fd/ r,
/disconnected/** rw,
}
# This is for any time guix is called by the daemon as a helper:
# - guix download
# - guix discover
# - guix gc --list-busy
# - probably more?
profile guix-helper flags=(enforce,attach_disconnected.path=/disconnected) {
include <abstractions/base>
include <abstractions/nameservice>
signal (receive),
ptrace (read) peer=guix-daemon,
/disconnected/run/dbus/system_bus_socket rw,
dbus (send, receive),
@{guix_localstatedir}/guix/discover/ rw,
@{guix_localstatedir}/guix/discover/* rw,
@{guix_localstatedir}/guix/substitute/ rw,
@{guix_localstatedir}/guix/substitute/** rwk,
@{guix_sysconfdir}/guix/** r,
@{guix_storedir}/** rwlmix,
@{PROC}/ r,
owner @{PROC}/@{pid}/{fd/,environ} r,
}
}

View file

@ -0,0 +1,5 @@
@{guix_storedir} = @storedir@
@{guix_sysconfdir} = @guix_sysconfdir@
@{guix_localstatedir} = @guix_localstatedir@
include if exists <tunables/guix.d>

View file

@ -234,6 +234,10 @@
(string-append "--with-bash-completion-dir=" (string-append "--with-bash-completion-dir="
(assoc-ref %outputs "out") (assoc-ref %outputs "out")
"/etc/bash_completion.d") "/etc/bash_completion.d")
;; TODO: Uncomment after guix is updated.
;; (string-append "--with-apparmor-profile-dir="
;; (assoc-ref %outputs "out")
;; "/etc/apparmor.d")
;; Set 'DOT_USER_PROGRAM' to the empty string so ;; Set 'DOT_USER_PROGRAM' to the empty string so
;; we don't keep a reference to Graphviz, whose ;; we don't keep a reference to Graphviz, whose