© 2015 X2Engine Inc.

Difference between revisions of "Preparing a Linux Server Environment"

From X2Engine
Jump to: navigation, search
(Enabling Login as the Webserver User)
(Ensuring Security)
Line 91: Line 91:
  
 
== Ensuring Security ==
 
== Ensuring Security ==
The problem of brute-force logins can be circumvented by ensuring that the main method of logging into the server and transferring files is through the secure shell daemon (SSHD), and that SSHD is configured to disallow password-based logins. SSHD will then require asymmetric key pairs to log in instead of passwords, thus making brute-force password attempts a non-issue. '''If your server is an Amazon Web Services EC2 instance, this will typically be the case already; the key pair is selected/generated before instantiation and is used for accessing it.'''
+
The problem of brute-force logins can be circumvented by ensuring that the main method of logging into the server and transferring files is through the secure shell daemon (SSHD), and that SSHD is configured to disallow password-based logins. SSHD will then require asymmetric key pairs to log in instead of passwords, thus making brute-force password attempts a non-issue. '''If your server is an Amazon Web Services EC2 instance, this will typically be the case already;''' the key pair is selected/generated before instantiation as the means of accessing the server.
  
There are a multitude of ways to generate asymmetric key pairs for SSH authentication. The following method will use the standard tools that come with OpenSSH (the most widely-used SSH client/server software), and will enable SSH login as the web server user:
+
=== Configuring SSH for RSA Key Authentication ===
# Begin a shell session as the Apache user via <tt>sudo -u <apache user> -i</tt>
+
# Begin a shell session as the web server user: <pre>sudo -u <apache user> -i</pre>
# If the home directory is not set, run as root the command <
+
# Create a ".ssh" directory in the user's home: <pre>mkdir ~/.ssh</pre>
# Run <tt>ssh-keygen -t rsa</tt> and (optionally) enter a passphrase to protect the key.
+
# Ensure the directory has the proper permissions: <pre>chmod 700 ~/.ssh</pre>
# The  
+
# Run: <pre>ssh-keygen -t rsa</pre> and (optionally) enter a passphrase to protect the key.
 +
# The keypair, when done, should be in <tt>~/.ssh/id_rsa</tt> (private) and <tt>~/.ssh/id_rsa.pub</tt> (public).
 +
# Download the private key, and delete it from the server as soon as possible.
  
 +
=== Protecting ~/.ssh ===
 +
If the user's home directory is the same as (or lies within) the web server's DocumentRoot (this will usually be the case on Debian-based systems), it is generally a very good idea to prevent all HTTP access to the directory storing the public key, regardless of whether the key pair is password-protected. You can do this by adding the following lines to the main Apache configuration (for Apache versions 2.0-2.2):
 +
<syntaxhighlight lang="apache">
 +
<Directory /var/www/.ssh>
 +
Order allow,deny
 +
Deny from all
 +
</Directory>
 +
</syntaxhighlight>
 +
