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
up vote 75 down vote accepted

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


From functional point of view, sftp-server and internal-sftp are almost identical. The main advantage of 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 internal-sftp is a performance, as it's not necessary to run a new sub-process for it.


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.

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


It may seem that sshd could automatically use internal-sftp, when it encounters sftp-server, as the functionality is identical and 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 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 sftp-server name hard-coded.

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.

  • 3
    ForceCommand internal-sftp should achieve the same – ptman Jun 9 '16 at 7:13
  • 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 '17 at 6:15

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

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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