Taking Notes from Apache Cookbook

Taking Notes from Apache Cookbook

Building Apache from the Sources

% ./buildconf

% ./configure --prefix=/usr/local/apache --with-layout=Apache --enable-modules=most --enable-mods-shared=all --with-mpm=prefork

make; make install

./configure --help display this help and exit

Useful configure Options

--prefix Specifies the top level of the directory tree into which files will be put.

--enable-layout This allows you to select one of the predefined filesystem structures; default is Apache.


This option controls which modules will be built as DSOs rather than being linked statically into the server. An

excellent shortcut value is most.



Starting, Stopping, and Restarting Apache

/usr/local/apache/bin/httpd -k start|restart|graceful|graceful-stop|stop


-d directory : specify an alternate initial ServerRoot

-f file : specify an alternate ServerConfigFile

-e level : show startup errors of level (see LogLevel)

-E file : log startup errors to file

-v : show version number

-h : list available command line options (this page)

-l : list compiled in modules

-L : list available configuration directives

-t : run syntax check for config files

Uninstalling Apache

On Red Hat Linux, to remove an Apache version installed with the RPM tool, use: rpm -ev apache

Starting Apache at Boot

Vendor Specific Packages:

Redhat and Fedora:

You can set Apache to start at boot using chkconfig: “chkconfig httpd on”.

start Apache with the service command: service httpd start

for build from Source:

# cp /usr/local/apache/bin/apachectl /etc/rc.d/init.d/httpd

# vi /etc/rc.d/init.d/httpd # add '# chkconfig 3 92 10'

# chkconfig --add httpd

# chkconfig --levels 35 httpd on

Finding Apache's Files

If you installed the software from an RPM package, use the -ql option to see where the files have been installed: rpm -ql httpd

Adding Common Modules

The most comprehensive list of third-party modules can be found in the Apache Module Registry at http://modules.apache.org.

Installing a Generic Third-Party Module

Move to the directory where the module's source file was unpacked, and then: /path/to/apache/bin/apxs -cia module.c

The -cia options mean to compile, install, and activate.

Installing mod_perl on a Unixish System

Download and unpack the mod_perl 2.0 source package, then use the following command:

perl Makefile.PL MP_APXS=/usr/local/apach/bin/apxs

Installing mod_php on a Unixish System

cd php-5.2.3; ./configure –with-apxs2=/usr/local/apache/bin/apxs;make; make install

LoadModule php5_module modules/libphp5.so

AddType application/x-httpd-php .php

AddType application/x-httpd-source .phps


common log format (CLF), and an enhanced format—called the combined log format—was created:

"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""

HTTP status codes

Successful 2xx

200 OK 201 Created

202 Accepted 203 Nonauthoritative information

204 No content 205 Reset content

206 Partial content

Redirection 3xx

300 Multiple choices 301 Moved permanently

302 Found 303 See other

304 Not modified 305 Use proxy

306 (Unused) 307 Temporary redirect

Client error 4xx

400 Bad request 401 Unauthorized

402 Payment required 403 Forbidden

404 Not found 405 Method not allowed

406 Not acceptable 407 Proxy authentication required

408 Request timeout 409 Conflict

410 Gone 411 Length required

412 Precondition failed 413 Request entity too large

414 Request -URI too long 415 Unsupported media type

416 Requested range not satisfiable

417 Expectation failed

Server error 5xx

500 Internal server error 501 Not implemented

502 Bad gateway 503 Service unavailable

504 Gateway timeout 505 HTTP version not supported

Getting More Details in Your Log Entries

CustomLog logs/access_log combined

The combined log format offers two additional pieces of information not included in the common log format: the Referer and the User-agent.

Getting More Detailed Errors: LogLevel Debug

the possible values are: emerg, alert, crit, error, warn, notice, info, debug.

Logging Cookies

To log cookies received from the client:

CustomLog logs/cookies_in.log "%{UNIQUE_ID}e %{Cookie}i"

CustomLog logs/cookies2_in.log "%{UNIQUE_ID}e %{Cookie2}i"

To log cookie values set and sent by the server to the client:

CustomLog logs/cookies_out.log "%{UNIQUE_ID}e %{Set-Cookie}o"

CustomLog logs/cookies2_out.log "%{UNIQUE_ID}e %{Set-Cookie2}o"

Not Logging Image Requests from Local Pages

<FilesMatch \.(jpg|gif|png)$>SetEnvIfNoCase Referer "^http://www.example.com/" local_referrer=1</FilesMatch>

CustomLog logs/access_log combined env=!local_referrer

SetEnvIfNoCase is the same as SetEnvIf except that variable comparisons are done in a case-insensitive manner.

Rotating Logfiles at a Particular Time

CustomLog "| /usr/local/apache/bin/rotatelogs /usr/local/apache/logs/access_log.%Y -%m-%d 86400" combined

The second argument is the interval (in seconds) between rollovers.

Rotating Logs on the First of the Month

Obtain and install Cronolog, and then place the following in your configuration file:

CustomLog "|/usr/bin/cronolog /www/logs/access%Y%m.log" combined

Logging Hostnames Instead of IP Addresses

You can let the Web server resolve the hostname when it processes the request by enabling runtime lookups with the Apache directive:

HostnameLookups On

Or you can let Apache use the IP address during normal processing and let a piped logging process resolve them as part of recording the entry:

HostnameLookups Off

