Setting up a VPS for containerized apps

Published by Jorge on

server

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.


If you want to read more like this, subscribe to my newsletter or follow me on Twitter

    Categories: Side projects