TIPS: block registrations based on country to avoid spam

Hi everyone,

This week, my peertube instance is the target of a huge spam attack. Bot were creating account every 9 minutes.
Many of them have IP from countries like indonesia, malaysia, etc.

So I used the nginx geoip module to block registration for IPs coming from there countries.

Following instructions are for debian.

First, to list countries :

  • install geoip-bin package
  • grep register /var/log/nginx/your_access.log | awk '{print $1}' | while read i; do echo "$i: "; geoiplookup $i; done

If you find many IPs from the same country… You got it !

To block these countries :

Check your nginx has geoip module with the command: nginx -V

In your /etc/nginx/nginx.conf, in the http block, and before any include:

    geoip_country /usr/share/GeoIP/GeoIP.dat;
    map $geoip_country_code $allowed_country {
                default yes;
                PH no;
                MYS no;

this is if you want a blacklist. If you want a whitelist, just exchange ‘yes’ and ‘no’

And in your /etc/nginx/sites-enabled/peertube :

    location / { ....


    location /api/v1/users/register {
      if ( $allowed_country = no ) {
        return 403 '{"error":"Your country is not allowed due to spam reasons. Please use the contact form."}';
      try_files /dev/null @peertube;
  location / {
    try_files /dev/null @peertube;
  location @peertube { ...

Users from blacklist countries can still use your instance. Only the registration form will be forbidden, and they will get the message you choose when they try to submit it.


Thansk for sharing. It might be useful to someone.

To those who wonder where the country codes are specified (as I deed before searching myself), look under map $geoip_country_code.... In johnLivingston sample, PH and MYS are those country codes.

I’m still trying to find the reasons about the try_files /dev/nulldirectives.

I’m a total noob to nginx… It’s the easier way I found to avoid copying the whole “location /” for “location /api/v1/register”. And try_files requires 2 arguments. I found this trick on stackoverflow

Nevermind. Thanks anyway.

In order to work with IPV6, you have to use the file /usr/share/GeoIP/GeoIPv6.dat
This file works for both IPV6 et IPV4.

It seems that my trick with the «location @peertube» breaks uploads. The client_max_body_size is is ignored.
I’m a total noob with nginx, so finaly, I copied the standard «location /» in the «location /api/v1/users/register»

Edited first post to add formatting.