Introduction

Apart from the very well-known FTP (File Transfer Protocol), we might have heard about SFTP (Secure File Transfer Protocol), another secure method that is similar to FTP but uses the Secure Shell (SSH) protocol to securely transfer files between client and server instead.

In this blog, I want to walk you through the process of setting up an SFTP server with a password or SSH key pair for authentication.

Prerequisite

  • A Ubuntu 24.04 server or any other Ubuntu version. If you use other Linux distros, the command might be different
  • You can log in server as “root”, or if you use a non-root user, this user should have sudo permission. I’m using a non-root user in this demo.
HostnameIP addressRole
sftp-server.srv.local192.168.68.113SFTP server

Set up the SFTP server using password for authentication

Step 1: Install openssh-server

sudo apt update
sudo apt install openssh-server -y

Step 2: Create an SFTP directory where it stores SFTP users’ data

sudo mkdir /sftp_data
sudo chmod 701 /sftp_data

Step 3: Create a user and group for SFTP users

Create a group for SFTP users – all SFTP users will be added to this group

sudo groupadd sftp_users

Create a test-user-1 user (change it to your own) and add it to the sftp_users group:

sudo useradd -g sftp_users -d /sftp_data/test-user-1/upload -s /usr/sbin/nologin test-user-1

Where:

  • -g: name or ID of the primary group of the new account
  • -d: is the home directory of the new account. In here, test-user-1 ‘s home directory is /sftp_data/test-user-1/upload
  • -s: login shell of the new account. Set to /usr/sbin/nologin so that it denies shell login access to a user account.

Update password for test-user-1 user:

sudo passwd test-user-1

Step 4: Create the new user SFTP directory

We need to create a home directory for the created test-user-1 user. Simply run:

sudo mkdir -p /sftp_data/test-user-1/upload
sudo chown -R root:sftp_users /sftp_data/test-user-1
sudo chown -R test-user-1:sftp_users /sftp_data/test-user-1/upload

Output:

Note: The PATH /sftp_data/<username> MUST be owned by root:sftp_users.

Step 5: Configure SFTP in SSH configuration

Run sudo nano /etc/ssh/sshd_config and add the following content to the end of the file:

# SFTP Configuration
Subsystem sftp internal-sftp          # Use in-process SFTP server
Match Group sftp_users
  ChrootDirectory /sftp_data/%u       # Prevent user access to anything beyond their home folder
  KbdInteractiveAuthentication yes    # Enable this to allow enter password from CLI
  PasswordAuthentication yes          # Allow user access SFTP with plain-text password
  X11Forwarding no                    # Disable X11 forwarding
  AllowTcpForwarding no               # Disable tunneling
  AllowAgentForwarding no             # Disable port forwarding
  PermitTunnel no                     # Disable network tunneling
  ForceCommand internal-sftp -d /upload # Force the connection to use the built-in SFTP server and go to /upload 

Remember to comment this line because we use internal-sftp option instead:

# Subsystem sftp /usr/lib/openssh/sftp-server

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

You can check it here to know more about why we use internal-sftp instead of sftp-server.

NOTE: On Ubuntu 24.04, if you don’t add these two options under Match Group:

  KbdInteractiveAuthentication yes 
  PasswordAuthentication yes        

You can’t use SFTP via command line to enter the password with sftp test-user-1@192.168.68.113. That’s because it always prefers to use SSH Keys as the default authentication.

Restart SSH service to make the configuration take effect

sudo systemctl restart ssh.service

Remember to open port 22/tcp if you enable firewall. Or if you install on AWS EC2, should open port 22/tcp in Security Group for specific IP allowed to access.

NOTED: the process of SFTP user creation above requires so much manual steps. I’ve written Automate SFTP User Creation on Ubuntu 24.04 to automate this process. Please feel free to check it out if you’re interested. Thanks.

Step 6: Testing SFTP access

Testing by WinSCP on Windows

Using WinSCP to log in test-user-1 with IP 192.168.68.113 (change to your SFTP username/IP address):

Once logged in successfully, I uploaded a file to test. Here is the result

Go to the SFTP server to verify. You should have the same result if you do it correctly

Testing by using CLI

From another PC that can connect to the SFTP server, run

sftp test-user-1@192.168.68.113

It’s going to ask password, enter your password there

(Optional) Set up the SFTP server using SSH keys for authentication

The above configuration is for password authentication. The default authentication for SFTP on the latest Ubuntu version prefers to use SSH Key pairs as a best practice. You can skip this step if you don’t want to use it. If you’re interested in using SSH Keys as authentication for the SFTP server. Can follow my guide here but you should complete the section above first.