CustomLog "| /usr/local/apache/bin/logresolve -c >> /path/to/logs /access_log.resolved" combined

Or you can let Apache use and log the IP addresses, and resolve them later when analyzing the logfile. Add this to http.conf:

CustomLog /path/to/logs /access_log.raw combined

And analyze the log with:

% /usr/local/apache/bin/logresolve -c < access_log.raw > access_log.resolved

Logging Proxy Requests

You want to log requests that go through your proxy to a different file than the requests coming directly to your server.

<Proxy *>SetEnv is_proxied 1</Proxy>

CustomLog logs/proxy_log combined env=is_proxied

If you want to apply different directives to different proxied paths:

<Directory proxy:*>RewriteEngine On

RewriteRule "\.(gif|png|jpg)$" "-" [ENV=proxied_image:1]

RewriteCond "%{ENV:proxied_image}" "!1"

RewriteRule "^" "-" [ENV=proxied_other:1] </Directory>

CustomLog logs/proxy_image_log combined env=proxied_image

CustomLog logs/proxy_other_log combined env=proxied_other

Directives in the <Directory proxy:*> container will only apply to requests going through your server

Logging Errors for Virtual Hosts to Multiple Files

Unlike activity logs, Apache will log error messages only to a single location. If the error is related to a particular virtual host and this host's <VirtualHost> container includes an ErrorLog entry, the error will be logged only in this file, and it won't appear in any global error log. If the <VirtualHost> does not specify an ErrorLog directive, the error will be logged only to the global error log.

Solution: Use piped logging to duplicate log entries:

ErrorLog "| tee logfile1 | tee logfile2 > logfile3"

Logging Server IP Addresses

You want to log the IP address of the server that responds to a request, possibly because you have virtual hosts with multiple addresses each.

Use the %A format effector in a LogFormat or CustomLog directive:

CustomLog logs/served-by.log "%A"

Logging the Referring Page: %{Referer}i

Logging the Name of the Browser Software: %{User -Agent}i

Logging Arbitrary Request Header Fields

Use the %{...}i log format variable in your access log format declaration. such as %{Host}i

CustomLog logs/accept_log "\"%{Accept}i\""

Logging Arbitrary Response Header Fields

Use the %{...}o log format variable in your access log format declaration: %{Last -Modified}o

Virtual Hosts

There are two different types of virtual host supported by Apache. The first type, called address-based or IP-based, is tied to the numeric network address used to reach the system. The other type of virtual host is called name-based because the server's response depends on the name by which it was called. The environment defined by the directives outside any <VirtualHost> containers is sometimes called the "default server," "main server," or perhaps the "global server."

Setting Up Name-Based Virtual Hosts


NameVirtualHost *:80

<VirtualHost *:80>ServerName TheSmiths.name

ServerAlias www.TheSmiths.name Smith.Family.name

DocumentRoot "C:/Apache/Sites/TheSmiths"</VirtualHost>

<VirtualHost *:80>ServerName JohnSmith.name

DocumentRoot "C:/Apache/Sites/JustJohnSmith"</VirtualHost>

The *:80 in the previous rules means that the specified hosts run on all addresses.

The argument to the <VirtualHost> container directive needs to match the argument in a NameVirtualHost directive.

Multiple names can be listed for a particular virtual host using the ServerAlias directive:

ServerAlias www.TheSmiths.name Smith.Family.name

You must still add records to your DNS server so that the names resolve to the IP address of the server system.

Designating One Name-Based Virtual Host as the Default

Add the following <VirtualHost> section, and list it before all of your other ones:

<VirtualHost *:80>ServerName default

DocumentRoot /www/htdocs

ErrorDocument 404 /site_list.html</VirtualHost>

Setting Up Address-Based Virtual Hosts

You have multiple IP addresses assigned to your system, and you want to support one Web site on each.


<VirtualHost>ServerName Example.Com

DocumentRoot "C:/Apache/Sites/Example.Com"</VirtualHost>

<VirtualHost>ServerName JohnSmith.Example.Com

DocumentRoot "C:/Apache/Sites/JustJohnSmith"</VirtualHost>

Creating a Default Address-Based Virtual Host

Use the _default_ keyword to designate a default host:

<VirtualHost _default_> DocumentRoot /www/htdocs</VirtualHost>

The _default_ keyword creates a virtual host that catches all requests for any address:port combinations for which there is no virtual host configured.

The _default_ directive may—and should—be used in conjunction with a particular port number, such as:

<VirtualHost _default_:443>

Mixing Address-Based and Name-Based Virtual Hosts

Mass Virtual Hosting Using Rewrite Rules

Use directives from mod_rewrite to map to a directory based on the hostname:

RewriteEngine on

RewriteCond "%{HTTP_HOST}" "^(www\.)?([^.]+)\.com"

RewriteRule "^(.*)$" "/home/%2$1"

The directives in the Solution map requests for www.something.com to the directory /home/something.

Logging for Each Virtual Host

Specify Errorlog and CustomLog within each virtual host declaration:

<VirtualHost *:80> ErrorLog /home/waldo/www/logs/error_log

CustomLog /home/waldo/www/logs/access_log combined</VirtualHost>

Port-Based Virtual Hosts

Explicitly list the port number in the <VirtualHost> declaration:

Listen 8080

<VirtualHost>DocumentRoot /www/vhosts/port8080</VirtualHost>

