content/blog/2022-11-29-nginx-referrer-ban-list.org
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