Password Protect Directories Using Htpasswd On Nginx

back to tech articles
Nginx 1.4.3, Magento CE 1.7.0.2

Apache offers us a neat security feature using http auth. It provides a simple way of protecting files and directories which is extremely useful, albeit not high-level security.

Nginx users will be happy to hear that this functionality is also available by default on Nginx 1.4.3 using the HttpAuthBasicModule. The Nginx docs offer a good example to setup basic authentication. Unfortunately though, it doesn’t work on PHP CLI 5.5.3. That’s because we need to specify some PHP-specific parameters inside our protect block.

Keep in mind that I’m setting this up on a Magento site, so your PHP CLI paths/sockets/ports might be different. We don’t have the htpasswd tool that comes with Apache, so we need to download one and generate a password. Alternatively, we could use PHP’s CLI or just Perl. Here’s all those methods:

Method 1.

1
2
3
$ cd /usr/local/bin
$ wget http://trac.edgewall.org/export/10791/trunk/contrib/htpasswd.py
$ chmod 755 /usr/local/bin/htpasswd.py

The script at edgewall is a python script which allows us to create encrypted passwords in the terminal in very similar way to Apache’s htpasswd. Now we need to create the password file add a username/password combo to it.

1
2
$ touch /etc/nginx/htpasswd
$ htpasswd.py -c -b /etc/nginx/htpasswd jason mypassword

Note that the -c switch means create and it overwrites all previous contents in the file. Omit -c to append your combo to the file instead. That’s method 1, let’s look at another way we can go without downloading any python scripts.

Method 2.

We need to generate an encrypted password in PHP’s CLI.

1
2
3
4
5
$ php -a
Interactive shell

php > echo crypt('mypassword', base64_encode('mypassword'));
bX6j7x3Ep6RnUphp

That’s generated the password, now we need to add it to our /etc/nginx/htpasswd file.

1
2
3
// exit php shell
bX6j7x3Ep6RnUphp > exit
$ echo 'jason:bX6j7x3Ep6RnUphp' >> /etc/nginx/htpasswd

Ok, that’s added our combo to the file and we’re ready to configure Nginx.

Method 3.

If you have Perl installed on your server (in most cases, perl will be installed), then we can generate a password using perl very easily:

1
2
3
$ perl -le 'print crypt("mypassword, "mypassword")'
sayVb7E97UXnw
$ echo 'jason:sayVb7E97UXnw' >> /etc/nginx/htpasswd

Done, the combo has been added to the file.

Your Nginx Configuration

By using one of the methods above, we now have our password file with a valid combo. Next we need to edit our conf file for the Nginx site. Mine is at /etc/nginx/conf/mysite.conf. Inside the conf file, we’re going to add a protect block as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
    location ~ ^/(keepitsecret|keepitsafe)/ {
        auth_basic "Restricted Access";
        auth_basic_user_file /etc/nginx/htpasswd;

        location ~ .php$ {
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            include fastcgi_params;
        }
    }

Note that we do not remove or change the php location block at all; we are just adding the protect block to the conf file. Save and exit the conf file and reload your Nginx configs. It’s always a good idea to test the conf file has no syntax errors before you commit to a reload or a restart.

1
2
3
4
5
$ /etc/init.d/nginx configtest
$ /etc/init.d/nginx reload
// OR
$ /etc/init.d/nginx configtest
$ /etc/init.d/nginx restart

We are done, our two directories keepitsecret and keepitsafe are secured to unauthorised users.

Well done, Gandalf would be proud.

Leave a Reply

Your email address will not be published. Required fields are marked *