Apache
last updated 2014-03
note - serving of local files
note: often the initial installation of Apache has the <Directory /> directive (directive for the root of the filesystem) set to allow access, in [Apache config dir]/sites-available/default! this means that the server can serve any file from the file system, not just the files in the htdocs document folder, which you typically want!
to avoid this, make sure it says Require all denied (Apache 2.4 - the 2.2 equivalent was Order Deny,Allow + Deny from All). current Debian/Ubuntu packages ship it like that in apache2.conf, but it's worth a check
self-signed SSL certificate
they might not pass as customer-friendly - in fact, if you need HTTPS/SSL for customer communication, you should always use signed certificates, as those do induce trust - but often you have private sections/domains/sites where self-signed is just fine… or you might just wanna test the SSL while waiting for the signed certificate
here are just the steps to get to your certificate; for details and explanations, see e.g. akadia.com
# openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 365 -subj "/CN=ssl-name"
# cp server.crt /etc/apache2/cert/ssl.crt
# cp server.key /etc/apache2/cert/ssl.key
# chmod 400 /etc/apache2/cert/ssl.crt /etc/apache2/cert/ssl.key
enable SSL/HTTPS in Apache
how to: use the following virtual host definition:
<VirtualHost *:443>
ServerName ssl-name
DocumentRoot /var/www/ssl/root
SSLEngine on
SSLCertificateFile /etc/apache2/server.crt
SSLCertificateKeyFile /etc/apache2/server.key
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
</VirtualHost>
where the certificate file and the certificate key file are either authority-signed or self-signed certificate files (see above), and add
Listen 443
to /etc/apache2/ports.conf and restart Apache
update 2026 - on Apache 2.4 NameVirtualHost is gone (it does nothing and warns), Listen 443 is enough - and on Debian/Ubuntu a2enmod ssl already adds it
.htaccess and mod_rewrite tricks
mostly based on 17 Useful .htaccess Tricks and Tips
general
set timezone
SetEnv TZ Australia/Melbourne
SEO friendly 301 permanent redirects
modern search engines have the capability to detect 301 Permanent Redirects and update their existing records
Redirect 301 http://www.domain.com/home http://www.domain.com/
skip the download dialogue
the following defines given types as octet-stream, thus making them "only to download"; clicking the link to such a resource will skip the "open / save" dialog and will start the download immediately
AddType application/octet-stream .pdf
AddType application/octet-stream .zip
AddType application/octet-stream .mov
skip or force www.
one of the SEO guidelines is: make sure there is only one URL pointing to your website
to force URLs without www.:
RewriteEngine On
RewriteCond %{HTTPS} =off
RewriteCond %{HTTP_HOST} ^www\..+$ [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [L,R=301]
to force www. in the URL, with the exception of subdom.domain.com:
RewriteEngine On
RewriteCond %{HTTPS} =off
RewriteCond %{HTTP_HOST} !^www\.
RewriteCond %{HTTP_HOST} !^subdom\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
custom error pages
ErrorDocument 401 /error/401.php
ErrorDocument 403 /error/403.php
ErrorDocument 404 /error/404.php
ErrorDocument 500 /error/500.php
compress files
you need to have the deflate module installed and enabled
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
cache files
the following example sets caching of multimedia files to 30 days:
<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|swf|js|css|pdf)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
disable caching for certain file types
the following example disables caching of scripts:
<FilesMatch ".(pl|php|cgi|spl|scgi|fcgi)$">
Header unset Cache-Control
</FilesMatch>
redirect one domain to another
RewriteEngine On
RewriteCond %{HTTP_HOST} olddomain\.com$ [NC]
RewriteRule ^(.*)$ http://www.newdomain.com/$1 [L,R=301]
redirect (sections) to https://
the following forces the /login and /signup sections of your site to use HTTPS
of course, it's recommended that you have a signed SSL certificate
RewriteEngine on
RewriteCond %{HTTPS} =off
RewriteCond %{REQUEST_URI} /login [NC,OR]
RewriteCond %{REQUEST_URI} /signup [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
simple MVC using .htaccess
you can redirect all requests to a single script file, and serve content based on REQUEST_URI:
RewriteEngine On
RewriteRule !robots\.txt|\.(js|ico|gif|jpg|png|css|flv|swf)$ index.php
provide different page versions based on user agent
you can provide different versions of your site for different browsers (e.g. links as a text-based browser, and for mobile devices):
RewriteEngine On
# MSIE
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/4(.*)MSIE
RewriteRule ^index\.html$ /index.ie.html [L]
# Netscape / Mozilla
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/5(.*)Gecko
RewriteRule ^index\.html$ /index.full.html [L]
# Lynx, text based
RewriteCond %{HTTP_USER_AGENT} ^Lynx/
RewriteRule ^index\.html$ /index.light.html [L]
# Mobile version of your site
RewriteCond %{HTTP_USER_AGENT} ^.*(iPad|iPhone).*$
RewriteRule ^(.*)$ http://ipad.domain.com [R=301]
# All other
RewriteRule ^index\.html$ /index.medium.html [L]
security
hotlinking protection with .htaccess
block all multimedia file requests that do not come from a direct link or from your site:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www.)?domain.com/.*$ [NC]
RewriteRule .(gif|jpg|swf|flv|png)$ /no-hotlink.html [R=302,L]
prevent hacks
block some common malicious URL hacks:
RewriteEngine On
# proc/self/environ? no way!
RewriteCond %{QUERY_STRING} proc/self/environ [OR]
# Block out any script trying to set a mosConfig value through the URL
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR]
# Block out any script trying to base64_encode crap to send via URL
RewriteCond %{QUERY_STRING} base64_encode.*(.*) [OR]
# Block out any script that includes a <script> tag in URL
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
# Block out any script trying to set a PHP GLOBALS variable via URL
RewriteCond %{QUERY_STRING} GLOBALS(=|[|\%[0-9A-Z]{0,2}) [OR]
# Block out any script trying to modify a _REQUEST variable via URL
RewriteCond %{QUERY_STRING} _REQUEST(=|[|\%[0-9A-Z]{0,2})
# Send all blocked request to page with 403 Forbidden error!
RewriteRule ^(.*)$ no-way.html [F,L]
block access to your .htaccess file
# secure .htaccess file
<Files .htaccess>
Require all denied
</Files>
# prevent viewing of a specific file
<Files secretfile.jpg>
Require all denied
</Files>
# multiple files / file types
<FilesMatch "\.(htaccess|htpasswd|ini|phps|fla|psd|log|sh)$">
Require all denied
</FilesMatch>
rename .htaccess files
AccessFileName htacc.ess
disable directory browsing
# disable directory browsing
Options All -Indexes
# enable directory browsing
Options All +Indexes
change default index page
DirectoryIndex my-home.html
block unwanted visitors based on referring domain
# block visitors referred from indicated domains
RewriteEngine on
RewriteCond %{HTTP_REFERER} scumbag.com [NC,OR]
RewriteCond %{HTTP_REFERER} wormhole.com [NC,OR]
RewriteRule .* - [F]
block requests based on User-Agent header
# block certain bots and spiders
SetEnvIfNoCase ^User-Agent$ .*(craftbot|download|extract|stripper|sucker|ninja|clshttp|webspider|leacher|collector|grabber|webpictures) HTTP_SAFE_BADBOT
SetEnvIfNoCase ^User-Agent$ .*(libwww-perl|aesop_com_spiderman) HTTP_SAFE_BADBOT
<RequireAll>
Require all granted
Require not env HTTP_SAFE_BADBOT
</RequireAll>
secure directories by disabling execution of scripts
AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi
Options -ExecCGI