Listen 9090

<VirtualHost>DocumentRoot /www/vhosts/port9090<VirtualHost>

Displaying the Same Content on Several Addresses

Specify both addresses in the <VirtualHost> directive:




Aliases, Redirecting, and Rewriting

Mapping a URL to a Directory

You want to serve content out of a directory other than the DocumentRoot directory.

Alias "/desired -URL-prefix" "/path/to/other/directory"

You may also need to add a few configuration directives to permit access to the directory that you are mapping to. An error message (in your error_log file) saying that the request was "denied by server configuration" usually indicates this condition. It is fairly common—and recommended —to configure Apache to deny all access, by

default, outside of the DocumentRoot directory.

<Directory "/path/to/other/directory "> Order allow,deny

Allow from all</Directory>

the Alias is very strict with respect to slashes. To avoid problem, create Aliases without the trailing slash on each argument.

Creating a New URL for Existing Content: Alias "/newurl" "/www/htdocs/oldurl"

Giving Users Their Own URLs

If you want users' Web locations to be under their home directories, add this to your httpd.conf file:

UserDir public_html

To put all users' Web directories under a central location: UserDir "/www/users/*/htdocs"

If you want to let users access their home directory without having to use a tilde (~) in the URL, you can use mod_rewrite to perform this mapping:

RewriteEngine On

RewriteCond "/home/$1/public_html" -d [NC]

RewriteRule "^/([^/]+)/(.*)" "/home/$1/public_html/$2"

Aliasing Several URLs with a Single Directive

Use AliasMatch in http.conf to match against a regular expression:

AliasMatch "^/pupp(y|ies)" "/www/docs/small_dogs"

AliasMatch "^/P-([[:alnum:]])([^/]*)" "/usr/local/projects/$1/$1$2"

Mapping Several URLs to the Same CGI Directory

ScriptAliasMatch "^/[sS]cripts?|cgi(-bin)?/" "/www/cgi-bin/"

Creating a CGI Directory for Each User

<Directory "/home/*/public_html/cgi-bin/">Options ExecCGI

SetHandler cgi-script </Directory>

ScriptAliasMatch "/~([^/]+)/cgi-bin/(.*)" "/home/$1/public_html/cgi-bin/$2"

Redirecting to Another Location

Redirect "/example" "http://www2.example.com/new/location"

Whereas Alias maps a URL to something in the local filesystem, Redirect maps a URL to another URL, usually on another server. The second argument is a full URL and is sent back to the client, which makes a second request for the new URL.

Redirections come in several different flavors: temp, permanent, gone, seeother.

Redirecting Several URLs to the Same Destination

RedirectMatch "^/[fF]ish(ing)?(/.*)?" "http://fish.example.com/$2"

Permitting Case-Insensitive URLs

You want requested URLs to be valid whether uppercase or lowercase letters are used.

Use mod_speling to make URLs case-insensitive: CheckSpelling On

The mod_speling module is part of the standard Apache distribution but is not enabled by default, so you need to explicitly enable it. In addition to making URLs case-insensitive, mod_speling, as the name implies, provides simple spellchecking capability. In particular, in the case of a "not found" error, mod_speling attempts to find files that may have been intended, based on similar spelling, transposed letters, or perhaps letters swapped with similar-looking numbers, like O for 0 and l for 1.

Showing Highlighted PHP Source without Symlinking

RewriteRule "^(.+\.php)s$" "$1" [H=application/x-httpd -php-source]

Replacing Text in Requested URLs

RewriteRule "(.*)string1 (.*)" "$1string2 $2" [N,PT]

The [N] flag tells Apache to rerun the rewrite rule. This rule will get run repeatedly until the RewriteCond fails.

The [PT] tells mod_rewrite to pass the rewritten URL on to the rest of Apache for any additional processing once the rewriting is done.

Rewriting Path Information to CGI Arguments

RewriteEngine on

RewriteRule "^/book/([^/]*)/([^/]*)" "/cgi-bin/book.cgi?author=$1&subject=$2" [PT]

Denying Access to Unreferred Requests

RewriteEngine On

RewriteCond "%{HTTP_REFERER}" !=""

RewriteCond "%{HTTP_REFERER}" "!^http://mysite.com/.*$" [NC]

RewriteRule "\.(jpg|gif|png)$ - [F]

If we've reached this point in the ruleset, we know that we have a request for an image file from within a page on another Web site. The RewriteRule matches a request and returns Forbidden to the client.

Redirecting Unreferred Requests to an Explanation Page

RewriteEngine On

RewriteCond "%{HTTP_REFERER}" "^$"

RewriteRule "(.*)" "/cgi-bin/need-referer" [PT,E=ORIG:$1]

Ihe original URI is put into the environment variable ORIG for the script to reference.

Rewriting Based on the Query String

RewriteCond "%{QUERY_STRING}" "^user=([^=]*)"

RewriteRule "/people" "http://%1.users.example.com/" [R]

The [R] tells mod_rewrite to direct the browser to the URL constructed by the RewriteRule directive.

Redirecting All—or Part—of Your Server to SSL

RewriteEngine on

RewriteCond "%{SERVER_PORT}" "^80$"

RewriteRule "^(.*)$" "https://%{SERVER_NAME}/$1" [R,L]

You can redirect particular URLs to a secure version:

RewriteRule "^/normal/secure(/.*)" "https://%{HTTP_HOST}/$1" [R,L]

