Why are there two ways to setup SFTP with OpenSSH and when to use which? Is there any difference between them?

I mean the first one is using a lib from OpenSSH and the second one says "use the internal", so it is also OpenSSH?

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

4 Answers 4


Both sftp-server and internal-sftp are part of OpenSSH. The sftp-server is a standalone binary. The internal-sftp is just a configuration keyword that tells sshd to use the SFTP server code built-into the sshd, instead of running another process (what would typically be the sftp-server).

The internal-sftp was added much later (OpenSSH 4.9p1 in 2008?) than the standalone sftp-server binary. But it is the default by now. The sftp-server is now redundant and is kept probably for a backward compatibility.

I believe there's no reason to use the sftp-server for new installations.

From a functional point of view, the sftp-server and internal-sftp are almost identical. They are built from the same source code.

The main advantage of the internal-sftp is, that it requires no support files when used with ChrootDirectory directive.

Quotes from the sshd_config(5) man page:

  • For Subsystem directive:

    The command sftp-server implements the SFTP file transfer subsystem.

    Alternately the name internal-sftp implements an in-process SFTP server. This may simplify configurations using ChrootDirectory to force a different filesystem root on clients.

  • For ForceCommand directive:

    Specifying a command of internal-sftp will force the use of an in-process SFTP server that requires no support files when used with ChrootDirectory.

  • For ChrootDirectory directive:

    The ChrootDirectory must contain the necessary files and directories to support the user's session. For an interactive session this requires at least a shell, typically sh, and basic /dev nodes such as null, zero, stdin, stdout, stderr, and tty devices. For file transfer sessions using SFTP no additional configuration of the environment is necessary if the in-process sftp-server is used, though sessions which use logging may require /dev/log inside the chroot directory on some operating systems (see sftp-server for details).

Another advantage of the internal-sftp is a performance, as it's not necessary to run a new sub-process for it.

It may seem that the sshd could automatically use the internal-sftp, when it encounters the sftp-server, as the functionality is identical and the internal-sftp has even the above advantages. But there are edge cases, where there are differences.

Few examples:

  • Administrator may rely on a login shell configuration to prevent certain users from logging in. Switching to the internal-sftp would bypass the restriction, as the login shell is no longer involved.

  • Using the sftp-server binary (being a standalone process) you can use some hacks, like running the SFTP under sudo.

  • For SSH-1 (if anyone is still using it), Subsystem directive is not involved at all. An SFTP client using SSH-1 tells the server explicitly, what binary the server should run. So legacy SSH-1 SFTP clients have the sftp-server name hard-coded.


There exist alternative SFTP implementations that can be used together with OpenSSH:


You can lock an authorized_key to the external sftp-server.

command="/usr/libexec/openssh/sftp-server" ssh-rsa AAAA…== user@host.com

When you do, your user can sftp, but cannot scp or ssh:

$ sftp host:/etc/group /tmp
Connecting to host...
Fetching /etc/group to /tmp/group
/etc/group                                    100%  870     0.9KB/s   00:00

Attempting to do anything else will just hang:

$ scp host:/etc/group /tmp
Killed by signal 2.

$ ssh host uptime
Killed by signal 2.

Alas, there is no easy way for a key to be locked to a chroot unless the sshd_config is modified. This would be really cool for a user to be able to do without the intervention of the system manager.

  • 4
    ForceCommand internal-sftp should achieve the same
    – ptman
    Jun 9, 2016 at 7:13
  • 2
    Handy thing there is that without chroot you can use sshfs host:/home/user/.ssh ~/hackme to edit all those settings back to open access if you change your mind later.
    – sh1
    Sep 23, 2017 at 6:15
  • the more important part of @sh1 's point is that if you're going to lock the user down to only sftp in their own .ssh/authorized_keys file, you'd better make sure to chroot them somewhere that .ssh isn't accessible, or they can just replace their authorized_keys file with something more permissve Nov 21, 2019 at 14:51
  • chown root:group authorized_keys && chmod 0440 authorized_keys
    – MichaIng
    Feb 20 at 13:12

If all you want to do is lock an account to use SFTP only, just give their account the default shell /sbin/nologin

  • 2
    The OP actually asked something entirely different. Dec 30, 2019 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.