This article describes how to setup a SFTP server installation,
plus some advices from a security point of view.
The users will find themselves inside a chrooted environment, and
the file system permissions are active:
Every user may have a seperated, isolated environment.
Step 1: Prepare your system
Create a group for users that are allowed to use sftp, and add some users to it. Since those users communicate with the ssh server without needing a login shell, we will disable shell access for them by setting /bin/false as login shell.
root@testkraxn /home/tester # groupadd sftponly root@testkraxn /home/tester # cat /etc/group | tail -n 1 sftponly:x:1001: root@testkraxn /home/tester # useradd garfield -d / -g 1001 -M -N -o -u 1001 root@testkraxn /home/tester # passwd garfield Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully root@testkraxn ~tester # chsh garfield Changing the login shell for garfield Enter the new value, or press ENTER for the default Login Shell [/bin/sh]: /bin/false root@testkraxn /home/tester # cat /etc/passwd | tail -n 1 garfield:x:1001:1001::/:/bin/false
Step 2: Configure the SSH Server
root@testkraxn /home/tester # cp /etc/ssh/sshd_config /etc/ssh/sshd_config.`date +%F_%T`.backup root@testkraxn /home/tester # vim /etc/ssh/sshd_config
replace line:
Subsystem sftp /usr/lib/openssh/sftp-server
with
Subsystem sftp internal-sftp
Then, append these lines at the end of the file:
Match group sftponly ChrootDirectory /var/www X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp
my whole config, to be complete here:
root@killerkraxn ~ # grep -vE '^\s*(#.*|)$' /etc/ssh/sshd_config Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_dsa_key UsePrivilegeSeparation yes KeyRegenerationInterval 3600 ServerKeyBits 768 SyslogFacility AUTH LogLevel INFO LoginGraceTime 120 PermitRootLogin yes StrictModes yes RSAAuthentication yes PubkeyAuthentication yes IgnoreRhosts yes RhostsRSAAuthentication no HostbasedAuthentication no PermitEmptyPasswords no ChallengeResponseAuthentication no X11Forwarding yes X11DisplayOffset 10 PrintMotd no PrintLastLog yes TCPKeepAlive yes AcceptEnv LANG LC_* Subsystem sftp internal-sftp UsePAM yes Match group sftponly ChrootDirectory /data/sftpusers X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp
Step 2: Create some test directories
I use a script like this to create a new user: (run as root)
NEW_USER=$1 echo crating user: $NEW_USER useradd $NEW_USER -d / -G sftponly -M -s /bin/false groups $NEW_USER cd /data/sftpusers echo "setting up home directories..." mkdir $NEW_USER chown root:$NEW_USER $NEW_USER chmod 750 $NEW_USER mkdir $NEW_USER/readonly chmod 755 $NEW_USER/readonly echo "you cannot change this file" > $NEW_USER/readonly/test.txt chmod 644 $NEW_USER/readonly/test.txt mkdir $NEW_USER/readwrite echo "delete me if you wish" > $NEW_USER/readwrite/test.txt chown $NEW_USER:$NEW_USER -R $NEW_USER/readwrite mkdir $NEW_USER/no-access chmod 700 $NEW_USER/no-access echo "you won't ever read this, douchebag!" > $NEW_USER/no-access/test.txt echo "you should set a password for the user: passwd $NEW_USER"
If you want to provide access to other folders to the users, you can mount
the directory into the users base dir.
In this example, i will grant access to /media/misc/foo to the user garfield:
root@testkraxn ~ # mkdir -p /data/sftpusers/garfield/media root@testkraxn ~ # mount --bind /media/misc/foo /data/sftpusers/garfield/media
Finally, the directory structure for the user looks like this:
root@killerkraxn /data/sftpusers # tree . └── garfield ├── no-access │ └── test.txt ├── readonly │ └── test.txt ├── readwrite │ └── test.txt └── misc └── foo --> mountpoint of /media/misc/foo └── foo-contents
Restart the ssh server and test the setup:
root@testkraxn ~ # service ssh restart
andre@buenosaires ~ % sftp garfield@ 192.168.56.102 garfield@ 192.168.56.102's password: Connected to 192.168.56.102. sftp> cd / sftp> pwd Remote working directory: / sftp> ls foo readonly readwrite no-access sftp> cd no-access sftp> pwd Remote working directory: /no-access sftp> ls remote readdir("/no-access"): Permission denied sftp> cd /readwrite sftp> mkdir bar sftp> ls bar test.txt sftp> cd /readonly sftp> mkdir bar Couldn't create directory: Permission denied sftp> ls test.txt sftp> cd /misc sftp> pwd Remote working directory: /misc sftp> ls foo sftp> exit
And the users do not have access to a shell when trying to connect via ssh:
andre@buenosaires ~ % ssh garfield @192.168.56.102 garfield@ 192.168.56.102's password: This service allows sftp connections only. Connection to 192.168.56.102 closed.