Hostname or IP Access Control
The following lines load this module:
LoadModule access_module libexec/httpd/mod_access.so 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 = 127.0.0.1 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
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 </Directory>
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
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 evolt.org'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/mod_auth.so AddModule mod_auth.c
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/mod_auth_dbm.so #LoadModule digest_module libexec/httpd/mod_digest.so #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
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/mod_auth_anon.so #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
AuthName "anonymous/your email" AuthType Basic Require valid-user Anonymous orko bender Anonymous_Authoritative on
Previously in the Series
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.
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> <Files *.mp3> Require user eustace </Files>
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 disobey.com, which bills itself as "content for the discontented."
Return to the Mac DevCenter.