First off, let me preface this by saying I am not running Debian and getting aggregate-flim setup and running was a little too difficult. But no matter, perl can be used to pull off the same functionality by aggregating the CIDR records. A big thanks to zwitterion.org.
The first script, list-iana-reserved-ranges grabs all of the IANA reserved address ranges and outputs them.
#!/usr/bin/perl -Tw
# [MJS 22 Oct 2001] List IANA Reserved ranges (for firewall purposes)
# [MJS 3 Mar 2008] IANA reformated document to use /8s and not ranges
use strict;
use LWP;
#
# Download Official IANA document
#
my $ua = new LWP::UserAgent;
my $res = $ua->get('http://www.iana.org/assignments/ipv4-address-space');
$res->is_success or die "HTTP request failed: " . $res->message . "\n";
#
# Print all the /8s.
#
print map { "$_\n" }
$res->content =~ m{ ( \d{3} \/ 8 ) .+? (?: UNALLOCATED | RESERVED ) }gx;
# $Id: list-iana-reserved-ranges,v 1.2 2008/05/17 07:00:42 suter Exp $
The second script, aggregate-cidr-addresses, aggregates all the addresses into larger subnets, cutting down on the amount of lines fed into iptables.
#!/usr/bin/perl -Tw
# [MJS 22 Oct 2001] Aggregate CIDR addresses
# [MJS 9 Oct 2007] Overlap idea from Anthony Ledesma at theplanet dot com.
use strict;
use Net::IP;
## Read in all the IP addresses from <>
my @addrs = map { new Net::IP $_ or die "Not an IP: \"$_\"."; }
map { /^\s*(.*?)\s*$/ and $1; } <>;
## Sort the IP addresses
@addrs = sort {
$a->bincomp( 'lt', $b ) ? -1 : ( $a->bincomp( 'gt', $b ) ? 1 : 0 );
} @addrs;
## Handle overlaps
my $count = 0;
my $current = $addrs[0];
foreach my $next ( @addrs[ 1 .. $#addrs ] ) {
my $r = $current->overlaps($next);
if ( $r == $IP_NO_OVERLAP ) {
$current = $next;
$count++;
}
elsif ( $r == $IP_A_IN_B_OVERLAP ) {
$current = $next;
splice( @addrs, $count, 1 );
}
elsif ( $r == $IP_B_IN_A_OVERLAP or $r == $IP_IDENTICAL ) {
splice( @addrs, $count + 1, 1 );
}
else {
die "$0: internal error - overlaps() returned an unexpected value!\n";
}
}
## Keep aggregating until we don't change anything
my $change = 1;
while ($change) {
$change = 0;
my @new_addrs = ();
my $current = $addrs[0];
foreach my $next ( @addrs[ 1 .. $#addrs ] ) {
if ( my $total = $current->aggregate($next) ) {
$current = $total;
$change = 1;
}
else {
push @new_addrs, $current;
$current = $next;
}
}
push @new_addrs, $current;
@addrs = @new_addrs;
}
## Print out the IP addresses
foreach (@addrs) {
print $_->prefix(), "\n";
}
# $Id: aggregate-cidr-addresses,v 1.3 2008/05/17 07:00:42 suter Exp $
To put everything together, you just need to replace your get-iana.sh script with something that uses the perl scripts, like the following:
#!/bin/bash
tempfile="/tmp/iana.$$.$RANDOM"
perl -Tw "/etc/firehol/list-iana-reserved-ranges" | perl -Tw "/etc/firehol/aggregate-cidr-addresses" >"${tempfile}"
echo >&2
echo >&2
echo >&2 "FOUND THE FOLLOWING RESERVED IP RANGES:"
printf "RESERVED_IPS=\""
i=0
for x in `cat ${tempfile}`
do
i=$[i + 1]
printf "${x} "
done
printf "\"\n"
if [ $i -eq 0 ]
then
echo >&2
echo >&2
echo >&2 "Failed to find reserved IPs."
echo >&2 "Possibly the file format has been changed, or I cannot fetch the URL."
echo >&2
rm -f ${tempfile}
exit 1
fi
echo >&2
echo >&2
echo >&2 "Differences between the fetched list and the list installed in"
echo >&2 "/etc/firehol/RESERVED_IPS:"
echo >&2 "# diff /etc/firehol/RESERVED_IPS ${tempfile}"
diff /etc/firehol/RESERVED_IPS ${tempfile}
if [ $? -eq 0 ]
then
echo >&2
echo >&2 "No differences found."
echo >&2
rm -f ${tempfile}
exit 0
fi
echo >&2
echo >&2
echo >&2 "Would you like to save this list to /etc/firehol/RESERVED_IPS"
echo >&2 "so that FireHOL will automatically use it from now on?"
echo >&2
while [ 1 = 1 ]
do
printf >&2 "yes or no > "
read x
case "${x}" in
yes) cp -f /etc/firehol/RESERVED_IPS /etc/firehol/RESERVED_IPS.old 2>/dev/null
cat "${tempfile}" >/etc/firehol/RESERVED_IPS || exit 1
echo >&2 "New RESERVED_IPS written to '/etc/firehol/RESERVED_IPS'."
break
;;
no)
echo >&2 "Saved nothing."
break
;;
*) echo >&2 "Cannot understand '${x}'."
;;
esac
done
rm -f ${tempfile}
There you have it, updated and compact RESERVED_IPS.