vyatta create firewall network group from geo ip table

The global Geo IP table is huge, and contains ranges of IP addresses that don’t necessarily fit into CIDR networks. Converting the IP ranges in the table into networks results in around 129,000 separate networks. Trying to define every network scope in the global table for inclusion in a firewall is well outside the realm of possibility. In the case of a few small countries, their ranges do actually fit into network groups. This is just a fun little exercise not to be used in production of course.

#!/usr/bin/perl
# FILE: netGroupCountry.pl
# AUTHOR: ForDoDone
# DATE: 2013-12-02
# NOTES: create a firewall network group for a specific country using a geoip table

use strict;
use Net::Netmask;

# download geoip table
# TODO: wget geoip table if doesn't exist, or if 1st wed of month

# set country here
# TODO: read from ARGV
# use Estonia for example it only has 236 IP ranges in table
my $country = 'EE';

# set geoip database CSV
my $geoIPDB='/var/lib/geoip/GeoIPCountryWhois.csv';

# open geoip table
open FILE, "$geoIPDB" or die $!;

# start the vyatta config wrapper
system("/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper begin");

# clear the old network group
system("/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper delete firewall group network-group $country");

# commit here optional
#system("/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper commit");

# setup commit counter for chunked commits
#my $i=0;
#my $chunk=100;

# read each line of the geoip table (~82k lines)
while(<FILE>){
  chomp;

  my @line = split(/"/,$_);

  # if country matches the one we want
  # convert the ip range to CIDR(s)
  # add the network to the network group
  if ("$line[9]" eq "$country" ){

    my @blocks = range2cidrlist("$line[1]","$line[3]");

        foreach(@blocks){
          my $setcmd = "set firewall group network-group $country network $_";
          system("/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper $setcmd");

          #print "set firewall group network-group $country network $_\n";

          # chunked commit
          #if ( $i % $chunk ){
          #  # do nothing
          #} else {
          #  print "committing after 100 entries... total: $i\n";
          #  system("/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper commit");
          #}
          #$i++;

        }

  }

}

# close geoip table
close FILE;

# run vyatta config wrapper to commit and end
system("/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper commit");
system("/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper end");
vyatta@vyatta:/usr/local/sbin$ time ./netGroupCountry.pl
Nothing to delete (the specified node does not exist)

real	1m3.515s
user	0m22.660s
sys	0m27.650s
vyatta@vyatta:/usr/local/sbin$

This definitely won’t work for larger networks, and who knows how it actually affects performance, I’ve never actually tried using the network group in the firewall.

Leave a Reply

Your email address will not be published. Required fields are marked *