July 8, 2018 · linux networking

Intro to Virtual Private Servers

I'm writing this reference as a guide to what is required to safely host your service on a Virtual Private Server. This is probably more of a reference for my future self rather than for anybody who stumbles upon this blog. I'm writing this because my VPS provider, OVH, is now advertising a better VPS for less money and I was in the process of switching.

The easiest part of this guide is creating the OVH account and setting up payment. For the operating system, I chose Debian 9, which is quite user-friendly IMO. This process took around an hour.

Bare Minimums

You will get an email with the IP address and password, so connect to it. When typing your password, you won't see anything appear on the screen.

$ ssh root@vps194186.vps.ovh.ca
The authenticity of host 'vps194186.vps.ovh.ca (158.69.204.181)' can't be established.
ECDSA key fingerprint is SHA256:Qq/75w7KhhpdrVyryEMsdlV5jrfat2iSKQmTbqzOI38.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'vps194186.vps.ovh.ca,158.69.204.181' (ECDSA) to the list of known hosts.
root@vps194186.vps.ovh.ca's password: 

Since there is a possibility that our password was sent in plain text over email, change the password immediately:

$ passwd
"Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully"

We don't want to continue to use the root account, so we can either enable the default debian account, or create our own user account.

Enabling the debian account:

$ passwd debian
"Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully"

Or creating your own account: (make sure to choose a very secure password!)

$ adduser yoonsik
"Adding user `yoonsik' ...
Adding new group `yoonsik' (1001) ...
Adding new user `yoonsik' (1001) with group `yoonsik' ...
Creating home directory `/home/yoonsik' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for yoonsik
Enter the new value, or press ENTER for the default
	Full Name []: Yoonsik Park
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n]"

If you created your own account, you need sudo (admin) privileges, so type:

$ usermod -aG sudo yoonsik

Next we need to update the system. Run all of the following commands in order

$ apt update
$ apt upgrade
$ apt dist-upgrade

Then we need to install a firewall. My choice of firewall is UFW (Uncomplicated Firewall). Install UFW and then allow SSH (important!) through it. Then we can enable it.

$ apt install ufw
$ ufw allow ssh
Rules updated
Rules updated (v6)
$ ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

Try logging out by typing exit and then try logging in using the other username:

$ ssh yoonsik@vps194186.vps.ovh.ca

Now that we have an account that has admin access, we need to disable allowing SSH login with root as a security precaution.

Open up the SSH configuration file and edit PermitRootLogin to no, as seen below:

$ sudo nano /etc/ssh/sshd_config

# Authentication:
#LoginGraceTime 2m
PermitRootLogin no
#StrictModes yes

Save and exit nano. Next restart the ssh server.

$ sudo service sshd restart

You can further harden the security by disabling the root account altogether:

$ sudo passwd -l root

Now that our server is secured, we can start moving on to...

Good Practices

Static Networking

If you are wanting your VPS to act as the server for a domain or subdomain, you will want to start by disabling cloud-init, an automatic service that configures a lot of settings on your Linux server, including hosts, hostnames, SSH settings etc.

Create a file to disable cloud-init:

$ sudo touch /etc/cloud/cloud-init.disabled

Next edit your hostname:

$ sudo nano /etc/hostname

server.naut.ca.

Then edit your hosts file:

$ sudo nano /etc/hosts

127.0.1.1 server.naut.ca server
127.0.0.1 localhost
...

Next, set a static IP address. From your VPS status page, you can find both the IPv4 and IPv6 addresses. I'll show you how to set up the IPv4 here. However, we first need to get the current gateway, before we set the network configuration to be static. You can find it by running:

$ ip route
default via 158.69.192.1 dev ens3 
158.69.192.1 dev ens3 scope link 

158.69.192.1 is our gateway.

Edit the network interfaces file and copy in the network configuration below. Wherever it says gateway use the gateway from above and change the address value to your IPv4 address.

$ sudo nano /etc/network/interfaces

source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback

auto ens3
iface ens3 inet static
    address 158.69.204.181
    netmask 255.255.255.255
    gateway 158.69.192.1

Finally we need to delete the auto-configured network from cloud-init earlier. Simply, sudo rm /etc/network/interfaces.d/50-cloud*. Reboot.

Reverse Hostname

Somewhere on your VPS configuration page, you should have the option to set the reverse hostname or reverse DNS configuration. Change this to the domain that you will be hosting it on, i.e. server.naut.ca

SSH using Public Key Encryption

This allows you to log in to your VPS without using a password by storing a special file on both your personal computer and the VPS. First check if you already have a SSH key on your personal computer by typing the following command

$ ls ~/.ssh/id_rsa.pub

ls: ~/.ssh/id_rsa.pub: No such file or directory

This response indicates you don't have the key. We can create a key by typing: ssh-keygen -b 4096. Next, we copy the public key to the VPS by typing ssh-copy-id yoonsik@server.naut.ca. Enter the password when it asks you to do so. Now, if you try connecting through SSH, you will find that it works without asking your password!

Finally, we can disable password SSH login. Open up the SSH configuration file on the server and edit PasswordAuthentication to no, as seen below:

$ sudo nano /etc/ssh/sshd_config

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no

Save and exit. Then reboot.

Harden Root Account Further

We can actually disable all logins to the root account, especially since we now have sudo access. The first command sets the password to an impossible hash. The second command locks the account. Run the following:

$ sudo usermod -p '!' root
$ sudo passwd -l root

Sudo without password

Run sudo visudo and edit the %sudo line near the bottom, to add NOPASSWD:

$ sudo visudo

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) NOPASSWD:ALL
...

Installing Development Tools

This will install things like compilers and make tools.

$ sudo apt-get install build-essential checkinstall autotools-dev autoconf

Nice to Have

Faster Reboots

I hate having to wait for my server to reboot, so I changed the default GRUB bootloader delay from 5 seconds to 1 second:

$ sudo nano /etc/default/grub

GRUB_DEFAULT=0
GRUB_TIMEOUT=1
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""

Then update the GRUB bootloader.

$ sudo update-grub

Update Script

I have a script that I run semi-regularly. It updates and upgrades the software on my system.

sudo apt update
sudo apt upgrade -y
sudo npm i -g ghost-cli@latest
cd /var/www/ghost
cp -r ./content ~/backups/ghost/

TO BE CONTINUED ...