How to setup an SFTP server on CentOS

This tutorial explains how to setup and use an SFTP server on CentOS. Before I start, let me explain what actually SFTP represents and what it is used for. Currently, most people know that we can use normal FTP for transferring, downloading or uploading data from a server to client or client to server. But this protocol is getting hacked easily (if TLS is not used) by anonymous intruders as it the ports are widely open to anyone. Therefore, SFTP has been introduced to as another alternative to meet the main purpose to strengthen the security level.

SFTP stands for SSH File Transfer Protocol or Secure File Transfer Protocol. It uses a separate protocol packaged with SSH to provide a secure connection.

1. Preliminary Note

For this tutorial, I am using CentOS 6.4 in the 32bit version. The same steps will work on CentOS 7 as well. The tutorial result will show how a client can be provided with access to the SFTP server but unable to login to the server itself by SSH.

2. Installation Phase

Unlike normal FTP, there's no need to install additional packages in order to use SFTP. We just require the prebuild SSHd package that got already installed during installation on the server. Therefore, just check to confirm if you already have the required SSH package. Below are the steps:


rpm -qa|grep ssh

The output should be similar to this:

[[email protected] ~]# rpm -qa|grep ssh

That's all, now we'll go on how to make the SFTP configuration.

3. Configuration Phase

Once all prerequisites of installation are done, we'll step over to configuration phase. For best practice, we need to create a group and user so that we can manage all user that shall get SFTP access. But first, let's create an additional folder called data. Below are the steps:

mkdir -p /data/shahrilk

Basically what I'm trying to do with the above step is to get a separate folder as main directory for the SFTP access. All user directories for the SFTP users will be subdirectories of this data folder.

Let's create a group for the SFTP user, below are the steps:

groupadd sftpusers

Then create a user and assign it to the SFTPUSERS group. Below are the steps:

useradd -g sftpusers -d /upload -s /sbin/nologin shahrilk
passwd shahrilk

Changing password for user shahrilk.
New password:
BAD PASSWORD: it is based on a dictionary word
Retype new password:
passwd: all authentication tokens updated successfully.

Below is the explanation of the above commands:

  1. I create a user and include the user into sftpusers group using -g command.
  2. I assign the main directory for the user to be in the /upload directory by setting the -d /upload command. This means that later the /upload folder will be under /data/shahrilk/upload.
  3. I limit the access to the /sbin/nologin shell to ensure the user is only able to use the SFTP protocol, not SSH.
  4. I name the user "shahrilk".
  5. Set password for user "shahrilk".

Now let's create the /upload folder under /data/shahrilk, then assign appropriate ownership to the folder.

chown -R shahrilk:sftpusers /data/shahrilk
mkdir -p /data/shahrilk/upload
chown -R shahrilk:sftpusers /data/shahrilk/upload

Once done, verify that the new folder under the directory /data exists and that we made the configuration correct.

[[email protected] ~]# ls -ld /data/
drwx-----x 14 root root 4096 Aug 19 11:13 /data/

[[email protected] ~]# ls -ld /data/shahrilk
drwxr-xr-x 4 shahrilk sftpusers 4096 Jan 19 2016 /data/shahrilk

[[email protected] ~]# ls -ld /data/shahrilk/upload
drwxr-xr-x 2 shahrilk sftpusers 4096 Aug 30 08:42 /data/shahrilk/upload

[[email protected] ~]# cat /etc/passwd|grep shahrilk

Now configure the SSH protocol to create an SFTP process. This can be done by editing the configuration file under /etc/ssh/sshd_config . Below are the steps:

vi /etc/ssh/sshd_config

Subsystem sftp internal-sftp

Match Group sftpusers
ChrootDirectory /data/%u
ForceCommand internal-sftp

Once done restart the SSH services, below are the steps :-

service sshd status

openssh-daemon (pid 1468) is running...

service sshd restart

Stopping sshd: [ OK ]
Starting sshd: [ OK ]

4. Testing Phase

Now everything has been configured, so let's make a test to ensure the setup meets our purpose.
I'll access SFTP by using another server called TEST01. First, I'll verify the Port of the SFTP server . To do that I'll use the nmap function. If your client server didn't have it you may download and install it with yum as shown below:

yum list nmap

Loaded plugins: refresh-packagekit, security
Repository 'OEL64' is missing name in configuration, using id
Available Packages
nmap.i686 2:5.51-2.0.1.el6 OEL64

yum install nmap -y

