How to Set Up an SFTP Server on Arch Linux (Step-by-Step with Chroot)

Set up an SFTP-only server on Arch Linux with OpenSSH, chroot to /srv/sftp, and internal-sftp. Install openssh, create sftpusers group, configure sshd_config, and restrict users to SFTP with no shell.

SFTP (SSH File Transfer Protocol) runs over SSH and encrypts credentials and data in transit, unlike plain FTP, which sends everything in clear text. This guide walks you through setting up an SFTP-only server on Arch Linux with chroot: users in the sftpusers group get only internal-sftp (no shell) and are restricted to /srv/sftp.

In this guide you’ll:

  • Install and enable OpenSSH (sshd) on Arch Linux with pacman
  • Create a shared chroot under /srv/sftp, add the sftpusers group, and create SFTP-only users with /sbin/nologin
  • Configure /etc/ssh/sshd_config with Match Group sftpusers, ChrootDirectory /srv/sftp, and ForceCommand internal-sftp
  • Test access with the sftp client and optionally add extra directories under /srv/sftp

Related SFTP guides:

Prerequisites

To follow along this guide ensure you have the following:

  • Arch Linux machine
  • Root access to the server or a user with root access
  • Internet access from the server

Ensuring that the server is up to date

Before proceeding, ensure your system is up to date. Use this command to refresh the system packages and update them.

1
sudo pacman -Syyu

2. Ensuring that the SSH service is installed

Verify that the ssh is installed:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ sudo pacman -Qi openssh

Name            : openssh
Version         : 8.6p1-1
Description     : Premier connectivity tool for remote login with the SSH protocol
Architecture    : x86_64
URL             : https://www.openssh.com/portable.html
Licenses        : custom:BSD
Groups          : None
Provides        : None
Depends On      : glibc  krb5  openssl  libedit  ldns  libxcrypt  libcrypt.so=2-64  zlib  pam
Optional Deps   : xorg-xauth: X11 forwarding
                  x11-ssh-askpass: input passphrase in X
                  libfido2: FIDO/U2F support
Required By     : None
Optional For    : None
Conflicts With  : None
Replaces        : None
Installed Size  : 5.79 MiB
Packager        : Giancarlo Razzolini <[email protected]>
Build Date      : Mon 19 Apr 2021 11:32:46 AM UTC
Install Date    : Thu 03 Jun 2021 03:23:32 AM UTC
Install Reason  : Explicitly installed
Install Script  : Yes
Validated By    : Signature

If ssh is not installed, install with this command:

1
sudo pacman -S openssh

Now that it is installed, start the service

1
sudo systemctl start sshd

Confirm its status

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
$ sudo systemctl status sshd

● sshd.service - OpenSSH Daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: disabled)
     Active: active (running) since Fri 2021-12-03 10:19:02 UTC; 17min ago
   Main PID: 467 (sshd)
      Tasks: 1 (limit: 4606)
     Memory: 5.0M
     CGroup: /system.slice/sshd.service
             └─467 sshd: /usr/bin/sshd -D [listener] 0 of 10-100 startups

Dec 04 14:53:30 ip-10-2-40-103 sshd[13109]: Unable to negotiate with 141.98.10.246 port 34078: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 14:53:42 ip-10-2-40-103 sshd[13111]: Unable to negotiate with 141.98.10.246 port 38674: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 14:53:53 ip-10-2-40-103 sshd[13115]: Unable to negotiate with 141.98.10.246 port 43268: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 14:54:05 ip-10-2-40-103 sshd[13117]: Unable to negotiate with 141.98.10.246 port 47864: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 14:54:17 ip-10-2-40-103 sshd[13119]: Unable to negotiate with 141.98.10.246 port 52460: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 14:54:41 ip-10-2-40-103 sshd[13123]: Unable to negotiate with 141.98.10.246 port 33418: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 14:54:53 ip-10-2-40-103 sshd[13127]: Unable to negotiate with 141.98.10.246 port 38014: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 14:55:05 ip-10-2-40-103 sshd[13129]: Unable to negotiate with 141.98.10.246 port 42614: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group-exc>
Dec 04 15:16:10 ip-10-2-40-103 sshd[13191]: Received disconnect from 61.177.173.21 port 60983:11:  [preauth]
Dec 04 15:16:10 ip-10-2-40-103 sshd[13191]: Disconnected from authenticating user root 61.177.173.21 port 60983 [preauth]

Creating users and groups and adding the necessary directories

Next we will ensure that the necessary users are present in the system. In my case, I would like to have the sftp users home as /srv/sftp

Let us create the home /srv/sftp with this command:

1
sudo mkdir /srv/sftp

Then let us create an umbrella group for SFTP only

1
sudo groupadd sftpusers

