Skip to main content

apache 2.2 - The A to Z of setting up a Linux box for secure local hosting

I am in the process of reinstalling the OS on a machine that will be used to host a couple of applications for our business. The applications will be local only; access from external clients will be via VPN only.



The prior setup used a hosting control panel (Plesk) for most of the admin, and I was looking at using another similar piece of software for the reinstall - but I figured I should finally learn how it all works. I can do most of the things the software would do for me, but I am unclear on the symbiosis of it all. This is all an attempt to further distance myself from the land of Configuration Programmer/Programmer, if at all possible.




I can't find a full walkthrough anywhere for what I'm looking for, so I thought I'd put up this question, and if people can help me on the way I will edit this with the answers, and document my progress/pitfalls. Hopefully someday this will help someone down the line.



The details:




  • CentOS 5.5 x86_64

  • httpd: Apache/2.2.3

  • MySQL: 5.0.77 (to be upgraded)

  • PHP: 5.1 (to be upgraded)




The requirements:




  • SECURITY!!


    • Secure file transfer

    • Secure client access (SSL Certs and CA)

    • Secure data storage


    • Secure connection to another local machine (MySQL)


  • Virtualhosts/multiple subdomains

  • Local email would be nice, but not critical



The Steps:



  • Download the latest CentOS DVD-iso (torrent worked great for me).






  • Install CentOS:
    While going through the install, I checked the Server Components option thinking I was going to be using another Plesk-like admin. In hindsight, considering I've decided to try to go my own way, this probably wasn't the best idea.





  • Basic config:
    Setup users, networking/IP address, etc. Yum update/upgrade.






  • Upgrade PHP/MySQL:
    To upgrade PHP and MySQL to the latest versions, I had to look to another repo outside CentOS. IUS looks great and I'm happy I found it!


  • Add IUS repository to our package manager



    cd /tmp
    wget http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/epel-release-1-1.ius.el5.noarch.rpm
    rpm -Uvh epel-release-1-1.ius.el5.noarch.rpm
    wget http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1-4.ius.el5.noarch.rpm
    rpm -Uvh ius-release-1-4.ius.el5.noarch.rpm
    yum list | grep -w \.ius\. # list all the packages in the IUS repository; use this to find PHP/MySQL version and libraries you want to install



    Remove old version of PHP and install newer version from IUS



    rpm -qa | grep php # to list all of the installed php packages we want to remove
    yum shell # open an interactive yum shell
    remove php-common php-mysql php-cli #remove installed PHP components
    install php53 php53-mysql php53-cli php53-common #add packages you want
    transaction solve #important!! checks for dependencies
    transaction run #important!! does the actual installation of packages.

    [control+d] #exit yum shell
    php -v
    PHP 5.3.2 (cli) (built: Apr 6 2010 18:13:45)


    Upgrade MySQL from IUS repository



    /etc/init.d/mysqld stop
    rpm -qa | grep mysql # to see installed mysql packages
    yum shell

    remove mysql mysql-server #remove installed MySQL components
    install mysql51 mysql51-server mysql51-devel
    transaction solve #important!! checks for dependencies
    transaction run #important!! does the actual installation of packages.
    [control+d] #exit yum shell
    service mysqld start

    mysql -v
    Server version: 5.1.42-ius Distributed by The IUS Community Project



    Upgrade instructions courtesy of IUS wiki: http://wiki.iuscommunity.org/Doc/ClientUsageGuide.






  • Install rssh (restricted shell) to provide scp and sftp access, without allowing ssh login


  • cd /tmp
    wget http://dag.wieers.com/rpm/packages/rssh/rssh-2.3.2-1.2.el5.rf.x86_64.rpm
    rpm -ivh rssh-2.3.2-1.2.el5.rf.x86_64.rpm

    useradd -m -d /home/dev -s /usr/bin/rssh dev
    passwd dev


    Edit /etc/rssh.conf to grant access to SFTP to rssh users.



    vi /etc/rssh.conf


    Uncomment or add:




    allowscp
    allowsftp


    This allows me to connect to the machine via SFTP protocol in Transmit (my FTP program of choice; I'm sure it's similar with other FTP applications).



    rssh instructions appropriated (with appreciation!) from http://www.cyberciti.biz/tips/linux-unix-restrict-shell-access-with-rssh.html.







  • Set up virtual interfaces


  • ifconfig eth1:1 192.168.1.3 up #start up the virtual interface
    cd /etc/sysconfig/network-scripts/
    cp ifcfg-eth1 ifcfg-eth1:1 #copy default script and match name to our virtual interface
    vi ifcfg-eth1:1 #modify eth1:1 script




    #ifcfg-eth1:1 | modify so it looks like this:
    DEVICE=eth1:1
    IPADDR=192.168.1.3
    NETMASK=255.255.255.0
    NETWORK=192.168.1.0
    ONBOOT=yes
    NAME=eth1:1




    Add more Virtual interfaces as needed by repeating. Because of the ONBOOT=yes line in the ifcfg-eth1:1 file, this interface will be brought up when the system boots, or the network starts/restarts.



    service network restart



    Shutting down interface eth0: [ OK ]
    Shutting down interface eth1: [ OK ]
    Shutting down loopback interface: [ OK ]
    Bringing up loopback interface: [ OK ]
    Bringing up interface eth0: [ OK ]
    Bringing up interface eth1: [ OK ]





    ping 192.168.1.3



    64 bytes from 192.168.1.3: icmp_seq=1 ttl=64 time=0.105 ms








  • Virtualhosts


  • In the rssh section above I added a user to use for SFTP. In this users' home directory, I created a folder called 'https'. This is where the documents for this site will live, so I need to add a virtualhost that will point to it. I will use the above virtual interface for this site (herein called dev.site.local).



    vi /etc/http/conf/httpd.conf


    Add the following to the end of httpd.conf:




      
    ServerAdmin dev@site.local
    DocumentRoot /home/dev/https
    ServerName dev.site.local
    ErrorLog /home/dev/logs/error_log
    TransferLog /home/dev/logs/access_log



    I put a dummy index.html file in the https directory just to check everything out. I tried browsing to it, and was met with permission denied errors. The logs only gave an obscure reference to what was going on:





    [Mon May 17 14:57:11 2010] [error] [client 192.168.1.100] (13)Permission denied: access to /index.html denied




    I tried chmod 777 et. al., but to no avail. Turns out, I needed to chmod+x the https directory and its' parent directories.



    chmod +x /home
    chmod +x /home/dev
    chmod +x /home/dev/https



    This solved that problem.






  • DNS


  • I'm handling DNS via our local Windows Server 2003 box. However, the CentOS documentation for BIND can be found here: http://www.centos.org/docs/5/html/Deployment_Guide-en-US/ch-bind.html







  • SSL


  • To get SSL working, I changed the following in httpd.conf:



    NameVirtualHost 192.168.1.3:443 #make sure this line is in httpd.conf 

    #change port to 443
    ServerAdmin dev@site.local

    DocumentRoot /home/dev/https
    ServerName dev.site.local
    ErrorLog /home/dev/logs/error_log
    TransferLog /home/dev/logs/access_log



    Unfortunately, I keep getting (Error code: ssl_error_rx_record_too_long) errors when trying to access a page with SSL. As JamesHannah gracefully pointed out below, I had not set up the locations of the certs in httpd.conf, and thusly was getting the page thrown at the broswer as the cert making the browser balk.



    So first, I needed to set up a CA and make certificate files. I found a great (if old) walkthrough on the process here: http://www.debian-administration.org/articles/284.




    Here are the relevant steps I took from that article:



    mkdir /home/CA
    cd /home/CA/
    mkdir newcerts private
    echo '01' > serial
    touch index.txt #this and the above command are for the database that will keep track of certs



    Create an openssl.cnf file in the /home/CA/ dir and edit it per the walkthrough linked above. (For reference, my finished openssl.cnf file looked like this: http://pastebin.com/raw.php?i=hnZDij4T)



    openssl req -new -x509 -extensions v3_ca -keyout private/cakey.pem -out cacert.pem -days 3650 -config ./openssl.cnf #this creates the cacert.pem which gets distributed and imported to the browser(s)


    Modified openssl.cnf again per walkthrough instructions.



    #generates certificate request, and key.pem which I renamed dev.key.pem.
    openssl req -sha1 -new -nodes -out dev.req.pem -config ./openssl.cnf



    Modified openssl.cnf again per walkthrough instructions.



    #create and sign certificate.
    openssl ca -out dev.cert.pem -md sha1 -config ./openssl.cnf -infiles dev.req.pem


    IMPORTANT!



    Move the files and reference them from httpd.conf in the new location




    cp dev.cert.pem /home/dev/certs/cert.pem
    cp dev.key.pem /home/certs/key.pem


    I updated httpd.conf to reflect the certs and turn SSLEngine on:



    NameVirtualHost 192.168.1.3:443 



    ServerAdmin dev@site.local
    DocumentRoot /home/dev/https
    SSLEngine on
    SSLCertificateFile /home/dev/certs/cert.pem
    SSLCertificateKeyFile /home/dev/certs/key.pem
    ServerName dev.site.local
    ErrorLog /home/dev/logs/error_log
    TransferLog /home/dev/logs/access_log




    Put the CA cert.pem in a web-accessible place, and downloaded/imported it into my browser. Now I can visit https://dev.site.local with no errors or warnings.






    And this is where I'm at. I will keep editing this as I make progress. Any tips on how to configure SSL email, and/or configuring secure connection to another Box that will be the MySQL server would be appreciated.

    Comments