Tuesday, 30 December 2014

Tuning it Up and Tightening the Screws

Before we put our RasPi server live to the world, there are some further steps that we need to take to improve its overall security, and keep in mind areas where we may improve its performance.  What we have really is a vanilla install of Raspbian Wheezy, with a few extra services such as Apache 2, PHP 5 and MySQL added in, and if we connect to it with our web browser, we will see Apache's vanilla test index page.

If anyone was to attempt to hack a standard install of any system, the plan of attack that is most likely to lead to success, is to utilise what they know or reasonably expect to be true, and that which they can easily find out.  For example, most people who have any experience with Raspberry Pis will know that the default user login is 'pi', and the default password is 'raspberry'.  Fortunately we were smart enough to update the default password to one of our own choosing (You did do his?  Didn't you?). We were also smart enough to set a new password for root.  This means that we have control over both the pi account, and the root account (sudo passwd root).  We keep the root account for times only when we desperately need it.  The pi account is more of an everyday account, and it has the ability to sudo if needed.

However, whilst we can use configuration of services such as SSHd to deny permission for the root account to remote in, we want the pi account, or an account like it to be able to remote in for our administrative needs.  Since we will deny root this privileged access, the pi account becomes the greatest weakness.  The authentication of every login requires two pieces of information - the user login, and the password.  If we continue using the pi account, any potential hacker will assume that the RasPi will by standard have such account, and we would be effectively giving them one of those pieces of information, making it easier for them to utilise hacking methods such as brute-force attacks to break only the password of the account.  Therefore, our first step must be to replace the pi account, with a new user account.

Clean up User Accounts

First, we need to find out which user groups the pi login is a member of:

groups pi

Replace Pi

From this list we need to choose which groups you want the new account to be a part of, and set up the new user with the following command

sudo useradd -m -G <list of groups> -s /bin/bash replace_pi

Depending upon how you are going to use your RasPi, you may not need your new account to be part of all of them. I left out dialout (not using these protocols), cdrom (no cd drive connected – don't need to access the drivers), games and spi.  Also I did not give it root.

Next we need to remove the pi user account.  It is a little bit like an old passport.  Just because we don't use it any more, we shouldn't leave it lying around where others might be able to use it for the wrong purposes.

sudo deluser --remove-home pi

Remove Unnecessary Accounts

Remove any guest accounts, or other unnecessary accounts.  To aid in this you may like to open the following files and review the contents:

/etc/passwd
/etc/groups


I found that there were several accounts whose name signified a certain purpose, that did not fit with how I plan to use my RasPi.  These were 'games', 'lp' and 'nobody'.  For now, this RasPi will not be used to run games, nor will it be a print server, and I don't like accounts named 'guest' or 'nobody'.  Removal of these accounts requires the removal of users in each group, then the deletion of the group:

sudo deluser games
sudo groupdel games
sudo deluser lp

sudo groupdel lp
sudo deluser nobody

sudo groupdel nogroup

Consider what access you want the new account to have. If you are deploying websites to /var/www, do you want the new account to have access to write to that folder? Or, if you use Visual Studio or Dreamweaver, or a version control tool to manage such deployments, do you want/need to create another account with the specific access permissions so it can do just that job? What protocols will your deployment tools use? FTP? Does the account have the right access?


Configure SSH

Returning to our thoughts about hackers having a higher chance of success by using what they know about common services, lets change what they know.

sudo nano /etc/ssh/sshd_config

Secure Ports

Within this config file we need to make a few changes.  Lets start with the most obvious.  Every one knows that SSH connections use port 22.  But they don't have to.  Lets change the port number that SSH listens to, to another port number - say 5022.  Given that we currently have two IP addresses operational for our RasPi at the moment, we should also restrict SSH access to just one of those addresses, to limit the opportunity for discovery.

# What ports, IPs and protocols we listen for
Port 5022
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
ListenAddress 192.168.72.88


Check the Protocol

SSH has gone through a number of iterations, and the service is into it's second major release.  This second release improves upon the security of the first, and is the version we should be using.  We need to configure our daemon to make sure Protocol 2 is used.

Look for the line in the file indicating which protocol is in use.  Should appear as:

Protocol 2
# HostKeys for protocol version 2


If you are seeing this in your config, you are right to proceed with using SSH 2.

Allow Users

Within the same config file, we should also specify which users are permitted to use (remotely login) the SSH service.  To do this, add in the following lines

AllowUsers replace_pi (use a comma separated list for every user account to be allowed access)

Another appropriate measure for securing SSH is to restrict the number of concurrent connection attempts - these are attempts where a login is in progress, but not yet succeeded.  This is done through the MaxStartUps property.  This property has three values that represent start:rate:full.  The start value tells the daemon how many connection attempts to allow at once without restriction.  Think about how many users you are likely to have attempting to connect at the same time via SSH - probably not many.  By default, this value is 10.  If this is definitely too many for your circumstances, then reduce that value.  Do not set the value below 1 or you are likely to have troubles connecting.  The rate value dictates the rate of connection refusals that should occur once the number of attempted connections meets or exceeds the start value.  So in the set of values expressed below, we allow a start value of 2 attempted connections, and after the second attempt, we will automatically fail 50 percent of any further connection attempts.  The last value, the full value, tells our daemon the absolute maximum number of connection attempts that are allowed before all further connection attempts will automatically fail.  Please note - these are connection attempts only.  Once the remote user has successfully logged in, their session is authenticated, and does not count towards the number of connection attempts anymore.  By reducing these properties to values that make sense for your own situation, you are limiting the impact of brute-force and DOS attacks against the daemon.

MaxStartUps 2:50:6

Minimise Unattended Session Risk

Next we want to minimise the unattended session risk.  To do this we are going to shorten timeout settings.  ClientAliveInterval tells the daemon how many seconds after the last activity from a connected client to send the Client Alive message.  This is a system level message that polls the client for activity.  If the client system does not respond, the daemon will send another client alive message after another period the length of the interval value.  The ClientAliveCountMax value tells the daemon how many un-responded ClientAlive messages to tolerate before closing a client connection.  With the following settings below, the daemon will wait for 4 minutes (240 seconds) after the last client connection activity, poll the client, and if the poll is not responded to, close the connection.

ClientAliveInterval 240
ClientAliveCountMax 0


Block root Access

We also do not want the root account using SSH.  Check that the following line is part of the config file :

PermitRootLogin no

Warning Banner

Within the sshd_config file, there is also a line for setting a banner message through a third file. Uncomment the line '#Banner /etc/issue':


Banner /etc/issue

Banner messages can be used in a couple of ways: a legal warning or notice, a statement of purpose or a terms and conditions of use. As a legal notice or terms and conditions, you can make users aware of the ownership of the server and attempt to scare them away with the threat of legal action. A good hacker however knows that for legal action to be successful, you need to be able to identify them. The threats are not that scary. A statement of purpose might be more useful - particularly one that indicates that there is not likely to be anything important on the server. Never reveal what equipment, systems or software are available unless you are providing public access, and try not to expose private information..

A bad banner:

################################################################
# This is the home sever of Joe Bloggs. It provides FTP, WWW,  #

# and MySql services, with authentication via Active Directory.#
################################################################

This banner tells potential hackers who the owner is, which ports should be open, what types of vulnerabilities to expect based upon the services exposed, and upon the fact that this would likely be a Windows server running Active Directory.  The only details it does not offer up in plain sight is the user's passwords.

A better banner:

################################################################
# This is the server for the internal use of the Bloggs family. No files of any value or            #
# external importance are maintained within. If you are not part of our family, please         #
# cease in your actions and disconnect from this server immediately.                                      #
################################################################


Use TCPIP Wrappers and edit /etc/hosts.allow file

Another important restriction that should be applied to SSH, is where on the network/Internet will your RasPi accept connections from.  The TCPIP Wrappers work by default to allow connections from everywhere, and this will occur if you do not modify the /etc/hosts.allow file and the /etc/hosts.deny file.

In the /etc/hosts.allow file, you need to explicitly state which IP addresses, or address ranges can connect to the daemon.

sshd: 192.168.72.11     # allows one host to connect to the daemon

sshd: 192.168.72.11, 192.168.72.12     # allows two hosts to connect

sshd: 192.168.72.0     # allows any host from the specified network segment to connect



If our host IP has not been found in the hosts.allow file, the daemon will next look for it in the hosts.deny file.  If the daemon finds it here, the connection will be denied.  Edit the /etc/hosts.deny file

sshd: *     # denies access to all hosts, except those that have already been grated access in the hosts.allow file

If you do not include a line such as this in your hosts.deny file, the daemon will:
- allow all hosts it finds listed in the hosts.allow file to connect
- deny connections to all other hosts if they are listed in the hosts.deny file (so, if you list none, then any host can ssh to your Pi)
- allow connections from all hosts not already listed in the hosts.allow and hosts.deny file, by default.

Verify the Configuration

At his point, we have made some significant changes.  Before proceeding any further, we should verify the integrity of the changes we have made by running the following command from the command line:

sudo /usr/sbin/sshd -t

Clean up Apache


Finally, let's look at the apache2.conf and ports.conf files, to improve security around our web server components.

sudo nano /etc/apache2/apache2.conf

For now, just review the values in the # prefork MPM section - may assist with performance and security

sudo nano /etc/apache2/ports.conf

In the ports.conf file, you can tell Apache to only listen on port 443 by commenting our the line for listening to port 80.  This would force all incoming connections through SSL ports (443).  Depending upon what you want to do with your RasPi, this may be an option to work with at a later point in time.



Make your own Index.html

Finally, change the default index page. The default index page is an indicator of a web server that is not fully configured. Search engines will index such pages making it easy for potential hackers to find such pages.  You don't need to change much - only the text that appears.