content/blog/2022-11-29-nginx-referrer-ban-list.org

0b2895a90c7751ce06e4b26d4db41005ea2f40a9
cleberg.net/content/blog/2022-11-29-nginx-referrer-ban-list.org rendered · source · history · blame · raw

135 lines · 3353 bytes

  1#+date:        <2022-11-29 Tue 00:00:00>
  2#+title:       Configuration of Nginx to Block Unwanted HTTP Referrers
  3#+description: Technical guide to implementing a referrer ban list in Nginx configurations to prevent access from undesired domains and improve web server security.
  4#+slug:        nginx-referrer-ban-list
  5#+filetags:    :nginx:security:webserver:
  6
  7* Creating the Ban List
  8
  9In order to ban list referral domains or websites with Nginx, you need
 10to create a ban list file. The file below will accept regexes for
 11different domains or websites you wish to block.
 12
 13First, create the file in your nginx directory:
 14
 15#+begin_src sh
 16doas nano /etc/nginx/banlist.conf
 17#+end_src
 18
 19Next, paste the following contents in and fill out the regexes with
 20whichever domains you're blocking.
 21
 22#+begin_src conf
 23# /etc/nginx/banlist.conf
 24
 25map $http_referer $bad_referer {
 26    hostnames;
 27
 28    default                           0;
 29
 30    # Put regexes for undesired referrers here
 31    "~news.ycombinator.com"           1;
 32}
 33#+end_src
 34
 35* Configuring Nginx
 36
 37In order for the ban list to work, Nginx needs to know it exists and how
 38to handle it. For this, edit the =nginx.conf= file.
 39
 40#+begin_src sh
 41doas nano /etc/nginx/nginx.conf
 42#+end_src
 43
 44Within this file, find the =http= block and add your ban list file
 45location to the end of the block.
 46
 47#+begin_src conf
 48# /etc/nginx/nginx.conf
 49
 50http {
 51  ...
 52
 53  # Include ban list
 54  include /etc/nginx/banlist.conf;
 55}
 56#+end_src
 57
 58* Enabling the Ban List
 59
 60Finally, we need to take action when a bad referral site is found. To do
 61so, edit the configuration file for your website. For example, I have
 62all website configuration files in the =http.d= directory. You may have
 63them in the =sites-available= directory on some distributions.
 64
 65#+begin_src sh
 66doas nano /etc/nginx/http.d/example.com.conf
 67#+end_src
 68
 69Within each website's configuration file, edit the =server= blocks that
 70are listening to ports 80 and 443 and create a check for the
 71=$bad_referrer= variable we created in the ban list file.
 72
 73If a matching site is found, you can return any
 74[[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes][HTTP Status
 75Code]] you want. Code 403 (Forbidden) is logical in this case since you
 76are preventing a client connection due to a banned domain.
 77
 78#+begin_src conf
 79server {
 80  ...
 81
 82  # If a referral site is banned, return an error
 83  if ($bad_referer) {
 84    return 403;
 85  }
 86
 87  ...
 88}
 89#+end_src
 90
 91* Restart Nginx
 92
 93Lastly, restart Nginx to enable all changes made.
 94
 95#+begin_src sh
 96doas rc-service nginx restart
 97#+end_src
 98
 99* Testing Results
100
101In order to test the results, let's curl the contents of our site. To
102start, I'll curl the site normally:
103
104#+begin_src sh
105curl https://cleberg.net
106#+end_src
107
108The HTML contents of the page come back successfully:
109
110#+begin_src html
111<!doctype html>...</html>
112#+end_src
113
114Next, let's include a banned referrer:
115
116#+begin_src sh
117curl --referer https://news.ycombinator.com https://cleberg.net
118#+end_src
119
120This time, I'm met with a 403 Forbidden response page. That means we are
121successful and any clients being referred from a banned domain will be
122met with this same response code.
123
124#+begin_src html
125<html>
126    <head>
127        <title>403 Forbidden</title>
128    </head>
129    <body>
130        <center><h1>403 Forbidden</h1></center>
131        <hr />
132        <center>nginx</center>
133    </body>
134</html>
135#+end_src