Preface and Apache 2 module configuration

by Christian 'Tiran' Heimes last modified Jan 09, 2010 11:53 PM

This tutorial describes how to set up an Apache 2 webserver as proxy with disk caching and deflating (compressing like mod_gzip) for Zope under Debian Testing. It may or may not be working with other distributions. Please send me feedback.

Prerequisites

  • Apache 2 installed and running
  • The following Apache 2 modules installed (they should be shipped with Apache 2)
  • mod_cache
  • mod_deflate
  • mod_disk_cache
  • mod_headers
  • mod_mime_magic
  • mod_proxy
  • mod_proxy_http
  • mod_rewrite
  • Zope installed and running

This howto is about Zope 2.7 under Python 2.3.3 but it should work with every other zope2 version. For Zope 2.7 you need

  • Zope 2.7 as source tar.gz or cvs checkout (Zope-2_7-branch) from http://zope.org/
  • Python 2.3.3 with unicode enabled (python2.3)
  • python2.3-xml (PyXML)
  • python2.3-dev (headers, distutils)
  • python2.3-psyco (python code optimizer)
  • some additional packages like python2.3-docutils (reST), python2-3-imaging (PIL)

Scenario

We have an Apache 2 server listening on both http and https requests on all interfaces. The site http://example.org/ is a zope with http://www.example.org/ as an alias. Every request to a manage url is rewritten to https://secure.example.org/ to secure management access. The zope http server is running on port 10080 at localhost and the site is stored in /example_org/.

Apache 2 directory layout

Debian is using the following directory structur for Apache 2

/etc/apache2/
base directory for all configuration files
/etc/apache2/apache2.conf
main configuration file. This file loads the other configurations from the directories mentioned below.
/etc/apache2/ports.conf
configuration file for Listen$Port
/etc/apache2/conf.d
directory for additional configuration options
/etc/apache2/sites-available
available sites
/etc/apache2/sites-enabled
enabled sites, may contain softlinks to files in /etc/apache2/site-available. Only this sites are loaded
/etc/apache2/mods-available
available modules (*.load) and module configurations (*.conf)
/etc/apache2/modules-enabled
enabled modules, may contain softlinks to files in /etc/apache2/mods-available. Only this modules are loaded. You must also link the conf file if it exists.
/etc/apache2/ssl
directory containing ssl cert files. I suggest creating three directories crl, crt and key in this directory.

To enable a site or a module symlink it from the -available to the -enabled directory:

user@myhost:/etc/apache2/sites-enabled$ ln -s ../sites-available/default

Loading the Apache 2 modules

Debian users should be save to use the default files.

deflate.load:

LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so

headers.load:

LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so

mime_magic.load:

LoadModule mime_magic_module /usr/lib/apache2/modules/mod_mime_magic.so

mime_magic.conf:

<IfModule mod_mime_magic.c>
    MIMEMagicFile /etc/apache2/magic
</IfModule>

proxy.load:

LoadModule cache_module /usr/lib/apache2/modules/mod_cache.so
LoadModule disk_cache_module /usr/lib/apache2/modules/mod_disk_cache.so
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so

proxy.conf

Don't symlink it! We will use our own configuration file.

rewrite.load:

LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so

ssl.load

Don't symlink it until you have a valid configuration and the all necessary ssl keys:

LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so

ssl.conf

Don't symlink it! We will use our own configuration file.

After you check or created the files symlink every file mods-enabled. Keep in mind that the module load order in the modules.load files are very important. If there are already some files in the mods-enabled directory make shure no module is loaded twice!

Custom configurations

Create the following files in /etc/apache2/conf.d. This files contains our own configurations so we won't bust the default configurations from debian.

deflate.conf:

