0
Apache WizardrySpells for conjuring 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 tomorr...
URLs you need    • http://slideshare.net/rbowen    • http://wiki.apache.org/httpd    • http://httpd.apache.org/docs/trunk/
Recipes Photo CC by Chemical Heritage Foundation - Flickr
CVE-2011-3192 (KillApache)    • Exploits bug in handling of range requests    • Range: requests a byte-range of a       do...
Whats the problem?    • No limit to the number or size of ranges    • Ranges can overlap    • Apache builds the entire res...
Solutions: Best (2.2)  # Drop the Range header when more than 5 ranges.  # CVE-2011-3192  SetEnvIf Range (,.*?){5,} bad-ra...
Solution 2  # Reject request when more than 5 ranges in the  # Range: header -- CVE-2011-3192  RewriteEngine on  RewriteCo...
Other solutions     • Disallow Range requests entirely         RequestHeader unset Range     • Limit the size of the Range...
Directory listings are boring
Say it with styleIndexStyleSheet /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       add...
Now, with extra class  <table id="indexlist">   <tr class="indexhead"><th class="indexcolicon">...<th class="indexcolname"...
An exercise for the reader:                              • Nifty mouse-over effects                                (JS in ...
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  ...
Proxying    • More useful example    • Proxying to back-end server that returns      fully-qualified URLsLoadModule substi...
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:]]+...
Make sure you ...     # Inspect POST payloads     SecFilterScanPOST On     # Default action set     SecFilterDefaultAction...
While you’re at it     # Inspect POST payloads     SecFilterScanPOST On     SecFilter “vidocin”25
Acceptable arguments# Only for the FormMail script<Location /cgi-bin/FormMail>   # Reject request where the value of param...
Which PHP script is slagging my server?     •   Which process, and what is         it doing?     •   Look at /server-statu...
Step 1: Look at top:     •  Run ‘top’     • Order by CPU usage     • Pick off the httpd processes        that are causing ...
Step 2: /server-status     •   Look at /server-status         output     •   Look for the PIDs you         noted     •   M...
/server-status
ExtendedStatus On    • You’ll need “ExtendedStatus On”      to get these details:            <Location /server-status>    ...
SNI      • General knowledge: SSL       requires one certificate per IP       address      • That is, only one SSL site ca...
SSL handshake
SSL handshake                Certificate                Hostname
Clearly this sucks
SNI
SNI      • Server Name Indication      • Passes server name in initial          handshake      •   Simple solutions are al...
Caveats    • You knew there would be a catch   Mozilla Firefox 2.0 or later   Opera 8.0 or later (the TLS 1.1 protocol mus...
Apache       • 2.2.12 or laterListen 443# Listen for virtual host requests on all IP addressesNameVirtualHost *:443# Go ah...
More Infohttp://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
Secure mod_dav deployment    • Security rule #1: Content is not      writable    • Corollary: Anyone telling you to      ‘...
However ...     •Setting up WebDAV       requires that content be       writable ...     •And owned by Apache     •This is...
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 co...
Secure DAV     • It’s possible to set up Dav without       having the files written by the       Apache user     • Sort of45
Two Apache Processes      Primary                     Secondary       server,                      server,     running as ...
Two Apache Processes                             Read-only                   Running ordinary set of modules              ...
Two Apache Processes          Read/Write     Remove all extra modules               SSL                   Secondary       ...
Multi-server config.           drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www1Listen *:80User wwwGroup wwwDocumentRoot /var/...
drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www1Listen *:80                    Can writeUser wwwGroup wwwDocumentRoot /var/ww...
drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www1             Can’tListen *:80User wwwGroup wwwDocumentRoot /var/www/         ...
<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 h...
<If>       <If ‘$req{Host} = “www.example.com”’>         RedirectMatch (.*) http://example.com/$1       </If>         $req...
Logging in 2.4  FYI:   • 2.4 is currently in beta   • Will release any day now   • 2.0 will be declared "end of life"   • ...
Per-module LogLevel  • mod_proxy is very chatty  • I really want to know what     mod_substitute is doing  • Each log line...
[Mon Aug 29 08:05:02.001881 2011] [core:warn] [pid 14974:tid140735307352416] pid file /usr/local/apache2/logs/httpd.pid ove...
LogLevel settings     • emerg     • alert     • crit     • error     • warn     • notice     • info     • debug
New ones:
LogLevels    • Original LogLevel settings taken from      syslog    • New ones more simply named tracen    • Noisier than ...
No more RewriteLog        LogLevel alert rewrite:trace3    • Trace slows things down - use only for      debugging    • ta...
Configurable    • Error log format is configurable, like the       access log               ErrorLogFormat   "[%t] [%l] [p...
[Sun Sep 04 18:30:47.846743 2011] [rewrite:trace1] [pid15332:tid 4334051328] mod_rewrite.c(468): [client ::1:61990] ::1 - ...
Whodunnit? (%L)                  • Correlate access log entries                    with error log entries                 ...
FallbackResource# BEGIN WordPress  RewriteEngine On  RewriteRule ^index.php$ - [L]  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_...
FallbackResource# BEGIN WordPress#  RewriteEngine On# RewriteRule ^index.php$ - [L]# RewriteCond %{DOCUMENT_ROOT}%{REQUEST...
Logging - Conditional Logging     • Don’t log certain things     • Per-directory logging68
Conditional LogFormat     • The LogFormat directive      supports some conditionals in      the variables     • "%!200,304...
Conditional LogFormat     • "%400,501{User-agent}i" logs      User-agent on 400 errors and      501 errors only     • For ...
Conditional CustomLog     • Stick Env=xyz on the end     • or Env=!xyz     • Yes, that’s =! not !=71
For example ...SetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-request...
For example ...SetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-request...
For example ...SetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-request...
So the images get logged hereSetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog ...
And everything else goes hereSetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog ...
Per directorySetEnvIf Request_URI ^/marketing mktCustomLog marketing.log common env=mkt 77
PCRE Zero-width assertions   • Match everything except one thing   • While you can do this with     RewriteRule, it would ...
Negative Lookahead    • PCRE provides a regex        syntax to say “not preceded        by” or “not followed by”    •   Ne...
Andrei Rocks    • While we’re on the topic:    • Pretty much the best      presentation on regular      expressions anywhe...
Everything except ...     •   “I want to redirect everything except /         images”     •   This is where you’d use a ne...
Everything except ...     • Match anything ...     •           RedirectMatch ^/(?!images/)(.*)              http://other.m...
Everything except ...     • Match anything ...     • That doesn’t start with images/           RedirectMatch ^/(?!images/)...
Everything except ...      This is called a “zero width” assertion,      because it doesn’t fill $1, and doesn’t      cons...
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 .htacc...
What the heck is it doing?           RewriteLog /var/log/rewrite.log           RewriteLogLevel 9     • Most entries betwee...
What the heck is it doing?           RewriteLog /var/log/rewrite.log           RewriteLogLevel 9     • If there’s nothing ...
Logging - RewriteLog     RewriteLog /var/log/rewrite.log     RewriteLogLevel 990
Logging - RewriteLog     RewriteLog /var/log/rewrite.log     RewriteLogLevel 991
Logging - RewriteLog     RewriteLog /var/log/rewrite.log     RewriteLogLevel 992
93
Kind of intimidating, isn’t it?94
Learn to ignore the irrelevant bits95
Which bits are those?        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]     [wooga.drbacchus.com/sid#b83444a8][rid#b8...
Client address        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/...
Dunno what those are        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]     [wooga.drbacchus.com/sid#b83444a8][rid#b85...
Time        121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]     [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/        in...
Unique id         121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]      [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/   ...
Request ID         121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]      [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d00/  ...
The useful bit         121.14.76.185 - - [24/Sep/2008:21:35:51 --0400]      [wooga.drbacchus.com/sid#b83444a8][rid#b85b8d0...
Wouldn’t it be nice if you could just see the      useful part?103
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...
RewriteLog |/usr/local/bin/rewrite_log_pipe      RewriteLogLevel 9           with ...      #!/usr/bin/perl      $|++;     ...
RewriteLog |/usr/local/bin/rewrite_log_pipe RewriteLogLevel 9       This bit says “instead of logging to a text        file...
#!/usr/bin/perl $|++; open (F, ">>/tmp/rewrite"); select F; while (<>) {   s/^.*((d).*)/$1/;   print; }      • Look for th...
Results in: (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched (3) applying pat...
Results in: (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched (3) applying pat...
Requested URI (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched (3) applying p...
Patterns applied (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched (3) applyin...
None of them matched (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched (3) app...
And now      • We can actually make some       sense of what’s happening      • Less inscrutable noise      • Yes, it mean...
Examples (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched        • This was t...
Examples (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched        • It shows w...
Examples (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched         • And what ...
Examples (4) RewriteCond: input=wooga.drbacchus.com pattern=!^wooga.drbacchus .com [NC] => not-matched        •   As well ...
Another example      (3) applying pattern ^/book/(mod)?_?rewrite to uri /                             index.php         • ...
Again ...      (3) applying pattern ^/book/(mod)?_?rewrite to uri /                             index.php         • What w...
And ...      (3) applying pattern ^/book/(mod)?_?rewrite to uri /                             index.php         • What it ...
Matched?      (3) applying pattern ^/book/(mod)?_?rewrite to uri /                             index.php          • If it ...
The whole thing(3) applying pattern ^/books?/(mod)?_?rewrite to uri /books/rewrite(2) rewrite /books/rewrite -> http://www...
The match:(3) applying pattern ^/books?/(mod)?_?rewrite to uri /books/rewrite(2) rewrite /books/rewrite -> http://www.amaz...
Followed by(3) applying pattern ^/books?/(mod)?_?rewrite to uri /books/rewrite(2) rewrite /books/rewrite -> http://www.ama...
[R](3) applying pattern ^/books?/(mod)?_?rewrite to uri /books/rewrite(2) rewrite /books/rewrite -> http://www.amazon.com/...
But it all runs together!       • Look for:       •      (2) init rewrite engine with requested uri /atom/1       • ‘init ...
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         Balanc...
Fairly simple to configure       <Proxy balancer://mycluster>         BalancerMember http://192.168.1.50:80         Balanc...
Fairly simple to configure       <Proxy balancer://mycluster>         BalancerMember http://192.168.1.50:80         Balanc...
Sticky Sessions      Ensures that connections go to the same server they                         started with.ProxyPass / ...
Balancing measures  ProxyPass / balancer://hotcluster/  <Proxy balancer://hotcluster>   BalancerMember http://1.2.3.4:8009...
1.2.3.5 gets twice the traffic  ProxyPass / balancer://hotcluster/  <Proxy balancer://hotcluster>   BalancerMember http://...
Hot spare  ProxyPass / balancer://hotcluster/  <Proxy balancer://hotcluster>   BalancerMember http://1.2.3.4:8009 loadfact...
bytraffic or byrequests  ProxyPass / balancer://hotcluster/  <Proxy balancer://hotcluster>   BalancerMember http://1.2.3.4...
BalancerManager      <Location /balancer-manager>       SetHandler balancer-manager       Order Deny,Allow       Deny from...
141
Disable a      particular host142
Notes      • The things on the other end don’t have to         be Apache      • This is a popular way to set up Ruby on   ...
server-info              <Location /server-info>                SetHandler server-info              </Location>
Demo   • Insert /server-info demo here
Require    • Order deny,allow    • Order allow,deny    • huh?
Require
Require
RequireAll       <RequireAll>         Require ip 10.1         Require Group marketing       </RequireAll>
RequireAny      <RequireAny>        Require ip 10.1        Require Group marketing      </RequireAny>
RequireNone      <RequireNone>        Require ip 10.1        Require Group marketing      </RequireNone>
Combined  <Directory /www/mydocs>    <RequireAll>      <RequireAny>         Require user superadmin         <RequireAll>  ...
Expressions    • New expression parser in 2.4    • Available in most directives that do any       kind of comparison or ma...
Other ...     • http://localhost/manual/expr.html
Bandwidth limiting                       Picture by Joachim S. Müller (Flickr)        People always want their websites to...
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 a...
mod_ratelimit     <Location /downloads>       SetHandler RATE_LIMIT       SetEnv rate-limit 400     </Location>  Speed is ...
Prior to 2.4      A variety of other modules do bandwidth      kind of things:                   mod_cband                ...
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 size170
Logging - mod_logio      Complete INPUT and      OUTPUT size171
Combined Log Format - Bytes transferred172
Less than half the story       • Only bytes transferred to the          client       • Doesn’t include headers       • Doe...
mod_logio      •Adds two additional       variables      •%I - Input bytes      •%O - Output bytes      •Includes headers,...
LogFormat175
mod_log_forensic    •   Did it ever finish?
ForensicLog   ForensicLog /var/log/httpd/forensic.log+TlvWvsCoyKYAAAPmBy8AAABG|GET /manual/images/feather.gif HTTP/1.1|Hos...
ForensicLog ForensicLog /var/log/httpd/forensic.log    •   Post-process with the check-        forensic script to tell you...
mod_whatkilledus    • Third-party module    • people.apache.org/~trawick/      Find it at http://    • Tells you what kill...
mod_whatkilledus[Fri Mar 11 14:25:18 2005] pid 16934 mod_whatkilledussig 11 crash[Fri Mar 11 14:25:18 2005] pid 16934 mod_...
mod_speling               CheckSpelling On              CheckCaseOnly On
Image Theft    • <img src="http://your.site.com/       cool_picture.jpg">
Image Theft  SetEnvIf Referer           ".example.com/" local_referal  # Allow browsers that do not send Referer info  Set...
Or ...RewriteEngine onRewriteCond %{HTTP_REFERER} !=""RewriteCond %{HTTP_REFERER} !example.com [NC]RewriteRule .(jpe?g|gif...
Or ...RewriteEngine onRewriteCond %{HTTP_REFERER} !=""RewriteCond %{HTTP_REFERER} !example.com [NC]# depending upon in whi...
Or ...RewriteEngine onRewriteCond %{HTTP_REFERER} !=""RewriteCond %{HTTP_REFERER} !example.com [NC]# depending upon in whi...
Or ...            In 2.4:<Location /images>  <If "$req{Referer} !~ /mysite.com/">    Require all denied  </If></Location>
Query Strings and Path Info
Query Stringsmonkeys.php?q=lemur&color=green&level=99.7&doc=info.txt     • Query Strings are:      • Ugly      • Hard to t...
Query Stringsmonkeys.php?q=lemur&color=green&level=99.7&doc=info.txt     • Query Strings are:      • Ugly      • Hard to t...
Path Infomonkeys.php?q=lemur&color=green&level=99.7&doc=info.txt             /monkeys/lemur/green/99.7/info
mod_rewritemonkeys.php?q=lemur&color=green&level=99.7&doc=info.txt             /monkeys/lemur/green/99.7/info     RewriteR...
Engineering for failure     • Why not do it right to begin       with, and avoid the mess?     • PHP makes this fairly eas...
Step One: SetHandler              /monkeys/lemur/green/99.7/info    • We want monkeys to be a PHP script    • We rename mo...
Step Two: explode()             /monkeys/lemur/green/99.7/info    • The rest of the solution is in your       PHP:   $args...
While we’re at it     • File extensions are *so* 1980s     • All your files are php files, right?     • Why give them a .p...
...      • If, by some miracle, we get this far ...      • Questions?
Addresses you need    • http://slideshare.net/rbowen    • http://wiki.apache.org/httpd    • http://httpd.apache.org/docs/t...
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Apache Wizardry - Ohio Linux 2011
Upcoming SlideShare
Loading in...5
×

Apache Wizardry - Ohio Linux 2011

4,111

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
4,111
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
25
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • Old Hat\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript of "Apache Wizardry - Ohio Linux 2011"

    1. 1. Apache WizardrySpells for conjuring your Apache HTTP Server / Rich Bowen - rbowen@apache.org
    2. 2. Shameless Plug Buy! Buy! Buy!
    3. 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. 4. URLs you need • http://slideshare.net/rbowen • http://wiki.apache.org/httpd • http://httpd.apache.org/docs/trunk/
    5. 5. Recipes Photo CC by Chemical Heritage Foundation - Flickr
    6. 6. CVE-2011-3192 (KillApache) • Exploits bug in handling of range requests • Range: requests a byte-range of a document • Range: 0-4,10-19,16-22,3-18 • Eg, single pages of a PDF document • Fixed in 2.2.20 and in trunk
    7. 7. Whats the problem? • No limit to the number or size of ranges • Ranges can overlap • Apache builds the entire response in memory before sending • Very easy to construct a range set that consumes all available RAM
    8. 8. Solutions: Best (2.2) # Drop the Range header when more than 5 ranges. # CVE-2011-3192 SetEnvIf Range (,.*?){5,} bad-range=1 RequestHeader unset Range env=bad-range # optional logging. CustomLog logs/range-CVE-2011-3192.log common env=bad-range
    9. 9. Solution 2 # Reject request when more than 5 ranges in the # Range: header -- CVE-2011-3192 RewriteEngine on RewriteCond %{HTTP:range} !(^bytes=[^,]+(,[^,]+){0,4}$|^$) RewriteRule .* - [F] • Use this for 1.3 and 2.0, because they dont have the PCRE sauce in SetEnvIf • Better yet, dont use 1.3 and 2.0
    10. 10. Other solutions • Disallow Range requests entirely RequestHeader unset Range • Limit the size of the Range header LimitRequestFieldSize 200
    11. 11. Directory listings are boring
    12. 12. Say it with styleIndexStyleSheet /styles/dir.css....odd { background-color: #eef;}.even { background-color: #fff;}
    13. 13. 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
    14. 14. 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">...
    15. 15. 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?
    16. 16. mod_substitite • New module in 2.2 • Rewrite content using regular expressions • Syntax is identical to sed
    17. 17. s/foo/bar/ • Simple example - switch fonts LoadModule substitute_module libexec/apache2/mod_substitute.so AddOutputFilterByType SUBSTITUTE text/html Substitute s/ariel/courier/i
    18. 18. Proxying • More useful example • Proxying to back-end server that returns fully-qualified URLsLoadModule substitute_module libexec/apache2/mod_substitute.soAddOutputFilterByType SUBSTITUTE text/htmlSubstitute s/backend.local/www.example.com/ni
    19. 19. mod_security • Are you running mod_security?
    20. 20. mod_security • You should be
    21. 21. http firewall • The earlier you catch it ...
    22. 22. Holes Photo CC by Darwin Bell
    23. 23. SQL Injection # Prevent SQL injection attacks SecFilter "delete[[:space:]]+from" SecFilter "insert[[:space:]]+into" SecFilter "select.+from"23
    24. 24. Make sure you ... # Inspect POST payloads SecFilterScanPOST On # Default action set SecFilterDefaultAction "deny,log,status:406"24
    25. 25. While you’re at it # Inspect POST payloads SecFilterScanPOST On SecFilter “vidocin”25
    26. 26. 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> 26
    27. 27. Which PHP script is slagging my server? • Which process, and what is it doing? • Look at /server-status for a process list
    28. 28. 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
    29. 29. Step 2: /server-status • Look at /server-status output • Look for the PIDs you noted • Move fast - the process may be gone already
    30. 30. /server-status
    31. 31. ExtendedStatus On • You’ll need “ExtendedStatus On” to get these details: <Location /server-status> SetHandler server-status </Location> ExtendedStatus On
    32. 32. 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
    33. 33. SSL handshake
    34. 34. SSL handshake Certificate Hostname
    35. 35. Clearly this sucks
    36. 36. SNI
    37. 37. SNI • Server Name Indication • Passes server name in initial handshake • Simple solutions are always best
    38. 38. 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
    39. 39. Apache • 2.2.12 or laterListen 443# Listen for virtual host requests on all IP addressesNameVirtualHost *:443# Go ahead and accept connections for these vhosts# from non-SNI clientsSSLStrictSNIVHostCheck off<VirtualHost *:443> DocumentRoot /www/example1 ServerName www.example.com</VirtualHost><VirtualHost *:443> DocumentRoot /www/example2 ServerName www.example2.org</VirtualHost>
    40. 40. More Infohttp://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI
    41. 41. 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
    42. 42. However ... •Setting up WebDAV requires that content be writable ... •And owned by Apache •This is annoying
    43. 43. WebDAV <Directory /var/www/content> Dav On </Directory>
    44. 44. 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
    45. 45. Secure DAV • It’s possible to set up Dav without having the files written by the Apache user • Sort of45
    46. 46. Two Apache Processes Primary Secondary server, server, running as running as user www user dav File System, owned by dav46
    47. 47. Two Apache Processes Read-only Running ordinary set of modules Running web apps, etc Primary server, running as user www File System, owned by dav47
    48. 48. Two Apache Processes Read/Write Remove all extra modules SSL Secondary server, Authenticated running as user dav File System, owned by dav48
    49. 49. Multi-server config. drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www1Listen *:80User wwwGroup wwwDocumentRoot /var/www/ Listen *:8080 2 DavLockDb /var/lock/dav User dav Group dav DocumentRoot /var/www/49
    50. 50. drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www1Listen *:80 Can writeUser wwwGroup wwwDocumentRoot /var/www/ Listen *:8080 2 DavLockDb /var/lock/dav User dav Group dav DocumentRoot /var/www/50
    51. 51. drwxr-xr-x 2 dav dav 68 Oct 3 12:41 /var/www1 Can’tListen *:80User wwwGroup wwwDocumentRoot /var/www/ Listen *:8080 2 DavLockDb /var/lock/dav User dav Group dav DocumentRoot /var/www/51
    52. 52. <If> Picture by BrewBooks (Flickr) My favorite new feature in 2.4
    53. 53. <If> <If ‘$req{Host} = “www.example.com”’> RedirectMatch (.*) http://example.com/$1 </If>
    54. 54. <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.
    55. 55. <If> <If ‘$req{Host} = “www.example.com”’> RedirectMatch (.*) http://example.com/$1 </If> $req $resp $env
    56. 56. Logging in 2.4 FYI: • 2.4 is currently in beta • Will release any day now • 2.0 will be declared "end of life" • 2.2 will be declared "maintenance only"
    57. 57. Per-module LogLevel • mod_proxy is very chatty • I really want to know what mod_substitute is doing • Each log line prefixed by the name of the module LogLevel warning substitute:debug
    58. 58. [Mon Aug 29 08:05:02.001881 2011] [core:warn] [pid 14974:tid140735307352416] pid file /usr/local/apache2/logs/httpd.pid overwritten --Unclean shutdown of previous Apache run?[Mon Aug 29 08:05:02.009024 2011] [mpm_event:notice] [pid 14974:tid140735307352416] Apache/2.3.12-dev (Unix) PHP/5.3.6 DAV/2 configured-- resuming normal operations[Mon Aug 29 08:05:02.009411 2011] [core:notice] [pid 14974:tid140735307352416] Command line: /usr/local/apache2/bin/httpd[Mon Aug 29 08:05:16.479215 2011] [negotiation:error] [pid 14977:tid4322246656] (2)No such file or directory: [client ::1:54690] cannot accesstype map file: /Users/rbowen/devel/apache/httpd-trunk/docs/manual/logging.html
    59. 59. LogLevel settings • emerg • alert • crit • error • warn • notice • info • debug
    60. 60. New ones:
    61. 61. LogLevels • Original LogLevel settings taken from syslog • New ones more simply named tracen • Noisier than debug • Not to be confused with TRACEEnable, which is something completely different
    62. 62. No more RewriteLog LogLevel alert rewrite:trace3 • Trace slows things down - use only for debugging • tail -f error_log | grep "rewrite:"
    63. 63. Configurable • Error log format is configurable, like the access log ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [client %a] %M"
    64. 64. [Sun Sep 04 18:30:47.846743 2011] [rewrite:trace1] [pid15332:tid 4334051328] mod_rewrite.c(468): [client ::1:61990] ::1 - - [localhost/sid#10080f190][rid#10286b2a0/initial] pass through /favicon.ico[Sun Sep 04 18:30:47.850033 2011] [core:error] [pid15332:tid 4334051328] [client ::1:61990] File does not exist: /usr/local/apache2/htdocs/favicon.ico
    65. 65. Whodunnit? (%L) • Correlate access log entries with error log entries • Which request caused this error? • Add %L to the LogFormat and to the ErrorLogFormat
    66. 66. FallbackResource# BEGIN WordPress  RewriteEngine On  RewriteRule ^index.php$ - [L]  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d  RewriteRule . /index.php [L]# END WordPress
    67. 67. FallbackResource# BEGIN WordPress#  RewriteEngine On# RewriteRule ^index.php$ - [L]# RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f#  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d#  RewriteRule . /index.php [L]# END WordPressFallbackResource /index.php# available in 2.2.8
    68. 68. Logging - Conditional Logging • Don’t log certain things • Per-directory logging68
    69. 69. 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 codes69
    70. 70. 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 logged70
    71. 71. Conditional CustomLog • Stick Env=xyz on the end • or Env=!xyz • Yes, that’s =! not !=71
    72. 72. For example ...SetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-requests.log common env=!gif-image 72
    73. 73. For example ...SetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-requests.log common env=!gif-image 73
    74. 74. For example ...SetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-requests.log common env=!gif-image 74
    75. 75. So the images get logged hereSetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-requests.log common env=!gif-image 75
    76. 76. And everything else goes hereSetEnvIf Request_URI .gif$ gif-imageCustomLog gif-requests.log common env=gif-imageCustomLog nongif-requests.log common env=!gif-image 76
    77. 77. Per directorySetEnvIf Request_URI ^/marketing mktCustomLog marketing.log common env=mkt 77
    78. 78. 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
    79. 79. Negative Lookahead • PCRE provides a regex syntax to say “not preceded by” or “not followed by” • Negative lookbehind and negative lookahead, respectively
    80. 80. 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
    81. 81. 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
    82. 82. Everything except ... • Match anything ... • RedirectMatch ^/(?!images/)(.*) http://other.myhost.com/$1
    83. 83. Everything except ... • Match anything ... • That doesn’t start with images/ RedirectMatch ^/(?!images/)(.*) http://other.myhost.com/$1
    84. 84. 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
    85. 85. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9
    86. 86. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9 • Alas, not in .htaccess • Logs are always opened at startup
    87. 87. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9 • Most entries between 1-4
    88. 88. What the heck is it doing? RewriteLog /var/log/rewrite.log RewriteLogLevel 9 • If there’s nothing in there, your rules are being ignored.
    89. 89. Logging - RewriteLog RewriteLog /var/log/rewrite.log RewriteLogLevel 990
    90. 90. Logging - RewriteLog RewriteLog /var/log/rewrite.log RewriteLogLevel 991
    91. 91. Logging - RewriteLog RewriteLog /var/log/rewrite.log RewriteLogLevel 992
    92. 92. 93
    93. 93. Kind of intimidating, isn’t it?94
    94. 94. Learn to ignore the irrelevant bits95
    95. 95. 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- matched96
    96. 96. 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- matched97
    97. 97. 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- matched98
    98. 98. 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- matched99
    99. 99. 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- matched100
    100. 100. 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- matched101
    101. 101. 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- matched102
    102. 102. Wouldn’t it be nice if you could just see the useful part?103
    103. 103. You could change the way mod_rewrite logs:
    104. 104. Piped logs • I actually use a piped lot handler to remove this superfluous stuff • Like so ...RewriteLog |/usr/local/bin/rewrite_log_pipeRewriteLogLevel 9105
    105. 105. RewriteLog |/usr/local/bin/rewrite_log_pipe RewriteLogLevel 9 with ... #!/usr/bin/perl $|++; open (F, ">>/tmp/rewrite"); select F; while (<>) { s/^.*((d).*)/$1/; print; }106
    106. 106. 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.”107
    107. 107. #!/usr/bin/perl $|++; open (F, ">>/tmp/rewrite"); select F; while (<>) { s/^.*((d).*)/$1/; print; } • Look for the (1) or (2) bit • drop everything before that108
    108. 108. 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.php109
    109. 109. 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.php110
    110. 110. 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.php111
    111. 111. 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.php112
    112. 112. 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.php113
    113. 113. And now • We can actually make some sense of what’s happening • Less inscrutable noise • Yes, it means something, but not to normal people114
    114. 114. 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]115
    115. 115. 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]116
    116. 116. 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]117
    117. 117. 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]118
    118. 118. 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]119
    119. 119. 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]120
    120. 120. 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]121
    121. 121. 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]122
    122. 122. 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]123
    123. 123. 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]124
    124. 124. 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]125
    125. 125. [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]126
    126. 126. 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 rewritten127
    127. 127. Load balancing
    128. 128. Fortunately ... Photo CC by Camo53 (flickr) • mod_proxy_balancer • Added in 2.1
    129. 129. 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
    130. 130. 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
    131. 131. 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
    132. 132. Sticky Sessions Ensures that connections go to the same server they started with.ProxyPass / balancer://mycluster/ stickysession=PHPSESSIONID135
    133. 133. 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>136
    134. 134. 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>137
    135. 135. 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>138
    136. 136. 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>139
    137. 137. BalancerManager <Location /balancer-manager> SetHandler balancer-manager Order Deny,Allow Deny from all Allow from .example.com </Location>140
    138. 138. 141
    139. 139. Disable a particular host142
    140. 140. 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 Mongrel143
    141. 141. server-info <Location /server-info> SetHandler server-info </Location>
    142. 142. Demo • Insert /server-info demo here
    143. 143. Require • Order deny,allow • Order allow,deny • huh?
    144. 144. Require
    145. 145. Require
    146. 146. RequireAll <RequireAll> Require ip 10.1 Require Group marketing </RequireAll>
    147. 147. RequireAny <RequireAny> Require ip 10.1 Require Group marketing </RequireAny>
    148. 148. RequireNone <RequireNone> Require ip 10.1 Require Group marketing </RequireNone>
    149. 149. Combined <Directory /www/mydocs> <RequireAll> <RequireAny> Require user superadmin <RequireAll> Require group admins Require ldap-group cn=Administrators,o=Airius <RequireAny> Require group sales Require ldap-attribute dept="sales" </RequireAny> </RequireAll> </RequireAny> <RequireNone> Require group temps Require ldap-group cn=Temporary Employees,o=Airius </RequireNone> </RequireAll> </Directory>
    150. 150. Expressions • New expression parser in 2.4 • Available in most directives that do any kind of comparison or matching • Will be available more places as time goes on
    151. 151. Other ... • http://localhost/manual/expr.html
    152. 152. Bandwidth limiting Picture by Joachim S. Müller (Flickr) People always want their websites to run slower. Seems odd to me ...
    153. 153. In 2.4 ... • 2.4 adds two new modules for this purpose • mod_dialup • mod_ratelimit
    154. 154. mod_dialup Party like it’s 1999
    155. 155. v.92? Really? <Location /mysite> ModemStandard V.92 </Location> Also available: V.21 V.26bis V.32 V.92
    156. 156. mod_ratelimit <Location /downloads> SetHandler RATE_LIMIT SetEnv rate-limit 400 </Location> Speed is in kb/s
    157. 157. Prior to 2.4 A variety of other modules do bandwidth kind of things: mod_cband mod_bwshare mod_bw mod_evasive mod_limitipconn
    158. 158. Logging • mod_logio • mod_log_forensic
    159. 159. Obligatory ridiculous log photo Photo by Zevotron (Flickr)
    160. 160. Not enough • Your log files don’t tell you enough • Want more
    161. 161. Logging - mod_logio Complete INPUT and OUTPUT size170
    162. 162. Logging - mod_logio Complete INPUT and OUTPUT size171
    163. 163. Combined Log Format - Bytes transferred172
    164. 164. 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 server173
    165. 165. mod_logio •Adds two additional variables •%I - Input bytes •%O - Output bytes •Includes headers, both directions174
    166. 166. LogFormat175
    167. 167. mod_log_forensic • Did it ever finish?
    168. 168. ForensicLog ForensicLog /var/log/httpd/forensic.log+TlvWvsCoyKYAAAPmBy8AAABG|GET /manual/images/feather.gif HTTP/1.1|Host:localhost|Connection:keep-alive|Referer:http%3a//localhost/manual/|User-Agent:Mozilla/5.0 (Macintosh; IntelMac OS X 10_7_1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1|Accept:*/*|Accept-Encoding:gzip,deflate,sdch|Accept-Language:en-US,en;q=0.8,de;q=0.6|Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3+TlvWvsCoyKYAAAPmBzAAAABB|GET /manual/style/css/manual.css HTTP/1.1|Host:localhost|Connection:keep-alive|Referer:http%3a//localhost/manual/|User-Agent:Mozilla/5.0 (Macintosh; IntelMac OS X 10_7_1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1|Accept:text/css,*/*;q=0.1|Accept-Encoding:gzip,deflate,sdch|Accept-Language:en-US,en;q=0.8,de;q=0.6|Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3+TlvWvsCoyKYAAAPmBzEAAABI|GET /manual/images/left.gif HTTP/1.1|Host:localhost|Connection:keep-alive|Referer:http%3a//localhost/manual/|User-Agent:Mozilla/5.0 (Macintosh; IntelMac OS X 10_7_1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1|Accept:*/*|Accept-Encoding:gzip,deflate,sdch|Accept-Language:en-US,en;q=0.8,de;q=0.6|Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3-TlvWvsCoyKYAAAPmBy8AAABG-TlvWvsCoyKYAAAPmBzAAAABB-TlvWvsCoyKYAAAPmBzEAAABI
    169. 169. ForensicLog ForensicLog /var/log/httpd/forensic.log • Post-process with the check- forensic script to tell you which URLs never exited
    170. 170. mod_whatkilledus • Third-party module • people.apache.org/~trawick/ Find it at http:// • Tells you what killed us
    171. 171. mod_whatkilledus[Fri Mar 11 14:25:18 2005] pid 16934 mod_whatkilledussig 11 crash[Fri Mar 11 14:25:18 2005] pid 16934 mod_whatkilledusactive connection: 127.0.0.1:43923->127.0.0.1:10101(conn_rec 30683a38)[Fri Mar 11 14:25:18 2005] pid 16934 mod_whatkilledusactive request (request_rec 30689978):GET /silly/?fn=sigsegv HTTP/1.0|Connection:close[Fri Mar 11 14:25:18 2005] pid 16934 mod_whatkilledusActive module: mod_silly2.c[Fri Mar 11 14:25:18 2005] pid 16934 mod_whatkilledusend of report
    172. 172. mod_speling CheckSpelling On CheckCaseOnly On
    173. 173. Image Theft • <img src="http://your.site.com/ cool_picture.jpg">
    174. 174. 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>
    175. 175. Or ...RewriteEngine onRewriteCond %{HTTP_REFERER} !=""RewriteCond %{HTTP_REFERER} !example.com [NC]RewriteRule .(jpe?g|gif|png)$ - [F,NC]
    176. 176. Or ...RewriteEngine onRewriteCond %{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 dont use a RegEx here:RewriteCond %{REQUEST_URI} !=/images/go_away.pngRewriteRule .(jpe?g|gif|png)$ /images/go_away.png [NC,L]
    177. 177. Or ...RewriteEngine onRewriteCond %{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 dont use a RegEx here:RewriteCond %{REQUEST_URI} !=/images/go_away.pngRewriteRule .(jpe?g|gif|png)$ http://other.example.com/images/go_away.png [R,NC,L]
    178. 178. Or ... In 2.4:<Location /images> <If "$req{Referer} !~ /mysite.com/"> Require all denied </If></Location>
    179. 179. Query Strings and Path Info
    180. 180. Query Stringsmonkeys.php?q=lemur&color=green&level=99.7&doc=info.txt • Query Strings are: • Ugly • Hard to type • Hard to remember • Potentially insecure
    181. 181. Query Stringsmonkeys.php?q=lemur&color=green&level=99.7&doc=info.txt • Query Strings are: • Ugly • Hard to type • Hard to remember • Potentially insecure
    182. 182. Path Infomonkeys.php?q=lemur&color=green&level=99.7&doc=info.txt /monkeys/lemur/green/99.7/info
    183. 183. mod_rewritemonkeys.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]
    184. 184. Engineering for failure • Why not do it right to begin with, and avoid the mess? • PHP makes this fairly easy • Use exactly the same technique in whatever your preferred language is
    185. 185. 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
    186. 186. 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]; ...
    187. 187. 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]
    188. 188. ... • If, by some miracle, we get this far ... • Questions?
    189. 189. Addresses you need • http://slideshare.net/rbowen • http://wiki.apache.org/httpd • http://httpd.apache.org/docs/trunk/ • rbowen@apache.org • http://omniti.com/is/hiring
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×