Setup and Secure a Linux Server

data center

A step-by-step tutorial to setup and secure a Linux Virtual Private Server for use with Apache, MySQL, and PHP to host a personal or professional website. The end goal will be to have a fully customizable LAMP (Linux, Apache, MySQL, and PHP) server, which will provide fully controllable WordPress site. When trying to setup and secure a Linux server, the command may be a bit different depending on your distribution. For example, Debian based distributions utilize apt to install packages, but Red Hat distributions utilize yum. However, these same steps can be applied to just secure your server for any purpose after the initial package installation. I will go into more details on what you need for a blog or other LAMP application in subsequent posts.

Initial Setup for Securing A Linux Server

The first step in your initial setup is securely logging into your linux server. You should have received login credentials from your server provider. Open a terminal window in Mac or Linux. If you are using a Windows computer, then you will need to download a small terminal program called Putty (https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html)
If you did not get assigned a root login from your hosting provider, then you will need to login with the elevated account and password they gave you.

SSH into server

ssh username@serverIP

Example:

ssh dragonslayer@192.168.1.1

The username will be the one assigned to you by our provider and the server IP will be the IP address assigned to your server.

Set root password

If you don’t have a root password, then you will need to create one utilizing the sudo command. Sudo is short for Super User DO.

sudo passwd root

Enter the new password for root

Keep in mind that you should not login as the root user unless you absolutely have to. The root user can execute any command without regard to consequences. Linux assumes that if you login as the root user that you know enough not completely ruin your system. There are no “are you sure” like you find on Windows or Mac machines. You’ve been warned.

login as root using

su -

Enter new password

The only reason we logged in as root right now was so we can fully execute the update and upgrade commands, and so we can install the necessary software needed to get our WordPress installation off the ground without issues. You may be able to do all of this using the sudo command, but in my experience, this doesn’t always work depending on your hosting provider.

Update Server Software

apt-get update && apt-get upgrade -y

If this is new to you then I will explain it briefly. The apt command is short for aptitude which is the command used in Debian based (think Debian, Ubuntu, Kali, Mint, and similar Linux distributions) which calls to a repository so you can check for updates or install new software. The update command updates the current packages, and the upgrade allows you to upgrade the system. The -y switch is a quicker way to avoid the “this update/upgrade will take up XX MB of storage space. Do you want to continue?”

Back to the show. This should go quickly since we haven’t installed any new software yet.

Now that we have the root password established and we’ve ran an update and upgrade on the server, we are ready to begin securing the server to help prevent automated attacks and scans from finding open ports and logins.

The first thing that needs to be done is change the default SSH port to something other than port 22. Most of your automated scanners will assume the port is 22 and just probe to see if it is open to the outside internet. The best thing to do is change the port number to a high number between 35000 and 65535 (max number of ports). To do that we need to change the SSH configuration file.

While logged in as root, use a command line editor like nano or vim to access the file. Nano and vim should already be loaded onto your server. A lot people like to use vim because of how robust it is, but I can never seem to remember the right key strokes to save and exit the app. So I just use nano because it tells you how to exit the app.

Configure SSH Sessions

nano /etc/ssh/sshd_config

You will usually see the line #Port 22 near the top of the config file. In order for you to use a custom port number, you will need to remove the comment tag “#” (octothorpe) and change the port number to something really high. Be sure you don’t use any ports from 1-1024 as these are known as common ports typically used. The last thing you want is to have a port open that is reserved for something else. This is why I say pick a port way outside of the range. Be sure to document your chosen port in your password manager. The last thing you need is lose access to your server because you can’t remember the port number assigned to SSH.

Disable Root Login

One more thing to think about while we are in the sshd_config file is the PermitRootLogin option. Some service providers don’t allow this by default, but some may not take the steps to remove this from the config file. After changing the port number, let’s take a stroll down the config file to see if there is an option to PermitRootLogin. You may see it listed as:

PermitRootLogin yes -- This means the server does allow root login
#PermitRootLogin yes -- This means the server does allow root login, but it has been disabled
PermitRootLogin no -- This means the server does not allow root login

Also, if your provider is like mine, then they have removed this line from the config file altogether and you don’t need to worry about it. If they gave you a root login and password, then you know for certain root logins are permitted.

After you have changed your SSH port to something other than 22 and greater than 35000, then you will need to restart the SSH service for the changes to take effect. Oh, before you close out of nano you need to save and exit. To do this hold down the control key and press X. For a Mac, the control key has the ^ symbol on it. Press “Y” for yes and then ‘enter’ key to confirm saving the file name. DO NOT CHANGE THE FILE NAME!!

Restart SSH and Login

Now we can restart the SSH service by typing the following:

systemctl restart sshd

This command is the system control, action, and service to restart. We will use this many times to restart certain services, so it will become second nature to you.

Don’t worry about restarting the service. It won’t log you out and make you log back in. However, the next time you login be sure to use -p [port number] switch to ensure you tell ssh to connect to the right port.

