From 6baf5127acda239740218dd7178631bcb0c2fa44 Mon Sep 17 00:00:00 2001 From: Luca Di Maio Date: Sun, 6 Aug 2023 11:37:50 +0200 Subject: [PATCH] init: use host's /etc/passwd in rootful setups This will ensure rootful containers (podman/docker) will not setup passwordless sudo/su, and instead use host's passwords It's still less secure than a full rootless setup, but it's better now than an open gate to root. Signed-off-by: Luca Di Maio --- distrobox-init | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/distrobox-init b/distrobox-init index 7553789a16..0132ac1251 100755 --- a/distrobox-init +++ b/distrobox-init @@ -1446,7 +1446,10 @@ fi # If we're running this script as root in a login shell (sudoless), we don't # have to bother setting up sudo. -if [ "${container_user_uid}" -ne 0 ]; then +# +# Also if we're in a rootful container, we can just use host's /etc/shadow to +# secure user passwords, so let's skip passwordless sudo too +if [ "${container_user_uid}" -ne 0 ] && [ ! -r /run/host/etc/shadow ] && [ ! -e /etc/passwd.done ]; then printf "distrobox: Setting up sudo...\n" mkdir -p /etc/sudoers.d # Do not check fqdn when doing sudo, it will not work anyways @@ -1514,6 +1517,7 @@ if ! grep "^$(printf '%s' "${container_user_name}" | tr '\\' '.'):" /etc/passwd; "${container_user_home}" "${SHELL:-"/bin/bash"}" >> /etc/passwd printf "%s::1::::::" "${container_user_name}" >> /etc/shadow fi + touch /etc/passwd.done # Ensure we're not using the specified SHELL. Run it only once, so that future # user's preferences are not overwritten at each start. elif [ ! -e /etc/passwd.done ]; then @@ -1541,13 +1545,22 @@ elif [ ! -e /etc/passwd.done ]; then touch /etc/passwd.done fi -# We generate a random password to initialize the entry for the user and root. -temporary_password="$(cat /proc/sys/kernel/random/uuid)" -printf "%s\n%s\n" "${temporary_password}" "${temporary_password}" | passwd root -printf "%s:%s" "${container_user_name}" "${temporary_password}" | chpasswd -e -# Delete password for root and user -printf "%s:" "root" | chpasswd -e -printf "%s:" "${container_user_name}" | chpasswd -e +# If we have read access to host's /etc/shadow, let's mount it read-only in the +# container, so that sudo, and su has a password and that's the same as the host +# +# else we fallback to the usual setup with passwordless sudo/su user. This is +# likely because we're in a rootless setup, so privilege escalation is not a concern. +if [ -r /run/host/etc/shadow ]; then + mount_bind /run/host/etc/shadow /etc/shadow ro +elif [ ! -e /etc/passwd.done ]; then + # We generate a random password to initialize the entry for the user and root. + temporary_password="$(cat /proc/sys/kernel/random/uuid)" + printf "%s\n%s\n" "${temporary_password}" "${temporary_password}" | passwd root + printf "%s:%s" "${container_user_name}" "${temporary_password}" | chpasswd -e + # Delete password for root and user + printf "%s:" "root" | chpasswd -e + printf "%s:" "${container_user_name}" | chpasswd -e +fi # If we do not have profile files in the home, we should copy the # skeleton files, if present.