Friday, 9 January 2009

SFTP on Ubuntu and Debian in 9 easy steps

In this post, I'll show you how to set up secure ftp (SFTP) access to your Ubuntu server. (Instructions for Debian are very similar: leave out the sudo part and follow these steps as root:)

For this to work, you'll need Ubuntu 8.10 "Intrepid", Debian 5.0 "Lenny" or newer. In this example, mark is the user that can gain superuser rights through sudo. "peter" and a few other users are the ones I want to give sftp access to their personal folder, but not shell access or anything else.

Step 1: If it doesn't exist yet, create a group for the users you want to have sftp access only:
mark@neuskeutel:~$ sudo groupadd sftponly

Step 2: Add user "peter" to this group:
mark@neuskeutel:~$ sudo adduser peter sftponly

Step 3: Install openssh-server if it's not installed yet.
mark@neuskeutel:~$ sudo apt-get install openssh-server

Step 4: Open the default OpenSSH server configuration for editing:
mark@neuskeutel:~$ sudo nano /etc/ssh/sshd_config

Step 5: Change the default sftp server from:
Subsystem sftp /usr/lib/openssh/sftp-server

Subsystem sftp internal-sftp

Step 6: Some users can only use sftp, but not other OpenSSH features like remote login. Let's create a rule for that group of users (we'll create the group afterwards). Add the following section to the bottom of /etc/ssh/sshd_config:
Match group sftponly
ChrootDirectory /home/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

Step 7: Pass ownership of peter's directory you want to be sftp accessible to the superuser:
mark@neuskeutel:~$ sudo chown root.root /home/peter

Step 8: Now we change peter's home directory (normally /home/peter) to /:
sudo usermod -d / peter

Step 9: Repeat steps 2, 7 and 8 for any other users that you want to give sftp access.

Did you find this tutorial helpful? Any problems when trying to follow it? Suggestions? Please comment and I'll try to follow up!


Anonymous said...

Step 2 is incorrect.

Mark Van den Borre said...

Wannes, I fixed the typo in the description for step 2. Thank you for noticing and reporting it!

Anonymous said...

i rely on rssh (restricted shell for scp/sftp, also available via "universe"-repo in ubuntu). once installed, changing the user's shell to rssh suffices to restrict that user to scp/sftp as well.

Mark Van den Borre said...

I looked into rssh too. My reasons for going with just OpenSSH, not rssh are twofold:

1) As far as I know, rssh can't control port forwarding.
2) Rssh is yet another package. I'd rather throw less and very well audited code at security.

Unknown said...

What is the point of step 8?

Mark Van den Borre said...


Why Step 8?

After the call to chroot(), sshd changes directory to the home directory relative to the new root directory.

Unknown said...

Oh, right. Thanks for the clarification.

RainCT said...

I've tried this on Hardy but get:
"Directive `ChrootDirectory' is not allowed within a Match block" and sshd failst o start. Do you know how to avoid this (if possible without changing the OpenSSH version or stuff like that)?

RainCT said...

Ah, I see version 5.0 of OpenSSH is required. Too bad.

RainCT said...

If anyone wants it, I have backported the OpenSSH version from Intrepid for Hardy in my PPA:

[DISCLAIMER: All files there come with NO support from Canonical nor Ubuntu, and only limited maintenance from me. Use them at your own responsibility.]

Anonymous said...

when using filezilla to connect I can still browse and navigate the system, I would like to locked this to only their home directory. Allowing for them to see files, download and upload files only.

Anonymous said...

Sorry I forgot to restart ssh.

sudo /etc/init.d/ssh restart

I did get an error on ubuntu 8.10 that said TcpForwarding was not allowed and once removed it worked fine.

Anonymous said...

Why if I skip step 7 the user cannot login? It seems the only way to allow the user to upload is to create a subdirectory as root then chown it to the user. Is there a better way?