You can redirect particular URLs to a secure version:

RewriteRule "^/normal/secure(/.*)" "https://%{HTTP_HOST}/$1" [R,L]

Or, you can simply use the Redirect directive in the http section of httpd.conf file to to cause a URL to be served as HTTPS:

Redirect "/" "https://secure.example.com/"

But make sure that this appears only in in the http scope and not in the https scope, or all https requests will loop.

Turning Directories into Hostnames

You want to migrate pathnames under a single hostname to distinct hostnames.

RewriteRule "^/(patha|pathb|pathc)(/.*)" "http://$1.example.com$2" [R]

RewriteRule "^/([^./]*)(/.*)" "http://$1.example.com$2" [R]

RewriteRule "^/~([^./]*)(/.*)" "http://$1.example.com$2" [R]

Redirecting All Requests to a Single Host

RewriteCond "%{HTTP_HOST}" "!^www.example.com" [NC,OR]

RewriteCond "%{SERVER_NAME}" "!^www.example.com" [NC]

RewriteRule "(.*)" "http://www.example.com$1" [R]

The NC (No Case) flag makes the regular expression case-insensitive.

The OR flag is a logical "or," allowing the two conditions to be strung together so that either one being true is a sufficient condition for the rule to be applied.

Rewriting Elements between Path and Query String

To rewrite http://example.com/path/to/5 to http://example.com/path/to?id=5 :

RewriteRule "^(/path/to)/(\d+)" "$1?id=$2" [PT]

To go the other way:

RewriteCond "%{QUERY_STRING}" "\bid=(\d+)\b"

RewriteRule "(/path/to)" "$1/%2" [PT,QSA]

Rewriting a Hostname to a Directory

You want requests for http://bogus.example.com/ to be turned into requests for http://example.com/bogus/ .

RewriteCond "%{HTTP_HOST}" "^([^.]+)\.example\.com" [NC]

RewriteRule "(.*)" "http://example.com/%1$1" [R]"

To do this transparently, without a redirect:

RewriteCond "%{HTTP_HOST}" "^([^.]+)\.example\.com$" [NC]

RewriteRule "(.*)" "/%1$1" [PT]

Turning URL Segments into Query Arguments

You want to turn requests of the form: http://example.com/foo/bar.html into something like this: http://example.com/cgi -bin/remap?page=foo/bar.html

RewriteRule "/(.*)" "/cgi-bin/remap?page=$1" [QSA,PT]

The QSA option allows any query-string information that was on the original request to be retained and merged with the one being added by the RewriteRule. The PT option tells the server to continue processing the request rather than treating it as completely finished.

Using AliasMatch, ScriptAliasMatch, and RedirectMatch

AliasMatch "/users/(.*)/" "/home/webonly/$1/"

RedirectMatch permanent "/projects/([^/]+)(/.*)" "http://$1.projectdomain.com$2"


Limiting Upload Size

<Directory "/usr/local/apache2/uploads">LimitRequestBody 10000</Directory>

Restricting Images from Being Used Off-Site

Add the following lines to the .htaccess file in the directory where the images are, or to the appropriate <Directory>

container in the httpd.conf file.

<FilesMatch "\.(jpg|jpeg|gif|png)$">SetEnvIfNoCase Referer "^http://([^/]*\.)?myserver.com /" local_referrer=1

Order Allow,Deny

Allow from env=local_referrer </FilesMatch>

In fact, by using the following recipe, you can even go one step further, and return a different image to users accessing your images via an off-site reference:

RewriteCond "%{ENV:local_referer}" "!=1"

RewriteRule ".*" "/Stolen-100x100.png" [L]

Requiring Both Weak and Strong Authentication

<Directory /www/htdocs/sensitive> Satisfy All

AuthType Basic

AuthName Sensitive

AuthUserFile /www/passwords/users

AuthGroupFile /www/passwords/groups

Require group salesmen

Order deny,allow

Deny from all

Allow from 192.168.1</Directory>

The Satisfy All directive requires that all access control measures be enforced for the specified scope.

Managing .htpasswd Files

htpasswd -c user.pass waldo

Create a new password file called user.pass with this one new entry for user waldo. Will prompt for password.

Add an entry for user ralph in password file user.pass. Will prompt for password: htpasswd user.pass ralph

Add a user ralph to password file user.pass with password mydogspot: htpasswd -b user.pass ralph mydogspo

the -D flag lets you delete an existing user from the password file: htpasswd -D user.pass waldo

Making Password Files for Digest Authentication

Use the following command forms to set up a credential file for a realm to be protected by Digest authentication:

% htdigest -c "By invitation only" rbowen

% htdigest "By invitation only" krietz

unlike entries in the password files created by htpasswd, which can be used anywhere, these passwords can be

used only in the specified authentication realm, because the encrypted hash includes the realm.

Relaxing Security in a Subdirectory

Add the following to either the .htaccess file in the subdirectory or in an appropriate

<Directory> container:

Satisfy Any

Order Deny,Allow

Allow from all

Lifting Restrictions Selectively

<Directory "/usr/local/apache/htdocs"> Satisfy All

Order allow,deny

Deny from all

<Files *.html>Order deny,allow

Allow from all

Satisfy Any</Files></Directory>

Accessing the Authenticated Username

Some scripting modules, such as mod_php, provide a standard interface for accessing values set by the server. For

