Password protect your website hosted on Apache web server

February 24, 2006
At times, when I am browsing the web, I click on a link such as this one and instead of a web page, I get a dialog box asking me to enter my user name and password. And only after I have been authenticated do I get access to the website (or page). This feature of password protection is very simple to implement in Apache web server.

Basically, the whole process of password authentication banks on just two files . Them being :
  1. .htpasswd - This file contains the user name - password combination of the users who are allowed access to the website or page. This file can reside anywhere other than the directory (or path) of your website. But usually, it is created in the Apache web server directory (/etc/apache2/.htpasswd). This is because, this file should not be accessible to the visitors to the site.
  2. .htaccess - This file defines the actual rules based on which users are given access or denied access to a particular section or whole of the website. This file should reside in the base directory of one's website. For example, if my website is located in the path '/var/www/mysite.com' and I want to provide user authentication to the entire website, then I will store the file .htaccess in the following location - '/var/www/mysite.com/.htaccess '.
If one is implementing this feature for the first time on one's server, then he has to create the .htpasswd file. I chose to create the .htpasswd file in the apache 2 configuration directory. After this, one can add any number of users and assign passwords to them. This is done by the htpasswd utility which gets installed with the apache2 web server.
# htpasswd -c /etc/apache2/.htpasswd ravi
New password: *****
Re-type new password: *****
Adding password for user ravi
#_
In the above command, -c option asks the htpasswd utility to first create a .htpasswd file in the /etc/apache2 directory. Simultaneously, I have provided the name of the user (myself) and the utility asks me to type a password which is used to authenticate me before allowing access to the site.

Note: Any number of users and their password may be entered in the same .htpasswd file per website.

Now I make this .htpasswd file readable by all the users as follows:
# chmod 644 /etc/apache2/.htpasswd
Next step is the creation of the file .htaccess which will prohibit the full or a part of the website which is situated in /var/www/mysite.com. Since I am interested in password protecting the whole website, I create the file in the /var/www/mysite.com base directory. But if I am interested in protecting only a sub-directory (say by name 'personal') of this site, then I will have to create it in the '/var/www/mysite.com/personal' directory.
# touch /var/www/mysite.com/.htaccess
Now I enter the following lines in the .htaccess file :
AuthUserFile  /etc/apache2/.htpasswd
AuthGroupFile /dev/null
AuthName MySiteWeb
AuthType Basic
require user ravi
Here 'AuthUserFile' points to the place where I have stored the .htpasswd flat file which contains the user names and passwords.
AuthGroupFile points to the group file which contains the group of users. Here I have opted to not have a group file and hence points it to /dev/null .
AuthName directive sets the name of the authorization realm for this directory. This name can contain spaces.This is a name given to users so they know which username and password to send.
AuthType value of Basic instructs apache to accept basic unencrypted passwords from the remote user's web browser.
The last line - require user ravi - tells apache that only the user with name 'ravi' should be allowed access provided the right password is entered. If more than one user is to be allowed access, then those user names could also be appended to the line. Suppose I want another user also to access the file, I modify the line as follows:
require user ravi john
And if I want all the users listed in the .htpasswd file to be allowed access, the line is modified as thus:
require valid-user
The .htaccess file also has to be provided the right file permissions.
# chmod 644 /var/www/mysite.com/.htaccess
One more step is needed; that is to change a line in the apache2 configuration file. In a previous article titled "Host websites on your local machine using Apache websever", I had dwelled upon the modular structure of the Apache 2 configuration files.

Following that structure, assuming my configuration file for the website /var/www/mysite.com is stored in /etc/apache2/sites-available/mysite.com , I open the file in an editor and change the following line :
<Directory /var/www/mysite.com/>
...
AllowOverride None
...
</Directory>
TO
<Directory /var/www/mysite.com/>
...
AllowOverride AuthConfig
...
</Directory>
... and save and exit the file. Now restart apache web server to re-read the configuration file.

