• 10 min read
  • Preface

    As of writing, the most recent version of CentOS available is 5.6 so I will be using it as the basis for this howto. If a newer version is available, I recommend you use that version instead. Much of these instructions should still apply, especially if it is only a newer 5.x release.

    This series of tutorials will help you set up a shared hosting server using hardened CentOS 5. The server will:

    • Run hardened CentOS 5
    • Use the Apache HTTPD daemon to serve webpages (optionally with SSL) using the ITK MPM
      • Have PHP 5 installed with the gd, mhash, mcrypt and suhosin extensions
      • Use mod_evasive installed to avoid DDoS attacks and mod_security to prevent hacks
    • Use dovecot to serve email to clients over IMAP and POP (both with SSL)
      • Dovecot looks up virtual users in the MySQL database and performs the SASL authentication
      • Dovecot is responsible for delivering all mail to each user's inbox
      • Each virtual user can be mapped to a system user and group
      • Roundcubemail configured for easy web access on all email accounts
    • Use Postfix MTA to accepts mail on ports 25 and 26 (for ISPs who block port 25) as well as 465 and 587
      • Relay access is denied without prior SASL authentication (which is handled by Dovecot)
      • User administration is easy; a change in the MySQL database will affect Dovecot and Postfix simultaneously
      • All incoming mail is scanned for spam (SpamAssassin) and viruses (clamd) with amavisd-new
      • Mail is rejected with an error instead of mail notices to prevent backscatter spam
    • Allow you to host multiple websites easily
      • Email addresses & passwords are stored in a MySQL database
      • Email aliases and domain-wide aliases (forward each user and alias in one domain to another) are supported
      • Each website gets its own system user making permission control easier and limiting damage in the event of a break-in or site hack
      • Flexible SSH configuration: each system user can independently be granted full SSH addess or be jailed to their ~/web folder

    Before starting

    When writing this tutorial, I assumed that you:

    • Have installed a Red Hat-based Linux distribution (RHEL, Fedora, CentOS, etc) before
    • Have a basic knowledge of how to use the command line (how to create/edit files, executing commands)
    • Have an extensive knowledge of the various security problems you will need to deal with while adminstering the server, including:
      • Rootkits and malware
      • Intrusion detection & prevention
      • Denial of service (DoS/DDoS) attacks
      • Spam prevention and backscatter spam
    • Are familiar with editing configuration files
    • Know how to add/remove software on the system using Yum
    • Are familiar with the basics of RPM rebuilding

    Legal Disclaimer

    Please note that this guide is provided on an informal, as-is basis. Although I have done my best to research, test and secure this setup, I am not responsible for any damanges you suffer as a result of using this configuration. Remember that you need to thoroughly test any setup before implementing it on a live server!

    Installing CentOS 5

    Visit the CentOS project website and download the latest 5.x netinstall ISO image from a nearby mirror. You will be installing the bare minimum set of packages, so there is no need to spend hours downloading all 7 CDs or the large DVD - you will only need the netinstall image. However, because we will be installing from the network, please be sure to mark down a mirror URL that you wish to use for the installation from the list of CentOS mirrors. You will need to enter this mirror's hostname and the path to the CentOS RPMs later on in the installation process.

    Once you have started the installation process, choose the HTTP install method and enter the URL and path that you noted earlier. In the example below, I am using mirror.iweb.ca.
    HTTP installation method
    For more information on this process, see section 12.11 of the Red Hat Enterprise Linux installation guide, Installing via HTTP.

    When promted for choosing a disk partition layout, choose the option that best suits your needs from the drop-down menu. However, ensure that Review and modify partitioning layout is selected before clicking Next.
    Partitioning setup
    Although not strictly nescessary, it is also wise to create a separate /home partition for your user's data. Keep in mind when allocating space to partitions that by the time you have finished configuring the server, all of the user data except MySQL databases will be stored on the /home partition (MySQL databases are stored under /var/lib/mysql instead).

    After selecting the root password, you will find yourself at the package group selection step. Unselect all groups, click Customize now at the bottom of the screen and then click Next.
    Customizing the initial software to be installed
    Browse in every section and unselect all groups, including the Base group. A server is only as secure as its weakest component, and so there is no sense in running or even installing any unnessesary software that can provide hackers with potential attack vectors. By installing a smaller software set, your server will be more secure.
    Deselecting all package groups
    Now that you've unselected all package groups, hit Next again to start the installation process. After a reboot, you will be running a bare-minimum CentOS 5 system!

    Repository setup

    The first step after installation is to install a few extra repositories. These will be used to install additional packages that are not included by default in the official CentOS repositories.


    EPEL (Enterprise Packages for Enterprise Linux) is a community-run repository as a part of the Fedora Project that contains many additional packages that we will find useful during the server configuration.

    rpm -Uhv http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm

    Note: this command works at the time of writing. However, in the future the release of the epel-release RPM may change. If this command fails, please see the FedoraProject EPEL page for the most up-to-date instructions.

    CentOS test repositories

    The CentOS test repository contains packages that are on their way to CentOS Plus and/or CentOS Extras. Currently, it holds PHP 5.2 which we will use in the web server tutorial and it may contain other package upgrades that you find useful.

    wget http://dev.centos.org/centos/5/CentOS-Testing.repo -O /etc/yum.repos.d/CentOS-Testing.repo

    CentOS source repositories

    Over the course of the server setup howto series, you may need to (re)build a few RPMs. Because of this, we will need to configure the CentOS source repositories so that the original CentOS SRPM packages can be downloaded and rebuilt.

    cat << EOF > /etc/yum.repos.d/CentOS-Source.repo
    # See http://bugs.centos.org/view.php?id=1646

    name=CentOS-\$releasever - Base SRPMS

    #released updates
    name=CentOS-\$releasever - Updates SRPMS

    #additional packages that may be useful
    name=CentOS-\$releasever - Extras SRPMS

    #additional packages that extend functionality of existing packages
    name=CentOS-\$releasever - Plus SRPMS

    64-bit users only

    If you are running a x86_64 system, yum will install the x86 (32-bit) alongside the x86_64 version of any package you install. This is rather pointless, so we can start by blacklisting all 32-bit packages. To do so, add the following line to the [main] section of /etc/yum.conf:


    Then we can proceed to remove the x86 packages that are preinstalled by the CentOS installation process.

    yum remove $(rpm -qa --qf '%{NAME}.%{ARCH}\n' | grep i[3,5,6]86 | awk '{printf $1" "}')

    WARNING: DO NOT run this if you are running a 32-bit CentOS 5 system (for example i686). Accepting the removal confirmation on a x86 machine will essentially remove your entire system.

    Additional packages

    The following list of packages are either used by the tutorials or are good general-purpose/troubleshooting utilities to have:

    yum install wget yum-utils {un,}zip curl bzip2 which vim-enhanced \
        vixie-cron rng-utils quota patch nano man logwatch jwhois acpid \
        crypto-utils fedora-packager bind-utils jwhois nmap telnet traceroute \

    Also, let's replace the rather old syslog daemon with the much more modern syslog-ng:

    yum install syslog-ng
    /sbin/chkconfig syslog off
    /sbin/service syslog stop
    /sbin/chkconfig syslog-ng on
    /sbin/service syslog-ng start

    Basic firewall & SELinux configuration

    Because all groups were deselected during installation, iptables has not been installed yet. Let's install it now:

    yum install iptables iptables-ipv6 system-config-securitylevel-tui

    Next, the system security configuration utility can establish some basic firewall rules and put SELinux into permissive mode so that you may test your server setup and then configure SELinux based on the denials logged (more on that in the security & reliability guide).


    Press the Tab key twice and select Permissive from the menu, then Tab twice again to select Customize.

    Because we only want to establish the base firewall rules, do not select any exceptions (they will be added later) and just press Tab until you can choose OK. Finally, select OK again to close the configuration utility and save the system security settings. Your /etc/sysconfig/iptables file should now look something like this:

    :INPUT ACCEPT [0:0]
    :OUTPUT ACCEPT [0:0]
    :RH-Firewall-1-INPUT - [0:0]
    -A INPUT -j RH-Firewall-1-INPUT
    -A FORWARD -j RH-Firewall-1-INPUT
    -A RH-Firewall-1-INPUT -i lo -j ACCEPT
    -A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
    -A RH-Firewall-1-INPUT -p 50 -j ACCEPT
    -A RH-Firewall-1-INPUT -p 51 -j ACCEPT
    -A RH-Firewall-1-INPUT -p udp --dport 5353 -d -j ACCEPT
    -A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
    -A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
    -A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

    If you wish, you may remove the rules for corresponding to ICMP (ping among others), ports 50, 51 (VPN), 631 (shared printing via CUPS) and 5353 (Multicast DNS).

    RPM building environment

    Note that you may wish to rebuild the package in another virtual machine/test CentOS environment, as the build process will require the installation of many additional developer packages that are not required on a server machine.

    Building RPMs as root is highly discouraged, as a simple typo in the spec file could damage your system. Thus if you do not already have a normal user account created on the server you should take the time to create one now:

    useradd youruser
    passwd youruser

    Next, switch to your regular user and setup the RPM building environment:

    su - youruser
    mkdir rebuilds

    System Updates

    Before configuring any services, make sure the system is up to date:

    yum update

    Now, let's move on to the more interesting part, installing and configuring the services!