# Create new SFTP user in Ubuntu Server for WordOps

**Date:** 2024-01-05  
**Author:** Kees C. Bakker  
**Categories:** bash  
**Original:** https://keestalkstech.com/create-new-sftp-user-in-ubuntu-server/

![Create new SFTP user in Ubuntu Server for WordOps](https://keestalkstech.com/wp-content/uploads/2024/01/dennis-kummer-52gEprMkp7M-unsplash.jpg)

---

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](https://filezilla-project.org/). Let's create a script that does the setup of the new SFTP user.

## Create user

As we're using [WordOps](https://wordops.net/), 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.

```sh
#!/bin/bash
set -Eeuo pipefail
IFS=$'\n\t'

create_sftp_user() {
    local group="www-data"  # Group for shared web access
    local username=$1
    local ssh_config="/etc/ssh/sshd_config"

    # 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"

    # Prompt to set the password for the user
    echo "Setting password for $username."
    sudo passwd "$username"

    # Only extend AllowUsers if it already exists (and only if not already present)
    if sudo grep -qE '^\s*AllowUsers\b' "$ssh_config"; then
        sudo sed -i -E "/^\s*AllowUsers\b/ { /(^|[[:space:]])${username}([[:space:]]|$)/! s/$/ ${username}/ }" "$ssh_config"
    fi

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

    # Configure SSH for SFTP access to /var/www
    echo "Configuring SSH for user $username."
    sudo tee -a "$ssh_config" > /dev/null <<EOF

Match User $username
    ChrootDirectory /var/www
    # Start directory inside the chroot. Must already exist and be writable for uploads.
    ForceCommand internal-sftp -d /
    PasswordAuthentication yes
    AllowAgentForwarding no
    AllowTcpForwarding no
    AllowStreamLocalForwarding no
    PermitTunnel no
    PermitTTY no
    X11Forwarding no
EOF

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

# Main script execution
read -p "Enter the username for SFTP: " username
create_sftp_user "$username"
```

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](https://community.wordops.net/d/187-wordpress-permissions-command). Save this script to `rights.sh` and you can call it like `rights.sh example.com`.

```sh
#!/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

- 2025-01-04: Let's restart ssh instead of sshd.
- 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.
