Knowledge Builder: Restrict Access and Secure Your Website with Apache

For most applications, there really isn't all that much to Apache configuration beyond setting up the virtual host and document root.

But Apache has a lot more to offer, and this set of articles will show how to set up some security on your site.

These articles assume that you are familiar with the basics of editing Apache configuration files. All of these settings can be performed at the directory level (as long as directory-level overrides are allowed), so you should not need access to the site configuration (meaning that you can do this on a shared host where you might not have access to the site/host configuration).

The information in these articles has been gathered from using Apache and reading the documentation.

Restrict Access to your Website

First off, restricting access to your entire website is pretty easy.

All you need to do is put the following at the top of the .htaccess file in your website's document root:

Order deny,allow
Deny from all

This will prevent anyone from seeing your website. Admittedly, not terribly useful, but it's a start.

It is important not to have a space in 'deny,allow', as this will cause an Apache server error.

If you are setting up a test website, you will likely want to restrict access to everyone except your own IP address (the computer on which you are testing the site in a browser):

Order deny,allow
Deny from all
Allow from 192.168.1.1

About Order, Deny and Allow

These three directives are all part of mod_access, which is a core module within Apache. Order is used to specify the order in which Deny and Allow directives are processed - we use the order 'deny,allow' to first restrict all access and then allow from a specific IP address.

If we reversed the arguments, then we would always be blocked from the site as the Allow directive is processed first and then the Deny directive (which blocks everyone) would subsequently override it.

Blacklisting

The above configuration is an example of whitelisting. We are restricting access to a limited network.

The opposite to this is, of course, blacklisting. We can allow access to all users, except from a specific IP or network:

Order allow,deny
Allow from all
Deny from 192.168.1.1

Require a Username/Password for your Website (Basic Authentication)

If you want to lockdown your website, but do not need a full user access solution built in PHP or ASP, etc, you can make use of a variety of authentication options with Apache.

This example uses the basic authentication methods available to the core of Apache httpd:

AuthUserFile /var/www/your-website/.htpasswd
AuthType Basic
AuthName "Authentication Required"
Require valid-user

.htpasswd file
In order for this to work properly, you will need to create a .htpasswd file (actually, you can call it what you like as long as you point the .htaccess file to it using the AuthUserFile).

To create the file, open a terminal and open the document root for your website. Then enter the following command:

/var/www/your-website$ htpasswd -c .htpasswd admin

You will then be prompted to enter a password for the user to be known as 'admin'. This will create the file with this user.

You can add subsequent users by entering the following:

/var/www/your-website$ htpasswd .htpasswd another-user

Allowing Trusted Connections and Require Passwords from Others

This should be fairly useful - it sets up a trusted connection (always allow access to people on a specific network) and requires authentication for anyone else outside of that network.

Satisfy any
 
Order deny,allow
Deny from all
 
Allow from 192.168.1
 
AuthUserFile /var/www/your-website/.htpasswd
AuthType Basic
AuthName "Authentication Required"
 
Require valid-user

Satisfy Directive

The Satisfy directive is required to allow Apache to skip the user authentication if the preceding Allow directives are met - thereby setting up the trusted connection. If you are accessing the site from outside the trusted network, then you will be asked to authenticate.

If the Satisfy directive is left to its default value of 'all' then the access requirement is changed subtly. Nobody outside the allowed network will be able to access the site at all. And everyone on the allowed network will also be required to login.

Restrict Access to a Directory Within Your Website

If you want to restrict access to a specific directory, such as an administration section, you have a couple of options. First, you can drop a .htaccess file into the directory which you want to restrict and set it up like this:

AuthUserFile /var/www/your-website/.htpasswd
AuthType Basic
AuthName "Authentication Required"
 
Require valid-user

However, this isn't always a good idea - it spreads the configuration around into multiple locations, and could become confusing when it comes to maintaining the site, especially if you start finding odd conflicts arising out of the various configurations in different directories.

The second option is to set up configuration blocks in the .htaccess you have in the root of your website.

<Directory /var/www/your-website/admin/>
  AuthUserFile /var/www/your-website/.htpasswd
  AuthType Basic
  AuthName "Authentication Required"
 
  Require valid-user
</Directory>

Restrict Access to a Specific URL

Using the or directives to restrict access to specific areas of a website only works if there is actually a physical file or directory. But as more and more site frameworks are using rewritten URLs, the chances of a URL mapping to a physical file or directory are getting pretty slim.

So, what can you do in these circumstances?

Well, something like this:

Satisfy any
 
Order allow,deny
 
SetEnvIf Request_URI "^/admin" admin
Deny from env=admin
 
AuthUserFile /var/www/your-website/.htpasswd
AuthType Basic
AuthName "Authentication Required"
 
Require valid-user
 
Allow from all

This configuration essentially sets the site up to be completely open by default ('Order allow,deny' and 'Allow from all').

Then, we conditionally set an environment variable using the SetEnvIf directive. The environment variable 'admin' is only set if the requested URI starts with /admin (in Apache, the requested URI is the URL after the host name).

Since we have the directive 'Order allow,deny', anyone accessing the admin section of the website will be denied due to the 'Deny from env=admin' directive. This then forces users to authenticate before they can access this URL.

Joint Credit

My colleague John Croucher worked with me to help figure this one out after we were asked to restrict access to a URL on a site using rewritten addresses this week.