Basic Access Control with Apache


Certain parts of your website will almost certainly need to be protected from being viewed by the general public; access control allows you to restrict these sections to authorized users either by hostname/IP address or by password authentication. We'll take a look at both of these methods.

Access Control by Address

Let's say you want to restrict a certain file, directory, or set of files and directories to a short list of fixed IP addresses or hostnames. You can do this at the global (httpd.conf) level if you have a permanent area of your site (such as a set of administration scripts) that you want to keep secure; or more efficiently for regular users or for temporary private resources, you can use an .htaccess file in any directory at or above the level of the items you want to protect.

Begin by making sure that .htaccess overrides are enabled in the part of the site that you want to protect. As you saw earlier, you can use AllowOverride Limit, at the /usr/local/www/data level or further down in the directory structure with another <Directory> container, to enable the use of the access-control directives Allow, Deny, and Order. Because Apache directives are all read in at the same time, you need to specify the order in which to read the Allow and Deny directives; otherwise, they'll override each other in ways you don't intend.

To close off a directory to everyone but certain specified addresses or hostnames, put an .htaccess file in that directory with the following contents:

Order deny,allow Deny from all Allow from 64.41.131.102 Allow from stripes.example.com Allow from nowhere.com Allow from 10.5.100 Allow from 10.67.22.211/255.255.255.0


As you can see, a number of different address formats are allowed; these are just matching rules, where if the connecting host matches any of these hostname or network patterns, it will be allowed access. Similarly, you can have the directory open to everybody except certain hosts:

Order allow,deny Allow from all Deny from l33t.hacker.com Deny from 192.168


You must place these commands inside a <Directory> or <Location> block if you're doing this in httpd.conf; you can also use <Files> or <FilesMatch> to list certain files, wherever in the system they might be, which should be subject to the access control:

<Files "*.jpg">   Order deny,allow   Deny from all   Allow from 64.41.131.102 </Files>


FilesMatch can be used to specify filenames matching regular expressions, as in this example, which would match all .gif, .jpg, .jpeg, and .png files:

<FilesMatch "\.(gif|jpe?g|png)$">   Order deny,allow   Deny from all   Allow from 64.41.131.102 </FilesMatch>


Note, however, that <Directory> and <Location> are not available in .htaccess files.

The <Limit> block, despite its name, is not required for the preceding access controls to work. Rather, its purpose is to list certain access methods to which the access controls should apply. For instance, you might choose to limit only GET and POST but leave all other methods unrestricted. Likewise, you could use <LimitExcept> to specify the only methods to which the access controls should not apply. You saw an example of this earlier, in the commented-out block controlling user directories within /home.

Caution

Access restriction by address is prone to failureIP addresses can be forged by a sufficiently determined attacker. What's more, a failure to detect a forged address is transparent and all but untraceable; if you use passwords instead, there's a dialogue that can be logged with much greater detail. Opt for password-based access control rather than address-based whenever possible.


Access Control by Password

Sometimes, it's not practical or desirable to limit access by address. A privileged portion of your site might be made available to registered users who have paid a fee, for example, and these users might not come from predictable IP addresses. This is where it's much more sensible to use password authentication for access control.

Apache stores its own username and password databases, distinct from the systemwide one in /etc/master.passwd and its relatives. This is for security purposes, and it's an extremely bad idea to try to merge the two authentication schemes together, so don't even think about it. The FreeBSD password database is for authenticating shell users who actually have an account on the system, whereas the Apache authentication databases control access to certain parts of your website for web surfers. You might have a situation in which these two areas of functionality overlap (such as an intranet server for a company), but don't be tempted to try to serve both from the same database. If you succeed, it will be a study in insecurity and irresponsible system administration techniques. This practice is explicitly discouraged by the Apache Group and will earn you a great deal more scorn than respect from your peers. It's not worth it.

To password-protect a portion of your website, you'll need to use an .htaccess file (or equivalent configuration in httpd.conf)including the appropriate use of <Directory>, <Location>, and <Files> blocksjust as with per-address access control. The contents of this file or configuration block are considerably different, though, involving an entirely different module in Apache to do the access control. A simple example of such a block follows:

AuthType Basic AuthName "Restricted Area" AuthUserFile /usr/local/www/.htpasswd Require valid-user


