Documents
Resources
Learning Center
Upload
Plans & pricing Sign in
Sign Out

apache-cookbook

VIEWS: 11 PAGES: 161

									Apache Cookbook
     ApacheCon Europe
           2007
        Amsterdam

 Rich Bowen - Asbury College
     rbowen@apache.org




              1
   Table of Contents
SSL vhosts
Rewrite based on query string
Preventing “image theft”
Logging more information
Logging to syslog
WebDAV
Preventing malicious requests with mod_security
Enabling PHP
Mass virtual hosting
Customized error messages
URL handler (“rewrite everything”)
Fancy directory listings
Caching dynamic content
/server-info goodness
/server-status goodness
UserDir without the ~
            Recipes


On CD

At
http://people.apache.org/~rbowen/presentation
s/apache_coobook_recipes.tar.gz




                    3
    Caveat: Versions

2.2 is the current version of Apache

With any luck, by the end of the year, 2.4 will
be the current version of Apache

If you are running 1.3, you really should
upgrade

Some, not all, of these recipes will work in 2.0




                      4
         SSL vhosts



Multiple SSL hosts, one IP address




                    5
            Problem


One SSL cert per IP address

Certificate is negotiated before the HOST:
header is sent




                     6
            Solution

Three options:

  Wildcard certificate

  Get more IP addresses

  Ignore the error messages




                     7
  Wildcard certificate

Costs $$$

Works for *.domain.tld

Cannot span multiple domains

Set up name-based vhosts the normal way




                    8
         Wildcard certificate
 NameVirtualHost *:443

 # Wildcard certificate for *.domain.com
 SSLCertificateFile /var/www/conf/server.crt
 SSLCertificateKeyFile /var/www/conf/server.key

 <VirtualHost *:443>
 ServerName one.domain.com
 DocumentRoot /var/www/one/htdocs
 SSLEngine On
 </VirtualHost>

 <VirtualHost *:443>
 ServerName two.domain.com
 DocumentRoot /var/www/two/htdocs
 SSLEngine On
 </VirtualHost>



01_wildcard_cert                9
Multiple IP addresses


This is the best solution

Not always an option




                     10
        Multiple IP addresses
   <VirtualHost 172.20.4.10:443>
   ServerName one.domain.com
   DocumentRoot /var/www/one/htdocs

   SSLCertificateFile /var/www/conf/one.crt
   SSLCertificateKeyFile /var/www/conf/one.key

   SSLEngine On
   </VirtualHost>

   <VirtualHost 172.20.4.11:443>
   ServerName two.domain.com
   DocumentRoot /var/www/two/htdocs

   SSLCertificateFile /var/www/conf/two.crt
   SSLCertificateKeyFile /var/www/conf/two.key

   SSLEngine On
   </VirtualHost>

02_ssl_hosts                    11
        Ignore errors

SSL cert will be valid for only one hostname

Other named vhosts will be encrypted

Browser will report that the cert doesn‟t match
the hostname

SSL is encryption + validation. You‟re losing
the validation.




                     12
              Ignore the errors
   NameVirtualHost *:443

   # Certificate for one.domain.com
   SSLCertificateFile /var/www/conf/one.crt
   SSLCertificateKeyFile /var/www/conf/one.key

   <VirtualHost *:443>
   ServerName one.domain.com
   DocumentRoot /var/www/one/htdocs
   SSLEngine On
   </VirtualHost>

   # Will be secure, but will generate errors
   <VirtualHost *:443>
   ServerName two.domain.com
   DocumentRoot /var/www/two/htdocs
   SSLEngine On
   </VirtualHost>


03_ssl_vhosts                   13
       Other options


Efforts are underway to escape this limitation

Browser support is the big hurdle




                     14
 Rewrite based on
QUERY_STRING or
   PATH_INFO
Sometimes what gets asked is:



   “I want to forbid access if the
  QUERY_STRING doesn‟t contain
             foo=bar”


                   15
     Rewrite by
   QUERY_STRING

The sensible solution would be to handle this
in your script/handler/program
But, if that‟s not an option, mod_rewrite
might be a good choice




                    16
           Problem

RewriteRule doesn‟t have access to the
QUERY_STRING

Only the URI - the bit after
http://hostname.com and before the ? - is
accessible to RewriteRule




                  17
            Solution

RewriteCond has access to the entire
requested URL, and any other server variables



 RewriteCond %{VARIABLE} regex




                   18
             RewriteCond
      Does the QUERY_STRING contain foo=bar


  RewriteCond %{QUERY_STRING} foo=bar
  RewriteRule ^ - [F]




