How To Password Protect Web Directories In Nginx [Fast]

, , , ,

How To Protect Directories With Encrypted Password In Nginx

Every once in a while depending on your application, you might decide that you need some kind of server side protection to specific directories that you don’t want visitors to have access to. This is particularly useful for WordPress sites, where administrators want to protect specific folders, but more importantly direct access to critical importance files within them.

In this tutorial you will learn a special way that i came up with, how to password protect one or more directories with an encrypted password in nginx web server. This will be done using (a not too simple) regular expression that will match wp-admin (and all php files in it), as well as wp-login.php.

Prerequisites

  1. Ubuntu Operating System + Nginx Web Server.
  2. Root Access, or a non-root user with sudo privileges.
  3. Htpasswd utility.

htpasswd utility can be installed like so:

sudo apt update && sudo apt upgrade -y
sudo apt install apache2-utils -y

Don’t worry you don’t have you use Apache server to use that utility 😛

After htpasswd is installed, you will have to navigate to Nginx directory and create the folder where your passwords will be kept:

nikolas@admintuts:~$ cd /etc/nginx
nikolas@admintuts:/etc/nginx$ mkdir htpasswd
nikolas@admintuts:/etc/nginx$ cd htpasswd
nikolas@admintuts:/etc/nginx/htpasswd$

Password Files Creation

Now you are located in htpasswd folder. Go ahead and use the httpasswd command as shown below:

nikolas@admintuts:/etc/nginx/htpasswd$ sudo htpasswd -c /etc/nginx/htpasswd/.mypasswds john
New password: 
Re-type new password: 
Adding password for user john
nikolas@admintuts:/etc/nginx/htpasswd$ sudo htpasswd .mypasswds alex
New password: 
Re-type new password: 
Adding password for user alex

Let me explain the above 2 blocks inner workings:

  1. htpasswd, is obviously the utility’s executable it self.
  2. the -c operator declares the absolute location of the hidden file .mypasswds will be created.
  3. .mypasswds is the name of the hidden file itself obviously. You can name it as you please.
  4. john and alex is the username we use. It can be anything you want.
  5. The difference between those 2 commands, is that when a new file is created we have to declare it’s absolute location via -c operator. So when we just want to append usernames within the same file, we don’t use the -c operator.

If we check the contents of the file .mypasswds we will see:

nikolas@admintuts:/etc/nginx/htpasswd$ cat .mypasswds
john:$apr1$yk95JECt$z0IEITnsI4Wc1xw9tDNyi/
alex:$apr1$tXbfel4z$CCWhxTRRJX0nwpOLJRll70

2 usernames, which it exactly what it should.

Configure Nginx Password Authentication

Now, its time to get our hands dirty with some Nginx and regular expressions. As i stated, this is a solution to the password protection problem that i personally came up with. It doesn’t exist anywhere else.

location ~ /(wp-login|wp-admin).*.php$ {
    auth_basic "Admin Login";
    auth_basic_user_file /etc/nginx/htpasswd/.mypasswds;
    try_files       $uri =404;
    fastcgi_index   index.php;
    fastcgi_pass    unix:/run/php/php7.3-fpm.sock;
    fastcgi_pass_request_headers on;
    fastcgi_split_path_info ^(.+.php)(/.+)$;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_intercept_errors on;
    fastcgi_ignore_client_abort off;
    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 180;
    fastcgi_request_buffering on;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    include fastcgi_params;
    }

Here is the regular expression deployed for you to check out.

Confirming The Password Authentication

The best way to verify our code works correctly is through the curl command. Surely you don’t want to mess with browser cookies, clearing them after and the like. Here are the results:

nikolas@admintuts:~$ curl -I https://admintuts.net/wp-admin/
HTTP/2 401 
server: nginx
date: Sat, 14 Sep 2019 01:03:22 GMT
content-type: text/html; charset=UTF-8
content-length: 172
www-authenticate: Basic realm="Admin Login"

nikolas@admintuts:~$ curl -I https://admintuts.net/wp-admin/update-core.php
HTTP/2 401 
server: nginx
date: Sat, 14 Sep 2019 01:04:38 GMT
content-type: text/html; charset=UTF-8
content-length: 172
www-authenticate: Basic realm="Admin Login"

nikolas@admintuts:~$ curl -I https://admintuts.net/wp-login.php
HTTP/2 401 
server: nginx
date: Sat, 14 Sep 2019 01:04:52 GMT
content-type: text/html; charset=UTF-8
content-length: 172
www-authenticate: Basic realm="Admin Login"

As you can see the server sends back a 401 (Unauthorized) response along with a www-authenticate header field containing at least one challenge (username-password combination request).

By now you should have everything you need to configure basic authentication for your site. Be aware of the fact, that password protection should always be combined with SSL encryption to avoid sending your credentials in plain text to the server.