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 ...