Default .htaccess file for all sites

November 4, 2009

Most of the sites I work with on a daily basis run on Linux servers, and run under the Apache web server. This gives me all the benefits and stresses of using .htaccess files to control things, from rewrite URLs to various security and performance aspects of sites. If you run any such sites and are unfamiliar with .htaccess, especially WordPress sites, I hope you’ll find this helpful.

If you follow my daily links, from time to time I link to various articles and blog posts that share amazing Apache techniques. The most common place that I find well-written articles on these subjects that I can actually understand and implement is Perishable Press, and I can’t recommend it enough if you need such knowledge.

At the moment, though, I want to share one simple technique that is too commonly forgotten – a default, basic .htaccess file to start off every website. It can and should be expanded for each website’s needs, but it ensures that really wonderful things are present from the start. Here is mine, as it currently stands, and I’ll comment on each section (defined as a # comment in the example) following the example:

  1. # basic compression
  2. <IfModule mod_gzip.c>
  3. mod_gzip_on Yes
  4. mod_gzip_dechunk Yes
  5. mod_gzip_item_include file \.(html?|txt|css|js)$
  6. mod_gzip_item_include mime ^text/.*
  7. mod_gzip_item_include mime ^application/x-javascript.*
  8. mod_gzip_item_exclude mime ^image/.*
  9. mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
  10. </IfModule>
  11. # Protect files and directories
  12. <FilesMatch "(\.(engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.php)? |xtmpl)|code-style\.pl|Entries.*|Repository|Root|Tag|Template)$">
  13. Order allow,deny
  14. </FilesMatch>
  15. # Don’t show directory listings
  16. Options -Indexes
  17. # Basic rewrite rules, stop unneeded PERL bot, block subversion directories
  18. <IfModule mod_rewrite.c>
  19. RewriteEngine On
  20. RewriteRule ^(.*/)?\.svn/ - [F,L]
  21. ErrorDocument 403 "Access Forbidden"
  22. RewriteCond %{HTTP_USER_AGENT} libwww-perl.*
  23. RewriteRule .* – [F,L]
  24. </IfModule>

Basic compression

The code in this section asks Apache to compress all CSS, JavaScript, HTML, and txt files, while not compressing images (to preserve their quality). This can greatly reduce the time it takes to load these kind of files, especially for libraries like jQuery. In this case, it is done with the mod_gzip module, which usually is installed in Apache.

Now, it is important to note that in some cases, the gzip module is either not installed, or is not as effective as the mod_deflate module. I learned from a server admin friend that mod_gzip can compress better, while mod_deflate runs faster overall. So in cases where CPU cycles are more of a concern for you individually, or your host, you can use mod_deflate in place of this section like this:

  1. <FilesMatch "\\.(js|css|html|htm|php|xml)$">
  2. SetOutputFilter DEFLATE
  3. </FilesMatch>

Protect files and directories

This simply looks at some common file and directory types that should not be viewed by users. Install directories, include directories, files that would contain sensitive code, etc. You can certainly customize the list, but it is good to have this as a basic defense.

Don’t show directory listings

All this one does is keep directories that don’t have a default index page (index.php, index.html, etc.) from listing their contents. It isn’t always a problem for directories to list their contents, but it is never a problem to hide them, either. If you want to list files, do it yourself so you can choose what gets listed.

Basic rewrite rules, stop unneeded PERL bot, block subversion directories

Most Apache installations have the mod_rewrite module, which is invaluable for friendly URLs, changed URLs, and any number of other things. In this case, we are just detecting whether it is present. If it is, we are sending away the libwww-perl bot (from this article), and we are also keeping users from viewing any .svn directories. These are created by Subversion, which is a wonderful thing that is beyond the scope of this post. If you have these directories, you should never upload them, but should instead export repositories. But regardless, accidents happen and sometimes these directories can end up on servers. If they do, they shouldn’t be publicly accessible.

Something extra for WordPress users

If you are a WordPress user, you have a wp-config.php file that contains database information. Potential attackers know this, and it is always a good idea to keep them out of this file. If you use another CMS, find out what file(s) correspond to this one, and change it accordingly. It’s a simple command that prevents users from directly visiting this file, while still allowing the web server itself to access the configuration information it contains.

  1. # block config file for the CMS, if any
  2. <files wp-config.php>
  3. order allow,deny
  4. deny from all
  5. </files>