Chapter 6. .htaccess files—Per-Directory Configuration

 

And everyone said, “If we only live, We too will go to sea in a Sieve—To the hills of the Chankly Bore!”

 
 --The Jumblies—Edward Lear

When you have multiple people managing different parts of your Apache server, it is often very useful to be able to give each person the ability to configure the particular directories for which they are responsible. This can, of course, be done with directives contained in <Directory> sections. However, it is often desirable to restrict the number of people that have direct access to the main server configuration file.

.htaccess files, described in this chapter, give you the ability to allow this sort of per-directory configuration without giving access to the main server configuration file, and without having to add directives for everyone, each time they want something changed.

A .htaccess file can be placed in any directory on the server, and may contain almost any configuration directive. The directives in each file apply to resources served out of that directory, and any subdirectories thereof, unless they are further overridden by directives appearing in other .htaccess files within deeper subdirectories.

Finally, directives in .htaccess files take effect immediately, as opposed to restarting your server for them to take effect, as is necessary for changes to the main server configuration file(s).

However, there are tradeoffs associated with using .htaccess files, and you should make sure that they are actually needed on your site before you put a lot of your configuration into them.

AccessFileName

Although the filename .htaccess will be used throughout this chapter, and in the rest of this book, to indicate the file in which you put per-directory configuration directives, this filename is configurable, using the AccessFileName directive. This directive appears in the main server configuration file, and tells Apache what files to look in for per-directory configuration directives.

The default value for this directive is .htaccess. However, on Microsoft Windows, where filenames starting with a dot are problematic, the directive should be given the value of htaccess, or some other file without a leading dot.

You can set this to whatever value you like, if there is some name that you find to be more intuitive. For example, if you would prefer to call your per-directory configuration files directory.conf, the following directive would let you do this:

AccessFileName directory.conf

You will notice, if you look at the documentation for this directive, that it is possible to set more than one filename to be used for per-directory configuration. Just because it's possible doesn't mean it's a good idea. Setting multiple values for this directive should be avoided for two reasons.

First and most importantly, it's confusing. If there are two (or more) possible files in any given directory where directives can be lurking, it will take longer for you to find that rogue directive that is causing undesired or unexpected results on your server. Likewise, if you are working in one file, but there are conflicting directives in the other file, then you might spend unnecessary time trying to figure out why your configuration is producing unexpected results.

Secondly, as is explained in more detail in the “Performance” section, looking for, and parsing the contents of .htaccess files takes time. And doubling the number of possible locations of .htaccess files by giving it two names to look for, rather than just one, will cause Apache to spend twice as much time looking for these files than it would with just one, even if you are not using any per-directory configuration files.

AllowOverride

Because this feature allows anyone with write access to any directory served by your Web server to make configuration changes, you will be glad to know that you can limit what you permit these files to override.

The AllowOverride directive can have one or more of five possible values, specifying what category of directives will be permitted in the files. In addition to these limitations, the documentation for each directive indicates the contexts it is permitted in, and this will specifically indicate whether that particular directive is permitted in .htaccess files.

The syntax for this directive is as follows:

AllowOverride All|None|directive-type1 [directive-type2] [directive-type3] etc

The possible directive types are detailed in the following sections.

AuthConfig (Authentication)

AllowOverride AuthConfig

The presence of the previous directive will allow use of the authorization directives (AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, and so on) in .htaccess files. These directives are covered in more detail in Chapter 21, “Authentication, Authorization, and Access Control,” but an example follows.

To require password authentication in a particular directory, you might add the following to a .htaccess file in that directory:

AuthType Basic
AuthName admins
AuthUserFile /usr/local/apache/secure/passwords
AuthGroupFile /usr/local/apache/secure/groups
Require group admin

If AuthConfig is not one of the directive types permitted by your AllowOverride directive, directives that fall into this category will be ignored.

FileInfo

AllowOverride FileInfo

