Categories
SysOps

How to stop referral spam using Nginx

Today, I will show you how to stop referral spam using simple nginx directives to return 403 Forbidden HTTP status code after encountering troublesome referer hostnames.

First step

Create referer blacklist /etc/nginx/referer_blacklist.conf configuration file that will contain void_referer variable
whose value depends on the provided http referer.

Notice that void_referer variable will be evaluated only when used. Even a large list of blocked referer domains does not add any extra costs to request processing.

map $http_referer $void_referer {
  hostnames;

  default                    0;
  "~*.example\.com"          1;
  "~*.example\.org"          1;
}

The regular expression is case-insensitive ~* and the .example.com will match hostnames like example.com, abcexample.com and sub.example.com.

Second step

Include blacklist in the main http block so it can be used in every protected server block.

http {

[...]

  # void_referer
  include referer_blacklist.conf;

[...]

Third step

Include referer validation in each server block you want to protect – return 403 Forbidden HTTP status code if referer matched.

server {

[...]

  if ($void_referer) {
    return 403;
  }

[...]

Fourth step

Reload nginx configuration.

$ sudo systemctl reload nginx

Fifth step

Verify HTTP status codes for common scenarios.

$ curl -s -o /dev/null -I -w "%{http_code}\n" https://blogsleeplessbeastie.wpcomstaging.com
200
$ curl -s -o /dev/null -I -w "%{http_code}\n" --referer http://google.com https://blogsleeplessbeastie.wpcomstaging.com
200
$ curl -s -o /dev/null -I -w "%{http_code}\n" --referer http://example.com https://blogsleeplessbeastie.wpcomstaging.com
403

References

Nginx map and referer modules.

Additional information

You can alternatively save the blacklist file inside /etc/nginx/conf.d/ directory as it is used to store global configuration directives in the default setup.