ssh username@serverIP -p 12345

This command tells the terminal to start an SSH connection, your username, at the server IP address, using port [12345] (whatever port you selected). You will need to use this same layout each time you connect to your server. Otherwise, you will get a connection rejected.

If your hosting provider sent you a root login and password, then you will need to be sure to add a non-root level user to conduct general server maintenance. My provider has already given me an elevated user account, but I will create another to walk you through the process. Type the command

adduser CustomUsername

If you’re not root, then you will need to use the sudo command

sudo adduser CustomUsername

Once you create a new user, you need to assign a password to it.

sudo passwd CustomUsername

Type in a custom password and press the enter key to set it.


Secure The Server

Firewall

Alright…Here comes the fun part of the securing process…setting up your firewall using IP Tables. IP Tables is the standard installation firewall for your linux server. A firewall allows you to set what traffic you want to reach your server and what traffic will be blocked or dropped. If you ever decide to take the time to go back and look at your server logs you will see how much traffic actually hits your server. You will have a constant barrage of web crawlers, sniffers, scanners, automated attacks, and many other bots seeing what you are made of. So, let’s make it harder for them to find us and see what we have, shall we?

IP Tables

The first thing we are going to do is list out what rules IP Tables has. If you have just started setting up your server, then you won’t see anything. Type this into your command line:

iptables -L

This command tells IP tables to list your current firewall rules.

If by chance you don’t have IP tables installed, then enter the command:

sudo apt-get install iptables

If you are logged in as root just remove the sudo command.

Like any other linux command there is a series of commands and switches needed to tell the software what you want it to do. Typically, you will see an iptables command look like this:

