ApacheLAMP 2017Linux

Apache HTTP Server – Building a LAMP Server

This is the fifth article in a series on building the ultimate LAMP Server. This covers installing Apache HTTP Server from source. Even for distros which maintain current versions, the Apache Software Foundation recommends compiling HTTP Server from source.

Estimated time (this post only): 10 minutes
* varies slightly by distro

Apache Prerequisites

You may already have most of the packages installed that you need if you’ve been following this series of posts, but run the following anyway to make sure you have absolutely everything for Apache HTTP Server:

CentOSFedoraUbuntu/DebianopenSUSEArch Linux
sudo yum install make gcc wget tar nano gcc-c++ gnupg expat-devel lynx
sudo dnf install make gcc wget tar nano gcc-c++ gnupg expat-devel lynx
sudo apt-get install make gcc wget tar nano g++ gnupg libexpat-dev lynx
sudo zypper install make gcc wget tar nano gcc-c++ gpg2 libexpat-devel lynx
sudo pacman -S make wget tar nano gcc gnupg expat lynx

PCRE

Although your distro probably already has PCRE installed, the Apache website recommends compiling the most recent version for use with HTTP Server. Apache requires the latest version of the original PCRE library and not PCRE2. Since development on PCRE has stopped, the following steps should ensure you have the latest version (many distros ship with older versions that contained bugs, so this is important).

cd ~
wget https://ftp.pcre.org/pub/pcre/pcre-8.41.tar.gz
wget https://ftp.pcre.org/pub/pcre/pcre-8.41.tar.gz.sig
wget https://ftp.pcre.org/pub/pcre/Public-Key
gpg --import Public-Key
gpg --verify pcre-8.41.tar.gz.sig pcre-8.41.tar.gz

The GPG commands will ensure the download matches the signature. If you don’t see "Good signature" in the output, then you have a corrupted download and should run the commands again. Now extract the archive, compile, and install:

tar zxvf pcre-8.41.tar.gz
mkdir pcre-8.41-bld
cd pcre-8.41-bld
cd pcre-8.41-bld
../pcre-8.41/configure --prefix=/opt/pcre
make
make test

Assuming all tests passed, you can continue:

sudo env "PATH=$PATH" make install
cd ..
rm Public-Key
sudo mv pcre-*-bld /usr/local/src/
rm -rf pcre-*

OpenSSL

Due to security issues and bugs, I highly recommend compiling OpenSSL from source rather than relying on the version that comes with your distro. For example: as of this writing, the LTS (long-term support) branch is 1.0.2, which is at version 1.0.2m. But CentOS only offers 1.0.2k, which contains several bugs. See the OpenSSL website for current version information. For this example I will be installing the current LTS version (change version number if necessary).

cd ~
wget https://www.openssl.org/source/openssl-1.0.2m.tar.gz
tar zxvf openssl-1.0.2m.tar.gz
cd openssl-1.0.2m
CC="gcc -fPIC" ./config --prefix=/opt/openssl --openssldir=/opt/openssl
make
make test

Assuming all tests passed, you can continue:

sudo env "PATH=$PATH" make install
cd ..
rm openssl-*.tar*
sudo mv openssl-* /usr/local/src/
export PATH=/opt/openssl/bin:$PATH
echo 'PATH=/opt/openssl/bin:$PATH' | sudo tee -a /etc/profile.d/openssl.sh

Important: if you did not compile Perl from source as recommended in the last post, the installation may fail. To overcome this, either compile Perl from source or install perl-podlators via your package manager.


Download Apache Files

You can make this process a lot faster if you use a browser on a desktop system to download the files and transfer them via SFTP to your LAMP server. This is easily done via Bitvise or other SFTP clients. Below I will cover the slightly more complicated method (caused so because of how Apache mirrors are linked to on their website).

First, visit this page to find your closest Apache mirror. Copy/paste the site address somewhere or write it down. Then find the latest stable version number at the HTTP Server Project page. Lastly, find the latest versions of APR and APR-utils and copy this information as well.

In the following example, the Apache mirror it found for me was "http://apache.mirrors.ionfish.org/" so replace that string and the version numbers with whatever you found.

cd ~
URL="http://apache.mirrors.ionfish.org/"
wget ${URL}httpd/httpd-2.4.29.tar.gz
wget apache.org/dist/httpd/httpd-2.4.29.tar.gz.asc
wget ${URL}apr/apr-1.6.3.tar.gz
wget apache.org/dist/apr/apr-1.6.3.tar.gz.asc
wget ${URL}apr/apr-util-1.6.1.tar.gz
wget apache.org/dist/apr/apr-util-1.6.1.tar.gz.asc
wget apache.org/dist/httpd/KEYS

Now, type the following commands to verify those downloads, editing for the proper version numbers as needed:

gpg --import KEYS
gpg --verify httpd-2.4.29.tar.gz.asc
gpg --verify apr-1.6.3.tar.gz.asc
gpg --verify apr-util-1.6.1.tar.gz.asc

If each check contains the text "Good signature" then the downloads are good. If there were problems, try a different Apache mirror.

Now that we’ve verified the downloads, extract them (edit commands as necessary):

tar -zxvf httpd-2.4.29.tar.gz
tar -zxvf apr-1.6.3.tar.gz
mv apr-1.6.3 httpd-2.4.29/srclib/apr
tar -zxvf apr-util-1.6.1.tar.gz
mv apr-util-1.6.1 httpd-2.4.29/srclib/apr-util
mkdir httpd-2.4.29-bld
cd httpd-2.4.29-bld

Build and Install

Now configure the source tree, build, and install. Below is the syntax I used but you may want to alter some options. See the Apache documentation for more options.

