How to setup secure file servers (SSH/SFTP)
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.
Requirements
- A Linux or Unix server (Ubuntu will be used here)
root
/sudo
access to the serversshd
(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 loginPasswordAuthentication 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
NEW_USERNAME="sftpuser"
# 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-forceableroot
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.
Troubleshooting
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"
# ...