ApacheLAMP 2018Linux

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. This is in addition to the packages mentioned on the Development Tools post.

CentOSFedoraUbuntu/DebianopenSUSEArch Linux
sudo yum install expat-devel lynx
sudo dnf install expat-devel lynx
sudo apt-get install libexpat-dev lynx
sudo zypper install libexpat-devel lynx
sudo pacman -S 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. See the PCRE site for the most current version of PCRE and edit the first line below as necessary.

TMPVER="8.42"
cd ~
wget https://ftp.pcre.org/pub/pcre/pcre-${TMPVER}.tar.gz
wget https://ftp.pcre.org/pub/pcre/pcre-${TMPVER}.tar.gz.sig
wget https://ftp.pcre.org/pub/pcre/Public-Key
gpg --import Public-Key
gpg --verify pcre-${TMPVER}.tar.gz.sig pcre-${TMPVER}.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-${TMPVER}.tar.gz
mkdir -v pcre-${TMPVER}/bld
cd pcre-${TMPVER}/bld
../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-${TMPVER} /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. Other distributions come with the newer stable 1.1.0 branch, but still may not have the latest bug fixes. See the OpenSSL website for current version information.

You can check your current version with:

openssl version

Important: Even if you have the latest version provided by your system, Apache may still fail to compile unless you compile OpenSSL from source. (This happened to me with Fedora, although Arch Linux had no issues with the latest version as provided on the system.) However, a side-by-side installation of two versions of OpenSSL using the same libraries can cause conflicts, possibly breaking things like your package manager or preventing you from generating certificates. So follow my instructions carefully, which worked for all tested distributions.

Download and compile. For this example I will be installing the current latest stable version. Change version number on the first line if necessary, and copy/paste the rest into your SSH terminal.

TMPVER="1.1.0h"
cd ~
wget https://www.openssl.org/source/openssl-${TMPVER}.tar.gz
tar zxvf openssl-${TMPVER}.tar.gz
cd openssl-${TMPVER}
CC="gcc -fPIC" ./config --prefix=/opt/openssl --openssldir=/opt/openssl
make && make test

Assuming all tests passed, you can continue. 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.

sudo env "PATH=$PATH" make install
cd ~
sudo mv openssl-${TMPVER} /usr/local/src/
rm openssl-*

Important: If your system provides the exact same version (or newer) of OpenSSL as the one you just installed, skip the following commands! This will force you to use the new version as the default.

export PATH=/opt/openssl/bin:$PATH
echo 'PATH=/opt/openssl/bin:$PATH' | \
sudo tee /etc/profile.d/openssl.sh
echo "/opt/openssl/lib" | \
sudo tee /etc/ld.so.conf.d/openssl.conf
sudo ldconfig

Important: In rare cases you may have issues with libs conflicting as mentioned previously. You will know if this happens because things which rely on OpenSSL such as your package manager may give you error messages about libssl.so.1.1 or something similar. If this happens, you can try the following fix:

sudo rm /etc/ld.so.conf.d/openssl.conf
sudo ldconfig

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://mirrors.koehn.com/apache/" so replace that string and the version numbers in the first few lines below with whatever you found. Then copy/paste the rest of the commands into your SSH terminal.

URL="http://mirrors.koehn.com/apache/"
APACHEVER="2.4.33"
APRVER="1.6.3"
APRUTILVER="1.6.1"
cd ~
wget ${URL}httpd/httpd-${APACHEVER}.tar.gz
wget apache.org/dist/httpd/httpd-${APACHEVER}.tar.gz.asc
wget ${URL}apr/apr-${APRVER}.tar.gz
wget apache.org/dist/apr/apr-${APRVER}.tar.gz.asc
wget ${URL}apr/apr-util-${APRUTILVER}.tar.gz
wget apache.org/dist/apr/apr-util-${APRUTILVER}.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-${APACHEVER}.tar.gz.asc
gpg --verify apr-${APRVER}.tar.gz.asc
gpg --verify apr-util-${APRUTILVER}.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:

tar zxvf httpd-${APACHEVER}.tar.gz
tar zxvf apr-${APRVER}.tar.gz
mv apr-${APRVER} httpd-${APACHEVER}/srclib/apr
tar zxvf apr-util-${APRUTILVER}.tar.gz
mv apr-util-${APRUTILVER} httpd-${APACHEVER}/srclib/apr-util
mkdir -v httpd-${APACHEVER}/bld
cd httpd-${APACHEVER}/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. If you did not compile OpenSSL as described above, you can try using the system-provided version by omitting the --with-ssl option, but this may not always work.

../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-${APACHEVER} /usr/local/src/
rm KEYS httpd-* 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

The first version of this tutorial, written years ago, assumed you were using SysVinit rather than Systemd under CentOS/Fedora, but since then almost all distributions use Systemd to start services, so I will only be covering that in this tutorial.

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, copy/paste 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_cgid 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:

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

Save and exit. 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:

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