From 37f00dec06261347806aba06d8717442339d8c31 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 15:17:21 +0000 Subject: [PATCH] Fix SSH logins into containers on Ubuntu 24.04 Two Noble-specific regressions broke `Permission denied (publickey)`: 1. The 24.04 base image ships a default 'ubuntu' user/group at UID/GID 1000. 02_user.sh runs `adduser --uid=1000`, which fails because the UID is taken; under `set -e` the whole startup aborted before the SSH key was installed (and before sshd started). Remove any user/group squatting on the requested UID/GID first. 22.04 has no user at 1000, so it was never affected. 2. `adduser --disabled-password` leaves the shadow password as '!' (locked). OpenSSH 9.x (24.04) refuses all authentication -- including publickey -- for locked accounts ("account is locked"), whereas 8.x (22.04) only applied this to password auth. Swap '!' for '*': still no usable password, but the account is no longer treated as locked. Verified end-to-end with real key logins on both ubuntu:24.04 and ubuntu:22.04 base images. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01CQUc7qbigQhV69kdg16eLa --- CHANGELOG | 1 + base/etc/runit_init.d/02_user.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 1fcca58..1deee4c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ Changes for v1.13: - fixed USER_GROUPS not honoring the requested GID when it was already in use (e.g. docker=998 colliding with the runit-log groups) - replaced obsolete libgl1-mesa-glx with libgl1 + libglx-mesa0 in base image so it builds on Ubuntu 24.04 (package was dropped in Noble) - jupyter image now installs into a dedicated virtualenv (/opt/jupyter-venv) instead of the system Python, fixing the PEP 668 externally-managed-environment failure on Ubuntu 24.04 while remaining compatible with older releases + - fixed SSH logins on Ubuntu 24.04: remove the default 'ubuntu' user/group squatting on UID/GID 1000 (its presence aborted user provisioning before the SSH key was installed), and unlock the account password field ('!' -> '*') since OpenSSH 9.x refuses publickey auth for locked accounts - minor update: - added CCC FUSE sidecar client shim integration for FUSE-enabled containers - added startup relink hook for fusermount3/fusermount/fusemount helper names after package installs diff --git a/base/etc/runit_init.d/02_user.sh b/base/etc/runit_init.d/02_user.sh index 1952a63..398d6c1 100755 --- a/base/etc/runit_init.d/02_user.sh +++ b/base/etc/runit_init.d/02_user.sh @@ -8,8 +8,37 @@ USER_PUBKEY=${USER_PUBKEY} USER_HOME=${BASE%"/"}/$USER_NAME +# Ubuntu 24.04 base images ship a default 'ubuntu' user (and group) at UID/GID +# 1000. When the requested USER_ID/USER_NAME differs, that pre-existing entry +# squats on the UID and `adduser --uid` fails; under `set -e` that aborts the +# whole startup before the SSH key is installed, which breaks SSH logins (this +# is never hit on 22.04, whose base image has no user at UID 1000). Remove the +# conflicting default user/group first so we can claim the requested IDs. +EXISTING_USER=$(getent passwd "$USER_ID" | cut -d: -f1) +if [ -n "$EXISTING_USER" ] && [ "$EXISTING_USER" != "$USER_NAME" ]; then + echo "Removing default user '$EXISTING_USER' occupying UID $USER_ID" + deluser "$EXISTING_USER" > /dev/null 2>&1 || userdel "$EXISTING_USER" > /dev/null 2>&1 || true +fi +EXISTING_GROUP=$(getent group "$USER_ID" | cut -d: -f1) +if [ -n "$EXISTING_GROUP" ] && [ "$EXISTING_GROUP" != "$USER_NAME" ]; then + echo "Removing default group '$EXISTING_GROUP' occupying GID $USER_ID" + groupdel "$EXISTING_GROUP" > /dev/null 2>&1 || true +fi + getent passwd $USER_NAME || adduser --uid=$USER_ID --home=$USER_HOME --disabled-password --gecos "" $USER_NAME +# OpenSSH 9.x (Ubuntu 24.04) refuses *all* authentication -- including publickey +# -- for accounts whose password is "locked", i.e. a shadow field starting with +# '!' as left by `adduser --disabled-password` (sshd logs "account is locked"). +# OpenSSH 8.x (22.04) only applied that to password auth, so key logins worked. +# Swap the locked '!' for '*': still no usable password (password auth stays +# disabled, and PasswordAuthentication is off anyway), but the account is no +# longer considered locked, so key-based logins work on 22.04 and 24.04 alike. +CURRENT_PW=$(getent shadow "$USER_NAME" | cut -d: -f2) +case "$CURRENT_PW" in + '!'*) usermod -p '*' "$USER_NAME" ;; +esac + if [ ! -z "${USER_GROUPS}" ]; then # split groups into list using ',' as separator IFS=',' read -ra USER_GROUPS <<< "${USER_GROUPS}"