Unix Insider –
Last month we continued our exploration of Web server security, laying out the details of directory-level access control based upon the client name or IP address. This month, we'll close out the series on security by looking at the next higher layer of access control: password protection.
Explicit Access Control
Sooner or later, someone will approach you and ask about individual access to the documents on a Web server. Usually, someone is excited about using the Web for information dissemination, but has documents that are not for general consumption. Financial reports come to mind, or design documents that you don't want to fall into a competitor's hands.
For these documents, address-based security is not sufficient. IP addresses can be spoofed, and more importantly, address-based security is only as good as the security of the device with the desired address. If you restrict access to a specific machine based upon its IP address, but that machine is located in hallway where anyone can walk up and use it, you have no security at all. Even in more secure areas, someone could duck into an unused office for ten minutes, download all sorts of things to a floppy and walk away undetected.
To avoid these scenarios, you can take advantage of the password protection features supported by most servers, more formally known as server-based user authentication.
The password protection model for servers like NCSA httpd or the Apache server is fairly straightforward. Using our old friend, the
<font face="Courier"><limit></font>directive, in conjunction with a few new directives for your
<font face="Courier">.htaccess</font>file, you can quickly build access control lists for all of your documents.
Before forging ahead, let's review what we covered in June and July. Server-wide access control is defined in your server's
<font face="Courier">access.conf</font>file, using the
<font face="Courier"><limit></font>directive to define who is allowed to visit your site. For more fine-grained control, you can place these same directives in a file named
<font face="Courier">.htaccess</font>in any directory on your server to manage access for just that directory and any subdirectories within it. So far, we've learned that the
<font face="Courier">deny</font>, and
<font face="Courier">order</font>directives let us control access based on the client's domain name or IP address.
Got that? Good.
The httpd password model closely parallels the Unix password scheme. That is, you can define individual users who are given access to a set of documents, and you can define groups of users to be granted access. Two files, one containing the users and another containing the groups, are needed for each directory you want to protect.
A simple example
The easiest way to see how password protection works is to look at a simple example.
Suppose we have a directory whose contents are to be restricted to three users: larry, curly, and moe. As a first step, within this directory, create a
<font face="Courier">.htaccess</font>file that looks like this:
<font face="Courier"> AuthUserFile /someplace/else/htpasswd AuthGroupFile /dev/null AuthName Stooges AuthType Basic <limit> require user larry curly moe </limit> </font>
Yikes! What does all this mean? Don't panic; it all makes sense:
<font face="Courier">AuthUserFile</font>is the full pathname of the file containing the password entries for your authorized users. You should keep this file in some directory other than the document directory; otherwise, someone could download your password file and attempt to crack your passwords. We'll see how to create this file a little later.
<font face="Courier">AuthGroupFile</font>is not needed nere, so we set it to
<font face="Courier">AuthName</font>defines the name of the security realm for these documents. This name may be presented to the user by the browser when they are prompted for the password, and it is often cached by the browser so that a user need not be prompted more than once for the same password for other documents in the same realm. Use some name that indicates to the user the scope of these documents.
<font face="Courier">AuthType</font>defines the type of authentication being performed. Depending on your server, you may have many choices. The most common and widely supported is
Once this file is in place, any reference to a document in this directory will cause the user to be prompted for a password. The user will enter a user name and password, which will be sent to the server. The server will see if the username is defined the
<font face="Courier">AuthUserFile</font>, verify that the password is correct, and finally check to make sure that the user name is either "larry", "curly", or "moe". If all three tests succeed, the user is granted access.
The only remaining step is to define the entries in the password file. To accomplish this, most servers come with a utility, usually named htpasswd, that creates entries in the file.
To create the first entry in the file, use htpasswd with the
<font face="Courier"> htpasswd -c /someplace/else/htpasswd larry </font>
You'll be prompted for larry's passwd. When the command is complete, the file will be created with an entry for larry. To add the remaining users, drop the
<font face="Courier"> htpasswd /someplace/else/htpasswd curly htpasswd /someplace/else/htpasswd moe </font>
When you're finished, the file will look something like this:
<font face="Courier"> larry:asy7Gtf56dgu1j curly:wIO98s.weru7ew moe:qwlm.7d56sANkdss </font>
The first field is the user name, of course; the stuff after the colon is the encrypted password.
That's it! Your password-secured directory is ready to go!
Working with groups
One way to limit access to a group of users is to list all their names in the
<font face="Courier">require user</font>directive. This can get tedious, so it makes more sense to define a group of allowed users instead. You do this by using a
<font face="Courier">require group</font>directive, naming the group(s) that are granted access to the directory. This is exactly the same as our previous example, but uses a group instead of an explicit user list:
<font face="Courier"> AuthUserFile /someplace/else/htpasswd AuthGroupFile /someplace/else/htgroup AuthName Stooges AuthType Basic <limit> require group stooges </limit> </font>
Using any text editor, create
<font face="Courier">/someplace/else/htgroup</font>to contain
<font face="Courier"> stooges: larry curly moe </font>
When authentication occurs, the server will verify that the user name and password are valid, and then will check to see that the user name is in the group named
<font face="Courier">stooges</font>. It's much easier to manage membership in the stooges group by editing the
<font face="Courier">htgroup</font>file than it is to edit the
<font face="Courier">.htaccess</font>, especially if you have several directories all restricted to access by the stooges. Most importantly, the group file can be maintained by someone who does not have the ability to write into the document directory, allowing you to separate the security management and content management responsibilities within your server.
Keep in mind that you can mix and match all the directives in a
<font face="Courier"><limit></font>directive. Thus, you can use password protection and domain protection together:
<font face="Courier"> AuthUserFile /someplace/else/htpasswd AuthGroupFile /someplace/else/htgroup AuthName Stooges AuthType Basic <limit> order deny, allow deny from all allow from .mycompany.com require group stooges </limit> </font>
For this directory, users must not only offer up the name of a stooge and a valid password, they must also be connecting from a machine within the
Web passwords & Unix passwords
An important point to remember is that, although they look and operate in a similar manner, there is no connection between Web user names and passwords and Unix user names and passwords. It is a common misconception among novice webmasters that a user must have an account on the Web server before they can take advantage of password authentication. This is completely false. You can define thousands of Web users in your
<font face="Courier">htpasswd</font>file without ever creating a single extra Unix account.
That said, you should know that the password encryption scheme used by htpasswd is the Unix password encryption algorithm. This means that you can create entries in your
<font face="Courier">htpasswd</font>file by cutting and pasting the first two fields of any entry in your Unix password file into your
<font face="Courier">htpasswd</font>file. This is really convenient if you are creating a secure directory intended for use only by the users on a machine; you can set up the password protection by copying entries from the Unix password file to your
<font face="Courier">htpasswd</font>file and tell your users to use the same user name and password that they use to log onto the machine. Of course, if a user changes their Unix password, the corresponding Web password will not be changed automatically.
This concludes our three-part series on server security. Hopefully, you've been implementing all this as we've gone along and now have a secure server, safe from prying eyes and delivering documents only to those who are intended to see them. If you'd like to see more detailed information on password protection, visit the NCSA User Authentication Tutorial.
All this security is important, because next month we're going to turn to a much more interesting aspect of server management: making money with your server. Just to make sure you come back, I'll make a simple promise: next month, I'll provide a single line of HTML you can add to any document on your site that could earn you hundreds or even thousands of dollars each month. Too good to be true? Check back in September and see for yourself!