<IfModule mod_deflate.c>
 DeflateCompressionLevel 3

 DeflateFilterNote Input instream
 DeflateFilterNote Output outstream
 DeflateFilterNote Ratio ratio

 LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate

 # Netscape 4.x has some problems...
 BrowserMatch ^Mozilla/4 gzip-only-text/html

 # Netscape 4.06-4.08 have some more problems
 BrowserMatch ^Mozilla/4\.0[678] no-gzip

 # MSIE masquerades as Netscape, but it is fine
 #BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

 # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
 # the above regex won't work. You can use the following
 # workaround to get the desired effect:
 BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html

 # Don't compress images, java scripts and style sheets
 SetEnvIfNoCase Request_URI \
   \.(?:gif|jpe?g|png|js|css)$ no-gzip dont-vary

 # Make sure proxies don't deliver the wrong content
 # this needs mod_headers but it's very important
 # so I don't add a IfModule around it
 Header append Vary User-Agent env=!dont-vary

</IfModule>

namevirtualhost.conf:

# we will add some configuration options later

proxy.conf (you can copy the file from mods-available and alter it):

<IfModule mod_proxy.c>

      #turning ProxyRequests on and allowing proxying from all may allow
      #spammers to use your proxy to send email.

      ProxyRequests Off

      #<Proxy *>
      #       Order deny,allow
      #       Deny from all
      #       #Allow from .your_domain.com
      #</Proxy>

      # allow to connect to localhost with port ending with 80 and 90 (www, webdav)
      # the having at least 2 digets before the 80 or 90
      <ProxyMatch http://localhost:[0-9]{2,}?[8|9]0/.*>
              Order deny,allow
              Allow from all
      </ProxyMatch>

      # Enable/disable the handling of HTTP/1.1 "Via:" headers.
      # ("Full" adds the server version; "Block" removes all outgoing Via: headers)
      # Set to one of: Off | On | Full | Block

      ProxyVia On

      # To enable the cache as well, edit and uncomment the following lines:
      # (no cacheing without CacheRoot)

      CacheRoot "/var/cache/apache2/proxy"
      # 300MB
      CacheSize 307200
      # in hours
      CacheGcInterval 4
      CacheMaxExpire 24
      CacheLastModifiedFactor 0.1
      CacheDefaultExpire 1
      CacheForceCompletion 100
      # Again, you probably should change this.
      #NoCache a_domain.com another_domain.edu joes.garage_sale.com

</IfModule>

ssl.conf:

<IfModule mod_ssl.c>
  SSLEngine on
  SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

  # path to a directory containing the ssl ca keyring and revocation list
  # you must create hash symlinks using the right Makefile!
  SSLCACertificatePath    /etc/apache2/crt/
  SSLCARevocationPath     /etc/apache2/crl/

  SSLSessionCache shm:/var/log/apache2/ssl_scache(128000)
  SSLMutex sem
  SSLRandomSeed startup file:/dev/urandom 512
  SSLRandomSeed connect file:/dev/urandom 512
</IfModule>

If you think everything is ok, restart apache2:

$ /etc/init.d/apache2 restart

Preparing virtual hosting

Virtual hosting means serving more than one domain from one ip address. The Apache 2 webservers knows what domain the browser wants by using the domain name that is send by the browser. Therefor it isn't possible to use virtual hosting for secure http (https, http over ssl) because the ssl handshake must be done before negotiationing the domain name. It's a shame that browsers and webservers aren't TLS aware.

Check the file /etc/apache2/ports.conf and see if Apache 2 is listening on the default port for http:

Listen 80

If you want to use SSL, you need to listen on the default port for https, too:

Listen 80
<IfModule mod_ssl.c>
  Listen 443
</IfModule>

If you have multiple network devies and/or ip adresses you can bind Apache to a single address:

Listen 192.168.7.1:80

Next you need to configure Apache 2 to use so called NameVirtualHost for virtual hosting. This is the easiest setup because you just need to provide the server name and the address/port in each virtual domain configuration section. Change the file /etc/apache2/conf.d/namevirtualhost.conf and add this line:

NameVirtualHost *:80
<IfModule mod_ssl.c>
  NameVirtualHost *:443
</IfModule>

The entries must look like the entries in ports.conf but with a leading *: if Apache 2 is listening on every address.

Restart Apache 2 and see if you can browse to your server. Maybe Apache 2 is complaining that it cannot find any virtual hosts matching the NameVirtualHost configuration but that's no problem. We'll fix that later.