Apache 2 only
Setting the Default Server Port, User, and Group
A number of the configuration directives that you have to set in httpd.conf
can be preset using a corresponding option at build time. In
particular, you can set the user and group under which the server runs
and the port number to which it’ll listen. What makes these different
from other values that might seem to be just as important—for example,
the document root—is that, for varying reasons, it may be particularly
useful or even necessary to specify them in advance.
The port is a required setting of Apache 2; the server won’t start
without it being explicitly configured. Specifying it at build time
will cause Apache to add a corresponding line into httpd.conf. Without it, you’ll need to edit httpd.conf, so if you want to create an immediately usable Apache, you must set it here, too. You can change it with the --with-port option, for example:
$ ./configure --with-port=80 ...
In Apache 1.3 the default port number in httpd.conf
is set to 80 automatically, so this option needn’t be specified for a
server running on the standard HTTP port. Of course, editing httpd.conf to add or change it isn’t a great burden, either.
The user and group affect the suExec wrapper (covered shortly), so you must set them at build time. In Apache 1.3 you use the --server-uid and --server-gid options to do this. The corresponding Apache 2 options are --with-server-uid and --with-server-gid. For example, to set the user to httpd and the group to the httpd group, you’d use the following for versions 1.3 and 2, respectively:
[1.3]$ ./configure --server-uid=httpd --server-gid=httpd ...
[2.0]$ ./configure --with-server-uid=httpd --with-server-gid=httpd ...
You can set a number of other directives in httpd.conf
that relate to the locations of things such as the document root and
the default CGI directory by overriding parts of Apache’s default
layout. I cover this in detail in the “Advanced Configuration” section
a little later in the chapter.
Determining Which Modules to Include
Other than optimizing Apache for the platform it’s to run on, the
most useful aspect of building Apache is to control which modules are
included or excluded. If you want to build a dynamic server, it’s often
simpler to build everything dynamically and then subsequently weed out
the modules you don’t want from the server configuration. However,
choosing modules at build time is essential for static servers because
you can’t subsequently change your mind. It can also be useful on
platforms where some modules simply won’t build and you need to
suppress them to avoid a fatal error during compilation.
Apache will build a default subset of the modules available unless
you tell it otherwise; you can do this explicitly by naming additional
modules individually, or you can ask for bigger subsets. You can also
remove modules from the list, which allows you to specify that you want
most or all of the modules built, and then make exceptions for the
modules you actually don’t want.
You specify module preferences using the enable and disable options. The syntax of these is one of the areas where the Apache 2 and Apache 1.3 configure
scripts differ quite significantly. In fact, it’s likely to be one of
the bigger problem areas for administrators looking to migrate.
However, although the Apache 2 syntax is more flexible, it still offers
essentially the same functionality. To simplify the task for
administrators who are looking to migrate, I’ll present the various
ways you can control the module list with examples for both versions of
Apache.
I’ll also tackle building Apache as a fully static
server first before going on to building it as a fully or partly
dynamic server.
Enabling or Disabling Individual Modules
Apache 1.3 provides the generic --enable-module option, which takes a single module name as a parameter. To enable mod_auth_dbm and add it to the list of modules that will be built, use this:
[1.3] $ ./configure --enable-module=auth_dbm
Apache 2 replaces this with a more flexible syntax that provides a
specific option for each available module. To fit in with the naming
convention for options, module names with underscores are specified
with – (minus) signs instead, so the previous command in Apache 2
becomes either one of these:
- [2.0] $ ./configure --enable-auth-dbm
[2.0] $ ./configure --enable-auth-dbm=yes
Disabling a module is similar. To remove mod_include and mod_userdir, which by default are included, use this:
[1.3] $ ./configure --disable-module=include --disable-module=userdir
or in Apache 2, use this:
- [2.0] $ ./configure --disable-include --disable-userdir
[2.0] $ ./configure --enable-include=no --enable-userdir=no
As mentioned earlier, in Apache 2 you can use the new --enable-modules option along with a list of module names. Notice the plural—this isn’t the same as Apache 1.3’s --enable-module. Unfortunately, there’s as yet no equivalent --disable-modules
option. So to enable DBM authentication, URL rewriting, and all the
proxy modules but disable user directories, as-is responses, and the
FTP proxy, you could use this:
[2.0] $ ./configure --enable-modules="auth_dbm rewrite proxy" \
--disable-userdir --disable-asis --disable-proxy_ftp"
This adds mod_auth_dbm, mod_rewrite, and mod_proxy and then removes mod_userdir, mod_asis, and mod_proxy_ftp (which was enabled when you enabled mod_proxy).
You can obtain the list of available modules, and their default state of inclusion or exclusion, from the configure --help
command. This produces an output that includes the following section
(this particular example is from an Apache 1.3 distribution because
Apache 2’s configure doesn’t yet provide this information):
[access=yes actions=yes alias=yes ]
[asis=yes auth=yes auth_anon=no ]
[auth_db=no auth_dbm=no auth_digest=no ]
[autoindex=yes cern_meta=no cgi=yes ]
[digest=no dir=yes env=yes]
[example=no expires=no headers=no ]
[imap=yes include=yes info=no ] [log_agent=no log_config=yes log_referer=no ]
[mime=yes mime_magic=no mmap_static=no ] [negotiation=yes proxy=norewrite=no ]
[setenvif=yes so=no speling=no ]
[status=yes unique_id=no userdir=yes ]
[usertrack=no vhost_alias=no ]
This tells you the names of the modules to use with configure
and which modules Apache will build by default. Unfortunately, it
doesn’t take account of any other parameters you might add, so you
can’t use it to check the result of specifying a list of enable and
disable options.
Once you’ve run the configure script and set up the source code for compilation and installation, you can build and install Apache with this:
$ make
# make install
Once this is done, you can go to the Apache installation directory, make any changes to httpd.conf that you need—such as the hostname, port number, and server administrator—and start up Apache. You could also just type make install,
but doing it in two steps will allow you to perform a last-minute check
on the results of the build before you actually install Apache.
Modules in Bulk
The --enable-module option of Apache 1.3 and the --enable-modules
option of Apache 2 have in common two special arguments that allow you
to specify a larger group of modules without listing them explicitly:
- most expands the default list to include a larger selection of the modules available.
- all goes further and builds all modules that aren’t experimental or otherwise treated specially.
Tables 3-2 and 3-3 contrast the modules that are built at the default, most, and all
levels, for Apache 1.3 and Apache 2, respectively. Each column adds to
the previous one, so the All column contains only those modules that
are additional to most.
The Explicitly Enabled column details all modules that aren’t included
unless explicitly enabled, along with a subheading detailing why.
Some experimental modules are likely to be added to the list of All
modules at some point in the future; in Apache 2 this includes mod_file_cache, mod_proxy, and mod_cache.
These modules have been listed under Additional rather than
Experimental in the Explicitly Enabled column to differentiate them
from truly experimental or demonstration modules such as mod_example, which should never be encountered in a production-server environment.
Table 3-2 is the list for Apache 1.3.
Table 3-2. Apache 1.3 Included Modules
Default |
Most |
All |
Explicitly Enabled |
mod_access |
mod_auth_anon |
mod_mmap_static |
mod_auth_digest |
mod_actions |
mod_auth_db |
(mod_so) |
|
mod_alias |
mod_auth_dbm |
Obsolete: |
|
mod_asis |
mod_cern_meta |
mod_auth_db |
|
mod_auth |
mod_digest |
mod_log_agent |
|
mod_autoindex |
mod_expires |
mod_log_referer |
|
mod_cgi |
mod_headers |
Example and Experimental |
|
mod_dir |
mod_info |
mod_example |
|
mod_env |
mod_mime_magic |
|
|
mod_imap |
mod_proxy |
|
|
mod_include |
mod_rewrite |
|
|
mod_log_config |
mod_speling |
|
|
mod_mime |
mod_unique_id |
|
|
mod_negotiation |
mod_usertrack |
|
|
mod_setenvif |
mod_vhost_alias |
|
|
(mod_so) |
|
|
|
mod_status |
|
|
|
mod_auth_db is deprecated in favor of mod_auth_dbm, which now also handles Berkeley DB. mod_log_referer and mod_log_agent are deprecated in favor of mod_log_confug. mod_so
is automatically enabled if any other module is dynamic; otherwise, it
must be enabled explicitly in Apache 1.3 (Apache 2 always enables it
even if all modules are static). mod_mmap_static is technically experimental but stable in practice. mod_auth_digest replaces mod_digest; only one of them may be built.
Table 3-3 is the corresponding list for Apache 2.
Table 3-3. Apache 2 Included Modules
Default |
Most |
All |
Explicitly Enabled |
mod_access |
mod_auth_anon |
mod_cern_meta |
mod_cache |
mod_actions |
mod_auth_dbm |
mod_mime_magic |
mod_disk_cache |
mod_alias |
mod_auth_digest |
mod_unique_id |
mod_mem_cache |
mod_asis |
mod_dav |
mod_usertrack |
mod_charset_lite |
mod_auth |
mod_dav_fs |
|
mod_deflate |
mod_autoindex |
mod_expires |
|
mod_ext_filter |
mod_cgi/mod_cgid |
mod_headers |
|
mod_file_cache |
mod_dir |
mod_info |
|
mod_isapi (Windows only) |
|
|
|
(Continued) |
Table 3-3. Apache 2 Included Modules (Continued)
Default |
Most |
All |
Explicitly Enabled |
mod_env |
mod_rewrite |
|
mod_ldap |
mod_http |
|
|
mod_auth_ldap |
mod_imap |
|
|
mod_logio |
mod_include |
|
|
mod_proxy |
mod_log_config |
|
|
mod_proxy_connect |
mod_mime |
|
|
mod_proxy_ftp |
mod_negotiation |
|
|
mod_proxy_http |
mod_setenvif |
|
|
mod_ssl |
mod_so |
|
|
mod_suexec |
mod_status |
|
|
Example and Experimental: |
mod_userdir |
|
|
mod_bucketeer |
|
|
|
mod_case_filter |
|
|
|
mod_case_filter_in |
|
|
|
mod_echo |
|
|
|
mod_example |
|
|
|
mod_optional_hook_export |
|
|
|
mod_optional_hook_import |
|
|
|
mod_optional_fn_import |
|
|
|
mod_optional_fn_export |
Either mod_cgid or mod_cgi
is built automatically depending on whether the chosen MPM is threaded.
Modules shown indented depend on the module before them; that is, mod_mem_cache requires mod_cache.mod_logio requires mod_log_config.mod_deflate and mod_ssl require external libraries to be built; mod_file_cache, mod_cache, and mod_proxy may migrate to the all list in time. mod_http
provides basic HTTP support; it may be removed for those intending to
use Apache as a framework for a generic protocol server, but should be
kept in general use.
Options concatenate so you can specify both general and specific
options together to get the mix of modules you want with the minimum of
effort. For example, in Apache 1.3, you can specify this:
- [1.3] $ ./configure --enable-module=most --enable-module=rewrite
[1.3] $ ./configure --enable-module=all --disable-module=rewrite --disable-module=so
or in Apache 2, you can specify this:
- [2.0] $ ./configure --enable-modules=most --enable-rewrite
[2.0] $ ./configure --enable-modules=all --disable-rewrite --disable-so
Deciding what to include and exclude is made simpler if you choose
to build a dynamic server because, as I mentioned earlier, you can
simply choose to build all the modules and sort them out later. Once
the server is installed, you can then comment out the directives in the
configuration for the modules you don’t want. This only breaks down if
a module can’t be built dynamically or you want to explicitly disable mod_so
(because by definition it can’t be dynamic and load itself ). If you
change your mind later, you just uncomment the relevant directives and
restart Apache.
Building Apache As a Dynamic Server
Building Apache as a purely dynamic server is almost as simple as
building it as a static server, though the options again differ between
Apache 1.3 and Apache 2. The approach taken also differs subtly. In
Apache 1.3, you have to both enable a module and specify that it’s to
be built dynamically; neither implies the other, so if you specify that
a module is dynamic without also enabling it, it won’t get built. In
Apache 2, if you ask for it to be built dynamically, it’ll also
automatically be enabled, which is more reasonable.
The option to create modules dynamically in Apache 1.3 is --enable-shared. This takes the name of a module as an argument or the special value max,
which takes the list of enabled modules and makes dynamic any of those
modules that are capable of being loaded dynamically. The following is
fairly typical of how the majority of Apache 1.3 servers are built:
[1.3] $./configure --enable-module=all --enable-shared=max
You could also have used most or left out the --enable-module option if you wanted fewer modules compiled. max operates on the result of the combination of all the --enable-module options you specify; it doesn’t imply a particular set of modules in and of itself.
Apache 2 does away with separate options and instead provides a single combined option, --enable-mods-shared, which both enables and makes dynamic the module or list of modules you specify. As with --enable-modules, you can also specify most or all. The equivalent to the previous command in Apache 2 is this:
[2.0] $ ./configure --enable-mods-shared=all
More interestingly, you can also keep Apache a primarily static
server but make one or two modules dynamic, or vice versa, so you can
have the best of both worlds. This allows you to take advantage of the
slightly increased performance benefits of binding a module statically
into the server but at the same time keeping optional features external
to the server so that they can be removed to make Apache more
lightweight without it.
For example, mod_rewrite
is very powerful, but it’s large, so if you’re not sure whether you’ll
actually be using it, you can only make it dynamic with this (depending
on what else you’ve enabled):
- [1.3] $ ./configure --enable-module=all --enable-shared=rewrite
[1.3] $ ./configure --enable-module=most
--enable-module=rewrite --enable-shared=rewrite
You don’t need to enable mod_rewrite explicitly in the first example because it’s covered by all. Otherwise, you need to add an --enable-module=rewrite as well. Apache 1.3 doesn’t build it by default.
The equivalent for Apache 2 is this:
- [2.0] $ ./configure --enable-modules=all --enable-mods-shared=rewrite,...
[2.0] $ ./configure --enable-modules=most --enable-mods-shared=rewrite,...
Interestingly, you can also make a module shared by giving the --enable option the value shared, so you could also have said this:
[2.0] $ ./configure --enable-modules=all --enable-rewrite=shared ...
Even if you choose to build Apache statically, you can still include the mod_so
module to allow dynamically loaded modules to be added to the server
later. In Apache 1.3 you do this by enabling all modules (which
includes mod_so), making any module dynamic, or explicitly add mod_so with this:
[1.3] $ ./configure --enable-module=so ...
Conversely, Apache 2 automatically includes mod_so even in a fully static server. If you don’t want it, you must explicitly disable it using any of these:
- [2.0] $ ./configure --disable-so ...
[2.0] $ ./configure --enable-so=no ...
[2.0] $ ./configure --disable-module=so,... ...
Alternatively, you can build a mostly dynamic server with one or two modules built statically. It’s rare that you wouldn’t want mod_access or mod_mime not built into the server, so you can make them static with this:
[1.3] $ ./configure --enable-module=all --enable-shared=all --disable-shared=access
--disable-shared=mime
To do the same for Apache 2, you make use of the last argument you can give to an --enable option: static. This is the only way to reverse the status of a module from dynamic back to built-in because there are no such options as --disable-mods-shared or --enable-mods-static in Apache 2 (at least not currently):
[2.0] $ ./configure --enable-modules=all --enable-access=static
--enable-mime=static
When Apache is built from this configuration, it automatically
inserts the directives to load dynamic modules, saving you the trouble
of doing it yourself. It is, therefore, convenient to build modules
even if you don’t really need them. You can comment out the enabling
directives and uncomment them later should you change your mind.
Apache the Way You Want It - Changing the Module Order (Apache 1.3)
One of the consistent bugbears of configuring Apache 1.3 servers is getting the loading order of the modules correct. This is because the order in which the modules are loaded into the server determines the order in which the Apache core calls them to handle requests.
Apache 2 does away with all of this by allowing modules to specify
their own ordering preferences. As a result, the ordering problem no
longer exists in Apache 2, and neither do the compile-time options to
change it.
For administrators still using Apache 1.3, it remains a problem, so the configure
script provides options to allow you to reorder modules. With a dynamic
server, this step isn’t essential because you can change the order of
modules just by changing the order of the LoadModule directives that load them:
# load modules in inverse priority
LoadModule vhost_alias_module libexec/mod_vhost_alias.so
...
LoadModule setenvif_module libexec/mod_setenvif.so
However, getting the order right at compile time will result in an httpd.conf
with the modules already in the correct order. A static server has no
such ability, so the build process is the only chance you get to
determine the default running order.
Because of this, Apache 1.3 provides the ClearModuleList and AddModule
directives. These allow the running order of modules to be explicitly
defined, overriding the order in a static Apache server and the LoadModule directives of a dynamic server:
# initial loading order comprises static modules
# add dynamic modules added to the end - that is at higher priority
(LoadModule directives)
# erase existing loading order
ClearModuleList
# define new loading order
AddModule mod_vhost_alias.c
...
AddModule mod_setenvif.c
The loading order is important because modules listed later in the
configuration file get processed first when URLs are passed to modules
for handling. If a module lower down the list completes the processing
of a request, modules at the top of the list will never see the
request, and any configuration defined for them will not be used. This
is significant for two particular cases:
Authentication modules such as mod_auth, mod_auth_anon, and mod_auth_dbm
are processed in the opposite order to the order in which they’re
loaded. If you want DBM authentication to be applied first, you need to
ensure that it’s loaded last. One reason for doing this is to
authenticate most users from a database but allow Apache to fall back
to basic authentication for one or two administrators so they can still
gain access in the event the database is damaged or lost.
Aliasing and redirection modules such as mod_alias, mod_vhost_alias, mod_speling, and mod_rewrite modify URLs based on the inverse of the order in which they’re loaded. For this reason, mod_vhost_alias usually loads first, so the others have a chance to act. In addition, for mod_rewrite to be used together with mod_alias, mod_alias must be loaded first.
By looking at the configuration file, you can see the running order for dynamic servers. For static servers, httpd -l
lists the modules in the server in the order they’re loaded. Servers
can have both types of modules, in which case the static modules load
first and the dynamic ones second. You can override this by using ClearModuleList, followed by AddModule directives to reconstruct the module order. This is also the only way to make a static module come before a dynamic one.
You can alter the running order of modules at build time with the --permute-module option. This takes a parameter of two module names, which are then swapped with each other in the loading order:
$ ./configure --permute-module=auth:auth_anon
This causes mod_auth (which is normally loaded before mod_auth_anon)
to be loaded after it, so you can perform file-based authentication
before anonymous authentication. Because Apache simply swaps the
modules without regard the position of any other modules, this is most
useful when modules are adjacent or near each other, such as the
various authentication modules. This also means that the previous is
equivalent to this:
$ ./configure --permute-module=auth_anon:auth
Alternatively, you can also specify two special tokens to move a module to either the start of the list or the end:
$ ./configure --permute-module=BEGIN:vhost_alias $ ./configure --permute-module=setenvif:END
Both these examples are real-world ones. mod_vhost_alias should usually be the last of the aliasing modules to be polled as outlined previously, and mod_setenvif should usually be one of the first, so it can set variables in time for other modules to take notice of them.
The END syntax is
handy for ensuring that a module comes after another, irrespective of
their original loading order. However, it’ll also cause the module to
be processed before all other modules, which might have unforeseen side
effects. Likewise, using BEGIN to
move a module to the beginning of the list will cause it to be
processed last, which will cause problems if it needs to operate before
another module.
Fortunately, Apache’s default order is sensible and rarely needs to
be modified, so use of this option is thankfully rare, and it’s
eliminated entirely in Apache 2. In a case when it’s important to move
a lot of modules around, it’s almost always simpler to ignore the
build-time configuration and use the ClearModuleList and AddModule directives instead.
However, only modules added with an AddModule directive after ClearModuleList
will be available to the server, irrespective of whether they’re
present in the running executable. Although you can simply remove a
dynamic module, this is essentially the only way for you to disable a
statically linked module. You still incur the cost of carrying the
inactive module as a dead weight within the running server, however.
Checking the Generated Configuration
You can capture the running commentary output by the configure
script to a file for later analysis. The following command on a Unix
platform lets you view the output while the configure process runs and
also records the output in a file:
$ ./configure | tee configure.output
It’s good to check the output from the configure
script before proceeding to the compilation stage—it’ll tell you which
modules are available, and of those modules, which ones you’ve chosen
to build and which you have chosen to ignore.
It’ll also tell you whether Apache has found system libraries for
certain features or has defaulted to using an internal version or
disabling the feature—this can have potentially important ramifications
for the availability of features in the server that aren’t always
apparent otherwise. You may not immediately realize that mod_rewrite
isn’t built to use DBM database maps because it didn’t find a DBM
implementation to use unless you review the output of the configuration
process.
Similarly, Apache requires and comes bundled with a cut-down version
of the Expat XML parser. If you already have Expat installed, Apache
will use it in preference to building its own copy. This can be
important because some third-party modules and frameworks can sometimes
behave unreliably if Apache uses a different Expat from the rest of the
system. The solution is simple: If you do have Expat but in a directory
Apache doesn’t expect, then you need to add the --with-expat= <directory> option.
See the section “Configuring Apache’s Library and Include Path”
later in the chapter for more on this and other features that may
require additional coaxing including DBM, LDAP, and SSL support.
Both Apache 1.3 and Apache 2 store their default configuration
information in a template file and generate an active configuration
from it according to the options you request and the capabilities of
the operating system. Although you don’t need to worry about this in
most cases, it can be handy to refer to the files containing the
generated configuration both to check the results and also to redo the
configuration if need be.
The Generated Configuration in Apache 1.3
Apache 1.3 holds most of its default configuration in a file called Configuration in the src directory,
and it’s still possible, although largely deprecated in these more
modern times, to configure Apache by editing it. Examining it can also
be educational as a glimpse into how Apache is put together, even if
you choose not to build Apache yourself.
The Apache 1.3 configuration process results in a file called src/Configuration.apaci (so as not to overwrite src/Configuration) and then uses a second script, src/Configure,
to produce the files necessary for building Apache based on its
contents. You use this script directly if you edit the Apache 1.3 Configuration file by hand; you can also use it to set up the Apache source without altering the configuration settings.
The Generated Configuration in Apache 2
Apache 2 has an almost completely overhauled build configuration
system that’s much more easily maintained, as well as being more
extensible and similar to other packages that also use autoconf.
Despite this, it behaves almost exactly like the familiar APACI
configuration interface of Apache 1.3. As a result, most aspects of
configuring an Apache source distribution are the same for either
version of the server, but there are just enough differences to be
inconvenient.
Apache 2 holds most of its default configuration in a file called configure.in, which is presupplied, but it can be regenerated using the buildconf script
provided. However, this should only ever be necessary for developers
who are pulling the Apache source code from the code repository via
CVS. This file isn’t designed for editing— Apache 2 intends to
determine as much as possible from the platform and the rest from
arguments to the configure script, rather than encourage hand editing of preset values.
The Apache 2 configuration process generates build instructions
throughout the source tree and additionally creates some useful files
that allow you to check and re-create the results:
- config.nice: This file contains a formatted multiline command line for rerunning the configure
script using the same arguments you passed to it the first time. This
makes it an executable script that allows you to repeat your steps, as
well as provide a convenient way to modify and store your configuration
parameters.
- config.log: This file contains any messages that were
produced by the compiler during the various build checks. Usually,
it’ll contain nothing except a few line number references from configure. These are intended to prefix the different points at which messages might arise, should any appear.
- config.status: This file contains a script that
performs the actual configuration of the source tree using the options
that were specified by configure but without analyzing the operating system for the build criteria, stored in config.cache.
Apache the Way You Want It - Building Apache from Source As an RPM (Apache 2)
Recent releases of the Apache 2 source distribution contain an RPM .spec file that you can use to build Apache as an installable RPM. The httpd.spec
file contains all the details needed to build a default Apache
installation and can be used without even unpacking the source archive
with this:
$ rpm -tb httpd-2.0.47.tar.gz
This tells the RPM tool to look inside a .tar file for the .spec file (-t) and to build only binary RPMs (-b). Configuration and building of Apache takes place automatically and should result in four RPM files being generated in /usr/src/packages/RPMS/i386 (this path may vary according to Linux distribution and processor architecture):
httpd-2.0.47-1.rpm
httpd-devel-2.0.47-1.rpm
httpd-ssl-2.0.47-1.rpm
For the build to be successful, you’ll need to have several other packages installed first, notably perl and findutils, but the build prerequisites also include pkgconfig, expat-devel, db3-devel, and openldap-devel. To get SSL support, you also need openssl-devel. Each of the -devel packages in turn needs its parent package, and these in turn may have other dependencies.
This is, however, misleading: It’s possible you might need all of
these packages, but you can also build an RPM package that doesn’t. You
can—and should—edit the httpd.spec file to eliminate dependencies you don’t require. For example, openldap is needed only if you want mod_ldap, and mod_auth_ldap.pkgconfig is needed only on some Linux distributions. Likewise, db3 is needed only if you want mod_auth_dbm to be able to handle Berkeley DB format databases. Similarly, expat-devel
is needed only if you want Apache to build with an existing Expat XML
parser installation; otherwise, it’ll happily build using the cut-down
version that’s included in the Apache source.
These dependences exist because the build instructions in httpd.spec include the modules that require them, but you can remove unnecessary packages from the BuildReq: line so long as you also remove the dependant modules. At the same time, if you want to ensure that the optional httpd-ssl package is built (in other words, make it mandatory), you add openssl-devel:
BuildPrereq: openldap-devel, db3-devel, expat-devel, findutils, perl, pkgconfig
becomes this:
BuildReq: perl, findutils, openssl-devel
Within the httpd.spec file is a configure command, which is most easily locatable by searching for a --prefix command line argument. You can customize this using all the criteria and strategies I’ve already discussed for a stand-alone configure command,
with the advantage of creating an installable package as the end
product. You should remove any part of the command you don’t
need—particularly modules that you don’t need but also directory
locations. You should also add a layout to provide the basic structure
of the installed server. You can even merge the SSL package into the main server, if you want to eliminate it as a separately installable component.
Because you want to edit the .spec file, it’s easiest to extract it singly from the archive and then build it using the -b option to RPM. This requires that the original archive file is present where rpm looks for it, in the SOURCES subdirectory of the RPM system:
$ tar zxvf httpd-2.0.47.tar.gz httpd-2.0.47/httpd.spec
$ mv httpd-2.0.47/httpd.spec .
...edit httpd.spec...
$ cp httpd-2.0.47.tar.gz /usr/src/packages/SOURCES
$ rpm -bb httpd.spec
If all goes well, this should generate Apache RPMs built according
to your precise specifications, including whichever modules and
features you want included. You can store the httpd.spec
file somewhere safe and reuse it any time to regenerate your Apache
setup. As new releases of Apache are made available, you can move your
changes into the new httpd.spec (assuming it has changed) with a minimum of fuss and build those according to the same criteria as before.
Apache the Way You Want It - Advanced Configuration
The configuration options you’ve considered so far are enough for many purposes, and certainly sufficient for setting up a test server.
However, there are many more advanced options at your disposal, ranging
from the useful to the curious to the downright obscure. This is
especially true of Apache 2, which provides many autoconf-derived options that, although available, aren’t actually that useful in Apache.
Of these options, the most immediately useful are the layout options
that determine both where Apache’s files are installed and where Apache
expects to find them by default. Other advanced features include the
build type for cross-platform builds, platform-specific rules, and
locating external packages required by some of Apache’s own features.
Configuring Apache’s Layout
You’ve already seen how --prefix defines the installation root for Apache. However, configure allows several more options to customize the location of Apache’s files in detail.
Choosing a Layout Scheme
The default layout for Apache consists of an installation path in /usr/local/apache,
with the various other directories placed underneath. However, it’s
possible to completely configure the entire layout. To make life
simple, the configure script accepts a named layout defined in a file called config.layout
that’s supplied with the Apache source distribution. This contains many
alternative layouts that can be chosen by specifying their name on the configure command line:
[1.3] $ ./configure --with-layout=Apache
[2.0] $ ./configure --enable-layout=Apache
This tells configure to use the Apache layout (this is in fact the default), which causes it to select the Apache layout record in config.layout:
# Classical Apache path layout.
<Layout Apache>
prefix: /usr/local/apache
exec_prefix: $prefix
bindir: $exec_prefix/bin
sbindir: $exec_prefix/bin
libexecdir: $exec_prefix/modules
mandir: $prefix/man
sysconfdir: $prefix/conf
datadir: $prefix
installbuilddir: $datadir/build
errordir: $datadir/error
iconsdir: $datadir/icons
htdocsdir: $datadir/htdocs
manualdir: $datadir/manual
cgidir: $datadir/cgi-bin
includedir: $prefix/include
localstatedir: $prefix
runtimedir: $localstatedir/logs
logfiledir: $localstatedir/logs
proxycachedir: $localstatedir/proxy
</Layout>
From this it’s clear which values control which locations and how the various values depend on each other; the installbuilddir and errordir
locations are new to Apache 2, but otherwise the locations understood
by the two versions are identical. The default layout in Apache 1.3
differs from the previous Apache 2 layout only in the name of the libexec directory; it’s $exec_prefix/libexec in Apache 1.3.
There are ten other layouts defined in config.layout. Note that case is important and that GNU is a valid parameter, but gnu or Gnu aren’t.
Table 3-4 details the available layouts along with their main
installation prefix (though many of them adjust specific locations in
addition).
Table 3-4. Layout Choices
Layout |
Description |
GNU |
Installs files directly into subdirectories of /usr/local rather than in a separate /usr/local/apache directory. The httpd binary thus goes in /usr/local/bin and the manual pages in /usr/local/man. |
MacOS X Server |
Installation paths for MacOS X Server (a.k.a. Rhapsody) operating system (prefix /Local/Library/WebServer). |
Darwin |
Installation paths for MacOS X (a.k.a. Darwin). This is the consumer version found on desktop machines, as opposed to the server edition, and has a significantly different layout (prefix /usr). |
RedHat |
Installs
files in the default locations for RedHat Linux. This is typically used
in the construction of RPM packages for RedHat and is also suitable for
RedHat-based distributions such as Mandrake Linux (prefix /usr). |
beos |
Installation paths for the BeOS operating system (prefix /boot/home/ apache). |
SuSE |
Installs files in the default locations for SuSE Linux.
This is typically used in the construction of RPM packages for SuSE and
is also suitable for UnitedLinux distributions (prefix /usr). |
OpenBSD |
Installs files in the default locations for OpenBSD (prefix /var/www). |
BSDI |
Installs files in the default locations for BSDI’s commercial BSD variant |
|
(prefix /var/www). |
Solaris |
Installs files in the default locations for Solaris (prefix /usr/apache). |
The Binary Distribution Layout
In addition to the standard layouts previously, there’s also one special layout, BinaryDistribution.
This is provided to build Apache for packaging and distribution. The
distribution may then be unpacked and installed on the target machine
or machines, with the installation root chosen at the time of
installation. All other locations are defined as relative directories.
This allows you to create an archive containing your own complete
custom Apache. You can then unpack and install it into the correct
location on multiple machines.
Because the creation of a binary distribution is more involved than a straightforward build and install, Apache 2 provides the binbuild.sh and install-bindist.sh scripts, located in the build directory under the top source distribution directory, to help you do it. To use binbuild.sh, you first need to edit it and modify the configure options defined in CONFIGPARAM to build the Apache server you want (don’t change the layout from BinaryDistribution). Then run the following from the top directory of the source distribution:
$ ./build/binbuild.sh
This will configure and build Apache as a binary distribution and
then package it into an archive named for the Apache version and target
host. For example, on a Pentium III Linux server, the resulting archive
would be called as so:
httpd-2.0.46-i786-pc-linux.tar.gz
You also get a readme file explaining how the archive was built:
httpd-2.0.46-i786-pc-linux.README
These files appear next to the unpacked source distribution—that is, the directory above where you actually ran binbuild.sh.
You can now transfer and unpack the archive onto any Linux server on
which you want to install Apache. After unpacking it, you use the install-bindist.sh script. This takes one argument, the server root where Apache is to be installed, for example:
$ ./install-bindist.sh /usr/local/apache_dist
You can also run this script directly from the source directory where you ran binbuild.sh if you want to install the distribution on the same host.
This will copy and set up the Apache distribution so that it’s
configured to run from the specified directory. Once this is done, you
can dispense with the original unpacked archive. The default server
root, if you don’t specify one, is /usr/local/apache2; this can be changed by editing DEFAULT_DIR at the same time as CONFIGPARAM before you run binbuild.sh. Note that install-bindist.sh is itself generated by binbuild.sh and doesn’t exist except in the build directory of the archives generated by it.
Another file that’s generated by binbuild.sh is the envvars file located adjacent to apachectl in the selected location for executables. apachectl reads envvars to
determine the correct environment to start Apache with. For a binary
distribution, this typically involves adding additional shared library
paths to LD_LIBRARY_PATH
(or a similar variable, depending on the platform) so that Apache can
find dynamic modules. This is a necessary step because Apache’s
installation directories weren’t known at the time you built it for
distribution. For a normal undistributed installation, this file
contains no active definitions. An original unmodified version of this
file is also provided as envvars-std, for reference, if you change envvars.
Adding and Customizing Layouts
It’s also possible to add your own custom layouts to the file by
adding a new definition with the name of your layout, for example:
# My custom Apache layout
<Layout AlphaComplex>
... locations ...
</Layout>
Although it’s not used in the default Apache layout, you can also use the special suffix + on locations to indicate that the name of the server (as defined by --target or --with-program
name in Apache 1.3 and 2, respectively) should be added to the end of
the path. For example, in the Darwin layout, you find this definition
for the log directory:
logfiledir: ${localstatedir}/log+
As localstatedir is set to /var in the Darwin layout, this means that (with a program name of osxhttpd) Apache’s log files will, in this layout scheme, be located here:
/var/log/osxhttpd
If you don’t want to edit the supplied layout.conf file, you can instead use your own file by prefixing the filename to the layout name:
[1.3] $ ./configure --with-layout=mylayout.conf:bespoke
[2.0] $ ./configure --enable-layout=mylayout.conf:bespoke
You can also specify a layout file outside the Apache source
distribution if you want. This makes it easy to maintain a local
configuration and build successive Apache releases with it.
The alternative to defining your own layout is to specify each of
the layout paths on the command line with individual options. The
approach you choose depends for the most part on how many locations you
want to change.
You can check the effect of a layout scheme with the --show-layout option. This causes the configure script
to return a list of the configured directories and defaults instead of
actually processing them, for example (using an Apache 1.3 source
distribution):
[1.3] $ ./configure --target=osxhttpd --with-layout=Darwin --show-layout
Apache the Way You Want It - Determining Apache’s Locations Individually
Each of Apache’s locations can also be set
individually, including a few rare ones that aren’t (at least, as yet)
permitted in the layout. The list of available options, with their
defaults in the Apache layout, is detailed in Table 3-5.
Table 3-5. Configuration Directives Relating to Locations
Option |
Description |
--with-program-name=NAME (2.0) Installs name-associated files using the base name of |
--target=NAME (1.3) |
NAME. This changes the name of the Apache executable |
from httpd to NAME and also changes the default names |
of the configuration, scoreboard, process ID, and lock |
files—httpd.conf becomes NAME.conf, and apachectl |
becomes NAMEctl, and so on. This can be useful, along |
with --runtimedir for running a second instance of |
Apache with a different configuration in parallel with an |
existing one. |
The default is httpd. In Apache 1.3 this option is called |
--target, but in Apache 2 it has been renamed to |
--with-program-name to make way for the new portability |
options --target, --host, and --build. |
--prefix=PREFIX |
Installs architecture-independent files in PREFIX. This |
determines the primary installation location for Apache |
and the default value of the server root, for instance, |
/usr/local/apache under Unix. Most other locations |
default to subdirectories of this value. |
--exec-prefix=EPREFIX |
Installs architecture-dependent files (meaning |
|
principally compiled executables) in EPREFIX. This |
|
determines the root location of executable files, from |
|
which the --bindir, --sbindir, and --libexec directories |
|
are derived (if specified as relative values). It defaults to |
|
the same value as PREFIX if unspecified. |
--bindir=DIR |
Installs user executables and scripts in DIR. Usually |
|
located in the bin directory under EPREFIX. |
--sbindir=DIR |
Installs sys admin executables in DIR [EPRIFIX/sbin]. |
--libexecdir=DIR |
Installs program executables in DIR. This defines the |
|
location of Apache’s dynamic modules, if any are |
|
installed. Usually located in the libexec (1.3) or modules |
|
(2.0) subdirectory under EPREFIX. |
--mandir=DIR |
Installs Unix manual pages for each of Apache’s |
|
executables in DIR. Usually located in the man directory |
|
under PREFIX. Not to be confused with --manualdir. |
--sysconfdir=DIR |
Installs configuration files such as httpd.conf and |
|
mime.types in DIR. Usually located in the conf directory |
|
under PREFIX. |
|
(Continued) |
Table 3-5. Configuration Directives Relating to Locations (Continued)
Option |
Description |
--datadir=DATADIR |
Installs read-only data files in DATADIR. This determines |
|
the root location of all nonlocal data files, from which the |
|
--installbuilddir, --errordir, --iconsdir, --htdocsdir, |
|
--manualdir, and --cgidir directories are derived, if |
|
specified as relative values. It defaults to the same value |
|
as PREFIX if unspecified. |
--errordir=DIR |
Installs custom error documents into DIR. These are |
|
referred to by ErrorDocument directives in the main |
|
configuration file and produce nicer, and multilingual, |
|
error messages than Apache’s built-in ones. Usually |
|
located in the error directory under DATADIR. New in |
|
Apache 2. |
--iconsdir=DIR |
Installs icons for directory indexing into DIR. AddIcon |
|
directives in the main configuration file refer to these. |
|
Usually located in the icons directory under DATADIR. |
|
New in Apache 1.3.10. |
--infodir=DIR |
Installs documentation in GNU "info" format into DIR. |
|
Apache itself doesn’t come with any information |
|
documentation, but third-party modules might. Not |
|
created by default but, is usually located in the info |
|
directory under DATADIR. New in Apache 2. |
--htdocsdir=DIR |
Installs the default Apache startup Web page into DIR. |
|
The master configuration uses this directory as the initial |
|
value for the DocumentRoot directive. New in Apache 1.3.10. |
--manualdir=DIR |
Installs Apache’s HTML documentation into DIR. Usually |
|
located in the manual directory under DATADIR. Not to be |
|
confused with --mandir. New in Apache 1.3.21. |
--cgidir=DIR |
Installs the standard Apache CGI scripts into DIR. Usually |
|
located in the cgi-bin directory under DATADIR. The |
|
master configuration file points to this directory via a |
|
ScriptAlias directive. New in Apache 1.3.10. |
--includedir=DIR |
Installs Apache’s header files in DIR. These are required |
|
by apxs to compile modules without the full Apache |
|
source tree available. Usually located in the include |
|
directory under PREFIX. |
--libdir=DIR |
Installs Apache’s nonmodule object libraries in DIR. |
|
Usually located in the lib directory under PREFIX. New in |
|
Apache 2. |
--localstatedir=LOCALDIR |
Installs modifiable data files in DIR. This defines where |
|
files that convey information about a particular instance |
|
of Apache are kept. It usually governs the locations of the |
|
runtime, log file, and proxy directories below. Usually the |
|
same as PREFIX. |
--runtimedir=DIR |
Installs run-time data in DIR. This determines the default |
|
locations of the process ID, scoreboard, and lock files. |
|
Usually located in the logs subdirectory under LOCALDIR. |
Table 3-5. Configuration Directives Relating to Locations (Continued)
Option |
Description |
--logfiledir=DIR |
Installs log file data in DIR. This determines the default locations of the error and access logs. Usually located in the logs subdirectory under LOCALDIR. |
--proxycachedir=DIR |
Installs proxy cache data in DIR. This determines the default location of the proxy cache. Usually located in the proxy subdirectory under LOCALDIR. |
--sharedstatedir=DIR |
Installs shared modifiable data files in DIR. Not created by default, but usually the same as PREFIX. New in Apache 2. |
When considering this list, it’s worth remembering that the
directory organization is actually an artifact of the layout
definitions in config.layout and not an implicit default; there’s nothing that automatically decides that the bin and sbin directories are under EPREFIX. The same is true for DATADIR and LOCALSTATEDIR—both define paths that are only used as the basis for the default values of other options in config.layout. If you create your own layout that doesn’t make use of them, they have no significance.
You can also combine a layout configuration with an individual location option. The configure script
reads the layout first and then overrides it with individual options.
For example, you can explicitly request the Apache layout and then
override the sbin directory so it’s different from the normal bin directory:
[1.3] $ ./configure --with-layout=Apache --sbindir=/usr/local/apache/sbin
[2.0] $ ./configure --enable-layout=Apache --sbindir=/usr/local/apache/sbin
As a final trick, you can actually use the variables in the layout
definition as part of individual location options. For example, the --exec_prefix option can be accessed with $exec_prefix.
You need to escape the dollar to prevent the shell from trying to
evaluate it, so the second command in the previous code could be
written more flexibly as this:
$ ./configure --enable-layout=Apache --sbindir=\$exec_prefix/sbin
You can do this for any of the values defined in config.layout, which allows you to customize any predefined layout without editing it.
To check that you’ve got everything right, use the --show-layout option:
$ ./configure --enable-layout=Apache --sbindir=\ $exec_prefix/sbin --show-layout
This also has the benefit of providing the names of the values you can use in your own modifications (by prefixing them with a $).
Apache the Way You Want It - Choosing a MultiProcessing Module (Apache 2)
One of the key innovations arising from the development of Apache 2 is the introduction of a fully multithreaded server
core, and the ability to choose from one of several possible cores that
implement different strategies for dealing with large numbers of
accesses.
The available server cores, known as MPMs, vary depending on the
platform you’re going to build Apache on. The greatest choice is
available to Unix derivatives such as Linux and MacOS X; the only other
platform that provides a choice is OS/2. MPMs are also available for
Windows, NetWare, and BeOS—if you’re on one of these platforms, then
Apache will automatically choose the appropriate MPM for you.
Remarkably, considering that the MPM is the central component of the
server that implements all of the core server directives, the only
option you have to worry about when choosing one is the --with-mpm option. For example, to explicitly tell Apache to use the worker MPM, you would use this:
$ ./configure --with-mpm=worker ...
The choice of MPM is closely related to the kind of usage pattern
you expect your server to experience, so it is primarily a performance
decision. Accordingly, I’ll cover it in detail in Chapter 9 and
summarize the configuration directives and build-time definitions in
Online Appendix J. For now, I’ll outline the options available with
brief notes on their characteristics.
Unix MPMs
Five MPMs are available for Unix platforms. The prefork and worker
MPMs are the two primary choices, offering 1.3 compatibility and
support for threads, respectively. Three other MPMs are also available
for the more adventurous administrator; leader and threadpool are variants of worker that use different strategies to manage and allocate work to different threads. The perchild MPM is more interesting; it allows different virtual hosts to run under different user and group IDs.
prefork
The prefork MPM implements a preforking Apache server
with the same characteristics and behavior as Apache 1.3. It doesn’t
benefit from the performance gains made possible using threads, but
it’s the most compatible with Apache 1.3 and therefore may offer a more
direct and convenient migration route. The following is an example of
its usage:
$ ./configure --with-mpm=prefork
worker
The worker MPM implements a fully threaded Apache server and is the primary MPM for use on Unix servers.
Rather than forking a process for each incoming request, it allocates a
thread from an existing process instead. Because threads share code and
data, they’re much more lightweight, and many more can exist
concurrently. They’re also much faster to start up and shut down. The
number of threads allowed to an individual process is limited; once
it’s reached, a new child process is forked:
$ ./configure --with-mpm=worker
leader
The leader MPM is an experimental variant of the worker MPM
that uses a different algorithm to divide work up between different
threads using the leader/follower design pattern. Although it’s
structured differently internally, it’s almost identical to worker from the point of view of configuration:
$ ./configure --with-mpm=leader
threadpool
Another experimental variant of the worker MPM, threadpool manages queues of threads and assigns them to incoming connections. In general, usage threadpool isn’t as efficient as worker and is primarily used as a development sandbox for testing features before they’re incorporated into other MPMs:
$ ./configure -with-mpm=threadpool
perchild
The perchild MPM implements an interesting variation of the worker MPM, where a child process is forked for each virtual server
configured in the server configuration. Within each process, a variable
number of threads are started to handle requests for that host. Because
of the alignment of processes to virtual hosts, the child processes can
run under the configured user and group for that host, permitting
external handlers and filters to run with the correct permissions and
obviating the need for the suExec wrapper:
$ ./configure -with-mpm=perchild
Although technically classed as experimental in Apache 2, the perchild MPM is unique in its capability to manage ownerships on a virtual host basis. For administrators who make extensive use of suExec and who want to enable the same permissions controls for mod_perl handlers, PHP pages, and other embedded scripting languages, perchild is the only choice.
Windows MPMs
The following option is the Windows-based option.
winnt
The winnt MPM is
the only Windows MPM supplied as standard with Apache 2. It implements
a single process, multithreaded server using the threading
implementation supported by Windows platforms. Despite its name, it
also works fine on Windows 2000 and XP. (Multiple process MPMs aren’t
practical on Windows platforms because they don’t implement anything
similar to the fork system call of Unix). The following is an example of its usage:
$ ./configure --with-mpm=winnt
OS/2 MPMs
The following option is specific to OS2.
The mpmt_os2 MPM implements a multiprocess (that is, forking), multithreaded server for OS/2. Like the worker MPM,
each process contains a limited number of threads, with a new process
spawned when the server becomes too busy to allocate a thread from an
existing process:
--with-mpm=mpmt_os2
Others
The following are specific to NetWare and BeOS and followed by an example.
netware
The netware MPM provides a multithreaded server on NetWare platforms:
$ ./configure --with-mpm=netware
beos
The beos MPM provides a multithreaded server on BeOS platforms:
./configure --with-mpm=beos
Rules (Apache 1.3)
Rules are special elements of the Apache 1.3 source that can be
enabled or disabled to provide specific features that depend on the
platform or other resources being available. These are more specialized
options that should generally only be overridden if actually necessary.
Apache 2 is quite different internally, so it does away with rules
entirely in favor of a more platform-sensitive build environment.
Rules are enabled or disabled with the --enable-rule and --disable-rule options. For example, to enable SOCKS5 proxy support, you’d specify this:
$ ./configure --enable-rule=SOCKS5
The list of rules and whether they’re enabled, disabled, or default (that is, determined automatically by configure) can be extracted from the output of configure --help. Third-party modules that patch Apache’s source code generally do it by adding a rule; for instance, mod_ssl adds the EAPI rule. The following is the list of standard rules:
DEV_RANDOM: Enables access to the /dev/random
device on Unix systems, which is necessary for modules that need a
source of randomness. Currently, the only module that needs this is mod_auth_digest, so configure will only enable this rule if mod_auth_digest is included. This is enabled by default.
EXPAT: Incorporate the Expat XML parsing library into Apache
for use by modules that process XML. There are no modules in the Apache
distribution at the moment that do, but third-party modules such as mod_dav can take advantage of it if present. This rule is enabled by default only if configure finds a lib/expat-lite directory in the src directory. In Apache 2, you can also use --enable-expat or --disable-expat. This is enabled by default since Apache 1.3 onward.
IRIXN32, IRIXNIS: These are specific to SGI’s IRIX operating system. IRIX32 causes configure to link against n32 libraries if present. It’s enabled. IRIXNIS applies to Apache systems running on relatively old versions of NIS, also known as Yellow Pages. It’s not enabled. Neither option is of interest to other platforms.
PARANOID: In Apache 1.3, modules are able to specify shell commands that can affect the operation of configure. Normally, configure just reports the event; with the PARANOID rule enabled, configure
prints the actual commands executed. Administrators building in
third-party modules may want to consider using this and watching the
output carefully. This rule isn’t enabled by default.
SHARED_CORE: This exports the Apache core into a dynamic
module and creates a small bootstrap program to load it. This is only
necessary for platforms where Apache’s internal symbols aren’t
exported, which dynamic modules require to load. The configure script will normally determine whether this is necessary. It’s included by default. This rule is enabled by default.
SHARED_CHAIN: On some platforms, dynamic libraries (which
include modules) won’t correctly feed the operating system information
about libraries they depend on when Apache is started. For example, mod_ssl
requires the SSLeay or OpenSSL library. If it’s compiled as a dynamic
module, Apache isn’t always told that it needs to load the SSL
libraries, too. On systems where this problem occurs, enabling the SHARED_CHAIN
rule can sometimes fix the problem. On other systems, it may cause
Apache to crash, so enable it only if modules are having problems
resolving library symbols. This rule is enabled by default.
SOCKS4,SOCKS5: These enable support for the SOCKS4 and SOCKS5 proxy protocols, respectively. If either option is selected, then the appropriate SOCKS library may need to be added to EXTRA_LIBS if configure can’t find it. These aren’t enabled by default.
WANTHSREGEX: Apache comes with a built-in regular expression engine that’s used by directives such as AliasMatch
to do regular expression matching. Some operating systems come with
their own regular expression engines that can be used instead if this
rule is disabled. configure
uses Apache’s own regular expression engine unless the
platform-specific configuration indicates otherwise. This rule is
enabled by default.
On the vast majority of platforms, rules such as SHARED_CHAIN shouldn’t need to be set by hand. In the event they are, an alternative and potentially preferable approach to enabling the SHARED_CHAIN rule is to use Apache’s LoadFile directive to have Apache load a library before the module that needs it, for example:
LoadFile /usr/lib/libopenssl.so
LoadModule ssl_module libexec/libssl.so
Note that the library on which the module depends should be loaded
before the module to allow it to resolve symbols supplied by the
library successfully.
You can find a little more information about some of these rules in the Apache 1.3 src/Configuration file. For detailed information on exactly what they do, look for the symbols in the source code, for example:
$ grep -r SOCKS5 apache_1.3.28 | less
Apache the Way You Want It - Building Apache with suExec support
suExec is a security wrapper for Unix systems that runs CGI scripts under a different user and group identity than the main server.
It works by inserting itself between Apache and the external script and
changing the user and group of the external process to a user and group
configured for the server or virtual host.
This allows you to have each virtual host run scripts under its
privileges and thus partition them from each other. Before you build suExec, it’s worth considering that Apache 2 provides a different solution to the same problem in the shape of the perchild multiprocessing module, which allows you to define a user and group identity per virtual host.
To get suExec support, you must tell Apache to use it at build time with the --enable-suexec option:
$ ./configure --enable-suexec
On its own, this is rare enough, however. For suExec to
actually work, it also needs to have various configuration options set.
None of these are configurable from Apache’s configuration to keep the suExec
wrapper secure from tampering, so if you need to set them, you must
define them at build time. Some of the defaults are also slightly odd
and aren’t governed by selecting an Apache layout, so if you use a
different layout, you’ll probably need to set some of them.
NOTE suExec is built so that it can only be run by the user and group of the main server as configured at build time. If you want to have suExec run by any User other than the default, then it’s not enough to change the settings of the User and Group directives in the server-level configuration—they must also be defined at build time so that suExec recognizes them. |
Of particular note are the minimum values of the user and group ID and the document root. The user and group IDs are lower limits that are compared to Apache’s User and Group settings. They constrain the user and group under that suExec
will allow itself to be run. This prevents the root user being
configured, for example. If you want to use your own user and group
with suExec, then you
have to ensure that the correct settings are established up front; if
you change them later to something below the allowed minimum values,
then you must rebuild suExec or it’ll detect that it’s being run by the wrong user or group and refuse to cooperate.
The document root setting is slightly misnamed; it determines where suExec
will permit executables to be run from. For a single Web site, it
should be the document root, but for virtual hosts, it should be a
parent directory that’s sufficiently broad enough to include all the
virtual host document root directories somewhere beneath it. For
example, if you have all your virtual hosts under /home/www/ virtualhostname, then the document root for suExec should be /home/www.
Table 3-6 lists all the configure options that control suExec.
Table 3-6. suExec Configure Script Options
Option |
Description |
[1.3] --server-uid=UID |
Sets the user ID that Apache will run under, and that |
[2.0] --with-server-uid=UID |
suExec will allow execution by. The default is nobody. |
[1.3] --server-gid=GID |
Sets the group ID that Apache will run under and that |
[2.0] --with--server-gid=GID |
suExec will allow execution by. The default is nobody |
|
under Apache 1.3 and #-1 under Apache 2. |
[1.3] --suexec-caller=NAME |
Sets the name of the user that’s allowed to call suExec. |
[2.0] --with-suexec-caller=NAME |
This should be set to the name of the User directive in |
|
httpd.conf. The default is www. |
[1.3] --suexec-docroot=DIR |
Sets the root directory of documents governed by |
[2.0] --with-suexec-docroot=DIR |
suExec. This affects the user directory processing of |
|
suExec. The default is PREFIX/htdocs. |
[1.3] --suexec-logfile=FILE |
Determines the location of suExec’s log file. By default |
[2.0] --with-suexec-logfile=FILE |
this is the master server log directory. |
[1.3] --suexec-userdir=DIR |
Specifies the name of the subdirectory as inserted into |
[2.0] --with-suexec-userdir=DIR |
URLs by mod_userdir. If user directories are in use |
|
and implemented by mod_userdir (as opposed to |
|
mod_rewrite, say), suExec needs to know what the |
|
substituted path is to operate correctly. The default is |
|
public_html, which is also the default of the UserDir |
|
directive in mod_userdir. |
[1.3] --suexec-uidmin=UID |
Specifies the minimum allowed value of the User |
[2.0] --with-suexec-uidmin=UID |
directive when evaluated as a numeric user ID. The |
|
default is 100, restricting access to special accounts, |
|
which are usually under 100 on Unix systems. |
[1.3] --suexec-gidmin=UID |
Specifies the minimum allowed value of the Group |
[2.0] --with-suexec-gidmin=UID |
directive when evaluated as a numeric group ID. The |
|
default is 100, restricting access to special accounts, |
|
which are usually under 100 on Unix systems. |
[1.3] --suexec-safepath=PATH |
Defines the value of the PATH environment variable |
[2.0] --with-suexec-safepath=PATH |
passed to CGI scripts. This should only include |
|
directories that are guaranteed to contain safe |
|
executables. The default is /usr/local/bin:/usr/ |
|
bin:/bin. Paranoid administrators may want to |
|
redefine this list to remove /usr/local/bin, or |
|
redefine it to nothing. |
[1.3] --suexec-umask=UMASK |
Specifies the maximum permissions allowed in the |
[2.0] --with-suexec-umask=UMASK |
user file-creation mask of the suExec executable as an |
|
octal number. By default the server’s umask is used, |
|
usually 022 (no group or other execute permission). |
|
This is also the hard limit, and suExec will refuse to |
|
even compile with a more generous setting. You can |
|
make the event more restrictive, however. To have |
|
suExec refuse to execute anything that’s group- |
|
writable, world-writable, or world-readable, use a |
|
umask of 026 (new in Apache 1.3.10). |
This requirement of forcing suExec
to be configured at compile time rather than runtime may seem more than
a little inconvenient, but this deliberate inflexibility has more than
a little to do with the fact that Apache has a very good reputation for
security. If you compare this to the almost continual litany of
exploits for some less popular proprietary Web servers that emphasize
convenience over security, it becomes easier to put up with this
relatively minor sort of inconvenience for the greater security it
gives you.
To find out what settings an existing suExec binary has been compiled with, you can use the -V option, for example:
$ /usr/local/apache/bin/suexec -V
-D AP_DOC_ROOT="/home/sites"
-D AP_GID_MIN=100
-D AP_HTTPD_USER="httpd"
-D AP_LOG_EXEC="/usr/local/apache/logs/cgi.log"
-D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
-D AP_UID_MIN=100
-D AP_USERDIR_SUFFIX="public_html"
suExec is installed into the bin directory (it moved here from the sbin
directory since Apache 1.3.12; if these are set to the same place, the
distinction is moot). Also, Apache 2 abstracts support for suExec within Apache itself into the new mod_suexec module and installs this into the configured libexec directory. This is potentially very handy because it allows you to disable suExec support by removing the module and add it later if you need it. Apache 1.3 doesn’t allow you this freedom as it integrates suExec support into the core.
NOTE In this chapter I’ll cover building and installing of suExec. I’ll cover the configuration and set up of suExec in Chapter 6. |
Configuring Apache’s Supporting Files and Scripts
As well as configuring the build process for Apache itself, configure
also sets up the various supporting scripts and applications that come
as standard with Apache. These range from shell scripts such as apachectl through Perl scripts such as dbmmanage and apxs to compiled binaries.
After the Apache executable has been built, the configuration
process carries out some additional stages to clean it of unnecessary
symbol information (useful for debugging but useless baggage for a
production environment) and to substitute your configuration
information into Apache’s supporting configuration files and scripts.
As with everything else, you can impose some control over this as
well. Table 3-7 shows the options that control which of these stages
are carried out by configure.
Table 3-7. Apache 1.3 Configure Options for Supporting Files and Scripts
Option |
Description |
Compatibility |
--with-perl=FILE |
The location of the local Perl interpreter. This is |
Apache 1.3 only |
required by several of Apache’s support scripts, |
|
including apxs and dbmmanage. Normally, configure |
|
works out the location automatically, but if Perl is |
|
installed somewhere obscure or there’s more than |
|
one interpreter, this option tells configure which |
|
of the scripts to use. |
|
--without-support |
Tells configure not to set up, compile, or install |
Apache 1.3 only |
any of the supporting applications. |
|
--without-confadjust Tells configure not to substitute information |
Apache 1.3 only |
derived at the configuration stage into the |
|
installed Apache configuration files. |
|
In Apache 2, you can also choose whether those supporting tools that
are built from source are linked statically or dynamically, in much the
same way as you can choose the static or dynamic status of modules. All
of these tools are built dynamically by default, but you can make some
or all of them into statically linked executables with one of the
options in Table 3-8.
Table 3-8. Apache 2 Configure Options for Statically Linking Support Files and Scripts
Option |
Description |
--enable-static-support |
All support executables are built statically. |
--enable-static-ab |
The Apache benchmarking tool ab is built statically. |
--enable-static-checkgid |
The group ID checking tool checkgid is built statically. |
--enable-static-htdbm |
The DBM-based basic authentication password tool htdbm is |
|
built statically. |
--enable-static-htdigest |
The file-based digest authentication password tool htdigest |
|
is built statically. |
--enable-static-htpasswd |
The file-based basic authentication password tool htpasswd |
|
is built statically. |
--enable-static-logresolve |
The IP to hostname DNS resolver logresolve is built |
|
statically. |
--enable-static-rotatelogs |
Apache the Way You Want It - Configuring Apache 2 for Cross-Platform Builds
One of Apache’s great strengths is its ability to run on almost any
platform. Apache 2 improves on this with the APR libraries, which
greatly enhance Apache’s ability to adapt to a new platform by
providing a portability layer of common functions and data structures.
You can find detailed information on the APR on the APR project pages
at http://apr.apache.org/.
Between the APR and the adoption of the autoconf
system for build configuration, you now have the ability to configure
and build Apache for a different platform and even a different processor, if you have a cross-platform compiler available. Many compilers are capable of cross-compliation, including gcc,
but not by default; you generally need to build a cross-compiling
version of the compiler first. You also need accompanying compiler
tools such as ld, ar, and ranlib—on Linux platforms these are generally in the binutils package. Consult the documentation for the installed compiler for information.
Once you have a cross-compiler set up, you can use it to build
Apache. To do this, specify one or more of the portability options --target, --host, and --build. All three of these options take a parameter of the form CPU-VENDOR-SYSTEM or CPU-VENDOR-OS-SYSTEM and work together as shown in Table 3-9.
Table 3-9. Configure Script Build Options
Option |
Description |
--host |
The system type of the platform that’ll actually run the server. |
--target |
The system type of the platform for which compiler tools will produce code. This isn’t in fact the target system (that’s the host),
but a definition that’s passed on to compiler tools that are themselves
built during the build process. Normally this would be the same as the
host, which it defaults to. |
--build |
The
system type of the platform that will carry out the build. This defines
your own server when the host is set to something different. It
defaults to host. |
These three values are used by the autoconf system,
on which the Apache 2 build configuration is based. As a practical
example of a host value, a Pentium III server running Linux would
usually be defined as i786-pc-linux-gnu.
This would be used for the host, if it’s the system that you’ll be
running Apache on, and the build host, if it’s the system that’ll be
building Apache. In most cases, all three values are the same, with the
target and build types defaulting to the host type. It’s rare that all
three are needed. You can find detailed information about them in the autoconf manual pages at http://www.lns.cornell.edu/public/COMP/info/autoconf/.
Normally, configure will
guess the host processor, platform vendor, and operating system type
automatically; then default the build and target to it for a local
build. Alternatively, you can override the host using the --host
option or adding it to the end of the command line as a nonoption. This
allows you to specify a different platform. For instance, to build for
a Sparc-based server running Solaris like so:
$ ./configure --build=i786-pc-linux-gnu --host=sparc-sun-solaris2
it’s necessary to specify both the host and build system types when
cross-compiling. This is because the build system type defaults to the
host if not set explicitly. (This is the correct behavior when not
cross-compiling but where the guessed host system type is incorrect.)
Another reason is that cross-compilers can’t always correctly determine
the build system. If it can, you can just use local instead of a complete system type definition:
$ ./configure --build=local --host=sparc-sun-solaris2
It might be necessary to specify the compiler explicitly if you have
both a native compiler and a cross-compiler on the same build host; configure
will generally find the native compiler first, and you need to tell it
otherwise. To do that, you can set the name of the compiler in the
environment variable CC like this:
$ CC=/path/to/cross/compiler ./configure ... --build=i786-pc-linux-gnu
--host=sparc-sun-solaris2
Alternatively, if the cross-compiler has a distinct and different
name and is on your path, you can just specify the name and leave out
the path. See “Configuring the Build Environment” later in the chapter
for more about how you can use environment variables to control the
configuration process.
Configuring Apache for Production or Debug Builds
Normally you want to produce a server executable that has debugging
information stripped from it and is compiled with any optimizations
available for a more efficient server. However, Apache comes with full
source code, so if you want, you can build a version of the server for
debugging purposes. Several options are available to help with this,
more in Apache 2 than in Apache 1.3 (see Table 3-10).
Table 3-10. Configure Script Debug Options
Option |
Description |
Compatibility |
--without-execstrip |
In Apache 1.3, this tells the build process to |
Apache 1.3 only |
|
disable optimizations and not to strip the |
|
|
symbol tables out of the resulting Apache |
|
|
binary so it can be debugged. This is also |
|
|
helpful for analyzing core files left by a |
|
|
crashed Apache process after the fact. |
|
--enable-maintainer-mode |
This is the Apache 2 equivalent of |
Apache 2 only |
--enable-debug |
--without-execstrip and similarly |
|
|
produces a binary for debugging. It also |
|
|
turns on some additional compile-time |
|
|
debug and warning messages. |
|
--enable-profile |
Switches on profiling for the Apache |
Apache 2 only |
|
Portable Runtime; for debugging only. |
|
--enable-assert-memory |
Switches on memory assertions in the |
Apache 2 only |
|
Apache Portable Runtime; for debugging |
|
|
only. |
|
A few other more specialized options are also available; see the bottom of the output from ./srclib/apr/configure --help for a complete—if rather terse—list of them. --enable-v4-mapped,
for example, tells Apache that it can use IPv6 sockets to receive IPv4
connections. Because this is highly dependent on the operating system,
it’s usually best to let configure choose these options for you. Many of these are general autoconf options rather than Apache-specific ones, and you can find more information about them in the autoconf documentation at http://www.lns.cornell.edu/public/COMP/
info/autoconf/.
Configuring Apache for Binary Distribution
Apache may also be compiled as a distributable binary archive, which
may be copied to other machines, unpacked, and installed. To do this,
you must build it using the BinaryDistribution layout and make use of the binbuild.sh
script, which is included in the build directory under the root of the
source distribution. See “The Binary Distribution Layout” section
earlier in the chapter where this is described in detail.
Configuring Apache’s Library and Include Paths
Apache relies on a lot of external libraries and headers to build
itself. Various parts of the server require additional libraries and
headers, or they’ll either disable themselves or be built with reduced
functionality. As usual, options are available to help you teach Apache
where to look for external libraries and their attendant headers and
where to install its own so that utilities such as apxs can find them. Not all of these are listed by configure --help, but some can be found running this:
srclib/package/configure -help
where package is one of apr, apr-util, or pcre.
You can subdivide these options into two loose categories: general options and module-specific options.
General Options
Table 3-11 lists the general options.
Table 3-11. Configure Script General Options
Option |
Description |
--includedir |
The location of Apache’s include files. Default PREFIX/include. This is a layout option (see Table 3-5). |
--oldincludedir |
The location of header files outside the Apache source distribution. The default is /usr/include. |
--libdir |
The location of Apache’s own libraries. The default is PREFIX/lib. A layout option (see earlier). |
You can specify external library and include paths with the -I and -L compiler options, for example:
$ CFLAGS="-I/home/my/includes -I/home/other/includes -L/home/my/lib/"
./configure ...
Module- and Package-Specific Options
Table 3-12 lists the module-specific options.
Table 3-12. Configure Script Module and Package Options
Option |
Description |
--with-apr=DIR |
Specifies the location of the APR headers, if you already happen to |
|
have one built and installed elsewhere. (The APR is available as a |
|
separate package from http://apr.apache.org/.) |
--with-dbm=DBMTYPE Specifies the type of DBM database to use. This is used by mod_auth_dbm |
and the DBM map feature of mod_rewrite. The default is to use SDBM, |
which comes bundled with Apache but that has limited functionality. |
A local version of a more powerful DBM such as GDBM can be |
specified with --with=dbm=gdbm. |
--with-expat=DIR |
Specifies the location of the Expat library and header files. configure |
|
will try several different permutations based on the base directory |
|
path specified by DIR; the default is to try /usr and /usr/local. |
--with-ssl=DIR |
Specifies the location of the OpenSSL library and header files, if |
|
mod_ssl has been enabled. Limited support for other SSL |
|
implementations is also available. |
--with-z=DIR |
Specifies the location of the Zlib compression library and header files, |
|
if mod_deflate has been enabled. |
Apache the Way You Want It - Configuring the Build Environment
Some of the more obscure Apache settings aren’t configurable via configure because they’re rarely needed except for very finely tuned servers
or to enable experimental features that are otherwise disabled. If you
need to enable one of these special options, then you have to define
them—either in the environment before running configure or afterward in one of the EXTRA_ definitions contained in the following:
[1.3] src/Configuration.apaci
[2.0] config_vars.mk
The first route is by far the more preferable because rerunning configure will wipe out any changes you made to the files it generates.
As a practical example, one parameter you might want to set that
isn’t available as a configurable option is to increase the hard
process limit that forms the upper boundary of the MaxClients directive. To set this so configure sees and absorbs it, add it to the environment with this:
$ CFLAGS='-DHARD_SERVER_LIMIT=1024' ./configure ...
This is just one of several values related to process and thread management
that you can set at compile time; see the MPM discussion in Chapters 8
and 9 and Online Appendix J for more. For developers, one other value
of note is GPROF, which creates a profiling Apache binary whose output can be analyzed with the gprof tool. It also enables an additional directive called GprofDir that determines the directory where the profile data file is created.
configure will take
an environment variable and integrate it with the other compiler flags
so that it’s active during compilation. The distinction is actually
fairly arbitrary, and in fact either will work fine.
You can even override the compiler that’s used to carry out the
build; you saw an example of that earlier when I discussed
cross-compiling Apache.
As another example, Apache 2 provides the experimental mod_charset_lite module for on-the-fly character set conversion. This module won’t work unless you also define APACHE_XLATE, so to enable it as well as increase the hard server limit, modify the previous command to get this:
[2.0] $ CFLAGS="-DHARD_SERVER_LIMIT=1024
-DAPACHE_XLATE" ./configure ...
Note the quotes, which are necessary if you want to specify more than one option this way.
You can also undefine something with -U if you want to undo a previously established setting. This works just the same as -D
except, of course, you don’t supply a value. Undefining something that
isn’t defined in the first place has no useful effect but is harmless.
Environment variables specified this way only last as long as the
execution of the command that follows them. If you’re going to be
reconfiguring Apache several times to refine the configuration, you can
instead set the variable permanently (or at least for the lifetime of
the shell). How you do this depends on the shell you’re using:
csh style:
$ setenv CFLAGS '-DHARD_SERVER_LIMIT=1024'
ksh/bash style:
$ export CFLAGS='-DHARD_SERVER_LIMIT=1024'
As I mentioned at the start, if you’ve already run configure, you can avoid rerunning it by editing the EXTRA_CFLAGS line in this:
[1.3] src/Configuration.apaci
[2.0] config_vars.mk
But keep in mind that rerunning configure will wipe out these edits.
Building Modules with configure and apxs
Apache’s standard configuration script enables modules to be
included or excluded in a flexible manner but only knows about modules
that are supplied with Apache. To build third-party modules into
Apache, you have to tell the configure script about them.
It’s tedious to have to reconfigure and rebuild Apache to add a
dynamic module to it because you only actually want to build the module
and not the entire server. For this reason, Apache comes with the apxs utility, a Perl script designed to configure and compile third-party modules without the need to have Apache’s source code present.
So Apache presents you with three options to add new modules to the server:
- Add a new module to the Apache source tree and tell configure to use it.
- Place the module source code somewhere in the file system and tell configure where to find it.
- Use apxs to build the module as a dynamic loadable module independently from configure.
However, configure
only works for modules that have their source code contained in a
single file. More complex modules require additional steps that have
their own installation scripts. These tend to use apxs to build themselves because apxs
is configured with the installation information for the version of
Apache that created it and can handle more than one source file. In
general, if a module comes with its own configuration script, you
should use it rather than try to handle the module with configure.
It’s not possible to use apxs
in all situations. Very occasionally, a module may require patches to
be made to the Apache source code itself before it can be built,
dynamically or otherwise. To use these modules, you must therefore
rebuild Apache after applying the necessary patches; apxs on its own will not be enough. Luckily, this is a rare occurrence.
Adding Third-Party Modules with configure
The configure script allows extra modules to be incorporated into the build process with the use of two additional options, --activate-module and --add-module. In Apache 2, --activate-module has been replaced by the semantically similar --with-module.
For example, to include the third-party module mod_bandwidth into Apache 1.3 as a static module, you first copy the source file mod_bandwidth.c into the /src/modules/extra directory and then tell configure to use it with this:
[1.3] $ ./configure --activate-module=src/modules/extra/ mod_bandwidth.c
You have to specify a relative pathname to the file that starts with src/modules in Apache 1.3; configure will not automatically realize where to find it—in this case, you have put the code in the extra directory, which exists in the Apache 1.3 source tree for just this purpose.
In Apache 2, the source distribution is organized a little differently, with a top-level modules directory under which modules are subcategorized by type: filters, generators, loggers, and so on. There’s no extra
directory as standard, but you can easily create one and then include a
third-party module by copying the module source and activating it with
this:
[2.0] $ ./configure --with-module=extra:mod_bandwidth.c
Many third-party modules provide their own installation scripts.
This is typically the case where the module involves multiple source
files and can’t be built using Apache’s default module compilation
rules. These typically build the module and then copy it into the
Apache modules directory tree ready for Apache to link them.
Accordingly, both --activate-module and --with-module will also accept an object file or a shared library object as the file parameter, for example:
[2.0] $ ./configure --with-module=extra:mod_bandwidth.o
You don’t have to stick with an extra in Apache 2; you can as easily create a mymodules directory if you prefer. On Unix systems, you can also use a symbolic link to point to a directory outside the distribution.
If configure finds the source code for the module, Apache 1.3 will print out an opening dialogue such as the following:
Configuring for Apache, Version 1.3.28
+ using installation path layout: Apache (config.layout)
+ activated bandwidth module (modules/extra/ mod_bandwidth.c)
Apache 2 will report the extra module in the report of enabled modules:
checking for extra modules... added extra:mod_bandwidth.c
It’s worth watching for these messages; if configure fails to find the module, this is when it will tell you.
To compile the module as a shared (dynamic) module, instead you can use --enable-shared:
[1.3] $ ./configure --activate-module=src/modules/ extra/mod_bandwidth.c
--enable-shared=bandwidth
[2.0] $ ./configure --with-module=extra:mod_bandwidth.c
--enable-mods-shared=bandwidth, <other modules>
Or, alternatively, to make all modules shared, including extras:
[1.3] $ ./configure --activate-module=src/modules/extra/ mod_bandwidth.c
--enable-shared=max
[2.0] $ ./configure --with-module=extra:mod_bandwidth.c
--enable-mods-shared=all
Rather than spending time copying module source code, you can have configure do it for you with the --add-module option. This has the same effect as --activate-module, but first copies the source code for the module from the specified location into src/modules/extra before activating it:
[1.3] $ ./configure --add-module=~/apache-modules/mod_bandwidth/mod_bandwidth.c
This produces a slightly different dialogue:
Configuring for Apache, Version 1.3.28
+ using installation path layout: Apache (config.layout)
+ on-the-fly added and activated bandwidth module (modules/extra/mod_bandwidth.o)
Apache the Way You Want It - Building Modules with apxs
apxs is a stand-alone utility for compiling modules dynamically without the need to use the configure script or have the Apache source code available. It does need Apache’s header files, though, which are copied to the location defined by --includedir when Apache is installed. However, it’s important to use an apxs
that was built with the same configuration options as Apache;
otherwise, it’ll make erroneous assumptions about where Apache’s
various installation locations are.
At best, this will mean you can’t use apxs to install modules; at worst, apxs won’t be able to find the header files and simply won’t work at all.
However, apxs is totally useless for static Apache servers and isn’t even installed unless mod_so is built for dynamic module support. Administrators migrating to Apache 2 will be glad to learn that despite the substantial changes since version 1.3, the apxs command line hasn’t changed at all and is the same for Apache 2 as it was in Apache 1.3.
Platforms that offer prebuilt packages often put utilities such as apxs into a separate optional package along with the header files. If the standard Apache installation doesn’t include apxs, look for it in a package called apache-devel or similar.
apxs takes a list of
C source files and libraries and compiles them into a dynamic module.
To compile a simple module with only one source file, you could use
something like this:
$ apxs -c mod_paranoia.c
This takes the source file and produces a dynamically loadable module called mod_paranoia.so. You can also compile stand-alone programs with apxs if you give it the -p option:
$ apxs -p -c program_that_uses_apache_libraries.c
apxs will happily
accept more than one source file and will also recognize libraries and
object files, adding them at the appropriate stage of the linking
process:
$ apxs -c mod_paranoia.c libstayalert.a lasershandy.o
The -c
option enables the use of a number of other code building options, most
of which are passed on to the C compiler (see Table 3-13).
Table 3-13. apxs Command Line Options
Option |
Description |
-o outputfile |
Sets the name of the resulting module file rather than inferring it from the name of the input files, for example, -o libparanoia.so. |
-D name=value |
Sets a define value for the compiler to use when compiling the source code, for example, -D DEBUG_LEVEL=3. |
-I includedir |
Adds a directory to the list of directories the compiler looks in for header files, for example, -I /include. |
-L libdir |
Adds a directory to the list of directories the linker looks in for libraries at the linking stage, for example, -L /usr/local/libs. |
-l library |
Adds a library to the list of libraries linked against the module, for example, -l ldap (assuming you have a libldap somewhere). |
-Wc,flag |
Passes an arbitrary additional flag to the compiler. The comma is important to prevent the flag being interpreted by apxs, for example, -Wc,-O3 enables optimization on some compilers (for instance, gcc). -I is shorthand for -Wc,-I. |
-Wl,flag |
Passes an arbitrary flag to the linker. The comma is important to prevent the flag being interpreted by apxs, for example, -Wl,-s strips symbols from the resulting object code on some compilers. -L is shorthand for -Wl,-L. |
Installing Modules with apxs
Once a module has been built, apxs can then install it into the place configured for modules (previously specified by the --libexecdir option), for example:
$ apxs -i mod_paranoia.so
This builds the module and then installs it into the configured libexec directory.
In addition, you can use the -a option to have apxs modify Apache’s configuration (that is, httpd.conf) to add the LoadModule directive (plus an AddModule directive in Apache 1.3), so Apache will load the module when it’s restarted:
$ apxs -i -a mod_paranoia.so
If the directive already exists but is commented out, apxs
is smart enough to just uncomment the existing line. This means that
for Apache 1.3, the module loading order is preserved. (Apache 2
doesn’t rely on the order anyway, so it isn’t bothered by this issue).
When adding a new module to Apache 1.3, it’s important to realize that apxs has no special knowledge of where the module should be in the loading order, so it simply adds the LoadModule and AddModule
directives to the end of their respective lists. Thus, before
restarting Apache, you should take the time to check if this is the
correct order. For example, it’s often necessary to move modules such
as mod_setenvif to the end, so they can always act before third-party modules that might rely on the settings of environment variables.
If the module is already installed but the configuration doesn’t
contain the corresponding directives to load it, you can instead use the -e option. This essentially tells apxs to recognize the -a flag but to not actually install the module:
$ apxs -e -a mod_paranoia.so
Alternatively, if you want to add the relevant lines but have them disabled currently, you can use the -A option instead, with either -i or -e. To install and configure the module in a disabled state, use this:
$ apxs -i -A mod_paranoia.so
To configure the module in a disabled state without installing it, use this:
$ apxs -e -A mod_paranoia.so
Both commands add the directives, but prefix them with a # to
comment them out of the active configuration. If they’re already
present, then they’re commented out in place; otherwise, they’re added
to the end.
On rare occasions, the name of the module can’t be directly inferred
from the name of the source file, in which case you have to specify it
explicitly with the -n option to ensure that the directives added by -a or -A are correct:
$ apxs -i -n paranoid -a mod_paranoia.so
You can combine the build and install stages into one command by specifying both the -c and -i options at the same time:
$ apxs -c -i -a mod_paranoia.c
Generating Module Templates with apxs
apxs can also generate template modules to kick start the development process for a new module with the -g option. For this to work with the -n option, you must specify the module name:
$ apxs -g -n paranoia
This will create a directory called paranoia within which apxs will generate a makefile that has various useful targets for building and testing the module and a source file called mod_paranoia.c.
When compiled, the module provides no directives, but creates a handler
you can use to prove that the module works. The handler name is based
on the module name, in this case paranoia_handler.
Remarkably, you can combine all the previous stages to create, build, and install a module into Apache in just three commands:
$ apxs -g -n paranoia
$ cd paranoia
$ apxs -c -i -a mod_paranoia.c
Of course, this module will do very little, but you can test it by
registering the default handler somewhere in the configuration:
AddHandler paranoia_handler .par
If you test this by creating a file called index.par (or any file with a.par extension), you’ll get a test page with the message:
The sample page from mod_paranoia.c
Overriding apxs Defaults and Using apxs in makefiles
The Apache build process preconfigures apxs
so that it automatically knows all the details of how Apache was built,
where it was installed, and what compiler options were used. This
allows apxs to build modules in the same way and to install them into the correct place automatically.
You may possibly need to add to or modify one of these presets, so apxs supplies the -S option to allow you to override any of its built-in presets. For example, to have apxs modify a configuration file that was moved to a different location after Apache was installed, you can override the SYSCONFDIR preset:
$ apxs -S SYSCONFDIR=/moved/conf/my_httpd.conf -i -a mod_paranoia.so
apxs is designed not
just to build modules itself but also to provide a means for more
complex modules to implement their own build processes. It enables them
to use apxs to build
and install themselves, automatically acquiring the correct defaults
and path information, rather than having the information configured by
hand. For this reason, apxs provides a query mode that allows configuration and compile-time details to be extracted with the -q option. Three groups of values can be returned by -q or set with -S
Table 3-14 shows the build settings.
Table 3-14. Compiler Options
Option |
Description |
CC |
Compiler command |
CFLAGS |
Compiler flags |
CFLAGS_SHLIB |
Additional compiler flags for building shared libraries (that’s, dynamic modules) |
LD_SHLIB |
Linker command for linking shared libraries |
LDFLAGS_SHLIB |
Additional linker flags for linking shared libraries |
LIBS_SHLIB |
Additional libraries to link shared libraries against |
Table 3-15 shows the primary layout settings (these are also settable via configure options).
Table 3-15. Layout Specific Compiler Options
Option TARGET |
Description Installation name (--with-program-name) |
PREFIX |
Installation prefix (--prefix) |
SBINDIR |
Location of system binaries (--sbindir) |
INCLUDEDIR |
Location of header files (--includedir) |
LIBEXECDIR |
Location of modules (--libexecdir) |
SYSCONFDIR |
Location of configuration files (--sysconfdir) |
In a configured Apache 2 source distribution, the configuration settings are stored in config_vars.mk.
There are many values here, including locations such as bindir, sbindir, and datadir; their expanded versions in exp_bindir, exp_sbindir, and exp_datadir; and their locations relative to the prefix in rel_bindir, rel_sbindir, and rel_datadir. You can also query the operating system with OS, the list of configured dynamic modules with DSO_MODULES, and the subdirectories that will be examined for modules to build with MODULE_DIRS, amongst many others.
For example, to return the flags used by Apache to build dynamic modules, you’d use this:
$ apxs -q CFLAGS_SHLIB
Modules can use these values in their own makefiles, allowing them to compile independently of apxs without having to replicate the configuration setup work previously done by configure when
Apache was built. For example, to use the same compiler and compiler
options used to build Apache originally, you could put a line in the
module’s makefile:
CC=`apxs -q CC`
CFLAGS=`apxs -q CFLAGS`
Summary
In this chapter, you saw how to build the Web server you want by
compiling the required source code components. You looked at the
advantages and disadvantages of static and dynamic loading of Apache’s
modules and saw how to customize Apache’s build process using the configure script for both Apache 1.3 and Apache 2. You also looked at the apxs script and saw how to build modules to add to an existing server.
There’s far more detail in this chapter than you really need to get
a grip on right away; you can ignore many of the more advanced options
until you encounter a situation that requires them. You can generate a
simple configuration in only two commands—the rest is merely detail.
As you go on to configure Apache, you may need to come back and
rebuild it—either to include some additional functionality into the
server or to restructure its layout to suit some new requirement. As
this chapter has shown, compiling source code is nothing to be afraid
of—it gives you a great deal of control over Apache that you otherwise
wouldn’t be able to get with a binary distribution, and for the most
part it’s both easy and painless. Building applications from source
tends to be an alien concept to the proprietary software world, but for
open-source projects it’s both common and unremarkable.