Red Hat / CentOS / Fedora – Create Jailed SFTP User

If you are working on a project and need SFTP capabilities but don’t want users to see each other’s files create a SFTP Jailed server.

Assumptions for the code below is that you are running Red Hat, CentOS, or Fedora and already have the OS running.

NOTE: In this first script block it will restart your server.

sudo groupadd sftpusers

# Archive sshd config
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original
#sudo cp /etc/ssh/sshd_config.original /etc/ssh/sshd_config

# Remove spaces, tabs, and comments to make it easier for below
sudo sed -i "/^\s*#/d;s/\s*#[^\"']*$//" /etc/ssh/sshd_config && sudo sed -i '/^\s*$/d' /etc/ssh/sshd_config
sudo sed -i 's/\t/ /g' /etc/ssh/sshd_config

# Comment out Subsystem
sudo sed -i "s|Subsystem sftp /usr/libexec/openssh/sftp-server|#Subsystem sftp /usr/libexec/openssh/sftp-server|" /etc/ssh/sshd_config
cat /etc/ssh/sshd_config | grep "Subsystem"
#sudo sed -i "s|X11Forwarding yes|X11Forwarding no|" /etc/ssh/sshd_config
#cat /etc/ssh/sshd_config | grep "X11Forwarding"

# Add needed config
echo -e "Subsystem sftp internal-sftp\nMatch Group sftpusers\nChrootDirectory /sftp/%u\nForceCommand internal-sftp" | sudo tee -a /etc/ssh/sshd_config
cat /etc/ssh/sshd_config | grep "Subsystem"

# Create jailed location
sudo mkdir /sftp

# Restart SSHD
sudo systemctl restart sshd

# OPTIONAL (BUT HELPFUL) Set SELinux as permissive. This allows you to still know what is going on but let it happen.
sudo cp /etc/selinux/config /etc/selinux/config.original
sudo sed -i '/^#/d' /etc/selinux/config
sudo sed -i '/^$/d' /etc/selinux/config
SELinuxStatus=$(cat /etc/selinux/config | grep SELINUX=|cut -d'=' -f2)
echo "Current Status: $SELinuxStatus"
sudo sed -i "s|SELINUX=$SELinuxStatus|SELINUX=permissive|" /etc/selinux/config
SELinuxStatus=$(cat /etc/selinux/config | grep SELINUX=|cut -d'=' -f2)
echo "New Status: $SELinuxStatus"
sudo shutdown -r now

If you create a file (such as this script block below could be called with a variable or simply as a script

With variable:

sh sftpuser1

Without variable:


Only difference is that the script will ask you type a username if you don’t provide one.

randompw=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)

echo -e "\033[32mSFTP User Setup - Start\033[0m"
if [ -z ${1+x} ]; then
  echo -e "\033[01m\e[4mType the desired username, followed by [ENTER]:\e[0m\033[0m"
  read sftpUser
  declare sftpUser=$1
echo -e "\033[32mSFTP User Setup - Stop\033[0m"

sudo useradd -g sftpusers -d /incoming -s /sbin/nologin $sftpUser

echo $sftpUser:$randompw | chpasswd

grep $sftpUser /etc/passwd

echo "UserID:" $sftpUser "has been created with the following password:" $randompw

sudo mkdir -p /sftp/$sftpUser/incoming

sudo chown $sftpUser:sftpusers /sftp/$sftpUser/incoming

ls -ld /sftp/$sftpUser/incoming
ls -ld /sftp/$sftpUser
ls -ld /sftp/


All information on this site is shared with the intention to help. Before any source code or program is ran on a production (non-development) system it is suggested you test it and fully understand what it is doing not just what it appears it is doing. I accept no responsibility for any damage you may do with this code.