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
-
TUXEDO Computers Unveils Linux Laptop Featuring AMD Ryzen CPU
This latest release is the first laptop to include the new CPU from Ryzen and Linux preinstalled.
-
XZ Gets the All-Clear
The back door xz vulnerability has been officially reverted for Fedora 40 and versions 38 and 39 were never affected.
-
Canonical Collaborates with Qualcomm on New Venture
This new joint effort is geared toward bringing Ubuntu and Ubuntu Core to Qualcomm-powered devices.
-
Kodi 21.0 Open-Source Entertainment Hub Released
After a year of development, the award-winning Kodi cross-platform, media center software is now available with many new additions and improvements.
-
Linux Usage Increases in Two Key Areas
If market share is your thing, you'll be happy to know that Linux is on the rise in two areas that, if they keep climbing, could have serious meaning for Linux's future.
-
Vulnerability Discovered in xz Libraries
An urgent alert for Fedora 40 has been posted and users should pay attention.
-
Canonical Bumps LTS Support to 12 years
If you're worried that your Ubuntu LTS release won't be supported long enough to last, Canonical has a surprise for you in the form of 12 years of security coverage.
-
Fedora 40 Beta Released Soon
With the official release of Fedora 40 coming in April, it's almost time to download the beta and see what's new.
-
New Pentesting Distribution to Compete with Kali Linux
SnoopGod is now available for your testing needs
-
Juno Computers Launches Another Linux Laptop
If you're looking for a powerhouse laptop that runs Ubuntu, the Juno Computers Neptune 17 v6 should be on your radar.