Also for step 7, wouldn't "chown root:root /home/peter" be better? Or does it even matter?

BTW, thanks very much for the directions, this is just what I was looking for.

energon said...

Thx Marc, exactly what I needed.

neongrau said...

After i first read some howto involving rssh i discovered your howto.

worked perfectly!

i just made a slight change
ChrootDirectory ~

this prevented me from resetting permissions and stuff so i could just use whatever homedir i want.

or is there a reason for doing it the way you described?

wake said...

I think the reason / is used as the ChrootDirectory, is because the home directory for the sftp user and all previous directories in the hierarchy must be owned by root, and only writeable by root. For instance if you want the user to be chrooted to /var/upload, you have to make sure /var/upload, /var and / are owned by root, and only writeable by root (chmod 755). Once the user logs in, since their home directory is owned by root they will not be able to upload files/create directories. Create a folder structure for them, chown the folder(s) to the sftp user, and they can then upload files.


Anonymous said...

any reason why enabling write access with:

chmod 775 /home/(username)
chown root.sftponly /home/(username)

is bad?

(Just installed it for apache2 uploads. Seems to work.)

Unknown said...

Am I supposed to create a new account to replace 'peter' or use an existing one. I really don't like the idea of shifting my entire home directory around!

Anonymous said...

This doesn't work with public key auth, because sshd requires the .ssh/authorized_keys file to be owned by the user logging in. Thus you can only let 1 user in. Is there a workaround for this?

Anonymous said...

I think I got it, it's not pretty but it should work:

1) Uncomment this line:
#AuthorizedKeysFile %h/.ssh/authorized_keys
And change it to:
AuthorizedKeysFile /home/%u/.ssh/authorized_keys

2) Create a 'jail' directory in each users chroot directory, e.g.
mkdir /home/henk/jail

3) Change ChrootDirectory /home/%u to
ChrootDirectory /home/%u/jail

4) Create a '.ssh' directory besides the jail directory for each user that uses public key auth

5) Place the authorized_keys file in the home directories and change ownership to that given user, e.g.:
chown henk:henk /home/henk/.ssh/authorized_keys

6) If the file doesn't have the right permissions already, change it now:
chmod 600 /home/henk/.ssh/authorized_keys

Also, if you want to provide access to a certain directory ( inside the 'jail' directory), e.g. /var/www/, try this:

chown henk:henk /var/www/ #(to permit access if not already so)
mkdir /home/henk/jail/
mount -o bind,nodev,nosuid,noexec /var/www/ /home/henk/jail/

Before the mount, the mount target should be owned by root. After the mount, that directory will be owned by whoever owns the other directory, in fact everything will be exactly the same. This also adds security because /var is probably not mounted with nodev,nosuid,noexec.

Anonymous said...

I want to change the home directory for all users to /Public just as a test. However after following these steps to change the home directory for user "peter" to / I am unable to use usermod -d to change the directory that I start in when I use a client such as WinSCP to my user. Instead, I always directly start at "/"

How do I fix this?

xian said...

This is a great article. For a little clarification on what happens in which order, I found this was also helpful:

I need multiple users to access the same directory (as per previous comment) using keys. To do this, I create each user with adduser and set them in the sftponly group with addgroup. I then create a shared jail as /var/sftp, and ensured root.root owned it with 755 perms (chown and chmod)- all the same as in the article.

Each user makes a private/public key-pair (e.g. with ssh-keygen) and give me the public key, which I add manually add to their pre-chroot /home/username/.ssh/authorized_keys (which must be owned by and writable only by that user).

Since authentication happens *before* the chroot, each user's /home/username/.ssh/authorized_keys is used. But since the user's home directory is evaluated *post* chroot, we've changed it to / (as per article), and so the default sshd AuthorizedKeysFile of $HOME/.ssh/authorized_keys no longer works, and must be changed to explicitly depend upon the user name.