04_query_string       19
       ^ rather than .*

^ means “starts with”

All strings start, even empty strings.

Thus, all strings match ^

^ is more efficient than .*




                      20
            Backreferences
       Or, you can do a rewrite based on the value of
       the QUERY_STRING



  RewriteCond %{QUERY_STRING} user=(.+)\b
  RewriteRule (.*) /home/%1/www$1




05_query_string            21
  More frequently ...


People want to map
http://example.com/one/two/three to
http://example.com/something.php?a=one&b=t
wo&c=three




                  22
            See also


Upcoming recipe “URL Handler”

Not quite the same, but many similar
techniques




                    23
               PATH_INFO
      Everything after the final / is the path info

      “Final /” refers to the / following an actual file
      or resource



http://example.com/index.php/one/two/three




                             24
         PATH_INFO


The trick is to figure out which bit is a valid
resource, and which bit is PATH_INFO

Two approaches




                      25
                 URL Prefix

       http://example.com/prefix/one/two/three

       You know that only URLs starting with prefix
       need special attention



 RewriteRule ^/prefix(.*) \
  /handler.php?args=$1


06_rewrite                 26
               File existance
       Check to see if the requested file exists

       If not, rewrite

       May interfere with other rewrite matches


   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteRule (.*) /handler.php?args=$1



07_rewrite                  27
                 Caveats

   May need to prepend a directory path
RewriteCond \
/var/www%{REQUEST_FILENAME} !-f

   Still need to do something useful with the
   value of $1, if you want it to be split into args.




                         28
             The full recipe

   RewriteRule ^/prefix/([^/]+)/([^/]+) \
    /handler.php?one=$1&two=$2 [PT,L]




08_rewrite               29
            Caveats


Exactly two arguments

No more, no less

Perhaps you want this to be more flexible?




                    30
                More flexible
   RewriteRule ^/prefix/([^/]+)?/?([^/]+)? \
    /handler.php?one=$1&two=$2 [PT,L]



        Matches are now optional

        Arguments will be passed null - just ignore
        them in handler.php, or check for null values
        and take appropriate measures


09_rewrite                   31
     More arguments

This technique can be repeated for up to 9
arguments.

$1 - $9

$10 is not available




                       32
Preventing image theft

“Image theft” is the term used for other sites
embedding your images in their pages.

Ideally, you want to forbid having your images
in any pages but your own

There are several ways to accomplish this




                     33
            SetEnvIf


SetEnvIf is provided by mod_setenvif

Sets environment variables if certain
conditions are met




                     34
                  SetEnvIf

SetEnvIf Referer “^http://myhost\.com” localref=1
<FilesMatch "\.(gif|jpg|png)">
  Order Deny,Allow
Deny from all
  Allow from env=localref
</FilesMatch>




               10_image_theft
                       35
                      Problem
         Some browsers don‟t set the Referer value


   SetEnvIf Referer “^http://myhost\.com” localref=1
   SetEnfIf Referer “^$” localref=1

   <FilesMatch "\.(gif|jpg|png)">
     Order Deny,Allow
   Deny from all
     Allow from env=localref
   </FilesMatch>

11_image_theft                36
               mod_rewrite
       Or, you could do it with a RewriteRule


RewriteEngine on
RewriteCond %{HTTP_REFERER} !=""
RewriteCond %{HTTP_REFERER} !example\.com
[NC]
RewriteRule \.(jpe?g|gif|png)$ - [F,NC]



                   11_image_theft
                         37
   But, more usefully


If you‟re just going to fail the request, use
SetEnvIf. It‟s more efficient

But if you wanted to do something more
interesting ...




                      38
          Redirect the request


  RewriteEngine on
  RewriteCond %{HTTP_REFERER} !=""
  RewriteCond %{HTTP_REFERER} !example\.com [NC]
  RewriteCond %{REQUEST_URI} !go_away.png
  RewriteRule \.(jpe?g|gif|png)$ /images/go_away.png [NC,L]




13_image_theft                 39
                       Or ...


  RewriteEngine on
  RewriteCond %{HTTP_REFERER} !=""
  RewriteCond %{HTTP_REFERER} !example\.com [NC]
  RewriteRule \.(jpe?g|gif|png)$ \
  http://othersite.com/images/unsavory.jpg [NC,R]




