]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: startup: warn when chroot is not set for root
authorWilly Tarreau <w@1wt.eu>
Wed, 20 May 2026 09:30:32 +0000 (11:30 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 20 May 2026 09:51:45 +0000 (11:51 +0200)
We're still regularly seeing insecure configs where chroot is missing.
Now that we have "chroot auto", there's no excuse for not knowing where
to chroot, so let's detect that we're starting as root, detect that the
process is allowed to chroot (i.e. no capability issue, or some hardened
containers), and if no chroot is set, let's emit a warning explaining how
to silence it, i.e. either "chroot auto" or "chroot /".

Most likely we'll start using "chroot auto" by default in 3.5 if no
usability issue is reported.

doc/configuration.txt
src/haproxy.c

index 7f4f927fe457dd38bfa2cbff6564532b331ad552..6139d19a87ba12b2c7cf04f9275bd4c562f74067 100644 (file)
@@ -2142,6 +2142,13 @@ chroot { <jail dir> | auto }
   The resulting jail has no name in the filesystem and is empty and read-only,
   removing the need to prepare a dedicated jail directory.
 
+  When starting with superuser privileges, a warning will be displayed if no
+  chroot is used, in order to encourage users to always use the mechanism. If
+  for any reason there is a compelling reason not to use chroot (e.g. access to
+  a server via a UNIX socket with an unconvenient path), it remains possible to
+  silence the warning by adding an explicit "chroot /", which has the benefit
+  of being visible in a configuration.
+
 close-spread-time <time>
   Define a time window during which idle connections and active connections
   closing is spread in case of soft-stop. After a SIGUSR1 is received and the
index 68ab5d5eeccedc83b81c43d021b6fda4a0e8de2b..ffd969d8ce30b4c6adc37b6fb4dce117d170adba 100644 (file)
@@ -3681,6 +3681,27 @@ int main(int argc, char **argv)
                }
        }
 
+       /* privileged users should use chroot whenever possible; use chroot /
+        * if really not wanted.
+        */
+
+       if (!global.chroot) {
+               int chroot_permitted = geteuid() == 0;
+
+#if defined(USE_PRCTL) && defined(PR_CAPBSET_READ) && defined(CAP_SYS_CHROOT)
+               chroot_permitted &= (prctl(PR_CAPBSET_READ, CAP_SYS_CHROOT, 0, 0, 0) == 1);
+#endif
+               if (chroot_permitted) {
+                       ha_warning("[%s.main()] HAProxy was started as root without any 'chroot' "
+                                  "directive. A chroot limits filesystem access of an intruder "
+                                  "to a single, preferably empty, directory. It is strongly recommended "
+                                  "to enable this feature whenever possible (it's always possible when "
+                                  "starting as root), via 'chroot auto' in the global section. If you "
+                                  "think you have good reasons for running outside a chroot, explicitly "
+                                  "configure 'chroot /' to silence this warning.\n", argv[0]);
+               }
+       }
+
 #ifdef CLONE_NEWUSER
        /* When we aren't root and intend to chroot, we try the Linux-only
         * unshare(CLONE_NEWUSER) mechanism if available to allow chroot as an