instance, to obtain the username that was used to authenticate from within a PHP script, it would access a field in the $_SERVER superglobal array:

$auth_user = $_SERVER['REMOTE_USER'];

For a Perl or mod_perl script, use:

my $username = $ENV{REMOTE_USER};

In a Server-Side Include (SSI) directive, this may look like:

Hello, user <!--#echo var="REMOTE_USER" -->. Thanks for visiting.

Preventing Brute-Force Password Attacks

you can use something like Apache::BruteWatch to tell you when a user is being attacked:

PerlLogHandler Apache::BruteWatch

PerlSetVar BruteDatabase DBI:mysql:brutelog

PerlSetVar BruteDataUser username

PerlSetVar BruteDataPassword password

PerlSetVar BruteMaxTries 5

PerlSetVar BruteMaxTime 120

PerlSetVar BruteNotify rbowen@example.com

Use AuthType Basic and the htpasswd tool to control access using Basic authentication. Use AuthType Digest and the htdigest tool for the Digest method.

Restricting Proxy Access to Certain URLs

You can block by keyword:

ProxyBlock .rm .ra .mp3

You can block by specific backend URLs:

<Directory proxy:http://other -host.org/path > Order Allow,Deny

Deny from all

Satisfy All</Directory>

Or you can block according to regular expression pattern matching:

<Directory proxy:*> RewriteEngine On

RewriteRule "\.(rm|ra)$" "-" [F,NC]

RewriteRule "^[a-z]+://[ -.a-z0-9]*\.mil($|/)" "-" [F,NC]</Directory>

F or forbidden, NC or nocase.

Protecting Server Files from Malicious Scripts

Ensure that none of your files are writable by the nobody user or the nobody group, and that sensitive files are not readable by that user and group:find / -user nobody; find / -group nobody

Restricting Access to Files Outside Your Web Root

<Directory /> Order deny,allow

Deny from all

AllowOverride None

Options None</Directory>

For Windows systems:<Directory C:/>...</Directory>

Repeat for each drive letter on the system.

If you wanted to create an Alias to some other section of your filesystem, you would need to explicitly permit this:

Alias /example /var/example

<Directory /var/example> Order allow,deny

Allow from all</Directory>

Limiting Methods by User

Apply user authentication per method using the Limit directive:

Order Deny,Allow

Allow from all

<Limit GET>Satisfy Any</Limit>

<LimitExcept GET> Satisfy All

Require valid-user </Limit>

Rebutting DoS Attacks with mod_evasive

Obtain mod_evasive from http://www.zdziarski.com/projects/mod_evasive/ and use a configuration like the following:

DOSPageCount 2

DOSPageInterval 1

DOSSiteCount 50

DOSSiteInterval 1

DOSBlockingPeriod 10

mod_evasive detects when a single client is making multiple requests in a short period of time, and denies further requests from that client.

This configuration places two restrictions on requests. First, the DOSPage directives state that if a single client address requests the same URL more than twice in a single second, it should be blocked. The DOSSite directives state that if a single client address requests more than 50 URLs in a single second, it should be blocked. This second value is higher because sometimes a single page will contain a large number of images, and so will result in a larger number of requests from one client.

The DOSBlockingPeriod directive sets the interval for which the client will be blocked—in this case, 10 seconds.

chroot is a Unix command that causes a program to run in a jail. That is to say, when the command is launched, the

accessible file system is replaced with another path, and the running application is forbidden to access any files outside of its new file system. By doing this, you are able to control what resources the program has access to and prevent it from writing to files outside of that directory, or running any programs that are not in that directory. This prevents a large number of exploits by simply denying the attacker access to the necessary tools.

Blocking Worms with mod_security

You can use mod_security third-party module to intercept common probes before they actually reach your Web

server's pages.

Mixing Read-Only and Write Access to a Subversion Repository

For a simple solution, you can use the <LimitExcept> to protect certain files or paths such that write access requires


<Location "/repos"> DAV svn

SVNParentPath "/repository/subversion "

AuthType Basic

AuthName "Log in for write access"

AuthUserFile "/path/to/authfile "

<LimitExcept GET REPORT OPTIONS PROPFIND>Requre valid-user</LimitExcept></Location>

For more flexible or finegrained control, combine this with the mod_authz_svn module:

LoadModule authz_svn_module modules/mod_authz_svn.so

<Location "/repos"> ... AuthzSVNAccessFile "/path/to/access -file"



Require valid-user</LimitExcept></Location>

Using Permanent Redirects to Obscure Forbidden URLs

Add an ErrorDocument script that issues a permanent redirect to a "document not found" message page:

Alias "/not-found" "/path/to/documentroot /not-found.html"

ErrorDocument 403 "/cgi/handle-403

And in the cgi-bin/handle-403 script, something like this:

#! /usr/bin/perl -w

print "Location: http://example.com /not-found\r\n\r\n";


Installing SSL

If you built Apache yourself from source, just add --enable-ssl to the ./configure arguments when you build Apache to include SSL as one of the built-in modules. The Apache SSL modules are an interface between Apache and the OpenSSL libraries, which you must install before any of this can work.

Generating Self-Signed SSL Certificates

Use the openssl command-line program that comes with OpenSSL:

Generating the private key:

openssl genrsa -out server.key 1024

Generating the certificate signing request:

openssl req -new -key server.key -out server.csr