The presence of the previous directive will allow use of the directives controlling document types (AddEncoding, AddLanguage, AddType, DefaultType, ErrorDocument, LanguagePriority, and so on) in .htaccess files.

You can learn more about the directives that fall into this category in Chapter 8, “MIME and File Types.” An example of how this might be used is shown here.

To specify the error document for a particular directory, you might add the following to a .htaccess in that directory:

ErrorDocument error.html

(See Chapter 9 for more information on the ErrorDocument directive.)

Indexes

AllowOverride Indexes

The presence of the previous directive in your server configuration file will allow the use of the directives controlling directory indexing (AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, and so on) in .htaccess files.

Chapter 11, “Directory Indexing,” covers the use of these directives in more detail. These directives are primarily used when there is no index file in the directory, and Apache automatically generates a directory listing. The DirectoryIndex directive, on the other hand, tells Apache which file to use as the default for a particular directory, when there is no filename specified.

The following example sets the default file for a particular directory to something other than what is configured for the rest of the server.

DirectoryIndex menu.shtml

Placing the previous directive in a .htaccess file in a particular directory will cause that file to be displayed when no other file has been specified.

Limit

AllowOverride Limit

The presence of the previous directive in your server configuration file will allow use of the directives controlling host access (Allow, Deny, and Order) to be used in .htaccess files.

For example, in a directory containing documents internal to your company, you might want to restrict access to hosts within your own network. This could be accomplished with the following directives, placed in a .htaccess file in that directory.

Deny from all
Allow from yourcompany.com
Order Deny,Allow

See Chapter 21 for more detail about using these types of directives.

Options

AllowOverride Options

The presence of the previous directive in your main server configuration file allows use of the directives controlling specific directory features (Options and XBitHack).

XBitHack turns on (or off) the capability for Apache to determine what files to parse for SSI (Server Side Include) directives. This functionality will be discussed in detail in Chapter 16, “Server-Side Includes.”

The Options directive is rather powerful, turning on or off a variety of different behaviors such as CGI execution, SSI, directory indexing, and following symbolic links. The directive itself is discussed in Chapter 4, but is mentioned in many other places because of its widespread effects. Consider carefully before permitting this functionality in .htaccess files.

All

AllowOverride All

The previous directive will enable all the previously listed categories of directives in .htaccess files.

None

AllowOverride None

The previous directive will cause Apache not to honor any directives placed in .htaccess files. In fact, it will cause Apache to not even look for these files. This has performance implications. See the section on Performance for more details.

Caveats and Limitations

Use of .htaccess files has two primary consequences, which you should carefully consider before allowing their use: performance and security.

Performance

To understand the performance impact of .htaccess files, you need to know a little about how they work.

When a client requests a resource from your server, that resource request is mapped to a directory path, or perhaps to some nonfile resource. If the target of the request is a file living in a directory, Apache then has to determine what additional configuration directives, if any, apply to that directory, and perhaps also to that particular file. The main server configuration file has already been parsed, and that configuration information is stored in memory. Therefore, this can be very quickly checked for references to the affected directory and/or file.

However, if the use of .htaccess files is enabled, there's another step that must be taken. For each directory along the path to the file, Apache has to check for a .htaccess file. Remember that .htaccess files apply not only to the directory they are in, but also to all subdirectories thereof. Therefore, to know what has to be applied to a particular directory, you have to check all parent directories, all the way to the root.

For example, if you are serving a file out of /usr/local/apache/htdocs/products/watchers, Apache has to check for following files:

/.htaccess
/usr/.htaccess
/usr/local/.htaccess
/usr/local/apache/.htaccess
/usr/local/apache/htdocs/.htaccess
/usr/local/apache/htdocs/products/.htaccess
/usr/local/apache/htdocs/products/watchers/.htaccess

Apache checks for the existence of each of these files, in that order. If it finds one of these files, it opens it and parses it for directives. If not, it moves on. It does this every time a file is requested out of any directory in which .htaccess files are permitted. Note that it does this whether or not there are any .htaccess files in any of those directories, so you pay this penalty even if you don't have any .htaccess files. As you can imagine, this slows things down.

