aboutsummaryrefslogtreecommitdiff
path: root/content/blog/2022-11-29-nginx-referrer-ban-list.md
blob: ea627224b55bac4ba3920a91df468f16819c0586 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
+++
date = 2022-11-29
title = "Creating a Referrer Ban List in Nginx"
description = "Learn how to create a ban list for referring sites in Nginx."
+++

## Creating the Ban List

In order to ban list referral domains or websites with Nginx, you need
to create a ban list file. The file below will accept regexes for
different domains or websites you wish to block.

First, create the file in your nginx directory:

```sh
doas nano /etc/nginx/banlist.conf
```

Next, paste the following contents in and fill out the regexes with
whichever domains you're blocking.

```conf
# /etc/nginx/banlist.conf

map $http_referer $bad_referer {
    hostnames;

    default                           0;

    # Put regexes for undesired referrers here
    "~news.ycombinator.com"           1;
}
```

## Configuring Nginx

In order for the ban list to work, Nginx needs to know it exists and how
to handle it. For this, edit the `nginx.conf` file.

```sh
doas nano /etc/nginx/nginx.conf
```

Within this file, find the `http` block and add your ban list
file location to the end of the block.

```conf
# /etc/nginx/nginx.conf

http {
  ...

  # Include ban list
  include /etc/nginx/banlist.conf;
}
```

## Enabling the Ban List

Finally, we need to take action when a bad referral site is found. To do
so, edit the configuration file for your website. For example, I have
all website configuration files in the `http.d` directory.
You may have them in the `sites-available` directory on some
distributions.

```sh
doas nano /etc/nginx/http.d/example.com.conf
```

Within each website's configuration file, edit the `server`
blocks that are listening to ports 80 and 443 and create a check for the
`$bad_referrer` variable we created in the ban list file.

If a matching site is found, you can return any [HTTP Status
Code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) you want.
Code 403 (Forbidden) is logical in this case since you are preventing a
client connection due to a banned domain.

```conf
server {
  ...

  # If a referral site is banned, return an error
  if ($bad_referer) {
    return 403;
  }

  ...
}
```

## Restart Nginx

Lastly, restart Nginx to enable all changes made.

```sh
doas rc-service nginx restart
```

## Testing Results

In order to test the results, let's curl the contents of our site. To
start, I'll curl the site normally:

```sh
curl https://cleberg.net
```

The HTML contents of the page come back successfully:

```html
<!doctype html>...</html>
```

Next, let's include a banned referrer:

```sh
curl --referer https://news.ycombinator.com https://cleberg.net
```

This time, I'm met with a 403 Forbidden response page. That means we
are successful and any clients being referred from a banned domain will
be met with this same response code.

```html
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>
```