You must supply Common Name the correct value, which is the hostname of the server on which this certicate will be used. It is crucial that the hostname that you put in here exactly match the hostname that will be used to access the site.

Removing the passphrase:

cp server.key server.key.org

openssl rsa -in server.key.org -out server.key

Signing your key:

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

You can also use the CA.pl script that comes with OpenSSL to generate a CA certificate of your own.

Then add the following lines in your httpd.conf configuration file:

SSLCertificateFile "/www/conf/server.crt"

SSLCertificateKeyFile "/www/conf/server.key"

Serving a Portion of Your Site via SSL

You want to have a certain portion of your site available via SSL exclusively.

<Directory /www/secure>SSLRequireSSL</Directory>

or: RewriteEngine On

RewriteCond %{HTTPS} !=on

RewriteRule ^/(.*) https://%{SERVER_NAME}/$1 [R,L]

The entire setup might look something like this:

NameVirtualHost *

<VirtualHost *> ServerName regular.example.com

DocumentRoot /www/docs

Redirect / https://secure.example.com/</VirtualHost>

<VirtualHost _default_:443> SSLEngine On

SSLCertificateFile /www/conf/ssl/ssl.crt

SSLCertificateKeyFile /www/conf/ssl/ssl.key

ServerName secure.example.com

DocumentRoot /www/docs</VirtualHost>

Wildcard Certificates

Create a certificate with a Common Name of *.example.com, where example.com is the domain for which you wish to use the certificate. This certificate will now work for any hostname in the example.com domain, such as www.example.com or secure.example.com.

Error Handling

Customized Error Messages

You want to display a customized error message, rather than the default Apache error page.

ErrorDocument 405 /errors/notallowed.htm

Redirecting Invalid URLs to Some Other Page

ErrorDocument 404 /index.html

DirectoryIndex index.html /path/to/notfound.html

Making Internet Explorer Display Your Error Page

Make the error document bigger—at least 512 bytes.

Notification on Error Conditions

Point the ErrorDocument directive to a CGI program that sends mail, rather than to a static document:

ErrorDocument 404 /cgi-bin/404.cgi


mod_proxy, which comes with Apache, handles proxying behavior. Apache 2.2 introduces a number of submodules, such as mod_proxy_balancer, which give additional functionality to mod_proxy.

Securing Your Proxy Server

<Proxy *> Order Deny,Allow

Deny from all

Allow from .yourdomain.com</Proxy>

Every request for resources that goes through your proxy server generates a logfile entry, containing the

address of the client and the resource that she requested through your proxy server.

It is possible to configure your server not to log these requests.

<Directory proxy:*> SetEnv PROXIED 1</Directory>

CustomLog /www/logs/access_log common env=!PROXIED

Preventing Your Proxy Server from Being Used as an Open Mail Relay

Use mod_rewrite to forbid proxy requests to port 25 (SMTP):

<Directory proxy:*> RewriteEngine On

RewriteRule "^proxy:[a-z]*://[^/]*:25(/|$)" "-" [F,NC,L] </Directory>

Forwarding Requests to Another Server

ProxyPass /other/ http://other.server.com/

ProxyPassReverse /other/ http://other.server.com/

The ProxyPassReverse directive ensures that any redirect headers sent from the backend server will be modified so that they appear to come from the main server.

Blocking Proxied Requests to Certain Places

You want to use your proxy server as a content filter, forbidding requests to certain places.

ProxyBlock forbiddensite.com www.competitor.com monster.com

Proxying mod_perl Content to Another Server

You want to run a second HTTP server for dynamically generated content and have Apache transparently map requests for this content to the other server.

First, install Apache, running on an alternate port, such as port 90, on which you will generate this dynamic content. Then, on your main server:

ProxyPass /dynamic/ http://localhost:90/

ProxyPassReverse /dynamic/ http://localhost:90/

By giving the dynamic content its own dedicated server, you allow the static content to be served much more rapidly, and the dynamic content has a dedicated server. Each server can have a smaller set of modules installed than it would otherwise require because it'll be performing a smaller subset of the functionality needed to do both tasks.

Configuring a Caching Proxy Server

Configure your server to proxy requests and provide a location for the cached files to be placed:

ProxyRequests on

CacheRoot /var/spool/httpd/proxy

Filtering Proxied Content

You want to apply some filter to proxied content, such as altering certain words.

In Apache 2.0 and later, you can use mod_ext_filter to create output filters to apply to content before it is sent to the user:

ExtFilterDefine naughtywords mode=output intype=text/html cmd="/bin/sed s/darned/blasted/g"

<Proxy *>SetOutputFilter naughtywords</Proxy>

Requiring Authentication for a Proxied Server

You wish to proxy content from a server, but it requires a login and password before content may be served from this proxied site.

ProxyPass "/secretserver/" ""

<Directory "proxy:">AuthName SecretServer

AuthType Basic

AuthUserFile /path/to/secretserver.htpasswd

Require valid-user </Directory>

Load Balancing with mod_proxy_balancer

Use mod_proxy_balancer to create a load-balanced cluster:

<Proxy balancer://mycluster>BalancerMember


ProxyPass /application balancer://mycluster/

You can indicate that a particular server is more powerful than another, and so should be allowed to assume

more of the load than other machines in the cluster.

BalancerMember loadfactor=2

Traffic may be balanced by traffic (bytes transferred) or by request (number of requests made per host) by putting

