From b6cb74032fbb20220c58fb898ad4ecaea428a0f5 Mon Sep 17 00:00:00 2001 From: Dave Webb Date: Thu, 29 Nov 2012 21:40:34 +0000 Subject: [PATCH 1/3] DCW - Added config entry for ipfilter.dat location --- bitflu.config.example | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bitflu.config.example b/bitflu.config.example index 0fe39c1f4..55a5fd399 100644 --- a/bitflu.config.example +++ b/bitflu.config.example @@ -139,6 +139,10 @@ webgui_port = 4081 # Bitflus 'root directory' workdir = ./workdir +# Support for ipfilter.dat files - needs Net::IPAddress::Filter::IPFilterDat +# Filepath of filter list file. +# ipfilter_dat_file = ./ipfilter.dat +ipfilter_dat_file = # Change uid/gid after startup (if started as root, needed for chroot) # runas_uid = From 7032da1c8419512cd5f27a0fd63d6bc8726efa5a Mon Sep 17 00:00:00 2001 From: Dave Webb Date: Sat, 1 Dec 2012 09:45:03 +0000 Subject: [PATCH 2/3] DCW - Start of IP filter support. TODO: Needs to instantiate the filter. --- bitflu.pl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/bitflu.pl b/bitflu.pl index c4cda37e7..7fb21e4ab 100755 --- a/bitflu.pl +++ b/bitflu.pl @@ -2421,6 +2421,10 @@ package Bitflu::Network; $self->debug("Won't connect to blacklisted IP $remote_ip"); return undef; } + elsif($self->IpIsFiltered($remote_ip)) { + $self->debug("Won't connect to filtered IP $remote_ip"); + $new_sock->close; + } if(KILL_IPV4 && $self->IsNativeIPv4($remote_ip)) { $self->debug("Will not connect to IPv4 addr $remote_ip"); return undef; @@ -2482,6 +2486,10 @@ package Bitflu::Network; $self->debug("Refusing incoming connection from blacklisted ip $new_ip"); $new_sock->close; } + elsif($self->IpIsFiltered($new_ip)) { + $self->debug("Refusing incoming connection from filtered ip $new_ip"); + $new_sock->close; + } elsif(KILL_IPV4 && $self->IsNativeIPv4($new_ip)) { $self->debug("Dropping new IPv4 connection from $new_ip"); $new_sock->close; @@ -2657,6 +2665,20 @@ package Bitflu::Network; } } + sub IpIsFiltered { + my($self, $this_ip) = @_; + + return 0 unless $self->{ip_filter}; + + # Filter only supports IPv4 + return 0 if $self->IsNativeIPv6($this_ip); + + if ( !$self->IsNativeIPv4($this_ip) ) { + $this_ip = $self->SixToFour($this_ip); + } + return $self->{ip_filter}->in_filter($this_ip); + } + sub debug { my($self, $msg) = @_; $self->{super}->debug("Network : ".$msg); } sub info { my($self, $msg) = @_; $self->{super}->info("Network : ".$msg); } From 4044a7ce6779f3eb9574c3662b766f287e694b12 Mon Sep 17 00:00:00 2001 From: Dave Webb Date: Sun, 2 Dec 2012 07:45:27 +0000 Subject: [PATCH 3/3] DCW - Tested and working. Now checks for perl module and filter file in constructor, but loads the actual filter in init(). Now calls debug() for every IP filtered. Plus copy and paste bugfix. --- bitflu.pl | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/bitflu.pl b/bitflu.pl index 7fb21e4ab..129187cee 100755 --- a/bitflu.pl +++ b/bitflu.pl @@ -1791,7 +1791,7 @@ package Bitflu::Network; use constant MAGIC_DSNUM => 1024*0.75; # Don't ask me why, but 0.75 makes our downspeed guess much better use constant KILL_IPV4 => 0; # 'simulate' non-working ipv4 stack -use fields qw( super NOWTIME avfds bpx_dn bpx_up _HANDLES _SOCKETS stagger up_q stats resolver_fail have_ipv6); +use fields qw( super NOWTIME avfds bpx_dn bpx_up _HANDLES _SOCKETS stagger up_q stats resolver_fail have_ipv6 ip_filter); ########################################################################## # Creates a new Networking Object @@ -1835,6 +1835,20 @@ package Bitflu::Network; } } + # Check whether to use an ipfilter.dat IP address filter. + if($self->{super}->Configuration->GetValue('ipfilter_dat_file')) { + my $ipfilter_dat_file = $self->{super}->Configuration->GetValue('ipfilter_dat_file'); + eval { + require Net::IPAddress::Filter::IPFilterDat; + }; + if ($@) { + $self->stop("Net::IPAddress::Filter::IPFilterDat is required for ipfilter.dat support."); + } + if ( ! -f $ipfilter_dat_file ) { + $self->stop("Unable to find ipfilter.dat file at '$ipfilter_dat_file'"); + } + } + if(KILL_IPV4) { $self->warn("IPv4 support is *DISABLED*"); } @@ -1843,7 +1857,7 @@ package Bitflu::Network; } ########################################################################## - # Register Admin commands + # Register Admin commands. Load any IP filter file. sub init { my($self) = @_; $self->info("IPv6 support is ".($self->HaveIPv6 ? 'enabled' : 'not active')); @@ -1853,6 +1867,16 @@ package Bitflu::Network; $self->{super}->Admin->RegisterCommand('netstat', $self, '_Command_Netstat', 'Display networking statistics'); $self->{super}->Admin->RegisterCommand('dig', $self, '_Command_Dig', 'Resolve a hostname'); $self->{super}->CreateSxTask(Superclass=>$self,Callback=>'_UpdateNetstats', Interval=>NETSTATS, Args=>[]); + + # Check whether to use an ipfilter.dat IP address filter. + if($self->{super}->Configuration->GetValue('ipfilter_dat_file')) { + my $ipfilter_dat_file = $self->{super}->Configuration->GetValue('ipfilter_dat_file'); + $self->info("Loading ipfilter.dat file '$ipfilter_dat_file'"); + $self->{ip_filter} = Net::IPAddress::Filter::IPFilterDat->new(); + $self->{ip_filter}->load_file($ipfilter_dat_file); + $self->info("IP address filter initialized"); + } + return 1; } @@ -2423,7 +2447,7 @@ package Bitflu::Network; } elsif($self->IpIsFiltered($remote_ip)) { $self->debug("Won't connect to filtered IP $remote_ip"); - $new_sock->close; + return undef; } if(KILL_IPV4 && $self->IsNativeIPv4($remote_ip)) { $self->debug("Will not connect to IPv4 addr $remote_ip"); @@ -2676,7 +2700,11 @@ package Bitflu::Network; if ( !$self->IsNativeIPv4($this_ip) ) { $this_ip = $self->SixToFour($this_ip); } - return $self->{ip_filter}->in_filter($this_ip); + my $is_filtered = $self->{ip_filter}->in_filter($this_ip); + + $self->debug("Filtering $this_ip") if $is_filtered; + + return $is_filtered; }