Wednesday, March 21, 2012

Smart Access Control with Apache

The Apache web server, which celebrated its seventeenth birthday in February, continues to dominate its peers in popularity. Given its vast array of features, and even greater list of add-in modules, it’s little wonder that Apache now boasts more than 60% of the HTTP server market share, according to the latest Netcraft report. If that includes your organization, you should learn about some of the most useful and effective modules you can use to restrict access to your Apache-powered website.

No doubt the most commonly used access control method for Apache is the .htaccess file, which allows you to specify configuration options for specific directories. But it isn’t the only way, and it’s certainly not the most efficient. We’ll discuss a few modules here that you can use to better customize access restrictions for your site, so you can, for instance, deny access for three hours every Tuesday and Thursday, or deny access to everyone from a specific domain.

User Authentication with htpasswd

Let’s begin with the simplest technique first, which relies on authentication. An administrator must create a passwords file that contains a list of usernames and associated passwords. Then, when users try to access a page, they are presented with a login screen. Only users who are listed in the passwords file are allowed access; all other users are denied access.

The passwords file is independent of any other file that maintains credentials of registered users. You must create the passwords file by hand and manually provide the usernames and passwords for all the users you wish to grant access to your site. Alternatively, you can use the mod_auth_ldap module to offer authentication to your operating system’s directory service if you already have LDAP configured.

If you’re not using LDAP, use the htpasswd utility that is part of the Apache installation to create the passwords file. The location of the htpasswd utility depends on how you installed Apache – whether as an independent package or as part of XAMPP or a Bitnami stack. If you installed Apache from the software repositories of your distribution, you’ll find it under /bin; if you installed Apache using the XAMPP stack, look under /opt/lampp/.

The command htpasswd -c /opt/lampp/lib/passwords username creates the password file under /op/lampp/lib. You can place the file anywhere you like within Apache’s directory structure. You need to use the -c option only once, when you create the file. When adding more users to the file, use htpasswd /opt/lampp/lib/passwords username2. Unfortunately you have to repeat the procedure for each user manually; you can’t create a passwords file from a list of usernames.

The next step is to make Apache authenticate users before allowing access. To do this you need to edit the httpd.conf file and create a new directory block for each directory you wish to block access to. Here’s a sample directory block that uses the passwords file to allow access only to authenticated users:

AuthType Basic
AuthName "Music Lovers May Proceed"
AuthUserFile /opt/lampp/lib/passwords
Require valid-user

The most important directives here are AuthType and Require. The former defines the type of authentication you wish to use – the choices are Basic or Digest. With Basic, passwords are transmitted over the Internet unencrypted, while Digest transmits each password as an MD5 hash, which makes it more secure. The Require directive tells Apache to check whether the user should be allowed access. In the above code sample, we use Require valid-user, which means only valid users are allowed access. You can similarly use Require user username to restrict access to only the listed usernames.

Although it’s not ideal because of the performance hit, you can use .htaccess files to the same effect. Just copy the same code into an .htaccess file within the directory you wish to restrict access to. Be sure to remove the and lines from the code though, as you only need them when working with httpd.conf and not with .htaccess, because the latter controls only the directory in which it’s placed.

While effective, the technique we’ve just discussed is not the most secure, because the passwords are stored in a basic file and may be transmitted over the Internet unencrypted. You should use the more secure AuthType Digest, as mentioned above, if you’re protecting sensitive data. The procedure is mostly the same with some minor difference, such as the use of the htdigest utility in place of htpasswd.

Restricting Access Based on Address

You can easily deny access to your whole site or specific sections of it using allow and deny directives in the httpd.conf file. If all you wish to do is refuse access to everyone from a particular address range, say 166.54.x.x, you can use this code block:

Order allow,deny
Allow from all
Deny from 166.54.

If you want to use this technique with .htaccess, just create a .htaccess file in the directory you wish to restrict access to and paste the same code into it, but remove the and lines.

Using the and directives in httpd.conf, you can apply the same code block to more than a single section of your website:

order allow,deny
Allow from all
Deny from 166.54.

Here, access to all URIs starting with a or b will be denied to everyone from a 166.54.x.x address.

Using rewrite_mod

One of the most popular Apache module is the regular-expression-based mod_rewrite, which employs user-defined rules to rewrite URLs. You can use this module to prevent image hotlinking, deny access based on a blacklist, deny access between specific times, and deny access to specified user agents or robots.
You can also use mod_rewrite in place of the above two code blocks, although that’s overkill for such simple denials:

RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^166\.54\.
RewriteRule .*? - [F]

The RewriteCond directive defines the condition – in this case, remote address, which is a server variable.

Server variables define parameters such as REMOTE_HOST, REMOTE_PORT, REMOTE_USER, TIME_MON, TIME_DAY, TIME_HOUR, and HTTP_USER_AGENT.

You then use the RewriteRule directive to send an “access forbidden” message to everyone from 166.54.x.x addresses using the [F] flag. You can also use the RewriteRule ^/[abAB] – [F] line to deny access to several directories.

You can use several server variables with RewriteCond to create rules. The following code, for example, denies access between 3 p.m. and 9 p.m.
RewriteEngine On
RewriteCond %{TIME_HOUR} >15 [OR]
RewriteCond %{TIME_HOUR} <21
RewriteRule .*? - [F]

Here, everyone gets a forbidden message, but you can use another RewriteCond if you wish to deny access to only a specific group. There are many different flags apart from forbidden, such as the [CO] flag to set a cookie when a particular rule matches, or [G] to send a Gone message, which means the resource the user is trying to access is no longer available.

Keeping unwanted bots and suspicious hosts from accessing your site and data is part of the job of an administrator. The simple access control methods here can help you restrict access to only the people you trust. Access control through authorization or depending on factors such as time of day or IP address can help you deny your site to troublemakers.

No comments:

Post a Comment