2023-10-26 15:54:56 +00:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
2025-07-29 16:33:46 +00:00
|
|
|
# Set debug mode based on the 4th script argument.
|
|
|
|
|
# This must be set BEFORE sourcing the logging library.
|
|
|
|
|
export DEBUG=${4:-0}
|
2023-11-03 14:35:15 +00:00
|
|
|
|
2025-07-29 16:33:46 +00:00
|
|
|
# Source the canonical logging library.
|
|
|
|
|
# The path is relative to this script's location.
|
|
|
|
|
source "$(dirname "$0")/scripts/logging.sh"
|
2025-04-10 15:23:32 +00:00
|
|
|
|
2025-07-29 16:33:46 +00:00
|
|
|
# Source the canonical system preparation library.
|
|
|
|
|
source "$(dirname "$0")/scripts/system_prep.sh"
|
2025-04-10 15:23:32 +00:00
|
|
|
|
2025-04-07 17:00:14 +00:00
|
|
|
validate_username() {
|
|
|
|
|
local username=$1
|
2025-04-10 15:23:32 +00:00
|
|
|
log_debug "Validating username: $username"
|
|
|
|
|
|
2025-04-07 17:47:19 +00:00
|
|
|
if ! [[ $username =~ ^[a-zA-Z0-9_]{3,32}$ ]]; then
|
|
|
|
|
log_error "Invalid username format. Username must be 3-32 characters long and contain only letters, numbers, and underscores."
|
2025-04-07 17:00:14 +00:00
|
|
|
return 1
|
|
|
|
|
fi
|
2025-04-10 15:23:32 +00:00
|
|
|
|
|
|
|
|
log_debug "Username validation passed"
|
2025-04-07 17:00:14 +00:00
|
|
|
return 0
|
2023-11-02 17:26:02 +00:00
|
|
|
}
|
2023-10-30 13:35:32 +00:00
|
|
|
|
2025-04-10 16:07:08 +00:00
|
|
|
# Main script
|
2023-10-30 17:09:45 +00:00
|
|
|
USERNAME=$1
|
|
|
|
|
PASSWORD=$2
|
2025-04-10 15:23:32 +00:00
|
|
|
SSH_ENABLED=${3:-false}
|
|
|
|
|
|
2025-07-24 17:44:09 +00:00
|
|
|
# Validate required parameters
|
|
|
|
|
if [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then
|
|
|
|
|
echo "ERROR: Missing required parameters. Usage: $0 <username> <password> [ssh_enabled]" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
2025-04-10 16:07:08 +00:00
|
|
|
# Log to file only
|
|
|
|
|
log "======== STARTING SFTP USER SETUP ========"
|
|
|
|
|
log "Script started with username: $USERNAME, ssh_enabled: $SSH_ENABLED"
|
2023-11-03 14:35:15 +00:00
|
|
|
|
2025-07-24 17:44:09 +00:00
|
|
|
# Pre-flight checks
|
|
|
|
|
log "Phase 0: Pre-flight environment checks"
|
|
|
|
|
if [ ! -d "/var/www/webroot/ROOT" ]; then
|
|
|
|
|
log_error "Web root directory /var/www/webroot/ROOT does not exist"
|
|
|
|
|
echo "ERROR: Web root directory /var/www/webroot/ROOT does not exist" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ ! -x "/usr/sbin/useradd" ]; then
|
|
|
|
|
log_error "useradd command not found or not executable"
|
|
|
|
|
echo "ERROR: useradd command not found or not executable" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if [ ! -x "/usr/sbin/chpasswd" ]; then
|
|
|
|
|
log_error "chpasswd command not found or not executable"
|
|
|
|
|
echo "ERROR: chpasswd command not found or not executable" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
log_success "Pre-flight checks passed"
|
|
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
# Log system information
|
|
|
|
|
log_system_info
|
2025-07-29 16:33:46 +00:00
|
|
|
log_debug "Script Parameters: username=$USERNAME, ssh_enabled=$SSH_ENABLED"
|
2025-04-10 15:23:32 +00:00
|
|
|
|
|
|
|
|
# Fix SFTP configuration
|
|
|
|
|
log "Phase 1: Configuring SSH/SFTP service"
|
2025-07-29 16:33:46 +00:00
|
|
|
if ! prepare_sftp_system; then
|
2025-04-10 15:23:32 +00:00
|
|
|
log_error "Failed to configure SSH/SFTP service, exiting"
|
2025-07-24 17:44:09 +00:00
|
|
|
echo "ERROR: Failed to configure SSH/SFTP service" >&2
|
2025-04-10 15:23:32 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
log_success "SSH/SFTP service configuration completed"
|
2023-10-26 15:54:56 +00:00
|
|
|
|
2025-04-07 17:47:19 +00:00
|
|
|
# Validate username format
|
2025-04-10 15:23:32 +00:00
|
|
|
log "Phase 2: Validating username"
|
2025-04-07 17:00:14 +00:00
|
|
|
if ! validate_username "$USERNAME"; then
|
2025-04-10 15:23:32 +00:00
|
|
|
log_error "Username validation failed, exiting"
|
2025-07-24 17:44:09 +00:00
|
|
|
echo "ERROR: Username validation failed for: $USERNAME" >&2
|
2025-04-07 17:00:14 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "Username validation passed"
|
2025-04-07 17:00:14 +00:00
|
|
|
|
|
|
|
|
# Check if user already exists
|
2025-04-10 15:23:32 +00:00
|
|
|
log "Phase 3: Checking if user already exists"
|
2025-04-07 17:00:14 +00:00
|
|
|
if id "$USERNAME" &>/dev/null; then
|
|
|
|
|
log_error "Username $USERNAME already exists. Please choose a different username."
|
2025-07-24 17:44:09 +00:00
|
|
|
echo "ERROR: Username $USERNAME already exists" >&2
|
2025-04-07 17:00:14 +00:00
|
|
|
exit 1
|
|
|
|
|
fi
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "Username is available for creation"
|
2023-11-02 17:48:26 +00:00
|
|
|
|
2023-11-01 10:54:29 +00:00
|
|
|
USER_HOME="/home/sftpusers/$USERNAME"
|
2023-10-30 16:13:29 +00:00
|
|
|
ROOT_DIRECTORY="/var/www/webroot/ROOT"
|
2025-04-10 15:23:32 +00:00
|
|
|
log_debug "Setting paths - USER_HOME: $USER_HOME, ROOT_DIRECTORY: $ROOT_DIRECTORY"
|
2023-11-01 06:42:52 +00:00
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
# Create the sftpusers group if it doesn't exist
|
|
|
|
|
log "Phase 4: Setting up groups"
|
|
|
|
|
if ! getent group sftpusers > /dev/null; then
|
2025-07-29 16:33:46 +00:00
|
|
|
log "Creating sftpusers group for SFTP-only access"
|
2025-04-10 15:23:32 +00:00
|
|
|
log_cmd "groupadd sftpusers" "Creating sftpusers group"
|
2023-11-03 14:35:15 +00:00
|
|
|
fi
|
2025-07-29 16:33:46 +00:00
|
|
|
# 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
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "Group setup completed"
|
2023-11-03 14:35:15 +00:00
|
|
|
|
2023-11-03 15:33:26 +00:00
|
|
|
# Ensure the parent directory for user home directories exists
|
2025-04-10 15:23:32 +00:00
|
|
|
log "Phase 5: Setting up directories"
|
2023-11-03 15:33:26 +00:00
|
|
|
if [ ! -d "/home/sftpusers" ]; then
|
2025-04-10 15:23:32 +00:00
|
|
|
log "Creating /home/sftpusers directory"
|
|
|
|
|
log_cmd "mkdir -p /home/sftpusers" "Creating /home/sftpusers directory"
|
|
|
|
|
log_cmd "chown root:root /home/sftpusers" "Setting ownership for /home/sftpusers"
|
|
|
|
|
log_cmd "chmod 755 /home/sftpusers" "Setting permissions for /home/sftpusers"
|
2023-11-03 14:35:15 +00:00
|
|
|
fi
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "Directory setup completed"
|
2023-11-03 14:35:15 +00:00
|
|
|
|
2025-07-29 16:47:55 +00:00
|
|
|
# Determine shell path
|
|
|
|
|
if [ "$SSH_ENABLED" = "true" ]; then
|
|
|
|
|
USER_SHELL="/shell/bin/bash"
|
|
|
|
|
else
|
|
|
|
|
USER_SHELL="/sbin/nologin"
|
|
|
|
|
fi
|
|
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
# Create the user account
|
|
|
|
|
log "Phase 6: Creating user account"
|
|
|
|
|
if [ "$SSH_ENABLED" = "true" ]; then
|
|
|
|
|
log "Creating user with SSH access"
|
2025-07-29 16:47:55 +00:00
|
|
|
if ! log_cmd "useradd -d $USER_HOME -m -s $USER_SHELL $USERNAME" "Creating user with SSH shell inside jail"; then
|
2025-07-24 17:44:09 +00:00
|
|
|
log_error "Failed to create user account with SSH access"
|
|
|
|
|
echo "ERROR: Failed to create user account with SSH access" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
2023-11-03 15:23:56 +00:00
|
|
|
else
|
2025-04-10 15:23:32 +00:00
|
|
|
log "Creating user with SFTP-only access"
|
2025-07-29 16:47:55 +00:00
|
|
|
if ! log_cmd "useradd -d $USER_HOME -m -s $USER_SHELL $USERNAME" "Creating user with nologin shell"; then
|
2025-07-24 17:44:09 +00:00
|
|
|
log_error "Failed to create user account with SFTP-only access"
|
|
|
|
|
echo "ERROR: Failed to create user account with SFTP-only access" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
2023-11-03 14:35:15 +00:00
|
|
|
fi
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "User account created"
|
|
|
|
|
|
|
|
|
|
# Set password
|
|
|
|
|
log "Phase 7: Setting user password"
|
2025-07-24 17:44:09 +00:00
|
|
|
if ! log_cmd "echo '$USERNAME:$PASSWORD' | chpasswd" "Setting user password"; then
|
|
|
|
|
log_error "Failed to set password for user $USERNAME"
|
|
|
|
|
echo "ERROR: Failed to set password for user $USERNAME" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "Password set for user $USERNAME"
|
|
|
|
|
|
|
|
|
|
# Set up proper directory structure for chroot jail
|
|
|
|
|
log "Phase 8: Setting up chroot jail structure"
|
|
|
|
|
log_cmd "chown root:root $USER_HOME" "Setting ownership for chroot directory"
|
|
|
|
|
log_cmd "chmod 755 $USER_HOME" "Setting permissions for chroot directory"
|
2023-10-26 15:54:56 +00:00
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
# Create writable data directory for user
|
|
|
|
|
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"
|
2023-11-01 05:22:36 +00:00
|
|
|
|
2025-04-10 16:07:08 +00:00
|
|
|
# Create mount point for webroot (using bind mount instead of symlink)
|
|
|
|
|
log "Phase 9: Setting up webroot access via bind mount"
|
2025-07-24 17:44:09 +00:00
|
|
|
if ! log_cmd "mkdir -p $USER_HOME/data/ROOT" "Creating ROOT mount point"; then
|
|
|
|
|
log_error "Failed to create ROOT mount point directory"
|
|
|
|
|
echo "ERROR: Failed to create ROOT mount point directory" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Check if ROOT_DIRECTORY exists before mounting
|
|
|
|
|
if [ ! -d "$ROOT_DIRECTORY" ]; then
|
|
|
|
|
log_error "Root directory $ROOT_DIRECTORY does not exist"
|
|
|
|
|
echo "ERROR: Root directory $ROOT_DIRECTORY does not exist" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
if ! log_cmd "mount --bind $ROOT_DIRECTORY $USER_HOME/data/ROOT" "Binding webroot to user's ROOT directory"; then
|
|
|
|
|
log_error "Failed to create bind mount for webroot access"
|
|
|
|
|
echo "ERROR: Failed to create bind mount for webroot access" >&2
|
|
|
|
|
exit 1
|
|
|
|
|
fi
|
2025-04-10 16:07:08 +00:00
|
|
|
|
|
|
|
|
# Add mount to fstab to persist across reboots
|
|
|
|
|
if ! grep -q "$ROOT_DIRECTORY $USER_HOME/data/ROOT" /etc/fstab; then
|
2025-07-24 17:44:09 +00:00
|
|
|
if ! log_cmd "echo \"$ROOT_DIRECTORY $USER_HOME/data/ROOT none bind 0 0\" >> /etc/fstab" "Adding bind mount to fstab"; then
|
|
|
|
|
log_warning "Failed to add bind mount to fstab - mount may not persist across reboots"
|
|
|
|
|
fi
|
2025-04-10 16:07:08 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
log_success "Created bind mount for webroot access"
|
2023-10-26 15:54:56 +00:00
|
|
|
|
2025-07-29 16:59:23 +00:00
|
|
|
# Bind shell, dev, and proc into chroot for SSH users
|
|
|
|
|
if [ "$SSH_ENABLED" = "true" ]; then
|
|
|
|
|
log "Phase 9.1: Mounting shell/dev/proc into chroot"
|
|
|
|
|
# 1. shell template
|
|
|
|
|
if ! mount | grep -q "${USER_HOME}/shell"; then
|
|
|
|
|
log_cmd "mkdir -p ${USER_HOME}/shell" "Creating shell mount point"
|
|
|
|
|
log_cmd "mount --bind /home/sftp-shell ${USER_HOME}/shell" "Binding shell template"
|
|
|
|
|
grep -q "/home/sftp-shell ${USER_HOME}/shell" /etc/fstab || echo "/home/sftp-shell ${USER_HOME}/shell none bind 0 0" >> /etc/fstab
|
|
|
|
|
fi
|
|
|
|
|
# 2. dev nodes
|
|
|
|
|
if ! mount | grep -q "${USER_HOME}/dev"; then
|
|
|
|
|
log_cmd "mkdir -p ${USER_HOME}/dev" "Creating dev mount point"
|
|
|
|
|
log_cmd "mount --bind /home/sftp-shell/dev ${USER_HOME}/dev" "Binding dev nodes"
|
|
|
|
|
grep -q "/home/sftp-shell/dev ${USER_HOME}/dev" /etc/fstab || echo "/home/sftp-shell/dev ${USER_HOME}/dev none bind 0 0" >> /etc/fstab
|
|
|
|
|
fi
|
|
|
|
|
# 3. read-only proc
|
|
|
|
|
if ! mount | grep -q "${USER_HOME}/proc"; then
|
|
|
|
|
log_cmd "mkdir -p ${USER_HOME}/proc" "Creating proc mount point"
|
|
|
|
|
log_cmd "mount --bind /proc ${USER_HOME}/proc" "Binding proc"
|
|
|
|
|
log_cmd "mount -o remount,bind,ro ${USER_HOME}/proc" "Remount proc read-only"
|
|
|
|
|
grep -q "/proc ${USER_HOME}/proc" /etc/fstab || echo "/proc ${USER_HOME}/proc none bind,ro 0 0" >> /etc/fstab
|
|
|
|
|
fi
|
|
|
|
|
log_success "Shell, dev, and proc mounted into chroot"
|
|
|
|
|
fi
|
|
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
# Add user to the required groups
|
|
|
|
|
log "Phase 10: Adding user to groups"
|
2025-07-29 16:33:46 +00:00
|
|
|
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
|
2023-11-01 16:48:25 +00:00
|
|
|
|
2025-07-29 16:33:46 +00:00
|
|
|
log_cmd "usermod -aG litespeed $USERNAME" "Adding user to litespeed group for file access"
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "Added $USERNAME to litespeed group for file access"
|
2023-10-27 16:19:22 +00:00
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
# Create welcome file
|
|
|
|
|
log "Phase 11: Creating welcome file"
|
|
|
|
|
cat > $USER_HOME/data/welcome.txt << EOF
|
|
|
|
|
Welcome to your SFTP account on Jelastic!
|
2023-10-26 15:54:56 +00:00
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
Your account has been set up with the following details:
|
2023-11-01 06:42:52 +00:00
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
Username: $USERNAME
|
|
|
|
|
Home Directory: $USER_HOME
|
|
|
|
|
Web Root: $USER_HOME/data/ROOT (symlink to $ROOT_DIRECTORY)
|
2023-11-01 06:42:52 +00:00
|
|
|
|
2025-04-10 15:23:32 +00:00
|
|
|
For help and support, please contact your system administrator.
|
|
|
|
|
EOF
|
|
|
|
|
log_cmd "chown $USERNAME:$USERNAME $USER_HOME/data/welcome.txt" "Setting welcome file ownership"
|
|
|
|
|
log_cmd "chmod 644 $USER_HOME/data/welcome.txt" "Setting welcome file permissions"
|
|
|
|
|
log_success "Welcome file created"
|
2023-11-01 05:22:36 +00:00
|
|
|
|
2025-04-10 16:07:08 +00:00
|
|
|
# Always export variables directly with no console output
|
|
|
|
|
export CREATED_USERNAME="$USERNAME"
|
|
|
|
|
export CREATED_PASSWORD="$PASSWORD"
|
|
|
|
|
|
|
|
|
|
# All logging should be to file only
|
2025-04-10 15:23:32 +00:00
|
|
|
log_success "Script completed successfully for user $USERNAME"
|
|
|
|
|
log "======== SFTP USER SETUP COMPLETE ========"
|
2023-11-02 17:48:26 +00:00
|
|
|
|
2025-04-10 16:07:08 +00:00
|
|
|
exit 0
|