Updated: 10 October 2026 · Applies to: OpenSSH 10.0 on Debian 13 and 10.2 on Ubuntu 26.04 (tested, with sudo 1.9.16 and sudo-rs 0.2.13), OpenSSH 9.9 on AlmaLinux 10 (config checked); same steps on Ubuntu 24.04, Rocky Linux and RHEL 9 and 10
Every Linux user who can log in over SSH can already use SFTP; there is nothing extra to install. To make an SFTP-only user (no shell, locked in one folder), put the user in a group and give that group ChrootDirectory and ForceCommand internal-sftp in the SSH server configuration. SFTP has no sudo command of its own: to work as root (or as www-data) over SFTP, start the server side through sudo with sftp -s "sudo /usr/lib/openssh/sftp-server" user@server, which needs a password-free sudo rule for that one program. Both are shown below, with the output from our tests.
Create an SFTP-only user with a chroot
- Create a group for SFTP-only users:
groupadd sftponly
- Create the user with no shell and a home folder under a common SFTP folder, then set a password:
useradd -M -d /srv/sftp/client1 -s /usr/sbin/nologin -G sftponly client1 passwd client1
- Create the folders. The chroot folder and every folder above it must be owned by root and not writable by group or others, so the user gets a writable folder inside it:
mkdir -p /srv/sftp/client1/upload chown root:root /srv/sftp /srv/sftp/client1 chmod 755 /srv/sftp /srv/sftp/client1 chown client1:client1 /srv/sftp/client1/upload
- Create
/etc/ssh/sshd_config.d/50-sftponly.conf:Match Group sftponly ChrootDirectory %h ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no%his the user's home folder.internal-sftpis the SFTP server built into sshd, so nothing needs to be copied into the chroot, and theSubsystemline in the main file can stay as it is. - Check the syntax and restart SSH:
sshd -t systemctl restart ssh # Debian and Ubuntu systemctl restart sshd # AlmaLinux, Rocky Linux and RHEL
To see what applies to the user, runsshd -T -C user=client1,host=localhost,addr=127.0.0.1 | grep -E "forcecommand|chrootdirectory". - Test from another computer with
sftp client1@SERVER-IP. In our Debian 13 test the user saw/, could not write there, and could upload intoupload:sftp> pwd Remote working directory: / sftp> put /tmp/report.txt dest open "/report.txt": Permission denied sftp> cd upload sftp> put /tmp/report.txt sftp> ls -l -rw-r--r-- ? 1000 1001 6 Oct 9 17:30 report.txt
An SSH login with the same user is refused:$ ssh client1@SERVER-IP This service allows sftp connections only.
Add more SFTP users and list them
Repeat steps 2 and 3 for each user (for example client2 with /srv/sftp/client2); the Match Group block covers everyone in the group without another restart. To list your SFTP-only users:
$ getent group sftponly sftponly:x:1000:client1,client2
Password or key login
- Keys: put the public key in
/srv/sftp/client1/.ssh/authorized_keys, owned by the user, withchmod 700on.ssh. SSH reads it before entering the chroot. - Passwords switched off: many servers set
PasswordAuthentication no. Our password login then failed withPermission denied (publickey). AddingPasswordAuthentication yesinside the Match block allowed passwords for the SFTP group only, and the login worked again.
How to use SFTP with sudo
This is for normal SSH users (not the chrooted ones above) who need to edit files they cannot write, for example in /etc or a website folder owned by www-data.
- Allow the user to run only the SFTP server program through sudo, without a password. Create
/etc/sudoers.d/deploy-sftpwithvisudo -f /etc/sudoers.d/deploy-sftp:deploy ALL=(root) NOPASSWD: /usr/lib/openssh/sftp-server
The program is/usr/lib/openssh/sftp-serveron Debian and Ubuntu and/usr/libexec/openssh/sftp-serveron AlmaLinux, Rocky Linux and RHEL. - Connect with the server program started through sudo:
sftp -s "sudo /usr/lib/openssh/sftp-server" deploy@SERVER-IP
In our test the user could then list/rootand upload to/etc; uploaded files belong to root:sftp> put /tmp/report.txt /etc/report.txt # ls -l /etc/report.txt -rw-r--r-- 1 root root 6 Oct 9 17:32 /etc/report.txt
- Safer for websites: allow only the web server user, so the user never gets root:
deploy ALL=(www-data) NOPASSWD: /usr/lib/openssh/sftp-server
sftp -s "sudo -u www-data /usr/lib/openssh/sftp-server" deploy@SERVER-IP
Uploads were then owned bywww-data, andls /rootgavePermission denied.
Without the sudoers rule the connection closes at once. Classic sudo (Debian 13) printed sudo: a terminal is required to read the password and sudo: a password is required; sudo-rs, the default on Ubuntu 26.04, printed sudo: I'm sorry deploy. I'm afraid I can't do that. With the rule, both worked the same way.
In graphical clients: according to WinSCP, enter the same command (for example sudo /usr/lib/openssh/sftp-server) in the SFTP server field on the SFTP page of the Advanced Site Settings, and sudo's requiretty option must stay off (the default). A client without such a field cannot use sudo for SFTP. Treat a root rule like this as full root access for that user.
SFTP-only users cannot use sudo. When client1 tried the -s "sudo ..." form, sshd answered with its refusal text and the client showed Received message too long 1416128883. That is intended: ForceCommand internal-sftp accepts only the normal SFTP subsystem.
Often better than sudo: give the user write access to the folder with an ACL. After setfacl -R -m u:deploy:rwX /var/www/html and setfacl -R -d -m u:deploy:rwX /var/www/html, plain sftp deploy@SERVER-IP could upload there. See how to configure ACLs on Linux.
Common problems
- Connection closes right after the password, and the SSH log says
bad ownership or modes for chroot directory "/srv/sftp/client2": the chroot folder (or one above it) is group-writable or not owned by root. Fix step 3. With key login the log saysAuthentication refused: bad ownership or modes for directory /srv/sftp/client1instead. - "Permission denied" when uploading: the user can write only in their own subfolder, not in the chroot root.
- "Received message too long" for a normal user: something in the user's shell startup files prints text; remove that output for non-interactive sessions.
- Uploads fail although ownership is right (AlmaLinux, Rocky Linux, RHEL): look for SELinux denials with
ausearch -m avc -ts recent. The policy has a boolean,ssh_chroot_rw_homedirs, for chroot folders inside home directories.
Related: how to use SFTP to transfer files, which port SFTP uses, how to add a user to sudo on Debian and how to log SFTP file transfers.
Official documentation: sshd_config (ChrootDirectory, ForceCommand, Match) and sftp (the -s option).
Ucartz services for this topic
- KVM VPS hosting: NVMe SSD and full root access, with Free Basic Managed Support.
- Unmanaged dedicated servers: full root access and free IPMI KVM, with Free Basic Managed Support.
- Linux server management: hardening, patching, monitoring and automation for Ubuntu, Debian, RHEL and AlmaLinux.
