MEDIUM: startup: warn when chroot is not set for root

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.
This commit is contained in:
Willy Tarreau 2026-05-20 11:30:32 +02:00
parent 3c35e7f137
commit b9acb4415f
2 changed files with 28 additions and 0 deletions

View 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

View 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