Fix SSH account creation
parent
4b5d7d1d8a
commit
32bd773fde
244
add-sftp.sh
244
add-sftp.sh
|
|
@ -1,184 +1,15 @@
|
|||
#!/bin/bash
|
||||
|
||||
# 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 debug mode based on the 4th script argument.
|
||||
# This must be set BEFORE sourcing the logging library.
|
||||
export DEBUG=${4:-0}
|
||||
|
||||
# Ensure log directory exists
|
||||
mkdir -p $LOG_DIR &>/dev/null
|
||||
# Source the canonical logging library.
|
||||
# The path is relative to this script's location.
|
||||
source "$(dirname "$0")/scripts/logging.sh"
|
||||
|
||||
# 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 script_id="$(date +%Y%m%d%H%M%S)-$$"
|
||||
|
||||
echo "[$script_id] $timestamp [$level] $message" >> "$LOG_FILE"
|
||||
|
||||
# Log errors to error log
|
||||
if [[ "$level" == "ERROR" || "$level" == "WARNING" ]]; then
|
||||
echo "[$script_id] $timestamp [$level] $message" >> "$ERROR_LOG"
|
||||
fi
|
||||
|
||||
# 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_to_file "ERROR" "$1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
log_to_file "WARNING" "$1"
|
||||
}
|
||||
|
||||
log_debug() {
|
||||
if [ "$DEBUG" -eq 1 ]; then
|
||||
log_to_file "DEBUG" "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
log_success() {
|
||||
log_to_file "SUCCESS" "$1"
|
||||
}
|
||||
|
||||
# Log system information for debugging context
|
||||
log_system_info() {
|
||||
log_debug "============= SYSTEM INFORMATION ============="
|
||||
log_debug "Operating System: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"')"
|
||||
log_debug "Kernel: $(uname -r)"
|
||||
log_debug "SSH Version: $(ssh -V 2>&1)"
|
||||
log_debug "SSH Config Status: $(systemctl status sshd | grep Active | awk '{print $2}')"
|
||||
log_debug "Script Parameters: username=$USERNAME, ssh_enabled=$SSH_ENABLED"
|
||||
log_debug "=============================================="
|
||||
}
|
||||
|
||||
# Function to log command execution with result
|
||||
log_cmd() {
|
||||
local cmd="$1"
|
||||
local cmd_desc="$2"
|
||||
|
||||
log_debug "Executing: $cmd_desc"
|
||||
log_debug "Command: $cmd"
|
||||
|
||||
# Execute command and capture output and status
|
||||
local output
|
||||
output=$(eval "$cmd" 2>&1)
|
||||
local status=$?
|
||||
|
||||
if [ $status -eq 0 ]; then
|
||||
log_debug "Command succeeded: $cmd_desc"
|
||||
if [ -n "$output" ]; then
|
||||
log_debug "Output: $output"
|
||||
fi
|
||||
else
|
||||
log_error "Command failed ($status): $cmd_desc"
|
||||
log_error "Error output: $output"
|
||||
fi
|
||||
|
||||
return $status
|
||||
}
|
||||
|
||||
# Fix SFTP configuration for Jelastic Virtuozzo LLSMP
|
||||
fix_sftp_config() {
|
||||
log "Checking and fixing SSH configuration for SFTP access"
|
||||
|
||||
# Create a backup of the original config
|
||||
log_cmd "cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d%H%M%S)" "Creating backup of original sshd_config"
|
||||
|
||||
# Fix the malformed SFTP subsystem line - using safer sed approach
|
||||
if grep -q "Subsystemsftp" /etc/ssh/sshd_config; then
|
||||
log "Fixing malformed SFTP subsystem configuration"
|
||||
# Use a temporary file for safer editing
|
||||
if 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 Subsystem line"; then
|
||||
log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying fixed configuration"
|
||||
log_success "Fixed malformed Subsystem line"
|
||||
else
|
||||
log_error "Failed to fix Subsystem line, reverting to backup"
|
||||
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"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Enable password authentication globally if it's set to no
|
||||
if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config; then
|
||||
log "Enabling password authentication in SSH"
|
||||
if log_cmd "sed 's/^PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Enabling password authentication"; then
|
||||
log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying configuration with password authentication"
|
||||
log_success "Enabled password authentication"
|
||||
else
|
||||
log_error "Failed to enable password authentication, reverting to backup"
|
||||
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"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove any existing incomplete/duplicate Match Group sftpusers blocks
|
||||
if grep -q "Match Group sftpusers" /etc/ssh/sshd_config; then
|
||||
log "Removing existing Match Group sftpusers blocks to prevent duplicates"
|
||||
# This complex sed pattern removes the Match Group sftpusers block completely
|
||||
if log_cmd "sed '/^Match Group sftpusers/,/^Match\|^[[:space:]]*$/d' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Removing existing Match Group blocks"; then
|
||||
log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying cleaned configuration"
|
||||
log_success "Removed existing Match Group sftpusers blocks"
|
||||
else
|
||||
log_error "Failed to remove existing Match Group blocks, reverting to backup"
|
||||
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"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure SFTP chroot jail cleanly at the end of the file
|
||||
log "Adding fresh SFTP chroot configuration for sftpusers group"
|
||||
cat >> /etc/ssh/sshd_config << EOF
|
||||
|
||||
# SFTP chroot configuration added by SFTP addon
|
||||
Match Group sftpusers
|
||||
ChrootDirectory /home/sftpusers/%u
|
||||
ForceCommand internal-sftp
|
||||
PasswordAuthentication yes
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
EOF
|
||||
|
||||
# Remove duplicate lines and verify config
|
||||
log "Cleaning up configuration file"
|
||||
if log_cmd "awk '!seen[\$0]++' /etc/ssh/sshd_config > /etc/ssh/sshd_config.new" "Removing duplicate lines"; then
|
||||
log_cmd "mv /etc/ssh/sshd_config.new /etc/ssh/sshd_config" "Applying deduplicated configuration"
|
||||
log_success "Removed duplicate lines from configuration"
|
||||
else
|
||||
log_error "Failed to remove duplicate lines, reverting to backup"
|
||||
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"
|
||||
fi
|
||||
|
||||
# Verify the configuration before restarting
|
||||
log "Verifying SSH configuration before restart"
|
||||
if log_cmd "sshd -t" "Validating sshd configuration"; then
|
||||
log_success "SSH configuration is valid, restarting service"
|
||||
log_cmd "systemctl restart sshd" "Restarting SSH service"
|
||||
else
|
||||
log_error "SSH configuration is INVALID, reverting to backup"
|
||||
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"
|
||||
log "Restarting SSH with original configuration"
|
||||
log_cmd "systemctl restart sshd" "Restarting SSH service with original config"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
# Source the canonical system preparation library.
|
||||
source "$(dirname "$0")/scripts/system_prep.sh"
|
||||
|
||||
validate_username() {
|
||||
local username=$1
|
||||
|
|
@ -193,39 +24,6 @@ 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
|
||||
|
|
@ -265,21 +63,17 @@ log_success "Pre-flight checks passed"
|
|||
|
||||
# Log system information
|
||||
log_system_info
|
||||
log_debug "Script Parameters: username=$USERNAME, ssh_enabled=$SSH_ENABLED"
|
||||
|
||||
# Fix SFTP configuration
|
||||
log "Phase 1: Configuring SSH/SFTP service"
|
||||
if ! fix_sftp_config; then
|
||||
if ! prepare_sftp_system; then
|
||||
log_error "Failed to configure SSH/SFTP service, exiting"
|
||||
echo "ERROR: Failed to configure SSH/SFTP service" >&2
|
||||
exit 1
|
||||
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
|
||||
|
|
@ -305,9 +99,14 @@ log_debug "Setting paths - USER_HOME: $USER_HOME, ROOT_DIRECTORY: $ROOT_DIRECTOR
|
|||
# Create the sftpusers group if it doesn't exist
|
||||
log "Phase 4: Setting up groups"
|
||||
if ! getent group sftpusers > /dev/null; then
|
||||
log "Creating sftpusers group for SFTP chroot access"
|
||||
log "Creating sftpusers group for SFTP-only access"
|
||||
log_cmd "groupadd sftpusers" "Creating sftpusers group"
|
||||
fi
|
||||
# Create the sshusers group if it doesn't exist
|
||||
if ! getent group sshusers > /dev/null; then
|
||||
log "Creating sshusers group for SFTP+SSH access"
|
||||
log_cmd "groupadd sshusers" "Creating sshusers group"
|
||||
fi
|
||||
log_success "Group setup completed"
|
||||
|
||||
# Ensure the parent directory for user home directories exists
|
||||
|
|
@ -390,10 +189,15 @@ log_success "Created bind mount for webroot access"
|
|||
|
||||
# Add user to the required groups
|
||||
log "Phase 10: Adding user to groups"
|
||||
log_cmd "usermod -aG sftpusers $USERNAME" "Adding user to sftpusers group"
|
||||
log_success "Added $USERNAME to sftpusers group for chroot access"
|
||||
if [ "$SSH_ENABLED" = "true" ]; then
|
||||
log_cmd "usermod -aG sshusers $USERNAME" "Adding user to sshusers group for SSH+SFTP access"
|
||||
log_success "Added $USERNAME to sshusers group"
|
||||
else
|
||||
log_cmd "usermod -aG sftpusers $USERNAME" "Adding user to sftpusers group for SFTP-only access"
|
||||
log_success "Added $USERNAME to sftpusers group"
|
||||
fi
|
||||
|
||||
log_cmd "usermod -aG litespeed $USERNAME" "Adding user to litespeed group"
|
||||
log_cmd "usermod -aG litespeed $USERNAME" "Adding user to litespeed group for file access"
|
||||
log_success "Added $USERNAME to litespeed group for file access"
|
||||
|
||||
# Create welcome file
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Simple logging function for SFTP User Addon
|
||||
log_message() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
local logfile="$3"
|
||||
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
|
||||
echo "[$timestamp][$level] $message" >> "/home/jelastic/add-sftp-user-addon/logs/$logfile"
|
||||
|
||||
# Also log to main log
|
||||
echo "[$timestamp][$level] $message" >> "/home/jelastic/add-sftp-user-addon/logs/script_output.log"
|
||||
|
||||
# Log errors/warnings
|
||||
if [[ "$level" == "ERROR" || "$level" == "WARNING" ]]; then
|
||||
echo "[$timestamp][$level] $message" >> "/home/jelastic/add-sftp-user-addon/logs/errors.log"
|
||||
fi
|
||||
|
||||
# Log success/info
|
||||
if [[ "$level" == "INFO" || "$level" == "SUCCESS" ]]; then
|
||||
echo "[$timestamp][$level] $message" >> "/home/jelastic/add-sftp-user-addon/logs/operations.log"
|
||||
fi
|
||||
}
|
||||
100
manifest.jps
100
manifest.jps
|
|
@ -2,7 +2,7 @@ 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.
|
||||
name: Add SFTP User for Jelastic
|
||||
name: Add SFTP User for MB Panel
|
||||
|
||||
targetNodes:
|
||||
nodeGroup: cp
|
||||
|
|
@ -76,26 +76,26 @@ onInstall:
|
|||
|
||||
# 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
|
||||
wget https://deploy-proxy.mightybox.io/addons/add-sftp-user/raw/branch/main/log_helper.sh -O /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
wget https://deploy-proxy.mightybox.io/addons/add-sftp-user/raw/branch/main/scripts/logging.sh -O /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
wget https://deploy-proxy.mightybox.io/addons/add-sftp-user/raw/branch/main/scripts/system_prep.sh -O /home/jelastic/add-sftp-user-addon/scripts/system_prep.sh
|
||||
|
||||
chmod +x /home/jelastic/add-sftp-user-addon/add-sftp.sh
|
||||
chmod +x /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
chmod +x /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
chmod +x /home/jelastic/add-sftp-user-addon/scripts/system_prep.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
|
||||
# Source libraries and run the system preparation function
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/system_prep.sh
|
||||
|
||||
# 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
|
||||
log "======== STARTING ADDON INSTALLATION ========"
|
||||
|
||||
# Fix ownership and permissions
|
||||
chown root:root /home
|
||||
chmod 755 /home
|
||||
# Create sftpusers group and directory before running full prep
|
||||
groupadd -f sftpusers
|
||||
mkdir -p /home/sftpusers
|
||||
|
||||
echo "Fixed /home ownership to root:root with 755 permissions" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
|
||||
echo "$(date) - Installing SFTP addon on Jelastic environment" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
|
||||
prepare_sftp_system
|
||||
|
||||
log "======== ADDON INSTALLATION COMPLETE ========"
|
||||
- cmd[cp]:
|
||||
user: root
|
||||
commands: |-
|
||||
|
|
@ -210,18 +210,18 @@ actions:
|
|||
touch "$LOG_FILE"
|
||||
|
||||
# Source the logging helper
|
||||
source /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
|
||||
# Log start of process
|
||||
log_message "INFO" "======== STARTING PASSWORD CHANGE ========" "password_change.log"
|
||||
log_message "INFO" "Verifying user exists: ${settings.manage_username}" "password_change.log"
|
||||
log "======== STARTING PASSWORD CHANGE ========"
|
||||
log "Verifying user exists: ${settings.manage_username}"
|
||||
|
||||
# Check if user exists
|
||||
if id ${settings.manage_username} &>/dev/null; then
|
||||
log_message "INFO" "User ${settings.manage_username} exists" "password_change.log"
|
||||
log "User ${settings.manage_username} exists"
|
||||
exit 0
|
||||
else
|
||||
log_message "ERROR" "User ${settings.manage_username} does not exist" "password_change.log"
|
||||
log_error "User ${settings.manage_username} does not exist"
|
||||
echo "User does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -243,21 +243,21 @@ actions:
|
|||
user: root
|
||||
commands: |-
|
||||
# Source the logging helper
|
||||
source /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
|
||||
log_message "INFO" "Changing password for user: ${settings.manage_username}" "password_change.log"
|
||||
log "Changing password for user: ${settings.manage_username}"
|
||||
|
||||
# Change password using echo and chpasswd
|
||||
if echo "${settings.manage_username}:${globals.password}" | /usr/sbin/chpasswd; then
|
||||
log_message "SUCCESS" "Password changed successfully for ${settings.manage_username}" "password_change.log"
|
||||
log_success "Password changed successfully for ${settings.manage_username}"
|
||||
echo "Password changed for ${settings.manage_username} at $(date)" >> /home/jelastic/add-sftp-user-addon/logs/script_output.log
|
||||
exit 0
|
||||
else
|
||||
log_message "ERROR" "Failed to change password for ${settings.manage_username}" "password_change.log"
|
||||
log_error "Failed to change password for ${settings.manage_username}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_message "SUCCESS" "======== PASSWORD CHANGE COMPLETED ========" "password_change.log"
|
||||
log_success "======== PASSWORD CHANGE COMPLETED ========"
|
||||
- if ("${response.exitStatus}" != "0"):
|
||||
return: passwordChangeError
|
||||
- return: passwordChangeSuccess
|
||||
|
|
@ -271,18 +271,18 @@ actions:
|
|||
touch "$LOG_FILE"
|
||||
|
||||
# Source the logging helper
|
||||
source /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
|
||||
# Log start of process
|
||||
log_message "INFO" "======== STARTING USER DELETION ========" "user_deletion.log"
|
||||
log_message "INFO" "Verifying user exists: ${settings.manage_username}" "user_deletion.log"
|
||||
log "======== STARTING USER DELETION ========"
|
||||
log "Verifying user exists: ${settings.manage_username}"
|
||||
|
||||
# Check if user exists
|
||||
if id ${settings.manage_username} &>/dev/null; then
|
||||
log_message "INFO" "User ${settings.manage_username} exists" "user_deletion.log"
|
||||
log "User ${settings.manage_username} exists"
|
||||
exit 0
|
||||
else
|
||||
log_message "ERROR" "User ${settings.manage_username} does not exist" "user_deletion.log"
|
||||
log_error "User ${settings.manage_username} does not exist"
|
||||
echo "User does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -296,15 +296,15 @@ actions:
|
|||
user: root
|
||||
commands: |-
|
||||
# Source the logging helper
|
||||
source /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
|
||||
log_message "INFO" "Checking home directory for: ${settings.manage_username}" "user_deletion.log"
|
||||
log "Checking home directory for: ${settings.manage_username}"
|
||||
|
||||
if test -d /home/sftpusers/${settings.manage_username}; then
|
||||
log_message "INFO" "Home directory found: /home/sftpusers/${settings.manage_username}" "user_deletion.log"
|
||||
log "Home directory found: /home/sftpusers/${settings.manage_username}"
|
||||
exit 0
|
||||
else
|
||||
log_message "ERROR" "Home directory not found for user: ${settings.manage_username}" "user_deletion.log"
|
||||
log_error "Home directory not found for user: ${settings.manage_username}"
|
||||
echo "User home directory not found"
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -318,38 +318,38 @@ actions:
|
|||
user: root
|
||||
commands: |-
|
||||
# Source the logging helper
|
||||
source /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
|
||||
log_message "INFO" "Starting deletion of user: ${settings.manage_username}" "user_deletion.log"
|
||||
log "Starting deletion of user: ${settings.manage_username}"
|
||||
|
||||
# First unmount any bind mounts
|
||||
if mount | grep -q "/home/sftpusers/${settings.manage_username}/data/ROOT"; then
|
||||
log_message "INFO" "Unmounting bind mount for user: ${settings.manage_username}" "user_deletion.log"
|
||||
log "Unmounting bind mount for user: ${settings.manage_username}"
|
||||
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
|
||||
log_message "INFO" "Removing bind mount from fstab for user: ${settings.manage_username}" "user_deletion.log"
|
||||
log "Removing bind mount from fstab for user: ${settings.manage_username}"
|
||||
sed -i "\|/home/sftpusers/${settings.manage_username}/data/ROOT|d" /etc/fstab
|
||||
fi
|
||||
|
||||
# Delete user account
|
||||
if userdel ${settings.manage_username}; then
|
||||
log_message "SUCCESS" "User account deleted: ${settings.manage_username}" "user_deletion.log"
|
||||
log_success "User account deleted: ${settings.manage_username}"
|
||||
else
|
||||
log_message "ERROR" "Failed to delete user account: ${settings.manage_username}" "user_deletion.log"
|
||||
log_error "Failed to delete user account: ${settings.manage_username}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove home directory
|
||||
if rm -rf /home/sftpusers/${settings.manage_username}; then
|
||||
log_message "SUCCESS" "Home directory removed: /home/sftpusers/${settings.manage_username}" "user_deletion.log"
|
||||
log_success "Home directory removed: /home/sftpusers/${settings.manage_username}"
|
||||
else
|
||||
log_message "WARNING" "Failed to remove home directory for: ${settings.manage_username}" "user_deletion.log"
|
||||
log_warning "Failed to remove home directory for: ${settings.manage_username}"
|
||||
fi
|
||||
|
||||
log_message "SUCCESS" "======== USER DELETION COMPLETED ========" "user_deletion.log"
|
||||
log_success "======== USER DELETION COMPLETED ========"
|
||||
exit 0
|
||||
- if ("${response.exitStatus}" != "0"):
|
||||
return: deleteUserError
|
||||
|
|
@ -363,24 +363,24 @@ actions:
|
|||
touch "$LOG_FILE"
|
||||
|
||||
# Source the logging helper
|
||||
source /home/jelastic/add-sftp-user-addon/log_helper.sh
|
||||
source /home/jelastic/add-sftp-user-addon/scripts/logging.sh
|
||||
|
||||
# Log start of process
|
||||
log_message "INFO" "======== LISTING SFTP USERS ========" "list_users.log"
|
||||
log_message "INFO" "Retrieving list of SFTP users" "list_users.log"
|
||||
log "======== LISTING SFTP USERS ========"
|
||||
log "Retrieving list of SFTP users"
|
||||
|
||||
# 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
|
||||
log_message "WARNING" "No SFTP users found" "list_users.log"
|
||||
log_message "INFO" "======== USER LISTING COMPLETED ========" "list_users.log"
|
||||
log_warning "No SFTP users found"
|
||||
log "======== USER LISTING COMPLETED ========"
|
||||
echo ""
|
||||
else
|
||||
log_message "SUCCESS" "Retrieved list of SFTP users" "list_users.log"
|
||||
log_message "DEBUG" "Found users: $(echo "$USERS_LIST" | wc -l)" "list_users.log"
|
||||
log_message "INFO" "======== USER LISTING COMPLETED ========" "list_users.log"
|
||||
log_success "Retrieved list of SFTP users"
|
||||
log_debug "Found users: $(echo "$USERS_LIST" | wc -l)"
|
||||
log "======== USER LISTING COMPLETED ========"
|
||||
echo "$USERS_LIST"
|
||||
fi
|
||||
- if ("${response.exitStatus}" != "0" || "${response.out}" == ""):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ==============================================================================
|
||||
# Canonical Logging Library for SFTP User Addon
|
||||
#
|
||||
# Provides a standardized set of functions for logging operations, errors,
|
||||
# debug messages, and command executions. This script is intended to be
|
||||
# sourced by other scripts in the addon.
|
||||
# ==============================================================================
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Log Configuration
|
||||
# ------------------------------------------------------------------------------
|
||||
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"
|
||||
|
||||
# Enable debug logging by setting DEBUG=1 in the environment, otherwise default to 0.
|
||||
DEBUG=${DEBUG:-0}
|
||||
|
||||
# Ensure the log directory exists. The calling script should have permissions.
|
||||
mkdir -p "$LOG_DIR" &>/dev/null
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Core Logging Engine
|
||||
#
|
||||
# @param {string} level - The log level (e.g., INFO, ERROR, DEBUG).
|
||||
# @param {string} message - The message to log.
|
||||
# ------------------------------------------------------------------------------
|
||||
log_to_file() {
|
||||
local level=${1:-INFO}
|
||||
local message=${2}
|
||||
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||
# Generate a unique ID for each script execution for better traceability.
|
||||
local script_id="$(date +%Y%m%d%H%M%S)-$$"
|
||||
|
||||
# Write to the main aggregated log file.
|
||||
echo "[$script_id] $timestamp [$level] $message" >> "$LOG_FILE"
|
||||
|
||||
# Route messages to specific logs based on level.
|
||||
if [[ "$level" == "ERROR" || "$level" == "WARNING" ]]; then
|
||||
echo "[$script_id] $timestamp [$level] $message" >> "$ERROR_LOG"
|
||||
fi
|
||||
|
||||
if [[ "$level" == "INFO" || "$level" == "SUCCESS" ]]; then
|
||||
echo "[$script_id] $timestamp [$level] $message" >> "$OPERATION_LOG"
|
||||
fi
|
||||
|
||||
if [[ "$level" == "DEBUG" && "$DEBUG" -eq 1 ]]; then
|
||||
echo "[$script_id] $timestamp [$level] $message" >> "$DEBUG_LOG"
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Logging Helper Functions
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Logs an informational message.
|
||||
log() {
|
||||
log_to_file "INFO" "$1"
|
||||
}
|
||||
|
||||
# Logs an error message.
|
||||
log_error() {
|
||||
log_to_file "ERROR" "$1"
|
||||
}
|
||||
|
||||
# Logs a warning message.
|
||||
log_warning() {
|
||||
log_to_file "WARNING" "$1"
|
||||
}
|
||||
|
||||
# Logs a debug message, only if DEBUG is enabled.
|
||||
log_debug() {
|
||||
if [ "$DEBUG" -eq 1 ]; then
|
||||
log_to_file "DEBUG" "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Logs a success message.
|
||||
log_success() {
|
||||
log_to_file "SUCCESS" "$1"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# System & Command Logging
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Logs critical system information for debugging context.
|
||||
log_system_info() {
|
||||
log_debug "============= SYSTEM INFORMATION ============="
|
||||
log_debug "Operating System: $(cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '\"')"
|
||||
log_debug "Kernel: $(uname -r)"
|
||||
log_debug "SSH Version: $(ssh -V 2>&1)"
|
||||
log_debug "SSH Config Status: $(systemctl status sshd | grep Active | awk '{print $2}')"
|
||||
# Note: Specific script parameters should be logged by the calling script.
|
||||
log_debug "=============================================="
|
||||
}
|
||||
|
||||
# Executes a command, captures its output and status, and logs the result.
|
||||
#
|
||||
# @param {string} cmd - The command to execute.
|
||||
# @param {string} cmd_desc - A human-readable description of the command.
|
||||
# @returns {int} The exit status of the executed command.
|
||||
# ------------------------------------------------------------------------------
|
||||
log_cmd() {
|
||||
local cmd="$1"
|
||||
local cmd_desc="$2"
|
||||
|
||||
log_debug "Executing: $cmd_desc"
|
||||
log_debug "Command: $cmd"
|
||||
|
||||
# Execute command and capture combined stdout/stderr.
|
||||
local output
|
||||
output=$(eval "$cmd" 2>&1)
|
||||
local status=$?
|
||||
|
||||
if [ $status -eq 0 ]; then
|
||||
log_debug "Command succeeded: $cmd_desc"
|
||||
if [ -n "$output" ]; then
|
||||
log_debug "Output: $output"
|
||||
fi
|
||||
else
|
||||
log_error "Command failed with status $status: $cmd_desc"
|
||||
log_error "Error output: $output"
|
||||
fi
|
||||
|
||||
return $status
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ==============================================================================
|
||||
# Canonical System Preparation Library for SFTP User Addon
|
||||
#
|
||||
# Provides a standardized function to prepare the Jelastic environment for
|
||||
# secure SFTP/SSH user chroot jailing.
|
||||
# ==============================================================================
|
||||
|
||||
# This script expects that 'scripts/logging.sh' has already been sourced
|
||||
# by the calling script, so functions like log() and log_cmd() are available.
|
||||
|
||||
prepare_sftp_system() {
|
||||
log "Phase: Preparing and Verifying System for SFTP/SSH"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Step 1: Fix critical directory permissions for chroot
|
||||
# --------------------------------------------------------------------------
|
||||
log "Checking and fixing critical directory permissions for chroot jail..."
|
||||
|
||||
if [ -d "/home" ] && [[ "$(stat -c '%U:%G' /home)" != "root:root" ]]; then
|
||||
log "Fixing /home ownership. Current: $(stat -c '%U:%G' /home)"
|
||||
log_cmd "chown root:root /home" "Set /home owner to root:root"
|
||||
fi
|
||||
log_cmd "chmod 755 /home" "Set /home permissions to 755"
|
||||
log_success "Directory permissions check complete."
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Step 2: Ensure PasswordAuthentication is enabled globally
|
||||
# --------------------------------------------------------------------------
|
||||
local sshd_config="/etc/ssh/sshd_config"
|
||||
log "Ensuring global PasswordAuthentication is enabled in $sshd_config..."
|
||||
|
||||
# Use grep to check the current state and sed to change it if needed.
|
||||
# This is more robust than blindly adding a line.
|
||||
if grep -qE "^[#\s]*PasswordAuthentication\s+no" "$sshd_config"; then
|
||||
log "PasswordAuthentication is disabled, enabling it now."
|
||||
# Comment out the old line and add the new one to be explicit.
|
||||
log_cmd "sed -i 's/^[#\s]*PasswordAuthentication\s+no/#&/' $sshd_config" "Commenting out old PasswordAuthentication line"
|
||||
log_cmd "echo 'PasswordAuthentication yes' >> $sshd_config" "Adding 'PasswordAuthentication yes' to sshd_config"
|
||||
elif ! grep -qE "^[#\s]*PasswordAuthentication\s+yes" "$sshd_config"; then
|
||||
log "PasswordAuthentication setting not found, adding it."
|
||||
log_cmd "echo 'PasswordAuthentication yes' >> $sshd_config" "Adding 'PasswordAuthentication yes' to sshd_config"
|
||||
else
|
||||
log_debug "PasswordAuthentication is already enabled."
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Step 3: Create a dedicated addon config for modern SSH servers
|
||||
# --------------------------------------------------------------------------
|
||||
local addon_config_file="/etc/ssh/sshd_config.d/99-sftp-addon.conf"
|
||||
log "Creating dedicated SSH configuration at $addon_config_file..."
|
||||
|
||||
# This configuration uses a two-group system:
|
||||
# 1. 'sftpusers': SFTP-only, forced into SFTP mode.
|
||||
# 2. 'sshusers': SFTP + SSH, allowed a real shell but still chrooted.
|
||||
cat > "$addon_config_file" << EOF
|
||||
# Configuration managed by SFTP-Addon - DO NOT EDIT MANUALLY
|
||||
|
||||
# --- SFTP-ONLY USERS ---
|
||||
# Users in this group are forced into the SFTP server and cannot get a shell.
|
||||
Match Group sftpusers
|
||||
ChrootDirectory /home/sftpusers/%u
|
||||
ForceCommand internal-sftp
|
||||
PasswordAuthentication yes
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
|
||||
# --- SSH & SFTP USERS ---
|
||||
# Users in this group can get a real SSH shell but are jailed to their home.
|
||||
Match Group sshusers
|
||||
ChrootDirectory /home/sftpusers/%u
|
||||
PasswordAuthentication yes
|
||||
AllowTcpForwarding no
|
||||
X11Forwarding no
|
||||
EOF
|
||||
log_success "Created dedicated SSH configuration for addon."
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Step 4: Validate configuration and restart SSH service
|
||||
# --------------------------------------------------------------------------
|
||||
log "Validating new SSH configuration..."
|
||||
if log_cmd "sshd -t" "Validating sshd configuration syntax"; then
|
||||
log_success "SSH configuration is valid. Restarting SSH service..."
|
||||
if ! log_cmd "systemctl restart sshd" "Restarting sshd service"; then
|
||||
log_error "Failed to restart sshd, but configuration was valid. Manual check may be required."
|
||||
return 1
|
||||
fi
|
||||
log_success "SSHD service restarted successfully."
|
||||
else
|
||||
log_error "SSH configuration is INVALID. The new config file at $addon_config_file may contain an error."
|
||||
# We don't revert here because the base config was likely valid.
|
||||
# The new file simply won't be loaded by sshd.
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Ensure /home/sftpusers exists with correct ownership and permissions
|
||||
if [ ! -d "/home/sftpusers" ]; then
|
||||
log_cmd "mkdir -p /home/sftpusers" "Creating /home/sftpusers directory"
|
||||
fi
|
||||
log_cmd "chown root:root /home/sftpusers" "Setting /home/sftpusers ownership to root:root"
|
||||
log_cmd "chmod 755 /home/sftpusers" "Setting /home/sftpusers permissions to 755"
|
||||
|
||||
log_success "System preparation complete."
|
||||
return 0
|
||||
}
|
||||
Loading…
Reference in New Issue