On 24/02/13 08:09, Matt Joyce wrote:
> On 23/02/13 19:27, Tom Eastep wrote:
>> Using ipsets is the only way that I would try such a thing.
>>
>> -Tom
>>
>> On 2/23/13 10:57 AM, "Cory Oldford" <c...@peaceworks.ca
>> <mailto:c...@peaceworks.ca>> wrote:
>>
>>     The overhead associated with matching against the complete bogon
>>     list is too much in my humble opinion.
>>
>>
>>     Cory Oldford
>>
>>     ------------------------------------------------------------------------
>>     *From: *"Dr. Jeffry A. Spain" <spa...@countryday.net
>>     <mailto:spa...@countryday.net>>
>>     *To: *"Shorewall Users" <shorewall-users@lists.sourceforge.net
>>     <mailto:shorewall-users@lists.sourceforge.net>>
>>     *Sent: *Saturday, February 23, 2013 12:38:14 PM
>>     *Subject: *[Shorewall-users] Full Bogon Filtering
>>
>>     What experience have users had using ShoreWall as a bogon filter
>>     using the Team Cymru full bogon lists
>>     (http://www.team-cymru.org/Services/Bogons/http.html)? The IPv4
>>     full bogon list contains over 4,600 separate networks that need
>>     to be denied, and the IPv6 list over 68,300. Having not tried
>>     this myself, I would be concerned a priori about ShoreWall server
>>     meltdown.
>>
>>     Jeffry A. Spain, Network Administrator
>>     Cincinnati Country Day School
>>
>>
>>     
>> ------------------------------------------------------------------------------
>>     Everyone hates slow websites. So do we.
>>     Make your web apps faster with AppDynamics
>>     Download AppDynamics Lite for free today:
>>     http://p.sf.net/sfu/appdyn_d2d_feb
>>     _______________________________________________
>>     Shorewall-users mailing list
>>     Shorewall-users@lists.sourceforge.net
>>     <mailto:Shorewall-users@lists.sourceforge.net>
>>     https://lists.sourceforge.net/lists/listinfo/shorewall-users
>>
>>     
>> ------------------------------------------------------------------------------
>>     Everyone hates slow websites. So do we. Make your web apps faster
>>     with AppDynamics Download AppDynamics Lite for free today:
>>     
>> http://p.sf.net/sfu/appdyn_d2d_feb_______________________________________________
>>     Shorewall-users mailing list
>>     Shorewall-users@lists.sourceforge.net
>>     <mailto:Shorewall-users@lists.sourceforge.net>
>>     https://lists.sourceforge.net/lists/listinfo/shorewall-users 
>>
>>
>>
>> -Tom
>> You do not need a parachute to skydive. You only need a parachute to
>> skydive twice.
>>
>>
>>
>> ------------------------------------------------------------------------------
>> Everyone hates slow websites. So do we.
>> Make your web apps faster with AppDynamics
>> Download AppDynamics Lite for free today:
>> http://p.sf.net/sfu/appdyn_d2d_feb
>>
>>
>> _______________________________________________
>> Shorewall-users mailing list
>> Shorewall-users@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/shorewall-users
> I have tried this myself and I have to second what Tom said above,
> unfortunately I havn't rewritten the shell scripts for it yet after
> losing them in a hard disk crash had other things needed resolving
> first however the actual update of the ipsets will cause a bit of a
> spike especially if your firewall system is a low end machine (An
> intel i7 hexacore was taking a minute or two to chew through it it)
> but I created a shell script to download the lists whenever they were
> modified, compare them and then update the ipsets with changes only. 
> I have been intending to implement this again myself and it would
> probably take as long to write a detailed explanation as it would to
> just go ahead and create the scripts again with comments.
>
> I should have some free time this morning so I will try to get that
> done today and get back to you with the shell script and comments.
>
>
> ------------------------------------------------------------------------------
> Everyone hates slow websites. So do we.
> Make your web apps faster with AppDynamics
> Download AppDynamics Lite for free today:
> http://p.sf.net/sfu/appdyn_d2d_feb
>
>
> _______________________________________________
> Shorewall-users mailing list
> Shorewall-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/shorewall-users
I have to apologize that things got a bit busy here and I forgot about
this until this evening, I just worked on the script and tested it.  It
will provide a short summary after a run which I generally let cron mail
to me so I know if the update stops working for any reason but you could
just as easily redirect it to a file too.

The script is attached with comments, note that this version works
pretty quickly because it doesn't go through and add them line by line
every load, instead it compares the sorted new list against ipset list
using comm to find added and deleted entries then only processes those,
as a sanity check it will use md5sum if available to confirm the updated
ipset matches checks the md5sum of the two lists match after updating
provided the md5sum binary is installed.

Few notes I thought I'd mention though the comments in the script
discuss them too:
Note that ipsets are lost on reboot but by default the script uses ipset
save to save the ipset to it's working directory, just need to use ipset
restore before using it for filtering shorewall can handle this for you
if you add something like the following to /etc/shorewall/start
   ipset -! restore -f /var/cache/bogon-lists/bogonsip4.ipset
Yes you could just readd each time but ipset restore is a lot faster at
it than a bash script.

It's your choice but I would suggest it may not hurt to consider my
suggestion in there about using caps support if you have it available,
that way you can avoid having a shell script running as root chewing on
an externally sourced file which to me seemed a bit too much like asking
for trouble.

Do check the script before using it as there are a few other options you
may wish to change.

As a side note the script as is will work with any list of CIDR ranges
that one might like to keep up to date and use for filtering in one per
line format including files containing #comments whole or end of line,
doesn't care about whitespace either.  It will need a small modification
to work with ftp:// urls, currently it is written to expect a
http_response code which is fine with these lists but might be an issue
if anyone wanted to adapt it.

Anyway, I'm happy to make freely available to anyone to use or modify as
they see fit hope it's useful to someone.  Comments welcome if there is
anything I missed somewhere.
#!/bin/bash
# This script handles fetching updates to the fullbogons lists hosted by 
team-cymru.org
# processing and preparing these into ipsets which allow effecient filtering by 
netfilter.
#
# A NOTE ON SECURITY
# Creting of modifying ipsets on linux requires privilages which means that 
this script is
# required to have access to privilages to function but the script is also 
engaged in the
# fetching and processing of a large datafile sourced from the internet, having 
the script
# run as root means having curl, various string manipulation utilities etc 
running as root
# also.
#
# Personally I would consider that too much of a security risk, there are at 
least two main
# options to get around this situation that occur to me the first would be to 
run the fetch
# with a seperate shell script running with the privilages of a normal user as 
there is no
# need for privilages to conduct those activities but then you still have a 
full root script
# reading and processing external data.
#
# I have this set up using a second alternative based on group permissions and 
linux file
# capabilities, the ipset binary is installed with execute permission only for 
owner (root)
# and group (ipset) and has the linux capability cap_net_admin set as a file 
capability, in
# this configuration an unprivilaged user who is a member of the ipset group 
can create and
# manage ipsets, this script is executed by cron with the privilages of just 
such a user.
#
# If you have linux file capability support and have the setcap utility 
installed but I would
# recommend the following proceedure.  Please someone feel free to comment if 
there is any
# pitfalls I am missing with this but it would seem to be significantly safer 
than full root.
#
# 1. Add the ipset group to the system with:
#   $ groupadd ipset
# 2. Change the group of the ipset binary and set file permissions, replace 
/usr/sbin/ipset
# with the path to the ipset binary on your system you can find it by typing:
#   $ which ipset
#   /usr/sbin/ipset
#   $ chgrp ipset /usr/sbin/ipset
#   $ chmod 750 /usr/sbin/ipset
# 3. Set the necessary file capability
#   $ setcap 'cap_net_admin=pe' /usr/sbin/ipset
# 4. Create your unprivilaged user and don't forget to also set permissions to 
allow the
# user account to write to the $WORKPATH you set in this script. Note the 
options set the
# account with homedir=$WORKPATH shell=/bin/false group=ipset
#   $ useradd -r -d <$WORKPATH> -s /bin/false -g ipset bogonmgr
#   $ chown bogonmgr.root /var/cache/bogon-lists
#   $ chmod 750 /var/cache/bogon-lists
# There is no strict need to deny the others permission on the directory I 
guess but no
# reason not to either so I figure might as well.

# SCRIPT CONFIGURATION
# BOGON LIST URLs
# By default this script is set up to use the fullbogons list from 
team-cymru.org however
# in principle it will work for any blocklist in one per line CIDR format.  The 
list must
# contain no other text besides comments starting with a hash character which 
are ignored
# as is any whitespace.  Note the script assumes a HTTP retreval and expects a 
to get a 
# HTTP status code back from the server, if you change this to a protocol other 
than HTTP/HTTPS
# you will need to modify the return test or it will result in false negatives 
and no
# ipsets being built.
IPV4LISTURL="http://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt";
IPV6LISTURL="http://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt";

# FETCH OPTIONS
# These options are used to control the fetch of the lists by cURL
# Maximum retries
RETRYMAX=5
# Connect timeout in seconds
CONNTIMEOUT=5
# Maximum time be aware this is for the transfer including all retries, retries 
could take
# up to 30 seconds make sure that this number is high enough to allow for the 
transfer of
# the IPv6 list which is approx 1MiB of data and don't forget to consider your 
value for
# the limit rate setting here.
MAXTIME=60
# Rate limit in bytes per second, suffixes k, M, G etc are supported.  You 
should adjust
# this value depending on your own connection on mine there is usually around 
80Mbps of
# headroom after accounting for traffic so I have this set to 50% of that 5M 
(40Mbps).
RATELIMIT="5M"

# PATH CONFIGURATION
# WORKPATH specifies the directory the script will use to download the blocklist
WORKPATH="/var/cache/bogon-lists"

# IPSET CONFIGURATION
# These set the names of the two ipsets which will be created and managed by 
this script.
IPV4IPSET="bogonsip4"
IPV6IPSET="bogonsip6"

# MISC OPTIONS
# IPSET SAVE
# This option causes the script to invoke ipset save after making changes to 
the networks
# within the ipset, this is recommended as it is much quicker to ipset restore 
the saved
# file than it is to loop through thousands of entries and add them one by one 
remember the
# ipset will be lost at reboot. To make sure that the ipset exists and is 
populated when
# shorewall starts I added the restore to the shorewall start scripts, the -! 
in the ipset
# command prevents ipset complaining at shorewall (re)start where the ipset 
already exists.
#   /etc/shorewall/start
# ipset -! restore -f /var/cache/bogon-lists/bogonsip4-save.ipset
#   /etc/shorewall6/start
# ipset -! restore -f /var/cache/bogon-lists/bogonsip6-save.ipset
IPSETSAVE=1

# FLUSH
# Setting this option to true will cause the ipset to be flushed and rebuilt 
completely
# instead of updating with the changes, this is a much slower process.
FLUSH=0

function fetchlist () {
   # The function used for fetching the list, using cURL means we wont need to 
explitly handle retries etc.

   # Use cURL to attempt the fetch and return the HTTP reply code and some 
stats, the stats we will use later.
   # Options: s=transfer silently, L=Handle redirect, R=Use remote file time, 
z=Time condition download only if newer than our file, o=Output filename, 
w=Write out tells curl what to return
   # retry limit of 5, Use compression if enabled note team-cmyru.org server 
doesn't yet but the AcceptEncoding header doesn't hurt and is there if they 
enable it later
   STATUS=`curl -s -L -R -z fullbogons-ipv4.txt -o fullbogons-ipv4.txt -w 
"%{http_code} %{time_total} %{size_download} %{speed_download}" --retry 5 
--compressed --connect-timeout $CONNTIMEOUT --max-time $MAXTIME --limit-rate 
$RATELIMIT --url "$IPV4LISTURL"`
   # Find the HTTP response code we recieved from cURL and make a note of the 
other stats for the summary
   HTTPCODE=`echo $STATUS | cut -d' ' -f1`
   HTTPSTATS4="$HTTPSTATS`echo $STATUS | cut -d' ' -f2-` "

   # We check here in case we have an error reply despite our retry efforts
   if [ $HTTPCODE -ne 304 ] && [ $HTTPCODE -ne 200 ]; then echo "URL fetch for 
$LISTURL retry limit exceeded."; exit 1; fi

   # Repeat for IPv6
   STATUS=`curl -s -L -R -z fullbogons-ipv6.txt -o fullbogons-ipv6.txt -w 
"%{http_code} %{time_total} %{size_download} %{speed_download}" --retry 5 
--compressed --connect-timeout $CONNTIMEOUT --max-time $MAXTIME --limit-rate 
$RATELIMIT --url "$IPV6LISTURL"`
   HTTPCODE=`echo $STATUS | cut -d' ' -f1`
   HTTPSTATS6="$HTTPSTATS`echo $STATUS | cut -d' ' -f2-` "

   # We check here in case we have an error reply despite our retry efforts
   if [ $HTTPCODE -ne 304 ] && [ $HTTPCODE -ne 200 ]; then echo "URL fetch for 
$LISTURL retry limit exceeded."; exit 1; fi
}

function listpreprocessor () {
   # For the incoming list first strip any comments or whitespace, then sort 
and pass through uniq to make sure each
   # entry occurs once and only once.
   cat "fullbogons-ipv4.txt" | sed -re 's/#.*$//g; s/\s+//; /^$/d' | sort | 
uniq >./ipv4-new
   ipset list $IPV4IPSET | awk '{ if (listing == 1) print $1; else if ($1 == 
"Members:") listing=1; }' | sed '/^$/d' | sort >./ipv4-old
   cat "fullbogons-ipv6.txt" | sed -re 's/#.*$//g; s/\s+//; /^$/d' | sort | 
