Custom-Compiling Apache and Subversionby Manni Wood
Custom-compiling Subversion and Apache is the best way of controlling what you want (and don't want) from your repository. I recently had to set up a Subversion repository for a project and found that custom compilation was the only way to get exactly what the project required.
The project requirements were:
- Allow secure repository access from anywhere on the internet.
- Ideally meet security requirements without having to ask the IT department to change any firewall rules.
- Keep the repository on a local or an NFS-mounted filesystem.
Using Apache 2.0 as the front end for Subversion was the best way to meet the first two requirements; we could use https, which our firewall already allowed. Using Subversion 1.1, and specifically the new FSFS repository storage method, allowed us to satisfy the third requirement.
Custom-compiling Apache 2.0 let me exclude modules that most binary Apache distributions typically include but that seem at odds with our goals, such as mod_userdir and mod_status. Custom-compiling Subversion also let me use the very latest version--1.1.3 at the time of this writing--and be certain it integrated well with my custom Apache install.
Because I did my work with Fedora Core 1, this article will have the most relevance to that OS and distribution, but hopefully this article will get you most of the way there with other Unixes as well.
Fedora Core is a reasonably feature-rich distribution; it already comes with gcc and OpenSSL, two essentials for getting Apache and Subversion working in the way that satisfied my three goals. If you do not have those packages on your Unix/Linux, install them. Your distribution media for Fedora Core contains these packages if you haven't already installed them; Sunfreeware.com has them for Solaris; other resources are available for other Unixes. Definitely get the binaries for these packages if you can; there's no benefit from custom-compiling these packages.
The exact versions I used were OpenSSL 0.9.7a Feb 19 2003, and gcc 3.3.2 20031022 (Red Hat Linux 3.3.2-1).
Please note that I'm assuming you can run all of these commands as root--it's necessary to make a lot of this stuff work.
I downloaded the latest Apache 2.0 source code (2.0.53 at the time of this writing) and copied it to /usr/local/src where I always do my custom compiling. If your system doesn't already have this directory, I encourage you to create it.
Red Hat/Fedora Core users note that distribution RPMs never install in /usr/local, which is nice: after all, /usr/local is for stuff that's "local" to your installation! Red Hat and Fedora Core's packages respect the proper use of /usr/local and leave it alone, which is particularly nice at upgrade time: your local modifications to your distribution survive upgrades intact. Complimentarily, almost all custom-compiled software that you will install from source code uses /usr/local as its base install path.
Next, I prepared Apache for compilation:
[root@localhost etc]# cp /downloads/httpd-2.0.53.tar.gz /usr/local/src [root@localhost etc]# cd /usr/local/src [root@localhost src]# tar -xzvf httpd-2.0.53.tar [root@localhost src]# cd /usr/local/src/httpd-2.0.53
Note that only GNU
tar recognizes the
If your Unix has a non-gzip-aware
tar, I recommend you use the
following command instead:
[root@localhost src]# gunzip httpd-2.0.53.tar.gz [root@localhost src]# tar -xvf httpd-2.0.53.tar [root@localhost src]# # re-gzip to save disc space [root@localhost src]# gzip httpd-2.0.53.tar
At this point, I was ready to configure Apache. I almost always run
./configure with arguments when I custom-compile software, and
over the years I've come to make a wrapper script called
runconfigure.sh so that I have a record of the arguments I used when I
./configure. In this script, I asked for all modules to be
shared, for most modules to be compiled in (especially ssl and dav, which
Subversion needs), but for mod_status and mod_userdir to be compiled out.
Arguably, I could also have compiled out other superfluous modules such as
mod_cgi. Here's my script:
#!/bin/sh # runconfigure.sh -- wrapper script for ./configure ./configure --enable-mods-shared="most ssl dav" --disable-status --disable-userdir
Then I compiled and installed Apache:
[root@localhost httpd-2.0.53]# chmod +x runconfigure.sh [root@localhost httpd-2.0.53]# ./runconfigure.sh [root@localhost httpd-2.0.53]# make [root@localhost httpd-2.0.53]# make install
A Few Fixes to Apache's Configuration and Startup
Interestingly, the Apache install script did not remove the mod_userdir
configuration from httpd.conf, even when I chose not to compile that
module. I had to comment it out manually. There's only one line to remove:
UserDir public_html/. Here's one way to do so, without having to
use an interactive editor:
[root@localhost httpd-2.0.53]# cd /usr/local/apache2/conf [root@localhost conf]# sed -i -e 's/^UserDir public_html/# &/' httpd.conf
I needed to fix another small problem with Apache in order for SSL to work
apachectl control script needs to define the
SSL on the command line to make Apache read its SSL
configuration from httpd.conf and ssl.conf. Although Apache
needs to have
SSL defined for both startup and shutdown, only the
startup clause of the Apache control script defines it. To fix this problem, I
opened /usr/local/apache2/bin/apachectl in a text editor, looked for
startssl|sslstart|start-SSL, and added the following
lines above that line:
stopssl|sslstop|stop-SSL) $HTTPD -k stop -DSSL ERROR=$? ;;
Once you have installed your own custom-compiled Apache with mod_ssl, don't
forget to start and stop Apache with the commands
/usr/local/apache2/bin/apachectl startssl and
/usr/local/apache2/bin/apachectl stopssl, not
Securing Apache Conveniently
To run using https, Apache needs a certificate to give to browsers. Compiling Apache does not generate this certificate; I had to create one myself.
First, I created the directories ssl.crt and ssl.key in
the default locations expected by /usr/local/apache2/conf/ssl.conf (which /usr/local/apache2/conf/httpd.conf
[root@localhost conf]# cd /usr/local/apache2/conf [root@localhost conf]# mkdir ssl.crt [root@localhost conf]# mkdir ssl.key
My project required only a self-signed certificate, not one from a
bona fide certificate-generating authority. Interestingly, there's a lot of
confusing information on the internet on just how to generate a self-signed
certificate for Apache, and, sadly, most of that information is way more
complicated than it has to be. It turns out I was able to generate the key and
the cert all in a single
openssl command (note that after some output, you
will be prompted for a pass phrase twice):
[root@localhost conf]# openssl req -new -x509 -days 365 -keyout ./ssl.key/server.key -out ./ssl.crt/server.crt -subj '/CN=Test-Only Certificate'
Because of the certificate, whenever Apache started it prompted me for the
pass phrase. This was not useful, because I planned on using
apachectl (or some form of it) in my server's startup and shutdown
scripts: I didn't want my server to stop and prompt me for a password every
time I rebooted it--after all, what if I had to reboot it remotely? I
wouldn't be at the console to enter the pass phrase. Happily, there's a way to
get around this problem (note that the
openssl command prompted me
for the pass phrase I selected above):
[root@localhost conf]# cp ssl.key/server.key ssl.key/server.key.org [root@localhost conf]# openssl rsa -in ssl.key/server.key.org -out ssl.key/server.key [root@localhost conf]# chmod 400 ssl.key/server.key
The new ssl.key/server.key above is insecure; I protected it by setting the permissions on the file as restrictively as possible.
Pages: 1, 2