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.