14_image_theft             40
Logging more information
  The standard log file is sometimes not
  sufficient.

  This recipe shows you how to get a little more
  information




                      41
     mod_log_config


Variables available for other values

Always use „combined‟ rather than „common‟




                     42
                               combined


  LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" \
       combined
  CustomLog logs/access_log combined




15_combined                                   43
 Additional variables

http://httpd.apache.org/docs/2.2/mod/mod_log
_config.html#formats

Most of the actual useful variables are already
in „combined‟

Most log analysis packages understand the
„combined‟ format




                     44
  Important variables
%{something}C - the value of the „something‟
cookie

%{something}i - the „something‟ request (input)
header

%{something}o - the „something‟ response
(output) header

%q - The query string

and ...


                    45
          mod_logio

%b gives the size of the response in bytes

Does not include headers

Does not include the request

mod_logio gives both of these




                    46
           mod_logio


%I - total size of request (Input) in bytes

%O - total size of response (Output) in bytes

Includes headers in each case.




                      47
               mod_dumpio
       http://httpd.apache.org/docs/2.2/mod/mod_du
       mpio.html

       Dumps all input and output to the error log



     # DumpIOLogLevel notice (2.3)
     DumpIOInput On
     DumpIOOutput On


16_dumpio                   48
   mod_log_forensic

http://httpd.apache.org/docs/2.2/mod/mod_log
_forensic.html

Logs at the start, end of a request

Uses unique IDs to match the two

check_forensic script alerts you to requests
that did not complete




                     49
            LogLevel

LogLevel changes the level at which error
messages are emitted

Can increase/decrease the volume of your
error_log

In practice, this seldom adds useful
information




                     50
         RewriteLog

Should always turn on the RewriteLog when
RewriteRules aren‟t doing what you expect
them to do

Can only be turned on in main config, not in
.htaccess files




                    51
                RewriteLog

    RewriteLog logs/rewrite_log
    RewriteLogLevel 9




17_rewritelog            52
         Other logs


suexec

SSL




             53
   Logging to syslog


“Offsite” logs, in the event of catastrophe

Multiple servers logging to the same place




                     54
   ErrorLog


   ErrorLog syslog
          ...
ErrorLog syslog:local0




          55
Then, in /etc/syslog.conf


      local0.* /var/log/error_log
                   ...
   local1.* @192.168.1.22:32376




                 56
         access_log


mod_log_config doesn‟t log to syslog

Have to use piped log handlers




                    57
                    Solution
CustomLog |/usr/bin/apache_syslog combined

    Where the script looks like:
     #!/usr/bin/perl
     use Sys::Syslog qw( :DEFAULT setlogsock );

     setlogsock('unix');
     openlog('apache', 'cons', 'pid', 'user');

     while ($log = <STDIN>) {
          syslog('notice', $log);
     }

     18_perl_syslog           58
                    ...

Sys::Syslog is a standard Perl module, so you
already have it installed

Piped logging is a standard feature

Script is started at server startup and remains
running for the life of the server




                     59
           WebDAV

Network filesystem over HTTP (or HTTPS)

Manage your web content

Access your files from anywhere

Impress your friends




                       60
              DAV


Distributed

Authoring

Versioning




               61
                    Modules
       mod_dav

       mod_dav_fs



./configure --enable-modules=most \
   --enable-mods-shared=all \
   --enable-dav --enable-dav-fs



19_dav_configure        62
                  Recipe

         DavLockDb dav/davlock

         Alias /dav /var/www/dav
         <Directory /var/www/dav>
            Dav On
         </Directory>




20_dav                 63
          Accessing



http://servername.com/dav/




                   64
  Client applications

Most modern operating systems

cadaver - Simple command-line application

NetDrive - Windows

DavExplorer - Java




                     65
For More Information


Thursday morning

Bill Rowe

http://www.eu.apachecon.com/program/talk/39




                   66
             Caveat


Files must be writeable by the Apache user

This makes most of us VERY uncomfortable




                    67
            Solution
Run two Apache instances, with different
permissions:

Instance 1, runs as apache.apache, content
owned by dav.dav

Instance 2, runs as dav.dav, has access to
these directories

Instance 2 runs over SSL, and is authenticated



                    68
                    Like ...                          2
1
                              User dav
                              Group dav
User apache
                              DocumentRoot /var/www
Group apache
                              <Directory /var/www>
DocumentRoot /var/www
                                Dav On
                              </Directory>



