Create new SFTP user in Ubuntu Server for WordOps

When you host a WordPress website, you might need to have FTP access. If you do FTP, why not SFTP (which uses SSH to do a secure transfer)? It is fully supported by FileZilla. Let's create a script that does the setup of the new SFTP user.

Create user

As we're using WordOps, we'll grand the new user rights on our /var/www directory. We do this by adding the new user to the www-data group and resetting the permissions recursively.

#!/bin/bash

create_sftp_user() {
    local username=$1
    local group="www-data" # Define the group name

    # Check if the user already exists
    if id "$username" &>/dev/null; then
        echo "Error: User '$username' already exists."
        return 1
    fi

    # Create the user with adduser
    echo "Creating user $username."
    sudo adduser --disabled-password --gecos "" "$username" || return 1
    
    # Prompt to set the password for the user
    echo "Setting password for $username."
    sudo passwd "$username" || return 1

    # Add the user to the specified group
    echo "Adding $username to the $group group."
    sudo usermod -a -G "$group" "$username"

    # Configure SSH for SFTP access to /var/www
    local ssh_config="/etc/ssh/sshd_config"
    echo "Configuring SSH for user $username."
    sudo sh -c "echo '
Match User $username
    ChrootDirectory /var/www
    ForceCommand internal-sftp
    AllowAgentForwarding no
    AllowTcpForwarding no
    PasswordAuthentication no
    PermitTunnel no
    X11Forwarding no
' >> $ssh_config"

    # Set the correct group permissions for /var/www
    echo "Setting correct group permissions for /var/www..."
    sudo chown -R :www-data /var/www
    sudo find /var/www -type d -exec chmod 775 {} \;
    sudo find /var/www -type f -exec chmod 664 {} \;
    sudo find /var/www -type d -exec chmod g+s {} \;

    # Reload SSH service to apply changes
    echo "Reloading SSH service."
    sudo systemctl reload sshd
}

# Main script execution
read -p "Enter the username for SFTP: " username
create_sftp_user "$username" || echo "Failed to create SFTP user."

Enjoy your SFTP user!

Restore

You might need to restore permissions on WordPress if you've messed them up. In my case my installation was asking some FTP permissions. To restore the WordOps permissions I've borrowed a script. Save this script to rights.sh and you can call it like rights.sh example.com.

#!/bin/bash

# Define the site name and the FTP user
site_name="$1"
ftp_user="ftpusr"

# Path to the WordPress directory
wp_path="/var/www/$site_name/htdocs"

# Check if the WordPress directory exists
if [ ! -d "$wp_path" ]; then
    echo "Error: Directory $wp_path does not exist. Make sure you've called the script with the right site."
    exit 1
fi

# Add ftpusr to the www-data group
echo "Adding $ftp_user to the www-data group..."
sudo usermod -a -G www-data $ftp_user

# Change to the WordPress directory
cd "$wp_path"

# Update ownership to www-data
echo "Setting ownership to www-data:www-data for $wp_path..."
sudo chown -R www-data:www-data .

# Update directory permissions to 775
echo "Updating directory permissions to 775..."
sudo find . -type d -exec chmod 775 {} \;

# Update file permissions to 664
echo "Updating file permissions to 664..."
sudo find . -type f -exec chmod 664 {} \;

# Set group ID on directories for inheriting group ownership
echo "Setting group ID on directories..."
sudo find . -type d -exec chmod g+s {} \;

echo "Permissions and ownership update complete."

😅 might be handy.

Changelog

  • 2024-01-12: Improved the restore script further, it now takes a parameter. I also set PermitTunnel no and AllowAgentForwarding no.
  • 2024-01-06: added a restore script. The main script does not take ownership, but uses the www-data group. This will ensure both your WordPress and SFTP user have permission to change the filesystem.
expand_less