cmc/cleberg.net

My personal web garden & blog.

clone: git clone https://gitbay.org/cmc/cleberg.net.git

main: content/blog/2022-11-29-nginx-referrer-ban-list.org · raw

  1#+date:        [2022-11-29 Tue 00:00:00]
  2#+title:       Nginx Referrer Ban List
  3#+description: Blocking unwanted referrers in Nginx with a simple ban list.
  4#+slug:        nginx-referrer-ban-list
  5#+filetags:    :linux:web:
  6
  7* Creating the Ban List
  8
  9In order to ban list referral domains or websites with Nginx, you need to create
 10a ban list file. The file below will accept regexes for different domains or
 11websites 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 whichever
 20domains 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 to
 38handle 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 location to
 45the 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 so,
 61edit the configuration file for your website. For example, I have all website
 62configuration files in the =http.d= directory. You may have them in the
 63=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 are
 70listening to ports 80 and 443 and create a check for the =$bad_referrer=
 71variable we created in the ban list file.
 72
 73If a matching site is found, you can return any [[https://en.wikipedia.org/wiki/List_of_HTTP_status_codes][HTTP Status Code]] you want. Code
 74403 (Forbidden) is logical in this case since you are preventing a client
 75connection due to a banned domain.
 76
 77#+begin_src conf
 78server {
 79  ...
 80
 81  # If a referral site is banned, return an error
 82  if ($bad_referer) {
 83    return 403;
 84  }
 85
 86  ...
 87}
 88#+end_src
 89
 90* Restart Nginx
 91
 92Lastly, restart Nginx to enable all changes made.
 93
 94#+begin_src sh
 95doas rc-service nginx restart
 96#+end_src
 97
 98* Testing Results
 99
100In order to test the results, let's curl the contents of our site. To start,
101I'll curl the site normally:
102
103#+begin_src sh
104curl https://cleberg.net
105#+end_src
106
107The HTML contents of the page come back successfully:
108
109#+begin_src html
110<!doctype html>...</html>
111#+end_src
112
113Next, let's include a banned referrer:
114
115#+begin_src sh
116curl --referer https://news.ycombinator.com https://cleberg.net
117#+end_src
118
119This time, I'm met with a 403 Forbidden response page. That means we are
120successful and any clients being referred from a banned domain will be met with
121this same response code.
122
123#+begin_src html
124<html>
125    <head>
126        <title>403 Forbidden</title>
127    </head>
128    <body>
129        <center><h1>403 Forbidden</h1></center>
130        <hr />
131        <center>nginx</center>
132    </body>
133</html>
134#+end_src