oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Apache Web-Serving with Mac OS X, Part 6
Pages: 1, 2, 3

Hostname or IP Access Control

The following lines load this module:

    LoadModule access_module      libexec/httpd/
     AddModule mod_access.c

The access module controls who can visit your Apache Web server, and we gave a few examples of doing so at the end of Part 3. Past what we've talked about, there's not much more to discuss, except for the following powerful collaboration.

A little bit later, we're going to talk about "environment variables." An environment variable is just a magical term for floating bits of data passed around every time Apache serves a Web page. For instance, when you access this site using a browser, an invisible piece of data named HTTP_USER_AGENT is created. This HTTP_USER_AGENT contains a value, like "Internet Explorer" or "Mozilla" or "Opera" or what have you. Below, I've included some common environment variables and what they could be assigned:

    HTTP_USER_AGENT = Mozilla/4.0 (compatible; MSIE 5.0; Mac_PowerPC)
    REMOTE_ADDR     =
    REQUEST_URI     = /cgi-bin/printenv

Astute readers may remember running a script called test-cgi back in Part 2, which actually prints out a number of common environment variables. To see a full list created during each and every browser request to your local Apache server, run the printenv script by going to

You're asking why all this matters. Well, with an Apache module called mod_setenvif (which we'll describe more in-depth later), you can create your own environment variables. I hear your shouts of "So!?" I know. Bear with me.

