# Block traffic based on GeoIP



## UltraLinuz (Jan 6, 2009)

I would like to add a rule to my pfi.conf that *blocks* any incoming *traffic based on* the *geografic location* of the *IP-address*. 

for example I would only allow IP addresses from France to access my apache server. All other trafic should be blocked.

As it looks to me one can do pretty advanced thing in pf but I am a complete newbee to FreeBSD. It looks to me that one somehow needs to use *GeoIP* and use *geoiplookup* to determine the origin of the IP address. 

Is this somehow possible?


----------



## danger@ (Jan 7, 2009)

I doubt this is possible to do with any firewall package available in FreeBSD. One thing that comes to my mind is to do a geoip based dns routing, i.e. you route DNS queries from France to the real web server, and others, say, to 127.0.0.1...

I can provide you with a patch for bind to do that.


----------



## Djn (Jan 7, 2009)

Alternatively, you could set up a named list of blocked networks, and then use pfctl to populate it from a cron job?
(Assuming there's some way to pick out the networks representing the relevant countries.)


----------



## anomie (Jan 7, 2009)

Well, you could use the per-country IP network lists: http://www.ipdeny.com/ipblocks/

As a security measure I'm not sure how effective this will be against a determined attacker. He can simply stage an attack from inside one of the (many) allowed networks.


----------



## Djn (Jan 7, 2009)

True, but there are large botnets or something operating from a few specific countries - blocking them will remove quite a lot of the log noise.


----------



## UltraLinuz (Jan 8, 2009)

Hehehe! This looks great!

It's a little bit of a hassle handeling the files but it will work. I wasn't aware of ipdeny.com but it will basically result in the same, most likely even with better performance.

And indeed it's not a very reliable protection mechanism, but I'd like to get rid of all this spam and intrision attempts from these few countries I really never visit, mail nor offer any services to.


----------



## Maurovale (Jan 11, 2009)

Hi there is a Mod of geoip that you can use with apache (http://www.maxmind.com/app/mod_geoip).

But also as already been said you can you the IPs from ipdeny (http://www.ipdeny.com/) and use it directly with pf firewall or make a script to load the rules in your firewall in case you use ipfw.

Best Regards


----------



## Excalibur (Jan 12, 2010)

Well, using the ipdeny blocks seems to be a good idea. But won't that slow down things a bit? If you're blocking like 25 countries from a server like I'm doing with IPTables&GeoIP on RHEL, that would be crazy because of how many IP-blocks you need to add.

I'm not sure what is the best method to block 25+ countries w/o slowing down things like crazy.

Additionally, Apache's GeoIP isn't really that helpful, it doesn't prevent access to the server itself from blocked hosts.

Ideas/Suggestions?


----------



## Ruler2112 (Jan 13, 2010)

I created a script to block IPs listed in the EmergingThreats.org list, updating both the list and firewall from the nightly cron job.  It would be very simple to run a separate copy from cron for each country you wish to block and thereby have an updated list and firewall for each.

There's also some discussion on the efficiency and memory usage of having huge tables of IPs to block in that thread.  Basically, pf sorts the IPs when it adds them to a table so lookups are very fast and the amount of memory consumed is inconsequential.

That ipdeny site is great - I never knew such a thing existed before!


----------



## Excalibur (Jan 13, 2010)

I'm sorry, as I'm really new to FreeBSD, does this work with IPFW as well?



			
				Ruler2112 said:
			
		

> I created a script to block IPs listed in the EmergingThreats.org list, updating both the list and firewall from the nightly cron job.  It would be very simple to run a separate copy from cron for each country you wish to block and thereby have an updated list and firewall for each.
> 
> There's also some discussion on the efficiency and memory usage of having huge tables of IPs to block in that thread.  Basically, pf sorts the IPs when it adds them to a table so lookups are very fast and the amount of memory consumed is inconsequential.
> 
> That ipdeny site is great - I never knew such a thing existed before!


----------



## ctaranotte (Jan 14, 2010)

I have found GEOIP more accurate than IPDENY (purely subjective).

mod_geoip is 100% working, maybe you should check your httpd.conf

Anyway, if you want to go the pf + GeoIP route:

1) jail httpd (man jail for more info)
2) look at net/tableutil in ports
3) visit tableutil home
4) look at the example of script handling peerguardian blocklists (GeoIP lists share the same format)
5) between 
	
	



```
gunzip -c - | sed "s/.*:\([0-9.-]\)/\1/" | \
```
 and 
	
	



```
tableutil -q text 2> /dev/null > /tmp/blocklist
```
 insert some grep instructions to keep only the countries of interests.

Last words, in this script, the pf table is in etc/pfdata/blocklist.

Good luck,


----------



## aragon (Jan 14, 2010)

You could do it in real time asynchronously with pflogd and a userland app.  It would work something like this:

1. Setup a pf rule set with two rules that log: (a) block rule that blocks source addresses that are added to a pf IP table, (b) accept rule that matches the first packet of every connection that isn't blocked above.

2. Write a daemon that tails pflogd's log file and does a GeoIP lookup on each block and accept log entry.  If the IP is french, remove it from the blocking IP table.  If it is non-french, add it to the blocking IP table.


----------



## Ruler2112 (Jan 14, 2010)

Excalibur said:
			
		

> I'm sorry, as I'm really new to FreeBSD, does this work with IPFW as well?



The script basically handles the downloading and management of old versions of the file you download, then runs a command to refresh the firewall table.  So the script will, but I don't know how to do the ipfw portion of it.  You'd have to figure out how to create a table in the firewall, then set the correct variable in the script to whatever shell command updates the firewall table.


----------



## sniper007 (Mar 12, 2010)

I figure out this site 
http://www.ipaddresslocation.org/ip_ranges/get_ranges.php

is more more accurate (for my country)  than ipdeny.

The darkside of this page is output because don't create pure txt file with IP blocks, which is very useful for writing script (for updating)


----------

