Guide to the .htaccess file

The httpd.conf File

The Apache server has one main configuration file, the httpd.conf file. On a shared host, you most likely do not have access to this file. The configuration file will have directives which include:

  • whether to allow distributed configuration files (the .htaccess files), and which directives to allow in the .htaccess file. This is done using the AllowOverride directive.
  • what these files will be called. By default, they are called .htaccess. This can be changed using the AccessFileName directive.

If you are not on a shared host, consider moving all the directives to the main configuration file - there is a performance penalty if .htaccess files are enabled even if they are never actually used. Also make sure .htaccess files are disabled in the main configuration file: AllowOverride None

What is a .htaccess file

The .htaccess file is a simple text file, which you can edit using a plain text editor. Note that .htaccess IS the name and extension - don't add anything like .txt at the end.

The directives in the .htaccess file act on the directory where the file is, and all descendant directories. For example, a .htaccess file in directory /user/john/html/ will affect subdirectories /user/john/html/subdir1, /user/john/html/subdir1/subsubdir1 etc. Each of the subdirectories can have a .htaccess file. If directives in these files conflict with those in the parent directory, the parent file directives are overridden.

In the .htaccess files, you include Apache directives. The complete list of directives for Apache 2.2 can be found here. Not all directives can be included in a .htaccess file. If you click on a directive, you get a full description which includes Syntax and Context. Check that the .htaccess is included in the Context specification. If you use a directive without .htaccess in the Context, you will most likely get a server error message: 500 Internal Server Error

Further, on a shared some directives may not be available - ask your host if a directive is allowed.

Securing the .htaccess file

The first thing you probably want to do is make this file unreadable by the general public. By default, .htaccess files are protected from visitors. Attempting to get it e.g. example.org/.htaccess, will generate a 403 message: You don't have permission to access /.htaccess on this server. You can also set it's CHMOD to 644. Alternatively, use the FilesMatch (or Files) directive in the file itself as follows:

#Deny access to all files ending with .htaccess or .config
<FilesMatch "\.(htaccess|config)$">
Order allow,deny
</FilesMatch>

Note: The lines beginning with the # are optional comment lines, and will be ignored by Apache.

FilesMatch uses a regular expression to match files ending in '.htaccess' or '.txt'. The Allow/Deny directives then deny access to the matched files. These files cannot now be accessed by typing the full url in the browser - a 403 error message is returned instead. If you have other sensitive files such as PHP ini files, you can protect them in the same way.

Password protect directories

Another use for directives is to password protect directories. For this, you use a password file and the .htaccess file. The password file will store a combination of the username and the password. This file can be created using the htpasswd utility bundled with the Apache server. For enhanced security, you must store this password file outside of your document root, if possible. Lets say you store this file as /user/john/access/passwords

Say you have created users peter and sandra with their passwords. Now you want to make directory /user/john/public/private/ accessible only to peter and sandra. Also you want the two to enter the correct passwords. In a .htaccess file in directory /user/john/public/private/, include these directives:

AuthType Basic
AuthName "Please log in"
AuthUserFile /usr/john/access/passwords
Require user peter sandra

This will cause a user name/password box to pop up whenever a resource in the directory is first requested. The text "Please log in" will be displayed in the box. Change it to whatever you want it to be.

You can also grant permission to a group. Lets say you create a group text file, /usr/john/access/groups. You add each group as a line of text with the following format:

GroupName: user1 user2...userN e.g. mathematicians: pythagoras euler fermat mandelbrot

Then use the AuthGroupFile directive: AuthType Basic
AuthName "Please log in"
AuthUserFile /usr/john/access/passwords
AuthGroupFile /usr/john/access/groups
Require group mathematicians
The users you specify must also be included in the password file, as they will be required to supply a password.

Note: Although its very simple to password protect your directories in this way, it's not very secure. This type of protection is good to stop the casual surfer from getting to the locked resources. Since the username and passwords are passed unencrypted across the network, anyone can capture this data using a packet sniffer. Also, once a user has been authenticated, they will remain so until the browser is closed. You cannot force a login every time a resource is requested.

Have a look here for a good discussion of user authentication using the .htaccess and httpd.conf files.

PHP configuration

Some ISPs do not provide access to the php.ini file for custom PHP configuration. Fortunately, some PHP directives can be set in a .htaccess file. A directive can be changed in the .htaccess file if the Changeable property is set to PHP_INI_ALL.

If the PHP directive is boolean, you use a php_flag directive to set it, e.g. php_flag display_errors offFor other values , use the php_value directive in the .htaccess file. php_value error_log "../error_log.txt" Some things you might want to do include making your site more secure, enabling logging of errors, and specifying the file to use for logging errors. Below is an example of a set of directives to do just that: #This specifies the full path for the error file
php_value error_log "/home/john/log/error_log.txt"

#This defines the directories to look for include files
php_value include_path ".:/usr/lib/php:/usr/john/html/inc"

#Strict error reporting
php_value error_reporting 2047

#Improve site security
php_flag magic_quotes_gpc off
php_flag display_errors off
php_flag log_errors on
php_flag register_globals off