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