Two-Factor Authentication System for Apache and SSH

If you run a publicly accessible Web server for your own use (and let's face it, if you're reading Linux Journal, there's a very good chance you do), how do you go about limiting the risk of someone accessing your site and doing bad things? How about SSH, an even bigger concern? In today's world, it's imperative to think about your exposure and take steps to limit as much risk as possible.

In this tutorial, I walk through the steps necessary to implement a home-grown two-factor authentication system for accessing your Web sites and for SSH access.

The Infrastructure and the "Challenge"

Running your own hardware can be a pain in the neck. After dealing with hardware failures, such as failed fans, failed power supplies, bad hard disks and the like, you finally may decide to dump your co-lo or bedroom closet and your hardware and jump into the world of elastic computing. One such option is Amazon's EC2 platform, which offers a variety of Linux flavors and has one of the most robust and mature cloud platforms available. I'm not an Amazon representative, but I'm the first to say try it. It's amazing stuff, and a micro instance is free for a year.

In the test scenario for this article, I use an Amazon EC2 server running Ubuntu 12.04 LTS to host a couple Web applications. If you use a different flavor of Linux, the instructions easily can be adapted to meet your specific needs. Let's assume the applications are, for the most part, for personal use only. If the sites were accessed only from work or home, you simply could secure the sites by creating firewall rules to allow Web traffic from only those IP addresses. This, incidentally, is exactly how one should secure SSH.

Let's assume though that this won't work for your Web apps because you do a fair amount of traveling and need to be able to access those applications while you're on the road, so a couple firewall rules won't help you. Let's also assume that your applications have their own security systems, but you still want an extra layer of security.

You could have set up a VPN server, but every once in a while, you might like to give a family member access to one of your sites, so a VPN approach wouldn't work.

Another consideration is Google Authenticator for true two-factor authentication. You certainly could go down this path, but you're looking for something you can do yourself—something that is self-contained and yours.

Just like so many things in the Linux world, where there's a will, there's a way! It turns out you easily can set up your own, homegrown, two-factor solution and use it to control access to your Web apps and SSH, while also making it possible to allow occasional access to your sites by other users.

Apache Authentication and Authorization

Since the Web server for this example is Apache, let's leverage the server's authentication and authorization capabilities to ask for a set of credentials before any of your sites are served up to a user.

In the interest of keeping things simple, and since you will follow best practice and allow only https traffic to and from your Web server, let's use the mod_auth_basic module for authentication.

Start by becoming root and installing Apache on your fresh Ubuntu install:

sudo su
apt-get install apache2

Let's assume your Web applications run in subfolders off of the main www document folder. This allows you to take care of all your sites at once by creating a single .htaccess file in the http server root folder:

vim /var/www/.htaccess

Now, let's add a few lines that tell Apache to require authentication and where to look for the password file:

AuthType Basic
AuthName "restricted area"
AuthUserFile /home/ubuntu/.htpasswd
require valid-user

With that in place, you now need to change the ownership of the file so the Apache process can read its contents:

chown www-data:www-data /var/www/.htaccess

Next, you need to create the .htpasswd file that you reference in your .htaccess file and configure its ownership so the Web server can read it:

htpasswd -cb /home/ubuntu/.htpasswd jameslitton test123
chown www-data:www-data /home/ubuntu/.htpasswd

Now you need to tell Apache to require authentication and to use the mod_auth_basic module for that purpose:

vim /etc/apache2/sites-available/default-ssl

Then you need to change AllowOverride None to AllowOverride AuthConfig:

Service apache2 restart

Visiting your site now prompts for a user name and password (Figure 1).

Figure 1. Authentication Request from mod_auth_basic