Over the next few weeks, we're going to be exploring how a few of our team members set up brand-new servers of their own. These aren't meant to be tutorials, but rather fun investigations into the near-infinite ways we can accomplish the same task.
If you'd like to be featured in a future edition, feel free to let me know: [email protected].
We all have our particular setups, applications we install, and services we run to keep our servers well-organized and secure. Today, I wanted to talk about a few things I do when starting with a new server.
Updates and security
The first thing I presume we all do is run apt update && apt upgrade -y
, or a similar command for the package manager on your distro. After this, I try my luck with apt autoremove
which, gets rid of some the unwanted files and packages that I won’t need.
Notice how I didn’t mention sudo
in the above commands… that’s because when I first log in to my VPS, I’m logged in as the omnipotent root
user. What’s worse is that I’m logged in as root user
over SSH! Not good. So, my next step involves changing a few things about my server:
- Create a new user with root privileges.
- Make sure that the new user can log in over SSH using a public-private key pair.
- Make sure that root user can’t login over SSH.
- Block unnecessary ports.
The order of this checklist is essential!
1. Create a new user
All this involves is:
$ adduser USER
$ usermod -aG sudo USER
The first command creates the user named USER
, prompts me for a new UNIX password plus a few details that you can skip through. The second command adds (appends) this user to the elite sudo
group. I usually test this user by running login USER
followed by the password I selected. I test the sudo
capability by running a simple command like sudo apt update
.
Sometimes I want to use sudo
without entering the password every time. To do this, I open the sudoers file using the visudo
command (similar to the vim
editor), and append the following line at the end:
USER ALL=(ALL) NOPASSWD:ALL
Here I replace the word USER
with my actual username, of course. This is useful when I want to run automated tasks (as this user) and minimize the amount of manual (aka human) intervention. I seldom set up this passwordless sudo
capability, but it comes in handy from time to time.
2. Adding SSH keys
Next, I add my public SSH key to by editing the file ~/.ssh/authorized_keys
as the new user and append the contents of a public key from my local machine. You can learn more about SSH at our guide.
3. Making sure that root can’t log in
I perform this step only after I’ve confirmed I can SSH into my VPS as the new USER
. I also make sure this user can perform sudo
actions otherwise, I might end up locking myself out of my brand-new VPS.
I edit the sshd_config file located at /etc/ssh/sshd_configto change the
PermitRootLogin yes` line to:
…
PermitRootLogin no
…
This adds a bit of extra security, since the attacker now has to guess my username as well—no generic phrase like root
would work. Also, if sudo
privileges are protected by yet another user password, an attacker would have another hurdle before gaining total control over my VPS.
Another thing I to change inside this sshd_config
file is the permission for using clear text passwords. Using SSH keys to login should be the norm since passwords are sent as clear text over the SSH channel and can compromise server security.
I uncomment the line #PasswordAuthentication ...
and set its value to no
as shown below:
…
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
#PermitEmptyPasswords no
...
4. Enabling a firewall
This is perhaps the most diverse topic, since firewalls differ from OS to OS. However, I mostly use Ubuntu, where ufw
is easy to use and configure. I open a few important ports for SSH, HTTP, and HTTPS, and the rest stay shut:
$ sudo ufw allow ssh
$ sudo ufw allow http https
$ sudo ufw enable
I always make sure not to run ufw enable
without opening the SSH port! That’s just another opportunity for me to lock myself out of my VPS.
I’m well aware that all these security measures could be improved upon—I could even automate most of them!
Installing the essentials
The essentials that I use every day for my environment are:
- Docker
- Git
- LXC
The Docker installation is easy if you follow the official documentation or our getting started guide. It involves adding official the Docker repository to our list of trusted repositories and installing Docker from there. However, I like to create a new Docker network to use instead of the default
network Docker provides.
This uses the same bridge driver as the default
Docker network does, but is vastly easier to work with as documented here. The following command creates a new network my-network
:
$ docker network create --driver bridge my-network
Containers on this network can talk to one another freely without the user having to expose any ports. I like to run untrusted containers in a different Docker network away from any sensitive data.
Using this bridge network significantly eases the process of deployment, and my Dockerfiles stay relatively free from EXPOSE
commands. After this, I log in to my Docker Store. I use this sometimes to get a snapshot of a running container docker commit
and save it in this registry for further use as a backup or for postmortem debugging if a container keeps crashing. Admittedly, this is a dirty way of doing this, and there are better alternatives. But if it ain’t broken…
While I’m at it, I also make a point of setting up my GitHub username. This is nothing special, but it does come handy at times.
A true container hypervisor
While Docker is great, I sometimes need a container that feels like an actual isolated operating system. For this, I use LX Containers.
LXC containers come with their own subnet, DNS and you can log in to any one of them and never realize that you are in a container, unless you know where to look. The storage comes from a nice OpenZFS backbone. This means automates backups using zfs send
, super-fast and efficient compression and most importantly no chance of undetected data corruption.
You can get a glimpse of a simple LXC setup over here, and I hope you can get creative with it and get the most of out of your VPS.
What did I miss?
Hopefully, my setup inspired you to organize your VPS better. However, there’s always room for improvement. In case, you find that something in my setup can be improved upon, I would love to hear your constructive criticism. Feel free to email me at [email protected]!
A note about tutorials: We encourage our users to try out tutorials, but they aren't fully supported by our team—we can't always provide support when things go wrong. Be sure to check which OS and version it was tested with before you proceed.
If you want a fully managed experience, with dedicated support for any application you might want to run, contact us for more information.