Then create an sftp only user called citizix:

1
sudo useradd -G sftpusers -d /srv/sftp/citizix -s /sbin/nologin citizix

The above options do the following:

  • -G sftpusers: Create user, append to sftpusers group
  • -d /srv/sftp/citizix: Set home dir as /srv/sftp/citizix
  • -s /sbin/nologin: We do not want the user to login, so no ssh login shell
  • Finally, username as citizix

Then add password to the created user using this command:

1
2
3
4
5
6
$ sudo passwd citizix

Changing password for user citizix.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

Configuring the ssh service

Now that we have installed the necessary software and created the users and groups, let us configure ssh.

Ensure password authentication is enabled for ssh. Edit the config file here /etc/ssh/sshd_config:

1
sudo vim /etc/ssh/sshd_config

Then ensure this line is not commented:

1
PasswordAuthentication yes

Next, we need to add rules for the users in the sftpusers group to be considered as sftp. Edit the config file:

1
sudo vim /etc/ssh/sshd_config

Add this content at the bottom of the file:

1
2
3
4
5
Match Group sftpusers
    X11Forwarding no
    AllowTcpForwarding no
    ChrootDirectory /srv/sftp
    ForceCommand internal-sftp

Then restart sshd to reload the config:

1
sudo systemctl restart sshd

Verify that sshd is running as expected:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ sudo systemctl status sshd

● sshd.service - OpenSSH Daemon
     Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: disabled)
     Active: active (running) since Sat 2021-12-04 15:48:19 UTC; 18s ago
   Main PID: 14269 (sshd)
      Tasks: 1 (limit: 4606)
     Memory: 892.0K
     CGroup: /system.slice/sshd.service
             └─14269 sshd: /usr/bin/sshd -D [listener] 0 of 10-100 startups

Dec 04 15:48:19 ip-10-2-40-103 systemd[1]: Started OpenSSH Daemon.
Dec 04 15:48:19 ip-10-2-40-103 sshd[14269]: Server listening on 0.0.0.0 port 22.
Dec 04 15:48:19 ip-10-2-40-103 sshd[14269]: Server listening on :: port 22.

Verifying that the set up is working as expected

After creating the user and adding the SFTP configuration, let’s test the setup with:

1
2
3
4
5
$ sftp [email protected]

[email protected]'s password:
Connected to 10.2.11.8.
sftp>

Now we have sftp server up and running with a user configured!

The users will be able to login to the server and access files and directories located in their home directory. If you want to give the user to other directories outside their own directory, just make sure the user has enough rights to access. These directories and files have to be within the sftp directory - /srv/sftp.

Example: to give the user access to a directory such as /srv/sftp/paymentfiles:

Create the directory

1
sudo mkdir /srv/sftp/paymentfiles

Then assign the user(citizix) access by making them own the directory:

1
sudo chown citizix:sftpusers /srv/sftp/paymentfiles

Users can then access that directory when they connect via SFTP.

Frequently Asked Questions (FAQ)

What is SFTP?

SFTP (SSH File Transfer Protocol) is a secure file transfer protocol that runs over SSH. Unlike FTP, it encrypts both authentication and data. OpenSSH provides the SFTP subsystem (internal-sftp), so no separate FTP server is needed on Arch Linux.

What port does SFTP use on Arch Linux?

SFTP uses the same port as SSH: port 22. The sshd service (OpenSSH daemon) handles both SSH logins and SFTP. Ensure sshd is enabled and listening: sudo systemctl enable --now sshd.

How do I restrict users to SFTP only (no shell) on Arch?

Create users with shell /sbin/nologin and add them to a group (e.g. sftpusers). In /etc/ssh/sshd_config, add a Match Group sftpusers block with ChrootDirectory /srv/sftp and ForceCommand internal-sftp. Restart sshd. Users in that group will only get an SFTP session, not a login shell.

Why use ChrootDirectory for SFTP?

ChrootDirectory restricts SFTP users to a specific directory (e.g. /srv/sftp) so they cannot browse the rest of the filesystem. On Arch we use a shared chroot (/srv/sftp); each user’s home can be a subdirectory (e.g. /srv/sftp/citizix). The chroot directory and its parents must be owned by root and not writable by the user.

How do I enable SSH/SFTP on Arch Linux at boot?

Run sudo systemctl enable sshd so the OpenSSH daemon starts on boot. Use sudo systemctl start sshd to start it immediately. The service name on Arch is sshd (not ssh).

Conclusion

You now have an SFTP-only server on Arch Linux with chroot to /srv/sftp: users in the sftpusers group can only use SFTP (no shell) and are limited to that directory. For client usage, see how to work with the SFTP client in Linux, or automate transfers with Python or Go.

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