Restricting access to a resource is often required when using the web. On complex web applications, this is often implemented using a login system which can be more or less sophisticated. If our requirements our pretty basic, however, we can use the authentication system provided by the Apache web server. In this tutorial we will see how can we do it.
In this tutorial you will learn:
- How to restrict access to a web page using the Apache web server
- How to store the user passwords in plain text files
- How to store the user passwords in a database
- How to allow access to multiple users
Software requirements and conventions used
|Category||Requirements, Conventions or Software Version Used|
|Software||The Apache web server|
|Other||Root privileges to modify configuration files|
# - requires given linux commands to be executed with root privileges either directly as a root user or by use of
The most basic setup involves the two steps: the creation of a password file
where users passwords will be stored, and the use of specific directives in
the server main configuration file (the location of
this file depends on the distribution we are using: on Fedora
and the Red Hat family of distribution, the file is
on Debian-based distribution, for example, is
a VirtualHost configuration file, or inside an
.htaccess file placed inside the
If we decide to use this last option, we must be sure the
AuthConfig directive can be overridden. Supposing the
.htaccess file is
/var/www/html/restricted directory, we would write:
<Directory /var/www/html/restricted> AllowOverride AuthConfig </Directory>
Creating the password file
Creating a password file is really easy: all we have to do is to use the
htpasswd utility, which usually comes with the Apache installation. It’s
very important that the file containing the users passwords is placed
in a directory where it can’t be accessed by the public. In this tutorial we
will create the file inside the
Suppose we want to allow access to the egdoc user. To create his password we would run:
$ sudo htpasswd -c /etc/httpd/passwords egdoc
htpasswd utility is used to manage user passwords and store them in
plain-text files. In this case we invoked the utility and used it with the
option: this is needed to create the file from scratch. If the file already
exists, it is truncated, therefore when we need to append new entries to it, the
option must be omitted.
We provided the two arguments: the first is the path of the password file, the second is the name of the user we want to create a password for. The command will prompt us to enter a password for the user, and to confirm it:
New password: Re-type new password:
We won’t be able to see the password as we enter it. If we now take a look inside the generated file, we can see that it has been stored after been hashed with the Apache APR1 hashing format:
Setup the server
Once our password file is ready, we need to create the right configuration for
the Apache web server. As an example, let’s assume we want to restrict access to
/var/www/restricted directory which is the
DocumentRoot of a VirtualHost
configured as follows:
<VirtualHost *:80> ServerName test.lan DocumentRoot /var/www/restricted <Directory /var/www/restricted> AuthType Basic AuthName "Restricted area!" AuthBasicProvider file AuthUserFile /etc/httpd/passwords Require user egdoc </Directory> </VirtualHost>
Let’s examine the directives we used in this configuration.
First of all, we used AuthType. This directive is used to select what type of authentication we want to use. In this case we choose “Basic” as a value: this functionality is provided by the mod_auth_basic module. Other possible values are None, Digest (provided by the mod_auth_digest module), and Form, which is provided by the mod_auth_form module.
The AuthBasicProvider directive is used to declare what provider should be used for authentication. In this case we could have omitted it, since file is the default value, provided by the mod_authn_file module.
With the AuthName directive, we setup a realm. This configuration has basically two purposes: as a first thing, the message we provide here, will appear as a message on the prompt provided by the server, for example:
The site says: “Restricted area!”
The “realm” is also used by the client, to decide what password it should send to the server. If the user is already authenticated, it will be able to access all the resources under the same realm, without having to login again.
The AuthUserFile directive is used to point to the plain text file hosting
the users password we created before with the
Finally, we have the Require directive. With this directive we can restrict access to a resource on the base of some parameters as the client IP address, or, like in this case, the authentication as a specific user.
/var/www/test directory contains an index file,
index.html, where we
just placed the “Access granted!” message. Once our configuration is ready
we can restart the server:
$ sudo systemctl restart httpd
When we try to access the page, we will be prompted to enter a login name and a password:
If we provide the right credentials, the access to the page will be granted:
In the vast majority of cases, we want to allow multiple users to access a
resource. In those cases we want to use a group file where we associate
the name of a group with a space-separated list of its members. Suppose
the path of our file is
/etc/httpd/groups; its content would be:
AllowedUsers: egdoc tim rob
We declared that the egdoc, tim and rob users are member of the AllowedUsers group: for each of them an entry in the password file should be added. At this point we need to change our server configuration and adapt it to the new setup:
<VirtualHost *:80> ServerName test.lan DocumentRoot /var/www/restricted <Directory /var/www/restricted> AuthType Basic AuthName "Restricted area!" AuthBasicProvider file AuthUserFile /etc/httpd/passwords AuthGroupFile /etc/httpd/groups Require group AllowedUsers </Directory> </VirtualHost>
We introduced a new directive, AuthGroupFile, and passed to it the path of the file where groups are mapped to users. We also changed the value of the Require directive; now, to be allowed to access the resource, an user must be part of the AllowedUsers group. To make the changes effective we need to restart the server.
Storing passwords in a database
In the previous example, we saw how to store the users passwords inside a simple, plain text file. This is a perfect viable solution when we don’t have a lot of users. When the list of users becomes quite long, instead, it could be quite impractical to scan the entire password file for each request. In cases like that, we may want to store the passwords in a database instead.
One option is to create a DBM file. We can accomplish the task by using the htdbm utility. To generate a dbm file in the same position we used in the previous example, we can run:
$ sudo htdbm -cB /etc/httpd/passwd/passwords egdoc New password: Re-type new password: Database passwd/password created.
As you can see, the syntax is very similar to the one used for htpasswd.
Just like before, we launched the command using the
-c option, to
create the file, or truncate it if it already exists. In this case we also used
-B option to use the bcrypt algorithm for the password encryption. Since
we changed the way the passwords are stored, we must also change the server
<VirtualHost *:80> ServerName test.lan DocumentRoot /var/www/restricted <Directory /var/www/restricted> AuthType Basic AuthName "Restricted area!" AuthBasicProvider dbm AuthDBMUserFile /etc/httpd/passwd/passwords Require user egdoc </Directory> </VirtualHost>
What we changed above, is the value we passed to the AuthBasicProvider directive, which now is dbm. We also substituted the AuthUserFile directive with AuthDBMUserFile, providing just like before, the path of the file where the password are stored. For this configuration to work, we must have the mod_authn_dmb module enabled.
In this tutorial we saw how to restrict the access to a resource and implement a simple login authentication system using the Apache web server. We saw how to store passwords in plain text files or in a dbm database format. We also saw how to allow access to multiple users using a Group file and what directives should be used to achieve our goal.