Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lang/en.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down Expand Up @@ -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..."
Expand Down
8 changes: 7 additions & 1 deletion lang/fr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down Expand Up @@ -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..."
Expand Down
23 changes: 15 additions & 8 deletions security.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

# =========================================
Expand Down Expand Up @@ -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
Expand All @@ -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}'"
47 changes: 40 additions & 7 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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}

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INITIAL_USER is prompted for the new-VPS flow but it isn't persisted to $LOCAL_STATE. If the setup is interrupted before the $USERNAME account is created (or before key-based login for $USERNAME works), a later resume will go through MODE=update and only tries ${USERNAME}@${VPS_IP} then root@${VPS_IP}—so VPSes with a non-root initial account and root login disabled can become non-resumable. Consider saving INITIAL_USER in the local state and including it as an additional SSH fallback in the update-mode connection test when $USERNAME is not yet available.

Suggested change
# Persister l'utilisateur initial dans l'état local pour permettre la reprise
if [[ -n "${LOCAL_STATE:-}" ]]; then
mkdir -p "$(dirname "$LOCAL_STATE")"
if [[ -f "$LOCAL_STATE" ]] && grep -q '^INITIAL_USER=' "$LOCAL_STATE"; then
tmp_state_file="$(mktemp)"
grep -v '^INITIAL_USER=' "$LOCAL_STATE" > "$tmp_state_file"
printf 'INITIAL_USER=%q\n' "$INITIAL_USER" >> "$tmp_state_file"
mv "$tmp_state_file" "$LOCAL_STATE"
else
printf 'INITIAL_USER=%q\n' "$INITIAL_USER" >> "$LOCAL_STATE"
fi
fi

Copilot uses AI. Check for mistakes.
# --- 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
Expand All @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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"
Expand All @@ -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"

# =========================================
Expand Down Expand Up @@ -684,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
Expand Down Expand Up @@ -846,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)
Expand Down
8 changes: 6 additions & 2 deletions vpskit.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copilot AI Mar 28, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This trap ... EXIT inside run_script() overwrites the earlier EXIT trap that cleans up $_LANG_TMP (set when lang.sh is downloaded). Because run_script() later executes trap - EXIT, the original cleanup trap is never restored, and $_LANG_TMP can be left behind on normal runs. Also, when tmp_script/_LANG_TMP are unset, rm -f "${var:-}" may end up being called with an empty-string operand. Consider using a cleanup function that checks for non-empty paths, and restore the previous EXIT trap (or explicitly rm -f "${_LANG_TMP:-}" before clearing/restoring traps).

Copilot uses AI. Check for mistakes.

info "$(printf "$MSG_VPSKIT_DOWNLOADING" "$script_name")"

Expand Down Expand Up @@ -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 ---
Expand Down
Loading