additional arguments on the ProxyPass directive:

ProxyPass /application balancer://mycluster/ lbmethod=bytraffic

And there is a Web-based balancer manager tool, which can be configured as follows:

<Location /balancer-manager>SetHandler balancer-manager</Location>

The balancer manager lets you set servers available or unavailable, and change their load factor, without restarting the server. This allows you to take servers offline for maintenance, do whatever needs to be done, and bring them back up, without ever affecting the end user.

Proxied Virtual Host

<VirtualaHost *:80> ServerName server2.example.com

ProxyPass /

ProxyPassReverse / </VirtualHost>

Refusing to Proxy FTP

Make sure that mod_proxy_ftp isn't loaded:

# LoadModule proxy_ftp_module modules/mod_proxy_ftp.so

mod_proxy has several helper modules that provide the protocol-specific proxying functionality. These modules are mod_proxy_http, for proxying HTTP requests; mod_proxy_ftp, for proxying FTP requests; and mod_proxy_connect, for support for the CONNECT HTTP method, used primarily for tunneling SSL requests through proxy servers.


Benchmarking Apache with ab

ab -n 1000 -c 10 http://www.example.com/test.html

-n requests Number of requests to perform

-c concurrency Number of multiple requests to make

Tuning KeepAlive Settings

KeepAlive On

MaxKeepAliveRequests 0

KeepAliveTimeout 15

The default behavior of HTTP is for each document to be requested over a new connection. This causes a lot of time to be spent opening and closing connections. KeepAlive allows multiple requests to be made over a single connection, thus reducing the time spent establishing socket connections. This, in turn, speeds up the load time for clients requesting content from your site.

Getting a Snapshot of Your Site's Activity

Enable the server-status handler to get a snapshot of what child processes are running and what each one is doing.

Enable ExtendedStatus to get even more detail:

<Location /server-status> SetHandler server-status

Order deny,allow

Deny from all

Allow from 192.168.1</Location>

ExtendedStatus On

Then, view the results at the URL http://servername/server-status. You should aslo restrict access to this handler.

Avoiding DNS Lookups

HostNameLookups Off

whenever possible, Allow from and/or Deny from directives use the IP address, rather than the hostname

of the hosts in question DNS lookups can take a very long time—anywhere from 0 to 60 seconds—and should be avoided at all costs.

Optimizing Symbolic Links

For tightest security, use Options SymlinksIfOwnerMatch, or Options -FollowSymLinks if you seldom or never use symlinks.

For best performance, use Options FollowSymlinks.

Minimizing the Performance Impact of .htaccess Files

Turn on AllowOverride only in directories where it is required, and tell Apache not to waste time looking for .htaccess file elsewhere:

AllowOverride None

Then use <Directory> sections to selectively enable .htaccess files only where needed.

.htaccess files cause a substantial reduction in Apache's performance, because it must check for a .htaccess in every

directory along the path to the requested file to be assured of getting all of the relevant configuration overrides.

<Directory /www/htdocs/users/leopold>AllowOverride All</Directory>

you would never have AllowOverride All enabled for your entire filesystem. anything that appears in a .htaccess can, can instead appear in a <Directory> section, referring to that same directory.

Disabling Content Negotiation

Disable content negotiation where it is not needed. If you do require content negotiation, use the type-map handler, rather than the MultiViews option:

Options -MultiViews

AddHandler type-map var

Caching Frequently Viewed Files

Use mod_mmap_static or mod_file_cache (for Apache 1.3 and 2.0, respectively) to cache these files in memory:

MMapFile /www/htdocs/index.html

MMapFile /www/htdocs/other_page.html

For Apache 2.0, you can use either module or the CacheFile directive. MMapFile caches the file contents in memory, while CacheFile caches the file handle instead, which gives slightly poorer performance but uses less memory:

CacheFile /www/htdocs/index.html

CacheFile /www/htdocs/other_page.html

Caching Directory Listings

You want to provide a directory listing but want to reduce the performance hit of doing so.

Use the TrackModified argument to IndexOptions to allow browsers to cache the results of an auto-generated directory index:

IndexOptions +TrackModified

Caching Dynamic Content

You want to cache dynamically generated documents that don't actually change very often.

In Apache 2.2, use the following recipe:

CacheEnable disk /

CacheRoot /var/www/cache

CacheIgnoreCacheControl On

CacheDefaultExpire 600

Directory Listings

Generating Directory/Folder Listings

<Directory /usr/local/htdocs/archives>Options +Indexes</Directory>

Disabling directory indexing below an enabled directory

