SlideShare a Scribd company logo
1 of 159
Apache Cookbook
Recipes for managing your Apache HTTP Server




          /         Rich Bowen - rbowen@apache.org
Shameless Plug




          Buy!
          Buy!
          Buy!
Old Hat ---->




     • 1.3 is end of life
     • 2.0 will be by the end of
       the year
     • 2.2 is now
     • 2.4 is tomorrow             Photo CC by “Lost Albatross” - Flickr
URLs you need




    • http://people.apache.org/~rbowen
    • http://wiki.apache.org/httpd
    • http://httpd.apache.org/docs/trunk/
Recipes




 Photo CC by Chemical Heritage Foundation - Flickr
Directory listings are boring
Say it with style

IndexStyleSheet /styles/dir.css

...

.odd {
  background-color: #eef;
}

.even {
  background-color:
    #fff;
}
Caveat: Some features 2.4 only




     • In 2.2 and earlier, you can specify
       a style sheet, but no classes are
       added to the HTML
     • Useful, but not quite as useful
Now, with extra class
  <table id="indexlist">
   <tr class="indexhead">
<th class="indexcolicon">...
<th class="indexcolname">...
<th class="indexcollastmod">...
<th class="indexcolsize">...
<th class="indexcoldesc">...
   <tr class="indexbreakrow">...
   <tr class="even"><td class="indexcolicon">...
An exercise for the reader:


                              • Nifty mouse-over effects
                                (JS in HeaderName
                                file?)
Photo CC by Ugglan - Flickr
                              • AJAXy file interaction
                                of some kind?
                              • Photo gallery, entirely
                                based on
                                mod_autoindex and
                                Javascript?
mod_substitite




    •  New module in 2.2
    • Rewrite content using
       regular expressions
    • Syntax is identical to sed
s/foo/bar/


    • Simple example - switch fonts
   LoadModule substitute_module 
          libexec/apache2/mod_substitute.so

   AddOutputFilterByType SUBSTITUTE text/html
   Substitute s/ariel/courier/i
Proxying

    • More useful example
    • Proxying to back-end server that returns
      fully-qualified URLs

LoadModule substitute_module 
       libexec/apache2/mod_substitute.so

AddOutputFilterByType SUBSTITUTE text/html
Substitute s/backend.local/www.example.com/ni
mod_security




    • Are you running mod_security?
mod_security




    • You should be
http firewall




     • The earlier you catch it ...
Holes




        Photo CC by
         Darwin Bell
SQL Injection




     # Prevent SQL injection attacks
     SecFilter "delete[[:space:]]+from"
     SecFilter "insert[[:space:]]+into"
     SecFilter "select.+from"




18
Make sure you ...




     # Inspect POST payloads
     SecFilterScanPOST On

     # Default action set
     SecFilterDefaultAction "deny,log,status:406"




19
While you’re at it




     # Inspect POST payloads
     SecFilterScanPOST On

     SecFilter “vidocin”




20
Acceptable arguments



# Only for the FormMail script
<Location /cgi-bin/FormMail>
   # Reject request where the value of parameter "recipient"
   # does not end with "@apache.org"
   SecFilterSelective ARG_recipient 
                      "![a-zA-Z0-9]+@apache.org$">
</Location>




 21
Which PHP script is slagging my server?




     •   Which process, and what is
         it doing?
     •   Look at /server-status for a
         process list
Step 1: Look at top:



     •  Run ‘top’
     • Order by CPU usage
     • Pick off the httpd processes
        that are causing the
        problem and make note of
        their PIDs
Step 2: /server-status



     •   Look at /server-status
         output
     •   Look for the PIDs you
         noted
     •   Move fast - the process
         may be gone already
/server-status
ExtendedStatus On


    • You’ll need “ExtendedStatus On”
      to get these details:


            <Location /server-status>
             SetHandler server-status
            </Location>

            ExtendedStatus On
SNI



      • General knowledge: SSL
       requires one certificate per IP
       address
      • That is, only one SSL site can
       be on each IP address
      • Limitation of SSL itself
SSL handshake
SSL handshake


                Certificate




                Hostname
Clearly this sucks
SNI
SNI




      • Server Name Indication
      • Passes server name in initial
          handshake
      •   Simple solutions are always
          best
Caveats


    • You knew there would be a catch
   Mozilla Firefox 2.0 or later
   Opera 8.0 or later (the TLS 1.1 protocol must be
   enabled)
   Internet Explorer 7 (Vista or higher, not XP) or
   later
   Google Chrome (Vista or higher, not XP. OS X
   10.5.7 or higher on Chrome 5.0.342.1 or newer)
   Safari Safari 3.2.1 and newer on Mac OS X 10.5.6
   and Windows Vista or higher, not XP
Apache       • 2.2.12 or later
Listen 443
# Listen for virtual host requests on all IP addresses
NameVirtualHost *:443

# Go ahead and accept connections for these vhosts
# from non-SNI clients
SSLStrictSNIVHostCheck off

<VirtualHost *:443>

 DocumentRoot /www/example1
 ServerName www.example.com

</VirtualHost>

<VirtualHost *:443>
 DocumentRoot /www/example2
 ServerName www.example2.org

</VirtualHost>
More Info




http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
Secure mod_dav deployment


    • Security rule #1: Content is not
      writable
    • Corollary: Anyone telling you to
      ‘chmod 777’ is a monkey
    • Anyone telling you ‘chown apache
      something.php’ *might* be a
      monkey. Or they might be working
      around Apache’s annoying
      permissions model
However ...




     •Setting up WebDAV
       requires that content be
       writable ...
     •And owned by Apache
     •This is annoying
WebDAV




         <Directory /var/www/content>
           Dav On
         </Directory>
Why this is a problem



     • People write bad code
     • It’s easy to get PHP (or whatever
       else) to overwrite your content
     • Now your site is a radical terrorist
       site
     • This is a very unpleasant thing to
       wake up to on a Saturday morning
Secure DAV




     • It’s possible to set up Dav without
       having the files written by the
       Apache user
     • Sort of

40
Two Apache Processes




      Primary                     Secondary
       server,                      server,
     running as                   running as
     user www                      user dav

                   File System,
                  owned by dav

41
Two Apache Processes


                             Read-only
                   Running ordinary set of modules
                       Running web apps, etc
      Primary
       server,
     running as
     user www

                   File System,
                  owned by dav

42
Two Apache Processes




          Read/Write
     Remove all extra modules
               SSL                   Secondary
                                       server,
         Authenticated
                                     running as
                                      user dav

                      File System,
                     owned by dav

43
Multi-server config.
           drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www
1
Listen *:80
User www
Group www
DocumentRoot /var/www/

                         Listen *:8080        2
                         DavLockDb /var/lock/dav
                         User dav
                         Group dav
                         DocumentRoot /var/www/
44
drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www


1
Listen *:80                    Can write
User www
Group www
DocumentRoot /var/www/

                       Listen *:8080        2
                       DavLockDb /var/lock/dav
                       User dav
                       Group dav
                       DocumentRoot /var/www/
45
drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www


1             Can’t
Listen *:80
User www
Group www
DocumentRoot /var/www/

                       Listen *:8080        2
                       DavLockDb /var/lock/dav
                       User dav
                       Group dav
                       DocumentRoot /var/www/
46
<If>                         Picture by BrewBooks (Flickr)




       My favorite new feature in 2.4
<If>


       <If ‘$req{Host} = “www.example.com”’>
         RedirectMatch (.*) http://example.com/$1
       </If>
<If>


       <If ‘$req{Host} = “www.example.com”’>
         RedirectMatch (.*) http://example.com/$1
       </If>


   This was hard prior to 2.4, and
  probably required mod_rewrite,
     or a separate virtual host.
<If>


       <If ‘$req{Host} = “www.example.com”’>
         RedirectMatch (.*) http://example.com/$1
       </If>



         $req
         $resp
         $env
Logging - Conditional Logging




     • Don’t log certain things
     • Per-directory logging

51
Conditional LogFormat



     • The LogFormat directive
      supports some conditionals in
      the variables
     • "%!200,304,302{Referer}i"
      logs Referer on all requests
      that do not return one of the
      three specified codes

52
Conditional LogFormat




     • "%400,501{User-agent}i" logs
      User-agent on 400 errors and
      501 errors only
     • For other status codes, the
      literal string "-" will be logged


53
Conditional CustomLog




     • Stick Env=xyz on the end
     • or Env=!xyz
     • Yes, that’s =! not !=

54
For example ...




SetEnvIf Request_URI .gif$ gif-image
CustomLog gif-requests.log common env=gif-image
CustomLog nongif-requests.log common env=!gif-image




 55
For example ...




SetEnvIf Request_URI .gif$ gif-image
CustomLog gif-requests.log common env=gif-image
CustomLog nongif-requests.log common env=!gif-image




 56
For example ...




SetEnvIf Request_URI .gif$ gif-image
CustomLog gif-requests.log common env=gif-image
CustomLog nongif-requests.log common env=!gif-image




 57
So the images get logged here




SetEnvIf Request_URI .gif$ gif-image
CustomLog gif-requests.log common env=gif-image
CustomLog nongif-requests.log common env=!gif-image




 58
