The Directory/Location Context Model & .htaccess In Depth

Apache In Depth

Chapter 3 · The Directory/Location Context Model & .htaccess In Depth

Web Servers Fundamentals Chapter 3 introduced .htaccess conceptually: a per-directory override file, checked on every request, with a real filesystem-scan cost in exchange for letting someone without access to the main config make changes. This chapter goes deep on the two things that actually determine what a given .htaccess file can do and how it interacts with everything else: AllowOverride's real granularity, and the actual merge order across every context type Apache supports.

AllowOverride: What .htaccess Is Actually Allowed to Touch

<Directory "/var/www/html"> AllowOverride None </Directory> <Directory "/var/www/html/blog"> AllowOverride AuthConfig FileInfo </Directory>

AllowOverride is not just an on/off switch — it names exactly which groups of directives a .htaccess file in that directory is permitted to set. None disables .htaccess checking entirely for that directory tree (and is the real fix for Fundamentals' own filesystem-scan cost, since Apache then knows not to look at all). All permits every group — broad and rarely the right default. In between, five named groups exist: AuthConfig (authentication directives — AuthType, AuthName, Require), FileInfo (ErrorDocument, and — notably — every mod_rewrite directive), Indexes (IndexOptions, DirectoryIndex, IndexIgnore), Limit (Require/Order/Allow/Deny access-control directives), and Options[=...] (the Options directive itself).

"Indexes" the AllowOverride group vs. "Indexes" the Options value — a real naming collision
AllowOverride Indexes and Options Indexes are two completely different things that happen to share a name. The AllowOverride group called Indexes controls whether .htaccess is even allowed to set directory-listing-related directives at all (IndexOptions, DirectoryIndex). The Options value called Indexes is the actual setting that turns directory listing on. Granting AllowOverride Indexes does not itself enable directory listing — a .htaccess file in that directory would still need its own Options +Indexes or Options -Indexes line, and that specific line falls under the separate Options override group, not this one.

The Real Merge Order: Directory → .htaccess → Files → Location

Apache applies contexts in a fixed order, and later contexts can override directives set by earlier ones — but this is a merge, not a wholesale replacement. Directives a later context doesn't mention still carry over from the broader context that set them. The real order: (1) the main server config and any matching <VirtualHost>, (2) every <Directory> block that matches the requested path, evaluated from the least specific path to the most specific, followed by that most specific directory's own .htaccess file (if AllowOverride permits it), (3) <Files>/<FilesMatch>, and finally (4) <Location>/<LocationMatch>.

<Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride None </Directory> <Directory "/var/www/html/private"> Options -Indexes Require ip 10.0.0.0/8 </Directory>

A request under /private merges both blocks: the more specific /private context isn't a full replacement of the parent, so FollowSymLinks is still inherited from the parent since /private never mentions it — only Indexes is actually touched, and the leading - means "remove this specific option," not "replace the whole Options list." The end result for /private is FollowSymLinks on, Indexes off, plus the new IP restriction — a genuine merge across two contexts, not the child context overwriting the parent's settings wholesale.

A Worked .htaccess Example

# Disable directory listing Options -Indexes # Custom 404 page ErrorDocument 404 /errors/404.html # Enable URL rewriting RewriteEngine On RewriteRule ^article/([0-9]+)$ article.php?id=$1 [L]

This one file actually needs two separate AllowOverride groups to work at all: Options (for the Options -Indexes line) and FileInfo (which covers both ErrorDocument and every mod_rewrite directive, including RewriteEngine and RewriteRule). A directory whose AllowOverride is set to just AuthConfig would reject every line in this file.

AllowOverride groupCoversTypical use
AuthConfigAuthType, AuthName, RequirePer-directory login restriction
FileInfoErrorDocument, all mod_rewrite directivesCustom error pages, URL rewriting
IndexesIndexOptions, DirectoryIndex, IndexIgnoreDirectory-listing appearance (not whether it's on)
LimitRequire/Order/Allow/DenyIP-based access restriction
Options[=...]The Options directive itselfTurning directory listing, symlink-following, etc. on/off
Where this points forward in this course
AllowOverride None everywhere it isn't genuinely needed is one of the standard hardening recommendations Chapter 8 covers in depth — it isn't just a performance win from skipping the per-request filesystem scan, it also closes off an entire class of misconfiguration risk from a compromised or careless .htaccess file, since there's nothing left for one to override.

Hands-On Exercises

Exercise 1

Using the two nested <Directory> blocks in this chapter's own merge-order example (Options Indexes FollowSymLinks on the parent, Options -Indexes on /private), state the effective Options settings a request to /private actually ends up with, and explain why FollowSymLinks survives even though /private never mentions it.

📄 View solution
Exercise 2

A directory has AllowOverride set to AuthConfig only, but its .htaccess file (this chapter's own worked example) contains RewriteEngine/RewriteRule and Options directives. Using this chapter's own material, explain what actually happens when a request hits that directory — not just "it won't work," but the specific real behavior.

📄 View solution
Exercise 3

Explain, in your own words, why "AllowOverride Indexes" does not by itself turn on directory listing, using this chapter's own warning box about the two different things named "Indexes."

📄 View solution

Chapter 3 Quick Reference

  • AllowOverrideNone (no .htaccess checking), All (everything), or a named group: AuthConfig, FileInfo, Indexes, Limit, Options
  • The AllowOverride Indexes group and the Options Indexes value are different things that share a name — one permits, the other enables
  • Real merge order: main config/VirtualHost → <Directory> (least to most specific) + .htaccess<Files><Location> — a merge, not a full replacement, at every step
  • A directive a .htaccess file isn't permitted to set by AllowOverride doesn't fail silently
  • AllowOverride None wherever genuinely possible is both a performance and a hardening win — expanded on in Chapter 8