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
-
Juno Tab 3 Launches with Ubuntu 24.04
Anyone looking for a full-blown Linux tablet need look no further. Juno has released the Tab 3.
-
New KDE Slimbook Plasma Available for Preorder
Powered by an AMD Ryzen CPU, the latest KDE Slimbook laptop is powerful enough for local AI tasks.
-
Rhino Linux Announces Latest "Quick Update"
If you prefer your Linux distribution to be of the rolling type, Rhino Linux delivers a beautiful and reliable experience.
-
Plasma Desktop Will Soon Ask for Donations
The next iteration of Plasma has reached the soft feature freeze for the 6.2 version and includes a feature that could be divisive.
-
Linux Market Share Hits New High
For the first time, the Linux market share has reached a new high for desktops, and the trend looks like it will continue.
-
LibreOffice 24.8 Delivers New Features
LibreOffice is often considered the de facto standard office suite for the Linux operating system.
-
Deepin 23 Offers Wayland Support and New AI Tool
Deepin has been considered one of the most beautiful desktop operating systems for a long time and the arrival of version 23 has bolstered that reputation.
-
CachyOS Adds Support for System76's COSMIC Desktop
The August 2024 release of CachyOS includes support for the COSMIC desktop as well as some important bits for video.
-
Linux Foundation Adopts OMI to Foster Ethical LLMs
The Open Model Initiative hopes to create community LLMs that rival proprietary models but avoid restrictive licensing that limits usage.
-
Ubuntu 24.10 to Include the Latest Linux Kernel
Ubuntu users have grown accustomed to their favorite distribution shipping with a kernel that's not quite as up-to-date as other distros but that changes with 24.10.