How to setup secure file servers (SSH/SFTP)

How to setup secure file servers (SSH/SFTP)
Page content

Sharing files is one of the oldest but also most delicate tasks on servers. If you would like to share your files in a simple but also pretty secure way, here is how to do it with SSH / SFTP.


  • A Linux or Unix server (Ubuntu will be used here)
  • root / sudo access to the server
  • sshd (sudo apt install ssh)

Initial setup

The following steps only need to be performed once.

# get root
sudo -s

# add group for sftp only users
groupadd sftponly 

# change the sshd configuration file
vi /etc/ssh/sshd_config
# file: /etc/ssh/sshd_config

# ...
# ensure this is present and not commented out...
Subsystem sftp /usr/lib/ssh/sftp-server

# add these lines
Match Group sftponly
  ChrootDirectory %h
  ForceCommand internal-sftp -d uploads
  AllowTcpForwarding no
  X11Forwarding no
  # PasswordAuthentication no

After changing the configuration you need to restart sshd. On Ubuntu you can do this with:

systemctl restart sshd

Explanation of sshd_config changes:

  • %h is a variable for user homes, e.g. /home/sftpuser
  • -d uploads changes directory to /home/sftpuser/uploads after login
  • PasswordAuthentication no is commented out for convenience, but would provide extra security by only allowing Public-key-authentication - see Extra security

Adding sftponly users

Now you can add any number of users as member of the sftponly group.

Please note: It is not possible (at least not without vast amounts of configuration) to chroot a user to /home/<username> without having an extra directory like /home/<username>/uploads, because the ChrootDirectory has to be owned by root, which prevents write permissions for sftp only users.

# store new username into a variable for easier usage in commands

# add the user that cannot login via ssh but only sftp
useradd -g sftponly -s /sbin/nologin "${NEW_USERNAME}"

# create the home directory with an additional writable uploads
mkdir -p "/home/${NEW_USERNAME}/uploads"

# change ownership to root (required for ChrootDirectory)
chown -R "root:root" "/home/${NEW_USERNAME}"

# change ownership of uploads directory and grant write permissions
chown -R "${NEW_USERNAME}:sftponly" "/home/${NEW_USERNAME}/uploads"
chmod ug+rwX "/home/${NEW_USERNAME}/uploads"

# change password of new user (manual input required)
passwd "${NEW_USERNAME}"

That should be it - now you have a file server, that can be accessed via SFTP protocol and is secured via chroot.

Extra security (advanced users)

The above routine will probably work, but for a server that is directly connected to the internet without a VPN security layer, you should provide a little extra security.

Disable root log in

You should always have a user that operates as non-root, even if it has sudo permissions this is good practise. Therefore, in your extra secure /etc/ssh/sshd_config you should always provide the config line

PermitRootLogin no

This prevents the user root completely from logging into the system. Reasons:

  • root is easy to guess and therefore brute-forceable
  • root is a user that has all permissions, which you do not want an attacker to have
  • It forces you to have a less privileged user

Setup Fail2ban

You should run Fail2ban , which is a system service that monitors logfiles, detects brute force attempts and bans the IP addresses of the attackers for a configurable amount of time via IP Tables firewall. Even if you followed all instructions above, Fail2ban will help you to prevent denial of service attacks. It also keeps the logfiles smaller.

Disable password authentication

Password authentication is enabled by default and prompts for username / password combinations, if you try to log in. Unfortunately this allows others trying to brute force passwords, especially for known usernames like root.

This is why you should disable password authentication completely and switch to public key authentication for production servers. BUT: Be careful to have a valid key based login before you disable the password log in - otherwise you will lock yourself out.


When something does not work like expected, it might be a good idea to have a look at the logfiles. Often you will find the reason pretty easily and googling the error message helps most of the time:

tail /var/log/auth.log
# ...
# sshd[2236]: fatal: bad ownership or modes for chroot directory "/home/sftpuser"
# ...
Andreas Fuhrich avatar
About Andreas Fuhrich
I’m a professional software developer and tech enthusiast from Germany. On this website I share my personal notes and side project details. If you like it, you could support me on github - if not, feel free to file an issue :-)