And everything else goes here




SetEnvIf Request_URI .gif$ gif-image
CustomLog gif-requests.log common env=gif-image
CustomLog nongif-requests.log common env=!gif-image




 59
Per directory




SetEnvIf Request_URI ^/marketing mkt
CustomLog marketing.log common env=mkt




 60
PCRE Zero-width assertions



   • Match everything except one thing
   • While you can do this with
     RewriteRule, it would be nice if you
     could do it with other directives
     DirectoryMatch
     FilesMatch
     RedirectMatch
Negative Lookahead




    • PCRE provides a regex
        syntax to say “not preceded
        by” or “not followed by”
    •   Negative lookbehind and
        negative lookahead,
        respectively
Andrei Rocks




    • While we’re on the topic:
    • Pretty much the best
      presentation on regular
      expressions anywhere:
    • http://www.slideshare.net/
      andreizm/andreis-regex-clinic
Everything except ...


     •   “I want to redirect everything except /
         images”

     •   This is where you’d use a negative lookahead

     •   Necessary because RedirectMatch doesn’t
         support negation

             RedirectMatch ^/(?!images/)(.*) 
               http://other.myhost.com/$1
Everything except ...



     • Match anything ...
     •

           RedirectMatch ^/(?!images/)(.*) 
             http://other.myhost.com/$1
Everything except ...



     • Match anything ...
     • That doesn’t start with images/

           RedirectMatch ^/(?!images/)(.*) 
             http://other.myhost.com/$1
Everything except ...



      This is called a “zero width” assertion,
      because it doesn’t fill $1, and doesn’t
      consume any characters in the match.


           RedirectMatch ^/(?!images/)(.*) 
             http://other.myhost.com/$1
What the heck is it doing?


           RewriteLog /var/log/rewrite.log
           RewriteLogLevel 9
What the heck is it doing?


           RewriteLog /var/log/rewrite.log
           RewriteLogLevel 9


     • Alas, not in .htaccess
     • Logs are always opened at startup
What the heck is it doing?


           RewriteLog /var/log/rewrite.log
           RewriteLogLevel 9



     • Most entries between 1-4
What the heck is it doing?


           RewriteLog /var/log/rewrite.log
           RewriteLogLevel 9


     • If there’s nothing in there, your rules are
       being ignored.
Logging - RewriteLog




     RewriteLog /var/log/rewrite.log
     RewriteLogLevel 9




73
Logging - RewriteLog




     RewriteLog /var/log/rewrite.log
     RewriteLogLevel 9




74
Logging - RewriteLog




     RewriteLog /var/log/rewrite.log
     RewriteLogLevel 9




75
76
Kind of intimidating, isn’t it?




77
Learn to ignore the irrelevant bits




78
Which bits are those?




        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]
     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/
        initial] (4) [perdir /var/www/vhosts/drbacchus/]
       RewriteCond: input='/var/www/vhosts/drbacchus/
     podcasts/poetry/maninmoon.mp3' pattern='!-f' => not-
                               matched



79
Client address




        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]
     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/
        initial] (4) [perdir /var/www/vhosts/drbacchus/]
       RewriteCond: input='/var/www/vhosts/drbacchus/
     podcasts/poetry/maninmoon.mp3' pattern='!-f' => not-
                               matched



80
Dunno what those are




        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]
     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/
        initial] (4) [perdir /var/www/vhosts/drbacchus/]
       RewriteCond: input='/var/www/vhosts/drbacchus/
     podcasts/poetry/maninmoon.mp3' pattern='!-f' => not-
                               matched



81
Time




        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]
     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/
        initial] (4) [perdir /var/www/vhosts/drbacchus/]
       RewriteCond: input='/var/www/vhosts/drbacchus/
     podcasts/poetry/maninmoon.mp3' pattern='!-f' => not-
                               matched



82
Unique id




        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]
     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/
        initial] (4) [perdir /var/www/vhosts/drbacchus/]
       RewriteCond: input='/var/www/vhosts/drbacchus/
     podcasts/poetry/maninmoon.mp3' pattern='!-f' => not-
                               matched



83
Request ID




        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]
     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/
        initial] (4) [perdir /var/www/vhosts/drbacchus/]
       RewriteCond: input='/var/www/vhosts/drbacchus/
     podcasts/poetry/maninmoon.mp3' pattern='!-f' => not-
                               matched



84
The useful bit




        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]
     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/
        initial] (4) [perdir /var/www/vhosts/drbacchus/]
       RewriteCond: input='/var/www/vhosts/drbacchus/
     podcasts/poetry/maninmoon.mp3' pattern='!-f' => not-
                               matched



85
Wouldn’t it be nice if you could just see the
     useful part?




86
You could change the way mod_rewrite logs:
Piped logs



      • I actually use a piped lot handler to
         remove this superfluous stuff
      • Like so ...
RewriteLog |/usr/local/bin/rewrite_log_pipe
RewriteLogLevel 9




88
RewriteLog |/usr/local/bin/rewrite_log_pipe
     RewriteLogLevel 9
          with ...

     #!/usr/bin/perl
     $|++;

     open (F, ">>/tmp/rewrite");
     select F;
     while (<>) {
       s/^.*((d).*)/$1/;
       print;
     }
89
RewriteLog |/usr/local/bin/rewrite_log_pipe
 RewriteLogLevel 9



       This bit says “instead of logging to a text
        file, invoke this script and send the log
                     entries there.”




90
#!/usr/bin/perl
 $|++;

 open (F, ">>/tmp/rewrite");
 select F;
 while (<>) {
   s/^.*((d).*)/$1/;
   print;
 }


     • Look for the (1) or (2) bit
     • drop everything before that
91
Results in:




