How to Install and Set Up an SFTP Server in Ubuntu 20.04

Install and configure an SFTP server on Ubuntu 20.04 using OpenSSH: create chrooted users, configure sshd, and use sftp commands for upload and download.

SFTP (SSH File Transfer Protocol, or Secure Shell File Transfer Protocol) provides secure file access, transfer, and management over SSH. It uses a single encrypted channel on TCP port 22, so you don’t need a separate FTP server or extra firewall ports. This guide walks you through installing and configuring an SFTP server on Ubuntu 20.04 using OpenSSH, then shows common SFTP client commands.

SFTP vs FTP

The File Transfer Protocol is a standard communication protocol used for the transfer of computer files from a server to a client on a computer network (including the Internet). FTP is built on a client–server model architecture using separate control and data connections between the client and the server. FTP has always been popular for storing or moving large files between systems. Files can be added to a central server, then users who want to access them can access them from there.

SFTP is aimed at providing enhanced security with tunneling using Secure Shell 2 (SSH2), a secure tunneling protocol. It emulates an FTP connection and provides a firewall friendly and encrypted channel for file transfers using TCP port 22. SSH offers enhanced security by having the entire file transfer session, including all session control commands, entirely encrypted at all times while only requiring a single port be opened on your firewall versus the two ports that need to be opened for FTP and SSL connections.

As an added feature, Secure FTP also compresses all data during the transmission, which can result in faster file transfers.

Prerequisites

  • Ubuntu 20.04 server or desktop with sudo access.
  • SSH port 22 reachable (and allowed in firewall if you connect remotely).

Install and configure SFTP on Ubuntu 20.04

We will: (1) install the OpenSSH server, (2) create an SFTP user and group, (3) configure the SSH daemon for chrooted SFTP, and (4) connect and run basic SFTP commands.

1. Install OpenSSH server

SFTP is provided by the OpenSSH server. Ensure your system is up to date, then install the ssh meta-package (which pulls in OpenSSH server) if needed:

1
2
sudo apt update
sudo apt upgrade -y
1
sudo apt install ssh

Example output:

1
2
3
4
5
6
7
$ sudo apt install ssh
Reading package lists... Done
Building dependency tree
...
Get:1 http://ports.ubuntu.com/ubuntu-ports focal-security/main arm64 ssh all 1:8.2p1-4ubuntu0.2 [5,084 B]
...
Setting up ssh (1:8.2p1-4ubuntu0.2) ...

2. Create SFTP user and group

Create a dedicated group and user for SFTP access (you can change the names).

Create a group:

1
sudo addgroup sftpgroup1

Example output:

1
2
3
# sudo addgroup sftpgroup1
Adding group 'sftpgroup1' (GID 1002) ...
Done.

Create a user in that group with a home directory:

1
sudo useradd -m sftpuser1 -g sftpgroup1

Set a password for the SFTP user:

1
sudo passwd sftpuser1

Restrict the home directory to the user (required for chroot):

1
sudo chmod 700 /home/sftpuser1/

3. Configure the SSH daemon for SFTP

Edit the SSH server config:

1
sudo vim /etc/ssh/sshd_config

Add the following block at the end of the file (use a single Match block; order matters):

1
2
3
4
5
Match group sftpgroup1
    ChrootDirectory /home
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp

This config:

  • Match group sftpgroup1 – applies only to users in sftpgroup1.
  • ChrootDirectory /home – restricts them to /home (they see /home as / and can only reach their own /home/sftpuser1).
  • ForceCommand internal-sftp – allows SFTP only; no shell or port forwarding.

Save and exit, then restart SSH:

1
sudo systemctl restart ssh

Note: ChrootDirectory (here /home) must be owned by root and not writable by the chrooted user. Each user’s directory under /home (e.g. /home/sftpuser1) can be owned by that user so they can upload and create files there.

4. Connect from the terminal

From any machine with an SSH client (including the server itself), connect with:

Or from another host, use the server’s IP or hostname instead of 127.0.0.1. When prompted, enter the SFTP user’s password.

Example:

1
2
3
4
5
6
7
8
$ sftp [email protected]
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:99KvuL95zO2CQbC8X0Re/Q+cYrJgqQgzpf1leemnjmY.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
[email protected]'s password:
Connected to 127.0.0.1.
sftp>

You are chrooted under /home; your effective root is /home, and your home directory appears as /sftpuser1. Run cd sftpuser1 to enter your upload directory.

Basic SFTP commands

Check version

1
2
3
sftp> version
SFTP protocol version 3
sftp>

Show remote working directory

To see the current working directory on the remote server, use pwd:

1
2
3
sftp> pwd
Remote working directory: /sftpuser1
sftp>

Show local working directory

To see the local machine’s present working directory, use lpwd:

1
2
3
sftp> lpwd
Local working directory: /home/ubuntu
sftp>