/var/www> ls -lad .
drwxrwxr-x 9 dav dav 306 Mar 23 22:42 .


                         69
Preventing malicious
   requests with
   mod_security

modsecurity.org

Apache module to do request filtering




                    70
         New syntax


Syntax has changed considerably in
mod_security 2, so some of these recipes
might not work quite as expected, depending
on what version you‟re using.




                   71
           Core rules


Download the core rules from
http://modsecurity.org/download/index.html

Try to understand before using - this will avoid
blocking desirable traffic




                     72
              Basic Configs

       Turn on the engine

       Enable scanning of request body


       # Basic configuration options
       SecRuleEngine On
       SecRequestBodyAccess On
       SecResponseBodyAccess Off


21_security                 73
             Trivial example
# Trivial SQL blocking rule
SecDefaultAction \
   log,auditlog,deny,status:403,phase:2,t:lowercase
SecRule REQUEST_URI|QUERY_STRING insert


  phase:2 indicates that this runs after
  URL mapping. phase:1 runs before
  URL mapping. t:lowercase lowercases
  the variable before comparison is
  applied                 74
                             22_security
                 SecRule
SecRule VARIABLES OPERATOR [ACTIONS]



     ACTIONS is optional - SecDefaultAction will
     be used

     Use multiple variables like
     REQUEST_URI|ARGS|QUERY_STRING

     OPERATOR is a regex match, by default


                         75
      More complex example
# file injection
SecRule
REQUEST_FILENAME|ARGS|ARGS_NAMES|RE
QUEST_HEADERS
"(?:\b(?:\.(?:ht(?:access|passwd|group)|www_?acl)|
global\.asa|httpd\.conf|boot\.ini)\b|\/etc\/)" \

"capture,ctl:auditLogParts=+E,deny,log,auditlog,stat
us:501,msg:'Remote File Access
Attempt.',severity:'2'"
23_security              76
                Note:

mod_security is extremely powerful

mod_security 2 adds a huge amount of new
functionality and flexibility

I‟m just beginning to learn it, so you should go
to the mailing lists with your questions

http://modsecurity.org/




                     77
       Enabling PHP


There‟s a certain amount of disagreement
about the Right Way to do this

So, if there‟s any confusion, you should keep
in mind one important rule of thumb




                    78
Rich is Right



          79
Now that we‟ve got that
  out of the way ...



           80
             AddType
AddType associates a MIME type with a file
extension

It tells the browser how to display a particular
type of content

e.g. image/gif files should use the GIF
rendering engine, and application/pdf files
should use Adobe Acrobat




                      81
   AddType




AddType image/gif .gif




          82
         AddHandler


AddHandler tells the server how to process a
certain type of file

Calls a Handler which does something to the
file before passing it along to the client




                    83
  AddHandler



AddHandler cgi-script .cgi




            84
                PHP

PHP is a handler

However, PHP predates the AddHandler
directive, and so uses the AddType directive

This is a grotty hack, and should be shunned




                    85
       The right way:



AddHandler application/x-httpd-php .php




                  86
      The other way




AddType application/x-httpd-php .php




                 87
Multiple file extensions

In either case, multiple file extensions can
cause problems.

foo.php.txt

With php as a handler, it will still be executed

With php as a mime type, it will lose its
text/plain attribute




                      88
          Discussion

They both work

Since it‟s a handler, I recommend using
AddHandler

Rasmus disagrees




                    89
            LoadModule


    Must also ensure that the php module is
    loaded:

LoadModule php5_module modules/libphp5.so




                        90
 Testing


<?php
 phpinfo();
?>




       91
92
Mass Virtual Hosting


Several ways to do it

Most of them are icky

Don‟t do this unless you really need to




                     93
              When?

When you have LOTS of vhosts

Most of us don‟t have that many vhosts

Most of us are better of just making
<VirtualHost> blocks




                     94
               Include
Put each vhost in its own file

