Skip to content

Instantly share code, notes, and snippets.

@flackend
Last active August 29, 2015 14:25
Show Gist options
  • Select an option

  • Save flackend/41f021bc776d72ebdadc to your computer and use it in GitHub Desktop.

Select an option

Save flackend/41f021bc776d72ebdadc to your computer and use it in GitHub Desktop.

Create a SFTP-Only User

Create a user with SFTP access, but without SSH shell or any other access.

Main resource: SFTP Only Without Bash/Shell (serveradminforhire.com).

We need to create a group for the users that will have only SFTP access:

groupadd sftponly

Now we'll add a new user:

useradd -G sftponly testuser -s /dev/null
  • -G sftponly adds the user to the group we created.
  • -s /dev/null 1 specifies the shell the user will use (none).

Optionally, you can set a password for the user. You can skip this step if you intend to only use public key authentication.

passwd testuser

Our user's home (also the only directectory that they will have access to) is /home/testuser. We need to create it, but it needs to be owned by root 2. So use sudo if you're not root:

sudo mkdir /home/testuser

Alternatively, you could specify a different directory to give the user access to. For example, /var/www. You can do that when you add the user:

useradd -G sftponly testuser -s /dev/null -d /var/www

Or, if you've already added the user, change the directory in /etc/passwd:

testuser:x:1002:1003::/var/www:/dev/null

Remember, the user's home must be owned by root:

chown root:root /var/www

Note: If you do set a home directory other than /home/testuser, you don't need to create /home/testuser.

If you want to use public key authentication, add your .ssh directory:

mkdir /home/testuser/.ssh

Note: The .ssh directory needs to be created wherever your user's home is. So in our alternative example, the directory would need to be at /var/www/.ssh.

Just like regular users, we need the owner to be the user and set up correct permissions:

touch /home/testuser/authorized_keys
chown -R testuser:testuser /home/testuser/.ssh
chmod 700 /home/testuser/.ssh
chmod 600 /home/testuser/.ssh/authorized_keys

Add your public key to authorized_keys.

Now we need to add the following to the end of /etc/ssh/sshd_config 3:

Match Group sftponly
ChrootDirectory %h
ForceCommand internal-sftp -l INFO -f AUTH
AllowTcpForwarding no

You'll need to restart ssh after editing its configuration for it to take effect:

service ssh restart

Now if you attempt to login with ssh (ssh testuser@hostname), you'll get a message like this:

This service allows sftp connections only.

While you should be able to login over SFTP and get access to just the user's home folder:

sftp testuser@hostname

Some guides say that you need to make sure that the "fake" shell is added to /etc/shells. In my experience it works without it. Not sure of the reasoning behind it.

Footnotes

  1. Explanations for /dev/null, /sbin/nologin, and /bin/false:

  2. “Write Failed: Broken Pipe” when trying to login through ssh with a specific user (stackoverflow.com)

  3. Match blocks need to be at the end of your config file because you cannot explicitly end blocks: OpenSSH: How to end a match block (unix.stackexchange.com).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment