Protecting your Web Pages with htaccess

Once you have a web server up and running, and you begin using it to either host your own files or applications, you may find that you would like to begin protecting access to some data on it from anyone casually browsing the web interface. While many applications you install will have login pages for admin tasks, what if you put up data of files that you want to protect yourself? There is an easy and very effective way to password protect web pages without having to involve complex login pages or applications.

Apache supports the use of .htaccess files for password protecting content on web pages. The .htaccess file is a very powerful and feature rich tool for configuring how your web server behaves, but is very simple and easy to understand. It allows you to configure a number of features such as blocking visitors from your site, redirecting visitors to somewhere else or setting up custom pages whenever a visitor gets an error message. We are going to use it here for the purposes of password protecting a web page.

.htaccess files are simply text files, which the Apache web server reads before reading any other files in a web directory, and takes action based on its content. The location of the .htaccess file is important, as it affects not just the directory it is in, but any sub-directories beneath that too.

Enabling htaccess

To enable the .htaccess feature in Apache, you must update the Apache config file. Navigate to the directory below and make a backup of the apache config file, just in case anything goes wrong. Then use the nano text editor to edit apache2.conf:

cd /etc/apache2
sudo cp apache2.conf apache2.conf.BACKUP
sudo nano apache2.conf

Scroll down through the file until you come to the <Directory /var/www/> section. Change, or comment out (with #) the AllowOverride line so that it reads, ‘AllowOverride All’:

<Directory /var/www/>
    Options Indexes FollowSymLinks
#    AllowOverride None
    AllowOverride All
    Require all granted

Then restart the Apache web server for the changes to take effect

sudo service apache2 restart

Writing the htpasswd File

Using htaccess for password protection involves two files: the .htaccess file saved under your web directory, and the htpasswd file which contains the password itself. For security reasons the htpasswd file should not be saved under the web directory (/var/www/html/). You don’t want to leave your password file lying somewhere around your web site, as there is potential for someone to scan for it or mirror your website (using wget or other tools) and get a copy of it. Lets create the htpasswd file first.

Htpasswd is a command on your system which creates the htpasswd file and encrypts the password which Apache will look for. It takes the form of, htpasswd filename username. If you are creating the htpasswd file for the first time, you need to use the –c flag; if you are adding a user to an existing file you don’t use the flag. I am going to create a directory in my home directory, and create a new htpasswd file, with a username of neptune:

mkdir /home/jupiter/htpasswd
cd /home/jupiter/htpasswd
htpasswd –c htpasswd neptune

you will be prompted to enter and re-enter the password for the user. Once complete, use cat to read the resulting file

Note that you can actually name your file anything you want, you are not obliged to call it ‘htpasswd’.

You will notice the username is in legible plain text, while the password has been scrambled. htpasswd uses a version of MD5 hashing which has been modified for Apache. Hashing is a form of encryption, but an encryption which is irreversible, i.e. one-way encryption. A hashed password cannot be decrypted to read the original password. When you enter the password to your site, Apache hashes what you enter and compares it to what it has on file in the htpasswd file.

MD5 (Message Digest v5) is a good hashing algorithm, but one for which weaknesses (called collisions) have been found in recent years. While MD5 is most likely sufficient for our needs, there is a stronger option: bcrypt. To use bcrypt hashing, use the –B flag when running the htpasswd command:

MD5 encrypted passwords begin with ‘$apr1$’; bcrypt encrypted passwords begin with ‘$2ys$’.

It is important to understand the role encryption is playing here. By encrypting the password, you are ensuring that, if someone gets hold of your htpasswd file from the server itself, they will not be able to read the password, or easily reverse the encryption. It does not protect you if you have used a weak password, i.e. 1234, and someone logging in to your webpage happens to guess it. Therefore using a long password or passphrase is recommended.

It could be argued that, if someone has access to your server to take the htpasswd file, then they could also take the data from the protected web directory also. While this is true to an extent, there are further security measures you could take to prevent this, through setting the security permissions of your files & folders appropriately. We are not going to cover that for now here.

Finally, change ownership of the file to allow the web server to be able to read it

sudo chown www-data:www-data htpasswd

Writing the .htaccess File

To create the .htaccess file, simply navigate to the web folder you want to password protect, and create a file named .htaccess with a text editor. I am going to do this in a web sub-folder called secrets

cd /var/www/html/secrets
nano .htaccess

Then save and exit (Ctrl + O, Ctrl + X). In this file, we are going to specify the following:

AuthName – the text that will be displayed when prompted for your password
AuthUserFile – the path to the .htpasswd file
AuthType – the authentication type
And either of the two following options:
Require valid-user – if there are multiple users in the .htpasswd file, any of their username:password combinations can be used
Require user <username> – only <username> is permitted log in. Their pswd must be in the .htpasswd file. No other user in the htpasswd file will be granted access

AuthName “What is the password?”
AuthUserFile /home/jupiter/htpasswd
AuthType Basic
Require valid-user

Save and exit the file, and then try browse to the folder secrets/ folder using a web browser. You should now be prompted to enter a username and password before you can get access.

If you go out of the folder and back in again, you will probably find that you are not prompted for a password the second, and subsequent times. To avoid prompting the user for their username and password each time, web browsers remember the values you entered and includes them on additional requests. This is a feature within the web browser and not something you can set on the server side.

Other Considerations

One other factor you should be aware of when it comes to password protection is the security of your connection from your web browser to the server. The data in your web folder is certainly now password protected, and the password has been moved outside of the web directory and is being stored encrypted. Your connection to your web server though is not secured, and the potential is there for a third party to sniff the traffic, and record the password as it travels across the network.

For a home based web server, this is not of concern, as you have control over the network and who is connected to it. If you are connecting to a web server across the internet though, you need to be aware of this. The solution to this is to encrypt your connection using HTTPS. For internet facing servers, Lets Encrypt offer a free, well vetted and completely secure solution, and I will be covering this in a future article.