Securing files with Nginx

We all use HTTP servers to deploy our applications. NGINX is also an http web server which has a rich set of configurations which gives simplicity for applications.

We can deploy our react or other applications with Nginx. For the application to work with Nginx we need to configure it first. This configuration can be done inside nginx.conf file.

This article is not about how NGINX works, there are multiple articles you may find on web for same. Here we will see how we can secure a particular file path.

Our Nginx setup comes with basic features, if we want to add some new functionality then we need to compile Nginx with extra modules. So for securing links we need Secure Link module. Following are the steps required for compiling Nginx with secure link.

# install deps (Ubuntu)
sudo apt-get install -y build-essential libpcre3 libpcre3-dev libssl-dev

wget http://nginx.org/download/nginx-1.10.1.tar.gz
tar -xf nginx-1.10.1.tar.gz
cd nginx-1.10.1

./configure --with-http_ssl_module --add-module= --with-http_secure_link_module

make -j
sudo make install
# nginx is now installed in /usr/local/nginx

The final output will be our Nginx setup which we can copy and paste on any server and the start setup. To start the server we need to run the following command.

root>./nginx

So with this, our Nginx is up and running. Now for storing files and accessing them over network, we need to configure it’s path in nginx.conf file. Following are the configuration we need to add

location /files {
secure_link $arg_token,$arg_expires;
secure_link_md5 "$secure_link_expires $uri $remote_addr secret";

if ($secure_link = "") {
return 403;
}

if ($secure_link = "0") {
return 410;
}

...
}

Here Nginx automatically handles decryption and verification of hash. $arg_token & $arg_expires are the query string params that needs to be pass along with the URL.

secure_link_md5 "$secure_link_expires $uri $remote_addr secret";

This is a pattern that needs to be matched with md5 we are passing in the query string. We can have our own pattern.

$secure_link = ""

If the hash code doesn’t match then it will return an empty string. In that case, we are returning 403 error code.

$secure_link = "0"

Our token expires according to provided timestamp. If the token is expired then we will get 0 from secure_link. For that, we should return 401 error code.

Most important part is how to generate token. There are several ways from which we can generate our md5 hash. We can use any programming language for this. Here we will see how we can generate token using shell script.

echo -n ‘1483228740 /files/my_report.pdf 192.168.33.14 secret’ | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =URL Request Format:http://<domain-name>/files/my_report.pdf?token=AUEnXC7T-Tfv9WLsWbf-mw&expires=1483228740

This is how our URL should be defined. We should pass token and expires as a part of the query parameters.Our file will be accessed only if the token and the expires parameter is correct. That is how we can protect our files using secure link. Thanks for reading this.