diff options
Diffstat (limited to 'config/pfblockerng/pfblockerng.inc')
-rw-r--r-- | config/pfblockerng/pfblockerng.inc | 143 |
1 files changed, 127 insertions, 16 deletions
diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index bc2ccfe1..d612dbf1 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -56,12 +56,12 @@ function pfb_global() { $pfb['aliasdir'] = "{$g['vardb_path']}/aliastables"; $pfb['logdir'] = "{$g['varlog_path']}/pfblockerng"; $pfb['etdir'] = "{$pfb['dbdir']}/ET"; - $pfb['ccdir'] = "{$pfb['dbdir']}/cc"; $pfb['nativedir'] = "{$pfb['dbdir']}/native"; $pfb['denydir'] = "{$pfb['dbdir']}/deny"; $pfb['matchdir'] = "{$pfb['dbdir']}/match"; $pfb['permitdir'] = "{$pfb['dbdir']}/permit"; $pfb['origdir'] = "{$pfb['dbdir']}/original"; + $pfb['ccdir'] = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP"; # Create Folders if not Exist. $folder_array = array ("{$pfb['dbdir']}","{$pfb['logdir']}","{$pfb['ccdir']}","{$pfb['origdir']}","{$pfb['nativedir']}","{$pfb['denydir']}","{$pfb['matchdir']}","{$pfb['permitdir']}","{$pfb['aliasdir']}"); @@ -240,6 +240,101 @@ function pfb_create_suppression_file() { } +// IPv6 Range to CIDR function used courtesey from: +// https://github.com/stilez/pfsense-leases/blob/50cc0fa81dba5fe91bcddaea016c245d1b8479cc/etc/inc/util.inc +function ip_range_to_subnet_array_temp2($ip1, $ip2) { + + if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2)) { + $proto = 'ipv4'; // for clarity + $bits = 32; + $ip1bin = decbin(ip2long32($ip1)); + $ip2bin = decbin(ip2long32($ip2)); + } elseif (is_ipaddrv6($ip1) && is_ipaddrv6($ip2)) { + $proto = 'ipv6'; + $bits = 128; + $ip1bin = Net_IPv6::_ip2Bin($ip1); + $ip2bin = Net_IPv6::_ip2Bin($ip2); + } else + return array(); + + // it's *crucial* that binary strings are guaranteed the expected length; do this for certainty even though for IPv6 it's redundant + $ip1bin = str_pad($ip1bin, $bits, '0', STR_PAD_LEFT); + $ip2bin = str_pad($ip2bin, $bits, '0', STR_PAD_LEFT); + + if ($ip1bin === $ip2bin) + return array($ip1 . '/' . $bits); + + if (strcmp($ip1bin, $ip2bin) > 0) + list ($ip1bin, $ip2bin) = array($ip2bin, $ip1bin); // swap contents of ip1 <= ip2 + + $rangesubnets = array(); + $netsize = 0; + + do { + // at loop start, $ip1 is guaranteed strictly less than $ip2 (important for edge case trapping and preventing accidental binary wrapround) + // which means the assignments $ip1 += 1 and $ip2 -= 1 will always be "binary-wrapround-safe" + + // step #1 if start ip (as shifted) ends in any '1's, then it must have a single cidr to itself (any cidr would include the '0' below it) + + if (substr($ip1bin, -1, 1) == '1') { + // the start ip must be in a separate one-IP cidr range + $new_subnet_ip = substr($ip1bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize); + $rangesubnets[$new_subnet_ip] = $bits - $netsize; + $n = strrpos($ip1bin, '0'); //can't be all 1's + $ip1bin = ($n == 0 ? '' : substr($ip1bin, 0, $n)) . '1' . str_repeat('0', $bits - $n - 1); // BINARY VERSION OF $ip1 += 1 + } + + // step #2, if end ip (as shifted) ends in any zeros then that must have a cidr to itself (as cidr cant span the 1->0 gap) + + if (substr($ip2bin, -1, 1) == '0') { + // the end ip must be in a separate one-IP cidr range + $new_subnet_ip = substr($ip2bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize); + $rangesubnets[$new_subnet_ip] = $bits - $netsize; + $n = strrpos($ip2bin, '1'); //can't be all 0's + $ip2bin = ($n == 0 ? '' : substr($ip2bin, 0, $n)) . '0' . str_repeat('1', $bits - $n - 1); // BINARY VERSION OF $ip2 -= 1 + // already checked for the edge case where end = start+1 and start ends in 0x1, above, so it's safe + } + + // this is the only edge case arising from increment/decrement. + // it happens if the range at start of loop is exactly 2 adjacent ips, that spanned the 1->0 gap. (we will have enumerated both by now) + + if (strcmp($ip2bin, $ip1bin) < 0) + continue; + + // step #3 the start and end ip MUST now end in '0's and '1's respectively + // so we have a non-trivial range AND the last N bits are no longer important for CIDR purposes. + + $shift = $bits - max(strrpos($ip1bin, '0'), strrpos($ip2bin, '1')); // num of low bits which are '0' in ip1 and '1' in ip2 + $ip1bin = str_repeat('0', $shift) . substr($ip1bin, 0, $bits - $shift); + $ip2bin = str_repeat('0', $shift) . substr($ip2bin, 0, $bits - $shift); + $netsize += $shift; + if ($ip1bin === $ip2bin) { + // we're done. + $new_subnet_ip = substr($ip1bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize); + $rangesubnets[$new_subnet_ip] = $bits - $netsize; + continue; + } + + // at this point there's still a remaining range, and either startip ends with '1', or endip ends with '0'. So repeat cycle. + } while (strcmp($ip1bin, $ip2bin) < 0); + + // subnets are ordered by bit size. Re sort by IP ("naturally") and convert back to IPv4/IPv6 + + ksort($rangesubnets, SORT_STRING); + $out = array(); + + foreach ($rangesubnets as $ip => $netmask) { + if ($proto == 'ipv4') { + $i = str_split($ip, 8); + $out[] = implode('.', array( bindec($i[0]),bindec($i[1]),bindec($i[2]),bindec($i[3]))) . '/' . $netmask; + } else + $out[] = Net_IPv6::compress(Net_IPv6::_bin2Ip($ip)) . '/' . $netmask; + } + + return $out; +} + + # Main pfBlockerNG Function function sync_package_pfblockerng($cron = "") { @@ -362,14 +457,15 @@ function sync_package_pfblockerng($cron = "") { # Configure ARRAYS # ############################################# - $continents = array ( "Africa" => "pfB_Africa", - "Antartica" => "pfB_Antartica", - "Asia" => "pfB_Asia", - "Europe" => "pfB_Europe", - "North America" => "pfB_NAmerica", - "Oceania" => "pfB_Oceania", - "South America" => "pfB_SAmerica", - "Top Spammers" => "pfB_Top" + $continents = array ( "Africa" => "pfB_Africa", + "Antartica" => "pfB_Antartica", + "Asia" => "pfB_Asia", + "Europe" => "pfB_Europe", + "North America" => "pfB_NAmerica", + "Oceania" => "pfB_Oceania", + "South America" => "pfB_SAmerica", + "Top Spammers" => "pfB_Top", + "Proxy and Satellite" => "pfB_PS" ); #create rules vars and arrays @@ -1097,16 +1193,16 @@ function sync_package_pfblockerng($cron = "") { $log_tab = "\t\t"; } - # Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled. - $pfb_alias_lists_all[] = "{$alias}"; - // Empty Header Field Validation Check - if (empty($header_url)) { - $log = "\n [ {$row['url']} ] {$log_tab} Header Field cannot be Empty. *Skipping* \n"; + if (empty($header_url) || preg_match("/\W/",$header_url)) { + $log = "\n [ {$row['url']} ]\n ** TERMINATED - Header contains Blank/International/Special or Spaces\n"; pfb_logger("{$log}","2"); continue; } + # Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled. + $pfb_alias_lists_all[] = "{$alias}"; + if (file_exists($pfbfolder . '/' . $header_url . '.txt') && $pfb['reuse'] == "") { if ($row['state'] == "Hold") { $log = "\n[ {$header_url} ] {$log_tab} Static Hold [ NOW ]\n"; @@ -1280,7 +1376,7 @@ function sync_package_pfblockerng($cron = "") { foreach ($url_list as $line) { # Network range 192.168.0.0-192.168.0.254 if (preg_match($pfb['range'],$line,$matches)) { - $a_cidr = ip_range_to_subnet_array($matches[1],$matches[2]); + $a_cidr = ip_range_to_subnet_array_temp2($matches[1],$matches[2]); if (!empty($a_cidr)) { foreach ($a_cidr as $cidr) { $new_file .= preg_replace($pfb_ipreg,'',$cidr) . "\n"; @@ -1498,7 +1594,7 @@ function sync_package_pfblockerng($cron = "") { } # Network range 192.168.0.0-192.168.0.254 elseif (preg_match($pfb['range'],$line,$matches)) { - $a_cidr = ip_range_to_subnet_array($matches[1],$matches[2]); + $a_cidr = ip_range_to_subnet_array_temp2($matches[1],$matches[2]); if (!empty($a_cidr)) { foreach ($a_cidr as $cidr) { $new_file .= preg_replace($pfb_ipreg, '',$cidr) . "\n"; @@ -2235,12 +2331,19 @@ function pfblockerng_php_install_command() { global $config,$pfb; pfb_global(); + // Remove previously used CC folder location if exists + @rmdir_recursive("{$pfb['dbdir']}/cc"); + # Uncompress Country Code File and delete Archive after extraction. exec("cd /{$pfb['ccdir']}; /usr/bin/tar -jxvf {$pfb['ccdir']}/countrycodes.tar.bz2"); unlink_if_exists("{$pfb['ccdir']}/countrycodes.tar.bz2"); # Download MaxMind Files and Create Country Code files and Build Continent XML Files update_output_window(gettext("Downloading MaxMind Country Databases. This may take a minute...")); exec("/bin/sh /usr/local/pkg/pfblockerng/geoipupdate.sh all >> {$pfb['geolog']} 2>&1"); + + @rename("{$pfb['dbdir']}/GeoIP.dat", "{$pfb['ccdir']}/GeoIP.dat"); + @rename("{$pfb['dbdir']}/GeoIPv6.dat", "{$pfb['ccdir']}/GeoIPv6.dat"); + update_output_window(gettext("MaxMind Country Database downloads completed...")); update_output_window(gettext("Converting MaxMind Country Databases for pfBlockerNG. This may take a few minutes...")); pfblockerng_uc_countries(); @@ -2248,6 +2351,12 @@ function pfblockerng_php_install_command() { pfblockerng_get_countries(); update_output_window(gettext("Completed Creating pfBlockerNG Continenet XML Files...")); + // Remove Original Maxmind Database Files + @unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryCSV.zip"); + @unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryWhois.csv"); + @unlink_if_exists("{$pfb['dbdir']}/GeoIPv6.csv"); + @unlink_if_exists("{$pfb['dbdir']}/country_continent.csv"); + # Add Widget to Dashboard update_output_window(gettext("Adding pfBlockerNG Widget to Dashboard.")); if ($pfb['keep'] == "on" && !empty($pfb['widgets'])) { @@ -2312,6 +2421,8 @@ function pfblockerng_php_deinstall_command() { unset($config['installedpackages']['pfblockerngsouthamerica']); if (is_array($config['installedpackages']['pfblockerngtopspammers'])) unset($config['installedpackages']['pfblockerngtopspammers']); + if (is_array($config['installedpackages']['pfblockerngproxyandsatellite'])) + unset($config['installedpackages']['pfblockerngproxyandsatellite']); } # Remove Widget (code from Snort deinstall) |