Limiting file system name space for sftp users

Some administrators might want to limit the file system name space that is accessible by users during file transfer operations. This task can be accomplished by configuring the sshd daemon to change the root directory of the sftp user connection. The administrator uses the sshd_config keyword ChrootDirectory to set up the environment. The keyword is described in ChrootDirectory.

After the environment has been set up, searches for file system objects (files and directories) are relative to the user's new root directory. If the new root directory does not contain a duplicate of the required programs or support files needed by the user, then the session might not be usable. The "internal-sftp" subsystem can be used to overcome this setup problem for sftp users. Specifying "internal-sftp" on either the sshd_config keywords Subsystem or ForceCommand causes the sshd daemon to implement an in-process sftp server. Such a server does not require duplication of the sftp-server command or other support files in the new root directory in order to connect via sftp. Thus, combining the use of the sshd_config keyword ChrootDirectory and the "internal-sftp" subsystem enables full sftp file transfer functionality, while limiting the file system objects that are accessible to the user. (The two keywords are described in Subsystem and ForceCommand.)

Note that specifying "internal-sftp" on the sshd_config keyword ForceCommand enables an in-process sftp server to be the only command to be run, regardless of the command specified by the user. For example, this prevents the user from running scp or from starting an interactive shell session via ssh on the server. In addition, the in-process sftp server allows users without shell access on the server to still transfer files via sftp. Using the ForceCommand keyword in this manner allows the administrator to apply this restriction to a limited set of users when placed inside a Match keyword as described in Match.

Public key authentication can also be used with the sshd_config keyword ChrootDirectory. However, the sshd daemon will search for the user's public keys (see the sshd_config keyword AuthorizedKeysFile) starting from the original root directory, not the new root directory specified by the ChrootDirectory keyword. Therefore, depending on the location of the new root directory, the user might not have access to their own public keys used during authentication.

Example 1: Use the sshd_config keyword ChrootDirectory and "internal-sftp" subsystem to cause the sshd daemon to set a user's root directory to the user's home directory.

Server (name is "server1") sshd_config keywords:
Subsystem sftp internal-sftp
	  ChrootDirectory %h
Client (user "employee1", home directory is /u/employee1):
> sftp server1
	Connecting to server1...
	sftp> pwd
	Remote working directory: /
	sftp> ls -a
   .        ..               .profile     .sh_history
	.ssh         myfile

After connecting and setting the root directory, the sshd daemon also attempts to change the user's current working directory to the user's home directory, relative to the root directory that is now in effect. For example, if the user's home directory were /u/employee1, then the sshd daemon would attempt to set the user's current working directory relative to the root directory (which also happens to be /u/employee1). Therefore, the sshd daemon sets the user's current working directory to /u/employee1/u/employee1, if the directory exists. This action might or might not be what is desired.

Example 2: An example of using the sshd keyword ChrootDirectory and the "internal-sftp" subsystem for a specific group of users. Users who are members of the group SFTPUSERS will have their root directory set to "/files/repository" and be forced into using sftp, regardless of the command they are attempting to run. If they are not members, their root directory will not be changed when connecting. They will also not be limited to only using sftp unless other sshd keywords were in effect for those users, such as a different ForceCommand in another Match block.

Server (name is "server1") sshd_config keywords:

Subsystem sftp internal-sftp
Match group SFTPUSERS
   ChrootDirectory /files/repository
   ForceCommand internal-sftp

Client (user "employee1" in group SFTPUSERS, home directory is /u/employee1):

> sftp server1
	Connecting to server1...
	sftp> pwd
	Remote working directory: /
	sftp> ls -a
	...          file1        file2