Setting up a VPS for containerized apps
Recently I’ve been setting up a new VPS for hosting dockerized web apps behind an nginx proxy. The goal is to have an nginx reverse proxy for serving the different web applications on the same server.
Setting up the VPS
When purchasing a VPS, you get an option to select a preinstalled distribution, if not, you just have to install a distribution yourself. I’m using Ubuntu because is the most popular and suits the task. I suggest using LTS versions to avoid the hassle of bugs, vulnerabilities and constant updates. After you have your distribution ready to use, ssh to the server and start to set it up.
Security recommendations
Attackers are lazy and they try the easiest way. Our goal is to make them more difficult to attack us than our neighbors so they won’t bother with us. That’s basically security 101.
WARNING: If you fail doing some of the next steps is possible that you need to reinstall the VPS and lose everything.
Update packages to latest version
It’s very important to keep the server packages up to date to fix discovered vulnerabilities. First upgrade all packages and remember to do so periodically.
$ sudo apt update && sudo apt upgrade
Use a non standard user
I suggest to create a different user if you have a preconfigured one or if you just have root and give it sudo access. Preconfigured users are known by attackers and they will try to login using that username.
# create new user $ sudo adduser vpsuser # add user to sudoers $ sudo usermod -aG sudo vpsuser
Try to login as the new user and perform a check that user is in sudoers group.
$ id vpsuser
uid=1001(vpsuser) gid=1001(vpsuser) groups=1001(vpsuser),27(sudo)
Disable root login
A basic security practice is to lock root user so no one can login as root. As we now have sudo access with our new user, we can lock root login in case it’s available.
$ sudo passwd -l root
To use root you can use su
from your user like this:
$ sudo su -
In case you want to enable password again you can do it like this:
$ sudo passwd
Configure a different ssh port
Another good security practice is to change the ssh port to a different one, so attackers need to try all ports before being able to attack. Just avoid selecting any reserved port that could conflict in the future with others that you need.
Edit the sshd_config
file and replace the value in the line containing Port 22
to Port 22123
$ nano /etc/ssh/sshd_config
Now you can restart the ssh server and check the port is properly changed.
$ service sshd restart
# Check that the port has change correctly
$ netstat -tlp | grep ssh
Use ssh keys and disable password login
It’s also recommended to disable password login with your user and use ssh keys. For that you need to create a ssh key in your client machine and set up the public key in the server.
For this you need to create .ssh
folder at /home/vpsuser/.ssh
and the authorized_keys
file with proper permissions.
$ mkdir ~./ssh && chmod 700 ~./ssh
$ touch ~./ssh/authorized_keys && chmod 600 ~./ssh/authorized_keys
# Edit the file and paste the authorized key
$ nano ~/.ssh/authorized_keys
Now try to enter using the ssh key to the VPS. If everything went fine, then you can disable password login to your vpsuser
.
WARNING: If you ever lose your ssh key you won’t be able to enter your VPS and you would have to reinstall and lose everything. It’s recommended to have multiple ssh keys authorized and kept in different places or backing up your ssh key.
# open ssh configuration $ nano/etc/ssh/sshd_config
# Disable password login inserting the following entry $PasswordAuthentication no
# Restart ssh service $sudo service ssh reload
There are dozens of security recommendations and practices that you can do besides these ones. But I think for most this is a quick “good enough” starting point.
Optional steps
There are other steps that are useful to do but not mandatory.
Set your own machine name
This is optional but in case you have a strange machine name I like to put my own machine name (i.e. myvps
) to not be confused when using multiple ssh sessions.
$ sudo hostnamectl set-hostname myvps
Some times hostname is also mapped to 127.0.0.1. If so, update /etc/hosts
and replace the old hostname with the new one.
Use a custom domain or subdomain for your VPS
You can use a subdomain of any of your domains to point to the VPS so you don’t have to remember its IP address or the complex domain the provider gives to you.
You just need to set a DNS A record in your domain provider DNS settings containing the VPS IP address.
Configure your timezone
Probably your VPS won’t be in the same timezone than you are. You can easily change that.
# List all available timezones $ timedatectl list-timezones # Set the desired timezone $ sudo timedatectl set-timezone Europe/Madrid
Periodic reboot
Create a weekly cronjob creating a file sudo vim /etc/cron.weekly/reboot
and give it execution access sudo chmod +x /etc/cron.weekly/reboot
.
#!/bin/sh shutdown -r now
Configure your ssh client for easy access
It’s also useful to configure you ssh client to remember your connection details. If you use Linux, you can create ~/.ssh/config
file and store the connection information.
Host yourvps HostName yourvps.example.com User vpsuser Port 22123
So now you can just do ssh yourvps
and you’re in.
Closing
So now you have your VPS prepared following some security recommendations that should be enough for most common cases. Now what I’d do is to configure my user with my own stuff. Setting up git, vim, aliases, etc. I have a dotfiles repository with a script that auto-configures the stuff I usually set up for convenience. I suggest you to do it also.
The next step is to install the required packages, setting up the reverse proxy and start deploying containerized webapps. We’ll see that in the next chapter.