uniq >./ipv6-new
   ipset list $IPV6IPSET | awk '{ if (listing == 1) print $1; else if ($1 == 
"Members:") listing=1; }' | sed '/^$/d' | sort >./ipv6-old
   comm -1 -3 ipv4-old ipv4-new | sed 's/\s+//' >./ipv4-add
   comm -1 -3 ipv6-old ipv6-new | sed 's/\s+//' >./ipv6-add
   comm -2 -3 ipv4-old ipv4-new | sed 's/\s+//' >./ipv4-del
   comm -2 -3 ipv6-old ipv6-new | sed 's/\s+//' >./ipv6-del
}

function updateipsets () {
   cat ipv4-add | while read CIDR; do ipset add $IPV4IPSET $CIDR; done
   cat ipv6-add | while read CIDR; do ipset add $IPV6IPSET $CIDR; done
   cat ipv4-del | while read CIDR; do ipset del $IPV4IPSET $CIDR; done
   cat ipv6-del | while read CIDR; do ipset del $IPV6IPSET $CIDR; done
}

function verify () {
   # Check if we have the md5sum command available, if we do then we can verify 
the ipset is correct
   if [ -x "`which md5sum`" ]; then
      mv ipv4-new ipv4-old
      mv ipv6-new ipv6-old
      ipset list $IPV4IPSET | awk '{ if (listing == 1) print $1; else if ($1 == 
"Members:") listing=1; }' | sed '/^$/d' | sort >./ipv4-new
      ipset list $IPV6IPSET | awk '{ if (listing == 1) print $1; else if ($1 == 
