#!/bin/bash # DragonCoreSSH V40 admin password recovery tool. # Usage: # sudo bash change_admin_password.sh # sudo bash change_admin_password.sh admin 'NewPasswordHere' # sudo bash change_admin_password.sh --user admin --generate set -euo pipefail RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' info() { echo -e "${GREEN}[+]${NC} $*"; } warn() { echo -e "${YELLOW}[!]${NC} $*"; } error() { echo -e "${RED}[x]${NC} $*"; exit 1; } INSTALL_DIR="${INSTALL_DIR:-/opt/sshpanel}" SERVICE_NAME="${SERVICE_NAME:-sshpanel}" ENV_FILE="${ENV_FILE:-${INSTALL_DIR}/.env}" ADMIN_USER="" NEW_PASSWORD="" GENERATE_PASSWORD=false NO_RESTART=false usage() { cat </dev/null 2>&1 || error "psql not found. Install PostgreSQL client first." get_env_value() { local key="$1" awk -v key="$key" ' $0 ~ "^" key "=" { sub("^[^=]*=", "") gsub(/^\"|\"$/, "") gsub(/^\047|\047$/, "") print exit } ' "$ENV_FILE" } remove_legacy_env_password() { local tmp tmp="$(mktemp)" awk ' /^ADMIN_PASSWORD=/ { next } { print } ' "$ENV_FILE" > "$tmp" install -m 600 "$tmp" "$ENV_FILE" rm -f -- "$tmp" chmod 600 "$ENV_FILE" 2>/dev/null || true } generate_password() { local pw="" if command -v openssl >/dev/null 2>&1; then pw="$(openssl rand -base64 24 | tr -d '\n' | tr -d '=/+' | head -c 24 || true)" fi if [[ ${#pw} -lt 20 ]]; then pw="$(tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 24 || true)" fi if [[ ${#pw} -lt 20 ]]; then pw="DragonCore$(date +%s%N)" fi printf '%s' "$pw" } hash_password() { local pw="$1" [[ -x "$INSTALL_DIR/sshpanel" ]] || error "Panel binary not found: $INSTALL_DIR/sshpanel" printf '%s' "$pw" | "$INSTALL_DIR/sshpanel" -hash-admin-password-stdin 2>/dev/null } PG_DSN="$(get_env_value PG_DSN)" [[ -n "$PG_DSN" ]] || error "PG_DSN not found inside $ENV_FILE" if [[ -z "$ADMIN_USER" ]]; then read -r -p "Admin username [admin]: " ADMIN_USER ADMIN_USER="${ADMIN_USER:-admin}" fi [[ -n "$ADMIN_USER" ]] || error "Admin username cannot be empty." if $GENERATE_PASSWORD; then NEW_PASSWORD="$(generate_password)" elif [[ -z "$NEW_PASSWORD" ]]; then read -r -s -p "New password: " PASS1 echo read -r -s -p "Confirm password: " PASS2 echo [[ "$PASS1" == "$PASS2" ]] || error "Passwords do not match." NEW_PASSWORD="$PASS1" fi [[ -n "$NEW_PASSWORD" ]] || error "Password cannot be empty." if [[ ${#NEW_PASSWORD} -lt 10 ]]; then error "Password must have at least 10 characters." fi PASSWORD_HASH="$(hash_password "$NEW_PASSWORD")" [[ "$PASSWORD_HASH" == \$2* ]] || error "Failed to generate a valid bcrypt password hash." info "Updating admin user '${ADMIN_USER}' in PostgreSQL..." psql "$PG_DSN" -v ON_ERROR_STOP=1 \ -v admin_user="$ADMIN_USER" \ -v password_hash="$PASSWORD_HASH" <<'SQL' CREATE TABLE IF NOT EXISTS admin_users ( id SERIAL PRIMARY KEY, username TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'reseller', max_users INT NOT NULL DEFAULT 30, expires_at TIMESTAMPTZ, is_active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); INSERT INTO admin_users (username, password_hash, role, max_users, expires_at, is_active) VALUES (:'admin_user', :'password_hash', 'superadmin', 0, NULL, TRUE) ON CONFLICT (username) DO UPDATE SET password_hash = EXCLUDED.password_hash, role = 'superadmin', max_users = 0, expires_at = NULL, is_active = TRUE; SQL if [[ "$ADMIN_USER" == "admin" ]]; then remove_legacy_env_password info "Removed any legacy plaintext ADMIN_PASSWORD entry from $ENV_FILE" fi if ! $NO_RESTART; then info "Restarting ${SERVICE_NAME} so the in-memory admin cache reloads..." if command -v systemctl >/dev/null 2>&1 && systemctl list-unit-files "${SERVICE_NAME}.service" >/dev/null 2>&1; then systemctl restart "$SERVICE_NAME" sleep 1 if systemctl is-active --quiet "$SERVICE_NAME"; then info "${SERVICE_NAME} restarted successfully." else warn "${SERVICE_NAME} is not active after restart. Last logs:" journalctl -u "$SERVICE_NAME" -n 30 --no-pager 2>/dev/null || true exit 1 fi elif command -v service >/dev/null 2>&1; then service "$SERVICE_NAME" restart || warn "Could not restart ${SERVICE_NAME}. Restart it manually." else warn "Could not restart ${SERVICE_NAME}. Restart it manually before logging in." fi else warn "Service restart skipped. Restart ${SERVICE_NAME} manually before logging in." fi echo info "Admin password changed." echo " Username : ${ADMIN_USER}" echo " Password : ${NEW_PASSWORD}" echo warn "Save this password now. It is only shown here."