From e80da3c57d0501d7a5962fcacd6416d47385e86a Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Sat, 23 May 2015 16:28:12 -0400 Subject: pfBlockerNG v1.09 --- config/pfblockerng/pfblockerng.widget.php | 453 +++++++++++++++++++++--------- 1 file changed, 325 insertions(+), 128 deletions(-) (limited to 'config/pfblockerng/pfblockerng.widget.php') diff --git a/config/pfblockerng/pfblockerng.widget.php b/config/pfblockerng/pfblockerng.widget.php index 229e084b..c9522cd7 100644 --- a/config/pfblockerng/pfblockerng.widget.php +++ b/config/pfblockerng/pfblockerng.widget.php @@ -15,7 +15,7 @@ snort_alerts.widget.php Copyright (C) 2009 Jim Pingle mod 24-07-2012 - mod 28-02-2014 by Bill Meeks + mod 28-02-2015 by Bill Meeks Javascript and Integration modifications by J. Nieuwenhuizen @@ -42,58 +42,268 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - +$nocsrf = true; @require_once("/usr/local/www/widgets/include/widget-pfblockerng.inc"); @require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); @require_once("guiconfig.inc"); -@require_once("globals.inc"); -@require_once("pfsense-utils.inc"); -@require_once("functions.inc"); pfb_global(); -// Ackwnowlege Failed Downloads +// Image source definition +$pfb['down'] = ""; +$pfb['up'] = ""; +$pfb['err'] = ""; + +// Alternating line shading +$pfb['RowOddClass'] = "style='background-color: #FFFFFF;'"; +$pfb['RowEvenClass'] = "style='background-color: #F0F0F0;'"; +$pfb['RowEvenClass2'] = "style='background-color: #D0D0D0;'"; +$pfb['ColClass'] = "listMRr"; + +$pfb['global'] = &$config['installedpackages']['pfblockerngglobal']; + +// Define default widget customizations +if (!isset($pfb['global']['widget-maxfails'])) { + $pfb['global']['widget-maxfails'] = '3'; +} +if (!isset($pfb['global']['widget-maxpivot'])) { + $pfb['global']['widget-maxpivot'] = '200'; +} +if (!isset($pfb['global']['widget-sortcolumn'])) { + $pfb['global']['widget-sortcolumn'] = 'none'; +} +if (!isset($pfb['global']['widget-sortdir'])) { + $pfb['global']['widget-sortdir'] = 'asc'; +} +if (!isset($pfb['global']['widget-popup'])) { + $pfb['global']['widget-popup'] = 'on'; +} + +// Collect variables +if (is_array($pfb['global'])) { + $pfb['maxfails'] = $pfb['global']['widget-maxfails']; + $pfb['maxpivot'] = $pfb['global']['widget-maxpivot']; + $pfb['sortcolumn'] = $pfb['global']['widget-sortcolumn']; + $pfb['sortdir'] = $pfb['global']['widget-sortdir']; + $pfb['popup'] = $pfb['global']['widget-popup']; +} + +// Save widget customizations +if ($_POST) { + if (is_numeric($_POST['pfb_maxfails'])) { + $pfb['global']['widget-maxfails'] = $_POST['pfb_maxfails']; + } + if (is_numeric($_POST['pfb_maxpivot'])) { + $pfb['global']['widget-maxpivot'] = $_POST['pfb_maxpivot']; + } + if (!empty($_POST['pfb_popup'])) { + $pfb['global']['widget-popup'] = $_POST['pfb_popup']; + } + if (!empty($_POST['pfb_sortcolumn'])) { + $pfb['global']['widget-sortcolumn'] = $_POST['pfb_sortcolumn']; + } + if (!empty($_POST['pfb_sortdir'])) { + $pfb['global']['widget-sortdir'] = $_POST['pfb_sortdir']; + } + write_config("pfBlockerNG: Saved Widget customizations via Dashboard"); + header("Location: ../../index.php"); +} + +// Ackwnowlege failed downloads if (isset($_POST['pfblockerngack'])) { - $clear = exec("/usr/bin/sed -i '' 's/FAIL/Fail/g' {$pfb['errlog']}"); + exec("/usr/bin/sed -i '' 's/FAIL/Fail/g' {$pfb['errlog']}"); header("Location: ../../index.php"); } -// This function will create the counts -function pfBlockerNG_get_counts() { - global $config, $g, $pfb; +// Called by Ajax to update table contents +if (isset($_GET['getNewCounts'])) { + pfBlockerNG_get_table("js"); + return; +} - // Collect Alias Count and Update Date/Time +// Sort widget table according to user configuration +function pfbsort(&$array, $subkey="id", $sort_ascending=FALSE) { + if (empty($array)) { + return; + } + if (count($array)) { + $temp_array[key($array)] = array_shift($array); + } + + foreach ($array as $key => $val) { + $offset = 0; + $found = FALSE; + foreach ($temp_array as $tmp_key => $tmp_val) { + if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { + $temp_array = array_merge((array)array_slice($temp_array,0,$offset), array($key => $val), array_slice($temp_array,$offset)); + $found = TRUE; + } + $offset++; + } + if (!$found) { + $temp_array = array_merge($temp_array, array($key => $val)); + } + } + + if ($sort_ascending) { + $array = array_reverse($temp_array); + } else { + $array = $temp_array; + } + return; +} + +// Collect all pfBlockerNG statistics +function pfBlockerNG_get_counts() { + global $config, $pfb; $pfb_table = array(); - $out = "\"\""; - $in = "\"\""; - if (is_array($config['aliases']['alias'])) { - foreach ($config['aliases']['alias'] as $cbalias) { - if (preg_match("/pfB_/", $cbalias['name'])) { - if (file_exists("{$pfb['aliasdir']}/{$cbalias['name']}.txt")) { - preg_match("/(\d+)/", exec("/usr/bin/grep -cv \"^1\.1\.1\.1\" {$pfb['aliasdir']}/{$cbalias['name']}.txt"), $matches); - $pfb_table[$cbalias['name']] = array("count" => $matches[1], "img" => $out); - $updates = exec("ls -ld {$pfb['aliasdir']}/{$cbalias['name']}.txt | awk '{ print $6,$7,$8 }'", $update); - $pfb_table[$cbalias['name']]['up'] = $updates; + + /* Alias Table Definitions - 'update' - Last Updated Timestamp + 'rule' - Total number of Firewall rules per alias + 'count' - Total Line Count per alias + 'packets' - Total number of pf packets per alias */ + + exec("/sbin/pfctl -vvsTables | grep -A4 'pfB_'", $pfb_pfctl); + if (!empty($pfb_pfctl)) { + foreach($pfb_pfctl as $line) { + $line = trim(str_replace(array( '[', ']' ), '', $line)); + if (substr($line, 0, 1) == '-') { + $pfb_alias = trim(strstr($line, 'pfB', FALSE)); + if (empty($pfb_alias)) { + unset($pfb_alias); + continue; + } + exec("/usr/bin/grep -cv '^1\.1\.1\.1' {$pfb['aliasdir']}/{$pfb_alias}.txt", $match); + $pfb_table[$pfb_alias] = array('count' => $match[1], 'img' => $pfb['down']); + exec("ls -ld {$pfb['aliasdir']}/{$pfb_alias}.txt | awk '{ print $6,$7,$8 }'", $update); + $pfb_table[$pfb_alias]['update'] = $update[0]; + $pfb_table[$pfb_alias]['rule'] = 0; + unset($match, $update); + continue; + } + + if (isset($pfb_alias)) { + if (substr($line, 0, 9) == 'Addresses') { + $addr = trim(substr(strrchr($line, ':'), 1)); + $pfb_table[$pfb_alias]['count'] = $addr; + continue; + } + if (substr($line, 0, 11) == 'Evaluations') { + $packets = trim(substr(strrchr($line, ':'), 1)); + $pfb_table[$pfb_alias]['packets'] = $packets; + unset($pfb_alias); } } } } + else { + // Error. No pf labels found. + $pfb['pfctl'] = TRUE; + } - // Collect if Rules are defined using pfBlockerNG Aliases. + // Determine if firewall rules are defined if (is_array($config['filter']['rule'])) { foreach ($config['filter']['rule'] as $rule) { - if (preg_match("/pfB_/",$rule['source']['address']) || preg_match("/pfb_/",$rule['source']['address'])) { - $pfb_table[$rule['source']['address']]['img'] = $in; + // Skip disabled rules + if (isset($rule['disabled'])) { + continue; + } + if (stripos($rule['source']['address'], "pfb_") !== FALSE) { + $pfb_table[$rule['source']['address']]['img'] = $pfb['up']; + $pfb_table[$rule['source']['address']]['rule'] += 1; } - if (preg_match("/pfB_/",$rule['destination']['address']) || preg_match("/pfb_/",$rule['destination']['address'])) { - $pfb_table[$rule['destination']['address']]['img'] = $in; + if (stripos($rule['destination']['address'], "pfb_") !== FALSE) { + $pfb_table[$rule['destination']['address']]['img'] = $pfb['up']; + $pfb_table[$rule['destination']['address']]['rule'] += 1; } } - return $pfb_table; } + + // Collect packet fence rule numbers + exec("/sbin/pfctl -vv -sr | grep 'pfB_'", $pfrules); + if (!empty($pfrules)) { + foreach ($pfrules as $result) { + // Sample : @112(0) block return in log quick on em1 from any to label "USER_RULE: pfB_PRI1" + if (preg_match("/@(\d+)\(\d+\).*\<(pfB_\w+):\d+\>/", $result, $rule)) { + $pfb_table[$rule[2]]['rules'] .= $rule[1] . '|'; + } + } + } + + // Sort tables per sort customization + if ($pfb['sortcolumn'] != "none") { + if ($pfb['sortdir'] == "asc") { + pfbsort($pfb_table, $pfb['sortcolumn'], TRUE); + } else { + pfbsort($pfb_table, $pfb['sortcolumn'], FALSE); + } + } + return $pfb_table; } -// Status Indicator if pfBlockerNG is Enabled/Disabled +// Called on initial load and Ajax to update table contents +function pfBlockerNG_get_table($mode="") { + global $pfb; + $counter = 0; $dcounter = 1; $response = ''; + + $pfb_table = pfBlockerNG_get_counts(); + if (!empty($pfb_table)) { + foreach ($pfb_table as $pfb_alias => $values) { + // Add firewall rules count associated with alias + $values['img'] = $values['img'] . "({$values['rule']})"; + + // If packet fence errors found, display error. + if ($pfb['pfctl']) { + $values['img'] = $pfb['err']; + } + + // Alias table popup + if ($values['count'] > 0 && $pfb['popup'] == "on") { + $alias_popup = rule_popup($pfb_alias, '', '', ''); + $alias_span = $alias_popup['src']; + $alias_span_end = $alias_popup['src_end']; + } + else { + $alias_span = ''; + $alias_span_end = ''; + } + + // Packet column pivot to Alerts Tab + if ($values['packets'] > 0) { + $rules = rtrim($values['rules'], '|'); + if ($values['packets'] > $pfb['maxpivot']) { + $aentries = $pfb['maxpivot']; + } else { + $aentries = $values['packets']; + } + + $packets = " + " . $alias_span . $pfb_alias . $alias_span_end . " + {$values['count']} + {$packets} + {$values['update']} + {$values['img']} + "); + } + } + } +} + +// Status indicator if pfBlockerNG is enabled/disabled if ("{$pfb['enable']}" == "on") { $pfb_status = "/themes/{$g['theme']}/images/icons/icon_pass.gif"; $pfb_msg = "pfBlockerNG is Active."; @@ -102,70 +312,78 @@ if ("{$pfb['enable']}" == "on") { $pfb_msg = "pfBlockerNG is Disabled."; } -// Collect Total IP/Cidr Counts +// Collect total IP/Cidr counts $dcount = exec("cat {$pfb['denydir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); $pcount = exec("cat {$pfb['permitdir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); $mcount = exec("cat {$pfb['matchdir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); $ncount = exec("cat {$pfb['nativedir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); -// Collect Number of Suppressed Hosts +// Collect number of suppressed hosts if (file_exists("{$pfb['supptxt']}")) { $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}"); } else { $pfbsupp_cnt = 0; } -#check rule count -#(label, evaluations,packets total, bytes total, packets in, bytes in,packets out, bytes out) -$packets = exec("/sbin/pfctl -s labels", $debug); -if (!empty($debug)) { - foreach ($debug as $line) { - // Auto-Rules start with 'pfB_', Alias Rules should start with 'pfb_' and exact spelling of Alias Name. - $line = str_replace("pfb_","pfB_",$line); - if ("{$pfb['pfsenseversion']}" >= '2.2') { - #USER_RULE: pfB_Top auto rule 8494 17 900 17 900 0 0 0 - if (preg_match("/USER_RULE: (\w+).*\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+/", $line, $matches)) { - if (isset($matches)) { - ${$matches[1]}+=$matches[2]; - } else { - ${$matches[1]} = 'Err'; - } - } - } else { - #USER_RULE: pfB_Top auto rule 1656 0 0 0 0 0 0 - if (preg_match("/USER_RULE: (\w+).*\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+/", $line, $matches)) { - if (isset($matches)) { - ${$matches[1]}+=$matches[2]; - } else { - ${$matches[1]} = 'Err'; - } - } - } - } -} +// Collect any failed downloads +exec("grep $(date +%m/%d/%y) {$pfb['errlog']} | grep 'FAIL'", $results); +$results = array_reverse($results); -// Called by Ajax to update alerts table contents -if (isset($_GET['getNewCounts'])) { - $response = ""; - $pfb_table = pfBlockerNG_get_counts(); - if (!empty($pfb_table)) { - foreach ($pfb_table as $alias => $values){ - if (!isset(${$alias})) { ${$alias} = "-";} - $response .= $alias . "||" . $values['count'] . "||" . ${$alias} . "||" . $values['up'] . "||" . $values['img'] . "\n"; - } - echo $response; - return; - } -} +?> + + + -// Print widget Status Bar Items -?> +
- +
@@ -187,12 +405,14 @@ $fails = exec("grep $(date +%m/%d/%y) {$pfb['errlog']} | grep 'FAIL'", $results) " . $pfbsupp_cnt . ""); ?> - @@ -205,76 +425,53 @@ $fails = exec("grep $(date +%m/%d/%y) {$pfb['errlog']} | grep 'FAIL'", $results) '2.0') { - $alertRowEvenClass = "listMReven"; - $alertRowOddClass = "listMRodd"; - $alertColClass = "listMRr"; -} else { - $alertRowEvenClass = "listr"; - $alertRowOddClass = "listr"; - $alertColClass = "listr"; -} - -# Last errors first -$results = array_reverse($results); - +// Report any failed downloads $counter = 0; -# Max errors to display -$maxfailcount = 3; if (!empty($results)) { foreach ($results as $result) { - $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass; - if (!isset(${$alias})) { ${$alias} = "-";} - echo(" "); + $RowClass = $counter % 2 ? $pfb['RowEvenClass'] : $pfb['RowOddClass']; + echo(" "); $counter++; - if ($counter > $maxfailcount) { - # To many errors stop displaying - echo(" "); + if ($counter > $pfb['maxfails']) { + // To many errors stop displaying + echo(" "); break; } } } -// Print Main Table Header ?> +
    " alt="" />  + " alt="" /> 
- "/> + "/>
" . $result . "
" . $result . "
" . (count($results) - $maxfailcount) . " more error(s)...
" . (count($results) - $pfb['maxfails']) . " more error(s)...
- +
- - - - - - + + + + + + - $values) { - $evenRowClass = $counter % 2 ? " listMReven" : " listMRodd"; - if (!isset(${$alias})) { ${$alias} = "-";} - echo(" - - - - - - "); - $counter++; - } -} -?> + + +
{$alias}{$values['count']}{${$alias}}{$values['up']}{$values['img']}
\ No newline at end of file -- cgit v1.2.3