"Members:") listing=1; }' | sed '/^$/d' | sort >./ipv6-new
      CHECK=`md5sum ipv4-new ipv4-old | awk '{ if (NR == 1) sum1=$1; else if 
(sum1 == $1) print "OK"; else print "FAIL MD5 Mismatch",sum1,$1 }'`
      if [ $CHECK != "OK" ]; then echo $CHECK; exit 1; fi
      CHECK=`md5sum ipv6-new ipv6-old | awk '{ if (NR == 1) sum1=$1; else if 
(sum1 == $1) print "OK"; else print "FAIL MD5 Mismatch",sum1,$1 }'`
      if [ $CHECK != "OK" ]; then echo $CHECK; exit 1; fi
   fi
}

function summary () {
   echo "Ipset update results"
   TS4=`date --date="@$(stat fullbogons-ipv4.txt --printf %Y)" '+%d/%m/%Y 
%H:%M:%S'`
   TS6=`date --date="@$(stat fullbogons-ipv4.txt --printf %Y)" '+%d/%m/%Y 
%H:%M:%S'`
   echo "IPv4 list fetch `echo $HTTPSTATS4 | cut -d' ' -f2` B in `echo 
$HTTPSTATS4 | cut -d' ' -f1`s rate `echo $HTTPSTATS4 | cut -d' ' -f3` B/s"
   echo "IPv4 list entries: `cat ipv4-new | wc -l` added: `cat ipv4-add | wc 
-l` deleted: `cat ipv4-del | wc -l` timestamp: $TS4"
   echo "IPv6 list fetch `echo $HTTPSTATS6 | cut -d' ' -f2` B in `echo 
$HTTPSTATS6 | cut -d' ' -f1`s rate `echo $HTTPSTATS6 | cut -d' ' -f3` B/s"
   echo "IPv6 list entries: `cat ipv6-new | wc -l` added: `cat ipv6-add | wc 
-l` deleted: `cat ipv6-del | wc -l` timestamp: $TS6"
   echo "Total processing time `echo "$(date '+%s.%N') - $BEGIN_TIME" | bc | 
xargs printf "%0.3g"` seconds"
}

function ipsetsave () {
   if [ $IPSETSAVE -eq 1 ]; then
      ipset save $IPV4IPSET -f ${IPV4IPSET}.ipset
      ipset save $IPV6IPSET -f ${IPV6IPSET}.ipset
   fi
}

BEGIN_TIME=`date +%s.%N`
cd $WORKPATH || exit 1

# We will create several working lists during execution, this makes sure that 
we don't leave
# them laying around even if we get killed due to an error etc
trap "rm ${WORKPATH}/ipv?-???" EXIT

# Create ipsets if they don't exist yet
# Default settings are adiquite for IPv4
ipset -! create $IPV4IPSET hash:net

# For the IPV6 list we override the default hash size and the max entries in 
the table 65536 is exceeded sometimes
# due to the significant unallocated IPv6 space.  Also need to explicitly 
declare family as IPv6 default is IPv4
ipset -! create $IPV6IPSET hash:net family inet6 hashsize 2048 maxelem 131072

# If flush is set this is where the ipsets get cleared
if [ $FLUSH -eq 1 ]; then
   ipset flush $IPV4IPSET
   ipset flush $IPV6IPSET
fi

# Fetch the ipset lists from the URLs defined in IPV4LISTURL and IPV6LISTURL
fetchlist
listpreprocessor
updateipsets
verify
if [ $IPSETSAVE = 1 ]; then ipsetsave; fi
summary

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_feb
_______________________________________________
Shorewall-users mailing list
Shorewall-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/shorewall-users

Reply via email to