Note: If you are using apache instead of apache2, then the file to be edited is /etc/httpd/conf/httpd.conf though the lines to be edited are the same.

That is it. From now on any user who visits the website will first have to enter the correct username and password before he is allowed access to the website.

17 comments:

  • Question, aren't these password passed in plain text? If so is there a way to encrypt them? Thanks!

  • Ravi

    Yes the passwords are passed in plain text. And at present, to my limited knowledge, only AuthType of 'Basic' is implemented which allows the user to pass the passwords in plain text.

    So if you want additional security like passing the password through the network in encrypted form, you will have to implement https (secure http) which is entirely different topic.

    But I would like to point out that the passwords themselves are stored in .htpasswd file in an encrypted form.

  • It is accurate to say the passwords are passed in plain text, however if you use Apache's mod_rewrite module, you can force a secure (HTTPS) connection - modify your Apache config file (for me this is /etc/httpd/conf/httpd.conf) and in the section indicated similar to:

    < VirtualHost *:80 >, add/uncomment such that the following lines read as required:
    RewriteEngine on
    RewriteRule ^/(protected.*) https://website.com/$1

    where website.com is your web address, and you want the www.website.com/protected/ folder to be the point where HTTPS connections are forced. So now, if you put your .htaccess file in eg /var/www/html/protected/, and any content you wanted to be secure in here also, then any user visiting or following a link to http://www.website.com/protected/ will be forced into a secure connection to https://www.website.com/protected/, and then asked for a username/password prior to entry.

  • If speed is an issue with your site, you can place all the same items you would normally place in the .htaccess file between the <Directory></Directory> tags in the apache configuration file.

    In fact this is the recommended way of implimenting this type of protection so Apache doesn't have to search through your file tree looking for .htaccess files and instead can focus on delivering your web content.

    Quoted from http://www.apache.org

    In general, you should never use .htaccess files unless you don't have access to the main server configuration file. There is, for example, a prevailing misconception that user authentication should always be done in .htaccess files. This is simply not the case. You can put user authentication configurations in the main server configuration, and this is, in fact, the preferred way to do things.

    (Found at: http://httpd.apache.org/docs/2.0/howto/htaccess.html)

  • The passwords are (SH1 I believe) hash encoded. They appear as an encoded form hat cannot be converted back to the original password. And are therefore very safe.

  • Even if the passwords are hash encoded, it's not safe to send them over an unencrypted connection. If the hash value is intercepted, it can later be used to impersonate that user, without knowing the original password. If you want to protect your website, you must use https.

  • David

    A well written, concise article. Told me exactly what I needed to know.

  • An article like this was what I needed, thanks to all!

  • I am interessted in on more thing.

    If i want to password protect my whole webpage, let's say:

    /var/www/mysite.com/

    but want to leave access to one subdirectory somewhere in the directory structure, let's say:

    /var/www/mysite.com/private_dir/pub_dir/

    can I change the protection mechanisman in that dir? is it possible to override the .htaccess-configuration?

  • MrGroove

    Nice write-up.

    Here's an article to password protect apache on Windows - http://www.groovypost.com/howto/apache/password-protect-apache-website/

  • Take note:
    .htpasswd trancates any long passwds to just 8 characters which makes the webpage vulnerable to brute-force attacks.

  • dchurch

    Hmmmm...this doesn't seem to be working as at 4rd March 2008. Has Apache2 been updated somehow and this method been obsoleted? Pages still load without any challenge for user or password...despite several restarts.

  • dchurch,

    This functionality still exists in apache. It's most likely an issue of your apache configuration

  • Skalsky

    Very well put. Thanks for making password protection easy to implement.

  • james

    This worked pretty well -- good job

  • Of ALL the tutorials I've found regarding this very topic, they were all identical to yours with one exception, they left out the /sites-enabled/000-default configuration.

    That was what I was missing. Thanks.

  • James

    Thank man this really worked well. First blog I could find that did a great job!