Set Up an SFTP Server with OpenSSH on Linux

작성자

카테고리:

← 피드로
DEV Community · dpm_bush · 2026-10-01 개발(SW)

SFTP is provided by OpenSSH, so a typical Linux server doesn’t need a separate FTP service. If SSH is already running, you may only need to create an account and check that it can connect.

The main decision is whether the account should also have shell access. A regular Linux user can usually use both SSH and SFTP. For file-transfer-only accounts, OpenSSH can force SFTP and optionally confine users to a directory.

This walkthrough uses Ubuntu or Debian and OpenSSH.

Install and check OpenSSH

On the server, install the OpenSSH server package and start the service:

sudo apt update
sudo apt install openssh-server
sudo systemctl enable --now ssh

Enter fullscreen mode Exit fullscreen mode

Check that it is running:

sudo systemctl status ssh

Enter fullscreen mode Exit fullscreen mode

SFTP uses the SSH service and normally connects on TCP port 22. If UFW is enabled and SSH uses its default port, allow the OpenSSH profile:

sudo ufw allow OpenSSH
sudo ufw status

Enter fullscreen mode Exit fullscreen mode

If SSH uses a different port, allow that port instead. A cloud firewall or security group may also need a rule for the SSH port.

Create and test a regular account

Create a user on the server:

sudo adduser sftpuser

Enter fullscreen mode Exit fullscreen mode

Follow the prompts to set the account details and password. A standard OpenSSH installation will often already have the SFTP subsystem enabled, so test a connection before changing the SSH configuration.

From another machine, run:

sftp sftpuser@SERVER_IP

Enter fullscreen mode Exit fullscreen mode

Replace SERVER_IP with the server’s hostname or IP address. If SSH listens on a custom port, use uppercase -P:

sftp -P 2222 sftpuser@SERVER_IP

Enter fullscreen mode Exit fullscreen mode

At the sftp> prompt, try a few basic operations:

pwd
ls
put test.txt
get test.txt
exit

Enter fullscreen mode Exit fullscreen mode

If you can log in and transfer a file, the basic setup is working. This account may also be able to open a normal SSH shell. If that’s not appropriate, create a restricted SFTP-only configuration.

Optional: confine an SFTP-only account

A chroot confines the account to a directory tree. The permissions are important: OpenSSH requires the chroot directory and its path components to be owned by root and not writable by group or other users. Give the user write access to a directory inside the chroot instead.

Create a group and add the account to it:

sudo groupadd sftpusers
sudo usermod -aG sftpusers sftpuser

Enter fullscreen mode Exit fullscreen mode

Create a jail with a writable uploads directory:

sudo mkdir -p /sftp/sftpuser/uploads
sudo chown root:root /sftp/sftpuser
sudo chmod 755 /sftp/sftpuser
sudo chown sftpuser:sftpusers /sftp/sftpuser/uploads

Enter fullscreen mode Exit fullscreen mode

The user will see the jail as their SFTP root and can write inside /uploads. Don’t make /sftp/sftpuser writable by the SFTP user to fix upload errors; that can violate OpenSSH’s chroot ownership checks.

Edit /etc/ssh/sshd_config, or an appropriate configuration snippet under /etc/ssh/sshd_config.d/ if your system uses snippets. Make sure there is an SFTP subsystem configured. Many Linux packages already configure it; an in-process configuration looks like this:

Subsystem sftp internal-sftp

Enter fullscreen mode Exit fullscreen mode

Avoid adding a duplicate or conflicting Subsystem line. Then add a group-specific rule near the end of the effective configuration:

Match Group sftpusers
    ChrootDirectory /sftp/%u
    ForceCommand internal-sftp
    DisableForwarding yes

Enter fullscreen mode Exit fullscreen mode

%u expands to the authenticated username. ForceCommand internal-sftp keeps matched users in SFTP rather than giving them an interactive shell. DisableForwarding yes disables SSH forwarding features for those users.

Validate before restarting SSH

A mistake in SSH configuration can lock you out of a remote server. Check the configuration before applying it:

sudo sshd -t

Enter fullscreen mode Exit fullscreen mode

No output means the syntax check succeeded. Then restart the service:

sudo systemctl restart ssh

Enter fullscreen mode Exit fullscreen mode

Keep your existing administrative SSH session open while testing a second connection. Log in as the restricted user and verify that the upload directory is writable:

sftp sftpuser@SERVER_IP

Enter fullscreen mode Exit fullscreen mode

At the prompt:

pwd
ls
cd uploads
put test.txt
ls

Enter fullscreen mode Exit fullscreen mode

The user should be confined to the chroot and able to write in uploads.

Common failures

Connection refused: Check that the SSH service is running, that you’re using the right port, and that the server firewall allows it. For a remote VPS, check its cloud firewall rules too.

Login denied: Verify the username and the configured authentication method. SFTP uses SSH authentication, so SSH keys can be used as well as passwords. To specify a private key from the client:

sftp -i ~/.ssh/id_ed25519 sftpuser@SERVER_IP

Enter fullscreen mode Exit fullscreen mode

Upload fails with permission denied: Check ownership and permissions on the destination directory. In the chroot example, uploads is writable by the account; the chroot root is deliberately not.

Chroot ownership or mode error: Check every component of the ChrootDirectory path. The jail hierarchy must be root-owned and not writable by group or other users.

Subsystem request failed: Check that an SFTP subsystem is configured and that there aren’t conflicting subsystem lines. Run sudo sshd -t after configuration changes.

A useful setup order

Start with OpenSSH, create a normal account, and confirm that SFTP works. Add a chroot and force SFTP only when you need that restriction. This separates basic connectivity problems from directory-permission and SSH-configuration problems—and helps keep a configuration change from interrupting your administrative access.

I originally published a more detailed version of this guide on the SSHFlow blog.

I’m also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.

원문에서 계속 ↗