The final /etc/ssh/sshd_config file looks like this (don't forget to restart ssh!):

AuthorizedKeysFile /home/%u/.ssh/authorized_keys

## directions from
Match group sftponly
ChrootDirectory /var/sftp
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

Anonymous said...

After that steps users from sftponly are able to navigate between all directories on my server. How to disable it?

Anonymous said...

Hi, I followed these to the letter and the user directories are not writeable. How do I allow users to upload files?

Gene said...

I would also like to know how to safely enable read/write access without introducing other issues.

Чок Коб said...

I'm too want to know

Anonymous said...

You can let users upload files by creating a new directory in the jail and set the owner of the directory to the user.

Anonymous said...

Didnt work for me. login in with sftp://localhost refuses user

Both SSH and FTP are running and user and usergroup are active

reseptor said...

thank you very much. great post. worked like a charm for my ubuntu 10 in MS virtual PC

michael said...

Hey! thanks for the great tutorial!
However I had problems to get it running, until I found out that you actually need to close the Match clause. Otherwise in my case no sftp connections were possible. So a corrected sshd.conf should look like this:

Match group sftponly
ChrootDirectory /home/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

hope this helps!

Melpomene said...

I keep getting the error "fatal: bad ownership or modes for chroot directory "/home/user"" in my /var/log/auth.log, after following the guide.
Both throught sftp and ssh access.
I have closed the Match as mentioned above.

Melpomene said...

Got it running. I had trailing / after my chroot and chmod commands.

sentono said...

working great in my end.. nice share and great tutorial :)

Unknown said...

thanks, i has helped me surely

Konika said...

I have connected to remote server and it appears in my list of bookmarks and as a folder in the browser window while general working.
But when I want to attach some file to the email, from this remote server, I cannot find it in the list of places on the left side bar.
Also when downloading something, I am unable to save the it directly on the server, again because it does not appear in the places to save.
Could you tell how to make this remote server always accessible as a local disk both while uploading from it or downloading to it?
Thanks in advance

Anonymous said...

Well the internal-sftp setting worked but didnt chroot anything so it made it useless.
Here is how to make a chrooted sftp only account with a compiled version of scponly on ubuntu 10.04

Ariese said...

I followed your guide, and now server is not connecting with the root user. I think you somehow blocked the SSH for all users.

Please fix this.

panelsaw said...

Saw trax really are a good panel saw I did used very heavily and it’s much better than if I’m going to compared to another one saw, its has good power and well accuracy, and I’m surely suggest for those who want to purchase best panel saw in this segment Highly Recommended. Panel Saw

Ameritechnology said...

Great product. Great customer service. You should be putting every other printing company out of business.You are top of my list for printing. Excellent service, excellent personnel High quality work,Highly recommended for everyone in the business.
Ameri Technology

Zap Cleaning said...

A definite 5 Star Company. This is the second time I have used zap cleaning. They did an excellent job cleaning my house, sidewalk, driveway and deck around the
pool. Everything looks brand new. Thank you for a job well done! I will use your company in the future.Awsome job at a great price too. Very happy.Zap Cleaning

American Electric said...

Honest, professional and excellent customer service Great service and great technicians! We had American Electric technicains and they install a whole house generator and a new electrical panel.The technicians were on time We would definitely recommend them again! American Electric

American Electric said...

American Electric Jacksonville - Would highly recommend. Prompt service, on time arrival, professional and courteous staff, reasonable prices! They were accommodating, clean, and easy to work with. I would highly recommend.
American Electric Jacksonville

Essential natural Oils said...

I’ve been using the bath and body range from Health & Beauty Natural Oils for quite some time now and I must say my skin feels ultra-soft and smells heavenly after using the products. Will definitely buy again.
If you are also looking for the best Essential Oils so you click here.

Vmax Brakes said...
This comment has been removed by the author.
Technosys Future said...

This information is very useful to me. Please share more information about this. Thankyou for sharing this information with us.
web designing company in Dwarka