ipfw divert filter for IPv4 geo-blocking

olli hauer ohauer at gmx.de
Wed Jul 27 20:08:56 UTC 2016


On 2016-07-27 15:36, Dr. Rolf Jansen wrote:
>> Am 26.07.2016 um 23:03 schrieb Julian Elischer <julian at freebsd.org>:
>> On 27/07/2016 3:06 AM, Dr. Rolf Jansen wrote:
>>> There is another tool called geoip , that I uploaded to GitHub, and that I use for looking up country codes by IP addresses on the command line.
>>>
>>>     https://github.com/cyclaero/ipdb/blob/master/geoip.c
>>>
>>> This one could easily be extended to produce sorted IP ranges per CC that could be fed into tables of ipfw. I am thinking of adding a command line option for specifying CC's for which the IP ranges should be exported, something like:
>>>
>>>    geoip -e DE:BR:US:IT:FR:ES
>>>
>>> And this could print sorted IP-Ranges belonging to the listed countries. For this purpose, what would be the ideal format for directly feeding the produced output into ipfw tables?
>> The format for using tables directly is the same as that used for routing tables.
>>>> table 5 add 1.1.1.0/32 1000
>>>> your application becomes an application for configuring the firewall.
>> (which you do by feeding commands down a pipe to ipfw, which is started as 'ipfw -q /dev/stdin')
> 
> I finished adding a second usage form for the geoip tool, namely generation of ipfw table construction directives filtered by country codes.
> 
> ______________
> $ geoip -h
> geoip v1.0.1 (16), Copyright © 2016 Dr. Rolf Jansen
> 
> Usage:
> 
> 1) look-up the country code belonging to an IPv4 address given by the last command line argument:
> 
>    geoip [-r bstfile] [-h] <dotted IPv4 address>
>       <IPv4 address>    a dotted IPv4 address to be looked-up.
> 
> 2) generate a sorted list of IPv4 address/masklen pairs per country code, formatted as ipfw table construction directives:
> 
>    geoip -t [CC:DD:EE:..] [-n table number] [-v table value] [-r bstfile] [-h]
> 
>       -t [CC:DD:EE:..]  output all IPv4 address/masklen pairs belonging to the listed countries, given by 2 letter
>                         capital country codes, separated by colon. An empty CC list means any country code.
>       -n table number   the ipfw table number between 0 and 65534 [default: 0].
>       -v table value    the 32-bit unsigned value of the ipfw table entry [default: 0].
> 
> valid arguments in both usage forms:
> 
>       -r bstfile        the path to the binary file with the consolidated IP ranges that has been.
>                         generated by the 'ipdb' tool [default: /usr/local/etc/ipdb/IPRanges/ipcc.bst].
>       -h                show these usage instructions.
> ______________
> 
> With that, the ipfw configuration script may contain something alike:
> 
>>     # allow only web access from DE, BR, US:
>     /usr/local/bin/geoip -t DE:BR:US -n 7 | /sbin/ipfw -q /dev/stdin
>     /sbin/ipfw -q add 70 deny tcp from not table\(7\) to any 80,443 in recv WAN_if setup
>> 
> OR, the other way around:
>>     # deny web access from certain disgraceful regions:
>     /usr/local/bin/geoip -t KO:TR:SA:RU:GB -n 66 | /sbin/ipfw -q /dev/stdin
>     /sbin/ipfw -q add 70 allow tcp from not table\(66\) to any 80,443 in recv WAN_if setup
>> ____________
> 
> 
> Best regards
> 
> Rolf

Nice work :)

Now it is also possible to use geoip to create files usable for pf.
(just pipe the output through sed -e 's/table 0 add //')

Perhaps the following diff for Makefile is useful.
- use PREFIX instead hard coded path
- use "install -s" instead "strip -x -o"
- use "install -m" instead "cp ; chmod"


--- Makefile.orig       2016-07-27 21:44:25.617707000 +0200
+++ Makefile    2016-07-27 21:47:18.341092000 +0200
@@ -43,6 +43,7 @@
 CC        = clang
 CFLAGS    = $(CDEFS) -DSVNREV=\"$(REVNUM)\" -std=c11 -g0 -Ofast -mssse3 -Wno-parentheses -Wno-empty-body
 LDFLAGS   = -lm
+PREFIX    ?= /usr/local

 HEADER    = store.h
 SOURCES   = store.c ipdb.c geoip.c geod.c
@@ -71,9 +72,8 @@
 update: clean all

 install: ipdb geoip geod
-       strip -x -o /usr/local/bin/ipdb ipdb
-       strip -x -o /usr/local/bin/geoip geoip
-       strip -x -o /usr/local/bin/geod geod
-       cp geod.rc /usr/local/etc/rc.d/geod
-       chmod 555 /usr/local/etc/rc.d/geod
-       cp ipdb-update.sh /usr/local/bin/ipdb-update.sh
+       install -s -m 555 ipdb ${PREFIX}/bin/ipdb
+       install -s -m 555 geoip ${PREFIX}/bin/geoip
+       install -s -m 555 geod ${PREFIX}/bin/geod
+       install -m 555 geod.rc ${PREFIX}/etc/rc.d/geod
+       install -m 555 ipdb-update.sh ${PREFIX}/bin/ipdb-update.sh


-- 
olli


More information about the freebsd-ipfw mailing list