# How to block an IP range? "Screened IPs" not being blocked

**URL:** https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851
**Category:** Support
**Created:** [27 באוקטובר,‏ 2025,‏ 5:32pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851 "2025-10-27T17:32:58Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 5:32pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/1 "2025-10-27T17:32:58Z")

</div>

Hi there, I’m trying to temporarily block an abusive `/16` subnet that is slamming a Discourse forum with requests. I tried this…

> [@How can I block an IP address? are there wildcards?](https://meta.discourse.org/t/how-can-i-block-an-ip-address-are-there-wildcards/25299/2):
>
> Yes, go to Admin, Logs, Screened IPs. either star wildcard or the crazy standard subnet nomenclature will work.

…but I’m still seeing a huge number of new requests from the same range in `/var/discourse/shared/standalone/log/var-log/nginx/access.log` .

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [27 באוקטובר,‏ 2025,‏ 6:46pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/2 "2025-10-27T18:46:38Z")

</div>

Since these are configured in Discourse, I’m pretty sure that the IPs are blocked by Discourse, not NGINX, so they’ll show up in the NGINX logs. It’s Discourse that’s blocking them, not nginx. If you want to block them so that they don’t show up in the NGINX logs you could block them with your firewall.

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 6:56pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/3 "2025-10-27T18:56:00Z")

</div>

Thanks Jay, you’re right about how it would still show up in the Nginx logs if blocked at the application level. However, the blocking at the application level isn’t doing what I would expect either. I tried connecting via a VPN and then I added my own IP address to the “Screened IPs” list, but it still allowed me to navigate the forum. I think that it must be called “Screened IPs” and not “Blocked IPs” because maybe it only prevents those IPs from registering an account?

What I need is for the Discourse app to deny access to the requested pages for requests coming from those addresses, and especially for it to not render those pages, as all of those requests are pegging the CPU.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [27 באוקטובר,‏ 2025,‏ 7:22pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/4 "2025-10-27T19:22:55Z")

</div>

Does Discourse see that you’re coming from one of the banned IPs if you go look at the user record from /admin/users? (If you’re behind a proxy like cloudflare, then Discourse may be seeing your proxy IP and not the IP of the user.)

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 7:37pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/5 "2025-10-27T19:37:15Z")

</div>

Yep, when I connect to the VPN and then look at the last IP of my user account in Discourse it shows the IP that my VPN gave me. However, when I open an incognito browser window and try to register a new account then it doesn’t allow it:

> New registrations are not allowed from your IP address.

So it appears that “Screened IPs” are just for registration, not for completely disallowing access to the website.

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 7:49pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/6 "2025-10-27T19:49:10Z")

</div>

And to further complicate things, `ufw` / nftables on the host server apparently doesn’t block things as expected inside Docker:

> [@Will UFW limit Discourse too?](https://meta.discourse.org/t/will-ufw-limit-discourse-too/231873/12):
>
> This is actually a really good question and one I’m surprised nobody else has yet asked. The answer is complicated, but so far the responses on this topic have unfortunately been dismissive in tone without answering the question. It isn’t per se that Discourse is bypassing ufw, but docker bypasses ufw by adding rules that cause any exposed ports of docker containers to work despite the presence of ufw. What’s going on? Incoming packets destined for a container hit the FORWARD table, not the IN…

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [27 באוקטובר,‏ 2025,‏ 7:54pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/7 "2025-10-27T19:54:26Z")

</div>

> [@sb56637](#):
>
> So it appears that “Screened IPs” are just for registration, not for completely disallowing access to the website.

I’m not sure where we document this but it’s come up a couple times recently.

“Screened IPs” blocks registrations and logins from blocked IPs that match, but not existing sessions.

I’m not sure where (if) we document this.

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 7:57pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/8 "2025-10-27T19:57:35Z")

</div>

Thanks for confirming.

So what would be the easiest method to deny requests from an IP or range of IPs? I found this, but it appears to be the opposite of what I need (whitelist rather than a blacklist), and messing around with the Nginx config inside the container feels like a total hack job:

> [@How to disable access to anyone not coming from a specific IP address](https://meta.discourse.org/t/how-to-disable-access-to-anyone-not-coming-from-a-specific-ip-address/114907/8):
>
> @pfaffman thank you for the pointers. I fixed it slight_smile Here is solution in case someone needs it. ./launcher enter app from /var/discourse folder Go to '/etc/nginx/ folder and create file ‘whitelist-ip.conf’ add below lines in ‘whitelist-ip.conf’ file allow 192.168.1.1; deny all; open /etc/nginx/conf.d/discourse.conf go to line no 37 see below section, it is for port 443 server { include /etc/nginx/whitelist-ip.conf; } add line ‘include /etc/nginx/whitelist-ip.conf;’ Test Ngin…

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [27 באוקטובר,‏ 2025,‏ 8:03pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/9 "2025-10-27T20:03:41Z")

</div>

> [@sb56637](#):
>
> So what would be the easiest method to deny requests from an IP or range of IPs?

I think doing it with UFW or IPTABLES . That removes stops it before Discourse gets involved. I’m always vague terrified mucking with firewalls for fear that I’ll lock myself out, but if you target just port 443 you aren’t in any danger.

Digital Ocean has some hints: [UFW Essentials: Common Firewall Rules and Commands for Linux Security | DigitalOcean](https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands). I’d just Google for examples.

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 8:06pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/10 "2025-10-27T20:06:09Z")

</div>

> [@pfaffman](#):
>
> I’m always vague terrified mucking with firewalls for fear that I’ll lock myself out, but if you target just port 443 you aren’t in any danger.

Exactly my fear as well. But I did enable it on the host and yet it’s still not blocking the problematic IP range. Apparently it needs a convoluted set of rules to make it apply the deny rules to the Docker containers.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [27 באוקטובר,‏ 2025,‏ 8:08pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/11 "2025-10-27T20:08:31Z")

</div>

> [@sb56637](#):
>
> Apparently it needs a convoluted set of rules to make it apply the deny rules to the Docker containers.

Oh. Yeah. That’s totally true. I ended up blocking access from my docker-based web servers to the docker-based postgres database (likely not one of your problems).

Here’s another idea: [Geo Blocking plugin](https://meta.discourse.org/t/geo-blocking-plugin/227824)

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 8:09pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/12 "2025-10-27T20:09:28Z")

</div>

> [@pfaffman](#):
>
> Here’s another idea: [Geo Blocking plugin](https://meta.discourse.org/t/geo-blocking-plugin/227824)

Thanks, I was looking at that too, but it doesn’t appear to allow blocking numeric IP ranges, just entire countries?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [27 באוקטובר,‏ 2025,‏ 8:14pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/13 "2025-10-27T20:14:26Z")

</div>

> [@sb56637](#):
>
> it doesn’t appear to allow blocking numeric IP ranges,

I haven’t installed it lately, but I’m pretty sure that it does

> [@Geo Blocking plugin](https://meta.discourse.org/t/geo-blocking-plugin/227824/1):
>
> This can be used to completely block access to your forum for certain countries **or networks** , for example fraud prevention or to comply with sanctions.

(emphasis added)

But then I found this:

> <https://github.com/communiteq/discourse-geo-blocking/blob/master/config/settings.yml#L23>

So I think that means you can put in whatever network you want there.

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [27 באוקטובר,‏ 2025,‏ 8:18pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/14 "2025-10-27T20:18:40Z")

</div>

```plaintext
/var/discourse/launcher enter app
apt install nano
nano /etc/nginx/conf.d/discourse.conf

```

And in the `server {` block add:

```plaintext
## 2025-10-27
deny 12.34.0.0/16;

```

Then save and

```plaintext
nginx -t
service nginx reload

```

I don’t quite understand why I’m still seeing hits from `12.34.x.x` in the Nginx `access.log`, but it does seem to be working because the CPU usage is now normal again. Incredibly convoluted process IMHO, but good enough for now to get the site back up off its knees.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [27 באוקטובר,‏ 2025,‏ 8:45pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/15 "2025-10-27T20:45:49Z")

</div>

> [@pfaffman](#):
>
> So I think that means you can put in whatever network you want there.

Yes, but currently it will only take AS numbers and not CIDR notation like 1.2.3.0/24.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [27 באוקטובר,‏ 2025,‏ 9:15pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/16 "2025-10-27T21:15:18Z")

</div>

> [@sb56637](#):
>
> ```plaintext
> service nginx reload
> 
> ```

Did that work? I think you need to do

```
sv restart nginx

```

But if you didn’t get an error I’m wrong.

> [@sb56637](#):
>
> I don’t quite understand why I’m still seeing hits from `12.34.x.x` in the Nginx `access.log`,

Nginx is still seeing those? Does it show that it’s serving them? Do you see those in the rails production.log?

> [@RGJ](#):
>
> Yes, but currently it will only take AS numbers and not CIDR notation like 1.2.3.0/24.

Ah. Maybe I should have paid more attention to that wikipedia page about AS numbers.

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [28 באוקטובר,‏ 2025,‏ 12:48am UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/17 "2025-10-28T00:48:00Z")

</div>

> [@pfaffman](#):
>
> > [@sb56637](#):
> >
> > ```plaintext
> > service nginx reload
> > 
> > ```
> 
> Did that work? I think you need to do
> 
> `sv restart nginx`

I think they’re both old aliases that are now mapped to systemd commands, ~~so `systemctl restart nginx` would be the most proper.~~  
_ **EDIT:** _ _It appears that `systemctl` doesn’t work inside Docker. Here are some explanations about the differences:_

- [https://serverfault.com/questions/867322/what-is-the-difference-between-service-and-systemctl](https://serverfault.com/questions/867322/what-is-the-difference-between-service-and-systemctl)
- [https://askubuntu.com/questions/903354/difference-between-systemctl-and-service-commands/903405](https://askubuntu.com/questions/903354/difference-between-systemctl-and-service-commands/903405)

> [@pfaffman](#):
>
> > [@sb56637](#):
> >
> > I don’t quite understand why I’m still seeing hits from `12.34.x.x` in the Nginx `access.log`,
> 
> Nginx is still seeing those? Does it show that it’s serving them? Do you see those in the rails production.log?

Yep, in the `access.log` they are still appearing like:

`[28/Oct/2025:00:29:27 +0000] "myforum.com" 12.34.56.78 "GET /permalink/12345 HTTP/1.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" "-" 403 691 "-" - 0.000 "-" "-" "-" "-" "-" "-" "-"`

They seem to be mainly hitting permalinks now (migrated from an old forum platform). Is there some kind of a loophole with permalinks that lets it get around the `deny` rule? I haven’t checked the `production.log` yet.

Overall I would say that the lack of a GUI to inspect the access logs and no app-level IP blocklist is quite a significant limitation of Discourse. It’s an infrequent occurrence, but when you do get hit by one of these bot/scraper/crawler attacks you just want to immediately identify the source and mitigate it, without mucking about in a bunch of config files and arcane commands, especially not levels deep inside a Docker container with all the weird abstraction that takes place there. The very old forum platform I migrated from showed a simple list of the users or IPs with the highest number of requests during an adjustable time window, and it could even be filtered by which users and/or IPs occupied the highest amount of CPU time. That way I could quickly identify the offending address or range, and then there was a point-n-click interface to add it to a blocklist, and it would throw a 404 for requests from those IPs.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [28 באוקטובר,‏ 2025,‏ 6:55am UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/18 "2025-10-28T06:55:07Z")

</div>

There is no problem.

> [@sb56637](#):
>
> Yep, in the `access.log` they are still appearing like:
> 
> `[28/Oct/2025:00:29:27 +0000] "myforum.com" 12.34.56.78 "GET /permalink/12345 HTTP/1.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" "-" 403 691 "-" - 0.000 "-" "-" "-" "-" "-" "-" "-"`

If you have a `deny` rule, things still get logged in nginx. And it works correctly, because there is a `403` there, which means the client was denied access.

These requests are **not** being forwarded to Discourse. If you want to know whether your blocking is working correctly, you should either

- look in the Discourse `production.log` instead
- look in the nginx logs but ignore any entry that has a `403` in the HTTP response code field.

---

<div class="post-metadata">

### Author: ![tobiaseigen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/tobiaseigen/32/539204_2.png) [@tobiaseigen](https://meta.discourse.org/u/tobiaseigen)
#### Post date: [12 בנובמבר,‏ 2025,‏ 9:57pm UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/19 "2025-11-12T21:57:15Z")

</div>

Is this topic now solved? Is there one post @rgj or @pfaffman that I can choose as the solution? Seems you collaborated on this one!

🤝

---

<div class="post-metadata">

### Author: ![sb56637](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sb56637](https://meta.discourse.org/u/sb56637)
#### Post date: [13 בנובמבר,‏ 2025,‏ 2:12am UTC](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851/20 "2025-11-13T02:12:28Z")

</div>

Hi there, I would say that this issue isn’t really solvable at present via “normal” methods. The admin interface for “Screened IPs” doesn’t do what most users would probably expect, and the method that actually works involves messing around with config files inside Discourse’s Docker container, so it’s more like a dirty hack rather than a solution, at least IMHO. It would be great if this got a bit more traction:

> [@GUI for inspecting access logs and IP block lists](https://meta.discourse.org/t/gui-for-inspecting-access-logs-and-ip-block-lists/386981):
>
> This idea comes from: It’s an infrequent occurrence, but when the forum gets hit by a bot/scraper/crawler attack the admin needs to quickly identify the source’s IP address/range and mitigate it, without mucking about in a bunch of config files and arcane commands, especially not levels deep inside a Docker container with all the weird abstraction that takes place there. What I am used to from other forum platforms is an admin GUI with a simple list of the users or IPs with the highest numbe…

[Next page](https://meta.discourse.org/t/how-to-block-an-ip-range-screened-ips-not-being-blocked/386851.md?page=2)
