Setting up a secure Linux server
Lock It
When you set up a new Linux server, take a few extra steps to ensure the system is truly secure.
I recently signed up for a cloud-based server system to replace my last co-located physical server, which had given up the ghost. The sign-up for the new system was painless, aside from the need to relinquish my precious credit card details, and within no more than a minute, I had a brand new Debian 8.1 "Jessie" server with a static IPv4 address.
It's relatively unusual for me to manually build boxes from scratch. However, because this Debian system is destined for service as a development server, I thought, for once, I'd take note of the steps I took to secure it.
The eclectic mixture of the following steps comprise a unique, personal-preference approach, but perhaps this summary will give you food for thought about how to secure your own servers. Start with these steps and add your own. Some of the settings you might be thinking about will be missing from this list (because the spectrum of possible security steps is simply too large to cover succinctly), but you might also find some ideas you hadn't considered.
This article shows what I did to set up a Debian Jessie server from scratch. The plan, as always, is to keep the number of packages to a minimum to help reduce security holes and reduce the need for ongoing package updates and maintenance. This article focuses on hardening a single Debian server system. Keep in mind that maintaining the overall security of your network requires many other steps, including maintaining security for routers, firewalls, intrusion prevention services, and much more.
Services
Once I had changed my DNS to point at the static IP address proffered by the cloud host, I logged into the system over SSH and immediately changed the root password to one of my liking (and which hadn't arrived over email!). A simple suggestion to the cloud provider would be, procedurally speaking, only offering the initial root password from their web interface (which uses HTTPS). Email is horribly insecure, and we're talking about a fresh server installation that is supposed to be trusted for a long time to come. To their credit, the cloud provider does encourage users to create an SSH key immediately which is the safest way of accessing SSH as opposed to passwords.
Once I logged in as "root" user over SSH, I got to work. The superuser should never be able to log in remotely over SSH without a user of less privilege to let them in through the front door first, so I shuddered at the sight of the prompt initially. I'll deal with that soon.
The first command I ran was to check that my new ISP had provisioned the size of machine correctly. I checked the RAM specifically:
# free -m
See Figure 1 for an example of the free -m
command. In my case, the command showed me under the top line of the column "used" that I had only used a remarkable 93MB of RAM to boot up my Debian instance without many running services (compare that to many, many more megabytes required by a fresh Windows installation).
Additionally, it showed me 401MB of free RAM under the "free" column, which meant I had been specified a tiny 512MB instance as expected. That's no problem for my needs when Linux is so fantastically efficient.
Next, I rapidly moved onto securing the box a little more to my liking. This next step was to shut down any services that exposed network ports to the Internet; initially, all I wanted open was my SSH server. To achieve this, I ran the following command:
# lsof -i | grep LISTEN
On the left-hand side, I saw service names (usually correlating to start/stop filenames in the /etc/init.d
directory) and on the right-hand side the network ports which they had opened. Those ports are usually listed as "service names" translated by the file /etc/services
from numbers to names.
I immediately spotted two services that weren't welcome (and potentially a security risk) and sought to shut them down. I figured out that /etc/init.d/rpcbind
was responsible for the first service so, remembering that init
was a thing of the past and this was a Systemd build, I promptly typed:
# systemctl stop rpcbind
followed by this command so rpcbind
wouldn't start up again after a reboot:
# systemctl disable rpcbind
Then, having seen that another port was open, I eventually figured out that the Systemd startup service called nfs-common
was responsible and disabled it also, simply replacing rpcbind
with that service name in the preceding commands.
If you get stuck (e.g., because you're not using Debian Jessie's version of the lsof
command but another distribution's) try tweaking the command below. It works for me on Jessie. The command searches for any listening services and outputs the name of the service along the user account responsible for spawning the service.
# lsof -i | grep LISTEN | awk '{print $1,$3}' rpcbind rpc master root sshd root httpd root httpd apache
In addition to shutting off services, you might also want to use this command to experiment with changing services to more secure user accounts. With some trial and error, you can successfully switch some of these services to non-root user accounts, which can only be a good thing for increasing your security.
Ssshhhh!
My next step was to move the SSH daemon sshd off the predictable port 22. Edit the file /etc/ssh/sshd_config
carefully, uncommenting the top line shown in Figure 2 and changing 22
to a port number of your choice like 2222
. This precaution will stop automated port 22 attacks from harassing your server.
You'll also want to prevent the root
user from logging in as we mentioned. Set the PermitRootLogin
parameter to no
:
PermitRootLogin no
Next, I'll quickly create that less-privileged user that I mentioned, but first, I'll make sure only the users I want to have permission to log in remotely. I add a line to the SSH config file (at the top of the file to remind me that I've made these changes the next time I view the file):
AllowUsers lionel, luis, neymar
Only three users can SSH into the box now. I need to make I create these accounts before logging out or restarting the OpenSSH server or I will be locked out. With a few pertinent questions, I type:
# adduser lionel
Hardening the SSH config file further is for another day (but you should definitely do it and understand what you have changed). Restart sshd
to make the changes live:
# systemctl restart ssh
To put my mind at rest, I'll do a quick check to ensure SSH is still allowing me to log in and peek at Systemd's syslog (by running journalctl -a
and looking at the last few entries) for errors. I still need to become fully familiar with the freshly released Systemd errors, but I don't see anything in the file relating to the changes I've made, so I'm happy for now.
The next step is to open up /etc/hosts.allow
and fiddle with TCP wrappers briefly by removing anything else that isn't commented and adding the IP addresses I connect from:
sshd: 11.22.33.44, 123.123.123.123, 9.8.7.6
Now only three IP addresses can log in over SSH, and the user must be one of the triumvirate's user names configured previously, such as lionel
. I then add the following line to hosts.deny
:
sshd: ALL
And, as if by magic, I'm all set. Remember not to shut your initial login window until you've tested a fresh SSH login.
Command History
I always struggle with Ctrl-R to reverse search through the command history, so I prefer to enable Page-Up and Page-Down key functionality. This change is not security related, but it helps me zip through the command line much more efficiently.
Figure 3 shows the two lines in the file /etc/inputrc
file I need to uncomment. I'll just wait for the next reboot to set it live; it's not urgent unless you've got loads of typing ahead.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.
-
Gnome OS Transitioning Toward a General-Purpose Distro
If you're looking for the perfectly vanilla take on the Gnome desktop, Gnome OS might be for you.
-
Fedora 41 Released with New Features
If you're a Fedora fan or just looking for a Linux distribution to help you migrate from Windows, Fedora 41 might be just the ticket.
-
AlmaLinux OS Kitten 10 Gives Power Users a Sneak Preview
If you're looking to kick the tires of AlmaLinux's upstream version, the developers have a purrfect solution.
-
Gnome 47.1 Released with a Few Fixes
The latest release of the Gnome desktop is all about fixing a few nagging issues and not about bringing new features into the mix.
-
System76 Unveils an Ampere-Powered Thelio Desktop
If you're looking for a new desktop system for developing autonomous driving and software-defined vehicle solutions. System76 has you covered.