Where to get mod_spin?
======================
It is available from here:
ftp://ftp.rexursive.com/pub/mod-spin/
You can also get source and binary RPM packages, built on and for Fedora Core
Linux distribution on x86 architecture. Skeleton application (i.e. an example
application) is available from here:
ftp://ftp.rexursive.com/pub/spinapps/app/
Unless you already have your own mod_spin applications, it can be useful for
testing if the installation of mod_spin actually worked. Source and binary
RPM packages are also available.
What else is required to build
==============================
1. Apache 2: http://httpd.apache.org/. Plus, you have to apply the following
patch to Apache 2.0.49 and below (later versions have the fix in place):
===============================================
diff -ruN httpd-2.0.49-vanilla/server/core.c httpd-2.0.49/server/core.c
--- httpd-2.0.49-vanilla/server/core.c 2004-03-09 09:54:20.000000000 +1100
+++ httpd-2.0.49/server/core.c 2004-03-22 18:56:29.000000000 +1100
@@ -2975,7 +2975,7 @@
}
/* Seek the file to 'offset' */
- if (offset != 0 && rv == APR_SUCCESS) {
+ if (offset >= 0 && rv == APR_SUCCESS) {
rv = apr_file_seek(fd, APR_SET, &offset);
}
===============================================
2. Apache Portable Runtime and Apache Portable Runtime Utilities - these come
with Apache 2, so nothing special is required to get them; the home page of
APR project is here: http://apr.apache.org/
IMPORTANT NOTE: You should always use the version of APR/APU that comes
with Apache. If you pick another version, especially with a different major
number, you may get a nasty surprise.
3. Apache Request Library, version 2 (libapreq2); the home page of this project
is here: http://httpd.apache.org/apreq/. Apache 2 requires version 2 of this
library/module and will not work with version 1; mod_apreq2 has to be
installed and configured for mod_spin to work.
IMPORTANT NOTE: mod_spin 1.0.10 and above is known to work with
libapreq2-2.06-dev and above (i.e. the multi-env version of this
library/module).
4. XML C parser and toolkit, libxml2. You can get if from here:
http://www.xmlsoft.org/. Most Linux distributions already include it.
Apache Portable Runtime Utilities Library includes some support for XML,
but libxml2 is a much more mature implementation.
5. A Linux (or Unix) system with Apache 2, APR, APR Util, libxml2 and
libapreq2 INSTALLED!
6. If you intend to rebuild scanner.c and parser.c files from scanner.l and
parser.y, respectively, you'll need Flex version 2.5.31 or better, which
comes with reentrant C scanner support. Versions below that won't work! You
can get this version of Flex from http://lex.sourceforge.net/. Also,
having Bison version 1.875 or better is recommended.
How to build and install
========================
There are three options to install mod_spin into Apache 2:
1. As a binary RPM on Fedora Core Linux Distribution
2. As Dynamic Shared Object (DSO) from source
3. By static linking into Apache 2 from source
IMPORTANT: You have to have Apache 2 configured, compiled and installed BEFORE
you attempt this procedure (either as an RPM or from source). You MUST have a
working apxs for options 2 and 3, otherwise nothing will work!
The various config scripts
==========================
Packages that mod_spin depends on come with their own configuration scripts.
Examples include apr-config, apu-config, apreq2-config, xml2-config etc. The
first two will normally reside in the binary path returned by apxs. Others
may be in various places on the system. If you want to use a particular one,
set the PATH variable so that it points to the version you want when you're
running the configure script.
Note on environment variables
=============================
Depending on the system you're running and the features you select, some
environment variables will have to be set, namely CFLAGS, CPPFLAGS and
LDFLAGS. Normally, they are picked up by the above configration scripts.
For instance, if you're compiling in MySQL support on Fedora Core 1, the
libraries will not be in /usr/lib, but in /usr/lib/mysql. Also, the headers
will not be in /usr/include, but in /usr/include/mysql. To make sure configure
finds the libraries and headers, the configure script will attempt to detect
the correct location of header files and library dependencies, by using
mysql_config. If that doesn't work, you'll have to run:
CPPFLAGS="$CPPFLAGS -I/usr/include/mysql \
LDFLAGS="$LDFLAGS -L/usr/lib/mysql" ./configure [other options here]
This would ensure that the compiler and linker can find the required files.
Some other systems may have those files in a different location, so you'll
have to know certain things about your system before you attempt this.
The same can be said for libxml2, which is a requirement to build mod_spin, as
of version 0.9.1. For instance, this library installs its header files in
/usr/include/libxml2 on Fedora Core 1. The configure script will attempt to
figure that out at the beginning of its run by running xml2-config. Sometimes
this won't work as expected. In that case pass relevant -I option on CPPFLAGS
variable and -l/-L options in the LDFLAGS variable, similar to the MySQL
example above.
The CFLAGS environment variable is used to pass optimisation and other flags
to the C compiler. For instance, you might want to see all warnings and
compile in debugging support. You would specify:
CFLAGS="-Wall -g" ./configure [other options here]
The above is relevant to systems that have GNU C Compiler (gcc). If you use
some other compiler, you should check its documentations for the options.
Installation of libraries
=========================
Default prefix is /usr/local, making the installation of libraries go into
/usr/local/lib. If you want rxv_spin library in the system location (i.e.
/usr/lib), specify /usr prefix during configuration. Note that this may clash
with rxv_spin library installation from the RPM, if you do have one.
WARNING: rxv_spin library (i.e. librxv_spin.* files) are ABSOLUTELY REQUIRED
to run both mod_spin and any applications that you may have. If the library
isn't installed correctly, things will break! Luckily, all three installation
options install libraries automatically and this usually isn't a problem.
Library conflicts
=================
If you have an RPM installed on the system that includes a library (including
mod_spin), the location will usually be /usr/lib. When building from source,
mod_spin will link against a specific library, possibly located in
/usr/local/lib, to avoid versioning conflicts and misterious problems with
your module when certain RPMs are removed. Use ldd to verify that you finished
mod_spin has correct dependencies.
Macro files for aclocal
=======================
Beginning with mod_spin 1.0.9, an installable M4 macro file, mod_spin.m4,
is located in the m4 subdirectory of the distribution. It gets installed into
the aclocal's ACDIR directory (to verify what that is on your system, run
'aclocal --print-ac-dir'). This macro file is required for all mod_spin
applications that want to use some mod_spin specific configure tests and it
simplifies writing of your own configure.ac files. All mod_spin macros start
with RXV_SPIN_, to distinguish them from other macros. You can see how they are
used in various mod_spin applications, including the skeleton application,
spin_app.
On most systems there is only one installation of aclocal. Therefore, both
packaged installation (via RPM or some other mechanism) and installation from
source would attempt to install this file in the system wide location. In all
cases, package installed file will be kept, as it is always marked with a
comment 'dnl PACKAGE' in the last line of the file. If you want to overwrite
this file with the M4 file from the source build, you will have to copy it to
the system wide location manually. This discussion only applies if both package
based and source based installation are used on the same system.
IMPORTANT: If you install mod_spin using an unprivileged user account, there
is a good chance you won't be able to write to system wide aclocal location
(usually one needs to be root to do this). Therefore, mod_spin.m4 file IS NOT
GOING TO BE INSTALLED. If you still need it for your applications, either
convice your system administrator to install the file in the system wide
location, copy the file into the m4 subdirectory of your application or use
a local installation of aclocal.
Session support
===============
As of mod_spin 1.0.5, session identifiers are taken from mod_unique_id and
hashed after concatenating SpinSalt configuration parameter to them. This then
creates a method of protection against session spoofing and hijacking. For
sessions to work at all, YOU MUST set SpinSalt parameter, which cannot be less
than 30 characters long. On purpose, there is no default for this parameter,
because it is supposed to be secret, somewhat random and unique to your server
(or group of servers).
Option 1: From binary RPM
=========================
You have to be using Fedora Core on an x86 machine to do this (or, if you
built your own binary RPM, any distro and architecture you did this for). If
you are, then it's really simple:
rpm -Uvh mod_spin-X.Y.Z-R.i386.rpm
where X.Y.Z is version of mod_spin and R is the RPM release of it. Such
installation will create a configuration file for mod_spin, located here:
/etc/httpd/conf.d/spin.conf. This is just an example file, but it should work
for the simplest of applications. You'll have to edit it to actually deploy
your own mod_spin applications, of course. Once you do that, any further
upgrades of mod_spin shouldn't overwrite the configuration file you fiddled
with, courtesy of RPM. Or you can provide applications' own configuration
files, especially if you're deploying those as RPMs as well.
If you want to develop software for mod_spin and you have an RPM installation,
you have to install the development RPM too (mod_spin 1.0.10 and above):
rpm -Uvh mod_spin-devel-X.Y.Z-R.i386.rpm
Option 2: DSO from source
=========================
From the top directory of mod_spin source do:
./configure [--prefix=/top/dir] [--with-apxs=/path/to/apxs] \
[--with-pgsql] [--with-mysql] \
[--with-flex-reentrant=/path/to/flex/installation/directory]
make
make install
Option 3: Static linking from source
====================================
From the top directory of mod_spin source do:
./configure [--prefix=/top/dir] --with-apache=/path/to/apache2/source \
[--with-apxs=/path/to/apxs] \
[--with-pgsql] [--with-mysql] \
[--with-flex-reentrant=/path/to/flex/installation/directory]
make
make install
From the top directory of Apache 2 source do:
If this is the first time you are installing mod_spin into this source tree of
Apache 2, you will have to build appropriate files in modules/spin directory:
./buildconf
IMPORTANT: If you compiled Apache 2 from this source tree before, you should
run:
make distclean
If you don't, compile or link may fail.
Configure Apache 2, either by using an existing configuration (you can also
edit config.nice and place --enable-spin there):
./config.nice --enable-spin
or by using brand new set of options:
./configure --enable-spin [your options here]
Later, if you don't want mod_spin (why would you ever want to do that ;-), then
specify --disable-spin in your configuration options. Now build Apache 2 and
install it:
make
make install
Uninstall
=========
If you installed from RPM, just do:
rpm -e mod_spin
and:
rpm -e mod_spin-devel
if you installed the development package.
In cases 2 and 3, you can simply run from the top directory of mod_spin source:
make uninstall
If you did the install into Apache 2 source for static linking, you should
run:
./buildconf
from the top directory of the Apache 2 source tree. This should clean up the
configure script and remove mod_spin options from it.
How to build RPMs
=================
You can do it from the tarball by:
rpmbuild -ta mod_spin-X.Y.Z.tar.bz2
The above will build both source and binary RPMs. Or you can build a binary
RPM from the source RPM like this:
rpmbuild --rebuild mod_spin-X.Y.Z-R.src.rpm
Most systems don't come with reentrant flex (this feature is available in
version 2.5.31 and above), so rebuilding the RPMs may fail during the
dependency check phase. However, replacing flex with a reentrant package may
have system wide implications, especially if you compile software that
produces scanners. Therefore, mod_spin, as of version 1.0.10, depends on
flex-reentrant package, which can coexist peacefully alongside flex on your
RPM based system. You can get this package from this location (just look for
the latest version):
ftp://ftp.rexursive.com/pub/flex/
Although source RPMs are normally versioned according to the distribution they
have been built on (for instance, SRPM built on Fedora Core 3 will have FC3 in
its name), you can still use them on other distributions. They may not install
cleanly due to dependency resolution issue, but most times a rebuild from the
source RPM will provide you with a binary package you can use.
Doxygen documentation
=====================
References to external documentation, namely that of Apache Portable Runtime,
Apache Portable Runtime Utilities Library and Apache Request Library, are all
done to the URLs at various Apache web sites. If you're installing from
source, in order to link to local documentation instead of one on the net, use
the installdox Perl script, located in the docs/html directory (after you
performed make install). Something like this should do the trick (of course,
substitute example locations with the ones on your system):
./installdox -l apr.tag@/usr/local/doc/apr \
-l apu.tag@/usr/local/doc/apr-util \
-l apreq2.tag@/usr/local/apache2/share/libapreq2/docs/html
For the RPM installation, the RPM post install script will attempt to detect
what documentation you have locally and run installdox for you. If you install
some documentation after you put mod_spin RPM on your system, you can either
run installdox manually (like in the example above) or you can reinstall the
RPM (the --force option does wonders here), which will run the post install
script again.
For your convenience, all mod_spin packages contain mod_spin.tag file, to
allow easy referencing from your documentation.
Module loading order
====================
The Apache Request Library module must be loaded before mod_spin, or your
Apache web server won't be able to resolve some symbols. So, have them like
this in your httpd.conf file:
LoadModule apreq_module modules/mod_apreq2.so
LoadModule spin_module modules/mod_spin.so
Luckily, when deployed in a standard Red Hat manner via the RPM, where each
module gets its own configuration file in conf.d directory, apreq is
alphabetically before spin, so it loads first. Phew!
Note on cookies
===============
As of Apache 2.0.48, support for RFC2965 cookies still has problems. It is
best to stick with Netscape cookies for now. Also, Apache 2.0.48 requires you
to specify CookieName or things won't work. This has been fixed in Apache CVS
and it will appear in later Apache versions.
SELinux environments
====================
If you are running Security Enhanced Linux (for instance, Fedora Core 3), you
may need to do a bit of extra configuration for mod_spin to work correctly.
For instance, if you place application/session database files in /var/tmp/myapp
directory, you'll have to make sure that this directory belongs to the correct
security context, which is normally root:object_r:httpd_cache_t. To do that,
you'd run:
chcon -R -u root -r object_r -t httpd_cache_t /var/tmp/myapp
Alternatively, you can set up a context file like this (myapp.ctx):
/var/tmp/myapp -d root:object_r:httpd_cache_t
/var/tmp/myapp/.* root:object_r:httpd_cache_t
You should then apply this context to the directory:
setfiles myapp.ctx /var/tmp/myapp
Without this, you may have Apache running in a different security context and
being denied access to your application/session database files. Meaning, every
time mod_spin attempts to access /var/tmp/myapp directory, although file
permissions allow it, file access would be denied by policy and the client
would get an internal server error response.
Configuration
=============
Here is an example snippet from httpd.conf (comments after configuration
parameters will cause errors - they are here only to point out the default
settings):
AddHandler spin-template .sm
AddType text/html .sm
SpinApplication /usr/local/libexec/spinapps/spinapp.so
SpinAppEntry rxv_spin_service # Default
SpinAppConfig /usr/local/etc/spinapps/spinapp.xml
SpinWorkspace /var/tmp/mod_spin
SpinCookie SpinSession
SpinSendfile on # Default
SpinCacheAll off # Default
SpinClearCount 0 # Default
SpinSalt # No default
SpinApplication, SpinAppEntry, SpinAppConfig, SpinWorkspace, SpinCookie,
SpinSendfile and SpinCacheAll can be placed in the main server section, virtual
host section, directory or location section. The nearest available will be
used. SpinClearCount and SpinSalt can only be placed in the global
configuration, as it doesn't make sense anywhere else.
SpinApplication is the path to the shared library that is your application.
SpinAppEntry is the name of the entry function in the shared library to call
(rxv_spin_service() by default). Function named in SpinAppEntry will be called
after this library is dynamically linked by mod_spin handler.
SpinAppConfig is the path to the application configuration file. This is a
simple XML file (so that we can use XML parsing facilities easily) which looks
like this:
]>
The value associated with spinparameter1
The value associated with spinparameter2
Given that parsing of the configuration file is a very rare event (application
parameters are kept in the database file after that), the overhead is not big.
The DTD of the document is preferably always local, simply because it is very
small and makes parsing a predictable event.
SpinWorkspace is a directory location where temporary files for session and
application data will go. On Linux (and possibly other systems), you can use
/dev/shm (temporary file system support in shared memory) for this, in order
to improve performance. If the system is rebooted, you will lose those files,
however. This directory must be readable, writable and executable by owner
only and it cannot be a symlink.
SpinCookie is the name of the cookie used for session management. This
parameter is optional, that is to say, if it isn't defined, sessions will not
be supported for that particular configuration section. By convention, this is
normally called SpinSession, but it can be called anything you like. As of
mod_spin 1.0.5, session cookie handling is entirely done in mod_spin. You need
to define SpinSalt for sessions to work.
SpinSendfile enables sendfile() support for pushing the data from the template
file onto the socket. Default is on. Disable this for file systems that have
problems with sendfile().
SpinCacheAll enables caching of all text for every template. This can improve
performance, but it'll use more memory. By default, this switch is turned off
and all file chunks 256 bytes in size and over will be put into the brigade as
FILE buckets, rather than IMMORTAL buckets.
SpinClearCount is the number of requests that a thread private pool and its
sub-pools will persist. The resources associated with those pools are parsed
templates, as well as pooled database connections. By setting this value to
more than zero (0), those resources will be periodically released.
SpinSalt is the cryptographic salt used to add randomness to the session id
hashes. It has to be at least 30 characters long. DO NOT SET THIS TO THE SAME
VALUE ON ALL YOUR SERVERS UNLESS YOU'RE RUNNING A CLUSTER of machines that
share sessions, as it'll be easier for potential attackers to hijack your
sessions. The best thing to do is to make this a "random" string, something
that doesn't make any sense in any language.
Strangely enough (as of mod_spin 1.0.6), you can set SpinSalt parameter twice
and that is not an error. This functionality exists to enable security savvy
administrators to rotate cryptographic salt, in order to make session hijacking
even more difficult. An external program, possibly started from cron, can
manipulate SpinSalt parameters in the configuration file. The first specified
SpinSalt will be considered new and the second one will be considered old, but
still valid (other instances of SpinSalt will be ignored). After a graceful
restart of Apache, mod_spin will accept sessions encrypted with both the old
and the new salt. All outgoing sessions will be encrypted using the new salt.
This enables smooth transition between different crypto salts.