Generate SSH-Key pair

On your client machine, we need to generate an SSH key pair (you can skip this step if you have your own SSH key pair); simply run (I’m running on the SFTP server to avoid mixing it with the key on my machine):

ssh-keygen -t rsa -b 4096

Output:

We need to copy the content of the /home/<your-username>/.ssh/id_rsa.pub file generated on your machine. In my case is /home/binh/.ssh/id_rsa.pub. Run:

# The ~/ is the short path of /home/<your-username>
cat ~/.ssh/id_rsa.pub

Output looks similar to:

Copy the content of the /home/<your-username>/.ssh/id_rsa.pub file, and save it to a temporary place where we will use it later.

Set up authorized_keys for test-user-1 user on the SFTP server

On the SFTP server, run the following to set up .ssh folder for test-user-1 user:

sudo mkdir /sftp_data/test-user-1/upload/.ssh
sudo touch /sftp_data/test-user-1/upload/.ssh/authorized_keys

Run sudo nano /sftp_data/test-user-1/upload/.ssh/authorized_keys, and paste the content of /home/<your-username>/.ssh/id_rsa.pub into this file

Output:

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

Grant proper permissions to /sftp_data/test-user-1/upload/.ssh and /sftp_data/test-user-1/upload/.ssh/authorized_keys. Run

sudo chown -R test-user-1:sftp_users /sftp_data/test-user-1/upload/.ssh
sudo chmod 700 /sftp_data/test-user-1/upload/.ssh
sudo chmod 600 /sftp_data/test-user-1/upload/.ssh/authorized_keys

Change the SSH configuration to use the SSH-Key pair instead of entering a password

Run sudo nano /etc/ssh/sshd_config and modify as follows:

# SFTP Configuration
Subsystem sftp internal-sftp          # Use in-process SFTP server
Match Group sftp_users
  ...
  
  # Comment these two lines to disable login by plain-text password
  # KbdInteractiveAuthentication yes
  # PasswordAuthentication yes

  ...

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

It should be like this:

Restart ssh service makes the configuration take effect

sudo systemctl restart ssh.service

(Optional) Configure SSH on client machine

If you generate SSH-Key pair on your client machine, no need to do this step, but if you do it on the SFTP server, need to create /home/<your-username>/.ssh/id_rsa file on your client machine, and copy the content of /home/<your-username>/.ssh/id_rsa on the SFTP server.

On the SFTP server, run cat /home/<your-username>/.ssh/id_rsa and copy the content of it to a temporary place

Output looks like:

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
...
...
nKjeYaMdKFMAAAAaYmluaEBzZnRwLXNlcnZlci5zcnYubG9jYWwB
-----END OPENSSH PRIVATE KEY-----

On your client machine: run sudo nano /home/<your-username>/.ssh/id_rsa and paste the content of id_rsa file into this file.

Press Ctrl + O and press Enter to save the content. Then press Ctrl + X to exit.

And, grant 600 permission to /home/<your-username>/.ssh/id_rsa, run:

sudo chmod 600 /home/<your-username>/.ssh/id_rsa

Then test it by running sftp test-user-1@192.168.68.113 (Again, change this to your username / your SFTP server’s IP)

You can see that we don’t have to enter the password anymore.

If you have multiple SSH-Key pairs on your client machine, and you want to use a dedicated private key for SFTP only. You will have to configure /home/<your-username>/.ssh/config file to tell which private key file SFTP should use to authenticate the connection.

Firstly, change your /home/<your-username>/.ssh/id_rsa to a new file, e.g. to /home/<your-username>/.ssh/id_rsa_sftp_key, simply run

sudo mv /home/<your-username>/.ssh/id_rsa /home/<your-username>/.ssh/id_rsa_sftp_key

And add a new /home/<your-username>/.ssh/config file with content below, run

cat <<EOF > /home/<your-username>/.ssh/config
# Change IP to your SFTP server's IP
Host 192.168.68.113
  Hostname 192.168.68.113
  PreferredAuthentications publickey
  IdentityFile ~/.ssh/id_rsa_sftp_key
EOF

Now you can test sftp -vvv test-user-1@192.168.68.113 to view the result in detail, you will see it load your private key at ~/.ssh/id_rsa_sftp_key

If you like my blog post and want to find a way to thank me, feel free to Buy me a coffee to support me in providing more quality content, or simply share it with others who may have the same issue. Thanks for reading my blog.


Discover more from Turn DevOps Easier

Subscribe to get the latest posts sent to your email.

By Binh

Leave a Reply

Your email address will not be published. Required fields are marked *

Content on this page