<Directory /usr/local/htdocs/archives/*>Options -Indexes</Directory>

<DirectoryMatch /usr/local/htdocs/archives/(images|video|audio)>Options -Indexes</DirectoryMatch>

Hiding Things from the Listing

IndexIgnore *.tmp *.swp .svn secret.txt

Files that are password-protected are automatically omitted from directory listings.

Sorting the List

IndexOrderDefault Descending Date

The possible arguments to IndexOrderDefault are:Name,Date,Size,Description.

Specifying How the List Will Be Formatted

There are three levels of formatting that can be set. The list may be unformatted, formatted, or can be rendered in an HTML table. To enable fancy indexing, do the following:

IndexOptions FancyIndexing

IndexOptions FancyIndexing HTMLTables

Listing the Directories First:IndexOptions FoldersFirst

Ordering by Version Number:IndexOptions VersionSort

Showing Forbidden Files

By default, Password -protected files and directories don't show up in the directory listing.

IndexOptions +ShowForbidden

Miscellaneous Topics

Renaming .htaccess Files: AccessFileName ht.access

If you use the AccessFileName directive, be sure to make any additional appropriate changes to your configuration such as the <FilesMatch "^\.ht"> container that keeps the files from being fetchable over the Web:

<FilesMatch "^ht\.">Order deny,allow

Deny from all</FilesMatch>

Solving the "Trailing Slash" Problem

Create Alias directives without the trailing slash: Alias /example /home/www/example

Alternate Default Document

DirectoryIndex index.html index.htm index.php default.htm

You also can provide a relative URL if you want to load content from some other directory, such as a CGI program:

DirectoryIndex /cgi-bin/index.pl

Setting Up a Default "Favicon"

favicon.ico files allow Web sites to provide a small (16 x 16 pixels) image to clients for use in labeling pages; for instance, the Mozilla browser will show the favicon in the location bar and in any page tabs.

AddType image/x-icon .ico

<Files favicon.ico>ErrorDocument 404 /icons/favicon.ico</Files>

Enabling .htaccess Files

Add the following line to your httpd.conf file in a scope that applies to the directory (or directories) for which you want to enable .htaccess files:

AllowOverride keyword ...


AllowOverride All|None|directive-type [directive-type]

The directive-type can be one of the following groupings of directives: AuthConfig, FileInfo, Indexes, Limit, Options[=Option,...].

Using Regular Expressions in Apache

RedirectMatch ^/[sS]upport/(.*) http://support.example.com/$1


Debugging Rewrites That Result in "Not Found" Errors

If your RewriteRule directives keep resulting in 404 Not Found error pages, add the PT (PassThrough) flag to the RewriteRule line. Without this flag, Apache won't process a lot of other factors that might apply, such as Alias settings.You can verify that this is the cause of your problem by cranking the mod_rewrite logging level up to 9 and seeing that the entries relating to the RewriteRule mention something about prefixes with document_root:

RewriteLog logs/rewrite-log

.htaccess Files Having No Effect

Make sure that AllowOverride is set to an appropriate value.

.htaccess files


.htaccess files provide a way to make configuration changes on a per-directory basis.

Post a Comment


Java (160) Lucene-Solr (112) Interview (64) All (58) J2SE (53) Algorithm (45) Soft Skills (39) Eclipse (33) Code Example (31) JavaScript (23) Linux (22) Spring (22) Windows (22) Tools (21) Web Development (20) Nutch2 (18) Bugs (17) Debug (16) Defects (14) Text Mining (14) Troubleshooting (14) J2EE (13) Network (13) PowerShell (11) Problem Solving (10) Chrome (9) Design (9) How to (9) Learning code (9) Performance (9) UIMA (9) html (9) Http Client (8) Maven (8) Security (8) Tips (8) bat (8) blogger (8) Big Data (7) Database (7) Google (7) Guava (7) JSON (7) Shell (7) System Design (7) ANT (6) Coding Skills (6) Lesson Learned (6) Programmer Skills (6) Scala (6) css (6) Algorithm Series (5) Cache (5) Continuous Integration (5) IDE (5) adsense (5) xml (5) AIX (4) Become a Better You (4) Code Quality (4) Concurrency (4) Dynamic Languages (4) GAE (4) Git (4) Good Programming Practices (4) Jackson (4) Memory Usage (4) Miscs (4) OpenNLP (4) Project Managment (4) Review (4) Spark (4) Testing (4) ads (4) regular-expression (4) Android (3) Apache Spark (3) Distributed (3) Eclipse RCP (3) English (3) Happy Hacking (3) IBM (3) J2SE Knowledge Series (3) JAX-RS (3) Jetty (3) Life (3) Python (3) Restful Web Service (3) Script (3) regex (3) seo (3) .Net (2) Android Studio (2) Apache (2) Apache Procrun (2) Architecture (2) Batch (2) Bit Operation (2) Build (2) Building Scalable Web Sites (2) C# (2) C/C++ (2) CSV (2) Career (2) Cassandra (2) Fiddler (2) Google Drive (2) Gson (2) How to Interview (2) Html Parser (2) Http (2) Image Tools (2) JQuery (2) Jersey (2) LDAP (2) Logging (2) Mac (2) Software Issues (2) Storage (2) Text Search (2) xml parser (2) AOP (1) Application Design (1) AspectJ (1) Chrome DevTools (1) Cloud (1) Codility (1) Data Mining (1) Data Structure (1) ExceptionUtils (1) Exif (1) Feature Request (1) FindBugs (1) Firefox (1) Greasemonkey (1) HTML5 (1) Httpd (1) I18N (1) IBM Java Thread Dump Analyzer (1) Invest (1) JDK Source Code (1) JDK8 (1) JMX (1) Lazy Developer (1) Machine Learning (1) Mobile (1) My Plan for 2010 (1) Netbeans (1) Notes (1) Operating System (1) Perl (1) Problems (1) Product Architecture (1) Programming Life (1) Quality (1) Redhat (1) Redis (1) RxJava (1) Solutions logs (1) Team Management (1) Thread Dump Analyzer (1) Visualization (1) boilerpipe (1) htm (1) ongoing (1) procrun (1) rss (1)

Popular Posts