Loaded plugins: refresh-packagekit, security
Repository 'OEL64' is missing name in configuration, using id
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package nmap.i686 2:5.51-2.0.1.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

Package Arch Version Repository Size
nmap i686 2:5.51-2.0.1.el6 OEL64 2.7 M

Transaction Summary
Install 1 Package(s)

Total download size: 2.7 M
Installed size: 9.7 M
Downloading Packages:
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Warning: RPMDB altered outside of yum.
Installing : 2:nmap-5.51-2.0.1.el6.i686 1/1
Verifying : 2:nmap-5.51-2.0.1.el6.i686 1/1

nmap.i686 2:5.51-2.0.1.el6

[[email protected] /]# nmap -n SFTP01

Starting Nmap 5.51 ( ) at 2016-08-30 02:27 MYT
Nmap scan report for SFTP01 (
Host is up (0.000085s latency).
Not shown: 998 closed ports
22/tcp open ssh
111/tcp open rpcbind

Nmap done: 1 IP address (1 host up) scanned in 0.23 seconds

You'll notice that currently on our SFTP server, the only open port is SSH 22. Now, let's try to access the SFTP from TEST01 client. Below are the steps:

[[email protected] /]# which sftp
[[email protected] /]# sftp [email protected]
Connecting to SFTP01...
[email protected]'s password:
sftp> pwd
Remote working directory: /upload

Great! Now our SFTP server is acessible from outside. Notice that the default directory is /upload . This means that SFTP will only show the default path as /upload even though our previous configuration made in the SFTP server directory is /data/shahrilk/upload.
Now let's try to get a file from the SFTP server directory into our testing client. First, let's create a test file under /data/shahrilk/upload . Below are the steps:

cd /data/shahrilk/upload
touch testing_file.txt

Then go back to our testing site TEST01 and see if we able to get and download the created file.

[[email protected] /]# sftp [email protected]
Connecting to SFTP01...
[email protected]'s password:
sftp> pwd
Remote working directory: /upload
sftp> ls
sftp> get testing_file.txt
Fetching /upload/testing_file.txt to testing_file.txt
sftp> quit

Excellent! Our SFTP test has been successful, let's try to access SSH using the user shahrilk . As previously we've set configuration as /sbin/nologin, therefore the user won't be able to use SSH services:

[[email protected] ~]# ssh [email protected]
[email protected]'s password:
^CConnection to sftp01 closed.

Nice! Now we have a secured SFTP server up and running.

Share this page:

Suggested articles

7 Comment(s)

Add comment


From: Chandrakumar Muthaiah at: 2016-08-31 20:46:53

Looks great but you need to change this line from

chown -R shahrilk:sftpusers /data/shahrilk


chown -R root:root /data/shahrilk

as it is needed for the chroot to work or sshd will produce permission denied.


From: shahril bin kamaruzzaman at: 2016-09-06 04:39:26

Nice heads up! 

From: greenears at: 2016-10-05 13:19:58

Hey thanks for your tutorial , but I have a problem. When I try to test it using the sftp [email protected] it gives me this error ' Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). Couldnt read packet: Connection reset by peer '

Maybe something with the ssh_config file ?


From: JJ at: 2016-12-27 06:00:46

WoW... Thanks for explaination. i will keep to visit this website to learn...

From: ws at: 2017-01-08 07:22:02

Nice write up!!!  Is it possible to add additional configurations such as block IP addresses after X numbers of incorrect login?

Thanks in advance.

From: Paul at: 2017-01-26 15:26:00

Thanks for your article. I was able to set it up.


For CentOS7 (my environment) -- I will agree with Chandrakumar's comment that the ownership of /data/shahrilk is not correct in  your article. 

The path /data/shahrilk must be root owned and writable only by root.

In your article, I would simply remove/skip the line:

chown -R shahrilk:sftpusers /data/shahrilk


Also, it will be useful to include a tip to look at /var/log/secure if readers are having trouble getting going. This will show connection attempts and any errors with authentication or setup.

Further, on CentOS 7, the line in /etc/ssh/sshd_config already exists, with no Match rules.... and show up slighly differently as:

Subsystem sftp internal-sftp    ? on CentOS 7, this appear as: /usr/libexec/openssh/sftp-server

And so you only need to add the rules at the end of the file, namely (only these lines)

Match Group sftpusersChrootDirectory /data/%uForceCommand internal-sftp

From: Gatsu at: 2017-09-01 17:35:04

Merci beaucoup mon ami. Tu es trés bon