This example includes the minimum number of directives needed to make password-protection work; each of these directives, or their alternatives, is required. These directives are a little confusing, so let's look at them individually:

  • AuthType This can be either Basic or Digest; Basic is the only one that really concerns us.

  • AuthName This is just a name for the "realm" or the area you're protecting. This name pops up in the authentication window in the user's browser (for example, "Enter username for 'Restricted Area' at www.example.com"), helping to tell the user which area he is entering and which username and password are needed. This can be anything you want, except it must be enclosed in quotes if there are spaces in the name.

  • AuthUserFile, AuthDBUserFile, and AuthDBMUserFile One of these directives must be present to specify the location of the file that contains the user/password database for the realm. (Each realm can have a different user database file if you like.) If it's a pure text file, use AuthUserFile; if it's in db or dbm format for lookup speed purposes (a good idea if there are a lot of users in it), use AuthDBUserFile or AuthDBMUserFile accordingly. We'll cover how to create plain-text or db/dbm user databases in a moment.

  • AuthGroupFile, AuthDBGroupFile, and AuthDBMGroupFile These directives work in the same way as the AuthUserFile ones, except that they specify groups of users from the file indicated with AuthUserFile, allowing you to restrict access to a group rather than just to certain users. This directive isn't required, but if you do use it, an AuthUserFile directive or equivalent (and associated user database file) needs to be present for its users to be recognized as part of the listed groups.

  • Require This tells Apache how to authenticate the user. The argument can be valid-user (any user present in the AuthUserFile file who enters the correct password), user <username> <username>... (a list of users), or group <groupname> <groupname>... (a list of groups).

Adding Users

After you have the access control block set up and apachectl configtest reports that the configuration is okay, it's time to add users. First, let's see how to make a plain-text user database, the kind for which you'd use an AuthUserFile directive. The command to use is htpasswd, which in FreeBSD is in /usr/local/bin and therefore part of your path:

# htpasswd -c /usr/local/www/.htpasswd frank


Note

The -c option is only necessary the first time you run htpasswd; this tells the program to create the file (because it doesn't exist yet), and you can omit the -c option every subsequent time.


You will then be prompted for the user's password, which you must enter twice (as usual). To do this in a script, you can use the -b option and specify the password as another argument:

# htpasswd -bm /usr/local/www/.htpasswd joe Pr1d3L4ndz


The other option used here is -m, which causes htpasswd to use an MD5-based encryption algorithm rather than the system's crypt() routine; this may provide you with better security. Other options can be found in the man apachectl page.

Caution

The user database file can be placed anywhere in the system that the web server user (nobody) can read, and it can be named anything you want, although having the name begin with .htpasswd (for example, .htpasswd-restrictedarea) is traditional and protects it from being viewed in directory listings, either on the shell or via the web server. However, it's a very bad idea to put the file anywhere where it can be accessed by a user with a web browser! To wit, don't put it anywhere inside /usr/local/www/data or in any user's public_html directory; instead, use web-inaccessible locations such as /usr/local/www or directly inside a user's home directory. You don't want people downloading your user database and cracking it!


Plain-text user databases work great for small lists of users; however, once you start working with dozens or hundreds of users, the time it takes to look up a user's password makes the authentication process cumbersome or even nonfunctional. The solution to this is to use a true database file, either in db or dbm form, and to use the appropriate AuthDBUserFile or AuthDBMUserFile directive in your access control block. The support program that allows you to work with the database files is /usr/local/bin/dbmmanage:

# dbmmanage /usr/local/www/.htpwddb adduser frank New password: Re-type new password: User frank added with password encrypted to NtMDxy6jwyW7A using crypt


This example will create a db-style database file called /usr/local/www/.htpwddb, which you can then specify with the AuthDBUserFile directive. The dbm equivalent can also be used if necessary, but you shouldn't have to. See man dbmmanage for further details on the user management commands you can use.

Adding Groups

Listing groups in a plain-text file (AuthGroupFile) is quite easy. Each line contains the group name, a colon, and then the list of users in the group:

mygroup: frank joe alice


The group file should probably be kept in the same place as the user file, and with a similar name; however, because the group file doesn't contain any passwords, security considerations aren't quite as critical. Just make sure that only root has the ability to write to the file!

Group files can be managed with dbmmanage as well, but this practice is usually unnecessary because (as with /etc/group) there are seldom anywhere near as many groups as there are users. You can use AuthGroupFile in conjunction with AuthDBUserFile if you want to mix formats; this is probably the simplest way to maintain a large user list along with a small group list.

Access Control by Address and Password

It's possible to require that a user satisfy both host address restrictions and password authentication before access control allows access to a restricted area. This is done with the Satisfy directive:

Allow from 64.41.131.102 Require valid-user Satisfy all


Satisfy all is the default setting if both Allow and Require directives are present; this behavior means that the incoming user must meet the Allow requirements and supply a valid username and password before access will be granted. You can also use Satisfy any to tell the server that the user must supply a valid password or be coming from an allowed address; this is useful if you want users at certain locations to have unconditional access to an area, but require authentication from all other users (for instance, if you're providing a service that you must administer through the same interface as every other user, but you don't want to be forever entering passwords for access).




FreeBSD 6 Unleashed
FreeBSD 6 Unleashed
ISBN: 0672328755
EAN: 2147483647
Year: 2006
Pages: 355
Authors: Brian Tiemann

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net