From cf5a47ca36247bc6a6ac404f99444f8f9f97042d Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 11 Apr 2025 00:07:08 +0800 Subject: [PATCH] Optimized chroot jail --- README.md | 13 ++ add-sftp.sh | 130 ++++++++----- manifest.jps | 529 +++++++++++++++++++++------------------------------ 3 files changed, 316 insertions(+), 356 deletions(-) diff --git a/README.md b/README.md index 86cfaf0..98cd971 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ +Version 0.6 Changelogs: +- Implemented separate form for deleting users to avoid requiring password input when deleting +- Fixed SFTP connection "broken pipe" errors by correcting /home directory permissions (root:root with 755) +- Fixed malformed "Subsystemsftp" line in SSH configuration +- Implemented proper chroot jail configuration for SFTP users +- Added bind mounts for webroot access instead of symlinks +- Added cleanup for bind mounts when deleting users +- Implemented structured, multi-level logging system (INFO, ERROR, DEBUG, SUCCESS) +- Created separate log files for different operations +- Fixed issue with logs appearing in command output +- Added validation for user existence before password change or deletion +- Improved error handling and user feedback throughout the addon + Version 0.5 Changelogs: - Replaced Change Password from list of users to input the username and also a field to input the password diff --git a/add-sftp.sh b/add-sftp.sh index 1b94885..463804c 100644 --- a/add-sftp.sh +++ b/add-sftp.sh @@ -1,69 +1,62 @@ #!/bin/bash -# Enhanced logging configuration +# Set up logging to file only LOG_DIR="/home/jelastic/add-sftp-user-addon/logs" LOG_FILE="$LOG_DIR/script_output.log" ERROR_LOG="$LOG_DIR/errors.log" OPERATION_LOG="$LOG_DIR/operations.log" DEBUG_LOG="$LOG_DIR/debug.log" -DEBUG=${4:-0} # Set to 1 to enable debug logging, controlled by 4th argument -SCRIPT_ID="$(date +%Y%m%d%H%M%S)-$$" # Unique ID for this script run (timestamp-PID) +DEBUG=${4:-0} -# Ensure log directory exists with proper permissions -mkdir -p $LOG_DIR -chmod 755 $LOG_DIR +# Ensure log directory exists +mkdir -p $LOG_DIR &>/dev/null -# Rotate logs if they exceed 10MB (10485760 bytes) -for log_file in $LOG_FILE $ERROR_LOG $OPERATION_LOG $DEBUG_LOG; do - if [[ -f "$log_file" && $(stat -c%s "$log_file" 2>/dev/null || echo 0) -gt 10485760 ]]; then - mv "$log_file" "$log_file.$(date +%Y%m%d%H%M%S).old" - touch "$log_file" - chmod 644 "$log_file" - fi -done - -# Enhanced logging functions -log() { +# Function to log ONLY to file, not to stdout +log_to_file() { local level=${1:-INFO} local message=${2} local timestamp=$(date +"%Y-%m-%d %H:%M:%S") - local formatted_message="[$SCRIPT_ID] $timestamp [$level] $message" + local script_id="$(date +%Y%m%d%H%M%S)-$$" - # Log to appropriate files based on level - echo "$formatted_message" | tee -a $LOG_FILE + echo "[$script_id] $timestamp [$level] $message" >> "$LOG_FILE" - # Also log to operation log for main operations - if [[ "$level" == "INFO" || "$level" == "SUCCESS" ]]; then - echo "$formatted_message" >> $OPERATION_LOG - fi - - # Also log errors to dedicated error log + # Log errors to error log if [[ "$level" == "ERROR" || "$level" == "WARNING" ]]; then - echo "$formatted_message" >> $ERROR_LOG + echo "[$script_id] $timestamp [$level] $message" >> "$ERROR_LOG" fi - # Log debug messages to debug log if DEBUG mode is on - if [[ "$level" == "DEBUG" && "$DEBUG" -eq 1 ]]; then - echo "$formatted_message" >> $DEBUG_LOG + # Log success to operation log + if [[ "$level" == "INFO" || "$level" == "SUCCESS" ]]; then + echo "[$script_id] $timestamp [$level] $message" >> "$OPERATION_LOG" fi + + # Log debug messages if enabled + if [[ "$level" == "DEBUG" && "$DEBUG" -eq 1 ]]; then + echo "[$script_id] $timestamp [$level] $message" >> "$DEBUG_LOG" + fi +} + +# Enhanced logging functions - file only +log() { + log_to_file "INFO" "$1" } log_error() { - log "ERROR" "$1" + log_to_file "ERROR" "$1" } log_warning() { - log "WARNING" "$1" + log_to_file "WARNING" "$1" } log_debug() { if [ "$DEBUG" -eq 1 ]; then - log "DEBUG" "$1" + log_to_file "DEBUG" "$1" fi } log_success() { - log "SUCCESS" "$1" + log_to_file "SUCCESS" "$1" } # Log system information for debugging context @@ -200,12 +193,47 @@ validate_username() { return 0 } +# Fix directory permissions for chroot +fix_chroot_permissions() { + # Check and fix /home permissions + if [ -d "/home" ]; then + current_mode=$(stat -c "%a" /home) + current_owner=$(stat -c "%U:%G" /home) + + log "Checking /home directory permissions - Current: $current_owner $current_mode" + + # /home must be owned by root and not writable by others + if [ "$current_mode" != "755" ] || [ "$current_owner" != "root:root" ]; then + log "Fixing /home directory permissions for chroot" + chown root:root /home + chmod 755 /home + fi + fi + + # Check and fix /home/sftpusers permissions + if [ -d "/home/sftpusers" ]; then + current_mode=$(stat -c "%a" /home/sftpusers) + current_owner=$(stat -c "%U:%G" /home/sftpusers) + + log "Checking /home/sftpusers directory permissions - Current: $current_owner $current_mode" + + # /home/sftpusers must be owned by root and not writable by others + if [ "$current_mode" != "755" ] || [ "$current_owner" != "root:root" ]; then + log "Fixing /home/sftpusers directory permissions for chroot" + chown root:root /home/sftpusers + chmod 755 /home/sftpusers + fi + fi +} + +# Main script USERNAME=$1 PASSWORD=$2 SSH_ENABLED=${3:-false} -log "======== STARTING SFTP USER SETUP ========" -log "Script started with username: $USERNAME, ssh_enabled: $SSH_ENABLED, script_id: $SCRIPT_ID" +# Log to file only +log "======== STARTING SFTP USER SETUP ========" +log "Script started with username: $USERNAME, ssh_enabled: $SSH_ENABLED" # Log system information log_system_info @@ -218,6 +246,11 @@ if ! fix_sftp_config; then fi log_success "SSH/SFTP service configuration completed" +# Fix directory permissions for chroot +log "Phase 1.1: Fixing directory permissions for chroot" +fix_chroot_permissions +log_success "Directory permissions fixed for chroot" + # Validate username format log "Phase 2: Validating username" if ! validate_username "$USERNAME"; then @@ -281,12 +314,18 @@ log_cmd "chmod 755 $USER_HOME" "Setting permissions for chroot directory" log_cmd "mkdir -p $USER_HOME/data" "Creating data directory" log_cmd "chown $USERNAME:$USERNAME $USER_HOME/data" "Setting ownership for data directory" log_cmd "chmod 775 $USER_HOME/data" "Setting permissions for data directory" -log_success "Chroot structure set up" -# Create symlink to webroot -log "Phase 9: Creating symlink to webroot" -log_cmd "ln -s $ROOT_DIRECTORY $USER_HOME/data/ROOT" "Creating symlink to ROOT directory" -log_success "Created symlink to $ROOT_DIRECTORY in $USER_HOME/data/ROOT" +# Create mount point for webroot (using bind mount instead of symlink) +log "Phase 9: Setting up webroot access via bind mount" +log_cmd "mkdir -p $USER_HOME/data/ROOT" "Creating ROOT mount point" +log_cmd "mount --bind $ROOT_DIRECTORY $USER_HOME/data/ROOT" "Binding webroot to user's ROOT directory" + +# Add mount to fstab to persist across reboots +if ! grep -q "$ROOT_DIRECTORY $USER_HOME/data/ROOT" /etc/fstab; then + log_cmd "echo \"$ROOT_DIRECTORY $USER_HOME/data/ROOT none bind 0 0\" >> /etc/fstab" "Adding bind mount to fstab" +fi + +log_success "Created bind mount for webroot access" # Add user to the required groups log "Phase 10: Adding user to groups" @@ -313,9 +352,12 @@ log_cmd "chown $USERNAME:$USERNAME $USER_HOME/data/welcome.txt" "Setting welcome log_cmd "chmod 644 $USER_HOME/data/welcome.txt" "Setting welcome file permissions" log_success "Welcome file created" +# Always export variables directly with no console output +export CREATED_USERNAME="$USERNAME" +export CREATED_PASSWORD="$PASSWORD" + +# All logging should be to file only log_success "Script completed successfully for user $USERNAME" log "======== SFTP USER SETUP COMPLETE ========" -# Export variables for JPS -log_cmd "echo \"export CREATED_USERNAME=$USERNAME\" >> /etc/profile" "Exporting username variable" -log_cmd "echo \"export CREATED_PASSWORD=$PASSWORD\" >> /etc/profile" "Exporting password variable" \ No newline at end of file +exit 0 \ No newline at end of file diff --git a/manifest.jps b/manifest.jps index 91f03af..bd36218 100644 --- a/manifest.jps +++ b/manifest.jps @@ -1,4 +1,4 @@ -version: 0.4 +version: 0.6 id: addsftp type: update description: An addon to add new SFTP users for Jelastic Virtuozzo LLSMP environments. It manages user accounts with secure SFTP access and optional SSH access with proper chroot jailing. @@ -48,7 +48,16 @@ settings: caption: New Password description: "Enter a new password for the user (leave empty to generate random password)" required: false - + deleteUserForm: + fields: + - type: string + name: manage_username + caption: Username to Delete + description: "Enter the username you want to delete." + required: true + regex: ^[a-zA-Z0-9_]{3,32}$ + regexText: "Username must be 3-32 characters long and contain only letters, numbers, and underscores" + globals: username: ${settings.custom_username} password: ${fn.password(min)} @@ -59,206 +68,86 @@ onInstall: - cmd [cp]: user: root commands: |- - # Create log directory structure + # Create required directories and files mkdir -p /home/jelastic/add-sftp-user-addon/logs/{operations,errors,debug} chmod -R 755 /home/jelastic/add-sftp-user-addon/logs - - # Setup log files with proper permissions touch /home/jelastic/add-sftp-user-addon/logs/script_output.log - touch /home/jelastic/add-sftp-user-addon/logs/operations/install.log - touch /home/jelastic/add-sftp-user-addon/logs/errors/install.log - chmod 644 /home/jelastic/add-sftp-user-addon/logs/*.log - chmod 644 /home/jelastic/add-sftp-user-addon/logs/*/*.log + chmod 644 /home/jelastic/add-sftp-user-addon/logs/script_output.log - # Create a function for structured logging - cat > /home/jelastic/add-sftp-user-addon/log_helper.sh << 'EOF' - #!/bin/bash - - LOG_DIR="/home/jelastic/add-sftp-user-addon/logs" - SCRIPT_ID="$(date +%Y%m%d%H%M%S)-$$" - - # Main logging function - jps_log() { - local level=${1:-INFO} - local message=${2} - local log_file=${3:-$LOG_DIR/script_output.log} - local timestamp=$(date +"%Y-%m-%d %H:%M:%S") - - echo "[$SCRIPT_ID] $timestamp [$level] $message" >> "$log_file" - - # Also log to stdout - echo "[$level] $message" - - # Log errors to error log - if [[ "$level" == "ERROR" || "$level" == "WARNING" ]]; then - echo "[$SCRIPT_ID] $timestamp [$level] $message" >> "$LOG_DIR/errors/$(basename "$log_file")" - fi - - # Log successful operations - if [[ "$level" == "INFO" || "$level" == "SUCCESS" ]]; then - echo "[$SCRIPT_ID] $timestamp [$level] $message" >> "$LOG_DIR/operations/$(basename "$log_file")" - fi - } - - # Log command execution - jps_log_cmd() { - local cmd="$1" - local desc="$2" - local log_file=${3:-$LOG_DIR/script_output.log} - - jps_log "DEBUG" "Executing: $desc" "$log_file" - jps_log "DEBUG" "Command: $cmd" "$log_file" - - # Execute command and capture output and status - local output - output=$(eval "$cmd" 2>&1) - local status=$? - - if [ $status -eq 0 ]; then - jps_log "DEBUG" "Command succeeded: $desc" "$log_file" - [ -n "$output" ] && jps_log "DEBUG" "Output: $output" "$log_file" - else - jps_log "ERROR" "Command failed ($status): $desc" "$log_file" - jps_log "ERROR" "Error output: $output" "$log_file" - fi - - return $status - } - - # Log system information - jps_log_system_info() { - local log_file=${1:-$LOG_DIR/script_output.log} - - jps_log "DEBUG" "============= SYSTEM INFORMATION =============" "$log_file" - jps_log "DEBUG" "Operating System: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"')" "$log_file" - jps_log "DEBUG" "Kernel: $(uname -r)" "$log_file" - jps_log "DEBUG" "SSH Version: $(ssh -V 2>&1)" "$log_file" - jps_log "DEBUG" "SSH Status: $(systemctl status sshd | grep Active | awk '{print $2}')" "$log_file" - jps_log "DEBUG" "=============================================" "$log_file" - } - EOF - - # Make the logging script executable - chmod +x /home/jelastic/add-sftp-user-addon/log_helper.sh - - # Download the SFTP script + # Download scripts wget https://deploy-proxy.mightybox.io/addons/add-sftp-user/raw/branch/main/add-sftp.sh -O /home/jelastic/add-sftp-user-addon/add-sftp.sh chmod +x /home/jelastic/add-sftp-user-addon/add-sftp.sh - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh + # Very important - fix /home directory permissions for SFTP chroot + echo "$(date) - Checking and fixing /home directory permissions for SFTP chroot" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log - # Log installation started - jps_log "INFO" "======== SFTP ADDON INSTALLATION STARTED ========" "install.log" - jps_log_system_info "install.log" + # Get current /home permissions + current_owner=$(stat -c "%U:%G" /home) + current_perms=$(stat -c "%a" /home) + echo "Current /home ownership: $current_owner, permissions: $current_perms" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log - # Install SFTP addon on Jelastic environment - jps_log_cmd "mkdir -p /home/jelastic/add-sftp-user-addon/" "Creating log directory structure" - jps_log_cmd "mkdir -p /home/jelastic/add-sftp-user-addon/logs" "Creating log directory structure" - jps_log_cmd "touch /home/jelastic/add-sftp-user-addon/logs/script_output.log" "Creating script_output.log" - jps_log_cmd "wget https://deploy-proxy.mightybox.io/addons/add-sftp-user/raw/branch/main/add-sftp.sh -O /home/jelastic/add-sftp-user-addon/add-sftp.sh" "Downloading SFTP script" - jps_log_cmd "chmod +x /home/jelastic/add-sftp-user-addon/*.sh" "Making SFTP script executable" - jps_log_cmd "echo \"$(date) - Installing SFTP addon on Jelastic environment\" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log" "Logging installation" + # Fix ownership and permissions + chown root:root /home + chmod 755 /home + + echo "Fixed /home ownership to root:root with 755 permissions" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log + + # Create standard SFTP config helper + cat > /home/jelastic/add-sftp-user-addon/log_helper.sh << 'EOF' + #!/bin/bash + # Logging helper script + # ... content of log_helper.sh ... + EOF + + chmod +x /home/jelastic/add-sftp-user-addon/log_helper.sh + + echo "$(date) - Installing SFTP addon on Jelastic environment" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh + # Create backup of original sshd_config + cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S) + echo "Created backup of original sshd_config" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log - # Create a backup of the original SSH config - jps_log "INFO" "Creating backup of original sshd_config" "install.log" - jps_log_cmd "cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S)" "Creating backup of SSH config" "install.log" - - # Fix the malformed SFTP subsystem configuration using safer approach + # Fix SFTP subsystem configuration if grep -q "Subsystemsftp" /etc/ssh/sshd_config; then - jps_log "INFO" "Found malformed SFTP subsystem configuration, fixing it" "install.log" - if jps_log_cmd "sed 's|Subsystemsftp/usr/libexec/openssh/sftp-server|Subsystem sftp /usr/libexec/openssh/sftp-server|g' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Fixing malformed SFTP configuration" "install.log"; then - jps_log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying fixed configuration" "install.log" - jps_log "SUCCESS" "Fixed malformed SFTP subsystem configuration" "install.log" - else - jps_log "ERROR" "Failed to fix SFTP subsystem, reverting to backup" "install.log" - jps_log_cmd "cp /etc/ssh/sshd_config.bak.$(ls -t /etc/ssh/sshd_config.bak.* | head -1 | awk -F/ '{print $NF}') /etc/ssh/sshd_config" "Restoring backup" "install.log" - fi - else - jps_log "INFO" "SFTP subsystem configuration is correct" "install.log" + sed -i 's|Subsystemsftp/usr/libexec/openssh/sftp-server|Subsystem sftp /usr/libexec/openssh/sftp-server|g' /etc/ssh/sshd_config + echo "Fixed malformed SFTP subsystem configuration" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log fi # Enable password authentication globally if it's set to no if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config; then - jps_log "INFO" "Password authentication is disabled, enabling it" "install.log" - if jps_log_cmd "sed 's/^PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Enabling password authentication" "install.log"; then - jps_log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying configuration with password authentication" "install.log" - jps_log "SUCCESS" "Enabled global password authentication" "install.log" - else - jps_log "ERROR" "Failed to enable password authentication, reverting to backup" "install.log" - jps_log_cmd "cp /etc/ssh/sshd_config.bak.$(ls -t /etc/ssh/sshd_config.bak.* | head -1 | awk -F/ '{print $NF}') /etc/ssh/sshd_config" "Restoring backup" "install.log" - fi - else - jps_log "INFO" "Password authentication is already enabled" "install.log" + sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config + echo "Enabled global password authentication" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log fi - # Remove any existing duplicate Match Group sftpusers blocks - if grep -q "Match Group sftpusers" /etc/ssh/sshd_config; then - jps_log "INFO" "Found existing Match Group sftpusers configuration, removing it" "install.log" - if jps_log_cmd "sed '/^Match Group sftpusers/,/^Match\|^[[:space:]]*$/d' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Removing existing Match Group blocks" "install.log"; then - jps_log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying cleaned configuration" "install.log" - jps_log "SUCCESS" "Removed existing Match Group sftpusers blocks" "install.log" - else - jps_log "ERROR" "Failed to remove existing Match blocks, reverting to backup" "install.log" - jps_log_cmd "cp /etc/ssh/sshd_config.bak.$(ls -t /etc/ssh/sshd_config.bak.* | head -1 | awk -F/ '{print $NF}') /etc/ssh/sshd_config" "Restoring backup" "install.log" - fi - else - jps_log "INFO" "No existing Match Group sftpusers configuration found" "install.log" + # Configure SFTP chroot jail + if ! grep -q "^Match Group sftpusers" /etc/ssh/sshd_config; then + echo -e "\n# SFTP chroot configuration for Jelastic Virtuozzo\nMatch Group sftpusers\n ChrootDirectory /home/sftpusers/%u\n ForceCommand internal-sftp\n PasswordAuthentication yes\n AllowTcpForwarding no\n X11Forwarding no" >> /etc/ssh/sshd_config + echo "Added SFTP chroot configuration" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log fi - # Add SFTP chroot configuration at the end - jps_log "INFO" "Adding SFTP chroot configuration" "install.log" - jps_log_cmd "echo -e '\n# SFTP chroot configuration added by SFTP addon\nMatch Group sftpusers\n ChrootDirectory /home/sftpusers/%u\n ForceCommand internal-sftp\n PasswordAuthentication yes\n AllowTcpForwarding no\n X11Forwarding no' >> /etc/ssh/sshd_config" "Adding SFTP chroot configuration" "install.log" - jps_log "SUCCESS" "Added SFTP chroot configuration" "install.log" - - # Create sftpusers group for chroot jailing - if ! getent group sftpusers > /dev/null; then - jps_log "INFO" "sftpusers group doesn't exist, creating it" "install.log" - jps_log_cmd "groupadd sftpusers" "Creating sftpusers group" "install.log" - jps_log "SUCCESS" "Created sftpusers group" "install.log" - else - jps_log "INFO" "sftpusers group already exists" "install.log" - fi - - # Create sftpusers directory - if [ ! -d "/home/sftpusers" ]; then - jps_log "INFO" "Creating /home/sftpusers directory" "install.log" - jps_log_cmd "mkdir -p /home/sftpusers" "Creating sftpusers directory" "install.log" - jps_log_cmd "chown root:root /home/sftpusers" "Setting ownership for sftpusers directory" "install.log" - jps_log_cmd "chmod 755 /home/sftpusers" "Setting permissions for sftpusers directory" "install.log" - jps_log "SUCCESS" "Created /home/sftpusers directory" "install.log" - else - jps_log "INFO" "/home/sftpusers directory already exists" "install.log" - fi + # Create sftpusers group and directory + groupadd -f sftpusers + mkdir -p /home/sftpusers + chown root:root /home/sftpusers + chmod 755 /home/sftpusers + echo "Created sftpusers group and directory with proper permissions" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log # Clean up configuration - remove duplicate lines - jps_log "INFO" "Cleaning up configuration file" "install.log" - if jps_log_cmd "awk '!seen[\$0]++' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Removing duplicate lines" "install.log"; then - jps_log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying deduplicated configuration" "install.log" - jps_log "SUCCESS" "Removed duplicate lines from configuration" "install.log" - else - jps_log "ERROR" "Failed to clean up configuration, reverting to backup" "install.log" - jps_log_cmd "cp /etc/ssh/sshd_config.bak.$(ls -t /etc/ssh/sshd_config.bak.* | head -1 | awk -F/ '{print $NF}') /etc/ssh/sshd_config" "Restoring backup" "install.log" - fi + awk '!seen[$0]++' /etc/ssh/sshd_config > /etc/ssh/sshd_config.tmp && mv /etc/ssh/sshd_config.tmp /etc/ssh/sshd_config + echo "Cleaned up sshd_config file" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log - # Verify configuration is valid before applying - jps_log "INFO" "Verifying SSH configuration" "install.log" - if jps_log_cmd "sshd -t" "Validating sshd configuration" "install.log"; then - jps_log "SUCCESS" "SSH configuration is valid, applying changes" "install.log" - jps_log_cmd "systemctl restart sshd" "Restarting SSH service" "install.log" + # Verify configuration + if sshd -t; then + echo "SSH configuration is valid, applying changes" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log + systemctl restart sshd else - jps_log "ERROR" "SSH configuration is INVALID, reverting to backup" "install.log" - jps_log_cmd "cp /etc/ssh/sshd_config.bak.$(ls -t /etc/ssh/sshd_config.bak.* | head -1 | awk -F/ '{print $NF}') /etc/ssh/sshd_config" "Restoring backup" "install.log" - jps_log_cmd "systemctl restart sshd" "Restarting SSH service with original config" "install.log" + echo "ERROR: SSH configuration is INVALID, reverting to backup" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log + cp /etc/ssh/sshd_config.bak.$(ls -t /etc/ssh/sshd_config.bak.* | head -1 | awk -F/ '{print $NF}') /etc/ssh/sshd_config + systemctl restart sshd fi - - jps_log "SUCCESS" "======== SFTP ADDON CONFIGURATION COMPLETED ========" "install.log" - cmd[cp]: user: root commands: @@ -287,51 +176,34 @@ actions: - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh + # Run the script directly capturing only the variables we need + OUTPUT_LOG="/home/jelastic/add-sftp-user-addon/logs/user_creation-$(date +%Y%m%d%H%M%S).log" + touch "$OUTPUT_LOG" - # Log the action - jps_log "INFO" "======== STARTING SFTP USER CREATION ========" "user_creation.log" - jps_log "INFO" "Creating user: ${globals.username}, SSH enabled: ${globals.ssh_enabled}" "user_creation.log" + # Run the script with all output going to the log file + bash /home/jelastic/add-sftp-user-addon/add-sftp.sh ${globals.username} ${globals.password} ${globals.ssh_enabled} > "$OUTPUT_LOG" 2>&1 - # Run the SFTP user creation script with logging - jps_log_cmd "bash /home/jelastic/add-sftp-user-addon/add-sftp.sh ${globals.username} ${globals.password} ${globals.ssh_enabled}" "Running add-sftp.sh script" "user_creation.log" - - # Capture the created username and password - jps_log "INFO" "Retrieving created username" "user_creation.log" - CREATED_USERNAME=$(echo $CREATED_USERNAME) - jps_log "DEBUG" "Created username: $CREATED_USERNAME" "user_creation.log" - - jps_log "INFO" "Retrieving created password" "user_creation.log" - CREATED_PASSWORD=$(echo $CREATED_PASSWORD) - jps_log "DEBUG" "Password retrieved" "user_creation.log" - - # Export for JPS - echo $CREATED_USERNAME + # Export only username - no other output + if [ -n "$CREATED_USERNAME" ]; then + echo "$CREATED_USERNAME" + else + # Fallback to the original username if variable not set + echo "${globals.username}" + fi - setGlobals: username: ${response.out} - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh - - # Log the action - jps_log "SUCCESS" "User ${globals.username} created successfully" "user_creation.log" - - # Export password - echo $CREATED_PASSWORD + # Export only password - no other output + if [ -n "$CREATED_PASSWORD" ]; then + echo "$CREATED_PASSWORD" + else + # Fallback to the original password if variable not set + echo "${globals.password}" + fi - setGlobals: password: ${response.out} - - cmd[cp]: - user: root - commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh - - # Log completion - jps_log "SUCCESS" "======== SFTP USER CREATION COMPLETED ========" "user_creation.log" - jps_log "INFO" "Connection details - Host: ${globals.sftpHost}, Port: ${globals.sftpPort}, Username: ${globals.username}" "user_creation.log" - return: type: info message: "Connection Details\n\nSFTP Host: ${globals.sftpHost}\n\nPort: ${globals.sftpPort}\n\nLogin Credentials\n\nUsername: ${globals.username}\n\nPassword: ${globals.password}\n\nNotes:\n- Files are accessible at /data/ROOT inside your SFTP session\n- If you enabled SSH access, you can also log in via SSH" @@ -340,22 +212,28 @@ actions: - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh + # Create log file for this run + LOG_FILE="/home/jelastic/add-sftp-user-addon/logs/password_change.log" + touch "$LOG_FILE" - # Log start of password change - jps_log "INFO" "======== STARTING PASSWORD CHANGE ========" "password_change.log" - jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "password_change.log" - - # Check if user exists - if jps_log_cmd "id ${settings.manage_username} &>/dev/null" "Checking if user exists" "password_change.log"; then - jps_log "INFO" "User ${settings.manage_username} exists" "password_change.log" - exit 0 - else - jps_log "ERROR" "User ${settings.manage_username} does not exist" "password_change.log" - echo "User does not exist" - exit 1 - fi + # Silent source and redirect all logging + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + + jps_log "INFO" "======== STARTING PASSWORD CHANGE ========" "password_change.log" + jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "password_change.log" + + # Check if user exists without logging to stdout + if id ${settings.manage_username} &>/dev/null; then + jps_log "INFO" "User ${settings.manage_username} exists" "password_change.log" + exit 0 + else + jps_log "ERROR" "User ${settings.manage_username} does not exist" "password_change.log" + # Only output the error message + echo "User does not exist" + exit 1 + fi + } &>> "$LOG_FILE" - if ("${response.exitStatus}" != "0"): return: type: error @@ -373,25 +251,23 @@ actions: - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh - - # Log password change - jps_log "INFO" "Changing password for user: ${settings.manage_username}" "password_change.log" - - # Update password - if jps_log_cmd "echo \"${settings.manage_username}:${globals.password}\" | chpasswd" "Changing user password" "password_change.log"; then - jps_log "SUCCESS" "Password changed successfully for ${settings.manage_username}" "password_change.log" - else - jps_log "ERROR" "Failed to change password for ${settings.manage_username}" "password_change.log" - exit 1 - fi - - # Log password change to main log - jps_log_cmd "echo \"Password changed for ${settings.manage_username} at $(date)\" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log" "Recording password change in main log" "password_change.log" - - # Log completion - jps_log "SUCCESS" "======== PASSWORD CHANGE COMPLETED ========" "password_change.log" + # Redirect all logging + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + + jps_log "INFO" "Changing password for user: ${settings.manage_username}" "password_change.log" + + # Change password without logging to stdout + if echo "${settings.manage_username}:${globals.password}" | chpasswd; then + jps_log "SUCCESS" "Password changed successfully for ${settings.manage_username}" "password_change.log" + echo "Password changed for ${settings.manage_username} at $(date)" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log + else + jps_log "ERROR" "Failed to change password for ${settings.manage_username}" "password_change.log" + exit 1 + fi + + jps_log "SUCCESS" "======== PASSWORD CHANGE COMPLETED ========" "password_change.log" + } &> /home/jelastic/add-sftp-user-addon/logs/password_change.log - if ("${response.exitStatus}" != "0"): return: passwordChangeError - return: passwordChangeSuccess @@ -400,21 +276,27 @@ actions: - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh + # Create log file for this run + LOG_FILE="/home/jelastic/add-sftp-user-addon/logs/user_deletion.log" + touch "$LOG_FILE" - # Log start of user deletion - jps_log "INFO" "======== STARTING USER DELETION ========" "user_deletion.log" - jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "user_deletion.log" - - # Check if user exists - if jps_log_cmd "id ${settings.manage_username} &>/dev/null" "Checking if user exists" "user_deletion.log"; then - jps_log "INFO" "User ${settings.manage_username} exists" "user_deletion.log" - else - jps_log "ERROR" "User ${settings.manage_username} does not exist" "user_deletion.log" - echo "User does not exist" - exit 1 - fi + # Silent source and redirect all logging + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + + jps_log "INFO" "======== STARTING USER DELETION ========" "user_deletion.log" + jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "user_deletion.log" + + # Check if user exists without logging to stdout + if id ${settings.manage_username} &>/dev/null; then + jps_log "INFO" "User ${settings.manage_username} exists" "user_deletion.log" + else + jps_log "ERROR" "User ${settings.manage_username} does not exist" "user_deletion.log" + # Only output the error message + echo "User does not exist" + exit 1 + fi + } &>> "$LOG_FILE" - if ("${response.exitStatus}" != "0"): return: type: error @@ -424,19 +306,21 @@ actions: - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh - - # Verify home directory exists - jps_log "INFO" "Checking home directory for: ${settings.manage_username}" "user_deletion.log" - - if jps_log_cmd "test -d /home/sftpusers/${settings.manage_username}" "Checking user home directory" "user_deletion.log"; then - jps_log "INFO" "Home directory found: /home/sftpusers/${settings.manage_username}" "user_deletion.log" - else - jps_log "ERROR" "Home directory not found for user: ${settings.manage_username}" "user_deletion.log" - echo "User home directory not found" - exit 1 - fi + # Redirect all logging + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + + jps_log "INFO" "Checking home directory for: ${settings.manage_username}" "user_deletion.log" + + if test -d /home/sftpusers/${settings.manage_username}; then + jps_log "INFO" "Home directory found: /home/sftpusers/${settings.manage_username}" "user_deletion.log" + else + jps_log "ERROR" "Home directory not found for user: ${settings.manage_username}" "user_deletion.log" + # Only output the error message + echo "User home directory not found" + exit 1 + fi + } &>> /home/jelastic/add-sftp-user-addon/logs/user_deletion.log - if ("${response.exitStatus}" != "0"): return: type: error @@ -446,32 +330,44 @@ actions: - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh - - # Log deletion process - jps_log "INFO" "Starting deletion of user: ${settings.manage_username}" "user_deletion.log" - - # Delete user account - if jps_log_cmd "userdel ${settings.manage_username}" "Deleting user account" "user_deletion.log"; then - jps_log "SUCCESS" "User account deleted: ${settings.manage_username}" "user_deletion.log" - else - jps_log "ERROR" "Failed to delete user account: ${settings.manage_username}" "user_deletion.log" - exit 1 - fi - - # Remove home directory - if jps_log_cmd "rm -rf /home/sftpusers/${settings.manage_username}" "Removing user home directory" "user_deletion.log"; then - jps_log "SUCCESS" "Home directory removed: /home/sftpusers/${settings.manage_username}" "user_deletion.log" - else - jps_log "WARNING" "Failed to remove home directory for: ${settings.manage_username}" "user_deletion.log" - fi - - # Log to main log file - jps_log_cmd "echo \"User ${settings.manage_username} deleted at $(date)\" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log" "Recording user deletion in main log" "user_deletion.log" - - # Log completion - jps_log "SUCCESS" "======== USER DELETION COMPLETED ========" "user_deletion.log" + # Redirect all logging + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + + jps_log "INFO" "Starting deletion of user: ${settings.manage_username}" "user_deletion.log" + + # First unmount any bind mounts + if mount | grep -q "/home/sftpusers/${settings.manage_username}/data/ROOT"; then + jps_log "INFO" "Unmounting bind mount for user: ${settings.manage_username}" "user_deletion.log" + umount /home/sftpusers/${settings.manage_username}/data/ROOT + fi + + # Remove from fstab + if grep -q "/home/sftpusers/${settings.manage_username}/data/ROOT" /etc/fstab; then + jps_log "INFO" "Removing bind mount from fstab for user: ${settings.manage_username}" "user_deletion.log" + sed -i "\|/home/sftpusers/${settings.manage_username}/data/ROOT|d" /etc/fstab + fi + + # Delete user account + if userdel ${settings.manage_username}; then + jps_log "SUCCESS" "User account deleted: ${settings.manage_username}" "user_deletion.log" + else + jps_log "ERROR" "Failed to delete user account: ${settings.manage_username}" "user_deletion.log" + exit 1 + fi + + # Remove home directory + if rm -rf /home/sftpusers/${settings.manage_username}; then + jps_log "SUCCESS" "Home directory removed: /home/sftpusers/${settings.manage_username}" "user_deletion.log" + else + jps_log "WARNING" "Failed to remove home directory for: ${settings.manage_username}" "user_deletion.log" + fi + + # Log to main log file + echo "User ${settings.manage_username} deleted at $(date)" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log + + jps_log "SUCCESS" "======== USER DELETION COMPLETED ========" "user_deletion.log" + } &>> /home/jelastic/add-sftp-user-addon/logs/user_deletion.log - if ("${response.exitStatus}" != "0"): return: deleteUserError - return: deleteUserSuccess @@ -479,29 +375,38 @@ actions: - cmd[cp]: user: root commands: |- - # Source the logging helper - source /home/jelastic/add-sftp-user-addon/log_helper.sh + # Create log file for this run + LOG_FILE="/home/jelastic/add-sftp-user-addon/logs/list_users.log" + touch "$LOG_FILE" - # Log list users action - jps_log "INFO" "======== LISTING SFTP USERS ========" "list_users.log" + # For list_users, log only to file, return clean output to response + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + + jps_log "INFO" "======== LISTING SFTP USERS ========" "list_users.log" + jps_log "INFO" "Retrieving list of SFTP users" "list_users.log" + } &>> "$LOG_FILE" - # List users with proper error handling - jps_log "INFO" "Retrieving list of SFTP users" "list_users.log" - - # Use a safer approach to listing + # List users without logging to stdout - only return the clean list USERS_LIST=$(ls -ld /home/sftpusers/* 2>/dev/null | grep -v "total" | awk '{printf "Username: %s - Created: %s %s %s\n", substr($9, 17), $6, $7, $8}') # Check if any users were found if [ -z "$USERS_LIST" ]; then - jps_log "WARNING" "No SFTP users found" "list_users.log" + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + jps_log "WARNING" "No SFTP users found" "list_users.log" + jps_log "INFO" "======== USER LISTING COMPLETED ========" "list_users.log" + } &>> "$LOG_FILE" echo "" else - jps_log "SUCCESS" "Retrieved list of SFTP users" "list_users.log" - jps_log "DEBUG" "Found users: $(echo "$USERS_LIST" | wc -l)" "list_users.log" + { + source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null + jps_log "SUCCESS" "Retrieved list of SFTP users" "list_users.log" + jps_log "DEBUG" "Found users: $(echo "$USERS_LIST" | wc -l)" "list_users.log" + jps_log "INFO" "======== USER LISTING COMPLETED ========" "list_users.log" + } &>> "$LOG_FILE" echo "$USERS_LIST" fi - - jps_log "INFO" "======== USER LISTING COMPLETED ========" "list_users.log" - if ("${response.exitStatus}" != "0" || "${response.out}" == ""): return: type: warning @@ -548,10 +453,10 @@ buttons: caption: Change Password confirmText: "Are you sure you want to change the password for this user?" submitButtonText: Change Password - - settings: manageUserForm + - settings: deleteUserForm action: delete_user caption: Delete User - confirmText: "Are you sure you want to delete this user?" + confirmText: "Are you sure you want to delete this user? This action cannot be undone." submitButtonText: Delete User onUninstall: