How to drop requests with an empty user agent?

I’m getting a lot of bad bots/crawlers hitting my Discourse site with an empty user agent. Normally I’d edit the nginx configuration to do this, but this isn’t accessible when using the Docker installation method. I don’t really want to add an extra RP just for this if I can avoid it.

1 Like

You can look at discourse_docker/web.ratelimited.template.yml at main · discourse/discourse_docker · GitHub as an example of how to modify the nginx config inside the container.


For anyone else wanting to do this specifically, I created /var/discourse/templates/web.blockemptyua.yml with the following contents:

  - replace:
     filename: "/etc/nginx/conf.d/discourse.conf"
     from: /listen 443 ssl http2;/
     to: |
       listen 443 ssl http2;
       if ($http_user_agent = "") { return 403; }

Then in /var/discourse/containers/app.yml I added this new template file to the end of the list of templates at the top of the file, followed by ./launcher rebuild app

Nginx now rejects all requests with an empty UA.

Edit: Changed the match/replace to be in a better place.


I don’t know docker, so just to be on safe side, because I’ll be nervous everytime I see replace anywhere…

This isn’t replacing totally content of discourse.conf but adding that, is it?

It’s replacing a line within the file. So it finds the first instance of:

listen 443 ssl http2;

And replaces it with

listen 443 ssl http2;
if ($http_user_agent = "") { return 403; }

So that we’re just adding a new line to the file in the correct place. None of the rest of the file is touched. It uses the same mechanism as the official templates to patch the file safely.


As I said earlier I don’t know docker. I’m just poor end user with PhD of copy&paste.

That’s why one notice to future searchers:

web.blockemptyua.yml can’t be very first one of declared templates. More precisely it has to come after web.template.yml (of perhaps even after every web.* templates).

Order has meaning here I reckon and if I/we are trying to work with it as first one rebuilding/bootstrapping stops with error because there isn’t any /etc/nginx/conf.d/discourse.conf at that moment.

Well, every day something new :wink:

1 Like

Indeed, it does need to go at the end. I’ve edited my post to include that :+1:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.