Good afternoon, look, I would like to know how to block the countries I need at this stage through nginx. Is there a solution through the standard firewall or do I need to do something myself?
Hi,
If you need to block some countries you can add them to ipsets and create firewall rules to DROP connections from those ipsets.
Take a look to this post:
Yes, but it blocks only by ip on the domain does not block
Sorry, I don’t understand what you mean by on the domain does not block. It’s a firewall rule that will block that IP, you don’t need to mess with Nginx to block those IPs.
Do you want to block countries only for one or x web domains in your server?
If you use Nginx+Apache2 you can use this guide to block them in Apache2.
If you use only Nginx, you must recompile it adding the GeoIP2 module, but I didn’t write a guide for that.
I’ve already solved this problem myself, there’s no simple firewall here
In fact, the only question was how to block separately countries on nginx not by IP server but by domain so that when a person goes to the site it shows him a custom page for example 403 so that type access is denied or something like that I tried through the standard firewall does not work only on a clean IP address without Cloudflare
Just share how you solved your issue. It might help future users
1. The Blocking File: /etc/nginx/deny-lists/block-countries.conf
This file contains the list of IP ranges (CIDR) that Nginx will reject.
A. Create the Directory Structure:
Bash
sudo mkdir -p /etc/nginx/deny-lists/
sudo chown -R www-data:www-data /etc/nginx/deny-lists/
B. Automate the IP List (Recommended): Manually maintaining thousands of IPs is impossible. Use this script to fetch fresh IP ranges for Russia (RU) and Belarus (BY).
-
Create the update script:
Bash
sudo nano /usr/local/bin/update-blocklist.sh -
Paste the following code:
Bash
#!/bin/bash
# Path to the blocklist file
BLOCK_FILE="/etc/nginx/deny-lists/block-countries.conf"
# Countries to block (ru = Russia, by = Belarus)
COUNTRIES=("ru" "by")
echo "# Updated: $(date)" > $BLOCK_FILE
for country in "${COUNTRIES[@]}"; do
echo "# Blocking $country" >> $BLOCK_FILE
# Fetch CIDR lists and format them for Nginx
curl -s https://www.ipverse.net/ipblocks/data/countries/$country.zone | awk '{print "deny " $1 ";"}' >> $BLOCK_FILE
done
# Test Nginx and reload if the config is valid
nginx -t && systemctl reload nginx
-
Make it executable:
Bash
sudo chmod +x /usr/local/bin/update-blocklist.sh
Check if the file contains data: cat /etc/nginx/deny-lists/block-countries.conf. It should be filled with lines like deny 5.101.0.0/18;.
2. Global Nginx Configuration: nginx.conf
Integrate the blocklist and set up the global error page paths.
-
Open
/etc/nginx/nginx.conf. -
Locate the
http { ... }block and insert these lines after the Cloudflare/Real-IP settings:
Nginx
http {
Global Country Blocklist
include /etc/nginx/deny-lists/block-countries.conf;
}
I use nginx for apache here is the instruction
Sorry, but having 8639 deny network rules in Nginx is a very inefficient way to do the job.
Which then do you think is effective with pleasure I want to see
Using GeoIP2 is pretty efficient but as I said, you must recompile Nginx to add that module. And for Apache, I shared a guide in a previous post.
geo $remote_addr $is_blocked { default 0; include /etc/nginx/deny-lists/block-countries.conf; }
If you recompile nginx, everything will be fine from the panel
geo is not the same as GeoIP2, but geo is much better than using deny rules.
I can’t remember whether the Nginx mainline version used by Hestia includes the geo module, but I believe it does, not as a module but included in the core so you could use it without recompiling Nginx.
Yes, no problem. I use a recompiled Nginx version to include several modules. Keep in mind that Hestia uses two Nginx instances: one to serve the control panel and another to serve your domains (this is the one that needs to be recompiled if you want to add modules).
But in your case, try the geo option.
OK, thank you