sudo iptables [option] CHAIN_rule [-j [target]

The words with the [] will be replaced with actual commands. Don’t worry, I will show you how this works and what it looks like.

To see a list of help options for iptables use the command

iptables --help

Sometimes these can be confusing to read and use, so how about I walk you through this nastiness? Let’s go…

WARNING!! WARNING!! YOU MUST DO THESE STEPS IN ORDER!! OTHERWISE, YOU COULD LOSE ACCESS TO YOUR SERVER AND HAVE TO REIMAGE AND START OVER

Our primary goal for our website is to allow traffic to find our web server and our website. However, we need to allow local traffic to traverse outside of the firewall.

Set Rules

sudo iptables -A INPUT -i lo -j ACCEPT

This command configures the firewall to accept traffic for the local host (lo) on interface (-i). From now on, everything that comes from your system will pass through your firewall. You must add this rule to allow applications to communicate with the localhost interface. (There are more than you think)

Now that we have taken care of the localhost traffic, we need to address the traffic coming from the internet. Keep in mind that we do want some traffic to find its way to the server. This is what allows us the opportunity to show off our website and our skills to the rest of the world. Since we are setting up a WordPress site here, we need to allow your typical HTTP traffic and secure HTTP traffic. Also, we can’t forget to allow our SSH traffic to get through as well. If we block our SSH traffic, then we can’t get command line access to the server for updates and maintenance.

First let’s be sure to allow our SSH traffic to get through. Truth be told this is the most important because we don’t want to be forced to wipe our server and start again.

Set SSH Port

sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Okay, so what have we done here? Seriously, I’m asking you here…help me out. It looks like we have sent a command to iptables to allow all (-A) INPUT traffic using protocol (-p) tcp with a destination port (–dport) of 22. The -j command is an action to ACCEPT command telling the firewall to accept all traffic for port 22. If you have been following along with me, then you know our –dport should be set to something greater than 35000. We should have something like:

sudo iptables -A INPUT -p tcp --dport 38980 -j ACCEPT

(You must enter your own port number after –dport.)

Setting IP Ranges For A port

The next step to setup and secure your linux server is to change the SSH port to only allow traffic from specific IP addresses or IP ranges. A primary concern with administering your server from your home IP address is you risk the chance that your IP address could change over time. If you decide to do this, then you should allow at least allow all traffic on your selected subnet. That is all traffic from an IP range of 256 addresses. If your IP address changes, then chances are you will fall within this specific IP range. Here is what the command would look like.

sudo iptables -A INPUT -p tcp --dport 38980 -m iprange --src-range 192.168.1.0/24 -j ACCEPT

You will notice I added extra commands “-m –src-range 192.168.1.0/24”. What this does is allow source IP addresses in the range of 192.168.1.0-192.168.1.255. That way if my IP address changes, I can still access my server. For mine, I have allowed my home IP range and those of certain VPN servers I use.

Allow Web Server Traffic

The next thing to do is allow both unencrypted and encrypted web traffic. Once we install our SSL certificate, we will route unencrypted traffic to our encrypted protocol. More on that later.

Our unencrypted HTTP traffic is transferred over port 80 for web servers. This is the typical port used for a website, but we could change that and have it forward to a different port. Generally, you don’t need to do that unless it’s for a really unique situation. Put the following command into your terminal.

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

While unencrypted web traffic goes through port 80, our encrypted web traffic will go through port 443. In today’s internet realm we alway want to ensure our traffic is encrypted because we don’t want someone sniffing our traffic or the traffic of our visitors. Therefore, we will ensure port 443 is able to get through the firewall.

Blocking IP Addresses

We can take things a bit farther and only limit traffic to our server from an IP address or a range of IP addresses. For a personal web server, you want to allow all IP address ranges unless you have a reason to block an IP or a range of IP’s.

For example, let’s look at an iptables command to block a known malicious IP address attacking your server.

sudo iptables -A INPUT -s your_IP_address_to_block -j DROP

The new switch command you see here is -s. This switch is a shortcut for the source command identifying the source IP address of you known threat.

Allow Outboud Traffic

Before we block all unneccesary traffic we need to allow outbound connections so we can get updates for our system. The easiest way to do this is to assume all outbound traffic is not malicious. I know this will raise some concerns among the security community, but for the purposes of getting things up and running will will make assumptions. Once we get our server installed and configured, we will revisit the iptables to block all outbound traffic except what is needed for software updates and other required services.

iptables -A INPUT -j ACCEPT -i lo
iptables -A INPUT -j ACCEPT -m state --state RELATED,ESTABLISHED

We have talked about the first line for the loopback address, but I will show it again as it is usually put in with the established connection rule. The second rule basically says all current established traffic will get through, but nothing else.

Block Remaining Traffic

The next command is one that will cause you to lose access to your server if you did not do the above steps correctly. What we will do now is essentially block all traffic except traffic to our SSH port, port 80, and port 443. Doing this will help our server from being overloaded with port scan requests and can help us stay more secure by filtering our unwanted traffic. Keep in mind that once you enter this next command in it will likely sever your connection to your server. You will need to log in again, but this time you will set your SSH command to the SSH port you opened in the firewall.

sudo iptables -A INPUT -j DROP

After you log back into your server we want to see what iptables has listed for our rules.

List Rules with Line Numbers

iptables -L --line-numbers

Here’s what you can expect it to look like…similar.

The one caveat about iptables is the rules are only valid until you restart. We need to ensure our iptables rules are persistently kept through reboots of the system. Let’s save the tables using this command:

Save Rules For Persistance

sudo -s iptables-save -c

The next time your system reboots, iptables will automatically load the firewall rules.

The firewall rules we went over here are only a few of what iptables can do. As we progress through our server setup, we will revisit iptables to add and remove additional rules.

Before we move onto the next subject you need to know how to remove rules input into iptables.

If something happens that you are having traffic blocked on all fronts, then you will want to perform an iptables flush which will delete all rules in your iptables.

Flush All Rules or Delete A Single Line

sudo iptables -F

Additionally, if you only want to delete a particular rule, then you’d enter:

sudo iptables -D INPUT Rule_Number_to_Delete

Intrusion Prevention System

Install fail2ban intrusion prevention software

Fail2ban is an opensource intrusion prevention software framework written in Python designed to block IP addresses from which bots or attackers try to penetrate your system. This software package is recommended, even essential in some cases, to guard your server against “Brute Force” or “Denial of Service” attacks.

Fail2ban works by monitoring the log files like /var/log/auth.log and bans IP addresses conducting too many failed login attempts. It does this by updating the system firewall rules to reject new connections from those IP addresses.

For a full write-up that describes fail2ban and how it really works, please go to : https://linuxhandbook.com/fail2ban-basic/

To install the software package, use the following command:

Install Fail2Ban

sudo apt-get install fail2ban

You can customize Fail2Ban configuration files to protect services that are exposed publicly and susceptible to repeated attacks.

Create a local copy of the jail.conf file. Creating a .local file of jail.conf will allow you to customize fail2ban for your specific application. Also, any changes you make to the jail.conf file will most likely be overwritten in an update, so we need a local file for the customization, if any.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

This command takes the original config file jail.conf and copies it to the same directory with a .local extension. This will allow you to know the difference.

Since fail2ban works great as soon as it’s installed, I’m not going to go into details right now on how to customize it. Let’s get our web server up and going, then in a later post I will go through some customizations.

The first thing we need to do is start and enable fail2ban so it will be defending our server from attacks.

Start Fail2Ban

sudo systemctl start fail2ban
sudo systemctl enable fail2ban

Hopefully, this will guide has been fairly easy to follow and you were able to execute the commands without any issues. If for some reason you have been locked out of your server, then you can use your hosting providers online portal to access your machine. Since these were the first steps in the server setup, you can just reinstall the server and start over. It’s not the best option because it is a lot of work, but it is necessary. I’ve had to reinstall many servers before I finally did it right.

Next, learn How To Install WordPress on your new Debian server.

Tagged with:

3 Comments

Add Comment

Leave a Reply

Your email address will not be published. Required fields are marked *