Package: apache2-bin Version: 2.4.62-3 Severity: normal Tags: upstream Hi,
I'm trying to start apache as a non-root user, with a minimal set of capabilities that allow it to work. My command line looks like this: capsh \ --keep=1 \ --gid=33 \ --groups=33 \ --caps="cap_net_bind_service+eip cap_sys_chroot+eip cap_setuid+ep" \ --uid=33 \ --addamb=cap_net_bind_service,cap_sys_chroot \ --print \ -- \ -c '/usr/sbin/apache2 -d "/etc/apache2" -DSSL -DNO_DETACH -DFOREGROUND -f "/etc/apache2/apache2.conf"' Diagnostic output from capsh(1) confirms capabilities are set correctly: Current: cap_net_bind_service,cap_sys_chroot=ip cap_setuid+p Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read,cap_perfmon,cap_bpf,cap_checkpoint_restore Ambient set =cap_net_bind_service,cap_sys_chroot Current IAB: ^cap_net_bind_service,^cap_sys_chroot Securebits: 020/0x10/5'b10000 (no-new-privs=0) secure-noroot: no (unlocked) secure-no-suid-fixup: no (unlocked) secure-keep-caps: yes (unlocked) secure-no-ambient-raise: no (unlocked) uid=33(www-data) euid=33(www-data) gid=33(www-data) groups=33(www-data) Guessed mode: UNCERTAIN (0) However, apache says: [unixd:alert] [pid 24573:tid 24573] AH02158: Cannot chroot when not started as root The same capsh command works with merecat httpd and allows it to chroot. The problem seems to be that in modules/arch/unix/mod_unixd.c, in static int unixd_drop_privileges(apr_pool_t *pool, server_rec *s), the code explicitly checks for geteuid() == 0 and doesn't even attempt the chroot if it's not running as root: if (geteuid()) { rv = errno; ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, APLOGNO(02158) "Cannot chroot when not started as root"); return rv; } This is just wrong. Apache has no business trying to guess what the kernel will allow it to do; there could be an arbitrary security/privilege mechanism (not just capabilities) in place that will allow this particular process to chroot to that particular directory at this particular time of day. Apache can't know this unless it tries to chroot. I think this check should be dropped; at most, if the chroot doesn't succeed, AND we're not running as root, Apache could include this information as a hint in the error message. "Cannot chroot when not started as root" is factually incorrect. Also, happy new year! AndrĂ¡s -- System Information: Debian Release: trixie/sid APT prefers stable-security APT policy: (500, 'stable-security'), (350, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 6.12.5-amd64 (SMP w/8 CPU threads; PREEMPT) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=hu_HU.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 Shell: /bin/sh linked to /usr/bin/dash Init: runit (via /run/runit.stopit) LSM: AppArmor: enabled -- There are more airplanes in the ocean than there are submarines in the air.