summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am7
-rw-r--r--configure.ac10
-rw-r--r--doc/guix.texi41
-rw-r--r--etc/apparmor.d/guix-daemon88
-rw-r--r--etc/apparmor.d/tunables/guix.in5
-rw-r--r--gnu/packages/package-management.scm4
7 files changed, 156 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 4f7308b295c..8779222df0c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,6 +68,7 @@
/doc/stamp-vti
/doc/version.texi
/doc/version-*.texi
+/etc/apparmor.d/tunables/guix
/etc/committer.scm
/etc/gnu-store.mount
/etc/guix-daemon.cil
diff --git a/Makefile.am b/Makefile.am
index 106849e89f0..bf7d1556f0e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -746,6 +746,13 @@ dist_fishcompletion_DATA = etc/completion/fish/guix.fish
# SELinux policy
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 += \
.dir-locals.el \
.guix-authorizations \
diff --git a/configure.ac b/configure.ac
index 82f12507745..6ad8e427736 100644
--- a/configure.ac
+++ b/configure.ac
@@ -81,6 +81,15 @@ AC_ARG_WITH([selinux-policy-dir],
[selinux_policydir='${datadir}/selinux/'])
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.
AC_MSG_CHECKING([for the store directory])
AC_MSG_RESULT([$storedir])
@@ -308,6 +317,7 @@ AC_CONFIG_FILES([Makefile
po/guix/Makefile.in
po/packages/Makefile.in
etc/guix-daemon.cil
+ etc/apparmor.d/tunables/guix
guix/config.scm])
AC_CONFIG_FILES([etc/committer.scm], [chmod +x etc/committer.scm])
diff --git a/doc/guix.texi b/doc/guix.texi
index d7d40ceb223..fc25b653f32 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -146,6 +146,7 @@ Copyright @copyright{} 2025 Artur Wroblewski@*
Copyright @copyright{} 2025 Edouard Klein@*
Copyright @copyright{} 2025 Rodion Goritskov@*
Copyright @copyright{} 2025 dan@*
+Copyright @copyright{} 2025 NoƩ Lopez@*
Permission is granted to copy, distribute and/or modify this document
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.
* Daemon Offload Setup:: Offloading builds to remote machines.
* SELinux Support:: Using an SELinux policy for the daemon.
+* AppArmor Support:: Using an AppArmor profile for the daemon.
@end menu
@node Build Environment Setup
@@ -1097,6 +1099,8 @@ systemctl daemon-reload
systemctl start guix-daemon
@end example
+If your system has AppArmor enabled, @pxref{AppArmor Support}.
+
@quotation Warning
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:
@@ -1526,6 +1530,43 @@ installation time whenever the Guix package that provides the
effectively running @code{guix-daemon} executable is upgraded.
@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
@section Invoking @command{guix-daemon}
@cindex @command{guix-daemon}
diff --git a/etc/apparmor.d/guix-daemon b/etc/apparmor.d/guix-daemon
new file mode 100644
index 00000000000..cb1ee92685c
--- /dev/null
+++ b/etc/apparmor.d/guix-daemon
@@ -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,
+ }
+}
diff --git a/etc/apparmor.d/tunables/guix.in b/etc/apparmor.d/tunables/guix.in
new file mode 100644
index 00000000000..e93f7caeb7d
--- /dev/null
+++ b/etc/apparmor.d/tunables/guix.in
@@ -0,0 +1,5 @@
+@{guix_storedir} = @storedir@
+@{guix_sysconfdir} = @guix_sysconfdir@
+@{guix_localstatedir} = @guix_localstatedir@
+
+include if exists <tunables/guix.d> \ No newline at end of file
diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm
index f04bd5efd9f..eadaea4967d 100644
--- a/gnu/packages/package-management.scm
+++ b/gnu/packages/package-management.scm
@@ -234,6 +234,10 @@
(string-append "--with-bash-completion-dir="
(assoc-ref %outputs "out")
"/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
;; we don't keep a reference to Graphviz, whose