Optimized chroot jail

main
Anthony 2025-04-11 00:07:08 +08:00
parent f1541e6669
commit cf5a47ca36
3 changed files with 316 additions and 356 deletions

View File

@ -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: Version 0.5 Changelogs:
- Replaced Change Password from list of users to input the username and also a field to input the password - Replaced Change Password from list of users to input the username and also a field to input the password

View File

@ -1,69 +1,62 @@
#!/bin/bash #!/bin/bash
# Enhanced logging configuration # Set up logging to file only
LOG_DIR="/home/jelastic/add-sftp-user-addon/logs" LOG_DIR="/home/jelastic/add-sftp-user-addon/logs"
LOG_FILE="$LOG_DIR/script_output.log" LOG_FILE="$LOG_DIR/script_output.log"
ERROR_LOG="$LOG_DIR/errors.log" ERROR_LOG="$LOG_DIR/errors.log"
OPERATION_LOG="$LOG_DIR/operations.log" OPERATION_LOG="$LOG_DIR/operations.log"
DEBUG_LOG="$LOG_DIR/debug.log" DEBUG_LOG="$LOG_DIR/debug.log"
DEBUG=${4:-0} # Set to 1 to enable debug logging, controlled by 4th argument DEBUG=${4:-0}
SCRIPT_ID="$(date +%Y%m%d%H%M%S)-$$" # Unique ID for this script run (timestamp-PID)
# Ensure log directory exists with proper permissions # Ensure log directory exists
mkdir -p $LOG_DIR mkdir -p $LOG_DIR &>/dev/null
chmod 755 $LOG_DIR
# Rotate logs if they exceed 10MB (10485760 bytes) # Function to log ONLY to file, not to stdout
for log_file in $LOG_FILE $ERROR_LOG $OPERATION_LOG $DEBUG_LOG; do log_to_file() {
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() {
local level=${1:-INFO} local level=${1:-INFO}
local message=${2} local message=${2}
local timestamp=$(date +"%Y-%m-%d %H:%M:%S") 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 "[$script_id] $timestamp [$level] $message" >> "$LOG_FILE"
echo "$formatted_message" | tee -a $LOG_FILE
# Also log to operation log for main operations # Log errors to error log
if [[ "$level" == "INFO" || "$level" == "SUCCESS" ]]; then
echo "$formatted_message" >> $OPERATION_LOG
fi
# Also log errors to dedicated error log
if [[ "$level" == "ERROR" || "$level" == "WARNING" ]]; then if [[ "$level" == "ERROR" || "$level" == "WARNING" ]]; then
echo "$formatted_message" >> $ERROR_LOG echo "[$script_id] $timestamp [$level] $message" >> "$ERROR_LOG"
fi fi
# Log debug messages to debug log if DEBUG mode is on # Log success to operation log
if [[ "$level" == "DEBUG" && "$DEBUG" -eq 1 ]]; then if [[ "$level" == "INFO" || "$level" == "SUCCESS" ]]; then
echo "$formatted_message" >> $DEBUG_LOG echo "[$script_id] $timestamp [$level] $message" >> "$OPERATION_LOG"
fi 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() {
log "ERROR" "$1" log_to_file "ERROR" "$1"
} }
log_warning() { log_warning() {
log "WARNING" "$1" log_to_file "WARNING" "$1"
} }
log_debug() { log_debug() {
if [ "$DEBUG" -eq 1 ]; then if [ "$DEBUG" -eq 1 ]; then
log "DEBUG" "$1" log_to_file "DEBUG" "$1"
fi fi
} }
log_success() { log_success() {
log "SUCCESS" "$1" log_to_file "SUCCESS" "$1"
} }
# Log system information for debugging context # Log system information for debugging context
@ -200,12 +193,47 @@ validate_username() {
return 0 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 USERNAME=$1
PASSWORD=$2 PASSWORD=$2
SSH_ENABLED=${3:-false} SSH_ENABLED=${3:-false}
log "======== STARTING SFTP USER SETUP ========" # Log to file only
log "Script started with username: $USERNAME, ssh_enabled: $SSH_ENABLED, script_id: $SCRIPT_ID" log "======== STARTING SFTP USER SETUP ========"
log "Script started with username: $USERNAME, ssh_enabled: $SSH_ENABLED"
# Log system information # Log system information
log_system_info log_system_info
@ -218,6 +246,11 @@ if ! fix_sftp_config; then
fi fi
log_success "SSH/SFTP service configuration completed" 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 # Validate username format
log "Phase 2: Validating username" log "Phase 2: Validating username"
if ! validate_username "$USERNAME"; then 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 "mkdir -p $USER_HOME/data" "Creating data directory"
log_cmd "chown $USERNAME:$USERNAME $USER_HOME/data" "Setting ownership for 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_cmd "chmod 775 $USER_HOME/data" "Setting permissions for data directory"
log_success "Chroot structure set up"
# Create symlink to webroot # Create mount point for webroot (using bind mount instead of symlink)
log "Phase 9: Creating symlink to webroot" log "Phase 9: Setting up webroot access via bind mount"
log_cmd "ln -s $ROOT_DIRECTORY $USER_HOME/data/ROOT" "Creating symlink to ROOT directory" log_cmd "mkdir -p $USER_HOME/data/ROOT" "Creating ROOT mount point"
log_success "Created symlink to $ROOT_DIRECTORY in $USER_HOME/data/ROOT" 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 # Add user to the required groups
log "Phase 10: Adding user to 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_cmd "chmod 644 $USER_HOME/data/welcome.txt" "Setting welcome file permissions"
log_success "Welcome file created" 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_success "Script completed successfully for user $USERNAME"
log "======== SFTP USER SETUP COMPLETE ========" log "======== SFTP USER SETUP COMPLETE ========"
# Export variables for JPS exit 0
log_cmd "echo \"export CREATED_USERNAME=$USERNAME\" >> /etc/profile" "Exporting username variable"
log_cmd "echo \"export CREATED_PASSWORD=$PASSWORD\" >> /etc/profile" "Exporting password variable"

View File

@ -1,4 +1,4 @@
version: 0.4 version: 0.6
id: addsftp id: addsftp
type: update 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. 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 caption: New Password
description: "Enter a new password for the user (leave empty to generate random password)" description: "Enter a new password for the user (leave empty to generate random password)"
required: false 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: globals:
username: ${settings.custom_username} username: ${settings.custom_username}
password: ${fn.password(min)} password: ${fn.password(min)}
@ -59,206 +68,86 @@ onInstall:
- cmd [cp]: - cmd [cp]:
user: root user: root
commands: |- commands: |-
# Create log directory structure # Create required directories and files
mkdir -p /home/jelastic/add-sftp-user-addon/logs/{operations,errors,debug} mkdir -p /home/jelastic/add-sftp-user-addon/logs/{operations,errors,debug}
chmod -R 755 /home/jelastic/add-sftp-user-addon/logs 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/script_output.log
touch /home/jelastic/add-sftp-user-addon/logs/operations/install.log chmod 644 /home/jelastic/add-sftp-user-addon/logs/script_output.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
# Create a function for structured logging # Download scripts
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
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 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 chmod +x /home/jelastic/add-sftp-user-addon/add-sftp.sh
# Source the logging helper # Very important - fix /home directory permissions for SFTP chroot
source /home/jelastic/add-sftp-user-addon/log_helper.sh echo "$(date) - Checking and fixing /home directory permissions for SFTP chroot" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
# Log installation started # Get current /home permissions
jps_log "INFO" "======== SFTP ADDON INSTALLATION STARTED ========" "install.log" current_owner=$(stat -c "%U:%G" /home)
jps_log_system_info "install.log" 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 # Fix ownership and permissions
jps_log_cmd "mkdir -p /home/jelastic/add-sftp-user-addon/" "Creating log directory structure" chown root:root /home
jps_log_cmd "mkdir -p /home/jelastic/add-sftp-user-addon/logs" "Creating log directory structure" chmod 755 /home
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" echo "Fixed /home ownership to root:root with 755 permissions" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
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" # 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]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Create backup of original sshd_config
source /home/jelastic/add-sftp-user-addon/log_helper.sh 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 # Fix SFTP subsystem configuration
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
if grep -q "Subsystemsftp" /etc/ssh/sshd_config; then if grep -q "Subsystemsftp" /etc/ssh/sshd_config; then
jps_log "INFO" "Found malformed SFTP subsystem configuration, fixing it" "install.log" sed -i 's|Subsystemsftp/usr/libexec/openssh/sftp-server|Subsystem sftp /usr/libexec/openssh/sftp-server|g' /etc/ssh/sshd_config
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 echo "Fixed malformed SFTP subsystem configuration" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
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"
fi fi
# Enable password authentication globally if it's set to no # Enable password authentication globally if it's set to no
if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config; then if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config; then
jps_log "INFO" "Password authentication is disabled, enabling it" "install.log" sed -i 's/^PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config
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 echo "Enabled global password authentication" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
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"
fi fi
# Remove any existing duplicate Match Group sftpusers blocks # Configure SFTP chroot jail
if grep -q "Match Group sftpusers" /etc/ssh/sshd_config; then if ! grep -q "^Match Group sftpusers" /etc/ssh/sshd_config; then
jps_log "INFO" "Found existing Match Group sftpusers configuration, removing it" "install.log" 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
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 echo "Added SFTP chroot configuration" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
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"
fi fi
# Add SFTP chroot configuration at the end # Create sftpusers group and directory
jps_log "INFO" "Adding SFTP chroot configuration" "install.log" groupadd -f sftpusers
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" mkdir -p /home/sftpusers
jps_log "SUCCESS" "Added SFTP chroot configuration" "install.log" chown root:root /home/sftpusers
chmod 755 /home/sftpusers
# Create sftpusers group for chroot jailing echo "Created sftpusers group and directory with proper permissions" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
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
# Clean up configuration - remove duplicate lines # Clean up configuration - remove duplicate lines
jps_log "INFO" "Cleaning up configuration file" "install.log" awk '!seen[$0]++' /etc/ssh/sshd_config > /etc/ssh/sshd_config.tmp && mv /etc/ssh/sshd_config.tmp /etc/ssh/sshd_config
if jps_log_cmd "awk '!seen[\$0]++' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Removing duplicate lines" "install.log"; then echo "Cleaned up sshd_config file" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
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
# Verify configuration is valid before applying # Verify configuration
jps_log "INFO" "Verifying SSH configuration" "install.log" if sshd -t; then
if jps_log_cmd "sshd -t" "Validating sshd configuration" "install.log"; then echo "SSH configuration is valid, applying changes" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
jps_log "SUCCESS" "SSH configuration is valid, applying changes" "install.log" systemctl restart sshd
jps_log_cmd "systemctl restart sshd" "Restarting SSH service" "install.log"
else else
jps_log "ERROR" "SSH configuration is INVALID, reverting to backup" "install.log" echo "ERROR: SSH configuration is INVALID, reverting to backup" >> /home/jelastic/add-sftp-user-addon/logs/script_output.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" cp /etc/ssh/sshd_config.bak.$(ls -t /etc/ssh/sshd_config.bak.* | head -1 | awk -F/ '{print $NF}') /etc/ssh/sshd_config
jps_log_cmd "systemctl restart sshd" "Restarting SSH service with original config" "install.log" systemctl restart sshd
fi fi
jps_log "SUCCESS" "======== SFTP ADDON CONFIGURATION COMPLETED ========" "install.log"
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: commands:
@ -287,51 +176,34 @@ actions:
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Run the script directly capturing only the variables we need
source /home/jelastic/add-sftp-user-addon/log_helper.sh 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 # Run the script with all output going to the log file
jps_log "INFO" "======== STARTING SFTP USER CREATION ========" "user_creation.log" bash /home/jelastic/add-sftp-user-addon/add-sftp.sh ${globals.username} ${globals.password} ${globals.ssh_enabled} > "$OUTPUT_LOG" 2>&1
jps_log "INFO" "Creating user: ${globals.username}, SSH enabled: ${globals.ssh_enabled}" "user_creation.log"
# Run the SFTP user creation script with logging # Export only username - no other output
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" if [ -n "$CREATED_USERNAME" ]; then
echo "$CREATED_USERNAME"
# Capture the created username and password else
jps_log "INFO" "Retrieving created username" "user_creation.log" # Fallback to the original username if variable not set
CREATED_USERNAME=$(echo $CREATED_USERNAME) echo "${globals.username}"
jps_log "DEBUG" "Created username: $CREATED_USERNAME" "user_creation.log" fi
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
- setGlobals: - setGlobals:
username: ${response.out} username: ${response.out}
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Export only password - no other output
source /home/jelastic/add-sftp-user-addon/log_helper.sh if [ -n "$CREATED_PASSWORD" ]; then
echo "$CREATED_PASSWORD"
# Log the action else
jps_log "SUCCESS" "User ${globals.username} created successfully" "user_creation.log" # Fallback to the original password if variable not set
echo "${globals.password}"
# Export password fi
echo $CREATED_PASSWORD
- setGlobals: - setGlobals:
password: ${response.out} 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: - return:
type: info 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" 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]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Create log file for this run
source /home/jelastic/add-sftp-user-addon/log_helper.sh LOG_FILE="/home/jelastic/add-sftp-user-addon/logs/password_change.log"
touch "$LOG_FILE"
# Log start of password change # Silent source and redirect all logging
jps_log "INFO" "======== STARTING PASSWORD CHANGE ========" "password_change.log" {
jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "password_change.log" source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null
# Check if user exists jps_log "INFO" "======== STARTING PASSWORD CHANGE ========" "password_change.log"
if jps_log_cmd "id ${settings.manage_username} &>/dev/null" "Checking if user exists" "password_change.log"; then jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "password_change.log"
jps_log "INFO" "User ${settings.manage_username} exists" "password_change.log"
exit 0 # Check if user exists without logging to stdout
else if id ${settings.manage_username} &>/dev/null; then
jps_log "ERROR" "User ${settings.manage_username} does not exist" "password_change.log" jps_log "INFO" "User ${settings.manage_username} exists" "password_change.log"
echo "User does not exist" exit 0
exit 1 else
fi 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"): - if ("${response.exitStatus}" != "0"):
return: return:
type: error type: error
@ -373,25 +251,23 @@ actions:
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Redirect all logging
source /home/jelastic/add-sftp-user-addon/log_helper.sh {
source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null
# Log password change
jps_log "INFO" "Changing password for user: ${settings.manage_username}" "password_change.log" jps_log "INFO" "Changing password for user: ${settings.manage_username}" "password_change.log"
# Update password # Change password without logging to stdout
if jps_log_cmd "echo \"${settings.manage_username}:${globals.password}\" | chpasswd" "Changing user password" "password_change.log"; then if echo "${settings.manage_username}:${globals.password}" | chpasswd; then
jps_log "SUCCESS" "Password changed successfully for ${settings.manage_username}" "password_change.log" jps_log "SUCCESS" "Password changed successfully for ${settings.manage_username}" "password_change.log"
else echo "Password changed for ${settings.manage_username} at $(date)" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
jps_log "ERROR" "Failed to change password for ${settings.manage_username}" "password_change.log" else
exit 1 jps_log "ERROR" "Failed to change password for ${settings.manage_username}" "password_change.log"
fi 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" jps_log "SUCCESS" "======== PASSWORD CHANGE COMPLETED ========" "password_change.log"
} &> /home/jelastic/add-sftp-user-addon/logs/password_change.log
# Log completion
jps_log "SUCCESS" "======== PASSWORD CHANGE COMPLETED ========" "password_change.log"
- if ("${response.exitStatus}" != "0"): - if ("${response.exitStatus}" != "0"):
return: passwordChangeError return: passwordChangeError
- return: passwordChangeSuccess - return: passwordChangeSuccess
@ -400,21 +276,27 @@ actions:
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Create log file for this run
source /home/jelastic/add-sftp-user-addon/log_helper.sh LOG_FILE="/home/jelastic/add-sftp-user-addon/logs/user_deletion.log"
touch "$LOG_FILE"
# Log start of user deletion # Silent source and redirect all logging
jps_log "INFO" "======== STARTING USER DELETION ========" "user_deletion.log" {
jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "user_deletion.log" source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null
# Check if user exists jps_log "INFO" "======== STARTING USER DELETION ========" "user_deletion.log"
if jps_log_cmd "id ${settings.manage_username} &>/dev/null" "Checking if user exists" "user_deletion.log"; then jps_log "INFO" "Verifying user exists: ${settings.manage_username}" "user_deletion.log"
jps_log "INFO" "User ${settings.manage_username} exists" "user_deletion.log"
else # Check if user exists without logging to stdout
jps_log "ERROR" "User ${settings.manage_username} does not exist" "user_deletion.log" if id ${settings.manage_username} &>/dev/null; then
echo "User does not exist" jps_log "INFO" "User ${settings.manage_username} exists" "user_deletion.log"
exit 1 else
fi 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"): - if ("${response.exitStatus}" != "0"):
return: return:
type: error type: error
@ -424,19 +306,21 @@ actions:
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Redirect all logging
source /home/jelastic/add-sftp-user-addon/log_helper.sh {
source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null
# Verify home directory exists
jps_log "INFO" "Checking home directory for: ${settings.manage_username}" "user_deletion.log" 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 if test -d /home/sftpusers/${settings.manage_username}; then
jps_log "INFO" "Home directory found: /home/sftpusers/${settings.manage_username}" "user_deletion.log" jps_log "INFO" "Home directory found: /home/sftpusers/${settings.manage_username}" "user_deletion.log"
else else
jps_log "ERROR" "Home directory not found for user: ${settings.manage_username}" "user_deletion.log" jps_log "ERROR" "Home directory not found for user: ${settings.manage_username}" "user_deletion.log"
echo "User home directory not found" # Only output the error message
exit 1 echo "User home directory not found"
fi exit 1
fi
} &>> /home/jelastic/add-sftp-user-addon/logs/user_deletion.log
- if ("${response.exitStatus}" != "0"): - if ("${response.exitStatus}" != "0"):
return: return:
type: error type: error
@ -446,32 +330,44 @@ actions:
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Redirect all logging
source /home/jelastic/add-sftp-user-addon/log_helper.sh {
source /home/jelastic/add-sftp-user-addon/log_helper.sh &>/dev/null
# Log deletion process
jps_log "INFO" "Starting deletion of user: ${settings.manage_username}" "user_deletion.log" jps_log "INFO" "Starting deletion of user: ${settings.manage_username}" "user_deletion.log"
# Delete user account # First unmount any bind mounts
if jps_log_cmd "userdel ${settings.manage_username}" "Deleting user account" "user_deletion.log"; then if mount | grep -q "/home/sftpusers/${settings.manage_username}/data/ROOT"; then
jps_log "SUCCESS" "User account deleted: ${settings.manage_username}" "user_deletion.log" jps_log "INFO" "Unmounting bind mount for user: ${settings.manage_username}" "user_deletion.log"
else umount /home/sftpusers/${settings.manage_username}/data/ROOT
jps_log "ERROR" "Failed to delete user account: ${settings.manage_username}" "user_deletion.log" fi
exit 1
fi # Remove from fstab
if grep -q "/home/sftpusers/${settings.manage_username}/data/ROOT" /etc/fstab; then
# Remove home directory jps_log "INFO" "Removing bind mount from fstab for user: ${settings.manage_username}" "user_deletion.log"
if jps_log_cmd "rm -rf /home/sftpusers/${settings.manage_username}" "Removing user home directory" "user_deletion.log"; then sed -i "\|/home/sftpusers/${settings.manage_username}/data/ROOT|d" /etc/fstab
jps_log "SUCCESS" "Home directory removed: /home/sftpusers/${settings.manage_username}" "user_deletion.log" fi
else
jps_log "WARNING" "Failed to remove home directory for: ${settings.manage_username}" "user_deletion.log" # Delete user account
fi if userdel ${settings.manage_username}; then
jps_log "SUCCESS" "User account deleted: ${settings.manage_username}" "user_deletion.log"
# Log to main log file else
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" jps_log "ERROR" "Failed to delete user account: ${settings.manage_username}" "user_deletion.log"
exit 1
# Log completion fi
jps_log "SUCCESS" "======== USER DELETION COMPLETED ========" "user_deletion.log"
# 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"): - if ("${response.exitStatus}" != "0"):
return: deleteUserError return: deleteUserError
- return: deleteUserSuccess - return: deleteUserSuccess
@ -479,29 +375,38 @@ actions:
- cmd[cp]: - cmd[cp]:
user: root user: root
commands: |- commands: |-
# Source the logging helper # Create log file for this run
source /home/jelastic/add-sftp-user-addon/log_helper.sh LOG_FILE="/home/jelastic/add-sftp-user-addon/logs/list_users.log"
touch "$LOG_FILE"
# Log list users action # For list_users, log only to file, return clean output to response
jps_log "INFO" "======== LISTING SFTP USERS ========" "list_users.log" {
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 # List users without logging to stdout - only return the clean list
jps_log "INFO" "Retrieving list of SFTP users" "list_users.log"
# Use a safer approach to listing
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}') 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 # Check if any users were found
if [ -z "$USERS_LIST" ]; then 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 "" echo ""
else 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" echo "$USERS_LIST"
fi fi
jps_log "INFO" "======== USER LISTING COMPLETED ========" "list_users.log"
- if ("${response.exitStatus}" != "0" || "${response.out}" == ""): - if ("${response.exitStatus}" != "0" || "${response.out}" == ""):
return: return:
type: warning type: warning
@ -548,10 +453,10 @@ buttons:
caption: Change Password caption: Change Password
confirmText: "Are you sure you want to change the password for this user?" confirmText: "Are you sure you want to change the password for this user?"
submitButtonText: Change Password submitButtonText: Change Password
- settings: manageUserForm - settings: deleteUserForm
action: delete_user action: delete_user
caption: 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 submitButtonText: Delete User
onUninstall: onUninstall: