From 0e6d5595ecee4994b5cab6be503c6ab52c9cbfe6 Mon Sep 17 00:00:00 2001 From: Edouard MANGEL Date: Sat, 28 Mar 2026 14:06:22 +0100 Subject: [PATCH 1/2] fix: robust SSH setup with non-root accounts and graceful error handling - setup.sh: prompt for initial admin account (default: root) to support providers that use ubuntu, ec2-user, admin, etc. instead of root - setup.sh: wrap ssh-copy-id and manual pipe fallback in error handlers; show clear error message and retry command on failure instead of silent crash via set -e - setup.sh: set USE_SUDO=true when initial account is not root - setup.sh: persist INITIAL_USER in local state; restore on resume; use as third connection fallback in update mode (after username and root) - setup.sh: fix silent crash when reading INITIAL_USER from old state files that predate this field (grep miss + pipefail = silent exit) - security.sh: fall back to root when deploy user cannot connect; keeps USERNAME as the audit target while SSH_USER handles the connection - vpskit.sh: fix unbound variable crash in EXIT trap when a child script exits via set -e (use ${tmp_script:-}); restore _LANG_TMP cleanup trap after run_script() instead of unconditionally clearing it - lang/en.sh + lang/fr.sh: add messages for initial user prompt, key-copy failure hint, and security audit root fallback --- lang/en.sh | 8 +++++++- lang/fr.sh | 8 +++++++- security.sh | 23 +++++++++++++++-------- setup.sh | 40 ++++++++++++++++++++++++++++++++++------ vpskit.sh | 8 ++++++-- 5 files changed, 69 insertions(+), 18 deletions(-) mode change 100644 => 100755 vpskit.sh diff --git a/lang/en.sh b/lang/en.sh index 13bd3d9..3a492de 100644 --- a/lang/en.sh +++ b/lang/en.sh @@ -188,12 +188,15 @@ MSG_SETUP_NEW_IP_PROMPT="VPS IP address: " MSG_SETUP_NEW_IP_REQUIRED_ERR="IP address required. Cancelled." MSG_SETUP_NEW_IP_INVALID_ERR="Invalid IP address: %s" MSG_SETUP_NEW_IP_FORMAT="Address must be in the format: 123.45.67.89" +MSG_SETUP_NEW_INITIAL_USER_PROMPT="Initial admin account on this server (default: root — enter e.g. ubuntu or admin if needed): " MSG_SETUP_NEW_STEP3_TITLE="Step 3/3: Sending the SSH key to the server" -MSG_SETUP_NEW_STEP3_DESC="Your public key will be sent to the VPS so you can\n connect without a password from now on.\n It will ask for the root password ONE LAST TIME." +MSG_SETUP_NEW_STEP3_DESC="Your public key will be sent to the VPS so you can\n connect without a password from now on.\n It will ask for the server password ONE LAST TIME." MSG_SETUP_NEW_STEP3_CONFIRM="Continue? (y/N): " MSG_SETUP_NEW_STEP3_MANUAL_SEND="Sending key manually (ssh-copy-id not available)..." MSG_SETUP_NEW_STEP3_SUCCESS="SSH key sent to the server." MSG_SETUP_NEW_STEP3_SKIPPED="Step skipped. Make sure your key is on the server." +MSG_SETUP_NEW_STEP3_COPY_FAILED="Failed to send SSH key to the server (wrong password or password auth disabled)." +MSG_SETUP_NEW_STEP3_COPY_FAILED_HINT="You can try again manually with:" MSG_SETUP_NEW_CONNTEST_INFO="Testing SSH connection..." MSG_SETUP_NEW_CONNTEST_OK="SSH connection successful!" MSG_SETUP_NEW_CONNTEST_ERR="Unable to connect. Check the IP and that the key is on the server." @@ -733,6 +736,9 @@ MSG_SECURITY_ERR_USER_REQUIRED="Username required." MSG_SECURITY_ERR_IP_INVALID="Invalid IP address: %s" MSG_SECURITY_ERR_IP_FORMAT=" Address must be in the format: 123.45.67.89" MSG_SECURITY_CONNECTING="Connecting to the server..." +MSG_SECURITY_WARN_USER_FAILED="Cannot connect as %s, trying root..." +MSG_SECURITY_TRYING_ROOT="Falling back to root..." +MSG_SECURITY_CONNECTED_AS_ROOT="Connected as root. The audit will run but some user-specific checks may differ." MSG_SECURITY_ERR_CONNECT="Unable to connect to %s@%s" MSG_SECURITY_ERR_CONNECT_HINT=" Check the IP, SSH key and username." MSG_SECURITY_SENDING="Sending audit script..." diff --git a/lang/fr.sh b/lang/fr.sh index 7c64a98..169d640 100644 --- a/lang/fr.sh +++ b/lang/fr.sh @@ -192,12 +192,15 @@ MSG_SETUP_NEW_IP_PROMPT="Adresse IP du VPS : " MSG_SETUP_NEW_IP_REQUIRED_ERR="Adresse IP requise. Annule." MSG_SETUP_NEW_IP_INVALID_ERR="Adresse IP invalide : %s" MSG_SETUP_NEW_IP_FORMAT="L'adresse doit etre au format : 123.45.67.89" +MSG_SETUP_NEW_INITIAL_USER_PROMPT="Compte admin initial sur ce serveur (par defaut : root — entrez ex. ubuntu ou admin si necessaire) : " MSG_SETUP_NEW_STEP3_TITLE="Etape 3/3 : Envoi de la cle SSH sur le serveur" -MSG_SETUP_NEW_STEP3_DESC="On va envoyer votre cle publique sur le VPS pour pouvoir\n se connecter sans mot de passe par la suite.\n Il vous demandera le mot de passe root UNE DERNIERE FOIS." +MSG_SETUP_NEW_STEP3_DESC="On va envoyer votre cle publique sur le VPS pour pouvoir\n se connecter sans mot de passe par la suite.\n Il vous demandera le mot de passe du serveur UNE DERNIERE FOIS." MSG_SETUP_NEW_STEP3_CONFIRM="Continuer ? (o/N) : " MSG_SETUP_NEW_STEP3_MANUAL_SEND="Envoi manuel de la cle (ssh-copy-id non disponible)..." MSG_SETUP_NEW_STEP3_SUCCESS="Cle SSH envoyee sur le serveur." MSG_SETUP_NEW_STEP3_SKIPPED="Etape ignoree. Assurez-vous que votre cle est sur le serveur." +MSG_SETUP_NEW_STEP3_COPY_FAILED="Echec de l'envoi de la cle SSH (mauvais mot de passe ou auth par mot de passe desactivee)." +MSG_SETUP_NEW_STEP3_COPY_FAILED_HINT="Vous pouvez reessayer manuellement avec :" MSG_SETUP_NEW_CONNTEST_INFO="Test de connexion SSH..." MSG_SETUP_NEW_CONNTEST_OK="Connexion SSH reussie !" MSG_SETUP_NEW_CONNTEST_ERR="Impossible de se connecter. Verifiez l'IP et que la cle est bien sur le serveur." @@ -737,6 +740,9 @@ MSG_SECURITY_ERR_USER_REQUIRED="Nom d'utilisateur requis." MSG_SECURITY_ERR_IP_INVALID="Adresse IP invalide : %s" MSG_SECURITY_ERR_IP_FORMAT=" L'adresse doit etre au format : 123.45.67.89" MSG_SECURITY_CONNECTING="Connexion au serveur..." +MSG_SECURITY_WARN_USER_FAILED="Impossible de se connecter en tant que %s, tentative avec root..." +MSG_SECURITY_TRYING_ROOT="Repli sur root..." +MSG_SECURITY_CONNECTED_AS_ROOT="Connecte en tant que root. L'audit fonctionnera mais certaines verifications utilisateur peuvent differer." MSG_SECURITY_ERR_CONNECT="Impossible de se connecter a %s@%s" MSG_SECURITY_ERR_CONNECT_HINT=" Verifiez l'IP, la cle SSH et le nom d'utilisateur." MSG_SECURITY_SENDING="Envoi du script d'audit..." diff --git a/security.sh b/security.sh index 357facf..79d3571 100644 --- a/security.sh +++ b/security.sh @@ -173,11 +173,18 @@ fi # --- Test connexion SSH --- info "$MSG_SECURITY_CONNECTING" -if ! ssh -i "$SSH_KEY" -o ConnectTimeout=10 -o BatchMode=yes "${USERNAME}@${VPS_IP}" "echo ok" &>/dev/null; then - err "$(printf "$MSG_SECURITY_ERR_CONNECT" "$USERNAME" "$VPS_IP")" - echo "" - echo "$MSG_SECURITY_ERR_CONNECT_HINT" - exit 1 +SSH_USER="$USERNAME" +if ! ssh -i "$SSH_KEY" -o ConnectTimeout=10 -o BatchMode=yes "${SSH_USER}@${VPS_IP}" "echo ok" &>/dev/null; then + warn "$(printf "$MSG_SECURITY_WARN_USER_FAILED" "$USERNAME")" + info "$MSG_SECURITY_TRYING_ROOT" + if ! ssh -i "$SSH_KEY" -o ConnectTimeout=10 -o BatchMode=yes "root@${VPS_IP}" "echo ok" &>/dev/null; then + err "$(printf "$MSG_SECURITY_ERR_CONNECT" "$USERNAME" "$VPS_IP")" + echo "" + echo "$MSG_SECURITY_ERR_CONNECT_HINT" + exit 1 + fi + SSH_USER="root" + warn "$MSG_SECURITY_CONNECTED_AS_ROOT" fi # ========================================= @@ -523,8 +530,8 @@ fi # ========================================= info "$MSG_SECURITY_SENDING" -REMOTE_TMP=$(ssh -i "$SSH_KEY" -o BatchMode=yes "${USERNAME}@${VPS_IP}" "mktemp /tmp/vps-XXXXXXXXXX.sh") -if ! scp -i "$SSH_KEY" "$TMPSCRIPT" "${USERNAME}@${VPS_IP}:${REMOTE_TMP}"; then +REMOTE_TMP=$(ssh -i "$SSH_KEY" -o BatchMode=yes "${SSH_USER}@${VPS_IP}" "mktemp /tmp/vps-XXXXXXXXXX.sh") +if ! scp -i "$SSH_KEY" "$TMPSCRIPT" "${SSH_USER}@${VPS_IP}:${REMOTE_TMP}"; then err "$MSG_SECURITY_ERR_SEND" rm -f "$TMPSCRIPT" exit 1 @@ -538,4 +545,4 @@ else SSH_TTY_FLAG="" fi -ssh $SSH_TTY_FLAG -i "$SSH_KEY" "${USERNAME}@${VPS_IP}" "chmod 700 '${REMOTE_TMP}'; sudo bash '${REMOTE_TMP}'; rm -f '${REMOTE_TMP}'" +ssh $SSH_TTY_FLAG -i "$SSH_KEY" "${SSH_USER}@${VPS_IP}" "chmod 700 '${REMOTE_TMP}'; sudo bash '${REMOTE_TMP}'; rm -f '${REMOTE_TMP}'" diff --git a/setup.sh b/setup.sh index ea5a0d1..f166569 100755 --- a/setup.sh +++ b/setup.sh @@ -199,6 +199,7 @@ if [ -f "$LOCAL_STATE" ]; then VPS_IP=$(read_state_var "$LOCAL_STATE" "VPS_IP") SSH_KEY=$(read_state_var "$LOCAL_STATE" "SSH_KEY") USERNAME=$(read_state_var "$LOCAL_STATE" "USERNAME") + INITIAL_USER=$(read_state_var "$LOCAL_STATE" "INITIAL_USER") || true if [[ -n "${VPS_IP:-}" && -n "${SSH_KEY:-}" && -n "${USERNAME:-}" ]]; then echo "" warn "$MSG_SETUP_SESSION_DETECTED" @@ -262,15 +263,32 @@ if [ "$MODE" = "new" ]; then exit 1 fi + # --- Compte initial du serveur --- + echo "" + read -p " $MSG_SETUP_NEW_INITIAL_USER_PROMPT" INITIAL_USER + INITIAL_USER=${INITIAL_USER:-root} + # --- Envoyer la clé SSH --- step "$MSG_SETUP_NEW_STEP3_TITLE" "$(echo -e "$MSG_SETUP_NEW_STEP3_DESC")" if confirm; then if command -v ssh-copy-id &>/dev/null; then - ssh-copy-id -i "${SSH_KEY}.pub" "root@${VPS_IP}" + if ! ssh-copy-id -i "${SSH_KEY}.pub" "${INITIAL_USER}@${VPS_IP}"; then + err "$MSG_SETUP_NEW_STEP3_COPY_FAILED" + echo "" + echo " $MSG_SETUP_NEW_STEP3_COPY_FAILED_HINT" + echo " ssh-copy-id -i '${SSH_KEY}.pub' ${INITIAL_USER}@${VPS_IP}" + exit 1 + fi else info "$MSG_SETUP_NEW_STEP3_MANUAL_SEND" - cat "${SSH_KEY}.pub" | ssh "root@${VPS_IP}" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" + if ! cat "${SSH_KEY}.pub" | ssh "${INITIAL_USER}@${VPS_IP}" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"; then + err "$MSG_SETUP_NEW_STEP3_COPY_FAILED" + echo "" + echo " $MSG_SETUP_NEW_STEP3_COPY_FAILED_HINT" + echo " ssh-copy-id -i '${SSH_KEY}.pub' ${INITIAL_USER}@${VPS_IP}" + exit 1 + fi fi success "$MSG_SETUP_NEW_STEP3_SUCCESS" else @@ -280,7 +298,7 @@ if [ "$MODE" = "new" ]; then # --- Test de connexion --- echo "" info "$MSG_SETUP_NEW_CONNTEST_INFO" - if ssh -i "$SSH_KEY" -o ConnectTimeout=5 -o BatchMode=yes "root@${VPS_IP}" "echo ok" &>/dev/null; then + if ssh -i "$SSH_KEY" -o ConnectTimeout=5 -o BatchMode=yes "${INITIAL_USER}@${VPS_IP}" "echo ok" &>/dev/null; then success "$MSG_SETUP_NEW_CONNTEST_OK" else err "$MSG_SETUP_NEW_CONNTEST_ERR" @@ -295,8 +313,12 @@ if [ "$MODE" = "new" ]; then read -p "$MSG_SETUP_NEW_USERNAME_PROMPT" USERNAME USERNAME=${USERNAME:-deploy} - SSH_USER="root" - USE_SUDO=false + SSH_USER="$INITIAL_USER" + if [ "$INITIAL_USER" = "root" ]; then + USE_SUDO=false + else + USE_SUDO=true + fi # ========================================= # MODE 2 : MISE À JOUR D'UN VPS EXISTANT @@ -343,6 +365,11 @@ elif [ "$MODE" = "update" ]; then SSH_USER="root" USE_SUDO=false success "$MSG_SETUP_UPDATE_CONNTEST_ROOT_OK" + elif [[ -n "${INITIAL_USER:-}" && "$INITIAL_USER" != "root" && "$INITIAL_USER" != "$USERNAME" ]] && \ + ssh -i "$SSH_KEY" -o ConnectTimeout=5 -o BatchMode=yes "${INITIAL_USER}@${VPS_IP}" "echo ok" &>/dev/null; then + SSH_USER="$INITIAL_USER" + USE_SUDO=true + success "$(printf "$MSG_SETUP_UPDATE_CONNTEST_USER_OK" "$INITIAL_USER")" else err "$(printf "$MSG_SETUP_UPDATE_CONNTEST_ERR" "$USERNAME")" echo " $MSG_SETUP_UPDATE_CONNTEST_HINT" @@ -352,7 +379,8 @@ elif [ "$MODE" = "update" ]; then fi # --- Sauvegarder la session locale --- -printf 'VPS_IP="%s"\nSSH_KEY="%s"\nUSERNAME="%s"\n' "$VPS_IP" "$SSH_KEY" "$USERNAME" > "$LOCAL_STATE" +printf 'VPS_IP="%s"\nSSH_KEY="%s"\nUSERNAME="%s"\nINITIAL_USER="%s"\n' \ + "$VPS_IP" "$SSH_KEY" "$USERNAME" "${INITIAL_USER:-root}" > "$LOCAL_STATE" chmod 600 "$LOCAL_STATE" # ========================================= diff --git a/vpskit.sh b/vpskit.sh old mode 100644 new mode 100755 index d2d6685..100e7e4 --- a/vpskit.sh +++ b/vpskit.sh @@ -71,7 +71,7 @@ run_script() { local tmp_script tmp_script=$(mktemp) - trap 'rm -f "$tmp_script" "${_LANG_TMP:-}"' EXIT + trap 'rm -f "${tmp_script:-}" "${_LANG_TMP:-}"' EXIT info "$(printf "$MSG_VPSKIT_DOWNLOADING" "$script_name")" @@ -112,7 +112,11 @@ run_script() { bash "$tmp_script" rm -f "$tmp_script" - trap - EXIT + if [[ -n "${_LANG_TMP:-}" ]]; then + trap 'rm -f "${_LANG_TMP}"' EXIT + else + trap - EXIT + fi } # --- Detection si le script est execute en local --- From 31d7c37056b1df233de6a29cb8b9d938122ebd94 Mon Sep 17 00:00:00 2001 From: Edouard MANGEL Date: Sat, 28 Mar 2026 14:19:52 +0100 Subject: [PATCH 2/2] fix: copy SSH key from initial user when root has no authorized_keys On providers like AWS/Ubuntu where the initial account is not root, the remote setup script was creating an empty authorized_keys for the new deploy user because /root/.ssh/authorized_keys doesn't exist. Now falls back to copying from /home/__SSH_USER__/.ssh/authorized_keys (the account used to connect) when root's file is absent or empty. Inject SSH_USER as a placeholder alongside USERNAME. --- setup.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.sh b/setup.sh index f166569..40935d2 100755 --- a/setup.sh +++ b/setup.sh @@ -712,8 +712,10 @@ if is_done "step3"; then skip_step "$(printf "$RMSG_SETUP_STEP3_TITLE" "$USERNAME")" elif confirm_step "$(printf "$RMSG_SETUP_STEP3_TITLE" "$USERNAME")" "$(printf "$RMSG_SETUP_STEP3_DESC" "$USERNAME")"; then mkdir -p "/home/$USERNAME/.ssh" - if [ -f /root/.ssh/authorized_keys ]; then + if [ -f /root/.ssh/authorized_keys ] && [ -s /root/.ssh/authorized_keys ]; then cp /root/.ssh/authorized_keys "/home/$USERNAME/.ssh/" + elif [ "__SSH_USER__" != "root" ] && [ -f "/home/__SSH_USER__/.ssh/authorized_keys" ] && [ -s "/home/__SSH_USER__/.ssh/authorized_keys" ]; then + cp "/home/__SSH_USER__/.ssh/authorized_keys" "/home/$USERNAME/.ssh/" else touch "/home/$USERNAME/.ssh/authorized_keys" fi @@ -874,10 +876,13 @@ inject_lang_into_remote "$TMPSCRIPT" # Remplacer le placeholder USERNAME (compatible macOS et Linux) SAFE_USERNAME=$(sed_escape "$USERNAME") +SAFE_SSH_USER=$(sed_escape "$SSH_USER") if [ "$OS" = "mac" ]; then sed -i '' "s|__USERNAME__|$SAFE_USERNAME|g" "$TMPSCRIPT" + sed -i '' "s|__SSH_USER__|$SAFE_SSH_USER|g" "$TMPSCRIPT" else sed -i "s|__USERNAME__|$SAFE_USERNAME|g" "$TMPSCRIPT" + sed -i "s|__SSH_USER__|$SAFE_SSH_USER|g" "$TMPSCRIPT" fi # Envoyer le script sur le serveur et l'exécuter (nom aleatoire pour eviter les attaques symlink)