(4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
.com' [NC] => not-matched
(3) applying pattern 'wp-rss2.php' to uri '/index.php'
(3) applying pattern '(journal/)?index.rdf' to uri '/index.php'
(3) applying pattern '^/wordpress/wp-comments' to uri '/index.php'
(3) applying pattern '^/perm/(.*)' to uri '/index.php'
(3) applying pattern '^/articles?/(.*)' to uri '/index.php'
(3) applying pattern '^/blog/(.*)' to uri '/index.php'
(3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php'
(3) applying pattern '^/book/cookbook' to uri '/index.php'
(3) applying pattern '^/book/2.2' to uri '/index.php'
(3) applying pattern '^/booklink/(.*)' to uri '/index.php'
(3) applying pattern '^/books?/(.+)' to uri '/index.php'
(1) pass through /index.php


92
Results in:




(4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
.com' [NC] => not-matched
(3) applying pattern 'wp-rss2.php' to uri '/index.php'
(3) applying pattern '(journal/)?index.rdf' to uri '/index.php'
(3) applying pattern '^/wordpress/wp-comments' to uri '/index.php'
(3) applying pattern '^/perm/(.*)' to uri '/index.php'
(3) applying pattern '^/articles?/(.*)' to uri '/index.php'
(3) applying pattern '^/blog/(.*)' to uri '/index.php' better?
                              See? Isn’t that
(3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php'
(3) applying pattern '^/book/cookbook' to uri '/index.php'
(3) applying pattern '^/book/2.2' to uri '/index.php'
(3) applying pattern '^/booklink/(.*)' to uri '/index.php'
(3) applying pattern '^/books?/(.+)' to uri '/index.php'
(1) pass through /index.php


93
Requested URI




(4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
.com' [NC] => not-matched
(3) applying pattern 'wp-rss2.php' to uri '/index.php'
(3) applying pattern '(journal/)?index.rdf' to uri '/index.php'
(3) applying pattern '^/wordpress/wp-comments' to uri '/index.php'
(3) applying pattern '^/perm/(.*)' to uri '/index.php'
(3) applying pattern '^/articles?/(.*)' to uri '/index.php'
(3) applying pattern '^/blog/(.*)' to uri '/index.php'
(3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php'
(3) applying pattern '^/book/cookbook' to uri '/index.php'
(3) applying pattern '^/book/2.2' to uri '/index.php'
(3) applying pattern '^/booklink/(.*)' to uri '/index.php'
(3) applying pattern '^/books?/(.+)' to uri '/index.php'
(1) pass through /index.php

94
Patterns applied




(4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
.com' [NC] => not-matched
(3) applying pattern 'wp-rss2.php' to uri '/index.php'
(3) applying pattern '(journal/)?index.rdf' to uri '/index.php'
(3) applying pattern '^/wordpress/wp-comments' to uri '/index.php'
(3) applying pattern '^/perm/(.*)' to uri '/index.php'
(3) applying pattern '^/articles?/(.*)' to uri '/index.php'
(3) applying pattern '^/blog/(.*)' to uri '/index.php'
(3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php'
(3) applying pattern '^/book/cookbook' to uri '/index.php'
(3) applying pattern '^/book/2.2' to uri '/index.php'
(3) applying pattern '^/booklink/(.*)' to uri '/index.php'
(3) applying pattern '^/books?/(.+)' to uri '/index.php'
(1) pass through /index.php

95
None of them matched




(4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
.com' [NC] => not-matched
(3) applying pattern 'wp-rss2.php' to uri '/index.php'
(3) applying pattern '(journal/)?index.rdf' to uri '/index.php'
(3) applying pattern '^/wordpress/wp-comments' to uri '/index.php'
(3) applying pattern '^/perm/(.*)' to uri '/index.php'
(3) applying pattern '^/articles?/(.*)' to uri '/index.php'
(3) applying pattern '^/blog/(.*)' to uri '/index.php'
(3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php'
(3) applying pattern '^/book/cookbook' to uri '/index.php'
(3) applying pattern '^/book/2.2' to uri '/index.php'
(3) applying pattern '^/booklink/(.*)' to uri '/index.php'
(3) applying pattern '^/books?/(.+)' to uri '/index.php'
(1) pass through /index.php

96
And now




     • We can actually make some
      sense of what’s happening
     • Less inscrutable noise
     • Yes, it means something, but
      not to normal people


97
Examples


(4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
.com' [NC] => not-matched




       • This was the result of
                 RewriteCond %{HTTP_HOST} 
                   !^wooga.drbacchus.com [NC]


98
Examples



(4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
.com' [NC] => not-matched



       • It shows what the input variable
           looked like


                 RewriteCond %{HTTP_HOST} 
                   !^wooga.drbacchus.com [NC]


99
Examples



 (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
 .com' [NC] => not-matched




         • And what pattern was applied
                  RewriteCond %{HTTP_HOST} 
                    !^wooga.drbacchus.com [NC]


100
Examples


 (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus
 .com' [NC] => not-matched




        •   As well as what happened

                  RewriteCond %{HTTP_HOST} 
                    !^wooga.drbacchus.com [NC]


101
Another example


      (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/
                             index.php'



         •   Was a result of
              RewriteRule ^/book/(mod)?_?rewrite 
             http://www.amazon.com/exec/obidos/asin/
                   1590595610/drbacchus/ [R,L]

102
Again ...


      (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/
                             index.php'



         • What was requested
             RewriteRule ^/book/(mod)?_?rewrite 
            http://www.amazon.com/exec/obidos/asin/
                  1590595610/drbacchus/ [R,L]

103
And ...


      (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/
                             index.php'



         • What it was compared against
             RewriteRule ^/book/(mod)?_?rewrite 
            http://www.amazon.com/exec/obidos/asin/
                  1590595610/drbacchus/ [R,L]

104
Matched?

      (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/
                             index.php'


          • If it matched, the next line will be
             the action log

             RewriteRule ^/book/(mod)?_?rewrite 
            http://www.amazon.com/exec/obidos/asin/
                  1590595610/drbacchus/ [R,L]

105
The whole thing




(3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite'
(2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/
asin/1590595610/drbacchus/'
(2) explicitly forcing redirect with http://www.amazon.com/exec/
obidos/asin/1590595610/drbacchus/
(1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ for redirect
(1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ [REDIRECT/302]


106
The match:




(3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite'
(2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/
asin/1590595610/drbacchus/'
(2) explicitly forcing redirect with http://www.amazon.com/exec/
obidos/asin/1590595610/drbacchus/
(1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ for redirect
(1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ [REDIRECT/302]


107
Followed by




(3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite'
(2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/
asin/1590595610/drbacchus/'
(2) explicitly forcing redirect with http://www.amazon.com/exec/
obidos/asin/1590595610/drbacchus/
(1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ for redirect
(1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ [REDIRECT/302]


108
[R]




(3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite'
(2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/
asin/1590595610/drbacchus/'
(2) explicitly forcing redirect with http://www.amazon.com/exec/
obidos/asin/1590595610/drbacchus/
(1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ for redirect
(1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/
drbacchus/ [REDIRECT/302]


109
But it all runs together!



       • Look for:
       •
      (2) init rewrite engine with requested uri /atom/1


       • ‘init rewrite engine’ shows where
         a new request started being
         rewritten

110
Load balancing
Fortunately ...




                            Photo CC by Camo53 (flickr)



     • mod_proxy_balancer
     • Added in 2.1
Fairly simple to configure




       <Proxy balancer://mycluster>
         BalancerMember http://192.168.1.50:80
         BalancerMember http://192.168.1.51:80
       </Proxy>
       ProxyPass /test balancer://mycluster
Fairly simple to configure




       <Proxy balancer://mycluster>
         BalancerMember http://192.168.1.50:80
         BalancerMember http://192.168.1.51:80
       </Proxy>
       ProxyPass /test balancer://mycluster
Fairly simple to configure




       <Proxy balancer://mycluster>
         BalancerMember http://192.168.1.50:80
         BalancerMember http://192.168.1.51:80
       </Proxy>
       ProxyPass /test balancer://mycluster
Sticky Sessions




      Ensures that connections go to the same server they
                         started with.


ProxyPass / balancer://mycluster/ 
  stickysession=PHPSESSIONID




118
Balancing measures




  ProxyPass / balancer://hotcluster/
  <Proxy balancer://hotcluster>
   BalancerMember http://1.2.3.4:8009 loadfactor=1
   BalancerMember http://1.2.3.5:8009 loadfactor=2
   # The below is the hot standby
   BalancerMember http://1.2.3.6:8009 status=+H
   ProxySet lbmethod=bytraffic
  </Proxy>


119
1.2.3.5 gets twice the traffic




  ProxyPass / balancer://hotcluster/
  <Proxy balancer://hotcluster>
   BalancerMember http://1.2.3.4:8009 loadfactor=1
   BalancerMember http://1.2.3.5:8009 loadfactor=2
   # The below is the hot standby
   BalancerMember http://1.2.3.6:8009 status=+H
   ProxySet lbmethod=bytraffic
  </Proxy>


120
Hot spare




  ProxyPass / balancer://hotcluster/
  <Proxy balancer://hotcluster>
   BalancerMember http://1.2.3.4:8009 loadfactor=1
   BalancerMember http://1.2.3.5:8009 loadfactor=2
   # The below is the hot standby
   BalancerMember http://1.2.3.6:8009 status=+H
   ProxySet lbmethod=bytraffic
  </Proxy>


121
bytraffic or byrequests




  ProxyPass / balancer://hotcluster/
  <Proxy balancer://hotcluster>
   BalancerMember http://1.2.3.4:8009 loadfactor=1
   BalancerMember http://1.2.3.5:8009 loadfactor=2
   # The below is the hot standby
   BalancerMember http://1.2.3.6:8009 status=+H
   ProxySet lbmethod=bytraffic
  </Proxy>


122
BalancerManager




      <Location /balancer-manager>
       SetHandler balancer-manager

       Order Deny,Allow
       Deny from all
       Allow from .example.com
      </Location>



123
124
Disable a
      particular host




125
Notes




      • The things on the other end don’t have to
         be Apache
      • This is a popular way to set up Ruby on
         Rails, with Mongrel




126
Bandwidth limiting
                       Picture by Joachim S. Müller (Flickr)




        People always want their websites to run
        slower. Seems odd to me ...
In 2.4 ...




      • 2.4 adds two new modules for this
         purpose
      • mod_dialup
      • mod_ratelimit
mod_dialup




     Party like it’s 1999
v.92? Really?
                <Location /mysite>
                  ModemStandard V.92
                </Location>

      Also available:
         V.21
         V.26bis
         V.32
         V.92
mod_ratelimit

     <Location /downloads>
       SetHandler RATE_LIMIT
       SetEnv rate-limit 400
     </Location>




  Speed is in kb/s
Prior to 2.4


      A variety of other modules do bandwidth
      kind of things:




                   mod_cband
                  mod_bwshare
                    mod_bw
                  mod_evasive
                 mod_limitipconn
Logging




    • mod_logio
    • mod_log_forensic
Obligatory ridiculous log photo




                                  Photo by Zevotron (Flickr)
Not enough




    • Your log files don’t tell you enough
    • Want more
Logging - mod_logio




      Complete INPUT and
      OUTPUT size



136
Logging - mod_logio




      Complete INPUT and
      OUTPUT size



137
Combined Log Format - Bytes transferred




138
Less than half the story

       • Only bytes transferred to the
          client
       • Doesn’t include headers
       • Doesn’t include data sent from
          the client to the server


139
mod_logio



      •Adds two additional
       variables
      •%I - Input bytes
      •%O - Output bytes
      •Includes headers, both
       directions
140
LogFormat




141
mod_log_forensic




    • Did it ever finish?
ForensicLog

 ForensicLog /var/log/httpd/forensic.log
ForensicLog

 ForensicLog /var/log/httpd/forensic.log




    • Post-process with the check-forensic
       script to tell you which URLs never exited
mod_speling




               CheckSpelling On
              CheckCaseOnly On
Image Theft


  SetEnvIf Referer 
          ".example.com/" local_referal
  # Allow browsers that do not send Referer info
  SetEnvIf Referer "^$" local_referal
  <Directory /web/images>
    Order Deny,Allow
    Deny from all
    Allow from env=local_referal
  </Directory>
Or ...




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

# depending upon in which context
# you use the RewriteRule,
# you might need a condition to
# exclude the go_away.png to prevent
# an internal redirect looping. We don't use a RegEx here:

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

# depending upon in which context
# you use the RewriteRule,
# you might need a condition to
# exclude the go_away.png to prevent
# an internal redirect looping. We don't use a RegEx here:

RewriteCond %{REQUEST_URI} !=/images/go_away.png
RewriteRule .(jpe?g|gif|png)$ 
 http://other.example.com/images/go_away.png [R,NC,L]
Query Strings and Path Info
Query Strings




monkeys.php?q=lemur&color=green&level=99.7&doc=info.txt

     • Query Strings are:
      • Ugly
      • Hard to type
      • Hard to remember
      • Potentially insecure
Query Strings




monkeys.php?q=lemur&color=green&level=99.7&doc=info.txt


     • Query Strings are:
      • Ugly
      • Hard to type
      • Hard to remember
      • Potentially insecure
Path Info




monkeys.php?q=lemur&color=green&level=99.7&doc=info.txt


             /monkeys/lemur/green/99.7/info
mod_rewrite




monkeys.php?q=lemur&color=green&level=99.7&doc=info.txt

             /monkeys/lemur/green/99.7/info



     RewriteRule ^/monkeys/(.+)/(.+)/(.+)/(.+) 
/monkeys.php?q=$1&color=$2&level=$3&doc=$4.txt 
                    [PT,L,NE]
Engineering for failure




     •   Why not do it right to
         begin with, and avoid the
         mess?
     •   PHP makes this fairly
         easy
Step One: SetHandler
              /monkeys/lemur/green/99.7/info

    • We want monkeys to be a PHP script
    • We rename monkeys.php to monkeys, and
       then ...
        <Files monkeys>
         SetHandler application/x-httpd-php
        </Files>
                            This goes in your
                            server config, or
                               in .htaccess
Step Two: explode()
             /monkeys/lemur/green/99.7/info

    • The rest of the solution is in your
       PHP:
   $args = explode( $_SERVER[‘PATH_INFO’] );
   $type = $args[0];
   $color = $args[1];
   ...
While we’re at it


     • File extensions are *so* 1980s
     • All your files are php files, right?
     • Why give them a .php extension?

    RewriteCond %{REQUEST_URI} !.
    RewriteRule ^ - [H=application/x-httpd-php,PT]
Write a better FM




     • I’ll never get this far in the presentation,
       right?

More Related Content

What's hot

Apache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer AppApache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer AppJim Jagielski
 
Drupal, varnish, esi - Toulouse November 2
Drupal, varnish, esi - Toulouse November 2Drupal, varnish, esi - Toulouse November 2
Drupal, varnish, esi - Toulouse November 2Marcus Deglos
 
Integrated Cache on Netscaler
Integrated Cache on NetscalerIntegrated Cache on Netscaler
Integrated Cache on NetscalerMark Hillick
 
Installation Openstack Swift
Installation Openstack SwiftInstallation Openstack Swift
Installation Openstack Swiftymtech
 
Dockerizing WordPress
Dockerizing WordPressDockerizing WordPress
Dockerizing WordPressdotCloud
 
Zend_Cache: how to improve the performance of PHP applications
Zend_Cache: how to improve the performance of PHP applicationsZend_Cache: how to improve the performance of PHP applications
Zend_Cache: how to improve the performance of PHP applicationsEnrico Zimuel
 
Site Performance - From Pinto to Ferrari
Site Performance - From Pinto to FerrariSite Performance - From Pinto to Ferrari
Site Performance - From Pinto to FerrariJoseph Scott
 
rest3d Web3D 2014
rest3d Web3D 2014rest3d Web3D 2014
rest3d Web3D 2014Remi Arnaud
 
Varnish http accelerator
Varnish http acceleratorVarnish http accelerator
Varnish http acceleratorno no
 
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...Positive Hack Days
 
Krzysztof Kotowicz - Hacking HTML5
Krzysztof Kotowicz - Hacking HTML5Krzysztof Kotowicz - Hacking HTML5
Krzysztof Kotowicz - Hacking HTML5DefconRussia
 
20100425 Configuration Management With Puppet Lfnw
20100425 Configuration Management With Puppet Lfnw20100425 Configuration Management With Puppet Lfnw
20100425 Configuration Management With Puppet Lfnwgarrett honeycutt
 
Automating complex infrastructures with Puppet
Automating complex infrastructures with PuppetAutomating complex infrastructures with Puppet
Automating complex infrastructures with PuppetKris Buytaert
 
Docker for PHP Developers - Madison PHP 2017
Docker for PHP Developers - Madison PHP 2017Docker for PHP Developers - Madison PHP 2017
Docker for PHP Developers - Madison PHP 2017Chris Tankersley
 
Making Your Capistrano Recipe Book
Making Your Capistrano Recipe BookMaking Your Capistrano Recipe Book
Making Your Capistrano Recipe BookTim Riley
 
MNPHP Scalable Architecture 101 - Feb 3 2011
MNPHP Scalable Architecture 101 - Feb 3 2011MNPHP Scalable Architecture 101 - Feb 3 2011
MNPHP Scalable Architecture 101 - Feb 3 2011Mike Willbanks
 

What's hot (20)

Apache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer AppApache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer App
 
Drupal, varnish, esi - Toulouse November 2
Drupal, varnish, esi - Toulouse November 2Drupal, varnish, esi - Toulouse November 2
Drupal, varnish, esi - Toulouse November 2
 
Integrated Cache on Netscaler
Integrated Cache on NetscalerIntegrated Cache on Netscaler
Integrated Cache on Netscaler
 
FreeBSD: Dev to Prod
FreeBSD: Dev to ProdFreeBSD: Dev to Prod
FreeBSD: Dev to Prod
 
Installation Openstack Swift
Installation Openstack SwiftInstallation Openstack Swift
Installation Openstack Swift
 
Building Client-Side Attacks with HTML5 Features
Building Client-Side Attacks with HTML5 FeaturesBuilding Client-Side Attacks with HTML5 Features
Building Client-Side Attacks with HTML5 Features
 
Varnish Cache
Varnish CacheVarnish Cache
Varnish Cache
 
Dockerizing WordPress
Dockerizing WordPressDockerizing WordPress
Dockerizing WordPress
 
Zend_Cache: how to improve the performance of PHP applications
Zend_Cache: how to improve the performance of PHP applicationsZend_Cache: how to improve the performance of PHP applications
Zend_Cache: how to improve the performance of PHP applications
 
Site Performance - From Pinto to Ferrari
Site Performance - From Pinto to FerrariSite Performance - From Pinto to Ferrari
Site Performance - From Pinto to Ferrari
 
rest3d Web3D 2014
rest3d Web3D 2014rest3d Web3D 2014
rest3d Web3D 2014
 
Varnish - PLNOG 4
Varnish - PLNOG 4Varnish - PLNOG 4
Varnish - PLNOG 4
 
Varnish http accelerator
Varnish http acceleratorVarnish http accelerator
Varnish http accelerator
 
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...
Изучаем миллиард состояний программы на уровне профи. Как разработать быстрый...
 
Krzysztof Kotowicz - Hacking HTML5
Krzysztof Kotowicz - Hacking HTML5Krzysztof Kotowicz - Hacking HTML5
Krzysztof Kotowicz - Hacking HTML5
 
20100425 Configuration Management With Puppet Lfnw
20100425 Configuration Management With Puppet Lfnw20100425 Configuration Management With Puppet Lfnw
20100425 Configuration Management With Puppet Lfnw
 
Automating complex infrastructures with Puppet
Automating complex infrastructures with PuppetAutomating complex infrastructures with Puppet
Automating complex infrastructures with Puppet
 
Docker for PHP Developers - Madison PHP 2017
Docker for PHP Developers - Madison PHP 2017Docker for PHP Developers - Madison PHP 2017
Docker for PHP Developers - Madison PHP 2017
 
Making Your Capistrano Recipe Book
Making Your Capistrano Recipe BookMaking Your Capistrano Recipe Book
Making Your Capistrano Recipe Book
 
MNPHP Scalable Architecture 101 - Feb 3 2011
MNPHP Scalable Architecture 101 - Feb 3 2011MNPHP Scalable Architecture 101 - Feb 3 2011
MNPHP Scalable Architecture 101 - Feb 3 2011
 

Similar to Apache Cookbook: Recipes for managing your Apache HTTP Server

PowerPoint Presentation
PowerPoint PresentationPowerPoint Presentation
PowerPoint Presentationwebhostingguy
 
[Devconf.cz][2017] Understanding OpenShift Security Context Constraints
[Devconf.cz][2017] Understanding OpenShift Security Context Constraints[Devconf.cz][2017] Understanding OpenShift Security Context Constraints
[Devconf.cz][2017] Understanding OpenShift Security Context ConstraintsAlessandro Arrichiello
 
Road to Opscon (Pisa '15) - DevOoops
Road to Opscon (Pisa '15) - DevOoopsRoad to Opscon (Pisa '15) - DevOoops
Road to Opscon (Pisa '15) - DevOoopsGianluca Varisco
 
Vorontsov, golovko ssrf attacks and sockets. smorgasbord of vulnerabilities
Vorontsov, golovko   ssrf attacks and sockets. smorgasbord of vulnerabilitiesVorontsov, golovko   ssrf attacks and sockets. smorgasbord of vulnerabilities
Vorontsov, golovko ssrf attacks and sockets. smorgasbord of vulnerabilitiesDefconRussia
 
WordPress Development Environments
WordPress Development Environments WordPress Development Environments
WordPress Development Environments Ohad Raz
 
Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)
Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)
Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)Codemotion
 
Apache web server installation/configuration, Virtual Hosting
Apache web server installation/configuration, Virtual HostingApache web server installation/configuration, Virtual Hosting
Apache web server installation/configuration, Virtual Hostingwebhostingguy
 
Deploying to Ubuntu on Linode
Deploying to Ubuntu on LinodeDeploying to Ubuntu on Linode
Deploying to Ubuntu on LinodeWO Community
 
Dockerizing WordPress
Dockerizing WordPressDockerizing WordPress
Dockerizing WordPressDocker, Inc.
 
Stress Free Deployment - Confoo 2011
Stress Free Deployment  - Confoo 2011Stress Free Deployment  - Confoo 2011
Stress Free Deployment - Confoo 2011Bachkoutou Toutou
 
Apache server configuration & optimization
Apache server configuration & optimizationApache server configuration & optimization
Apache server configuration & optimizationGokul Muralidharan
 
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...Hackito Ergo Sum
 
Apache2 BootCamp : Getting Started With Apache
Apache2 BootCamp : Getting Started With ApacheApache2 BootCamp : Getting Started With Apache
Apache2 BootCamp : Getting Started With ApacheWildan Maulana
 
Nginx A High Performance Load Balancer, Web Server & Reverse Proxy
Nginx A High Performance Load Balancer, Web Server & Reverse ProxyNginx A High Performance Load Balancer, Web Server & Reverse Proxy
Nginx A High Performance Load Balancer, Web Server & Reverse ProxyAmit Aggarwal
 
Apache Server Tutorial
Apache Server TutorialApache Server Tutorial
Apache Server TutorialJagat Kothari
 
CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...
CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...
CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...PROIDEA
 
Local development environment evolution
Local development environment evolutionLocal development environment evolution
Local development environment evolutionWise Engineering
 
Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!Jeff Jones
 

Similar to Apache Cookbook: Recipes for managing your Apache HTTP Server (20)

PowerPoint Presentation
PowerPoint PresentationPowerPoint Presentation
PowerPoint Presentation
 
[Devconf.cz][2017] Understanding OpenShift Security Context Constraints
[Devconf.cz][2017] Understanding OpenShift Security Context Constraints[Devconf.cz][2017] Understanding OpenShift Security Context Constraints
[Devconf.cz][2017] Understanding OpenShift Security Context Constraints
 
Road to Opscon (Pisa '15) - DevOoops
Road to Opscon (Pisa '15) - DevOoopsRoad to Opscon (Pisa '15) - DevOoops
Road to Opscon (Pisa '15) - DevOoops
 
Vorontsov, golovko ssrf attacks and sockets. smorgasbord of vulnerabilities
Vorontsov, golovko   ssrf attacks and sockets. smorgasbord of vulnerabilitiesVorontsov, golovko   ssrf attacks and sockets. smorgasbord of vulnerabilities
Vorontsov, golovko ssrf attacks and sockets. smorgasbord of vulnerabilities
 
WordPress Development Environments
WordPress Development Environments WordPress Development Environments
WordPress Development Environments
 
Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)
Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)
Gianluca Varisco - DevOoops (Increase awareness around DevOps infra security)
 
Apache web server installation/configuration, Virtual Hosting
Apache web server installation/configuration, Virtual HostingApache web server installation/configuration, Virtual Hosting
Apache web server installation/configuration, Virtual Hosting
 
Deploying to Ubuntu on Linode
Deploying to Ubuntu on LinodeDeploying to Ubuntu on Linode
Deploying to Ubuntu on Linode
 
Dockerizing WordPress
Dockerizing WordPressDockerizing WordPress
Dockerizing WordPress
 
Stress Free Deployment - Confoo 2011
Stress Free Deployment  - Confoo 2011Stress Free Deployment  - Confoo 2011
Stress Free Deployment - Confoo 2011
 
Apache server configuration & optimization
Apache server configuration & optimizationApache server configuration & optimization
Apache server configuration & optimization
 
Top ten-list
Top ten-listTop ten-list
Top ten-list
 
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...
[HES2013] Virtually secure, analysis to remote root 0day on an industry leadi...
 
Apache2 BootCamp : Getting Started With Apache
Apache2 BootCamp : Getting Started With ApacheApache2 BootCamp : Getting Started With Apache
Apache2 BootCamp : Getting Started With Apache
 
Rack
RackRack
Rack
 
Nginx A High Performance Load Balancer, Web Server & Reverse Proxy
Nginx A High Performance Load Balancer, Web Server & Reverse ProxyNginx A High Performance Load Balancer, Web Server & Reverse Proxy
Nginx A High Performance Load Balancer, Web Server & Reverse Proxy
 
Apache Server Tutorial
Apache Server TutorialApache Server Tutorial
Apache Server Tutorial
 
CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...
CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...
CONFidence 2018: Attacking web servers via run time configuration (Eldar "Wir...
 
Local development environment evolution
Local development environment evolutionLocal development environment evolution
Local development environment evolution
 
Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!Apache and PHP: Why httpd.conf is your new BFF!
Apache and PHP: Why httpd.conf is your new BFF!
 

More from Rich Bowen

Why your employees should contribute to Open Source
Why your employees should contribute to Open SourceWhy your employees should contribute to Open Source
Why your employees should contribute to Open SourceRich Bowen
 
URL Mapping, with and without mod_rewrite
URL Mapping, with and without mod_rewriteURL Mapping, with and without mod_rewrite
URL Mapping, with and without mod_rewriteRich Bowen
 
Don't be a jerk
Don't be a jerkDon't be a jerk
Don't be a jerkRich Bowen
 
Write A Better FM - Ohio Linux 2011
Write A Better FM - Ohio Linux 2011Write A Better FM - Ohio Linux 2011
Write A Better FM - Ohio Linux 2011Rich Bowen
 
mod_rewrite bootcamp, Ohio LInux 2011
mod_rewrite bootcamp, Ohio LInux 2011mod_rewrite bootcamp, Ohio LInux 2011
mod_rewrite bootcamp, Ohio LInux 2011Rich Bowen
 
Write a better FM
Write a better FMWrite a better FM
Write a better FMRich Bowen
 

More from Rich Bowen (7)

The apacheway
The apachewayThe apacheway
The apacheway
 
Why your employees should contribute to Open Source
Why your employees should contribute to Open SourceWhy your employees should contribute to Open Source
Why your employees should contribute to Open Source
 
URL Mapping, with and without mod_rewrite
URL Mapping, with and without mod_rewriteURL Mapping, with and without mod_rewrite
URL Mapping, with and without mod_rewrite
 
Don't be a jerk
Don't be a jerkDon't be a jerk
Don't be a jerk
 
Write A Better FM - Ohio Linux 2011
Write A Better FM - Ohio Linux 2011Write A Better FM - Ohio Linux 2011
Write A Better FM - Ohio Linux 2011
 
mod_rewrite bootcamp, Ohio LInux 2011
mod_rewrite bootcamp, Ohio LInux 2011mod_rewrite bootcamp, Ohio LInux 2011
mod_rewrite bootcamp, Ohio LInux 2011
 
Write a better FM
Write a better FMWrite a better FM
Write a better FM
 

Recently uploaded

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 

Recently uploaded (20)

Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 

Apache Cookbook: Recipes for managing your Apache HTTP Server

  • 1. Apache Cookbook Recipes for managing your Apache HTTP Server / Rich Bowen - rbowen@apache.org
  • 2. Shameless Plug Buy! Buy! Buy!
  • 3. Old Hat ----> • 1.3 is end of life • 2.0 will be by the end of the year • 2.2 is now • 2.4 is tomorrow Photo CC by “Lost Albatross” - Flickr
  • 4. URLs you need • http://people.apache.org/~rbowen • http://wiki.apache.org/httpd • http://httpd.apache.org/docs/trunk/
  • 5. Recipes Photo CC by Chemical Heritage Foundation - Flickr
  • 7. Say it with style IndexStyleSheet /styles/dir.css ... .odd { background-color: #eef; } .even { background-color: #fff; }
  • 8. Caveat: Some features 2.4 only • In 2.2 and earlier, you can specify a style sheet, but no classes are added to the HTML • Useful, but not quite as useful
  • 9. Now, with extra class <table id="indexlist"> <tr class="indexhead"> <th class="indexcolicon">... <th class="indexcolname">... <th class="indexcollastmod">... <th class="indexcolsize">... <th class="indexcoldesc">... <tr class="indexbreakrow">... <tr class="even"><td class="indexcolicon">...
  • 10. An exercise for the reader: • Nifty mouse-over effects (JS in HeaderName file?) Photo CC by Ugglan - Flickr • AJAXy file interaction of some kind? • Photo gallery, entirely based on mod_autoindex and Javascript?
  • 11. mod_substitite • New module in 2.2 • Rewrite content using regular expressions • Syntax is identical to sed
  • 12. s/foo/bar/ • Simple example - switch fonts LoadModule substitute_module libexec/apache2/mod_substitute.so AddOutputFilterByType SUBSTITUTE text/html Substitute s/ariel/courier/i
  • 13. Proxying • More useful example • Proxying to back-end server that returns fully-qualified URLs LoadModule substitute_module libexec/apache2/mod_substitute.so AddOutputFilterByType SUBSTITUTE text/html Substitute s/backend.local/www.example.com/ni
  • 14. mod_security • Are you running mod_security?
  • 15. mod_security • You should be
  • 16. http firewall • The earlier you catch it ...
  • 17. Holes Photo CC by Darwin Bell
  • 18. SQL Injection # Prevent SQL injection attacks SecFilter "delete[[:space:]]+from" SecFilter "insert[[:space:]]+into" SecFilter "select.+from" 18
  • 19. Make sure you ... # Inspect POST payloads SecFilterScanPOST On # Default action set SecFilterDefaultAction "deny,log,status:406" 19
  • 20. While you’re at it # Inspect POST payloads SecFilterScanPOST On SecFilter “vidocin” 20
  • 21. Acceptable arguments # Only for the FormMail script <Location /cgi-bin/FormMail> # Reject request where the value of parameter "recipient" # does not end with "@apache.org" SecFilterSelective ARG_recipient "![a-zA-Z0-9]+@apache.org$"> </Location> 21
  • 22. Which PHP script is slagging my server? • Which process, and what is it doing? • Look at /server-status for a process list
  • 23. Step 1: Look at top: • Run ‘top’ • Order by CPU usage • Pick off the httpd processes that are causing the problem and make note of their PIDs
  • 24. Step 2: /server-status • Look at /server-status output • Look for the PIDs you noted • Move fast - the process may be gone already
  • 26. ExtendedStatus On • You’ll need “ExtendedStatus On” to get these details: <Location /server-status> SetHandler server-status </Location> ExtendedStatus On
  • 27. SNI • General knowledge: SSL requires one certificate per IP address • That is, only one SSL site can be on each IP address • Limitation of SSL itself
  • 29. SSL handshake Certificate Hostname
  • 31. SNI
  • 32. SNI • Server Name Indication • Passes server name in initial handshake • Simple solutions are always best
  • 33. Caveats • You knew there would be a catch Mozilla Firefox 2.0 or later Opera 8.0 or later (the TLS 1.1 protocol must be enabled) Internet Explorer 7 (Vista or higher, not XP) or later Google Chrome (Vista or higher, not XP. OS X 10.5.7 or higher on Chrome 5.0.342.1 or newer) Safari Safari 3.2.1 and newer on Mac OS X 10.5.6 and Windows Vista or higher, not XP
  • 34. Apache • 2.2.12 or later Listen 443 # Listen for virtual host requests on all IP addresses NameVirtualHost *:443 # Go ahead and accept connections for these vhosts # from non-SNI clients SSLStrictSNIVHostCheck off <VirtualHost *:443> DocumentRoot /www/example1 ServerName www.example.com </VirtualHost> <VirtualHost *:443> DocumentRoot /www/example2 ServerName www.example2.org </VirtualHost>
  • 36. Secure mod_dav deployment • Security rule #1: Content is not writable • Corollary: Anyone telling you to ‘chmod 777’ is a monkey • Anyone telling you ‘chown apache something.php’ *might* be a monkey. Or they might be working around Apache’s annoying permissions model
  • 37. However ... •Setting up WebDAV requires that content be writable ... •And owned by Apache •This is annoying
  • 38. WebDAV <Directory /var/www/content> Dav On </Directory>
  • 39. Why this is a problem • People write bad code • It’s easy to get PHP (or whatever else) to overwrite your content • Now your site is a radical terrorist site • This is a very unpleasant thing to wake up to on a Saturday morning
  • 40. Secure DAV • It’s possible to set up Dav without having the files written by the Apache user • Sort of 40
  • 41. Two Apache Processes Primary Secondary server, server, running as running as user www user dav File System, owned by dav 41
  • 42. Two Apache Processes Read-only Running ordinary set of modules Running web apps, etc Primary server, running as user www File System, owned by dav 42
  • 43. Two Apache Processes Read/Write Remove all extra modules SSL Secondary server, Authenticated running as user dav File System, owned by dav 43
  • 44. Multi-server config. drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www 1 Listen *:80 User www Group www DocumentRoot /var/www/ Listen *:8080 2 DavLockDb /var/lock/dav User dav Group dav DocumentRoot /var/www/ 44
  • 45. drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www 1 Listen *:80 Can write User www Group www DocumentRoot /var/www/ Listen *:8080 2 DavLockDb /var/lock/dav User dav Group dav DocumentRoot /var/www/ 45
  • 46. drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www 1 Can’t Listen *:80 User www Group www DocumentRoot /var/www/ Listen *:8080 2 DavLockDb /var/lock/dav User dav Group dav DocumentRoot /var/www/ 46
  • 47. <If> Picture by BrewBooks (Flickr) My favorite new feature in 2.4
  • 48. <If> <If ‘$req{Host} = “www.example.com”’> RedirectMatch (.*) http://example.com/$1 </If>
  • 49. <If> <If ‘$req{Host} = “www.example.com”’> RedirectMatch (.*) http://example.com/$1 </If> This was hard prior to 2.4, and probably required mod_rewrite, or a separate virtual host.
  • 50. <If> <If ‘$req{Host} = “www.example.com”’> RedirectMatch (.*) http://example.com/$1 </If> $req $resp $env
  • 51. Logging - Conditional Logging • Don’t log certain things • Per-directory logging 51
  • 52. Conditional LogFormat • The LogFormat directive supports some conditionals in the variables • "%!200,304,302{Referer}i" logs Referer on all requests that do not return one of the three specified codes 52
  • 53. Conditional LogFormat • "%400,501{User-agent}i" logs User-agent on 400 errors and 501 errors only • For other status codes, the literal string "-" will be logged 53
  • 54. Conditional CustomLog • Stick Env=xyz on the end • or Env=!xyz • Yes, that’s =! not != 54
  • 55. For example ... SetEnvIf Request_URI .gif$ gif-image CustomLog gif-requests.log common env=gif-image CustomLog nongif-requests.log common env=!gif-image 55
  • 56. For example ... SetEnvIf Request_URI .gif$ gif-image CustomLog gif-requests.log common env=gif-image CustomLog nongif-requests.log common env=!gif-image 56
  • 57. For example ... SetEnvIf Request_URI .gif$ gif-image CustomLog gif-requests.log common env=gif-image CustomLog nongif-requests.log common env=!gif-image 57
  • 58. So the images get logged here SetEnvIf Request_URI .gif$ gif-image CustomLog gif-requests.log common env=gif-image CustomLog nongif-requests.log common env=!gif-image 58
  • 59. And everything else goes here SetEnvIf Request_URI .gif$ gif-image CustomLog gif-requests.log common env=gif-image CustomLog nongif-requests.log common env=!gif-image 59
  • 60. Per directory SetEnvIf Request_URI ^/marketing mkt CustomLog marketing.log common env=mkt 60
  • 61. PCRE Zero-width assertions • Match everything except one thing • While you can do this with RewriteRule, it would be nice if you could do it with other directives DirectoryMatch FilesMatch RedirectMatch
  • 62. Negative Lookahead • PCRE provides a regex syntax to say “not preceded by” or “not followed by” • Negative lookbehind and negative lookahead, respectively
  • 63. Andrei Rocks • While we’re on the topic: • Pretty much the best presentation on regular expressions anywhere: • http://www.slideshare.net/ andreizm/andreis-regex-clinic
  • 64. Everything except ... • “I want to redirect everything except / images” • This is where you’d use a negative lookahead • Necessary because RedirectMatch doesn’t support negation RedirectMatch ^/(?!images/)(.*) http://other.myhost.com/$1
  • 65. Everything except ... • Match anything ... • RedirectMatch ^/(?!images/)(.*) http://other.myhost.com/$1
  • 66. Everything except ... • Match anything ... • That doesn’t start with images/ RedirectMatch ^/(?!images/)(.*) http://other.myhost.com/$1
  • 67. Everything except ... This is called a “zero width” assertion, because it doesn’t fill $1, and doesn’t consume any characters in the match. RedirectMatch ^/(?!images/)(.*) http://other.myhost.com/$1
  • 68.
  • 69. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9
  • 70. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9 • Alas, not in .htaccess • Logs are always opened at startup
  • 71. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9 • Most entries between 1-4
  • 72. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9 • If there’s nothing in there, your rules are being ignored.
  • 73. Logging - RewriteLog RewriteLog /var/log/rewrite.log RewriteLogLevel 9 73
  • 74. Logging - RewriteLog RewriteLog /var/log/rewrite.log RewriteLogLevel 9 74
  • 75. Logging - RewriteLog RewriteLog /var/log/rewrite.log RewriteLogLevel 9 75
  • 76. 76
  • 77. Kind of intimidating, isn’t it? 77
  • 78. Learn to ignore the irrelevant bits 78
  • 79. Which bits are those? 121.14.76.185 - - [24/Sep/2008:21:35:51 --0400] [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/ initial] (4) [perdir /var/www/vhosts/drbacchus/] RewriteCond: input='/var/www/vhosts/drbacchus/ podcasts/poetry/maninmoon.mp3' pattern='!-f' => not- matched 79
  • 80. Client address 121.14.76.185 - - [24/Sep/2008:21:35:51 --0400] [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/ initial] (4) [perdir /var/www/vhosts/drbacchus/] RewriteCond: input='/var/www/vhosts/drbacchus/ podcasts/poetry/maninmoon.mp3' pattern='!-f' => not- matched 80
  • 81. Dunno what those are 121.14.76.185 - - [24/Sep/2008:21:35:51 --0400] [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/ initial] (4) [perdir /var/www/vhosts/drbacchus/] RewriteCond: input='/var/www/vhosts/drbacchus/ podcasts/poetry/maninmoon.mp3' pattern='!-f' => not- matched 81
  • 82. Time 121.14.76.185 - - [24/Sep/2008:21:35:51 --0400] [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/ initial] (4) [perdir /var/www/vhosts/drbacchus/] RewriteCond: input='/var/www/vhosts/drbacchus/ podcasts/poetry/maninmoon.mp3' pattern='!-f' => not- matched 82
  • 83. Unique id 121.14.76.185 - - [24/Sep/2008:21:35:51 --0400] [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/ initial] (4) [perdir /var/www/vhosts/drbacchus/] RewriteCond: input='/var/www/vhosts/drbacchus/ podcasts/poetry/maninmoon.mp3' pattern='!-f' => not- matched 83
  • 84. Request ID 121.14.76.185 - - [24/Sep/2008:21:35:51 --0400] [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/ initial] (4) [perdir /var/www/vhosts/drbacchus/] RewriteCond: input='/var/www/vhosts/drbacchus/ podcasts/poetry/maninmoon.mp3' pattern='!-f' => not- matched 84
  • 85. The useful bit 121.14.76.185 - - [24/Sep/2008:21:35:51 --0400] [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/ initial] (4) [perdir /var/www/vhosts/drbacchus/] RewriteCond: input='/var/www/vhosts/drbacchus/ podcasts/poetry/maninmoon.mp3' pattern='!-f' => not- matched 85
  • 86. Wouldn’t it be nice if you could just see the useful part? 86
  • 87. You could change the way mod_rewrite logs:
  • 88. Piped logs • I actually use a piped lot handler to remove this superfluous stuff • Like so ... RewriteLog |/usr/local/bin/rewrite_log_pipe RewriteLogLevel 9 88
  • 89. RewriteLog |/usr/local/bin/rewrite_log_pipe RewriteLogLevel 9 with ... #!/usr/bin/perl $|++; open (F, ">>/tmp/rewrite"); select F; while (<>) { s/^.*((d).*)/$1/; print; } 89
  • 90. RewriteLog |/usr/local/bin/rewrite_log_pipe RewriteLogLevel 9 This bit says “instead of logging to a text file, invoke this script and send the log entries there.” 90
  • 91. #!/usr/bin/perl $|++; open (F, ">>/tmp/rewrite"); select F; while (<>) { s/^.*((d).*)/$1/; print; } • Look for the (1) or (2) bit • drop everything before that 91
  • 92. Results in: (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched (3) applying pattern 'wp-rss2.php' to uri '/index.php' (3) applying pattern '(journal/)?index.rdf' to uri '/index.php' (3) applying pattern '^/wordpress/wp-comments' to uri '/index.php' (3) applying pattern '^/perm/(.*)' to uri '/index.php' (3) applying pattern '^/articles?/(.*)' to uri '/index.php' (3) applying pattern '^/blog/(.*)' to uri '/index.php' (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php' (3) applying pattern '^/book/cookbook' to uri '/index.php' (3) applying pattern '^/book/2.2' to uri '/index.php' (3) applying pattern '^/booklink/(.*)' to uri '/index.php' (3) applying pattern '^/books?/(.+)' to uri '/index.php' (1) pass through /index.php 92
  • 93. Results in: (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched (3) applying pattern 'wp-rss2.php' to uri '/index.php' (3) applying pattern '(journal/)?index.rdf' to uri '/index.php' (3) applying pattern '^/wordpress/wp-comments' to uri '/index.php' (3) applying pattern '^/perm/(.*)' to uri '/index.php' (3) applying pattern '^/articles?/(.*)' to uri '/index.php' (3) applying pattern '^/blog/(.*)' to uri '/index.php' better? See? Isn’t that (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php' (3) applying pattern '^/book/cookbook' to uri '/index.php' (3) applying pattern '^/book/2.2' to uri '/index.php' (3) applying pattern '^/booklink/(.*)' to uri '/index.php' (3) applying pattern '^/books?/(.+)' to uri '/index.php' (1) pass through /index.php 93
  • 94. Requested URI (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched (3) applying pattern 'wp-rss2.php' to uri '/index.php' (3) applying pattern '(journal/)?index.rdf' to uri '/index.php' (3) applying pattern '^/wordpress/wp-comments' to uri '/index.php' (3) applying pattern '^/perm/(.*)' to uri '/index.php' (3) applying pattern '^/articles?/(.*)' to uri '/index.php' (3) applying pattern '^/blog/(.*)' to uri '/index.php' (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php' (3) applying pattern '^/book/cookbook' to uri '/index.php' (3) applying pattern '^/book/2.2' to uri '/index.php' (3) applying pattern '^/booklink/(.*)' to uri '/index.php' (3) applying pattern '^/books?/(.+)' to uri '/index.php' (1) pass through /index.php 94
  • 95. Patterns applied (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched (3) applying pattern 'wp-rss2.php' to uri '/index.php' (3) applying pattern '(journal/)?index.rdf' to uri '/index.php' (3) applying pattern '^/wordpress/wp-comments' to uri '/index.php' (3) applying pattern '^/perm/(.*)' to uri '/index.php' (3) applying pattern '^/articles?/(.*)' to uri '/index.php' (3) applying pattern '^/blog/(.*)' to uri '/index.php' (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php' (3) applying pattern '^/book/cookbook' to uri '/index.php' (3) applying pattern '^/book/2.2' to uri '/index.php' (3) applying pattern '^/booklink/(.*)' to uri '/index.php' (3) applying pattern '^/books?/(.+)' to uri '/index.php' (1) pass through /index.php 95
  • 96. None of them matched (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched (3) applying pattern 'wp-rss2.php' to uri '/index.php' (3) applying pattern '(journal/)?index.rdf' to uri '/index.php' (3) applying pattern '^/wordpress/wp-comments' to uri '/index.php' (3) applying pattern '^/perm/(.*)' to uri '/index.php' (3) applying pattern '^/articles?/(.*)' to uri '/index.php' (3) applying pattern '^/blog/(.*)' to uri '/index.php' (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/index.php' (3) applying pattern '^/book/cookbook' to uri '/index.php' (3) applying pattern '^/book/2.2' to uri '/index.php' (3) applying pattern '^/booklink/(.*)' to uri '/index.php' (3) applying pattern '^/books?/(.+)' to uri '/index.php' (1) pass through /index.php 96
  • 97. And now • We can actually make some sense of what’s happening • Less inscrutable noise • Yes, it means something, but not to normal people 97
  • 98. Examples (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched • This was the result of RewriteCond %{HTTP_HOST} !^wooga.drbacchus.com [NC] 98
  • 99. Examples (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched • It shows what the input variable looked like RewriteCond %{HTTP_HOST} !^wooga.drbacchus.com [NC] 99
  • 100. Examples (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched • And what pattern was applied RewriteCond %{HTTP_HOST} !^wooga.drbacchus.com [NC] 100
  • 101. Examples (4) RewriteCond: input='wooga.drbacchus.com' pattern='!^wooga.drbacchus .com' [NC] => not-matched • As well as what happened RewriteCond %{HTTP_HOST} !^wooga.drbacchus.com [NC] 101
  • 102. Another example (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/ index.php' • Was a result of RewriteRule ^/book/(mod)?_?rewrite http://www.amazon.com/exec/obidos/asin/ 1590595610/drbacchus/ [R,L] 102
  • 103. Again ... (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/ index.php' • What was requested RewriteRule ^/book/(mod)?_?rewrite http://www.amazon.com/exec/obidos/asin/ 1590595610/drbacchus/ [R,L] 103
  • 104. And ... (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/ index.php' • What it was compared against RewriteRule ^/book/(mod)?_?rewrite http://www.amazon.com/exec/obidos/asin/ 1590595610/drbacchus/ [R,L] 104
  • 105. Matched? (3) applying pattern '^/book/(mod)?_?rewrite' to uri '/ index.php' • If it matched, the next line will be the action log RewriteRule ^/book/(mod)?_?rewrite http://www.amazon.com/exec/obidos/asin/ 1590595610/drbacchus/ [R,L] 105
  • 106. The whole thing (3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite' (2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/ asin/1590595610/drbacchus/' (2) explicitly forcing redirect with http://www.amazon.com/exec/ obidos/asin/1590595610/drbacchus/ (1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ for redirect (1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ [REDIRECT/302] 106
  • 107. The match: (3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite' (2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/ asin/1590595610/drbacchus/' (2) explicitly forcing redirect with http://www.amazon.com/exec/ obidos/asin/1590595610/drbacchus/ (1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ for redirect (1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ [REDIRECT/302] 107
  • 108. Followed by (3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite' (2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/ asin/1590595610/drbacchus/' (2) explicitly forcing redirect with http://www.amazon.com/exec/ obidos/asin/1590595610/drbacchus/ (1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ for redirect (1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ [REDIRECT/302] 108
  • 109. [R] (3) applying pattern '^/books?/(mod)?_?rewrite' to uri '/books/rewrite' (2) rewrite '/books/rewrite' -> 'http://www.amazon.com/exec/obidos/ asin/1590595610/drbacchus/' (2) explicitly forcing redirect with http://www.amazon.com/exec/ obidos/asin/1590595610/drbacchus/ (1) escaping http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ for redirect (1) redirect to http://www.amazon.com/exec/obidos/asin/1590595610/ drbacchus/ [REDIRECT/302] 109
  • 110. But it all runs together! • Look for: • (2) init rewrite engine with requested uri /atom/1 • ‘init rewrite engine’ shows where a new request started being rewritten 110
  • 111.
  • 113.
  • 114. Fortunately ... Photo CC by Camo53 (flickr) • mod_proxy_balancer • Added in 2.1
  • 115. Fairly simple to configure <Proxy balancer://mycluster> BalancerMember http://192.168.1.50:80 BalancerMember http://192.168.1.51:80 </Proxy> ProxyPass /test balancer://mycluster
  • 116. Fairly simple to configure <Proxy balancer://mycluster> BalancerMember http://192.168.1.50:80 BalancerMember http://192.168.1.51:80 </Proxy> ProxyPass /test balancer://mycluster
  • 117. Fairly simple to configure <Proxy balancer://mycluster> BalancerMember http://192.168.1.50:80 BalancerMember http://192.168.1.51:80 </Proxy> ProxyPass /test balancer://mycluster
  • 118. Sticky Sessions Ensures that connections go to the same server they started with. ProxyPass / balancer://mycluster/ stickysession=PHPSESSIONID 118
  • 119. Balancing measures ProxyPass / balancer://hotcluster/ <Proxy balancer://hotcluster> BalancerMember http://1.2.3.4:8009 loadfactor=1 BalancerMember http://1.2.3.5:8009 loadfactor=2 # The below is the hot standby BalancerMember http://1.2.3.6:8009 status=+H ProxySet lbmethod=bytraffic </Proxy> 119
  • 120. 1.2.3.5 gets twice the traffic ProxyPass / balancer://hotcluster/ <Proxy balancer://hotcluster> BalancerMember http://1.2.3.4:8009 loadfactor=1 BalancerMember http://1.2.3.5:8009 loadfactor=2 # The below is the hot standby BalancerMember http://1.2.3.6:8009 status=+H ProxySet lbmethod=bytraffic </Proxy> 120
  • 121. Hot spare ProxyPass / balancer://hotcluster/ <Proxy balancer://hotcluster> BalancerMember http://1.2.3.4:8009 loadfactor=1 BalancerMember http://1.2.3.5:8009 loadfactor=2 # The below is the hot standby BalancerMember http://1.2.3.6:8009 status=+H ProxySet lbmethod=bytraffic </Proxy> 121
  • 122. bytraffic or byrequests ProxyPass / balancer://hotcluster/ <Proxy balancer://hotcluster> BalancerMember http://1.2.3.4:8009 loadfactor=1 BalancerMember http://1.2.3.5:8009 loadfactor=2 # The below is the hot standby BalancerMember http://1.2.3.6:8009 status=+H ProxySet lbmethod=bytraffic </Proxy> 122
  • 123. BalancerManager <Location /balancer-manager> SetHandler balancer-manager Order Deny,Allow Deny from all Allow from .example.com </Location> 123
  • 124. 124
  • 125. Disable a particular host 125
  • 126. Notes • The things on the other end don’t have to be Apache • This is a popular way to set up Ruby on Rails, with Mongrel 126
  • 127. Bandwidth limiting Picture by Joachim S. Müller (Flickr) People always want their websites to run slower. Seems odd to me ...
  • 128. In 2.4 ... • 2.4 adds two new modules for this purpose • mod_dialup • mod_ratelimit
  • 129. mod_dialup Party like it’s 1999
  • 130. v.92? Really? <Location /mysite> ModemStandard V.92 </Location> Also available: V.21 V.26bis V.32 V.92
  • 131. mod_ratelimit <Location /downloads> SetHandler RATE_LIMIT SetEnv rate-limit 400 </Location> Speed is in kb/s
  • 132. Prior to 2.4 A variety of other modules do bandwidth kind of things: mod_cband mod_bwshare mod_bw mod_evasive mod_limitipconn
  • 133. Logging • mod_logio • mod_log_forensic
  • 134. Obligatory ridiculous log photo Photo by Zevotron (Flickr)
  • 135. Not enough • Your log files don’t tell you enough • Want more
  • 136. Logging - mod_logio Complete INPUT and OUTPUT size 136
  • 137. Logging - mod_logio Complete INPUT and OUTPUT size 137
  • 138. Combined Log Format - Bytes transferred 138
  • 139. Less than half the story • Only bytes transferred to the client • Doesn’t include headers • Doesn’t include data sent from the client to the server 139
  • 140. mod_logio •Adds two additional variables •%I - Input bytes •%O - Output bytes •Includes headers, both directions 140
  • 142. mod_log_forensic • Did it ever finish?
  • 144. ForensicLog ForensicLog /var/log/httpd/forensic.log • Post-process with the check-forensic script to tell you which URLs never exited
  • 145. mod_speling CheckSpelling On CheckCaseOnly On
  • 146. Image Theft SetEnvIf Referer ".example.com/" local_referal # Allow browsers that do not send Referer info SetEnvIf Referer "^$" local_referal <Directory /web/images> Order Deny,Allow Deny from all Allow from env=local_referal </Directory>
  • 147. Or ... RewriteEngine on RewriteCond %{HTTP_REFERER} !="" RewriteCond %{HTTP_REFERER} !example.com [NC] RewriteRule .(jpe?g|gif|png)$ - [F,NC]
  • 148. Or ... RewriteEngine on RewriteCond %{HTTP_REFERER} !="" RewriteCond %{HTTP_REFERER} !example.com [NC] # depending upon in which context # you use the RewriteRule, # you might need a condition to # exclude the go_away.png to prevent # an internal redirect looping. We don't use a RegEx here: RewriteCond %{REQUEST_URI} !=/images/go_away.png RewriteRule .(jpe?g|gif|png)$ /images/go_away.png [NC,L]
  • 149. Or ... RewriteEngine on RewriteCond %{HTTP_REFERER} !="" RewriteCond %{HTTP_REFERER} !example.com [NC] # depending upon in which context # you use the RewriteRule, # you might need a condition to # exclude the go_away.png to prevent # an internal redirect looping. We don't use a RegEx here: RewriteCond %{REQUEST_URI} !=/images/go_away.png RewriteRule .(jpe?g|gif|png)$ http://other.example.com/images/go_away.png [R,NC,L]
  • 150. Query Strings and Path Info
  • 151. Query Strings monkeys.php?q=lemur&color=green&level=99.7&doc=info.txt • Query Strings are: • Ugly • Hard to type • Hard to remember • Potentially insecure
  • 152. Query Strings monkeys.php?q=lemur&color=green&level=99.7&doc=info.txt • Query Strings are: • Ugly • Hard to type • Hard to remember • Potentially insecure
  • 154. mod_rewrite monkeys.php?q=lemur&color=green&level=99.7&doc=info.txt /monkeys/lemur/green/99.7/info RewriteRule ^/monkeys/(.+)/(.+)/(.+)/(.+) /monkeys.php?q=$1&color=$2&level=$3&doc=$4.txt [PT,L,NE]
  • 155. Engineering for failure • Why not do it right to begin with, and avoid the mess? • PHP makes this fairly easy
  • 156. Step One: SetHandler /monkeys/lemur/green/99.7/info • We want monkeys to be a PHP script • We rename monkeys.php to monkeys, and then ... <Files monkeys> SetHandler application/x-httpd-php </Files> This goes in your server config, or in .htaccess
  • 157. Step Two: explode() /monkeys/lemur/green/99.7/info • The rest of the solution is in your PHP: $args = explode( $_SERVER[‘PATH_INFO’] ); $type = $args[0]; $color = $args[1]; ...
  • 158. While we’re at it • File extensions are *so* 1980s • All your files are php files, right? • Why give them a .php extension? RewriteCond %{REQUEST_URI} !. RewriteRule ^ - [H=application/x-httpd-php,PT]
  • 159. Write a better FM • I’ll never get this far in the presentation, right?

Editor's Notes

  1. Old Hat