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
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.2 or better: http://httpd.apache.org/.
2. Apache Portable Runtime and Apache Portable Runtime Utilities 1.2.8
or better. Version 1.3.x is highly recommended, as it contains code for
correct handling of database column names. The home page of APR project is
here: http://apr.apache.org/
IMPORTANT NOTE: You should always use the version of APR/APU that you used
to link Apache with. 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.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 is known to work with libapreq2-2.07 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.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.33 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.
7. The build and install are tested with GNU tools on Linux (Fedora). Other
tools may work, but you will have to find out for yourself.
How to build and install
========================
There are three options to install mod_spin into Apache:
1. As a binary RPM
2. As Dynamic Shared Object (DSO) from source
3. By static linking into Apache from source
IMPORTANT: You have to have Apache 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-1-config, apu-1-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, 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 something like:
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.
For instance, this library installs its header files in /usr/include/libxml2
on Fedora. 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 (or /usr/local/lib64 on some 64-bit systems). If you want
rxv_spin library in the system location (i.e. /usr/lib or /usr/lib64), 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 or /usr/lib64. When building
from source, mod_spin will link against a specific library, possibly located
in /usr/local/lib or /usr/local/lib64, 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
=======================
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
===============
Session identifiers are taken from mod_unique_id and hashed using MD5. An HMAC
MD5 of the hash is appended to the hash. This then creates a method of
protection against session spoofing (not unbreakable, but enough to prevent
massive amount of sessions from being introduced). 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 an RPM based distro to do this (the packages are normally
built for Fedora on x86). If you are, then it's really simple:
rpm -Uvh mod_spin-X.Y.Z-R.ARCH.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 (or deploy your own
files via RPM of you application) 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:
rpm -Uvh mod_spin-devel-X.Y.Z-R.ARCH.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-flex-reentrant=/path/to/flex/installation/directory]
make
make install
Option 3: Static linking from source
====================================
IMPORTANT: THIS OPTION HAS NOT BEEN TESTED IN A WHILE AND IT MAY NOT WORK AT
ALL. IT SURE ISN'T RECOMMENDED.
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-flex-reentrant=/path/to/flex/installation/directory]
make
make install
From the top directory of Apache source do:
If this is the first time you are installing mod_spin into this source tree of
Apache, you will have to build appropriate files in modules/spin directory:
./buildconf
IMPORTANT: If you compiled Apache from this source tree before, you should
run:
make distclean
If you don't, compile or link may fail.
Configure Apache, 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 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 source for static linking, you should
run:
./buildconf
from the top directory of the Apache 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.33 and above), but unless you've changed the scanner rules,
rebuilding the RPMs shouldn't fail (i.e. generated C files are shipped with
the distribution). If scanner rules were changed, however, you will need
reentrant flex. Replacing flex with a reentrant package may have system wide
implications, especially if you compile software that produces scanners.
Therefore, mod_spin was designed to use flex-reentrant package, which can
coexist peacefully alongside flex on your RPM based system.
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 build 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 or rebuild the binary RPM and install it 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!
SELinux environments
====================
If you are running Security Enhanced Linux (for instance, Fedora), you may
need to do a bit of extra configuration for mod_spin to work correctly
(depending on the application/session store type you choose). For instance,
with SQLite2/3, if you place application/session database in /var/tmp/myapp.db
file, you'll have to make sure that this file belongs to the correct security
context, which is normally root:object_r:httpd_cache_t. To do that, you'd run:
chcon -u root -r object_r -t httpd_cache_t /var/tmp/myapp.db
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.db file, although file
permissions allow it, file access would be denied by policy and the client
would get an internal server error response.
To make labeling of files correct, use semanage command, to set you local file
contexts to the correct value. For instance:
semanage fcontext -a -t http_cache_t '/var/tmp/modspin(/.*)?'
Obviously, if you're running other databases where connections are made via a
TCP or Unix domain socket, you will have to allow Apache to connect to those
sockets. On Fedora, this is done using SELinux booleans. You can obtain the
list of those by running sestatus -b. You can change them by running
setsebool. Check relevant manual pages for all details.
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
# AddOutputFilter SPIN-TEMPLATE .sm
AddType text/html .sm
SpinApplication /usr/local/libexec/spinapps/spinapp.so
SpinAppInit rxv_spin_init # Default
SpinAppPrepare rxv_spin_prepare # Default
SpinAppService rxv_spin_service # Default
SpinAppConfig /usr/local/etc/spinapps/spinapp.xml
SpinStore file:/var/tmp/mod_spin
# SpinStore sqlite3:/var/tmp/mod_spin/store.db
# SpinStore mysql:dbname=spintest,flags=CLIENT_FOUND_ROWS
# SpinStore pgsql:dbname=spintest
SpinStoreTable spinstore # Default
SpinCookie SpinSession
SpinCookiePath / # Default
SpinCookieDomain .example.com
SpinTimeout 0 # Default
SpinConnPool on # Default
SpinConnCount 5 # Default
SpinSalt # No default
SpinApplication, SpinAppInit, SpinAppPrepare, SpinAppService, SpinAppConfig,
SpinStore, SpinStoreTable, SpinCookie, SpinCookiePath, SpinCookieDomain,
SpinTimeout and SpinConnPool can be placed in the main server section, virtual
host section, directory or location section. The nearest available will be
used. SpinConnCount and SpinSalt can only be placed in the global
configuration, as they don't make sense anywhere else.
SpinApplication is the path to the shared library that is your application.
SpinAppInit is the name of the application init function in the shared library
(rxv_spin_init() by default). This function, if exists, will be called when
the library is dynamically linked into Apache.
SpinAppPrepare is the name of the application prepare function (called in the
fixups phase of the request processing) in the shared library
(rxv_spin_prepare() by default). Function named in SpinAppPrepare will be
called after the library is dynamically linked by mod_spin.
SpinAppService is the name of the application service function (called from the
handler) in the shared library (rxv_spin_service() by default). Function named
in SpinAppService will be called after the library is dynamically linked by
mod_spin.
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
The DTD of the document is local in the above example, but you don't need to
specify it in your file. You can even omit the XML declaration.
SpinStore is a location (in APR Util DBD speak) of your session and appliction
store. The store is actually a table in an SQL database (e.g. PostgreSQL,
SQLite3 etc.). This parameter obeys SpinConnPool parameter. With version 1.3.x
of APR Util DBD, supported database prefixes are pgsql, mysql, sqlite2 (this
won't work, as this driver doesn't support prepared statements), sqlite3 and
oracle. This obviously depends on how APR Utils was compiled and linked and
what databases really exist in your environment. If you're using MySQL, you
have to specify flags=CLIENT_FOUND_ROWS in your connect string, or the store
isn't going to work properly.
You can also specify a special driver, file:, followed by the directory where
the store will be located. In this case, application and session data is kept
in XML files. This store backend features best performance. See the above
example snippet from the httpd.conf file for more details.
SpinStoreTable is the name of the SQL table used for the store. This parameter
has no effect when file based store is in use.
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. Session
cookie handling is entirely done in mod_spin. You need to define SpinSalt for
sessions to work.
SpinCookiePath is the path of the cookie used for session management. It is
set to "/" by default.
SpinCookieDomain is the domain of the cookie used for session management. It
is not set by default.
SpinTimeout is session timeout in seconds. After this time, the session data
from session store will be ignored (i.e. not retrieved) and overwritten by new
data if the same session ID is used. By default, this value is set to zero,
meaning no timeout. Specifying anything but an integer greater or equal zero
will set the value to zero.
An external program, possibly started from cron, can reap session data that
timed out, whether in a database or file based store.
SpinConnPool enables pooling of connections and it is turned on by default.
SpinConnCount specifies the number of connections to keep in the connection
pool. Least Recently Used (LRU) algorithm is used to maintain up to this many
connections open. Specifying anything but an integer greater than zero will
set the value to the default. Default is 5. Note that any connection that has
not been used for more than a minute will be closed and removed from the
connection pool.
SpinSalt is the cryptographic salt (key) used to produce HMACs for 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 spoof 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, you can set SpinSalt parameter more than once and that is
not an error. This functionality exists to enable security savvy
administrators to rotate cryptographic salt, in order to make session
spoofing even more difficult.
An external program, possibly started from cron, can manipulate SpinSalt
parameters in the configuration file (or, file included from 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.