Include them


      Include conf/vhosts/*.conf

000Default.conf

ZZZWildcard.conf



                     95
    mod_vhost_alias


Comes with Apache

Very well documented

Rather limiting




                    96
    mod_vhost_alias


Substitutes bits of the hostname into the
directory path, using templates, like ...




                     97
 # %0 gives you the entire hostname:

 VirtualDocumentRoot /var/www/%0

 # www.example.com maps to
 # /var/www/www.example.com




24_vhost_alias          98
 # %1 gives you the first part of the hostname:

 VirtualDocumentRoot /var/www/%1

 # www.example.com maps to
 # /var/www/www




25_vhost_alias            99
 # %2 gives you the second part of
 # the hostname:

 VirtualDocumentRoot /var/www/%2

 # www.example.com maps to
 # /var/www/example



26_vhost_alias          100
 # %3 gives you the third part of
 # the hostname:

 VirtualDocumentRoot /var/www/%3

 # www.example.com maps to
 # /var/www/com



27_vhost_alias            101
 # And so ...

 VirtualDocumentRoot /var/www/%1/%2/%3

 # www.example.com maps to
 # /var/www/www/example/com




28_vhost_alias       102
 # -1, -2, -3 counts from the right
 VirtualDocumentRoot /var/www/%-1/%-2

 # www.example.com maps to
 # /var/www/com/example




29_vhost_alias        103
 # m.n lets you choose particular letters
 VirtualDocumentRoot \
 /var/www/%-2.1/%-2.2/%-2.3+

 # www.example.com maps to
 # /var/www/e/x/ample




30_vhost_alias            104
 # likewise ...
 VirtualScriptAlias \
 /var/www/%-2.1/%-2.2/%-2.3+/cgi

 # /cgi-bin maps to the directory
 # /var/www/e/x/ample/cgi
 # for www.example.com



31_vhost_alias            105
         Advantages


Don‟t have to restart to add a new vhost

All your vhosts are identical and predictable




                     106
             Caveats

All your vhosts must be identical

You can‟t intermix vhost_alias vhosts and
regular vhosts on the same IP address

mod_alias and mod_userdir always override
vhost_alias directives




                    107
    Vhosts with mod_rewrite



   RewriteEngine On
   RewriteCond %{HTTP_HOST} \
              ^([^.])\.example\.com
   RewriteRule (.*) /var/www/%1$1



32_vhost_rewrite        108
      Disadvantages


May cause interactions with other
RewriteRules (like in .htaccess files) that may
cause breakage.




                     109
   Customized Error
      Messages

Override the default boring error responses

Less jarring to the user

Give them useful information or links




                     110
    ErrorDocument



ErrorDocument 404 /errors/404.html




                111
 Not always an error
      message
Can be used as a “default document” when
something is not found

ErrorDocument 404 /index.html

ErrorDocument 401 /register.html




                   112
     Embedded logic


Can contain basic embedded logic using SSI

See extras/httpd-multilang-errordoc.conf for
extended example




                    113
              Embedded logic

Alias /error /www/error
<Directory /www/error>
 Options IncludesNoExec
 AddOutputFilter Includes html
</Directory>
ErrorDocument 404 /error/404.html



33_errordoc            114
        Then 404.html is ...
<html>
<head><title>Not Found</title></head>
<body>
<!--#if expr=”HTTP_REFERER” -->
The link from <!--#echo var=”HTTP_REFERER” -
-> appears to be bad.
<!--#else -->
The URL you entered could not be found here.
<!--#endif -->
</body>
</html>
            34_404       115
URL Handler (“Rewrite
    Everything”)


One content handler for all requests




                    116
                Recipe

 RewriteEngine On
 RewriteCond %{REQUEST_FILENAME} !-f
 RewriteCond %{REQUEST_FILENAME} !-d
 RewriteCond $1 !=/handler.php
 RewriteRule (.*) /handler.php [PT]




35_rewrite          117
          handler.php

handler.php would know what was actually
requested by looking at
$_SERVER[„REQUEST_URI‟]

Other files (images, css, static files) are served
as normal, due to the -f test.




                     118
      ErrorDocument

Can also be done with an ErrorDocument

ErrorDocument 404 /handler.php

HOWEVER, ErrorDocuments can‟t receive
POST data, so this is a rather limited solution




                     119
Fancy Directory Listings

                 Auto directory listings
                 are ugly

                 It would be nice to
                 have more control
                 over them




           120
     Suppress unwanted
          columns

   IndexOptions SuppressLastModified \
            SuppressDescription




36_indexoptions        121
        Insert “wrapper” html


    IndexOptions SuppressHTMLPreamble
    HeaderName /style/header.html
    ReadmeName /style/footer.html




37_indexoptions       122
                   Wrapper
   <html>
   <head><title>Directory Listing</title>
   </head>
   <body>
38_header

               ... Listing goes here ...

   </body>
   </html>
39_footer                 123
                     CSS


   IndexStyleSheet "/css/style.css"




40_css                  124
   Caching Dynamic
       Content

Much of your „dynamic‟ content doesn‟t
change very often

Cache it to improve performance




                   125
             Warning


Caching dynamic content, by definition,
causes stale content to be served

Note that “private” content will not (usually) be
cached




                     126
       Cache for 10 minutes

     CacheRoot /usr/local/apache/cache
     CacheEnable disk /
     CacheDirLevels 5
     CacheDirLength 3

     # Cache stuff for 10 minutes
     CacheDefaultExpire 600
     CacheIgnoreCacheControl On

41_cache               127
 Cleaning the cache


There are two ways to clear the cache

Depending on how much you care ...




                   128
            htcacheclean
    Cleans up your cache periodically

    Can specify an upper limit on size

    -t deletes empty directories (in the cache)


htcacheclean -d 10 \
   -p /var/cache/apache
   -l 50M \
   -t
                         129
        httacheclean

Runs every 10 minutes (or whatever you
specify)

Keeps cache below 50M (or whatever ...)

Purges older content first




                     130
                rm -rf


If you don‟t care about gradually expiring
content, just delete everything in the cache
directory

Faster - if you need to quickly purge the cache




                    131
/server-info goodness


mod_info gives useful information about your
server configuration




                   132
      Configuration

<Location /server-info>
  SetHandler server-info
  # Order deny,allow
  # deny from all
  # allow from 192.168
</Location>



                133
Security considerations


 Should protect this resource

 Don‟t give crackers additional information




                     134
/server-info




     135
/server-info?config




         136
              ?config
Includes Include‟ed files

Shows line numbers, file names




                     137
               ?config


Particularly useful on third-party distros of
Apache with unfamiliar config file layout

Locate overlapping or conflicting configuration
settings




                      138
?server




   139
              ?server



Equivalent to httpd -V




                    140
?list




 141
?hooks




  142
And if you select one ...




      That‟s ?mod_log_config.c

               143
/server-status goodness


      Displays the current status of the
      server

      Also some basic statistical reports




                144
         Configuration


<Location /server-status>
  SetHandler server-status
  # Order deny,allow
  # deny from all
  # allow from 192.168
</Location>


                   145
             Security


As with /server-info, protect

Also, reveals what users are looking at what
content




                     146
     ExtendedStatus


ExtendedStatus On

Gives more information




                    147
/server-status




      148
Or, more interesting ...




           149
ExtendedStatus




      150
  /server-status?auto
Machine-readable

Useful for things like mrtg




                     151
          Example mrtg script

#!/usr/bin/perl
use LWP::Simple;
$content = get("http://localhost/server-status?auto");

$content =~ m/BusyWorkers: (\d+)/s;
print $1 . "\n";
$content =~ m/IdleWorkers: (\d+)/s;
print $1 . "\n";


42_mrtg                      152
  /server-status?refresh=4

     Automatically refreshes every N seconds

     Or, combine them:


http://rocinante.rcbowen.com/server-status?auto&refresh=2


     Not sure what that‟s useful for ...




                            153
UserDir without the ~


Using mod_rewrite to create a per-user URL,
without the ~




                   154
            Problem


 We want:

http://example.com/username/foo
 To work the same as:

http://example.com/~username/foo



                   155
                   But


 Somehow, ...
http://example.com/not-a-username/foo
 still needs to work properly




                      156
                        -d


  RewriteEngine On

  # If that home directory exists ...
  RewriteCond /home/$1 -d
  RewriteRule ^/([^/]+)/(.*) /home/$1/www/$2



43_userdir               157
           How this works
RewriteEngine On
RewriteCond /home/$1 -d
RewriteRule ^/([^/]+)/(.*) /home/$1/www/$2


     That‟s right, $1 is used in the RewriteCond
     before it is defined in the RewriteRule

     Pretty cool, hmm?



                         158
               Huh?


RewriteRules are always evaluated before the
corresponding RewriteConds

You can watch this in the RewriteLog:




                   159
          http://example.com/rbowen/index.html


(3) applying pattern '^/([^/]+)/(.*)' to uri '/rbowen/index.html'
(4) RewriteCond: input='/home/rbowen' pattern='-d' => matched
(2) rewrite '/rbowen/index.html' -> '/home/rbowen/www/index.html'
(2) local path result: /home/rbowen/www/index.html
(1) go-ahead with /home/rbowen/www/index.html [OK]




                                  160
      That‟s all, folks


rbowen@apache.org

http://people.apache.org/~rbowen/




                   161

								
To top