It is therefore preferable, if it's at all possible, to set AllowOverride none and put any per-directory configurations inside of the <Directory> sections in your main server configuration file.

Security

When you allow per-directory configuration, you're allowing whoever has write access to directories on your server to affect the behavior of your Apache server. A few security considerations go along with this.

For the most part, the people that have access to make these configuration changes can only make changes that affect things in their own directory. In a sense, they can only screw up their own stuff. However, this is not true for several reasons.

Insufficient Directory Security

First, it is likely that you have directories on your server that are insufficiently secured. This is particularly going to be the case if you have multiple people providing content for your server. File and directory permissions might be a little relaxed so that more than one person can modify the content. Yes, you should use user groups for this, rather than making the files world-writable, but perhaps you were a little sloppy with a directory or two. You've now made a situation where someone can come in and add a .htaccess file to change the behavior of files served out of that directory. Whether this is done in malice, as a practical joke, or for some other reason, it can result in a denial of service by making files load with incorrect MIME types, redirecting content to other locations, or other configuration changes.

The solution to this problem, of course, is to be vigilant about security. You need to read Chapter 19, “Apache Security,” and you need to make sure that any new directories that are created have reasonable file permissions on them. This can best be accomplished by a nightly cron job that sets the permissions to what they should be.

CGI and SSI

If you allow AllowOverride Options, your users have the ability to add Options ExecCGI and Options Includes. These two abilities—to execute CGI programs and to have Server Side Includes (SSI) in their files, are potentially pretty big security problems. So, be very cautious about allowing Options in your AllowOverride policy.

CGI programs can contain any code whatsoever, and can potentially do malicious things. You are somewhat saved by the fact that CGI programs are run (usually) as the “nobody” users, or some other unprivileged user, but even that user can do a lot of damage doing a rm -rf / [1] because there are always a number of files with world-writable permissions.

Likewise, SSI can execute arbitrary code, with the added benefit that with the #exec cmd syntax you can embed arbitrary system commands in the HTML and have them executed.

See Chapter 15, “CGI Programs,” and Chapter 16, for more information about the capabilities of these two options, and how to be more careful about security issues.

More importantly, if your users don't really need to be able to do these things, don't enable AllowOverride Options. If users really need this functionality, still don't enable it. In your server configuration file, simply enable Options ExecCGI for perhaps one directory that only trusted users have access to. You can also enable a tamer version of Includes by enabling Options IncludesNOEXEC in your configuration file. As the name implies, this enables SSI, but does not enable the use of the #exec directive.

Symlinks

For Windows users, this is not an issue. For most other operating systems, symbolic links are not, by default, followed by Apache. That is, if you have a symbolic link to a directory, within a directory you're serving content out of, Apache will not allow retrieval of content out of that directory. This is for security reasons.

If, for example, you were to create a symbolic link to /etc, within your document directory, then anyone could happily download /etc/passwd or /etc/shadow, and crack your passwords at their leisure. That would not be desirable.

However, with Options FollowSymlinks turned on, Apache will follow symlinks quite happily. Although there are cases where this is useful, you don't generally want nonadmin users to add Options FollowSymlinks to their .htaccess file and be able to then serve your entire hard drive on their Web site.

As with CGI and SSI, the solution to this is to not allow Options to be overridden. If there is some reason that users really do need to follow symlinks in their file space, you can add, in your main server configuration, an Options SymlinksIfOwnerMatch directive. This allows Apache to follow symlinks, if and only if the directory or file it is linked to is owned by the same user as the link itself.

Summary

.htaccess files allow users to set per-directory configurations without modifying the main server configuration file. This is handy on sites where users are running content out of their home directory, or any other situation where you have more than one person providing content on a Web site. They should, however, be avoided if they are not actually necessary, because there are performance and security concerns with using them.



[1] Windows users, think format c: -y -y

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset