Ok, I have to admit, I’ve been getting pretty used to just running up my list of installed libraries and applications via apt-get. Haven’t had to compile anything lately. Not that it’s hard to do so, but a single command is rather easy especially when it takes care of a lot of work for you.
Either way, every now and then you’ll want to compile your own copy of an application any way. For me, right now it’s cause of some features I want such as being able to setup Perfect Forward Secrecy on a few sites. This whole setup, the compiling the list of configuration arguments I wanted, trial and error with dependencies and build methods, and a bit of going back and fixing up a few things took about 2 days. Could have done it quicker, or potentially even slower if I researched some more things, but I was the point where I was rather happy with this being a model setup for future deployments.
So here’s the game plan…I’ve got a shiny new Debian 7 VPS that I’m turning into a new ultra secure LAMP server. A few things I’ll leave to install via apt-get…OpenSSL in the Deb7 repo is up to 1.0.1e (the latest at the time of this writing) so it’ll support TLS 1.2 that I need. APR is something we’ll need for the Event MPM, we’ll install it via apt-get to also install a few other packages Apache uses as well, but we’ll download the latest version to include in the configuration process since it’s nothing really big or difficult.
So let’s go ahead and install a few things that we’ll need…
<strong>root@localhost:~/#</strong> apt-get install libaprutil1 libaprutil1-dev build-essential libgdbm3 libgdbm-dev
Next, I made a new directory, /opt/src/, downloaded all of the packages, unzipped, and deleted archives. At the time of writing, that was a few wgets involving Apache 2.4.7, PHP 5.5.7, APR 1.5.0, APR-Util 1.5.3, APR-Iconv 1.2.1, and ZLib 1.2.8.
So, now got the latest versions of Apache, PHP, MySQL, and the APR suite downloaded to the /opt/src/ directory, unzip them all, delete the archives (or move them to another directory!). First, we’ll build APR 1.5.0.
<strong>root@localhost:/opt/src#</strong> cd apr-1.5.0/ <strong>root@localhost:/opt/src/apr-1.5.0/#</strong> chmod +x configure && ./configure --enable-threads --prefix=/opt/apr-1.5.0
So far so easy, goto the APR src directory, make the configure script executable, pass on a few arguments to the configure script, and read over everything to make sure the system isn’t missing some software or something didn’t go slightly wrong. Once it looks good, just run a quick
make && make install to install APR. Next, onto APR-Iconv.
<strong>root@localhost:/opt/src/apr-1.5.0/#</strong> cd ../apr-iconv-1.2.1/ <strong>root@localhost:/opt/src/apr-iconv-1.2.1/#</strong> chmod +x ./configure && ./configure --prefix=/opt/apr-iconv-1.2.1 --with-apr=/opt/apr-1.5.0/bin/apr-1-config
Those few lines simply change directories, quick chmod, and APR-Iconv is almost installed! Look things over, once it looks good with no serious warnings, run
make && make install to move onto APR-Util.
<strong>root@localhost:/opt/src/apr-iconv-1.2.1/#</strong> cd ../apr-util-1.5.3/ <strong>root@localhost:/opt/src/apr-util-1.5.3/#</strong> chmod +x configure && ./configure --prefix=/opt/apr-util-1.5.3 --with-iconv=/opt/apr-iconv-1.2.1 --with-crypto --with-gdbm --with-openssl --with-apr=/opt/apr-1.5.0/bin/apr-1-config
You should be getting the hang of it by now, as long as nothing is on fire, continue to
make && make install. Done with the APR suite, move onwards to ZLib!
<strong>root@localhost:/opt/src/apr-util-1.5.3/#</strong> cd ../zlib-1.2.8/ <strong>root@localhost:/opt/src/zlib-1.2.8/#</strong> chmod +x configure && ./configure --prefix=/opt/zlib-1.2.8 && make && make install
Ok, so that one I just went ahead and put the
make && make install suffixed to the configure command because it’s such a simple compile I’m sure any machine will configure properly. Done with all the prerequisites, onto the actual fun!
Now, compiling Apache can be a very easy, or very strenuous process. It all depends on what modules your applications need, how much time you want to spend researching performance/modules, and various other unique variables. For my purposes, I’m compiling all the MPMs modularly so I can swap back and forth if need be, got everything available being compiled but I’ll go back and only load the ones I need later once I have a few hours to go through a bunch of configuration files.
<strong>root@localhost:/opt/src/zlib-1.2.8/#</strong> cd ../httpd-2.4.7/ <strong>root@localhost:/opt/src/httpd-2.4.7/#</strong> /configure --prefix=/opt/apache2 --enable-mpms-shared=all --with-mpm=event --enable-threads --enable-mods-shared=reallyall --enable-http --enable-deflate --enable-expires --enable-headers --enable-rewrite --enable-mime-magic --enable-log-debug --enable-ssl --enable-nonportable-atomics=yes --enable-ssl-staticlib-deps --enable-mods-static=ssl --with-apr=/opt/apr-1.5.0/bin/apr-1-config --with-apr-util=/opt/apr-util-1.5.3/bin/apu-1-config --enable-fcgi --with-z=/opt/zlib-1.2.8
Ok, that one’ll throw you for a loop. Either way, again check to make sure it isn’t whining about much…might complain about lack of LUA, privileges, etc. For the most part, don’t worry about it. If you knew you should, then you would. Everything look nice?
make && make install and let’s recap what we just did…
- We setup our environment, a few prerequisites, a work area with extracted source files in /opt, then we were ready to build
- Spent a lot of time researching configuration options via
./configure --helpand Google Fu, configuring, building, reconfiguring, and rebuilding, and a few more times of that later figured everything out and started fresh…
- Configured and built APR. Some will say to include the APR and APR-Util source files in the srclib/ directory in the Apache source directory and let the Apache configure script configure them as well, but doing so will not build correctly in most cases with a very custom setup.
- Configured and built APR-Iconv, then APR-Util, followed by Zlib.
- Configured and built Apache 2.4. Apache has some crazy configuration options, and I used most of them. All modules and MPMs were compiled and set to load modularly, this lets us experiment with different setups to see which performs best and also lets us expand and contract our feature set easily.
Ok, so that’s where we’re at now. We could go ahead and test the Apache setup, but let’s configure the init.d script first so that it’ll run on start up.
<strong>root@localhost:/opt/apache2/#</strong> cp bin/apachectl /etc/init.d/apache2 <strong>root@localhost:/opt/apache2/#</strong> nano /etc/init.d/apache2
Now, the reason we’re copying this over instead of symlinking it, is because we want to keep the original apachectl file while making a few simple adjustments; this file was configured specifically to this installation so it requires very little modification.
Now, append the following lines right after the first line (after the interpreter declaration)
### BEGIN INIT INFO # Provides: apache2 # Required-Start: $local_fs $remote_fs $network $syslog $named # Required-Stop: $local_fs $remote_fs $network $syslog $named # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # X-Interactive: true # Short-Description: Start/stop apache2 web server ### END INIT INFO
Save, and exit.
Finish up with a few quick commands to finalize the Apache environment…we’ll symlink the compiled binaries to somewhere in our default PATH. You could add it to your ~/.bashrc file, but this way it’s system-wide and not user-specific. Then just update with default parameters, boom, you can use Apache 2 as a service and it’ll start on boot!
<strong>root@localhost:/opt/apache2/#</strong> ln -s /opt/apache2/bin/* /usr/local/bin/ <strong>root@localhost:/opt/apache2/#</strong> update-rc.d -f apache2 remove <strong>root@localhost:/opt/apache2/#</strong> update-rc.d -f apache2 defaults 91 09
You should now be able to start/stop/etc Apache 2 via:
<strong>root@localhost:/opt/apache2/#</strong> service apache2 stop <strong>root@localhost:/opt/apache2/#</strong> /etc/init.d/apache2 start
Ok, got about half of this done now, onto MySQL which has just as many configure options as Apache does, but thankfully most of them wouldn’t be close to being needed…
<strong>root@localhost:/opt/apache2/#</strong> cd /opt/src/mysql-5.6.15/ <strong>root@localhost:/opt/src/mysql-5.6.15/#</strong>