By creating your own environment variables, you can use the Allow and Deny directives from mod_access to restrict visitors based on more than just IPs or hostnames (as we've previously demonstrated). Let me show you an example:

    SetEnvIfNoCase User-Agent "^EmailWolf" shelbyville

    <Directory /Users/multar/Sites>
       Order Allow,Deny
       Allow from all
       Deny from env=shelbyville

With the above simplicity, we're now denying access to our site from any User-Agent with the name "Email Wolf." This User-Agent, along with many others, is often labeled a "bad robot" as it sniffs around for email addresses to add to spam databases. Here we're detecting whether the access is coming from a known bad bot, and if so, we set an environment variable named shelbyville. Our Deny from env=shelbyville says, "Hey! If there's an environment variable named shelbyville, deny them access!"

We'll explain the SetEnvIfNoCase line more in the next article, but you can read more about stopping email harvesters with's Using Apache to Stop Bad Robots, and the sequel, Stopping Spambots II: The Admin Strikes Back.

Username-Based Access Control

The following lines load this module:

    LoadModule auth_module        libexec/httpd/
     AddModule mod_auth.c

You'll remember mod_auth from Part 4 of our omnibus, where we chatted about password protecting certain directories. We walked through creating an .htpasswd file, which contained all our usernames, and then we created an .htaccess file like so:

    AuthName "Uber Goober Ad Campaign"
    AuthType Basic
    AuthUserFile /Library/WebServer/.htpasswd

    Require valid-user

With the above .htaccess file sitting in a directory, we're restricting access to that directory with a password. If any valid-user from the AuthUserFile enters the correct username and password, then we let them in -- everyone else is denied. As in our previous article, if you want to use features like AuthGroupFile or the other require directives, then I'm going to push you rudely to Apache's Web site -- they give a decent tutorial there.

There are two more authentication modules related to mod_auth, and they're normally commented in your Apache configuration file. The relevant lines look like so:

    #LoadModule dbm_auth_module    libexec/httpd/
    #LoadModule digest_module      libexec/httpd/
     #AddModule mod_auth_dbm.c
     #AddModule mod_digest.c

We won't be touching on these here -- they're commented for a reason. Most of the time, if you have special needs for authentication involving different file structures, this is where you'd look. The module mod_auth_dbm covers storing the password information in a DBM file, whereas module mod_digest "implements an older version of the MD5 Digest Authentication specification which will probably not work with modern browsers."

There may be some interest in anonymous access control, though. This feature allows you to "authenticate" users, but to do so without knowing who the user is. You can use anonymous control in conjunction with other access control methods (like Allow, Deny, and AuthUserFile).

Why would you want something like this? Perhaps you've got a large amount of documents you don't want indexed by search engines -- you could try a robots.txt file, but some engines don't listen to them. With anonymous access control, you can allow anyone who'll take the time to read your directions.

The actual module lines for anonymous access control are commented in your configuration file, so to follow along with these examples, you'll need to uncomment them and then restart Apache. I also assume you're throwing the examples in an .htaccess file (instructions on how to use .htaccess files are in Part 4). The module lines look like so:

    #LoadModule anon_auth_module   libexec/httpd/
     #AddModule mod_auth_anon.c

With the above uncommented and Apache restarted, plop the following into your .htaccess and save to the directory you want to protect (I'll save my copy into /Users/deedee/Sites):

    AuthName "anonymous/your email"
    AuthType Basic
    Require valid-user

    Anonymous orko bender
    Anonymous_Authoritative on

Previously in the Series

Apache Web-Serving with Mac OS X: Part 1

Apache Web-Serving with Mac OS X: Part 2

Apache Web-Serving with Mac OS X: Part 3

Apache Web-Serving with Mac OS X, Part 4

Apache Web-Serving With Mac OS X, Part 5

You should recognize the first three directives, as they're typical to what we've seen before (before we gave AuthType a whimsical name -- in this case, we're using it as mini-instructions for the visitor). The Anonymous directive controls what usernames should be considered "anonymous" -- in this case, we've got "orko" and "bender," but we could just as easily have chosen "overtkill," "charizad," and "slimer" too.

The Anonymous_Authoritative controls whether we want to pass unauthorized usernames and passwords off to another authentication scheme for processing. If we say "on," then anonymity is king -- either the visitor logs in with "orko" or "bender" or they're not allowed access.

On the other hand, if we say "off" then we can add in some of what we already know -- authentication via passwords. Take a look at the configuration below. If the user does not log in with "heenie" or "retrogirl" then the username is passed off to the AuthUserFile, where it's also checked against. If it doesn't exist in that file either, then the user is denied.

    AuthName "anonymous/your email"
    AuthUserFile /Library/WebServer/.htpasswd
    AuthType Basic
    Require valid-user

    Anonymous heenie retrogirl
    Anonymous_Authoritative off

As is typical, you can be as serene or as complicated as you want. The following configuration will allow any user to get a directory listing. Any user listed in the AuthUserFile can get access to all .jpg files, as well as any anonymous user logging in with "mrs_decepticon" or "spiderj" assuming they enter a valid email address (one with a "@" and "."). Finally, only the "eustace" user can download MP3 files:

    AuthType basic
    AuthName "anonymous/your email"
    AuthUserFile /Library/WebServer/.htpasswd

    Anonymous mrs_decepticon spiderj
    Anonymous_Authoritative off
    Anonymous_VerifyEmail on

    <Files *.jpg>
       Require valid-user

    <Files *.mp3>
       Require user eustace

You can, of course, get even more convoluted, restricting by IP address or hostname, environment variables, and "oh, the madness!" Just make sure you comment your craziness -- it's certainly easy to get confused as to who has access to what.

Huh? What's That Noise?

Something startles you out of your reverie -- a rather rude employee down the hall slamming doors or doing some other bit of mundania. Shaking your head and murmuring about "15 minutes to get back to the zone," you stand up to stretch your unused limbs of movement. Some ornament on the wall blinks and jumps off a badly painted cliff. You can't believe the time -- not even half the day has gone by.

With your module exploration nearly finished, you figure you'll be done by the end of the workday. Keep watch for "Apache Web-Serving with Mac OS X, Part 7," where we'll finish our spelunking and increase our Web-serving knowledge in places where most haven't delved.

If you're feeling especially adventurous, hunt down the 20 comic book and cartoon characters spread throughout this article. Each character is from a comic book or cartoon I personally read or watch (some easy, like "scary godmotherish" being from Jill Thompson's "Scary Godmother"; some delightfully esoteric). Your task: identify which book or show they come from. The person who emails me the most correct entries will be mentioned in the next article, as well as receiving something random in the mail from yours truly. Good luck!

Kevin Hemenway is the coauthor of Mac OS X Hacks, author of Spidering Hacks, and the alter ego of the pervasively strange Morbus Iff, creator of, which bills itself as "content for the discontented."

Return to the Mac DevCenter.