The SFTP user is restricted to their home. Run cd sftpuser1 to enter it, then create a directory with mkdir:

1
2
3
4
5
6
7
sftp> ls
sftpuser1  ubuntu
sftp> cd sftpuser1
sftp> ls
sftp> mkdir datadir
sftp> ls
datadir

Upload files

From the local shell (one-liner): use a here-string to run put after connecting:

1
sftp {user}@{host}:{remote-path} <<< $'put {local-path}'

Example:

1
2
3
4
5
6
7
$ sftp [email protected]:/sftpuser1/ <<< $'put ./citizix.txt'
[email protected]'s password:
Connected to 127.0.0.1.
Changing to: /sftpuser1/
sftp> put ./citizix.txt
Uploading ./citizix.txt to /sftpuser1/citizix.txt
./citizix.txt

From inside an SFTP session: use ls (remote), lls (local), and put to upload:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
sftp> pwd
Remote working directory: /sftpuser1/datadir
sftp> ls
sftp> lls
citizix.txt  snap  tmp
sftp> put citizix.txt
Uploading citizix.txt to /sftpuser1/datadir/citizix.txt
citizix.txt                                                            100%   32    25.8KB/s   00:00
sftp> ls
citizix.txt
sftp>

Use mput with a glob to upload multiple files (e.g. data[23] uploads data2 and data3):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
sftp> pwd
Remote working directory: /sftpuser1/data
sftp> ls
sftp> lls
data1  data2  data3
sftp> mput data[23]
Uploading data2 to /sftpuser1/data/data2
data2                                                                  100%    0     0.0KB/s   00:00
Uploading data3 to /sftpuser1/data/data3
data3                                                                  100%    0     0.0KB/s   00:00
sftp> ls
data2  data3

Download files

From the local shell: download a single file in one command:

1
sftp {user}@{remote-host}:{remote-file-name} {local-file-name}

Example:

1
2
3
4
5
# sftp [email protected]:/sftpuser1/citizix.txt .
[email protected]'s password:
Connected to 127.0.0.1.
Fetching /sftpuser1/citizix.txt to ./citizix.txt
/sftpuser1/citizix.txt                                                 100%   32    26.7KB/s   00:00

From inside SFTP: use get for one file and mget with a glob for multiple:

1
2
3
4
5
6
7
8
sftp> ls
data2  data3
sftp> lls
sftp> get data2
Fetching /sftpuser1/data/data2 to data2
sftp> lls
data2
sftp>
1
2
3
4
5
6
sftp> mget data*
Fetching /sftpuser1/data/data2 to data2
Fetching /sftpuser1/data/data3 to data3
sftp> lls
data2  data3
sftp>

Create and delete directories

Use mkdir and rmdir:

1
2
3
4
5
6
sftp> ls
sftp> mkdir data
sftp> ls
data
sftp> rmdir data
sftp>

Remove files

Use rm (supports globs):

1
2
3
4
sftp> rm data*
Removing /sftpuser1/data/data2
Removing /sftpuser1/data/data3
sftp>

Rename files

Use rename oldpath newpath:

1
2
3
4
5
6
sftp> ls
data3
sftp> rename data3 data_original
sftp> ls
data_original
sftp>

Check filesystem usage

Use df (and df -h for human-readable sizes). The stats are for the remote SFTP server’s filesystem, not the local machine:

1
2
3
4
5
6
sftp> df
        Size         Used        Avail       (root)    %Capacity
    29540600      5917856     22103188     23622744          20%
sftp> df -h
    Size     Used    Avail   (root)    %Capacity
  28.2GB    5.6GB   21.1GB   22.5GB          20%

Get help

Run ? or help inside an SFTP session. For full documentation, see man sftp on the client.

1
2
3
4
5
6
7
sftp> ?
Available commands:
bye                                Quit sftp
cd path                            Change remote directory to 'path'
chgrp [-h] grp path                Change group of file 'path' to 'grp'
chmod [-h] mode path               Change permissions of file 'path' to 'mode'
...

Exit the SFTP session

Use bye, exit, or quit:

1
2
sftp> exit
$

Verifying the setup

  • SSH/SFTP: systemctl status ssh should show the SSH service running; port 22 should be listening.
  • Connect: sftp [email protected] (or your server IP) should prompt for password and then show the sftp> prompt.
  • Chroot: After login, pwd should show /sftpuser1 (or similar); you should not be able to access paths outside the chroot.

Summary

You installed the OpenSSH server on Ubuntu 20.04, created an SFTP-only user and group, and configured sshd with a Match block so that group is chrooted under /home and limited to SFTP. You can connect with sftp user@host, then use put/get, mput/mget, mkdir/rmdir, rm, and rename for file operations. For more SFTP client commands, see How to work with SFTP client in Linux.

comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy