Categories
Linux

Permitting SFTP file access while denying shell login

When you google on how to configure remote file access on linux most tutorials and how-tos will guide you towards ftp (file transer protocol) which has existed for ages and is well supported across all devices from mobile to desktop. However using FTP in these day and age without securing it using SSL is kind a naive. User credentials are sent over in clear-text and I don’t have to tell you that sooner or later the credentials will be compromised and your data might be at risk.

FTP similar to Telnet was never a protocol designed with security in mind. There are several solutions to FTP’s shortcomings. As mentioned, you can use FTP in combination with SSL or you can use SSH’s File Transfer Protocol SFTP for securily transferring data using the SSH network protocol.

In general, SSH is used for securely logging into a system remotely. By default, every user with SSH access automatically also has SFTP file access. The issue with simply adding a user to the system for SFTP access is that they also automatically receive shell-access. This grants them the right to run processes and potentially administer your system you may not wish them to run on your server. This tutorial will show you how to add a user to your system without granting them shell permissions but still allowing them file-access.

First, if you haven’t yet installed the openssh server yet, do so now (prepend every command with “sudo” if not logged-in as root):

[bash]
# apt-get install openssh-server
[/bash]

Once the ssh-server is installed we need to add a user we wish to only allow SFTP access. Add a new usegroup to consolidate multiple users that should only receive SFTP access:

[bash]
# addgroup sftponly
[/bash]

Next, edit the ssh-daemon configuration file: /etc/ssh/sshd_config (you can use vim or whaever editor you prefer)
Look for the following line:

[bash]
Subsystem sftp /usr/lib/openssh/sftp-server
[/bash]

and replace the line with this instruction (you can also simply comment out the above line using # and insert the following line below):

[bash]
Subsystem sftp internal-sftp
[/bash]

At the end of the same file add the following lines to restrict the access of the users bleonging to the sftponly user-group:

[bash]
# Rules for sftponly group
Match group sftponly
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
[/bash]

Save the file and restart the ssh-daemon via:

[bash]
# /etc/init.d/ssh restart
[/bash]

Next, create the directory which the users will be jailed too:

[bash]
# mkdir /srv/sftponly/
[/bash]

Optionally you can use a mount-bind to map a specific filesystem into that folder. My share is located at /mnt/fs and I use mount-bind to map the shared-folder to sftponly:

[bash]
# mount –bind /mnt/fs /srv/sftponly/
[/bash]

Add a new user to the system and specify the previously created group as the user’s primary group. Disable shell-login and don’t create a home directory. See man-pages about adduser for more information about the available command-line switches:

[bash]
# adduser –home /srv/nfs4/fs/ –no-create-home –ingroup sftponly –disabled-login <username>
[/bash]

Set a password for the new user:

[bash]
# passwd <username>
[/bash]

In order for the user to be chrooted (jailed) to the specified directory the user’s home directory must be owned by root as well as only be writable by root:

[bash]
# chown root:root /srv/sftponly/
[/bash]

In case you are not able to log-in using the newly added user or even worse if the user is not getting jailed it’s best to check the auth.log in /var/log/auth.log

[bash]
Apr 20 12:34:04 fs sshd[12015]: Server listening on 0.0.0.0 port 22.
Apr 20 12:34:04 fs sshd[12015]: Server listening on :: port 22.
Apr 20 12:34:09 fs sshd[12018]: Accepted password for <username> from 10.1.1.185 port 54493 ssh2
Apr 20 12:34:09 fs sshd[12018]: pam_unix(sshd:session): session opened for user <username> by (uid=0)
Apr 20 12:34:09 fs sshd[12023]: fatal: bad ownership or modes for chroot directory "/srv/sftponly"
Apr 20 12:34:09 fs sshd[12018]: pam_unix(sshd:session): session closed for user<username>
Apr 20 12:34:25 fs sshd[12029]: Accepted password for <username> from 10.1.1.185 port 54494 ssh2
Apr 20 12:34:25 fs sshd[12029]: pam_unix(sshd:session): session opened for user username by (uid=0)
Apr 20 12:34:25 fs sshd[12037]: fatal: bad ownership or modes for chroot directory "/srv/sftponly"
Apr 20 12:34:25 fs sshd[12029]: pam_unix(sshd:session): session closed for user <username>
Apr 20 12:37:02 fs sshd[12076]: Accepted password for <username> from 10.1.1.185 port 54516 ssh2
Apr 20 12:37:02 fs sshd[12076]: pam_unix(sshd:session): session opened for user <username> by (uid=0)
Apr 20 12:37:02 fs sshd[12081]: fatal: bad ownership or modes for chroot directory "/srv/sftponly"
Apr 20 12:37:02 fs sshd[12076]: pam_unix(sshd:session): session closed for user <username>

[/bash]

In my case the specific user wasn’t getting jailed because the permissions on the root-folder were not correctly set. Make sure the home directory is owned by root and not the user itself.

Remove write permissions from others:

[bash]
# chmod go-w /srv/sftponly/
[/bash]