7

I would like to allow traffic from one country only.

I have seen and read online multiple ways, but most of them are outdated (with Xtables-addons), and the other half show how to blacklist IPs that one dose not like.

However this is a wrong approach, to black list everything one by one. A better approach will be to do a white list so everything beside that white list will be blocked.

I am in France; I want to allow only french clients/users to access the server.

The iptables rule I have inplace is

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination xx.xx.xx.xx:80

just forwarding traffic.

ctrl-alt-delor
  • 27,473
  • 9
  • 58
  • 102
teran
  • 71
  • 1
  • 1
  • 2
  • You will need a list of all IP addresses that are in your country. These exist, but are buggy; Because the IPv4 addresses are running out, IP addresses are being allocated in a strange way that makes it impossible to be reliable. You will get false positives, and false negatives. (Then there are VPNs, these can be used to get around what ever you do. By blocking traffic by country, you become part of the marketing department of the VPN providers.). – ctrl-alt-delor May 01 '19 at 07:57
  • Apache or Nginx? Please add to the question. Any know framework, like PHP/Magento/Drupal? Answers would be much better with more data. – Rui F Ribeiro May 01 '19 at 08:00
  • no framework. this is before it reach the framework, firewall wise with iptables – teran May 01 '19 at 08:45
  • 2
    Just a side note, be very careful about the legal implications when restricting traffic from other EU countries. Free movement of goods / services has caught out a number of companies this way in the past. – Philip Couling May 01 '19 at 09:38
  • You might have French clients/users who are Internet-connected to points outside your country. Also, do you need to consider Réunion and other _départements d'outre-mer_? – roaima May 01 '19 at 10:09
  • this is for security purposes, only french ip users will be able to connect to the server for example ssh or any other service i put on on the server. that way, bots/crawlers/hackers that will scan from outside france wont be able to see open ports\service unless they scan from a french ip. this is usefull for lots of application – teran May 01 '19 at 11:30
  • See [this answer](https://unix.stackexchange.com/a/527504/7286) to the same question. For European countries, you can get a list of IPs from RIPE (the official registry) so you don't need to rely on something compiled by some private company. Then you just use that list with standard `ipset` rules. – mivk Feb 06 '20 at 12:22

3 Answers3

4

I'm not suggesting this is the best option, but if you can't find another that works then you could "roll your own" using a downloadable GeoIP database and the ipset tool.

For example download the Geolite2 database Countries in CSV format. Download and unzip the files:

wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
unzip GeoLite2-Country-CSV.zip
cd GeoLite2-Country-CSV_20190430

Find the id for France and filter all records for french networks:

grep France GeoLite2-Country-Locations-en.csv
3017382,en,EU,Europe,FR,France,1

awk -F, '$2 == 3017382 {print $1}' > french_networks.txt

Build an ipset containing french networks called france:

ipset create france hash:net
while read network ; do 
    ipset add france $network; 
done < french_networks.txt

Use the ipset to create an iptables rule which drops anything not from France. Note you might need to add extra rules ensure local networks are not dropped:

iptables -A INPUT -m set ! --match-set france src -j DROP
Philip Couling
  • 17,591
  • 5
  • 42
  • 82
  • trying to do it but iptables v1.6.1: Set !france doesn't exist. Try `iptables -h' or 'iptables --help' for more information. – teran May 01 '19 at 13:35
  • I'll admit I've not tried using `!` before to match IPs not in set. Alternatively you might be able to `iptables -A INPUT -m set --match-set 'france' src -j ACCEPT` might work, then put a blanket `iptables -A INPUT -j DROP` rule after it. – Philip Couling May 01 '19 at 13:40
  • the ! should be after set, iptables -A INPUT -m set ! --match-set france src -j DROP however ! one problem happen. when applying ur way, u have no ping to the outside world . tried to ping google nothing :P, after removing the rule, ping started work again. – teran May 01 '19 at 13:52
  • @teran I've edited to correct. This rule will block ALL traffic that isn't with a French IP. If you'd like to allow outgoing connections to communicate elsewhere then you can add a specific rule to allow this. – Philip Couling May 01 '19 at 14:28
  • 1
    actually , it does not work. :s i tried to access my server from outside france and i am still able to reach the server. – teran May 01 '19 at 15:03
  • @teran free geolite may be outdated. You can test if your ip in that list with 'ipset test france ' command. If your ip in that list, be sure you write your rule to correct chain. – ibrahim May 02 '19 at 06:39
  • a **month** later, i have not find a solution yet :s maybe some one knows a free linux application perhaps in github that does such thing ? my server is being spammed and attack from outsiders , i wish to allow only one country, why is that so difficult xD . – teran Jun 24 '19 at 20:35
  • @teran because **the internet isn't designed that way**. IP addresses do not contain a geographical component. So any solution will at its heart be based on a geo-ip database as ive described. If you cant easily find one of those then any app developer will face the same problem. – Philip Couling Jun 24 '19 at 22:02
  • ofc , i know that ;) but what u wrote did not work, at the 1 of may i update my post that it does not work, i tried with different country. perhpas i did something wrong, have u tried it urself ? – teran Jun 27 '19 at 20:25
1

You can easily get the France IPs for the iptables using the below page.

https://www.ip2location.com/free/visitor-blocker

In that page, choose France then select "Linux iptables accept" as the output format.

Vlam
  • 111
  • 2
0

You can try csf - it's easy to install, and in csfpost.sh you can set you iptables rules. in csf.conf you have CC_ALLOW_FILTER where you can set FR. Please check web documentation and a word of advice - access to console on server is a good ideea, just in case you lock yourself out hehe.