../httpd-2.4.29/configure --prefix=/opt/apache --with-included-apr \
--enable-so --with-pcre=/opt/pcre --with-ssl=/opt/openssl --enable-ssl
make
sudo env "PATH=$PATH" make install

Do some cleanup:

cd ..
sudo mv httpd-*-bld /usr/local/src/
rm KEYS
rm -rf httpd-*
rm apr-*

Let’s start it up and make sure it works:

sudo /opt/apache/bin/apachectl -k start
lynx http://localhost

Ignore the error about the lack of a FQDN for now. If everything worked you should see the words "It works!" at the top of the screen. Then exit Lynx with q.


Configure Apache

CentOS/FedoraUbuntu/Debian/openSUSE/Arch Linux

Set Apache to start automatically on boot:

sudo /opt/apache/bin/apachectl -k stop
sudo touch /etc/init.d/apache2
sudo chmod 755 /etc/init.d/apache2
sudo nano /etc/init.d/apache2

In this new file, add the following:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          apache2
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: apache2
# Description:       httpd server for serving web content
### END INIT INFO

case "$1" in
start)
        echo "Starting Apache ..."
        # Change the location to your specific location
        /opt/apache/bin/apachectl -k start
;;
stop)
        echo "Stopping Apache ..."
        # Change the location to your specific location
        /opt/apache/bin/apachectl -k stop
;;
graceful)
        echo "Restarting Apache gracefully..."
        # Change the location to your specific location
        /opt/apache/bin/apachectl -k graceful
;;
restart)
        echo "Restarting Apache ..."
        # Change the location to your specific location
        /opt/apache/bin/apachectl -k restart
;;
*)
        echo "Usage: '$0' {start|stop|restart|graceful}"
        exit 64
;;
esac
exit 0

Save and exit. Then:

sudo chkconfig --add apache2

Apache should load at startup now. You can also easily start/stop/restart it with:

sudo service apache2 start
sudo service apache2 stop
sudo service apache2 restart

Set Apache to start automatically on boot:

sudo /opt/apache/bin/apachectl -k stop
sudo touch /etc/systemd/system/apache2.service
sudo chmod 664 /etc/systemd/system/apache2.service
sudo nano /etc/systemd/system/apache2.service

In this new file, add the following:

[Unit]
Description=httpd server for serving web content
After=network.target

[Service]
Type=forking
Restart=yes
EnvironmentFile=/opt/apache/bin/envvars
ExecStart=/opt/apache/bin/apachectl -k start
ExecStop=/opt/apache/bin/apachectl -k stop
ExecReload=/opt/apache/bin/apachectl -k graceful
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

The restart option can cause problems if you don’t properly shut down Apache with systemctl (see below) before upgrading Apache later, but it helps ensure Apache will restart if it encounters a problem. Save and exit. Then:

sudo systemctl daemon-reload
sudo systemctl enable apache2.service

Apache should load at startup now. You can also easily start/stop/restart it with:

sudo systemctl start apache2.service
sudo systemctl stop apache2.service
sudo systemctl restart apache2.service

Let’s get rid of that annoying error message now…

sudo nano /opt/apache/conf/httpd.conf

Go down and un-comment/edit the line that begins with "#ServerName" so it says something like:

ServerName lamp.localdomain:80

Change the above to match whatever FQDN you gave the system during install (or just use the static IP address). While you are in here you may also want to un-comment any needed modules. Common modules you may need include "mod_cgi" and "mod_rewrite" (Ctrl-W comes in handy here). We will cover the SSL stuff in a minute.

After saving and exiting nano, do the following to ensure you don’t get the FQDN error anymore:

CentOS/FedoraUbuntu/Debian/openSUSE/Arch Linux
sudo service apache2 restart
sudo systemctl restart apache2.service

Setup SSL

Now set up SSL if desired. You need to edit the configuration file again:

sudo nano /opt/apache/conf/httpd.conf

Find and un-comment the following three lines, which are not together (Ctrl-W comes in handy here):

LoadModule ssl_module modules/mod_ssl.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
Include conf/extra/httpd-ssl.conf

For now we are not going to edit the "httpd-ssl.conf" configuration file so just generate and sign a certificate. First, generate the key (you may wish to use a 2048 bit key for compatibility reasons):

cd ~
openssl genrsa -out server.key 4096

I didn’t use the -des3 option above because I don’t want to have to enter a password every time Apache starts (and this is just a test bed). Now let’s create the CSR:

openssl req -new -key server.key -out server.csr

The above command will ask for some info to be included in the certificate. Go with defaults or customize as desired. Finally, we can create the actual certificate:

openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt

Customize the above command as desired. I set the certificate to expire in 10 years since this is only for testing purposes. Now type the following:

ls server*

The above should show the following 3 files:

server.crt server.csr server.key

Copy the needed files to their proper location, restart Apache, and test SSL:

CentOS/FedoraUbuntu/Debian/openSUSE/Arch Linux
sudo cp server.key /opt/apache/conf/
sudo cp server.crt /opt/apache/conf/
sudo service apache2 restart
lynx https://localhost
sudo cp server.key /opt/apache/conf/
sudo cp server.crt /opt/apache/conf/
rm server.*
sudo systemctl restart apache2.service
lynx https://localhost

Lynx will complain about it being a self-signed certificate. Just verify it is okay with y.

This is also a good time to test the connection from the host system (if using a VM) or another computer on your network using a browser like Firefox or Chrome. Just open your browser of choice and type each of the following in turn into the address bar (adjusting the IP address if needed):

http://192.168.56.101
https://192.168.56.101

You will get a security warning for the SSL site. That is expected, so confirm the certificate. If something went wrong, the problem is most likely with your firewall settings, so go back to that section in the previous article and check that the HTTP/HTTPS ports are open on your local network.

Leave a Reply