My server setup: Ranvir Singh and Linux containers
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_config
to change thePermitRootLogin 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!
How do you set up your server?
Installing the essentials
The essentials that I use every day for my environment are:
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
$ 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 ran[email protected]!