#!/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" # -------------------------------------------------------------------------- # Step 5: Build read-only shell template for jailed SSH users # -------------------------------------------------------------------------- local shell_tmpl="/home/sftp-shell" if [ ! -x "$shell_tmpl/bin/bash" ]; then log "Creating minimal shell environment at $shell_tmpl" log_cmd "mkdir -p $shell_tmpl/bin $shell_tmpl/lib64" "Creating template directories" log_cmd "cp /bin/bash $shell_tmpl/bin/" "Copying bash binary" # Copy required shared libraries for bash for lib in $(ldd /bin/bash | awk '{print $3}' | grep -E '^/'); do log_cmd "cp --dereference $lib $shell_tmpl/lib64/" "Copying $(basename $lib)" done log_cmd "chmod -R 755 $shell_tmpl" "Setting permissions on shell template" log_success "Shell template created for jailed SSH users" else log_debug "Shell template already exists, skipping rebuild." fi log_success "System preparation complete." return 0 }