A beginners guide to setting up Ubuntu 16.04 and SFTP
While frontend and backend technology has evolved into a fairly user/developer friendly environment, interacting with servers still seems to be reserved for geeks and wizards. But with a little help, many things are actually quite doable.
In this post I will guide you through the process of setting up some users with sftp access to their respective home folders, without allowing them normal ssh access through the console.
Personally I am using a digitalocean.com server, they provide a pretty neat service for a reasonable price. If you want to sign up through this link you will get a $10 credit. However any other server running Ubuntu 16.04 (or maybe even 14.04) should be fine as well.
In case you just created a new server, I will walk you through adding your ssh key, disabling login via password and setting up your firewall.
If you have already done this, just skip ahead to the Setting up SFTP section.
Before we get going, note that I am working on a mac. If you are using a different OS, especially windows, some commands might differ. However, the general steps are the same.
Before we do anything, make sure you can login to your server using a password. With DigitalOcean you will get an email with the password for your server. You are required to change it the first time you log into your server. So log in, and follow the prompts to change your password. Once you successfully changed your password, you can logout using the
To be able to login without a password we need an ssh key pair which we will copy to our server.
If you already have a pair of keys, you can use this key instead of creating a new one. To view all key pairs, use this command:
$ ls ~/.ssh/
If you see
id_rsa.pub, you are all set and can use those keys, the benefit of using the
id_rsa key is, that you will be able to login without specifying the key name.
To create a new public key pair use the
ssh-keygen command, if you do not have any ssh key yet, use the default name
id_rsa instead of
$ ssh-keygen -t rsa Generating public/private rsa key pair. # take care to not overwrite a key you are currently using # choose a new name that describes the keys usage Enter file in which to save the key (/Users/YOURUSERNAME/.ssh/id_rsa): /Users/YOURUSERNAME/.ssh/devserver_rsa # you can choose a strong password or leave it blank # if you enter a passphrase you will need to enter it when you log into your server Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /Users/YOURUSERNAME/.ssh/devserver_rsa. Your public key has been saved in /Users/YOURUSERNAME/.ssh/devserver_rsa. The key fingerprint is: SHA256:ptdHTSJHm8aFXjevLQy3TLCHARgstNS8wQml7M6//lI yourname@something The key's randomart image is: +---[RSA 2048]----+ | .+Bo+..... | | o.oO o++...| | +. o..B*..o| | . . +=++ .| | . S .B.+ | | o o .E. * .| | + ... . . | | o. . | | .++. | +----[SHA256]-----+
Now you need to add the key to your server. DigitOcean offers a convenient GUI when creating a server, but you can easily do this in the terminal as well. Just make sure to reference the correct
.pub file and replace
126.96.36.199 with your servers ip.
$ cat ~/.ssh/devserver_rsa.pub | ssh email@example.com "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
If you just want to print the key, to copy it to, just use the
$ cat ~/.ssh/devserver_rsa.pub ssh-rsa AAAAxchuMZERJsWrbRkzwsDeBRgbgFWfkeaEDxUjRt9pybmjXUDXdaMYuGHf+FzLukXJsIKzPmsWrbRkzwsDeBRgbg+v/ EDxUjR/mjXUDXdaMY+kzwsDeBRgbgFWfkeaEDxUjRt9pybmjXUDXfkeaEDxUjRt9pybmjXUDXdaMYuGHf/ MZERJsWrbRkzwsDeBRgbgFWfkeaEDxUjRt/rbRkzwsDeBRgbg/xchuMZERJsWrbRkzwsDeBRgbgFWfkeaEDxUjRt9 pybmjXUDXdaMYuGHfxchuMZERJsWrbRkzwsDeBRgbgFWfkeaEDxUjRt9pybmjXUDXdaMYuGHfWpn lukasoppermann@Lukass-MacBook-Pro.local
Test SSH login without password
Before we go ahead and disable the login via password we better make sure we can actually login using the SSH key. Otherwise we might permanently lock ourselves out of our own server.
- If you are connected to your server, disconnect by typing
exitand confirm with the
- Reconnect using the
sshcommand, replacing the IP with your servers IP.
$ ssh firstname.lastname@example.org
If you have used an SSH key other than
id_rsa you will need to use the following command instead, replacing the IP and
devserver_rsa with the name of your key.
$ ssh -i /Users/$(whoami)/.ssh/devserver_rsa.pub email@example.com
- You will be asked if you want to connect to the server. Confirm by typing
yesand hitting return.
The authenticity of host '188.8.131.52 (184.108.40.206)' can't be established. RSA key fingerprint is b1:4d:37:57:ca:35:4d:5f:f3:59:cd:c0:c4:48:86:11. Are you sure you want to continue connecting (yes/no)? yes
- If everything went according to plan you should now be connected.
Tip: If you are using a different key than
id_rsa you can create an
alias to make connecting easier.
# create an alias to connect with the command ssh-devserver $ alias ssh-devserver="ssh -i /Users/$(whoami)/.ssh/devserver_rsa.pub firstname.lastname@example.org"
Open a new terminal window or reload your profile to have this alias available.
Disable SSH login via password
Now that we know we can login with the SSH key we can disable SSH access via password.
This is recommended because it prevents attackers from brute forcing their way into your server, by trying random passwords.
Connect to your server and open the
$ ssh email@example.com $ sudo nano /etc/ssh/sshd_config
PermitRootLogin in the
sshd_config file to
without-password to restrict login via SSH key.
Close and save the
sshd_config file by pressing
ctrl + x, type
y and confirm with the
return key. Now you just need to reload the ssh service.
$ service ssh reload
To follow best practices it is advised that you now create a new
sudo user to use instead of the root, as root as near unlimited power and you can easily mess up your server. For brevities sake I will leave this for another article.
Setting up Ubuntus firewall UFW
First we need to allow SSH access to not lock ourselves out of our own server. Once this is allowed, we can enable the firewall and check the status.
# allow ssh access through firewall $ sudo ufw allow ssh # enable firewall $ ufw enable Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup # check firewall status $ ufw status To Action From -- ------ ---- 22 ALLOW Anywhere 22 (v6) ALLOW Anywhere (v6)
exit your server with the firewall active if the two entries above are not shown. If you can't get it to work, you can disable the firewall again using the
disable command. Check the status afterwards to make sure the firewall is actually disabled.
$ ufw disable Firewall stopped and disabled on system startup $ ufw status Status: inactive
If you are planning on using your server to host any kind of application, you will probably want to allow
https. In case you need to delete a rule, the easiest way is to used the numbered status, this way you can just use the
ufw delete command with the number of the rule you want to delete.
# allow http & https $ ufw allow http $ ufw allow https # show the numbered firewall status $ ufw status numbered Status: active To Action From -- ------ ---- [ 1] 22 ALLOW IN Anywhere [ 2] 80 ALLOW IN Anywhere [ 3] 443 ALLOW IN Anywhere [ 4] 22 (v6) ALLOW IN Anywhere (v6) [ 5] 80 (v6) ALLOW IN Anywhere (v6) [ 6] 443 (v6) ALLOW IN Anywhere (v6) # delete a rule, e.g. 6: 443 (v6) $ ufw delete 6
Setting up SFTP
First we create a new user group
sftpuser which we will use to restrict the directories accessible through sftp. Afterwards we create our first user
lukas and assign this user to the
sftpuser group. The
--ingroup flag assigns the user to the desired group and additionally prevents the creation of the default group
lukas (the username). You will be prompted to enter a password for the new user. Afterwards you may fill in some optional information about your user.
$ addgroup sftpuser Adding group 'sftpuser' (GID 1000) ... Done. $ adduser lukas --ingroup sftpuser Adding user 'lukas' ... Adding new user 'lukas' (1000) with group 'sftpuser' ... Creating home directory '/home/lukas' ... Copying files from '/etc/skel' ... Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully Changing the user information for lukas Enter the new value, or press ENTER for the default Full Name : Room Number : Work Phone : Home Phone : Other : Is the information correct? [Y/n] Y
By default Ubuntu will create a directory with the users name in the
/home directory. However we only want the user to be able to access a
files directory within an
ftp directory. For this we need to create the
files directory, change the ownership of the users home directory (
root:root and change the access rights for the
files directory to our user
$ mkdir /home/lukas/ftp $ mkdir /home/lukas/ftp/files $ chown root:root /home/lukas $ chown root:root /home/lukas/ftp $ chown lukas:sftpuser /home/lukas/ftp/files # if necessary make the folder writable $ chmod ug+rwX /home/lukas/ftp/files # check for access rights $ namei -l /home/lukas/ftp/files drwxr-xr-x root root / drwxr-xr-x root root home drwxr-xr-x root root lukas drwxr-xr-x root root ftp drwxr-xr-x lukas sftpuser files
Now we need to set the home directory for our user to
/home/lukas/ftp. You can check the home directory of another user with the
$ usermod -d /home/lukas/ftp lukas # to check a users home directory $ eval echo "~lukas" /home/lukas/ftp
The last thing we need to do is to modify the
/etc/ssh/sshd_config file. First we need to comment out the old
Subsystem line and add a new one
Subsystem sftp internal-sftp instead. This newer version is needed for the
ChrootDirectory config we will add at the end.
$ nano /etc/ssh/sshd_config # Within v: # Search for the line below, add the # to disable it and add the new Subsystem line #Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp
Afterwards add the code below to the end of the
at very end of the file file. The
Match will only activate this for users in the
sftpuser group and allow the access via sftp but only to their home directory
ChrootDirectory %h. Make sure the lines after the
Match Group sftpuser are indented to only apply those the the match.
Match Group sftpuser ChrootDirectory %h X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp
Now we just need to restart the SSH service and you should be able to connect with your new user either via an ftp tool, or the
$ service ssh restart # check if sftp access is working $ sftp firstname.lastname@example.org email@example.com`s password: Connected to 220.127.116.11. sftp> bye # check if ssh access is disabled ssh firstname.lastname@example.org email@example.com's password: This service allows sftp connections only. Connection to 18.104.22.168 closed.
SSH access should be disabled, so that the new user is an sftp only users with no
shell and no
sudo. This is for security purposes, you want to have as few users with shell access as possible and you probably do not want to grant
ssh access to the users you give an ftp access to. Always be careful with access rights.