Getting the Apache/MySQL/PHP/SSL combo running on a Linux system
The aim of this page is to help Linux users (and probably users of other *nixes like BSD) set up the Apache/MySQL/PHP/SSL combo on their boxen so they can build their own secure, database-driven websites.
In order to avoid making these "instructions" distribution-specific, we'll be compiling everything from source. This assumes that all the development tools are installed on your machine. Refer to your own distribution's manuals in order to find out if this is the case, and to install the tools if not. Perl 5.6.0 is also required for setting up OpenSSL - once again, refer to your documentation for installation instructions.
Since we're going to be compiling from source, we'll need a place to store the source trees. Where you decide to put this repository is entirely up to you. Some people put it under /usr/src, others under /usr/local/src. Personally, I tend to keep downloaded stuff on a separate partition mounted on /opt and I put source trees in /opt/src. I'll be assuming this is where you'll be putting your stuff too, but nothing's to stop you using another location if you have a personal preference for something else - just remember to replace /opt/src with the location you choose...
Finally, please bear in mind that I am no real "expert" in any of the fields discussed herein. It is therefore, to a certain extent, a case of the blind leading the blind - all I can do is relate the steps I went through in order to get things up and running on my machines.
Note to Red Hat and Mandrake users: Check the version of your compiler. If you're using the Red Hat "experimental" gcc 2.96 compiler (gcc -v will tell you what version of gcc you have), you're likely to run into difficulties using some of the stuff compiled with it. MySQL AB clearly states that random crashes experienced while using a MySQL server compiled with gcc 2.96 disappeared as soon as the binary was replaced with a binary compiled with a different compiler.
Step 1: Downloading the software
- The MySQL source: As of now (late 2004) there are 3 main branches of MySQL. There's the "old" 3.23.x branch, the "production" 4.x branch, and the "beta" 5.x branch. Which one you use is up to you, although the instructions herein deal with the 4.x branch. The latest stable version in this branch is 4.1.8, which you can download from here. You will end up downloading a tarball called mysql-4.1.8.tar.gz.
- The Apache webserver source: Apache version 2.0.x has been released long since but I decided to stick with the latest 1.3.x version (1.3.33) mainly because it's the one I know best and it works perfectly well. Also, PHP 4.x, which is non-threaded, doesn't play nicely with Apache 2.x, which is threaded. PHP5, on the other hand, does play nicely with Apache 2.x. The source is available from here. Go for the tarball - you'll be downloading apache_1.3.33.tar.gz.
- The PHP source: Available from here. Download either php-4.3.10.tar.gz or, if bzip2 is installed on your system, php-4.3.10.tar.bz2.
- zlib: Just about every modern Linux distribution ships with zlib-1.1.4, or later, but if yours is more than, say, a year old, you should check that you are up to date. A security vulnerability was discovered in zlib-1.1.3 so, if that's the version you have, then you should upgrade. Download version 1.1.4 or later which is available from here, zlib-1.1.4.tar.gz. The latest version available is 1.2.1, zlib-1.2.1.tar.gz.
- OpenSSL: "SSL" (Secure Socket Layer) - these are the libraries which handle the data encryption. They rely on the zlib compression algorithms in places. The latest version, (0.9.7e as of writing this) is available here, openssl-0.9.7e.tar.gz.
- mod_ssl: This is what gets Apache to use SSL encryption. Download the latest production version from here, mod_ssl-2.8.22-1.3.33.tar.gz.
- OpenSSH: Secure shell. Strictly speaking, this isn't needed to get your server up and running. However, you'll find it more than useful for remote administering it and for uploading/downloading data to/from it over a secure channel. The package provides tools giving you a shell, ftp access and straightforward file copying over SSL. This is much more secure than telnet, unencrypted ftp and NFS. The latest version is 3.9p1 and can be downloaded here, openssh-3.9p1.tar.gz. Users of OpenBSD will want to download the "original" OpenSSH - openssh-3.9.tar.gz
Step 2: Installing libz
Both mod_ssl and OpenSSH link against a library called libcrypt which is part of OpenSSL. This library is, in turn, linked against libz, which means that the whole 9 SSL yards depend upon a nicely clamped down version of libz. This is why we have to install libz before anything else which uses it.
Refer to your distribution's documentation to find out which version of libz is already installed. If it is 1.1.4 or later then you need not bother with this and you can skip straight to step 3. Otherwise, remove the current installation of libz (according to the instructions for your distribution), ignoring any dependency warnings - we're going to install a replacement, so it doesn't matter if other tools link to this library.
If you haven't already done so, create your /opt/src directory:# mkdir -p /opt/src
Switch to root, go into that directory and unpack the zlib tarball.$ su - Password: [enter your root password here] # cd /opt/src # tar -xzf /<path to where you saved>/zlib-1.2.1.tar.gz
You'll now have a directory called zlib-1.2.1 in /opt/src. Go into it and then build and install the libz library.# cd zlib* # ./configure --prefix=/usr # make # make install
This has built and installed the static library, libz.a, that can be linked into statically linked executables. We'll also want the shared library, libz.so:# make clean # ./configure --prefix=/usr --shared # make # make install # ldconfig
That's all there is to it! You now have a secure version of zlib, which you can use to build applications which link against it.
Step 3: Installing MySQL
Getting MySQL up and running is one of the trickiest bits, so we might as well get it out of the way as soon as possible.
First of all, untar/unzip the MySQL tarball into your source directory.# cd /opt/src # tar -xzf /<path where you saved>/mysql-4.1.8.tar.gz
Next, make sure that there is a mysql group and a mysql user on the system. Your system might tell you that the user and group already exist when you run these commands:# groupadd mysql # useradd -g mysql mysql
Next, cd into the mysql source directory and configure the compile process using the following options:
- --prefix=/usr/local/mysql (to tell make where to install mysql).
- --enable-assembler (so that some of the string manipulation functions are optimised).
- --with-unix-socket-path=/tmp/mysql.sock (to tell it where to set up the Unix socket when the daemon is running)
- --with-mysqld-user=mysql (to name the unprivileged user as which the mysql daemon will run)
- --without-debug (so as not to bloat the binaries with debug info)
Note the use of the backslash to split a looooooong command line over several screen lines:# cd mysql-4.1.8 # ./configure --prefix=/usr/local/mysql \ --enable-assembler \ --with-unix-socket-path=/tmp/mysql.sock \ --with-mysqld-user=mysql \ --without-debug
Build and install the binaries (this can be long...):# make # make install
Note that this process installed some libraries in /usr/local/mysql/lib/mysql. For the libraries to become "visible" to the system, you must add a line containing this path to your /etc/ld.so.conf file and run ldconfig.
Now go into the directory where mysql was installed.# cd /usr/local/mysql
Under this directory is another directory called bin containing among other things a script called mysql_install_db, the purpose of which is to set up mysql's initial "housekeeping" databases. Run it:# bin/mysql_install_db
Make sure that file ownership is set correctly for the directories and files:# cd /usr/local # chown -R root:mysql mysql # cd mysql # chown -R mysql var
With any luck, you should be able to start the mysqld daemon now.# /usr/local/mysql/bin/mysqld_safe &
You can add the following lines to your startup script (usually /etc/rc.d/rc.local) to have mysqld started whenever your machine boots:/usr/local/mysql/bin/mysqld_safe & sleep 3
The 3 second pause is there in order to delay the login prompt long enough for mysql to display any status messages. Without this, the status messages could get displayed while you're in the process of logging in, and this looks horribly confusing on the screen :)
You still need to be root in order to install the rest of the software, so don't switch back to your unprivileged user yet.
Step 4: Installing OpenSSL
OpenSSL is next in the priority list. Go back to your /opt/src directory, unpack the OpenSSL tarball, then go into the newly created directory.# cd /opt/src # tar -xzf /<path to where you saved>/openssl-0.9.7e.tar.gz # cd openssl-0.9.7e
Due to patent issues, servers based in the EU, the USA and Japan are not allowed to use the IDEA encryption algorithm for commercial purposes without obtaining a licence from MediaCrypt beforehand.
The patent on the IDEA protocol expires in November 2010.
If your SERVER is: then configure OpenSSL with: Based in the EU, USA or Japan and used for commercial purposes ./config no-idea shared -fPIC Outside the EU, USA and Japan or only for non-commercial use ./config shared -fPIC
If you used the "no-idea" option in order to comply with MediaCrypt then you will be told to run "make depend" before compiling.
Now, build the OpenSSL libraries.# make
Optionally, you can run a test to make sure everything is working OK (this can take some time on slower machines).# make test
Finally, install the libraries.# make install
This will install OpenSSL in a directory heirarchy under /usr/local/ssl. Among other things, new libraries will be installed in /usr/local/ssl/lib, so add that path to the TOP of your /etc/ld.so.conf (so that these new libraries are found before any older ones which may be already installed) and run ldconfig. That's it for OpenSSL.
Step 5: Installing OpenSSH
In mid 2002 there were a couple of security scares about OpenSSH. Apparently, there was little to indicate that GNU/Linux was affected (whereas OpenBSD, for example, certainly was), but I'd rather preempt any potential problems and get you to use a fixed version.
Versions 3.4p1 and later split the ssh daemon, sshd, into two parts. Part of it runs with root privileges, the other part (which forks the login with which you interact over the remote connection) runs as a non privileged user called 'sshd'.
Obviously, this will only work if there is such a user on your system. So, you have to create it:# useradd -s /bin/false sshd
Naturally, you will be informed if such a user did already exist on your machine.
Next, as usual, go into your /opt/src directory and unpack the source tarball.# cd /opt/src # tar -xzf /<path to where you saved>/openssh-3.9p1.tar.gz
Next, we have to configure the build process and tell it what to include in the binaries. Most recent distros use shadow passwords, so we'll need to tell OpenSSH to use MD5. We'll also tell it where to find the OpenSSL libraries and where to put its PID file (so we know it's running when it is).# cd openssh-3.9p1 # ./configure --with-md5-passwords --with-ssl-dir=/usr/local/ssl --with-pid-dir=/var/run
Next, build and install the software.# make # make install
A default installation of ssh on a server allows a client to log in as root. Even though everything, including the authentication, is encrypted, I still consider this to be a security risk since only someone physically sitting at the machine should be able to do so. OpenSSH provides a way to stop this from happening.
Open your /usr/local/etc/sshd_config file with your favourite text editor. You will find a line which reads "#PermitRootLogin yes". Remove the '#' and change 'yes' to 'no' then save the file. Now you can start the sshd daemon.# sshd
Check to see that it's running by cross-checking the PID stored in /var/run/sshd.pid with the real PID of the process (the actual PID you find will almost certainly not be the same as on this system):# cat /var/run/sshd.pid 24254 # ps awx | grep sshd | grep -v grep 24254 ? S 0:00 sshd
Now check to see that it's working by attempting to ssh to yourself using your loopback IP address (127.0.0.1). Assuming you are user joebloggs:# ssh email@example.com The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. RSA key fingerprint is 67:c8:99:d4:30:81:29:b3:70:a4:13:d3:f4:b3:f7:32. Are you sure you want to continue connecting (yes/no)?
The RSA key on your machine will differ from this because it is generated randomly. And for those who are getting mischievous ideas, the data shown is not my RSA key :o). Anyway, answer yes here.Warning: Permanently added '127.0.0.1' (RSA) to the list of known hosts. firstname.lastname@example.org's password:
Type your password and voilà, you should be logged in. Don't forget to log out again....$ logout Connection to 127.0.0.1 closed.
Step 6: Installing Apache, PHP and mod_ssl
Once again, go to your /opt/src directory and unpack the tarballs.# cd /opt/src # tar -xzf /<path to where you saved>/apache_1.3.33.tar.gz # tar -xzf /<path to where you saved>/mod_ssl-2.8.22-1.3.33.tar.gz
If you downloaded a .tar.gz file for PHP then:# tar -xzf /<path to where you saved>/php-4.3.10.tar.gz
If you downloaded a .tar.bz2 file then:# tar -xjf /<path to where you saved>/php-4.3.10.tar.bz2
(Note that older versions of 'tar' expect you to use 'y' instead of 'j' in the command above.)
From here onwards I'll assume you're using the same versions of the software packages as me. This means that you will now have 3 new directories under /opt/src, namely apache_1.3.33, php-4.3.10 and mod_ssl-2.8.22-1.3.33. If you downloaded different versions (if, for example, a newer version became available since this article was written) then don't forget to adjust the pathnames you use in the following commands so that they reflect what's on your machine rather than what's on mine.
The first thing to do is to patch Apache with the mod_ssl patch, and then build it. For this, mod_ssl's configure script has to know where our Apache source tree is, where our OpenSSL libraries and headers are, and where we want Apache to be installed. We must also tell Apache to incorporate its 'mod_so' module so that we can use PHP as an external module. The advantage of this is not having to recompile Apache each time we update PHP - and vice-versa. Note that I will be installing Apache into /opt/apache - you'll have to change the path used (after --prefix=) in the following command (and in the command used to start the daemon later on) if you want to install it elsewhere.# cd ../mod_ssl-2.8.22-1.3.33 # ./configure --with-apache=../apache_1.3.33 \ --with-ssl=/usr/local/ssl \ --prefix=/opt/apache \ --enable-module=so
Now we build Apache.# cd ../apache_1.3.33 # make
Secure HTTP (HTTPS) works this way: the server sends a certificate to the client in order to prove that it is trustworthy. This certificate contains data about the server and is signed by a known authority. Having your certificate signed by an authority costs money, so what we're going to do here is sign the certificate ourselves.
The client browser will notice that the certificate has been signed by an unknown authority and ask you if you really want to proceed. Some browsers will also complain about the domain having created the certificate being different from the domain presenting it. That too is OK for now. However, if this server is set up in a production environment, you must create a legitimate certificate and have it signed by a known authority.
Once the certificate has been accepted by the client (either because it was signed by a known authority or because we told the browser to shut up and just get on with it), the server is deemed trustworthy and the data exchange itself can be initiated over an encrypted connection.
Run this:# make certificate
...and follow the instructions given.
Finally, we install Apache.# make install
The next thing to do is to configure and build PHP.# cd /opt/src/php-4.3.10 # ./configure --prefix=/usr/local \ --sysconfdir=/etc \ --localstatedir=/var \ --with-apxs=/opt/apache/bin/apxs \ --with-openssl=/usr/local/ssl \ --with-mysql=/usr/local/mysql \ --with-mysql-sock=/tmp/mysql.sock \ --enable-sockets \ --enable-track-vars # make # make install
The last thing to do before starting the Apache server is to edit its configuration file. This file is /opt/apache/conf/httpd.conf.
I won't go into any details about how to configure Apache because there are literally thousands of such howto's already on the web, including on Apache's own website at www.apache.org. However, the more impatient ones among you who want to get PHP scripts working now will have to do this:
- Open up /opt/apache/conf/httpd.conf with your favourite text editor.
- Locate the section which starts with <IfModule mod_mime.c>.
- A page or two down you'll come across a couple of indented lines which start with the AddType keyword. Add this line in the same spot:AddType application/x-httpd-php .php
- Don't forget to save the modified httpd.conf file...
You can now launch Apache in http-only mode this way:# /opt/apache/bin/apachectl start
Alternatively, you can start Apache to serve both http and https this way:# /opt/apache/bin/apachectl startssl
You can stop the Apache server with this command:# /opt/apache/bin/apachectl stop
If you add this to your startup script, you can have Apache started when Linux boots:/opt/apache/bin/apachectl startssl
If you have any (nice) comments to make about the information on this page or if you've seen a huge, glaring blooper, please let me know .
2006-03-17 Control of this howto was transferred from the original author to Howard Pritchett when the "DADVSI" law, which is basically designed to limit free speech and the use of Free Software, was voted in. 2004-12-28 Bumped up a few software versions:
- Apache 1.3.33
- mod_ssl 2.8.22-1.3.33
- OpenSSL 0.9.7e
- OpenSSH 3.9p1
- MySQL 4.1.8
- PHP 4.3.10
2004-09-02 Changed the "chown -R root.mysql" to the more BSD-friendly "chown -R root:mysql". Linux supports both, but FreeBSD at least complains about use of the period being deprecated. In fact FreeBSD 5.x demands a colon. Thanks to Scott for the heads-up. 2004-07-05 I received a mail from MediaCrypt pointing out that the patent inhibiting free use of the IDEA algorithm is not only in force in the EU, but also in the USA and Japan. The text has been updated to reflect this.
This was also a good opportunity for me to update the howto with later versions of the software involved, and to switch to a more flexible method of using PHP. This is what has been updated:
- Finally switched to MySQL 4.0.x
- Bumped the version of Apache up to 1.3-current (1.3.31)
- PHP went up to version 4.3.7 and I'm now building it as a Dynamic Shared Object for Apache instead of a static library. This has meant changing the way Apache is compiled, too.
- Moved up to zlib-1.2.1
- Updated to OpenSSL-0.9.7d
- Updated to OpenSSH-3.8.1
2003-11-11 Just a minor change in the section devoted to compiling and installing Apache. Removes a potential source of confusion. Thanks to for pointing it out. 2003-10-05 Nearly 10 months have elapsed since the last update to this howto. Vulnerabilities in all the software packages discussed except zlib have been discovered, so I took advantage of moving this howto here to update it - or maybe that should be the other way round because I took advantage of updating it to move it. Whatever...
Anyway, the page has now been moved to its new home on this server and it has been updated with the following modifications:
Additionally, the "make depend" step needed if compiling OpenSSL without the IDEA algorithm has been added, and a correction to the reasons why one may not use that algorithm has been made.
- OpenSSL version 0.9.7c
- OpenSSH version 3.7.1p2
- MySQL version 3.23.58
- Apache version 1.3.28
- mod_ssl version 2.8.15-1.3.28
- PHP version 4.3.3
2002-12-14 A vulnerability has been discovered in MySQL 3.23.53. MySQL AB promptly released 3.23.54 to correct the problem. 2002-12-10 That does it. Many people were letting me know that there were problems getting LAMPS up and running by using the instructions on this page - and I was indeed aware of a bug or two in the documentation. Add to that the various security issues discovered since this page was originally written, and you get enough reasons to put things right. This version of the howto page introduces the following changes:
Have fun :o)
- We've moved from OpenSSH 3.4 to OpenSSH 3.5.
- We've moved from MySQL 3.23.49a to MySQL 3.23.53 and we're compiling it from source instead of using ready-made binaries.
- The "Slapper" attack of late 2002 gave us a slap in the face and made us upgrade a few other things, so we've moved from OpenSSL 0.9.6d to OpenSSL 0.9.6h, from Apache 1.3.26 to Apache 1.3.27 and from mod_ssl 2.8.9-1.3.26 to mod_ssl 2.8.12-1.3.27.
- PHP 4.2.x seems to be stable and secure enough and there's even a PHP 4.3.0rc available for the more daring. We've moved on to PHP 4.2.3 from PHP 4.1.2.
- Instead of using PHP's built-in support for MySQL, we're using the original MySQL libraries installed along with MySQL itself.
- We've made it easier to patch the Apache source with the mod_ssl stuff and activate the PHP module in one step.
- Bugfix: The commands are properly sequenced in order to avoid problems compiling and installing PHP as an Apache module.
Last update: 11-JUL-2008
This page has been served 54319 times since 05-OCT-2003