If using Apache 2.4 or later, you can use the non-deprecated configuration directive "Require"<ref>[http://httpd.apache.org/docs/2.4/howto/access.html Apache 2.4 Documentation: Access Control]</ref> as follows :
 +
<syntaxhighlight lang="apache">
 +
<Directory /var/www/.ssh>
 +
Require All Denied
 +
</Directory>
 +
</syntaxhighlight>
 +
 +
 +
 +
=== Disabling Password-based Authentication ===
 
To verify that password authentication is disabled, search for the directive in the SSHD configuration (which should be in the same place on almost every Linux and Unix system<ref>Assuming the ubiquitous [http://www.openssh.com/ OpenSSH] server is the software in use. All RHEL-based and Debian-based Linux systems, as well as FreeBSD, use OpenSSH as their chosen SSH server, and as of this writing none of them build OpenSSH such that the configuration path is any different.</ref>):
 
To verify that password authentication is disabled, search for the directive in the SSHD configuration (which should be in the same place on almost every Linux and Unix system<ref>Assuming the ubiquitous [http://www.openssh.com/ OpenSSH] server is the software in use. All RHEL-based and Debian-based Linux systems, as well as FreeBSD, use OpenSSH as their chosen SSH server, and as of this writing none of them build OpenSSH such that the configuration path is any different.</ref>):
 
<pre>grep '^PasswordAuthentication' /etc/ssh/sshd_config</pre>
 
<pre>grep '^PasswordAuthentication' /etc/ssh/sshd_config</pre>
 
In the output of <tt>grep</tt> you should see this:
 
In the output of <tt>grep</tt> you should see this:
 
<pre>PasswordAuthentication no</pre>
 
<pre>PasswordAuthentication no</pre>
If this is not the case, i.e. if it reads "yes" instead of "no", or the only instance of "PasswordAuthentication" is commented in the file by having its line begin with a hash symbol ("#"), edit the file <tt>/etc/ssh/sshd_config</tt> so that it contains a line that reads <tt>PasswordAuthentication no</tt>.  
+
If this is not the case, i.e. if it reads "yes" instead of "no", or the only instance of "PasswordAuthentication" is commented in the file by having its line begin with a hash symbol ("#"), edit the file <tt>/etc/ssh/sshd_config</tt> so that it contains a line that reads <tt>PasswordAuthentication no</tt> and then restart the SSH daemon to enact the changes via <tt>service ssh stop</tt> (Debian) or <tt>service sshd stop</tt> (RHEL). However, '''before doing this,''' ensure that the primary administrative user already has a key pair set up for logins; you will otherwise be locked out of your server.
  
  
  
 
<references />
 
<references />

Revision as of 22:08, 16 January 2013


Introduction

This aims to be a generic all-purpose guide for preparing a Linux system for running X2CRM, which applies both to physical servers and virtual servers, i.e. Amazon EC2 instances. It will cover two main families of Linux distributions: RHEL-based and Debian-based. RHEL-based distributions include, most notably: CentOS, Oracle Linux and Amazon Linux. Debian-based distributions include the popular Ubuntu and Ubuntu derivatives, as well as Linux Mint. It will be assumed in this guide, unless otherwise noted, that command line operations are being performed as the root user.

When installing packages, note: there may be slight differences in the names of software packages between distributions of Linux. Thus, in cases where a package name copied verbatim from this guide does not exist, the package manager's search utility should be used to determine the proper package name.

On Debian-based systems, the command is:

apt-cache search <package name> # (Debian-like)
yum search <package name> # (RHEL-like)

In each case, use parts of the full name to increase the likelihood of getting search results. Note that Debian's apt-cache search utility will accept regular expressions (if quoted properly). To search for packages on RHEL-based systems with regular expressions, search results from yum can be simply piped to grep:

yum search <package name> | grep <package regex>

Installing the Base Stack

To begin, refresh the software package database:

apt-get update # (Debian-like)
yum update # (RHEL-like)

Next install Apache, PHP and MySQL. Debian-based systems should have a utility called "tasksel" that can begin installation of all the necessary packages for a LAMP (Linux, Apache, MySQL & PHP) server in one command:

tasksel lamp-server

However, this task usually does not include the package for the PHP cURL extension, so it must be installed separately via apt-get install php5-curl

On RHEL-based systems:

yum install install mysql php-mysql php httpd php-mbstring php-curl

On many RHEL-based systems, PHP will be built without POSIX support (the compile flag '--disable-posix' should appear in the "Configure Command" section of phpinfo() ). Thus, the requirements checker script will not display the proper warning when the apache UID doesn't match the ownership of the web document root. Although it is not necessary (the next steps will ensure that this requirement is met anyway), the POSIX extension can be added if desired by installing the package php-process or php-posix (depending on the distribution and release version).

There are two more optional but useful PHP extensions: APC (caching extension) and Suhosin (PHP security). These packages should be available in most Debian-based distributions and can be installed via apt-get install php5-suhosin php-apc. In CentOS, they can be acquired by enabling the EPEL software repository and then running yum install php-suhosin php-pecl-apc.

To start the server, run:

service apache2 start # (Debian-like)
service httpd start # (RHEL-like)

Navigate to the web server's FQDN[[wikipedia:Fully qualified domain name]]: a domain name that specifies its exact location in the tree hierarchy of the Domain Name System (DNS). or IP address to verify that the web server is running.

Preparing the Environment

The default DocumentRoot of Apache Webserver on most distributions of Linux will be owned by the root user immediately after installation, whereas its default User and Group will be set to "www-data" (Debian) or "apache" (RHEL). Thus, no web application whatsoever will have write permissions to the directory it runs in (which is problematic). Thus, the first step is to ensure the ownership of the files and Apache process are the same.

Determining the DocumentRoot

This is a rather important aspect of a web server is where the files to be served are stored in the local filesystem, and will be necessary in the next steps of this process. To obtain it, search for the DocumentRoot directive in the configuration as follows:

grep -r '^ DocumentRoot' /etc/apache2/ # (Debian-like)
grep -r '^ DocumentRoot' /etc/httpd/ # (RHEL-like)

In most cases, the directive will be set to /var/www on Debian-based distributions and /var/www/html on RHEL-based ones.

Determining the Apache User/Group

On Debian-based systems, these directives are typically set to "www-data", and on RHEL-based systems, to "apache". However, if in doubt, there are at least three methods of finding out the values to which the User/Group directives set.

Direct Method

The most reliable way of finding out what they are is by searching the configuration files for the directives:

grep -r '^ *\(User\|Group\)' /etc/apache2/ # (Debian-like)
grep -r '^ *\(User\|Group\)' /etc/httpd/ # (RHEL-like)

Note that on Debian-based systems you may see that, in place of literal strings, there are references to environment variables, i.e. ${APACHE_RUN_USER}. To find their actual values, search for them in the same manner:

grep -r '^ *export *APACHE_RUN_' /etc/apache2/

Using ps

One can search for the process and see its user, if Apache is already running, using ps:

ps aux | grep '\(apache|httpd\)'

The first column of output should be the user name or id of the running process, whereas the last should be the executable file of the process. Locate the web server process (the path to the executable should be something like /usr/sbin/apache2 or /usr/sbin/httpd).

Using PHP's POSIX Library

If the POSIX library is available in PHP, you can find the UID by creating a PHP script in the DocumentRoot with the following contents and opening it in a web browser:

<?php 
echo 'UID (Server): '.posix_geteuid().'<br>';
echo 'UID (Directory owner): '.fileowner(realpath(dirname(__FILE__)));
?>

If the web server is properly set up, both of the numbers displayed should be equal.

Changing DocumentRoot Ownership

Once the UID of the webserver has been determined, change the ownership of the public web directory as follows:

chown -R <user>:<group> <DocumentRoot> # (Debian-like)
chown -R <user>:<group> <DocumentRoot> # (RHEL-like)

Use the user name or ID of the running webserver process in place of <user> and <group>, and the server's DocumentRoot in place of <DocumentRoot>.

Enabling Login as the Webserver User

To greatly ease the process of installing and maintaining X2CRM, the default Apache web user (assumed www-data in the Debian family and apache in the RHEL family, and denoted <apache user> in the general case) can also be used for logging into the server and uploading / altering files, thus avoiding all permissions issues. In many cases, the ability to log in as the web server user will be disabled for security purposes. This is mostly due to how the usernames are easy to guess in brute-force remote login attempts. See Ensuring Security for details.

Setting the Shell

In most cases, login as the user is disabled via the shell environment variable. To check that this is so, use the getent command as follows:

getent passwd <apache user>

You should see output that looks like this:

www-data:x:33:33:www-data:/var/www:/bin/false

Or:

apache:x:48:48:Apache:/var/www:/sbin/nologin

In both cases, the last field in the (colon-delinated) line indicates the login shell; /bin/false and /sbin/nologin each make it impossible to run a shell as the user. Note also that the second-to-last field is the home directory of the user. If the field is blank (i.e. there are two colons side-by-side before the login shell) it is recommended at this stage to set the home directory of the user as follows:

usermod -d <DocumentRoot> <apache user>

If that command returns the error message that the user is currently logged in, try again after shutting down the web server as follows:

service apache2 stop # (Debian-like)
service httpd stop # (RHEL-like)

Finally, to change the login shell, use chsh:

chsh <apache user> -s /bin/bash

Ensuring Security

The problem of brute-force logins can be circumvented by ensuring that the main method of logging into the server and transferring files is through the secure shell daemon (SSHD), and that SSHD is configured to disallow password-based logins. SSHD will then require asymmetric key pairs to log in instead of passwords, thus making brute-force password attempts a non-issue. If your server is an Amazon Web Services EC2 instance, this will typically be the case already; the key pair is selected/generated before instantiation as the means of accessing the server.

Configuring SSH for RSA Key Authentication

  1. Begin a shell session as the web server user:
    sudo -u <apache user> -i
  2. Create a ".ssh" directory in the user's home:
    mkdir ~/.ssh
  3. Ensure the directory has the proper permissions:
    chmod 700 ~/.ssh
  4. Run:
    ssh-keygen -t rsa
    and (optionally) enter a passphrase to protect the key.
  5. The keypair, when done, should be in ~/.ssh/id_rsa (private) and ~/.ssh/id_rsa.pub (public).
  6. Download the private key, and delete it from the server as soon as possible.

Protecting ~/.ssh

If the user's home directory is the same as (or lies within) the web server's DocumentRoot (this will usually be the case on Debian-based systems), it is generally a very good idea to prevent all HTTP access to the directory storing the public key, regardless of whether the key pair is password-protected. You can do this by adding the following lines to the main Apache configuration (for Apache versions 2.0-2.2):

<Directory /var/www/.ssh>
Order allow,deny
Deny from all
</Directory>

If using Apache 2.4 or later, you can use the non-deprecated configuration directive "Require"[1] as follows :

<Directory /var/www/.ssh>
Require All Denied
</Directory>


Disabling Password-based Authentication

To verify that password authentication is disabled, search for the directive in the SSHD configuration (which should be in the same place on almost every Linux and Unix system[2]):

grep '^PasswordAuthentication' /etc/ssh/sshd_config

In the output of grep you should see this:

PasswordAuthentication no

If this is not the case, i.e. if it reads "yes" instead of "no", or the only instance of "PasswordAuthentication" is commented in the file by having its line begin with a hash symbol ("#"), edit the file /etc/ssh/sshd_config so that it contains a line that reads PasswordAuthentication no and then restart the SSH daemon to enact the changes via service ssh stop (Debian) or service sshd stop (RHEL). However, before doing this, ensure that the primary administrative user already has a key pair set up for logins; you will otherwise be locked out of your server.


  1. Apache 2.4 Documentation: Access Control
  2. Assuming the ubiquitous OpenSSH server is the software in use. All RHEL-based and Debian-based Linux systems, as well as FreeBSD, use OpenSSH as their chosen SSH server, and as of this writing none of them build OpenSSH such that the configuration path is any different.