Nginx

How to Block Hotlinking with Nginx

Nginx is a lightweight web server capable of handling humongous number of requests at a given time without making the server busy....

Written by SXI ADMIN · 4 min read >
Nginx is a lightweight web server capable of handling humongous number of requests at a given time without making the server busy. It contains sophisticated features such as asynchronous processing, support to ipv6, cache loader, http/2 support, block hotlinking, thread pools, SPDY and SSL, and many more. Among them one of the most important features for any website in general is block hotlinking. Hotlinking is a malicious practice often done by certain petty web masters when they are unable to afford for bandwidth cost, and thereby they end up taking it from somewhere else. This hampers legitimate web masters from utilizing the bandwidth they paid for. On top of that, the linked resource might be unavailable for the users who visit the original website, when the bandwidth allocated for the original webmaster is run out, and site owner didn’t pay for the excessively consumed bandwidth. All in all, to preserve the integrity, availability of the website hotlinking should be stopped, and this guide teaches how to get it done with ease.

Preparation

In the preparation segment, the general instructions for both later said methods are taken down. Obviously, it’s important to have a console to access the server over SSH, and a proper text editor as nano to open the Nginx configuration file. Once both are acquired, use the following commands to open, save, and apply the changes. The following steps assume the user already accessed to the server over SSH.

  • Type the following command to open the default configuration file of Nginx. If each domain has a separate configuration file, use its name instead of default.
nano /etc/nginx/sites-available/default

  • In the default or the configuration file type the codes stated in one of the later said methods. Make sure to use only one of them.
    • Use the following command to test out the configuration file before pushing it to the live mode.
    nginx -t
    • If everything is in the right order, go ahead and type the following command to apply the changes to take effect.
    sudo systemctl restart nginx

Method 1: General Method

The general method is very easy to implement and understand as it contains just a location block. Furthermore, it blocks requests to certain file formats only instead of blocking every request from invalid referers to the server.

  1. Copy the following code snippet.
  2. Open the default file of nginx as seen in the “Preparation” phase.
  3. Paste the copied code snippet under the first location block found in default file. In nginx, the regular expression case insensitive (~*) is always prioritized before forward slash (/), and thus the following code snippet is executed before the forward slash location block.
  4. Save, and close the default file, and then follow 3, 4 steps in “Preparation” phase to make changes to take effect.

In the following example, it blocks requests to css, gif, ico, jpeg, js, png, woff, woff2, ttf, ttc, otf, and eot files. There are 10 conditional statements under location block. The first conditional statement allows the resources to be directly viewed through the web browser, 2nd and 3rd blocks allow the resources to be viewed through the original site (both naked, and www sub domains), rest of the blocks except the search?q and the last block allow search engine crawlers to access, and index the resources, which is very important to index the images in both google images, and bing images. The search?q allows google cache service to access, and save the resources along with the page, and thereby the page can be accessed directly through google search result when the site is offline.

location ~* .(css|gif|ico|jpeg|jpg|js|png|woff|woff2|ttf|ttc|otf|eot)$ {
if ($http_referer !~ "^$"){
set $rule_0 1$rule_0;
}
if ($http_referer !~ "^http://nucuta.com/.*$"){
set $rule_0 2$rule_0;
}
if ($http_referer !~ "^http://nucuta.com$"){
set $rule_0 3$rule_0;
}
if ($http_referer !~* "google."){
set $rule_0 4$rule_0;
}
if ($http_referer !~* "search?q=cache"){
set $rule_0 5$rule_0;
}
if ($http_referer !~* "msn."){
set $rule_0 6$rule_0;
}
if ($http_referer !~* "yahoo."){
set $rule_0 7$rule_0;
}
if ($http_user_agent !~* "googlebot"){
set $rule_0 8$rule_0;
}
if ($http_user_agent !~* "msnbot"){
set $rule_0 9$rule_0;
}
if ($http_user_agent !~* "slurp"){
set $rule_0 10$rule_0;
}
if ($rule_0 = "10987654321"){
return 403;
break;
}
}

Method 2: Valid_Referers Method

Valid referers is the most convenient, and the widely recognized method to block invalid referers with ease. It contains just two lines compared to the previous method and is very flexible. However, it’s a bit hard to digest as it’s involved regular expressions, and a different mechanism to block requests from invalid referers.

  1. Copy the following code snippet to in between, and at the very beginning of the main location block.
  2. Replace the domain name list with the allowed domain names, for instance google, bing, or your own domains etc.
  3. Save, and close the default file, and then follow 3, 4 steps in “Preparation” phase to make changes to take effect.

valid_referers none blocked server_names

*.linux.com linux.* www.linux.com/about/
~.linux.;
 
if ($invalid_referer) {
return 403;
}

It mainly has two code blocks, valid_referers, and the if conditional expression with invalid_referer variable. By default, this code block is used in between, and at the very beginning of the location block before the execution of any other code, but it can be used any other place too, such as in between a location code block with regular expressions to detect specific file formats to make the blocking relevant for the aforesaid file formats, as in the method 1. As explained earlier, the method contains just two code blocks, the first code block contains 3 keywords, the first one is “none” when the referer field is missing in the HTTP request, second one is “blocked” when the referer field is deleted by any middle party, such as a proxy, firewall etc., the third keyword is for specifying the valid domain names.

When the domain name starts with “~” symbol it’s regarded as a regular expression, and thus very complex patterns can be used, but it might be difficult to understand if regular expressions are not known well. If none of the conditions are met in valid_referers statement, the invalid_referer variable is set to empty string, otherwise it’s set to 1, what it means if the coming request doesn’t contain any referer field, or if nginx identified that referer field is removed by a firewall or a proxy, or if the referer field is set to the specified domains (valid domain name list) then invalid referer variable is set to empty string, and thereby its if condition is not executed. However, if request is coming from a domain that is not specified in the valid_referers expression as a valid domain, then it’s blocked.

 

CONCLUSION

Please be sure to consider this content and prevent hotlinking on your Nginx hosted sites.

How to Use URL Rewriting

SXI ADMIN in Nginx
  ·   7 min read