Your Daily Source for Apache News and Information |
Breaking News | Preferences | Contribute | Triggers | Link Us | Search | About |
|
By In this article, I'll talk about using databases for authentication, rather than the standard text-file There are basically three reasons to use a database, rather than a text file, to store data. The first reason is speed. Accessing data stored in a database is much faster than accessing data stored in a text file. A database is designed for rapid location of information. A text file, you have to read through each record until you find what you are looking for. The second reason is ease of data retrieval. A database--at least, a decent database--provides you with a language (usually SQL) for querying the database for specific information. The third reason is data integrity. Since a database handles a lot of things for you, which you would have to handle for yourself when using a text file, you are less likely to screw up your data, and lose information, when using a real database. Why Use a Database for Authentication?All of the above three reasons are important when selecting a method of authentication on your Apache server. If you're running a site with a very small number of user accounts, it may not be worth the hassle to try to use a database for your authentication. But, as your list of users grows, these things will become real assets. As your list of users grows, it takes proportionately longer to find a given user in the password file. Past a certain number of people (about 2,000, in my experience) the look-up just takes too long. Users that are listed at the bottom of the file will just be denied access, because Apache gives up looking for them before it can get that far in the file. Managing the user lists is easier also. Rather than trying to open a large text file, and scroll through it looking for a name, you can use database queries to find the user you're looking for, and change their password, or remove them, or add a new user. If you let your users change their password, then you are at risk of corrupting your data. Consider the situation where two users try to exit their password at nearly the same time. User A loads the file into memory, and changes their password, and starts to write the file back to disk. At that moment, user B loads the file into memory to look for their password. Oops. The file has not been written back to disk yet, so user B only gets part of the file. When they write the file back to disk, most of the users mysteriously disappear. Actually, you'll (hopefully) implement some kind of file locking to avoid this completely, but using a database removes the concern completely. OK, So How Do I Do This?There are several Apache modules that let you use a database for your authentication. I'm going to talk about just two of them: mod_auth_db
If you compiled Apache with LoadModule db_auth_module libexec/mod_auth_db.so and, then ... AddModule mod_auth_db.c Otherwise (if you don't have Wait a Second--What's a DB File?Berkeley DB files are just one type of database files. They (usually) contain just key/value pairs, and so are rather limited in how much "real" database functionality you can get out of them (although there are some pretty slick extensions to them) but for HTTP authentication, a key/value pair is exactly what you want to store. If you want to read more about DB files, you should look at the Sleepycat Software Web site, at http://www.sleepycat.com/ Sleepycat maintains the DB library and has some documentation about DB. Protecting a DirectoryOnce you have compiled the AuthName "Members Only" AuthType Basic AuthDBUserFile /usr/local/apache/passwd/passwords.dat AuthDBGroupFile /usr/local/apache/passwd/passwords.dat require user rbowen Now, users accessing the directory will be required to authenticate against the list of valid users who are in A Few CaveatsWell, there are a few different ways to get usernames/passwords in the DB file. And a few caveats are necessary here. First, there are several different implementations of DB, with slightly different names. While I won't go into the gory details here (mostly because I don't know them all) suffice it to say that you may need to experiment some in order to get things working the way that you think they should. It's worth the effort, but be warned. Secondly, just to confuse things a little further (at least in my mind) on Linux, two of the implementations (DB and DBM) which are usually different on other platforms, are the same. Third, you'll find, as part of the standard Apache distribution, another module, called And, finally, because there is so much platform dependency in these DB implementations, you'll find that a DB file (or DBM file) generated on one system may or may not work on another. So, after all those caveats, you may be wondering if this is really worth it? Well, it is. These are things that might happen, but in practice (at least in my experience) seldom do. How Do I Get Users Into the File?Well, there's a tool that comes with Apache, called You'll find full documentation for If you are going to be doing more with these files, you will probably want something a little easier to automate. Perhaps the best tool for this will be Perl, using the The following Perl code, for example, will add a user use DB_File; tie %database, 'DB_File', "passwords.dat" or die "Can't initialize database: $!\n"; $username = 'rbowen'; $password = 'mypassword'; @chars=(0..9,'a'..'z'); $salt = '', map { $chars[int rand @chars] } (0..1); $crypt = crypt($password, $salt); $database{$username} = $crypt; untie %database; Passwords are stored in Unix What About Groups?In last week's article, we talked about putting users into groups and requiring a particular group of users. You can do the same thing with AuthDBUserFile /usr/local/apache/passwd/passwords.dat AuthDBGroupFile /usr/local/apache/passwd/passwords.dat The user file and group file are pointing at the same location. What's up with that? It turns out that Because DB files, as I mentioned early on in this article, just store a key/value pair, something has to be done to work around this limitation. What the authors of So, if you were still using the Perl code above, you'd replace the line: $database{$username} = $crypt; with $database{$username} = "$crypt:$group"; or something to that effect. You can specify more than one group by listing the groups, separated by commas. I'm not aware of any nice way to do this with Once you have your passwords and groups in the file, you can require a group in the regular way: require group administrators This is not the only way to do this, it's just the way that I do it. You can also have a separate group file, just like you do with regular text file authentication. If you ahve a separate group file, it would contain a list of What about Microsoft Windows?I actually don't know the answer to this one. I know that there are Windows implementations of DB files, so I don't know of any particular reason for it not to work. But I've never tried it myself. I'd love to hear from one of you telling me that you have it working on Windows, and telling me what you did to get it working. Summary
Future columnsPlease let me know if there are other topics that you'd like for me to talk about in future columns. You can send your suggestions to me at And please let me know what you think of my columns, at that same address. Many thanks for reading down this far! --Rich |
|
|
About Triggers | Media Kit | Security | Triggers | Login |
All times are recorded in UTC. Linux is a trademark of Linus Torvalds. Powered by Linux 2.4, Apache 1.3, and PHP 4 Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy. |