From b6bbbf2f27fcb337ff79f9fb38f842f6296dde94 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Mon, 16 Feb 2015 22:01:33 -0500 Subject: pfBlockerNG - Fix Aliastable issue on Nano/Ramdisk Installations 1. On Nano/Ramdisk Installations, the /var/db/aliastables folder gets deleted on reboot. This causes a 60 second delay per alias. This PR archives the /var/db/aliastable/pfB_*.txt files to the pfBNG pbi /etc folder. On reboot the contents of this archive are restored. 2. Remove the previous Fetch Timeout code. 3. Improve the IPv6 Regex code. 4. Minor text improvements 5. Add conf_mount RW/RO to the sh script. 6. Add the aliastables() function to restore the aliastables files on reboot. --- config/pfblockerng/pfblockerng.inc | 101 ++++++++++++++++++++++++++++--------- config/pfblockerng/pfblockerng.sh | 72 +++++++++++++++++++++----- 2 files changed, 136 insertions(+), 37 deletions(-) diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index a1ee6abc..3db5b07b 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -78,6 +78,7 @@ function pfb_global() { $pfb['log'] = "{$pfb['logdir']}/pfblockerng.log"; $pfb['supptxt'] = "{$pfb['dbdir']}/pfbsuppression.txt"; $pfb['script'] = 'sh /usr/local/pkg/pfblockerng/pfblockerng.sh'; + $pfb['aliasarchive'] = "/usr/pbi/pfblockerng-" . php_uname("m") . "/etc/aliastables.tar.bz2"; # General Variables $pfb['config'] = $config['installedpackages']['pfblockerng']['config'][0]; @@ -334,6 +335,51 @@ function ip_range_to_subnet_array_temp2($ip1, $ip2) { } +// Archive Aliastables for NanoBSD and RAMDisk Installations +function pfb_aliastables($mode) { + global $g,$config,$pfb; + $earlyshellcmd = "/usr/local/pkg/pfblockerng/pfblockerng.sh aliastables"; + $msg = ""; + + // Only Execute function if Platform is NanoBSD or Ramdisks are used. + if (($g['platform'] != "pfSense") || isset($config['system']['use_mfs_tmpvar'])) { + if ($mode == "update") { + // Archive Aliastable Folder + exec ("cd {$pfb['aliasdir']}; ls -A pfB_*.txt && /usr/bin/tar -jcvf {$pfb['aliasarchive']} pfB_*.txt >/dev/null 2>&1"); + $msg = "\n\nArchiving Aliastable Folder"; + } + elseif ($mode == "conf") { + // Check conf file for earlyshellcmd + if (is_array($config['system']['earlyshellcmd'])) { + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (!preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { + $a_earlyshellcmd[] = "{$earlyshellcmd}"; + $msg = "\n** Adding earlyshellcmd **\n"; + } + } + else { + $config['system']['earlyshellcmd'] = "{$earlyshellcmd}"; + $msg = "\n** Adding earlyshellcmd **\n"; + } + } + } + else { + // Remove earlyshellcmd if found. + if (is_array($config['system']['earlyshellcmd'])) { + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { + $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); + @unlink_if_exists("{$pfb['aliasarchive']}"); + $msg = "\n** Removing earlyshellcmd **\n"; + } + } + } + + if ($msg != "") + pfb_logger("{$msg}","1"); +} + + # Main pfBlockerNG Function function sync_package_pfblockerng($cron = "") { @@ -365,14 +411,8 @@ function sync_package_pfblockerng($cron = "") { } } - # TBC if Required ! (Fetch Timeout in 2.2) - - #apply fetch timeout to pfsense-utils.inc - $pfsense_utils = file_get_contents('/etc/inc/pfsense-utils.inc'); - $new_pfsense_utils = preg_replace("/\/usr\/bin\/fetch -q/","/usr/bin/fetch -T 5 -q",$pfsense_utils); - if ($new_pfsense_utils != $pfsense_utils) { - @file_put_contents('/etc/inc/pfsense-utils.inc',$new_pfsense_utils, LOCK_EX); - } + // Call function for NanoBSD/Ramdisk processes. + pfb_aliastables("conf"); # Collect pfSense Max Table Size Entry $pfb['table_limit'] = ($config['system']['maximumtableentries'] != "" ? $config['system']['maximumtableentries'] : "2000000"); @@ -1173,7 +1213,7 @@ function sync_package_pfblockerng($cron = "") { $pattern8 = '[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}::\/[0-9]{2}'; $pattern9 = '[A-Fa-f0-9]{1,4}:([A-Fa-f0-9]{1,4}::)\/[0-9]{2}'; $pattern10 = '[A-Fa-f0-9]{1,4}::\/[0-9]{2}'; - $pfb['ipv6'] = "/^($pattern1)$|^($pattern2)$|^($pattern3)$|^($pattern4)$|^($pattern5)$|^($pattern6)$|^($pattern7)$|^($pattern8)$|^($pattern9)$|^($pattern10)$/"; + $pfb['ipv6'] = "/($pattern1)|($pattern2)|($pattern3)|($pattern4)|($pattern5)|($pattern6)|($pattern7)|($pattern8)|($pattern9)|($pattern10)/"; $pfb['supp_update'] = FALSE; $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); @@ -2223,6 +2263,9 @@ function sync_package_pfblockerng($cron = "") { #load filter file which will create the pfctl tables filter_configure(); + + // Call function for NanoBSD/Ramdisk processes. + pfb_aliastables("update"); } else { # Don't Execute on User 'Save' if (!$pfb['save']) { @@ -2253,8 +2296,11 @@ function sync_package_pfblockerng($cron = "") { $log = implode($result_pfctl); pfb_logger("{$log}","1"); } + + // Call function for NanoBSD/Ramdisk processes. + pfb_aliastables("update"); } else { - $log = "\n No Changes to Aliases, Skipping pfctl Update \n"; + $log = "\nNo Changes to Aliases, Skipping pfctl Update \n"; pfb_logger("{$log}","1"); } } @@ -2282,7 +2328,7 @@ function sync_package_pfblockerng($cron = "") { ######################################### - # Define/Apply CRON Jobs # + # Define/Apply CRON Jobs # ######################################### # Clear any existing pfBlockerNG Cron Jobs @@ -2291,13 +2337,13 @@ function sync_package_pfblockerng($cron = "") { # Replace Cron job with any User Changes to $pfb_min if ($pfb['enable'] == "on") { # Define pfBlockerNG CRON Job - $pfb_cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php cron >> {$pfb['log']} 2>&1"; + $pfb_cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php cron >> {$pfb['log']} 2>&1"; # $pfb['min'] ( User Defined Variable. Variable defined at start of Script ) - $pfb_hour = "*"; - $pfb_mday = "*"; - $pfb_month = "*"; - $pfb_wday = "*"; - $pfb_who = "root"; + $pfb_hour = "*"; + $pfb_mday = "*"; + $pfb_month = "*"; + $pfb_wday = "*"; + $pfb_who = "root"; install_cron_job($pfb_cmd, true, $pfb['min'], $pfb_hour, $pfb_mday, $pfb_month, $pfb_wday, $pfb_who); } @@ -2311,12 +2357,12 @@ function sync_package_pfblockerng($cron = "") { # MaxMind GeoIP Cron Hour is randomized between 0-23 Hour to minimize effect on MaxMind Website - $pfb_gmin = "0"; - $pfb_ghour = rand(0,23); - $pfb_gmday = "1,2,3,4,5,6,7"; - $pfb_gmonth = "*"; - $pfb_gwday = "2"; - $pfb_gwho = "root"; + $pfb_gmin = "0"; + $pfb_ghour = rand(0,23); + $pfb_gmday = "1,2,3,4,5,6,7"; + $pfb_gmonth = "*"; + $pfb_gwday = "2"; + $pfb_gwho = "root"; install_cron_job($pfb_gcmd, true, $pfb_gmin, $pfb_ghour, $pfb_gmday, $pfb_gmonth, $pfb_gwday, $pfb_gwho); } @@ -2413,6 +2459,15 @@ function pfblockerng_php_deinstall_command() { rmdir_recursive("{$pfb['dbdir']}"); rmdir_recursive("{$pfb['logdir']}"); + // Remove earlyshellcmd if found. + if (is_array($config['system']['earlyshellcmd'])) { + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { + $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); + @unlink_if_exists("{$pfb['aliasarchive']}"); + } + } + # Remove Settings from Config if (is_array($config['installedpackages']['pfblockerng'])) unset($config['installedpackages']['pfblockerng']); diff --git a/config/pfblockerng/pfblockerng.sh b/config/pfblockerng/pfblockerng.sh index cc11be6b..fd0a2f4a 100644 --- a/config/pfblockerng/pfblockerng.sh +++ b/config/pfblockerng/pfblockerng.sh @@ -35,6 +35,7 @@ etblock=$(echo $8 | sed 's/,/, /g') etmatch=$(echo $9 | sed 's/,/, /g') # File Locations +aliasarchive="/usr/pbi/pfblockerng-$mtype/etc/aliastables.tar.bz2" pathgeoipdat=/usr/pbi/pfblockerng-$mtype/share/GeoIP/GeoIP.dat pfbsuppression=/var/db/pfblockerng/pfbsuppression.txt masterfile=/var/db/pfblockerng/masterfile @@ -46,6 +47,7 @@ errorlog=/var/log/pfblockerng/error.log etdir=/var/db/pfblockerng/ET tmpxlsx=/tmp/xlsx/ +pfbdbdir=/var/db/pfblockerng/ pfbdeny=/var/db/pfblockerng/deny/ pfborig=/var/db/pfblockerng/original/ pfbmatch=/var/db/pfblockerng/match/ @@ -65,6 +67,17 @@ syncfile=/tmp/pfbsyncfile matchfile=/tmp/pfbmatchfile tempmatchfile=/tmp/pfbtempmatchfile +PLATFORM=`cat /etc/platform` +USE_MFS_TMPVAR=`/usr/bin/grep -c use_mfs_tmpvar /cf/conf/config.xml` +DISK_NAME=`/bin/df /var/db/rrd | /usr/bin/tail -1 | /usr/bin/awk '{print $1;}'` +DISK_TYPE=`/usr/bin/basename ${DISK_NAME} | /usr/bin/cut -c1-2` + +if [ "${PLATFORM}" != "pfSense" ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = "md" ]; then + /usr/local/bin/php /etc/rc.conf_mount_rw >/dev/null 2>&1 + if [ ! -d $pfbdbdir ]; then mkdir $pfbdbdir; fi + if [ ! -d $pfsense_alias_dir ]; then mkdir $pfsense_alias_dir; fi +fi + if [ ! -f $masterfile ]; then touch $masterfile; fi if [ ! -f $mastercat ]; then touch $mastercat; fi if [ ! -f $tempfile ]; then touch $tempfile; fi @@ -79,6 +92,16 @@ if [ ! -d $pfbmatch ]; then mkdir $pfbmatch; fi if [ ! -d $etdir ]; then mkdir $etdir; fi if [ ! -d $tmpxlsx ]; then mkdir $tmpxlsx; fi + +# Exit Function to set mount RO if required before Exiting +exitnow() { + if [ "${PLATFORM}" != "pfSense" ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = "md" ]; then + /usr/local/bin/php /etc/rc.conf_mount_ro >/dev/null 2>&1 + fi + exit +} + + ########## # Process to condense an IP range if a "Max" amount of IP addresses are found in a /24 range per Alias Group. process24() { @@ -86,7 +109,7 @@ process24() { if [ ! -x $pathgeoip ]; then echo "Process24 - Application [ GeoIP ] Not found. Can't proceed." echo "Process24 - Application [ GeoIP ] Not found. Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi # Download MaxMind GeoIP.dat Binary on first Install. @@ -98,7 +121,7 @@ fi if [ ! -f $pathgeoipdat ]; then echo "Process24 - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed." echo "Process24 - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi count=$(grep -c ^ $pfbdeny$alias".txt") @@ -192,6 +215,7 @@ echo "-------------------------------------------------------" cocount=$(grep -cv "^1\.1\.1\.1" $pfbdeny$alias".txt") echo "Post /24 Count [ $cocount ]"; echo fi +exitnow } @@ -247,6 +271,7 @@ printf "%-10s %-10s %-10s %-30s\n" "Original" "Masterfile" "Outfile" "Sanity Che echo "----------------------------------------------------------" printf "%-10s %-10s %-10s %-30s\n" "$countg" "$countm" "$counto" " [ $sanity ]" echo "----------------------------------------------------------" +exitnow } @@ -257,7 +282,7 @@ suppress() { if [ ! -x $pathgrepcidr ]; then echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" >> errorlog - exit + exitnow fi if [ -e "$pfbsuppression" ] && [ -s "$pfbsuppression" ]; then @@ -270,7 +295,7 @@ if [ -e "$pfbsuppression" ] && [ -s "$pfbsuppression" ]; then echo; echo "===[ Suppression Stats ]========================================"; echo printf "%-20s %-10s %-10s %-10s %-10s\n" "List" "Pre" "RFC1918" "Suppress" "Masterfile" echo "----------------------------------------------------------------" - exit + exitnow fi for i in $cc; do @@ -342,7 +367,7 @@ else echo "===[ Suppression Stats ]========================================"; echo printf "%-20s %-10s %-10s %-10s %-10s\n" "List" "Pre" "RFC1918" "Suppress" "Masterfile" echo "----------------------------------------------------------------" - exit + exitnow fi for i in $cc; do alias=$(echo "${i%|*}") @@ -372,6 +397,7 @@ else fi done fi +exitnow } @@ -382,7 +408,7 @@ duplicate() { if [ ! -x $pathgrepcidr ]; then echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" >> errorlog - exit + exitnow fi dupcheck=yes @@ -415,6 +441,7 @@ printf "%-10s %-10s %-10s %-30s\n" "Original" "Masterfile" "Outfile" " [ Post Du echo "----------------------------------------------------------" printf "%-10s %-10s %-10s %-30s\n" "$countg" "$countm" "$counto" " [ $sanity ]" echo "----------------------------------------------------------" +exitnow } @@ -425,7 +452,7 @@ deduplication() { if [ ! -x $pathgeoip ]; then echo "d-duplication - Application [ GeoIP ] Not found. Can't proceed." echo "d-duplication - Application [ GeoIP ] Not found. Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi # Download MaxMind GeoIP.dat on first Install. @@ -438,7 +465,7 @@ fi if [ ! -f $pathgeoipdat ]; then echo "d-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed." echo "d-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi > $tempfile; > $tempfile2; > $dupfile; > $addfile; > $dedupfile; > $matchfile; > $tempmatchfile; count=0; dcount=0; mcount=0; mmcount=0 @@ -541,6 +568,7 @@ echo " [ Post d-Deduplication count ] [ $count ]"; echo # Write "1.1.1.1" to empty Final Blocklist Files emptyfiles=$(find $pfbdeny -size 0) for i in $emptyfiles; do echo "1.1.1.1" > $i; done +exitnow } @@ -551,7 +579,7 @@ pdeduplication(){ if [ ! -x $pathgeoip ]; then echo "p-duplication - Application [ GeoIP ] Not found. Can't proceed." echo "p-duplication - Application [ GeoIP ] Not found. Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi # Download MaxMind GeoIP.dat on first Install. @@ -563,7 +591,7 @@ fi if [ ! -f $pathgeoipdat ]; then echo "p-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed." echo "p-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi > $tempfile; > $tempfile2; > $dupfile; > $addfile; > $dedupfile; count=0; dcount=0 @@ -616,6 +644,7 @@ echo; echo " [ Post p-Deduplication count ] [ $count ]" # Write "1.1.1.1" to empty Final Blocklist Files emptyfiles=$(find $pfbdeny -size 0) for i in $emptyfiles; do echo "1.1.1.1" > $i; done +exitnow } @@ -626,7 +655,7 @@ processet() { if [ ! -x $pathgunzip ]; then echo "Application [ Gunzip ] Not found, Can't proceed." echo "Application [ Gunzip ] Not found, Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi if [ -s $pfborig$alias".gz" ]; then @@ -714,6 +743,7 @@ if [ -s $pfborig$alias".gz" ]; then else echo; echo "No ET .GZ File Found!" fi +exitnow } # Process to extract IP addresses from XLSX Files @@ -722,7 +752,7 @@ processxlsx() { if [ ! -x $pathtar ]; then echo "Application [ TAR ] Not found, Can't proceed." echo "Application [ TAR ] Not found, Can't proceed. [ $now ]" >> $errorlog - exit + exitnow fi if [ -s $pfborig$alias".zip" ]; then @@ -738,6 +768,7 @@ else echo "XLSX Download File Missing" echo " [ $alias ] XLSX Download File Missing [ $now ]" >> $errorlog fi +exitnow } closingprocess() { @@ -856,6 +887,7 @@ echo; echo "pfSense Table Stats"; echo "-------------------" $pathpfctl -s memory | grep "table-entries" pfctlcount=$($pathpfctl -vvsTables | awk '/Addresses/ {s+=$2}; END {print s}') echo "Table Usage Count " $pfctlcount +exitnow } remove() { @@ -883,6 +915,15 @@ emptychk=$(find $masterfile -size 0) if [ ! "$emptychk" == "" ]; then rm -r $masterfile; rm -r $mastercat fi +exitnow +} + +# Process to restore aliasables from archive on reboot ( NanoBSD and Ramdisk Installations only ) +aliastables() { + if [ "${PLATFORM}" != "pfSense" ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = "md" ]; then + [ -f $aliasarchive ] && cd $pfsense_alias_dir && /usr/bin/tar -jxvf $aliasarchive + fi + exitnow } @@ -920,8 +961,11 @@ case $1 in remove) remove ;; + aliastables) + aliastables + ;; *) - exit + exitnow ;; esac -exit \ No newline at end of file +exitnow \ No newline at end of file -- cgit v1.2.3 From 0707346f40609c5db5ef027d489e0e4af7b32e08 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Mon, 16 Feb 2015 22:34:28 -0500 Subject: pfBlockerNG - Improve Alerts Tab (Speed/Efficiency) A significant change to the Alerts Tab. This was previously using the pfSense conv_log_filter function which for this purpose was too bulky. Added a new function conv_log_filter_lite to improve the process. 75% improvement in Processing Time/CPU Load ( even with alerts counts >500 ) Improved the Javascript function so that its not called when not required. This was spinning up additional php-fpm processes. Changed !empty to !isset for Deny/Permit/Match Alert Counts. Previously could not enter a "0" value with !empty. --- config/pfblockerng/pfblockerng_alerts.php | 219 +++++++++++++++++++++--------- 1 file changed, 155 insertions(+), 64 deletions(-) diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index f03f7040..cb892187 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -41,8 +41,12 @@ // Auto-Resolve Hostnames if (isset($_REQUEST['getpfhostname'])) { - $getpfhostname = htmlspecialchars($_REQUEST['getpfhostname']); - $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES); + $getpfhostname = trim(htmlspecialchars($_REQUEST['getpfhostname'])); + if (strlen($getpfhostname) >= 8) { + $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES); + } else { + $hostname = $getpfhostname; + } if ($hostname == $getpfhostname) { $hostname = 'unknown'; } @@ -52,9 +56,8 @@ if (isset($_REQUEST['getpfhostname'])) { require_once("util.inc"); require_once("guiconfig.inc"); -require_once("filter_log.inc"); require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); - +global $rule_list; pfb_global(); // Application Paths @@ -88,11 +91,11 @@ $rule_list = array(); $results = array(); $data = exec ("/sbin/pfctl -vv -sr | grep 'pfB_'", $results); -if (empty($config['installedpackages']['pfblockerngglobal']['pfbdenycnt'])) +if (!isset($config['installedpackages']['pfblockerngglobal']['pfbdenycnt'])) $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = '25'; -if (empty($config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'])) +if (!isset($config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'])) $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = '5'; -if (empty($config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'])) +if (!isset($config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'])) $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'] = '5'; if (empty($config['installedpackages']['pfblockerngglobal']['alertrefresh'])) $config['installedpackages']['pfblockerngglobal']['alertrefresh'] = 'off'; @@ -293,6 +296,103 @@ function check_lan_dest($lan_ip,$lan_mask,$dest_ip,$dest_mask="32") { } +// Parse Filter log for pfBlockerNG Alerts +function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt) { + global $rule_list; + $fields_array = array(); + $logarr = ""; + $denycnt = 0; + $permitcnt = 0; + $matchcnt = 0; + + if (file_exists($logfile)) { + exec("/usr/local/sbin/clog " . escapeshellarg($logfile) . " | grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/grep 'filterlog:' | /usr/bin/tail -r -n {$tail}", $logarr); + } + else return; + + if (!empty($logarr) && !empty($rule_list['id'])) { + foreach ($logarr as $logent) { + $pfbalert = array(); + $log_split = ""; + + if (!preg_match("/(.*)\s(.*)\sfilterlog:\s(.*)$/", $logent, $log_split)) + continue; + + list($all, $pfbalert[99], $host, $rule) = $log_split; + $rule_data = explode(",", $rule); + $pfbalert[0] = $rule_data[0]; // Rulenum + + // Skip Alert if Rule is not a pfBNG Alert + if (!in_array($pfbalert[0], $rule_list['id'])) + continue; + + $pfbalert[1] = $rule_data[4]; // Realint + $pfbalert[3] = $rule_data[6]; // Act + $pfbalert[4] = $rule_data[8]; // Version + + if ($pfbalert[4] == "4") { + $pfbalert[5] = $rule_data[15]; // Protocol ID + $pfbalert[6] = $rule_data[16]; // Protocol + $pfbalert[7] = $rule_data[18]; // SRC IP + $pfbalert[8] = $rule_data[19]; // DST IP + } else { + $pfbalert[5] = $rule_data[14]; // Protocol ID + $pfbalert[6] = $rule_data[13]; // Protocol + $pfbalert[7] = $rule_data[15]; // SRC IP + $pfbalert[8] = $rule_data[16]; // DST IP + } + + if ($pfbalert[5] == "6" || $pfbalert[5] == "17") { + $pfbalert[9] = $rule_data[20]; // SRC Port + $pfbalert[10] = $rule_data[21]; // DST Port + $pfbalert[11] = $rule_data[23]; // TCP Flags + } else { + $pfbalert[9] = ""; + $pfbalert[10] = ""; + $pfbalert[11] = ""; + } + + // Skip Repeated Alerts + if (($pfbalert[3] . $pfbalert[8] . $pfbalert[10]) == $previous_dstip || ($pfbalert[3] . $pfbalert[7] . $pfbalert[9]) == $previous_srcip) + continue; + + $pfbalert[2] = convert_real_interface_to_friendly_descr($rule_data[4]); // Friendly Interface Name + $pfbalert[6] = strtoupper($pfbalert[6]); + + if ($pfbalert[3] == "block") { + if ($denycnt < $pfbdenycnt) { + $fields_array['Deny'][] = $pfbalert; + $denycnt++; + } + } + elseif ($pfbalert[3] == "pass") { + if ($permitcnt < $pfbpermitcnt) { + $fields_array['Permit'][] = $pfbalert; + $permitcnt++; + } + } + elseif ($pfbalert[3] == "unkn(%u)" || $pfbalert[3] == "unkn(11)") { + if ($matchcnt < $pfbmatchcnt) { + $fields_array['Match'][] = $pfbalert; + $matchcnt++; + } + } + + // Exit function if Sufficinet Matches found. + if ($denycnt >= $pfbdenycnt && $permitcnt >= $pfbpermitcnt && $matchcnt >= $pfbmatchcnt) { + unset ($pfbalert, $logarr); + return $fields_array; + } + + // Collect Details for Repeated Alert Comparison + $previous_srcip = $pfbalert[3] . $pfbalert[7] . $pfbalert[9]; + $previous_dstip = $pfbalert[3] . $pfbalert[8] . $pfbalert[10]; + } + unset ($pfbalert, $logarr); + return $fields_array; + } +} + $pgtitle = gettext("pfBlockerNG: Alerts"); include_once("head.inc"); ?> @@ -394,16 +494,9 @@ if ($savemsg) { - @@ -450,8 +543,8 @@ if ($pfb['runonce']) { } else { $pfblines = (exec("/usr/local/sbin/clog {$filter_logfile} | /usr/bin/grep -c ^") /2 ); } - $fields_array = conv_log_filter($filter_logfile, $pfblines, $pfblines); + $fields_array = conv_log_filter_lite($filter_logfile, $pfblines, $pfblines, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt); $continents = array('pfB_Africa','pfB_Antartica','pfB_Asia','pfB_Europe','pfB_NAmerica','pfB_Oceania','pfB_SAmerica','pfB_Top'); $supp_ip_txt .= "Clicking this Suppression Icon, will immediately remove the Block.\n\nSuppressing a /32 CIDR is better than Suppressing the full /24"; @@ -514,30 +607,33 @@ if ($pfb['runonce']) { $counter = 0; // Process Fields_array and generate Output -if (!empty($fields_array)) { - foreach ($fields_array as $fields) { +if (!empty($fields_array[$type]) && !empty($rule_list)) { + $key = 0; + foreach ($fields_array[$type] as $fields) { $rulenum = ""; $alert_ip = ""; $supp_ip = ""; $pfb_query = ""; - $rulenum = $fields['rulenum']; - if ($fields['act'] == $rtype && !empty($rule_list) && in_array($rulenum, $rule_list['id']) && $counter < $pfbentries) { - - // Skip Repeated Events - if (($fields['dstip'] . $fields['dstport']) == $previous_dstip || ($fields['srcip'] . $fields['srcport']) == $previous_srcip) { - continue; - } + /* Fields_array Reference [0] = Rulenum [6] = Protocol + [1] = Real Interface [7] = SRC IP + [2] = Friendly Interface Name [8] = DST IP + [3] = Action [9] = SRC Port + [4] = Version [10] = DST Port + [5] = Protocol ID [11] = Flags + [99] = Timestamp */ - $proto = str_replace("TCP", "TCP-", $fields['proto']) . $fields['tcpflags']; + $rulenum = $fields[0]; + if ($counter < $pfbentries) { + $proto = str_replace("TCP", "TCP-", $fields[6]) . $fields[11]; // Cleanup Port Output - if ($fields['proto'] == "ICMP") { - $srcport = $fields['srcport']; - $dstport = $fields['dstport']; + if ($fields[6] == "ICMP") { + $srcport = ""; + $dstport = ""; } else { - $srcport = " :" . $fields['srcport']; - $dstport = " :" . $fields['dstport']; + $srcport = " :" . $fields[9]; + $dstport = " :" . $fields[10]; } // Don't add Suppress Icon to Country Block Lines @@ -546,10 +642,10 @@ if (!empty($fields_array)) { } // Add DNS Resolve and Suppression Icons to External IPs only. GeoIP Code to External IPs only. - if (in_array($fields['dstip'], $pfb_local) || check_lan_dest($lan_ip,$lan_mask,$fields['dstip'],"32")) { + if (in_array($fields[8], $pfb_local) || check_lan_dest($lan_ip,$lan_mask,$fields[8],"32")) { // Destination is Gateway/NAT/VIP $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; - $host = $fields['srcip']; + $host = $fields[7]; if (is_ipaddrv4($host)) { $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); @@ -568,19 +664,17 @@ if (!empty($fields_array)) { } if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { - $hostname = getpfbhostname('src', $fields['srcip'], $counter); + $hostname = getpfbhostname('src', $fields[7], $counter); } else { $hostname = ""; } - $src_icons = $alert_ip . " " . $supp_ip . " "; - $dst_icons = ""; - $scc = $country; - $dcc = ""; + $src_icons = $alert_ip . " " . $supp_ip . " "; + $dst_icons = ""; } else { // Outbound $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; - $host = $fields['dstip']; + $host = $fields[8]; if (is_ipaddrv4($host)) { $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); @@ -599,15 +693,13 @@ if (!empty($fields_array)) { } if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { - $hostname = getpfbhostname('dst', $fields['dstip'], $counter); + $hostname = getpfbhostname('dst', $fields[8], $counter); } else { $hostname = ""; } - $src_icons = ""; - $dst_icons = $alert_ip . " " . $supp_ip . " "; - $scc = ""; - $dcc = $country; + $src_icons = ""; + $dst_icons = $alert_ip . " " . $supp_ip . " "; } # IP Query Grep Exclusion @@ -681,9 +773,9 @@ if (!empty($fields_array)) { } } + // Truncate Long List Names $pfb_matchtitle = "Country Block Rules cannot be suppressed.\n\nTo allow a particular Country IP, either remove the particular Country or add the Host\nto a Permit Alias in the Firewall Tab.\n\nIf the IP is not listed beside the List, this means that the Block is a /32 entry.\nOnly /32 or /24 CIDR Hosts can be suppressed.\n\nIf (Duplication) Checking is not enabled. You may see /24 and /32 CIDR Blocks for a given blocked Host"; - // Truncate Long List Names if (strlen($pfb_match[1]) >= 17) { $pfb_matchtitle = $pfb_match[1]; $pfb_match[1] = substr($pfb_match[1], 0, 16) . '...'; @@ -691,27 +783,22 @@ if (!empty($fields_array)) { // Print Alternating Line Shading if ($pfb['pfsenseversion'] > '2.0') { - $alertRowEvenClass = "listMReven"; - $alertRowOddClass = "listMRodd"; + $alertRowEvenClass = "listMReven"; + $alertRowOddClass = "listMRodd"; } else { - $alertRowEvenClass = "listr"; - $alertRowOddClass = "listr"; + $alertRowEvenClass = "listr"; + $alertRowOddClass = "listr"; } - // Collect Details for Repeated Alert Comparison - $previous_srcip = $fields['srcip'] . $fields['srcport']; - $previous_dstip = $fields['dstip'] . $fields['dstport']; - $countrycode = trim($scc . $dcc); - $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass; echo " - - + + - - - + + + "; $counter++; if ($counter > 0 && $rtype == "block") { @@ -725,6 +812,7 @@ if (!empty($fields_array)) {
- = '2.2'): ?> - -    - - -    - -    - + + +     
{$fields['time']}{$fields['interface']}{$fields[99]}{$fields[2]} {$rule} {$proto}{$src_icons}{$fields['srcip']}{$srcport}
{$hostname['src']}
{$dst_icons}{$fields['dstip']}{$dstport}
{$hostname['dst']}
{$countrycode}{$src_icons}{$fields[7]}{$srcport}
{$hostname['src']}
{$dst_icons}{$fields[8]}{$dstport}
{$hostname['dst']}
{$country} {$pfb_match[1]}
{$pfb_match[2]}
+ @@ -762,9 +850,12 @@ function findhostnames(counter) { ) } -var lines = ; -for (alertcount = 0; alertcount < lines; alertcount++) { - setTimeout(findhostnames(alertcount), 30); +var alertlines = ; +var autoresolve = ""; +if ( autoresolve == "on" ) { + for (alertcount = 0; alertcount < alertlines; alertcount++) { + setTimeout(findhostnames(alertcount), 30); + } } //]]> -- cgit v1.2.3 From 5710913b9b14034d6abd7754dd2b85537e9dcf2f Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Mon, 16 Feb 2015 22:38:01 -0500 Subject: pfBlockerNG - Bump version to 1.05 --- pkg_config.10.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg_config.10.xml b/pkg_config.10.xml index 29fa878b..8f038252 100644 --- a/pkg_config.10.xml +++ b/pkg_config.10.xml @@ -117,7 +117,7 @@ Firewall https://forum.pfsense.org/index.php?topic=86212.0 https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.xml - 1.04 + 1.05 Beta 2.2 BBCan177@gmail.com -- cgit v1.2.3 From b9d81c4f46607ef54c62925b3cccb9e3479a6fa4 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Mon, 16 Feb 2015 22:54:35 -0500 Subject: pfBlockerNG - Mods to inc file. Move the unlink_if_exists outside of the if statement, as it needs to be called independently. --- config/pfblockerng/pfblockerng.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index 3db5b07b..78622631 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -364,12 +364,12 @@ function pfb_aliastables($mode) { } } else { - // Remove earlyshellcmd if found. + // Remove Aliastables archive and earlyshellcmd if found. + @unlink_if_exists("{$pfb['aliasarchive']}"); if (is_array($config['system']['earlyshellcmd'])) { $a_earlyshellcmd = &$config['system']['earlyshellcmd']; if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); - @unlink_if_exists("{$pfb['aliasarchive']}"); $msg = "\n** Removing earlyshellcmd **\n"; } } @@ -2459,12 +2459,12 @@ function pfblockerng_php_deinstall_command() { rmdir_recursive("{$pfb['dbdir']}"); rmdir_recursive("{$pfb['logdir']}"); - // Remove earlyshellcmd if found. + // Remove Aliastables archive and earlyshellcmd if found. + @unlink_if_exists("{$pfb['aliasarchive']}"); if (is_array($config['system']['earlyshellcmd'])) { $a_earlyshellcmd = &$config['system']['earlyshellcmd']; if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); - @unlink_if_exists("{$pfb['aliasarchive']}"); } } -- cgit v1.2.3 From 399d1ea90173aa7ce0983a8d849caa7feffa08e0 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Tue, 17 Feb 2015 08:15:30 -0500 Subject: pfBlockerNG - Mods to Alerts tab for IPv6 --- config/pfblockerng/pfblockerng_alerts.php | 42 +- config/pfblockerng/pfblockerng_alerts.php.bak | 866 ++++++++++++++++++++++++++ 2 files changed, 889 insertions(+), 19 deletions(-) create mode 100644 config/pfblockerng/pfblockerng_alerts.php.bak diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index cb892187..22464207 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -326,26 +326,30 @@ function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermi if (!in_array($pfbalert[0], $rule_list['id'])) continue; - $pfbalert[1] = $rule_data[4]; // Realint - $pfbalert[3] = $rule_data[6]; // Act - $pfbalert[4] = $rule_data[8]; // Version + $pfbalert[1] = $rule_data[4]; // Realint + $pfbalert[3] = $rule_data[6]; // Act + $pfbalert[4] = $rule_data[8]; // Version if ($pfbalert[4] == "4") { - $pfbalert[5] = $rule_data[15]; // Protocol ID - $pfbalert[6] = $rule_data[16]; // Protocol - $pfbalert[7] = $rule_data[18]; // SRC IP - $pfbalert[8] = $rule_data[19]; // DST IP + $pfbalert[5] = $rule_data[15]; // Protocol ID + $pfbalert[6] = $rule_data[16]; // Protocol + $pfbalert[7] = $rule_data[18]; // SRC IP + $pfbalert[8] = $rule_data[19]; // DST IP + $pfbalert[9] = $rule_data[20]; // SRC Port + $pfbalert[10] = $rule_data[21]; // DST Port + $pfbalert[11] = $rule_data[23]; // TCP Flags } else { - $pfbalert[5] = $rule_data[14]; // Protocol ID - $pfbalert[6] = $rule_data[13]; // Protocol - $pfbalert[7] = $rule_data[15]; // SRC IP - $pfbalert[8] = $rule_data[16]; // DST IP + $pfbalert[5] = $rule_data[13]; // Protocol ID + $pfbalert[6] = $rule_data[12]; // Protocol + $pfbalert[7] = "[" . $rule_data[15] . "]"; // SRC IP + $pfbalert[8] = "[" . $rule_data[16] . "]"; // DST IP + $pfbalert[9] = $rule_data[17]; // SRC Port + $pfbalert[10] = $rule_data[18]; // DST Port + $pfbalert[11] = $rule_data[20]; // TCP Flags } if ($pfbalert[5] == "6" || $pfbalert[5] == "17") { - $pfbalert[9] = $rule_data[20]; // SRC Port - $pfbalert[10] = $rule_data[21]; // DST Port - $pfbalert[11] = $rule_data[23]; // TCP Flags + // skip } else { $pfbalert[9] = ""; $pfbalert[10] = ""; @@ -628,12 +632,12 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { $proto = str_replace("TCP", "TCP-", $fields[6]) . $fields[11]; // Cleanup Port Output - if ($fields[6] == "ICMP") { - $srcport = ""; - $dstport = ""; + if ($fields[6] == "ICMP" || $fields[6] == "ICMPV6") { + $srcport = ""; + $dstport = ""; } else { - $srcport = " :" . $fields[9]; - $dstport = " :" . $fields[10]; + $srcport = ":" . $fields[9]; + $dstport = ":" . $fields[10]; } // Don't add Suppress Icon to Country Block Lines diff --git a/config/pfblockerng/pfblockerng_alerts.php.bak b/config/pfblockerng/pfblockerng_alerts.php.bak new file mode 100644 index 00000000..cb892187 --- /dev/null +++ b/config/pfblockerng/pfblockerng_alerts.php.bak @@ -0,0 +1,866 @@ += 8) { + $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES); + } else { + $hostname = $getpfhostname; + } + if ($hostname == $getpfhostname) { + $hostname = 'unknown'; + } + echo $hostname; + die; +} + +require_once("util.inc"); +require_once("guiconfig.inc"); +require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); +global $rule_list; +pfb_global(); + +// Application Paths +$pathgeoip = "/usr/pbi/pfblockerng-" . php_uname("m") . "/bin/geoiplookup"; +$pathgeoip6 = "/usr/pbi/pfblockerng-" . php_uname("m") . "/bin/geoiplookup6"; + +// Define File Locations +$filter_logfile = "{$g['varlog_path']}/filter.log"; +$pathgeoipdat = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIP.dat"; +$pathgeoipdat6 = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIPv6.dat"; + +// Emerging Threats IQRisk Header Name Reference +$pfb['et_header'] = TRUE; +$et_header = $config['installedpackages']['pfblockerngreputation']['config'][0]['et_header']; +if (empty($et_header)) + $pfb['et_header'] = FALSE; + +// Collect pfBlockerNGSuppress Alias and Create pfbsuppression.txt +if ($pfb['supp'] == "on") + pfb_create_suppression_file(); + +// Collect Number of Suppressed Hosts +if (file_exists("{$pfb['supptxt']}")) { + $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}"); +} else { + $pfbsupp_cnt = 0; +} + +// Collect pfBlockerNG Rule Names and Number +$rule_list = array(); +$results = array(); +$data = exec ("/sbin/pfctl -vv -sr | grep 'pfB_'", $results); + +if (!isset($config['installedpackages']['pfblockerngglobal']['pfbdenycnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = '25'; +if (!isset($config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = '5'; +if (!isset($config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'] = '5'; +if (empty($config['installedpackages']['pfblockerngglobal']['alertrefresh'])) + $config['installedpackages']['pfblockerngglobal']['alertrefresh'] = 'off'; +if (empty($config['installedpackages']['pfblockerngglobal']['hostlookup'])) + $config['installedpackages']['pfblockerngglobal']['hostlookup'] = 'off'; + +if (isset($_POST['save'])) { + if (!is_array($config['installedpackages']['pfblockerngglobal'])) + $config['installedpackages']['pfblockerngglobal'] = array(); + $config['installedpackages']['pfblockerngglobal']['alertrefresh'] = $_POST['alertrefresh'] ? 'on' : 'off'; + $config['installedpackages']['pfblockerngglobal']['hostlookup'] = $_POST['hostlookup'] ? 'on' : 'off'; + if (is_numeric($_POST['pfbdenycnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = $_POST['pfbdenycnt']; + if (is_numeric($_POST['pfbpermitcnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = $_POST['pfbpermitcnt']; + if (is_numeric($_POST['pfbmatchcnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'] = $_POST['pfbmatchcnt']; + + write_config("pfBlockerNG pkg: updated ALERTS tab settings."); + header("Location: " . $_SERVER['PHP_SELF']); + exit; +} + +if (is_array($config['installedpackages']['pfblockerngglobal'])) { + $alertrefresh = $config['installedpackages']['pfblockerngglobal']['alertrefresh']; + $hostlookup = $config['installedpackages']['pfblockerngglobal']['hostlookup']; + $pfbdenycnt = $config['installedpackages']['pfblockerngglobal']['pfbdenycnt']; + $pfbpermitcnt = $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt']; + $pfbmatchcnt = $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt']; +} + +// Collect pfBlockerNG Firewall Rules +if (!empty($results)) { + foreach ($results as $result) { + + # Find Rule Descriptions + $descr = ""; + if (preg_match("/USER_RULE: (\w+)/",$result,$desc)) + $descr = $desc[1]; + + if ($pfb['pfsenseversion'] >= '2.2') { + preg_match ("/@(\d+)\(/",$result, $rule); + } else { + preg_match ("/@(\d+)\s/",$result, $rule); + } + + $id = $rule[1]; + # Create array of Rule Description and pfctl Rule Number + $rule_list['id'][] = $id; + $rule_list[$id]['name'] = $descr; + } +} + +// Add IP to the Suppression Alias +if (isset($_POST['addsuppress'])) { + $ip = ""; + if (isset($_POST['ip'])) { + $ip = $_POST['ip']; + $table = $_POST['table']; + $descr = $_POST['descr']; + $cidr = $_POST['cidr']; + + // If Description or CIDR field is empty, exit. + if (empty($descr) || empty($cidr)) { + header("Location: " . $_SERVER['PHP_SELF']); + exit; + } + + if (is_ipaddr($ip)) { + + $savemsg1 = "Host IP address {$ip}"; + if (is_ipaddrv4($ip)) { + $iptrim1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.0/24', $ip); + $iptrim2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.', $ip); + $iptrim3 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$4', $ip); + + if ($cidr == "32") { + $pfb_pfctl = exec ("/sbin/pfctl -t {$table} -T show | grep {$iptrim1} 2>&1"); + + if ($pfb_pfctl == "") { + $savemsg2 = " : Removed /32 entry"; + exec ("/sbin/pfctl -t {$table} -T delete {$ip}"); + } else { + $savemsg2 = " : Removed /24 entry, added 254 addr"; + exec ("/sbin/pfctl -t {$table} -T delete {$iptrim1}"); + for ($add_ip=0; $add_ip <= 255; $add_ip++){ + if ($add_ip != $iptrim3) { + exec ("/sbin/pfctl -t {$table} -T add {$iptrim2}{$add_ip}"); + } + } + } + } else { + $cidr = 24; + $savemsg2 = " : Removed /24 entry"; + exec ("/sbin/pfctl -t {$table} -T delete {$iptrim1} 2>&1", $pfb_pfctl); + if (!preg_grep("/1\/1 addresses deleted/", $pfb_pfctl)) { + $savemsg2 = " : Removed all entries"; + // Remove 0-255 IP Address from Alias Table + for ($del_ip=0; $del_ip <= 255; $del_ip++){ + exec ("/sbin/pfctl -t {$table} -T delete {$iptrim2}{$del_ip}"); + } + } + } + } + + // Collect pfBlockerNGSuppress Alias Contents + $pfb_sup_list = array(); + $pfb_sup_array = array(); + $pfb['found'] = FALSE; + $pfb['update'] = FALSE; + if (is_array($config['aliases']['alias'])) { + foreach ($config['aliases']['alias'] as $alias) { + if ($alias['name'] == "pfBlockerNGSuppress") { + $data = $alias['address']; + $data2 = $alias['detail']; + $arr1 = explode(" ",$data); + $arr2 = explode("||",$data2); + + if (!empty($data)) { + $row = 0; + foreach ($arr1 as $host) { + $pfb_sup_list[] = $host; + $pfb_sup_array[$row]['host'] = $host; + $row++; + } + $row = 0; + foreach ($arr2 as $detail) { + $pfb_sup_array[$row]['detail'] = $detail; + $row++; + } + } + $pfb['found'] = TRUE; + } + } + } + + // Call Function to Create Suppression Alias if not found. + if (!$pfb['found']) + pfb_create_suppression_alias(); + + // Save New Suppress IP to pfBlockerNGSuppress Alias + if (in_array($ip . '/' . $cidr, $pfb_sup_list)) { + $savemsg = gettext("Host IP address {$ip} already exists in the pfBlockerNG Suppress Table."); + } else { + if (!$pfb['found'] && empty($pfb_sup_list)) { + $next_id = 0; + } else { + $next_id = count($pfb_sup_list); + } + $pfb_sup_array[$next_id]['host'] = $ip . '/' . $cidr; + $pfb_sup_array[$next_id]['detail'] = $descr; + + $address = ""; + $detail = ""; + foreach ($pfb_sup_array as $pfb_sup) { + $address .= $pfb_sup['host'] . " "; + $detail .= $pfb_sup['detail'] . "||"; + } + + // Find pfBlockerNGSuppress Array ID Number + if (is_array($config['aliases']['alias'])) { + $pfb_id = 0; + foreach ($config['aliases']['alias'] as $alias) { + if ($alias['name'] == "pfBlockerNGSuppress") { + break; + } + $pfb_id++; + } + } + + $config['aliases']['alias'][$pfb_id]['address'] = rtrim($address, " "); + $config['aliases']['alias'][$pfb_id]['detail'] = rtrim($detail, "||"); + $savemsg = gettext($savemsg1) . gettext($savemsg2) . gettext(" and added Host to the pfBlockerNG Suppress Table."); + $pfb['update'] = TRUE; + } + + if ($pfb['found'] || $pfb['update']) { + // Save all Changes to pfsense config file + write_config(); + } + } + } +} + +// Host Resolve Function lookup +function getpfbhostname($type = 'src', $hostip, $countme = 0) { + $hostnames['src'] = ''; + $hostnames['dst'] = ''; + $hostnames[$type] = '
'; + return $hostnames; +} + + +// Determine if Alert Host 'Dest' is within the Local Lan IP Range. +function check_lan_dest($lan_ip,$lan_mask,$dest_ip,$dest_mask="32") { + $result = check_subnets_overlap($lan_ip, $lan_mask, $dest_ip, $dest_mask); + return $result; +} + + +// Parse Filter log for pfBlockerNG Alerts +function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt) { + global $rule_list; + $fields_array = array(); + $logarr = ""; + $denycnt = 0; + $permitcnt = 0; + $matchcnt = 0; + + if (file_exists($logfile)) { + exec("/usr/local/sbin/clog " . escapeshellarg($logfile) . " | grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/grep 'filterlog:' | /usr/bin/tail -r -n {$tail}", $logarr); + } + else return; + + if (!empty($logarr) && !empty($rule_list['id'])) { + foreach ($logarr as $logent) { + $pfbalert = array(); + $log_split = ""; + + if (!preg_match("/(.*)\s(.*)\sfilterlog:\s(.*)$/", $logent, $log_split)) + continue; + + list($all, $pfbalert[99], $host, $rule) = $log_split; + $rule_data = explode(",", $rule); + $pfbalert[0] = $rule_data[0]; // Rulenum + + // Skip Alert if Rule is not a pfBNG Alert + if (!in_array($pfbalert[0], $rule_list['id'])) + continue; + + $pfbalert[1] = $rule_data[4]; // Realint + $pfbalert[3] = $rule_data[6]; // Act + $pfbalert[4] = $rule_data[8]; // Version + + if ($pfbalert[4] == "4") { + $pfbalert[5] = $rule_data[15]; // Protocol ID + $pfbalert[6] = $rule_data[16]; // Protocol + $pfbalert[7] = $rule_data[18]; // SRC IP + $pfbalert[8] = $rule_data[19]; // DST IP + } else { + $pfbalert[5] = $rule_data[14]; // Protocol ID + $pfbalert[6] = $rule_data[13]; // Protocol + $pfbalert[7] = $rule_data[15]; // SRC IP + $pfbalert[8] = $rule_data[16]; // DST IP + } + + if ($pfbalert[5] == "6" || $pfbalert[5] == "17") { + $pfbalert[9] = $rule_data[20]; // SRC Port + $pfbalert[10] = $rule_data[21]; // DST Port + $pfbalert[11] = $rule_data[23]; // TCP Flags + } else { + $pfbalert[9] = ""; + $pfbalert[10] = ""; + $pfbalert[11] = ""; + } + + // Skip Repeated Alerts + if (($pfbalert[3] . $pfbalert[8] . $pfbalert[10]) == $previous_dstip || ($pfbalert[3] . $pfbalert[7] . $pfbalert[9]) == $previous_srcip) + continue; + + $pfbalert[2] = convert_real_interface_to_friendly_descr($rule_data[4]); // Friendly Interface Name + $pfbalert[6] = strtoupper($pfbalert[6]); + + if ($pfbalert[3] == "block") { + if ($denycnt < $pfbdenycnt) { + $fields_array['Deny'][] = $pfbalert; + $denycnt++; + } + } + elseif ($pfbalert[3] == "pass") { + if ($permitcnt < $pfbpermitcnt) { + $fields_array['Permit'][] = $pfbalert; + $permitcnt++; + } + } + elseif ($pfbalert[3] == "unkn(%u)" || $pfbalert[3] == "unkn(11)") { + if ($matchcnt < $pfbmatchcnt) { + $fields_array['Match'][] = $pfbalert; + $matchcnt++; + } + } + + // Exit function if Sufficinet Matches found. + if ($denycnt >= $pfbdenycnt && $permitcnt >= $pfbpermitcnt && $matchcnt >= $pfbmatchcnt) { + unset ($pfbalert, $logarr); + return $fields_array; + } + + // Collect Details for Repeated Alert Comparison + $previous_srcip = $pfbalert[3] . $pfbalert[7] . $pfbalert[9]; + $previous_dstip = $pfbalert[3] . $pfbalert[8] . $pfbalert[10]; + } + unset ($pfbalert, $logarr); + return $fields_array; + } +} + +$pgtitle = gettext("pfBlockerNG: Alerts"); +include_once("head.inc"); +?> + +
+ + + + +\n"; +if ($savemsg) { + print_info_box($savemsg); +} + +?> + + + + + + +
+ +
+ + + + + + + + + + $pfb['denydir'] . " " . $pfb['nativedir'], "Permit" => $pfb['permitdir'], "Match" => $pfb['matchdir']) as $type => $pfbfolder ): + switch($type) { + case "Deny": + $rtype = "block"; + $pfbentries = "{$pfbdenycnt}"; + break; + case "Permit": + $rtype = "pass"; + $pfbentries = "{$pfbpermitcnt}"; + break; + case "Match": + if ($pfb['pfsenseversion'] >= '2.2') { + $rtype = "unkn(%u)"; + } else { + $rtype = "unkn(11)"; + } + $pfbentries = "{$pfbmatchcnt}"; + break; + } + +?> +
  +   +   +
+ + ', ''); ?> + + ', ''); ?> + + ', ''); ?> + +   />  + +   />    +
+ +        + ', '');?> +
+ + + + + +
+ +      + +
+ + + + + + + + + + + + + + + + + + + + + + + + += '2.2') { + $pfblines = exec("/usr/local/sbin/clog {$filter_logfile} | /usr/bin/grep -c ^"); + } else { + $pfblines = (exec("/usr/local/sbin/clog {$filter_logfile} | /usr/bin/grep -c ^") /2 ); + } + + $fields_array = conv_log_filter_lite($filter_logfile, $pfblines, $pfblines, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt); + $continents = array('pfB_Africa','pfB_Antartica','pfB_Asia','pfB_Europe','pfB_NAmerica','pfB_Oceania','pfB_SAmerica','pfB_Top'); + + $supp_ip_txt .= "Clicking this Suppression Icon, will immediately remove the Block.\n\nSuppressing a /32 CIDR is better than Suppressing the full /24"; + $supp_ip_txt .= " CIDR.\nThe Host will be added to the pfBlockerNG Suppress Alias Table.\n\nOnly 32 or 24 CIDR IPs can be Suppressed with the '+' Icon."; + $supp_ip_txt .= "\nTo manually add Host(s), edit the 'pfBlockerNGSuppress' Alias in the Alias Tab.\nManual entries will not remove existing Blocked Hosts"; + + // Array of all Local IPs for Alert Analysis + $pfb_local = array(); + + // Collect Gateway IP Addresses for Inbound/Outbound List matching + $int_gateway = get_interfaces_with_gateway(); + if (is_array($int_gateway)) { + foreach ($int_gateway as $gateway) { + $convert = get_interface_ip($gateway); + $pfb_local[] = $convert; + } + } + + // Collect Virtual IP Aliases for Inbound/Outbound List Matching + if (is_array($config['virtualip']['vip'])) { + foreach ($config['virtualip']['vip'] as $list) { + $pfb_local[] = $list['subnet']; + } + } + // Collect NAT IP Addresses for Inbound/Outbound List Matching + if (is_array($config['nat']['rule'])) { + foreach ($config['nat']['rule'] as $natent) { + $pfb_local[] = $natent['target']; + } + } + + // Collect 1:1 NAT IP Addresses for Inbound/Outbound List Matching + if(is_array($config['nat']['onetoone'])) { + foreach ($config['nat']['onetoone'] as $onetoone) { + $pfb_local[] = $onetoone['source']['address']; + } + } + + // Convert any 'Firewall Aliases' to IP Address Format + if (is_array($config['aliases']['alias'])) { + for ($cnt = 0; $cnt <= count($pfb_local); $cnt++) { + foreach ($config['aliases']['alias'] as $i=> $alias) { + if (isset($alias['name']) && isset($pfb_local[$cnt])) { + if ($alias['name'] == $pfb_local[$cnt]) { + $pfb_local[$cnt] = $alias['address']; + } + } + } + } + } + // Remove any Duplicate IPs + $pfb_local = array_unique($pfb_local); + + // Determine Lan IP Address and Mask + if (is_array($config['interfaces']['lan'])) { + $lan_ip = $config['interfaces']['lan']['ipaddr']; + $lan_mask = $config['interfaces']['lan']['subnet']; + } +} + +$counter = 0; +// Process Fields_array and generate Output +if (!empty($fields_array[$type]) && !empty($rule_list)) { + $key = 0; + foreach ($fields_array[$type] as $fields) { + $rulenum = ""; + $alert_ip = ""; + $supp_ip = ""; + $pfb_query = ""; + + /* Fields_array Reference [0] = Rulenum [6] = Protocol + [1] = Real Interface [7] = SRC IP + [2] = Friendly Interface Name [8] = DST IP + [3] = Action [9] = SRC Port + [4] = Version [10] = DST Port + [5] = Protocol ID [11] = Flags + [99] = Timestamp */ + + $rulenum = $fields[0]; + if ($counter < $pfbentries) { + $proto = str_replace("TCP", "TCP-", $fields[6]) . $fields[11]; + + // Cleanup Port Output + if ($fields[6] == "ICMP") { + $srcport = ""; + $dstport = ""; + } else { + $srcport = " :" . $fields[9]; + $dstport = " :" . $fields[10]; + } + + // Don't add Suppress Icon to Country Block Lines + if (in_array(substr($rule_list[$rulenum]['name'], 0, -3), $continents)) { + $pfb_query = "Country"; + } + + // Add DNS Resolve and Suppression Icons to External IPs only. GeoIP Code to External IPs only. + if (in_array($fields[8], $pfb_local) || check_lan_dest($lan_ip,$lan_mask,$fields[8],"32")) { + // Destination is Gateway/NAT/VIP + $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; + $host = $fields[7]; + + if (is_ipaddrv4($host)) { + $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); + } else { + $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2); + } + + $alert_ip .= " "; + + if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { + $supp_ip .= ""; + } + + if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { + $hostname = getpfbhostname('src', $fields[7], $counter); + } else { + $hostname = ""; + } + + $src_icons = $alert_ip . " " . $supp_ip . " "; + $dst_icons = ""; + } else { + // Outbound + $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; + $host = $fields[8]; + + if (is_ipaddrv4($host)) { + $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); + } else { + $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2); + } + + $alert_ip .= " "; + + if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { + $supp_ip .= ""; + } + + if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { + $hostname = getpfbhostname('dst', $fields[8], $counter); + } else { + $hostname = ""; + } + + $src_icons = ""; + $dst_icons = $alert_ip . " " . $supp_ip . " "; + } + + # IP Query Grep Exclusion + $pfb_ex1 = "grep -v 'pfB\_\|\_v6\.txt'"; + $pfb_ex2 = "grep -v 'pfB\_\|/32\|/24\|\_v6\.txt' | grep -m1 '/'"; + + // Find List which contains Blocked IP Host + if ($pfb_query == "Country") { + # Skip + } else { + // Search for exact IP Match + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host); + $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' | {$pfb_ex1}"); + // Search for IP in /24 CIDR + if (empty($pfb_query)) { + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.0/24\'', $host); + $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); + } + // Search for First Two IP Octets in CIDR Matches Only. Skip any pfB (Country Lists) or /32,/24 Addresses. + if (empty($pfb_query)) { + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host); + $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + } + // Search for First Two IP Octets in CIDR Matches Only (Subtract 1 from second Octet on each loop). + // Skip (Country Lists) or /32,/24 Addresses. + if (empty($pfb_query)) { + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.', $host); + $host2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$2', $host); + for ($cnt = 1; $cnt <= 5; $cnt++) { + $host3 = $host2 - $cnt . '\''; + $pfb_query = exec("grep -rH {$host1}{$host3} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + // Break out of loop if found. + if (!empty($pfb_query)) + $cnt = 6; + } + } + // Search for First Three Octets + if (empty($pfb_query)) { + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.$3\.\'', $host); + $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + } + // Search for First Two Octets + if (empty($pfb_query)) { + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host); + $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + } + // Report Specific ET IQRisk Details + if ($pfb['et_header'] && preg_match("/{$et_header}/", $pfb_query)) { + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host); + $pfb_query = exec("grep -Hm1 {$host1} {$pfb['etdir']}/* | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' -e 's/ET_/ET IPrep /' "); + if (empty($pfb_query)) { + $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1.$2.$3.0/24\'', $host); + $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); + } + } + // Default to "No Match" if not found. + if (empty($pfb_query)) + $pfb_query = "No Match"; + } + + # Split List Column into Two lines. + unset ($pfb_match); + if ($pfb_query == "No Match") { + $pfb_match[1] = "{$pfb_query}"; + $pfb_match[2] = ""; + } else { + preg_match ("/(.*)\s(.*)/", $pfb_query, $pfb_match); + if ($pfb_match[1] == "") { + $pfb_match[1] = "{$pfb_query}"; + $pfb_match[2] = ""; + } + } + + // Truncate Long List Names + $pfb_matchtitle = "Country Block Rules cannot be suppressed.\n\nTo allow a particular Country IP, either remove the particular Country or add the Host\nto a Permit Alias in the Firewall Tab.\n\nIf the IP is not listed beside the List, this means that the Block is a /32 entry.\nOnly /32 or /24 CIDR Hosts can be suppressed.\n\nIf (Duplication) Checking is not enabled. You may see /24 and /32 CIDR Blocks for a given blocked Host"; + + if (strlen($pfb_match[1]) >= 17) { + $pfb_matchtitle = $pfb_match[1]; + $pfb_match[1] = substr($pfb_match[1], 0, 16) . '...'; + } + + // Print Alternating Line Shading + if ($pfb['pfsenseversion'] > '2.0') { + $alertRowEvenClass = "listMReven"; + $alertRowOddClass = "listMRodd"; + } else { + $alertRowEvenClass = "listr"; + $alertRowOddClass = "listr"; + } + + $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass; + echo " + + + + + + + + "; + $counter++; + if ($counter > 0 && $rtype == "block") { + $mycounter = $counter; + } + } + } +} +?> + +
{$fields[99]}{$fields[2]}{$rule}{$proto}{$src_icons}{$fields[7]}{$srcport}
{$hostname['src']}
{$dst_icons}{$fields[8]}{$dstport}
{$hostname['dst']}
{$country}{$pfb_match[1]}
{$pfb_match[2]}
+
+ + +
+ + + + + + +
+ + \ No newline at end of file -- cgit v1.2.3 From 05ca471a39ebb0a1ef2c128a0a6fa12a32cd9a67 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Tue, 17 Feb 2015 08:30:20 -0500 Subject: pfBlockerNG - Remove bak file! --- config/pfblockerng/pfblockerng_alerts.php.bak | 866 -------------------------- 1 file changed, 866 deletions(-) delete mode 100644 config/pfblockerng/pfblockerng_alerts.php.bak diff --git a/config/pfblockerng/pfblockerng_alerts.php.bak b/config/pfblockerng/pfblockerng_alerts.php.bak deleted file mode 100644 index cb892187..00000000 --- a/config/pfblockerng/pfblockerng_alerts.php.bak +++ /dev/null @@ -1,866 +0,0 @@ -= 8) { - $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES); - } else { - $hostname = $getpfhostname; - } - if ($hostname == $getpfhostname) { - $hostname = 'unknown'; - } - echo $hostname; - die; -} - -require_once("util.inc"); -require_once("guiconfig.inc"); -require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); -global $rule_list; -pfb_global(); - -// Application Paths -$pathgeoip = "/usr/pbi/pfblockerng-" . php_uname("m") . "/bin/geoiplookup"; -$pathgeoip6 = "/usr/pbi/pfblockerng-" . php_uname("m") . "/bin/geoiplookup6"; - -// Define File Locations -$filter_logfile = "{$g['varlog_path']}/filter.log"; -$pathgeoipdat = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIP.dat"; -$pathgeoipdat6 = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIPv6.dat"; - -// Emerging Threats IQRisk Header Name Reference -$pfb['et_header'] = TRUE; -$et_header = $config['installedpackages']['pfblockerngreputation']['config'][0]['et_header']; -if (empty($et_header)) - $pfb['et_header'] = FALSE; - -// Collect pfBlockerNGSuppress Alias and Create pfbsuppression.txt -if ($pfb['supp'] == "on") - pfb_create_suppression_file(); - -// Collect Number of Suppressed Hosts -if (file_exists("{$pfb['supptxt']}")) { - $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}"); -} else { - $pfbsupp_cnt = 0; -} - -// Collect pfBlockerNG Rule Names and Number -$rule_list = array(); -$results = array(); -$data = exec ("/sbin/pfctl -vv -sr | grep 'pfB_'", $results); - -if (!isset($config['installedpackages']['pfblockerngglobal']['pfbdenycnt'])) - $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = '25'; -if (!isset($config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'])) - $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = '5'; -if (!isset($config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'])) - $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'] = '5'; -if (empty($config['installedpackages']['pfblockerngglobal']['alertrefresh'])) - $config['installedpackages']['pfblockerngglobal']['alertrefresh'] = 'off'; -if (empty($config['installedpackages']['pfblockerngglobal']['hostlookup'])) - $config['installedpackages']['pfblockerngglobal']['hostlookup'] = 'off'; - -if (isset($_POST['save'])) { - if (!is_array($config['installedpackages']['pfblockerngglobal'])) - $config['installedpackages']['pfblockerngglobal'] = array(); - $config['installedpackages']['pfblockerngglobal']['alertrefresh'] = $_POST['alertrefresh'] ? 'on' : 'off'; - $config['installedpackages']['pfblockerngglobal']['hostlookup'] = $_POST['hostlookup'] ? 'on' : 'off'; - if (is_numeric($_POST['pfbdenycnt'])) - $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = $_POST['pfbdenycnt']; - if (is_numeric($_POST['pfbpermitcnt'])) - $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = $_POST['pfbpermitcnt']; - if (is_numeric($_POST['pfbmatchcnt'])) - $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'] = $_POST['pfbmatchcnt']; - - write_config("pfBlockerNG pkg: updated ALERTS tab settings."); - header("Location: " . $_SERVER['PHP_SELF']); - exit; -} - -if (is_array($config['installedpackages']['pfblockerngglobal'])) { - $alertrefresh = $config['installedpackages']['pfblockerngglobal']['alertrefresh']; - $hostlookup = $config['installedpackages']['pfblockerngglobal']['hostlookup']; - $pfbdenycnt = $config['installedpackages']['pfblockerngglobal']['pfbdenycnt']; - $pfbpermitcnt = $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt']; - $pfbmatchcnt = $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt']; -} - -// Collect pfBlockerNG Firewall Rules -if (!empty($results)) { - foreach ($results as $result) { - - # Find Rule Descriptions - $descr = ""; - if (preg_match("/USER_RULE: (\w+)/",$result,$desc)) - $descr = $desc[1]; - - if ($pfb['pfsenseversion'] >= '2.2') { - preg_match ("/@(\d+)\(/",$result, $rule); - } else { - preg_match ("/@(\d+)\s/",$result, $rule); - } - - $id = $rule[1]; - # Create array of Rule Description and pfctl Rule Number - $rule_list['id'][] = $id; - $rule_list[$id]['name'] = $descr; - } -} - -// Add IP to the Suppression Alias -if (isset($_POST['addsuppress'])) { - $ip = ""; - if (isset($_POST['ip'])) { - $ip = $_POST['ip']; - $table = $_POST['table']; - $descr = $_POST['descr']; - $cidr = $_POST['cidr']; - - // If Description or CIDR field is empty, exit. - if (empty($descr) || empty($cidr)) { - header("Location: " . $_SERVER['PHP_SELF']); - exit; - } - - if (is_ipaddr($ip)) { - - $savemsg1 = "Host IP address {$ip}"; - if (is_ipaddrv4($ip)) { - $iptrim1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.0/24', $ip); - $iptrim2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.', $ip); - $iptrim3 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$4', $ip); - - if ($cidr == "32") { - $pfb_pfctl = exec ("/sbin/pfctl -t {$table} -T show | grep {$iptrim1} 2>&1"); - - if ($pfb_pfctl == "") { - $savemsg2 = " : Removed /32 entry"; - exec ("/sbin/pfctl -t {$table} -T delete {$ip}"); - } else { - $savemsg2 = " : Removed /24 entry, added 254 addr"; - exec ("/sbin/pfctl -t {$table} -T delete {$iptrim1}"); - for ($add_ip=0; $add_ip <= 255; $add_ip++){ - if ($add_ip != $iptrim3) { - exec ("/sbin/pfctl -t {$table} -T add {$iptrim2}{$add_ip}"); - } - } - } - } else { - $cidr = 24; - $savemsg2 = " : Removed /24 entry"; - exec ("/sbin/pfctl -t {$table} -T delete {$iptrim1} 2>&1", $pfb_pfctl); - if (!preg_grep("/1\/1 addresses deleted/", $pfb_pfctl)) { - $savemsg2 = " : Removed all entries"; - // Remove 0-255 IP Address from Alias Table - for ($del_ip=0; $del_ip <= 255; $del_ip++){ - exec ("/sbin/pfctl -t {$table} -T delete {$iptrim2}{$del_ip}"); - } - } - } - } - - // Collect pfBlockerNGSuppress Alias Contents - $pfb_sup_list = array(); - $pfb_sup_array = array(); - $pfb['found'] = FALSE; - $pfb['update'] = FALSE; - if (is_array($config['aliases']['alias'])) { - foreach ($config['aliases']['alias'] as $alias) { - if ($alias['name'] == "pfBlockerNGSuppress") { - $data = $alias['address']; - $data2 = $alias['detail']; - $arr1 = explode(" ",$data); - $arr2 = explode("||",$data2); - - if (!empty($data)) { - $row = 0; - foreach ($arr1 as $host) { - $pfb_sup_list[] = $host; - $pfb_sup_array[$row]['host'] = $host; - $row++; - } - $row = 0; - foreach ($arr2 as $detail) { - $pfb_sup_array[$row]['detail'] = $detail; - $row++; - } - } - $pfb['found'] = TRUE; - } - } - } - - // Call Function to Create Suppression Alias if not found. - if (!$pfb['found']) - pfb_create_suppression_alias(); - - // Save New Suppress IP to pfBlockerNGSuppress Alias - if (in_array($ip . '/' . $cidr, $pfb_sup_list)) { - $savemsg = gettext("Host IP address {$ip} already exists in the pfBlockerNG Suppress Table."); - } else { - if (!$pfb['found'] && empty($pfb_sup_list)) { - $next_id = 0; - } else { - $next_id = count($pfb_sup_list); - } - $pfb_sup_array[$next_id]['host'] = $ip . '/' . $cidr; - $pfb_sup_array[$next_id]['detail'] = $descr; - - $address = ""; - $detail = ""; - foreach ($pfb_sup_array as $pfb_sup) { - $address .= $pfb_sup['host'] . " "; - $detail .= $pfb_sup['detail'] . "||"; - } - - // Find pfBlockerNGSuppress Array ID Number - if (is_array($config['aliases']['alias'])) { - $pfb_id = 0; - foreach ($config['aliases']['alias'] as $alias) { - if ($alias['name'] == "pfBlockerNGSuppress") { - break; - } - $pfb_id++; - } - } - - $config['aliases']['alias'][$pfb_id]['address'] = rtrim($address, " "); - $config['aliases']['alias'][$pfb_id]['detail'] = rtrim($detail, "||"); - $savemsg = gettext($savemsg1) . gettext($savemsg2) . gettext(" and added Host to the pfBlockerNG Suppress Table."); - $pfb['update'] = TRUE; - } - - if ($pfb['found'] || $pfb['update']) { - // Save all Changes to pfsense config file - write_config(); - } - } - } -} - -// Host Resolve Function lookup -function getpfbhostname($type = 'src', $hostip, $countme = 0) { - $hostnames['src'] = ''; - $hostnames['dst'] = ''; - $hostnames[$type] = '
'; - return $hostnames; -} - - -// Determine if Alert Host 'Dest' is within the Local Lan IP Range. -function check_lan_dest($lan_ip,$lan_mask,$dest_ip,$dest_mask="32") { - $result = check_subnets_overlap($lan_ip, $lan_mask, $dest_ip, $dest_mask); - return $result; -} - - -// Parse Filter log for pfBlockerNG Alerts -function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt) { - global $rule_list; - $fields_array = array(); - $logarr = ""; - $denycnt = 0; - $permitcnt = 0; - $matchcnt = 0; - - if (file_exists($logfile)) { - exec("/usr/local/sbin/clog " . escapeshellarg($logfile) . " | grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/grep 'filterlog:' | /usr/bin/tail -r -n {$tail}", $logarr); - } - else return; - - if (!empty($logarr) && !empty($rule_list['id'])) { - foreach ($logarr as $logent) { - $pfbalert = array(); - $log_split = ""; - - if (!preg_match("/(.*)\s(.*)\sfilterlog:\s(.*)$/", $logent, $log_split)) - continue; - - list($all, $pfbalert[99], $host, $rule) = $log_split; - $rule_data = explode(",", $rule); - $pfbalert[0] = $rule_data[0]; // Rulenum - - // Skip Alert if Rule is not a pfBNG Alert - if (!in_array($pfbalert[0], $rule_list['id'])) - continue; - - $pfbalert[1] = $rule_data[4]; // Realint - $pfbalert[3] = $rule_data[6]; // Act - $pfbalert[4] = $rule_data[8]; // Version - - if ($pfbalert[4] == "4") { - $pfbalert[5] = $rule_data[15]; // Protocol ID - $pfbalert[6] = $rule_data[16]; // Protocol - $pfbalert[7] = $rule_data[18]; // SRC IP - $pfbalert[8] = $rule_data[19]; // DST IP - } else { - $pfbalert[5] = $rule_data[14]; // Protocol ID - $pfbalert[6] = $rule_data[13]; // Protocol - $pfbalert[7] = $rule_data[15]; // SRC IP - $pfbalert[8] = $rule_data[16]; // DST IP - } - - if ($pfbalert[5] == "6" || $pfbalert[5] == "17") { - $pfbalert[9] = $rule_data[20]; // SRC Port - $pfbalert[10] = $rule_data[21]; // DST Port - $pfbalert[11] = $rule_data[23]; // TCP Flags - } else { - $pfbalert[9] = ""; - $pfbalert[10] = ""; - $pfbalert[11] = ""; - } - - // Skip Repeated Alerts - if (($pfbalert[3] . $pfbalert[8] . $pfbalert[10]) == $previous_dstip || ($pfbalert[3] . $pfbalert[7] . $pfbalert[9]) == $previous_srcip) - continue; - - $pfbalert[2] = convert_real_interface_to_friendly_descr($rule_data[4]); // Friendly Interface Name - $pfbalert[6] = strtoupper($pfbalert[6]); - - if ($pfbalert[3] == "block") { - if ($denycnt < $pfbdenycnt) { - $fields_array['Deny'][] = $pfbalert; - $denycnt++; - } - } - elseif ($pfbalert[3] == "pass") { - if ($permitcnt < $pfbpermitcnt) { - $fields_array['Permit'][] = $pfbalert; - $permitcnt++; - } - } - elseif ($pfbalert[3] == "unkn(%u)" || $pfbalert[3] == "unkn(11)") { - if ($matchcnt < $pfbmatchcnt) { - $fields_array['Match'][] = $pfbalert; - $matchcnt++; - } - } - - // Exit function if Sufficinet Matches found. - if ($denycnt >= $pfbdenycnt && $permitcnt >= $pfbpermitcnt && $matchcnt >= $pfbmatchcnt) { - unset ($pfbalert, $logarr); - return $fields_array; - } - - // Collect Details for Repeated Alert Comparison - $previous_srcip = $pfbalert[3] . $pfbalert[7] . $pfbalert[9]; - $previous_dstip = $pfbalert[3] . $pfbalert[8] . $pfbalert[10]; - } - unset ($pfbalert, $logarr); - return $fields_array; - } -} - -$pgtitle = gettext("pfBlockerNG: Alerts"); -include_once("head.inc"); -?> - -
- - - - -\n"; -if ($savemsg) { - print_info_box($savemsg); -} - -?> - - - - - - -
- -
- - - - - - - - - - $pfb['denydir'] . " " . $pfb['nativedir'], "Permit" => $pfb['permitdir'], "Match" => $pfb['matchdir']) as $type => $pfbfolder ): - switch($type) { - case "Deny": - $rtype = "block"; - $pfbentries = "{$pfbdenycnt}"; - break; - case "Permit": - $rtype = "pass"; - $pfbentries = "{$pfbpermitcnt}"; - break; - case "Match": - if ($pfb['pfsenseversion'] >= '2.2') { - $rtype = "unkn(%u)"; - } else { - $rtype = "unkn(11)"; - } - $pfbentries = "{$pfbmatchcnt}"; - break; - } - -?> -
  -   -   -
- - ', ''); ?> - - ', ''); ?> - - ', ''); ?> - -   />  - -   />    -
- -        - ', '');?> -
- - - - - -
- -      - -
- - - - - - - - - - - - - - - - - - - - - - - - -= '2.2') { - $pfblines = exec("/usr/local/sbin/clog {$filter_logfile} | /usr/bin/grep -c ^"); - } else { - $pfblines = (exec("/usr/local/sbin/clog {$filter_logfile} | /usr/bin/grep -c ^") /2 ); - } - - $fields_array = conv_log_filter_lite($filter_logfile, $pfblines, $pfblines, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt); - $continents = array('pfB_Africa','pfB_Antartica','pfB_Asia','pfB_Europe','pfB_NAmerica','pfB_Oceania','pfB_SAmerica','pfB_Top'); - - $supp_ip_txt .= "Clicking this Suppression Icon, will immediately remove the Block.\n\nSuppressing a /32 CIDR is better than Suppressing the full /24"; - $supp_ip_txt .= " CIDR.\nThe Host will be added to the pfBlockerNG Suppress Alias Table.\n\nOnly 32 or 24 CIDR IPs can be Suppressed with the '+' Icon."; - $supp_ip_txt .= "\nTo manually add Host(s), edit the 'pfBlockerNGSuppress' Alias in the Alias Tab.\nManual entries will not remove existing Blocked Hosts"; - - // Array of all Local IPs for Alert Analysis - $pfb_local = array(); - - // Collect Gateway IP Addresses for Inbound/Outbound List matching - $int_gateway = get_interfaces_with_gateway(); - if (is_array($int_gateway)) { - foreach ($int_gateway as $gateway) { - $convert = get_interface_ip($gateway); - $pfb_local[] = $convert; - } - } - - // Collect Virtual IP Aliases for Inbound/Outbound List Matching - if (is_array($config['virtualip']['vip'])) { - foreach ($config['virtualip']['vip'] as $list) { - $pfb_local[] = $list['subnet']; - } - } - // Collect NAT IP Addresses for Inbound/Outbound List Matching - if (is_array($config['nat']['rule'])) { - foreach ($config['nat']['rule'] as $natent) { - $pfb_local[] = $natent['target']; - } - } - - // Collect 1:1 NAT IP Addresses for Inbound/Outbound List Matching - if(is_array($config['nat']['onetoone'])) { - foreach ($config['nat']['onetoone'] as $onetoone) { - $pfb_local[] = $onetoone['source']['address']; - } - } - - // Convert any 'Firewall Aliases' to IP Address Format - if (is_array($config['aliases']['alias'])) { - for ($cnt = 0; $cnt <= count($pfb_local); $cnt++) { - foreach ($config['aliases']['alias'] as $i=> $alias) { - if (isset($alias['name']) && isset($pfb_local[$cnt])) { - if ($alias['name'] == $pfb_local[$cnt]) { - $pfb_local[$cnt] = $alias['address']; - } - } - } - } - } - // Remove any Duplicate IPs - $pfb_local = array_unique($pfb_local); - - // Determine Lan IP Address and Mask - if (is_array($config['interfaces']['lan'])) { - $lan_ip = $config['interfaces']['lan']['ipaddr']; - $lan_mask = $config['interfaces']['lan']['subnet']; - } -} - -$counter = 0; -// Process Fields_array and generate Output -if (!empty($fields_array[$type]) && !empty($rule_list)) { - $key = 0; - foreach ($fields_array[$type] as $fields) { - $rulenum = ""; - $alert_ip = ""; - $supp_ip = ""; - $pfb_query = ""; - - /* Fields_array Reference [0] = Rulenum [6] = Protocol - [1] = Real Interface [7] = SRC IP - [2] = Friendly Interface Name [8] = DST IP - [3] = Action [9] = SRC Port - [4] = Version [10] = DST Port - [5] = Protocol ID [11] = Flags - [99] = Timestamp */ - - $rulenum = $fields[0]; - if ($counter < $pfbentries) { - $proto = str_replace("TCP", "TCP-", $fields[6]) . $fields[11]; - - // Cleanup Port Output - if ($fields[6] == "ICMP") { - $srcport = ""; - $dstport = ""; - } else { - $srcport = " :" . $fields[9]; - $dstport = " :" . $fields[10]; - } - - // Don't add Suppress Icon to Country Block Lines - if (in_array(substr($rule_list[$rulenum]['name'], 0, -3), $continents)) { - $pfb_query = "Country"; - } - - // Add DNS Resolve and Suppression Icons to External IPs only. GeoIP Code to External IPs only. - if (in_array($fields[8], $pfb_local) || check_lan_dest($lan_ip,$lan_mask,$fields[8],"32")) { - // Destination is Gateway/NAT/VIP - $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; - $host = $fields[7]; - - if (is_ipaddrv4($host)) { - $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); - } else { - $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2); - } - - $alert_ip .= " "; - - if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { - $supp_ip .= ""; - } - - if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { - $hostname = getpfbhostname('src', $fields[7], $counter); - } else { - $hostname = ""; - } - - $src_icons = $alert_ip . " " . $supp_ip . " "; - $dst_icons = ""; - } else { - // Outbound - $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; - $host = $fields[8]; - - if (is_ipaddrv4($host)) { - $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); - } else { - $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2); - } - - $alert_ip .= " "; - - if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { - $supp_ip .= ""; - } - - if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { - $hostname = getpfbhostname('dst', $fields[8], $counter); - } else { - $hostname = ""; - } - - $src_icons = ""; - $dst_icons = $alert_ip . " " . $supp_ip . " "; - } - - # IP Query Grep Exclusion - $pfb_ex1 = "grep -v 'pfB\_\|\_v6\.txt'"; - $pfb_ex2 = "grep -v 'pfB\_\|/32\|/24\|\_v6\.txt' | grep -m1 '/'"; - - // Find List which contains Blocked IP Host - if ($pfb_query == "Country") { - # Skip - } else { - // Search for exact IP Match - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host); - $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' | {$pfb_ex1}"); - // Search for IP in /24 CIDR - if (empty($pfb_query)) { - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.0/24\'', $host); - $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); - } - // Search for First Two IP Octets in CIDR Matches Only. Skip any pfB (Country Lists) or /32,/24 Addresses. - if (empty($pfb_query)) { - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host); - $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); - } - // Search for First Two IP Octets in CIDR Matches Only (Subtract 1 from second Octet on each loop). - // Skip (Country Lists) or /32,/24 Addresses. - if (empty($pfb_query)) { - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.', $host); - $host2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$2', $host); - for ($cnt = 1; $cnt <= 5; $cnt++) { - $host3 = $host2 - $cnt . '\''; - $pfb_query = exec("grep -rH {$host1}{$host3} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); - // Break out of loop if found. - if (!empty($pfb_query)) - $cnt = 6; - } - } - // Search for First Three Octets - if (empty($pfb_query)) { - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.$3\.\'', $host); - $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); - } - // Search for First Two Octets - if (empty($pfb_query)) { - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host); - $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); - } - // Report Specific ET IQRisk Details - if ($pfb['et_header'] && preg_match("/{$et_header}/", $pfb_query)) { - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host); - $pfb_query = exec("grep -Hm1 {$host1} {$pfb['etdir']}/* | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' -e 's/ET_/ET IPrep /' "); - if (empty($pfb_query)) { - $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1.$2.$3.0/24\'', $host); - $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); - } - } - // Default to "No Match" if not found. - if (empty($pfb_query)) - $pfb_query = "No Match"; - } - - # Split List Column into Two lines. - unset ($pfb_match); - if ($pfb_query == "No Match") { - $pfb_match[1] = "{$pfb_query}"; - $pfb_match[2] = ""; - } else { - preg_match ("/(.*)\s(.*)/", $pfb_query, $pfb_match); - if ($pfb_match[1] == "") { - $pfb_match[1] = "{$pfb_query}"; - $pfb_match[2] = ""; - } - } - - // Truncate Long List Names - $pfb_matchtitle = "Country Block Rules cannot be suppressed.\n\nTo allow a particular Country IP, either remove the particular Country or add the Host\nto a Permit Alias in the Firewall Tab.\n\nIf the IP is not listed beside the List, this means that the Block is a /32 entry.\nOnly /32 or /24 CIDR Hosts can be suppressed.\n\nIf (Duplication) Checking is not enabled. You may see /24 and /32 CIDR Blocks for a given blocked Host"; - - if (strlen($pfb_match[1]) >= 17) { - $pfb_matchtitle = $pfb_match[1]; - $pfb_match[1] = substr($pfb_match[1], 0, 16) . '...'; - } - - // Print Alternating Line Shading - if ($pfb['pfsenseversion'] > '2.0') { - $alertRowEvenClass = "listMReven"; - $alertRowOddClass = "listMRodd"; - } else { - $alertRowEvenClass = "listr"; - $alertRowOddClass = "listr"; - } - - $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass; - echo " - - - - - - - - "; - $counter++; - if ($counter > 0 && $rtype == "block") { - $mycounter = $counter; - } - } - } -} -?> - -
{$fields[99]}{$fields[2]}{$rule}{$proto}{$src_icons}{$fields[7]}{$srcport}
{$hostname['src']}
{$dst_icons}{$fields[8]}{$dstport}
{$hostname['dst']}
{$country}{$pfb_match[1]}
{$pfb_match[2]}
-
- - -
- - - - - - -
- - \ No newline at end of file -- cgit v1.2.3 From 4fbdf9a64da94ce08da8e253d6ab7f4c6eb33ffd Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Tue, 17 Feb 2015 22:40:06 -0500 Subject: pfBlockerNG - Mods to Alerts Tab (IPv6) Improve Alerts Tab for IPv6 entries. --- config/pfblockerng/pfblockerng_alerts.php | 113 ++++++++++++++++-------------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index 22464207..416b78de 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -312,40 +312,40 @@ function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermi if (!empty($logarr) && !empty($rule_list['id'])) { foreach ($logarr as $logent) { - $pfbalert = array(); + $pfbalert = array(); $log_split = ""; if (!preg_match("/(.*)\s(.*)\sfilterlog:\s(.*)$/", $logent, $log_split)) continue; list($all, $pfbalert[99], $host, $rule) = $log_split; - $rule_data = explode(",", $rule); - $pfbalert[0] = $rule_data[0]; // Rulenum + $rule_data = explode(",", $rule); + $pfbalert[0] = $rule_data[0]; // Rulenum // Skip Alert if Rule is not a pfBNG Alert if (!in_array($pfbalert[0], $rule_list['id'])) continue; - $pfbalert[1] = $rule_data[4]; // Realint - $pfbalert[3] = $rule_data[6]; // Act - $pfbalert[4] = $rule_data[8]; // Version + $pfbalert[1] = $rule_data[4]; // Realint + $pfbalert[3] = $rule_data[6]; // Act + $pfbalert[4] = $rule_data[8]; // Version if ($pfbalert[4] == "4") { - $pfbalert[5] = $rule_data[15]; // Protocol ID - $pfbalert[6] = $rule_data[16]; // Protocol - $pfbalert[7] = $rule_data[18]; // SRC IP - $pfbalert[8] = $rule_data[19]; // DST IP - $pfbalert[9] = $rule_data[20]; // SRC Port - $pfbalert[10] = $rule_data[21]; // DST Port - $pfbalert[11] = $rule_data[23]; // TCP Flags + $pfbalert[5] = $rule_data[15]; // Protocol ID + $pfbalert[6] = $rule_data[16]; // Protocol + $pfbalert[7] = $rule_data[18]; // SRC IP + $pfbalert[8] = $rule_data[19]; // DST IP + $pfbalert[9] = $rule_data[20]; // SRC Port + $pfbalert[10] = $rule_data[21]; // DST Port + $pfbalert[11] = $rule_data[23]; // TCP Flags } else { - $pfbalert[5] = $rule_data[13]; // Protocol ID - $pfbalert[6] = $rule_data[12]; // Protocol - $pfbalert[7] = "[" . $rule_data[15] . "]"; // SRC IP - $pfbalert[8] = "[" . $rule_data[16] . "]"; // DST IP - $pfbalert[9] = $rule_data[17]; // SRC Port - $pfbalert[10] = $rule_data[18]; // DST Port - $pfbalert[11] = $rule_data[20]; // TCP Flags + $pfbalert[5] = $rule_data[13]; // Protocol ID + $pfbalert[6] = $rule_data[12]; // Protocol + $pfbalert[7] = $rule_data[15]; // SRC IP + $pfbalert[8] = $rule_data[16]; // DST IP + $pfbalert[9] = $rule_data[17]; // SRC Port + $pfbalert[10] = $rule_data[18]; // DST Port + $pfbalert[11] = $rule_data[20]; // TCP Flags } if ($pfbalert[5] == "6" || $pfbalert[5] == "17") { @@ -508,12 +508,12 @@ if ($savemsg) { - + - + - - + + @@ -549,7 +549,7 @@ if ($pfb['runonce']) { } $fields_array = conv_log_filter_lite($filter_logfile, $pfblines, $pfblines, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt); - $continents = array('pfB_Africa','pfB_Antartica','pfB_Asia','pfB_Europe','pfB_NAmerica','pfB_Oceania','pfB_SAmerica','pfB_Top'); + $continents = array('pfB_Africa','pfB_Antartica','pfB_Asia','pfB_Europe','pfB_NAmerica','pfB_Oceania','pfB_SAmerica','pfB_Top'); $supp_ip_txt .= "Clicking this Suppression Icon, will immediately remove the Block.\n\nSuppressing a /32 CIDR is better than Suppressing the full /24"; $supp_ip_txt .= " CIDR.\nThe Host will be added to the pfBlockerNG Suppress Alias Table.\n\nOnly 32 or 24 CIDR IPs can be Suppressed with the '+' Icon."; @@ -651,12 +651,6 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; $host = $fields[7]; - if (is_ipaddrv4($host)) { - $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); - } else { - $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2); - } - $alert_ip .= " "; @@ -680,12 +674,6 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { $rule = $rule_list[$rulenum]['name'] . "
(" . $rulenum .")"; $host = $fields[8]; - if (is_ipaddrv4($host)) { - $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); - } else { - $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2); - } - $alert_ip .= " "; @@ -706,26 +694,31 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { $dst_icons = $alert_ip . " " . $supp_ip . " "; } + // Determine Country Code of Host + if (is_ipaddrv4($host)) { + $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2); + } else { + $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2); + } + # IP Query Grep Exclusion $pfb_ex1 = "grep -v 'pfB\_\|\_v6\.txt'"; $pfb_ex2 = "grep -v 'pfB\_\|/32\|/24\|\_v6\.txt' | grep -m1 '/'"; // Find List which contains Blocked IP Host - if ($pfb_query == "Country") { - # Skip - } else { + if (is_ipaddrv4($host) && $pfb_query != "Country") { // Search for exact IP Match $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host); - $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' | {$pfb_ex1}"); + $pfb_query = exec("/usr/bin/grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' | {$pfb_ex1}"); // Search for IP in /24 CIDR if (empty($pfb_query)) { $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.0/24\'', $host); - $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); + $pfb_query = exec("/usr/bin/grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); } // Search for First Two IP Octets in CIDR Matches Only. Skip any pfB (Country Lists) or /32,/24 Addresses. if (empty($pfb_query)) { $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host); - $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + $pfb_query = exec("/usr/bin/grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); } // Search for First Two IP Octets in CIDR Matches Only (Subtract 1 from second Octet on each loop). // Skip (Country Lists) or /32,/24 Addresses. @@ -734,7 +727,7 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { $host2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$2', $host); for ($cnt = 1; $cnt <= 5; $cnt++) { $host3 = $host2 - $cnt . '\''; - $pfb_query = exec("grep -rH {$host1}{$host3} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + $pfb_query = exec("/usr/bin/grep -rH {$host1}{$host3} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); // Break out of loop if found. if (!empty($pfb_query)) $cnt = 6; @@ -743,26 +736,30 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { // Search for First Three Octets if (empty($pfb_query)) { $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.$3\.\'', $host); - $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + $pfb_query = exec("/usr/bin/grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); } // Search for First Two Octets if (empty($pfb_query)) { $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host); - $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); + $pfb_query = exec("/usr/bin/grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}"); } // Report Specific ET IQRisk Details if ($pfb['et_header'] && preg_match("/{$et_header}/", $pfb_query)) { $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host); - $pfb_query = exec("grep -Hm1 {$host1} {$pfb['etdir']}/* | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' -e 's/ET_/ET IPrep /' "); + $pfb_query = exec("/usr/bin/grep -Hm1 {$host1} {$pfb['etdir']}/* | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' -e 's/ET_/ET IPrep /' "); if (empty($pfb_query)) { $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1.$2.$3.0/24\'', $host); - $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); + $pfb_query = exec("/usr/bin/grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}"); } } - // Default to "No Match" if not found. - if (empty($pfb_query)) - $pfb_query = "No Match"; } + elseif (is_ipaddrv6($host) && $pfb_query != "Country") { + $pfb_query = exec("/usr/bin/grep -Hm1 '{$host}' {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | grep -v 'pfB\_'"); + } + + // Default to "No Match" if not found. + if (empty($pfb_query)) + $pfb_query = "No Match"; # Split List Column into Two lines. unset ($pfb_match); @@ -777,6 +774,16 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { } } + // Add []'s to IPv6 Addresses and add a zero-width space as soft-break opportunity after each colon if we have an IPv6 address (from Snort) + if ($fields[4] == "6") { + $fields[97] = "[" . str_replace(":", ":​", $fields[7]) . "]"; + $fields[98] = "[" . str_replace(":", ":​", $fields[8]) . "]"; + } + else { + $fields[97] = $fields[7]; + $fields[98] = $fields[8]; + } + // Truncate Long List Names $pfb_matchtitle = "Country Block Rules cannot be suppressed.\n\nTo allow a particular Country IP, either remove the particular Country or add the Host\nto a Permit Alias in the Firewall Tab.\n\nIf the IP is not listed beside the List, this means that the Block is a /32 entry.\nOnly /32 or /24 CIDR Hosts can be suppressed.\n\nIf (Duplication) Checking is not enabled. You may see /24 and /32 CIDR Blocks for a given blocked Host"; @@ -800,8 +807,8 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { - - + + "; $counter++; -- cgit v1.2.3 From e49ea2af46ed44cd955c1f4513b66ca984c2fc8a Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Tue, 17 Feb 2015 23:15:06 -0500 Subject: pfBlockerNG - Mod to IPv4 CIDR Regex --- config/pfblockerng/pfblockerng.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index 78622631..df546963 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -1189,7 +1189,7 @@ function sync_package_pfblockerng($cron = "") { # IPv4 REGEX Definitions $pfb['range'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))-((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))/'; $pfb['block'] = '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[ 0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.([0]{1})\s+/'; - $pfb['cidr'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/[0-9]{2}/'; + $pfb['cidr'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/([1-9]{1}|[12][0-9]|3[012]))$/'; $pfb['single'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s+/'; $pfb['s_html'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/'; -- cgit v1.2.3 From f80245904687c0adca749a62739dd2898ebd788e Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Wed, 18 Feb 2015 23:21:59 -0500 Subject: pfBlockerNG - Default "Keep Settings" to "on" https://redmine.pfsense.org/issues/4373#change-17404 --- config/pfblockerng/pfblockerng.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/pfblockerng/pfblockerng.xml b/config/pfblockerng/pfblockerng.xml index 54c6c061..bdfecd96 100644 --- a/config/pfblockerng/pfblockerng.xml +++ b/config/pfblockerng/pfblockerng.xml @@ -234,6 +234,7 @@ pfb_keep checkbox Keep Settings and Lists intact when pfBlockerNG is Disabled or After pfBlockerNG Re-Install/De-Install + on CRON MIN Start Time -- cgit v1.2.3 From 7a9603b71a68fd1edec153151ce78eff7a17b05f Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Thu, 19 Feb 2015 00:41:41 -0500 Subject: pfBlockerNG - Fix missing Start Hour code --- config/pfblockerng/pfblockerng.inc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index df546963..dbe0a7f5 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -440,6 +440,8 @@ function sync_package_pfblockerng($cron = "") { $pfb['validate']= $pfb['config']['pfblocker_cb']; # User Defined CRON Start Minute $pfb['min'] = $pfb['config']['pfb_min']; + # User Defined CRON Start Hour + $pfb['hour'] = $pfb['config']['pfb_hour']; # Reloads Existing Blocklists without Downloading New Lists $pfb['reuse'] = $pfb['config']['pfb_reuse']; # Enable OpenVPN AutoRules @@ -2339,13 +2341,13 @@ function sync_package_pfblockerng($cron = "") { # Define pfBlockerNG CRON Job $pfb_cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php cron >> {$pfb['log']} 2>&1"; # $pfb['min'] ( User Defined Variable. Variable defined at start of Script ) - $pfb_hour = "*"; + # $pfb['hour'] ( User Defined Variable. Variable defined at start of Script ) $pfb_mday = "*"; $pfb_month = "*"; $pfb_wday = "*"; $pfb_who = "root"; - install_cron_job($pfb_cmd, true, $pfb['min'], $pfb_hour, $pfb_mday, $pfb_month, $pfb_wday, $pfb_who); + install_cron_job($pfb_cmd, true, $pfb['min'], $pfb['hour'], $pfb_mday, $pfb_month, $pfb_wday, $pfb_who); } # Clear any existing pfBlockerNG MaxMind CRON Job -- cgit v1.2.3 From f3694e2170392cc89d14eabadfaded8ab7bca6d6 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Thu, 19 Feb 2015 01:33:22 -0500 Subject: Revert "pfBlockerNG - Fix missing Start Hour code" This reverts commit 7a9603b71a68fd1edec153151ce78eff7a17b05f. --- config/pfblockerng/pfblockerng.inc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index dbe0a7f5..df546963 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -440,8 +440,6 @@ function sync_package_pfblockerng($cron = "") { $pfb['validate']= $pfb['config']['pfblocker_cb']; # User Defined CRON Start Minute $pfb['min'] = $pfb['config']['pfb_min']; - # User Defined CRON Start Hour - $pfb['hour'] = $pfb['config']['pfb_hour']; # Reloads Existing Blocklists without Downloading New Lists $pfb['reuse'] = $pfb['config']['pfb_reuse']; # Enable OpenVPN AutoRules @@ -2341,13 +2339,13 @@ function sync_package_pfblockerng($cron = "") { # Define pfBlockerNG CRON Job $pfb_cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php cron >> {$pfb['log']} 2>&1"; # $pfb['min'] ( User Defined Variable. Variable defined at start of Script ) - # $pfb['hour'] ( User Defined Variable. Variable defined at start of Script ) + $pfb_hour = "*"; $pfb_mday = "*"; $pfb_month = "*"; $pfb_wday = "*"; $pfb_who = "root"; - install_cron_job($pfb_cmd, true, $pfb['min'], $pfb['hour'], $pfb_mday, $pfb_month, $pfb_wday, $pfb_who); + install_cron_job($pfb_cmd, true, $pfb['min'], $pfb_hour, $pfb_mday, $pfb_month, $pfb_wday, $pfb_who); } # Clear any existing pfBlockerNG MaxMind CRON Job -- cgit v1.2.3 From eeca7210dbc18f19ff8c267442b5b0642f4525a9 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Thu, 19 Feb 2015 13:26:14 -0500 Subject: Revert "pfBlockerNG - Mod to IPv4 CIDR Regex" This reverts commit e49ea2af46ed44cd955c1f4513b66ca984c2fc8a. --- config/pfblockerng/pfblockerng.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index df546963..78622631 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -1189,7 +1189,7 @@ function sync_package_pfblockerng($cron = "") { # IPv4 REGEX Definitions $pfb['range'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))-((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))/'; $pfb['block'] = '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[ 0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.([0]{1})\s+/'; - $pfb['cidr'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/([1-9]{1}|[12][0-9]|3[012]))$/'; + $pfb['cidr'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/[0-9]{2}/'; $pfb['single'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s+/'; $pfb['s_html'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/'; -- cgit v1.2.3 From f3bfd33d8ce160b32e413dc530281ea4908cded8 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Thu, 19 Feb 2015 14:36:37 -0500 Subject: pfBlockerNG - Mods to Schedule converter As spotted by phil.davis - https://github.com/phil-davis/pfsense-packages/commit/c5b497d4ea370e8f076bd95af5259d547894f2fa --- config/pfblockerng/pfblockerng.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config/pfblockerng/pfblockerng.php b/config/pfblockerng/pfblockerng.php index 0ca3aa7d..1dec1520 100644 --- a/config/pfblockerng/pfblockerng.php +++ b/config/pfblockerng/pfblockerng.php @@ -251,7 +251,7 @@ if ($argv[1] == 'gc') { } if ($argv[1] == 'cron') { - $hour = date('H'); + $hour = date('G'); $dow = date('N'); $pfb['update_cron'] = FALSE; @@ -270,7 +270,7 @@ if ($argv[1] == 'cron') { $sch2 = strval($shour); for ($i=0; $i<11; $i++) { $shour += 2; - if ($shour > 24) + if ($shour >= 24) $shour -= 24; $sch2 .= "," . strval($shour); } @@ -280,7 +280,7 @@ if ($argv[1] == 'cron') { $sch3 = strval($shour); for ($i=0; $i<7; $i++) { $shour += 3; - if ($shour > 24) + if ($shour >= 24) $shour -= 24; $sch3 .= "," . strval($shour); } @@ -290,7 +290,7 @@ if ($argv[1] == 'cron') { $sch4 = strval($shour); for ($i=0; $i<5; $i++) { $shour += 4; - if ($shour > 24) + if ($shour >= 24) $shour -= 24; $sch4 .= "," . strval($shour); } @@ -300,7 +300,7 @@ if ($argv[1] == 'cron') { $sch6 = strval($shour); for ($i=0; $i<3; $i++) { $shour += 6; - if ($shour > 24) + if ($shour >= 24) $shour -= 24; $sch6 .= "," . strval($shour); } @@ -310,7 +310,7 @@ if ($argv[1] == 'cron') { $sch8 = strval($shour); for ($i=0; $i<2; $i++) { $shour += 8; - if ($shour > 24) + if ($shour >= 24) $shour -= 24; $sch8 .= "," . strval($shour); } @@ -319,7 +319,7 @@ if ($argv[1] == 'cron') { $shour = intval(substr($pfb['hour'], 0, 2)); $sch12 = strval($shour) . ","; $shour += 12; - if ($shour > 24) + if ($shour >= 24) $shour -= 24; $sch12 .= strval($shour); @@ -1480,4 +1480,4 @@ EOF; // Unset Arrays unset ($roptions4, $et_options, $xmlrep); } -?> \ No newline at end of file +?> -- cgit v1.2.3 From 39a582b41ee23ac7fca9540b80e005192a974faa Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Thu, 19 Feb 2015 23:37:21 -0500 Subject: pfBlockerNG - Collect VIP Subnets for Alerts Tab --- config/pfblockerng/pfblockerng_alerts.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index 416b78de..0164a4d2 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -570,7 +570,10 @@ if ($pfb['runonce']) { // Collect Virtual IP Aliases for Inbound/Outbound List Matching if (is_array($config['virtualip']['vip'])) { foreach ($config['virtualip']['vip'] as $list) { - $pfb_local[] = $list['subnet']; + if ($list['type'] == "single" && $list['subnet_bits'] == "32") + $pfb_local[] = $list['subnet']; + elseif ($list['type'] == "single" || $list['type'] == "network") + $pfb_local = array_merge (subnet_expand ("{$list['subnet']}/{$list['subnet_bits']}"), $pfb_local); } } // Collect NAT IP Addresses for Inbound/Outbound List Matching -- cgit v1.2.3 From 4a1c359d46f21af9cb7871791614ca15a2f3da9d Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Sun, 22 Feb 2015 19:31:13 -0500 Subject: pfBlockerNG - Alerts Tab Filter Regex 1) Add Filter Regex to Alerts Tab (Based on Firewall Diag Logs & Snort pkg) 2) Change Suppression icon to use "Green +" Icon --- config/pfblockerng/pfblockerng_alerts.php | 149 ++++++++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 10 deletions(-) diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index 0164a4d2..e092b25c 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -69,6 +69,9 @@ $filter_logfile = "{$g['varlog_path']}/filter.log"; $pathgeoipdat = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIP.dat"; $pathgeoipdat6 = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIPv6.dat"; +// Define Alerts Log filter Rollup window variable. (Alert Filtering Code adapted from B.Meeks - Snort Package) +$pfb['filterlogentries'] = FALSE; + // Emerging Threats IQRisk Header Name Reference $pfb['et_header'] = TRUE; $et_header = $config['installedpackages']['pfblockerngreputation']['config'][0]['et_header']; @@ -127,6 +130,54 @@ if (is_array($config['installedpackages']['pfblockerngglobal'])) { $pfbmatchcnt = $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt']; } + +function pfb_match_filter_field($flent, $fields) { + foreach ($fields as $key => $field) { + if ($field == null) + continue; + if ((strpos($field, '!') === 0)) { + $field = substr($field, 1); + $field_regex = str_replace('/', '\/', str_replace('\/', '/', $field)); + if (@preg_match("/{$field_regex}/i", $flent[$key])) + return false; + } + else { + $field_regex = str_replace('/', '\/', str_replace('\/', '/', $field)); + if (!@preg_match("/{$field_regex}/i", $flent[$key])) + return false; + } + } + return true; +} + + +if ($_POST['filterlogentries_submit']) { + // Set flag for filtering alert entries + $pfb['filterlogentries'] = TRUE; + + // Note the order of these fields must match the order decoded from the alerts log + $filterfieldsarray = array(); + $filterfieldsarray[0] = $_POST['filterlogentries_rule'] ? $_POST['filterlogentries_rule'] : null; + $filterfieldsarray[2] = $_POST['filterlogentries_int'] ? $_POST['filterlogentries_int'] : null; + $filterfieldsarray[6] = strtolower($_POST['filterlogentries_proto']) ? $_POST['filterlogentries_proto'] : null; + + // Remove any zero-length spaces added to the IP address that could creep in from a copy-paste operation + $filterfieldsarray[7] = $_POST['filterlogentries_srcip'] ? str_replace("\xE2\x80\x8B", "", $_POST['filterlogentries_srcip']) : null; + $filterfieldsarray[8] = $_POST['filterlogentries_dstip'] ? str_replace("\xE2\x80\x8B", "", $_POST['filterlogentries_dstip']) : null; + + $filterfieldsarray[9] = $_POST['filterlogentries_srcport'] ? $_POST['filterlogentries_srcport'] : null; + $filterfieldsarray[10] = $_POST['filterlogentries_dstport'] ? $_POST['filterlogentries_dstport'] : null; + $filterfieldsarray[90] = $_POST['filterlogentries_dnsbl'] ? $_POST['filterlogentries_dnsbl'] : null; + $filterfieldsarray[99] = $_POST['filterlogentries_date'] ? $_POST['filterlogentries_date'] : null; +} + + +if ($_POST['filterlogentries_clear']) { + $pfb['filterlogentries'] = TRUE; + $filterfieldsarray = array(); +} + + // Collect pfBlockerNG Firewall Rules if (!empty($results)) { foreach ($results as $result) { @@ -298,7 +349,7 @@ function check_lan_dest($lan_ip,$lan_mask,$dest_ip,$dest_mask="32") { // Parse Filter log for pfBlockerNG Alerts function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt) { - global $rule_list; + global $pfb, $rule_list, $filterfieldsarray; $fields_array = array(); $logarr = ""; $denycnt = 0; @@ -360,8 +411,13 @@ function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermi if (($pfbalert[3] . $pfbalert[8] . $pfbalert[10]) == $previous_dstip || ($pfbalert[3] . $pfbalert[7] . $pfbalert[9]) == $previous_srcip) continue; - $pfbalert[2] = convert_real_interface_to_friendly_descr($rule_data[4]); // Friendly Interface Name - $pfbalert[6] = strtoupper($pfbalert[6]); + $pfbalert[2] = convert_real_interface_to_friendly_descr($rule_data[4]); // Friendly Interface Name + $pfbalert[6] = str_replace("TCP", "TCP-", strtoupper($pfbalert[6]), $pfbalert[6]) . $pfbalert[11]; // Protocol Flags + + // If Alerts Filtering is selected, process Filters as required. + if ($pfb['filterlogentries'] && !pfb_match_filter_field($pfbalert, $filterfieldsarray)) { + continue; + } if ($pfbalert[3] == "block") { if ($denycnt < $pfbdenycnt) { @@ -445,7 +501,7 @@ if ($savemsg) {
{$fields[2]} {$rule} {$proto}{$src_icons}{$fields[7]}{$srcport}
{$hostname['src']}
{$dst_icons}{$fields[8]}{$dstport}
{$hostname['dst']}
{$src_icons}{$fields[97]}{$srcport}
{$hostname['src']}
{$dst_icons}{$fields[98]}{$dstport}
{$hostname['dst']}
{$country} {$pfb_match[1]}
{$pfb_match[2]}
- +
+ + + + "> + + + + "> + + + $pfb['denydir'] . " " . $pfb['nativedir'], "Permit" => $pfb['permitdir'], "Match" => $pfb['matchdir']) as $type => $pfbfolder ): switch($type) { @@ -632,8 +753,6 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { $rulenum = $fields[0]; if ($counter < $pfbentries) { - $proto = str_replace("TCP", "TCP-", $fields[6]) . $fields[11]; - // Cleanup Port Output if ($fields[6] == "ICMP" || $fields[6] == "ICMPV6") { $srcport = ""; @@ -660,7 +779,7 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { $supp_ip .= ""; } @@ -683,7 +802,7 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { $supp_ip .= ""; } @@ -757,7 +876,7 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { } } elseif (is_ipaddrv6($host) && $pfb_query != "Country") { - $pfb_query = exec("/usr/bin/grep -Hm1 '{$host}' {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | grep -v 'pfB\_'"); + $pfb_query = exec("/usr/bin/grep -Hm1 {$host} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | grep -v 'pfB\_'"); } // Default to "No Match" if not found. @@ -809,7 +928,7 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { - + @@ -872,6 +991,16 @@ if ( autoresolve == "on" ) { } } +function enable_showFilter() { + document.getElementById("filter_enable_row").style.display="none"; + document.getElementById("filter_options_row").style.display="table-row"; +} + +function enable_hideFilter() { + document.getElementById("filter_enable_row").style.display="table-row"; + document.getElementById("filter_options_row").style.display="none"; +} + //]]> -- cgit v1.2.3 From cbdace7e8760f5ff5407f484c968cfd5d4656cee Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Sun, 22 Feb 2015 19:51:51 -0500 Subject: pfBlockerNG - Mods for Nano Aliastables ro/rw Add RW/RO commands for Aliastables Archiving for Nano/Ramdisk Installs. --- config/pfblockerng/pfblockerng.inc | 14 +- config/pfblockerng/pfblockerng.inc.bak | 2701 ++++++++++++++++++++++++++++++++ 2 files changed, 2712 insertions(+), 3 deletions(-) create mode 100644 config/pfblockerng/pfblockerng.inc.bak diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc index 78622631..6ee9592a 100644 --- a/config/pfblockerng/pfblockerng.inc +++ b/config/pfblockerng/pfblockerng.inc @@ -343,10 +343,11 @@ function pfb_aliastables($mode) { // Only Execute function if Platform is NanoBSD or Ramdisks are used. if (($g['platform'] != "pfSense") || isset($config['system']['use_mfs_tmpvar'])) { + conf_mount_rw(); if ($mode == "update") { // Archive Aliastable Folder exec ("cd {$pfb['aliasdir']}; ls -A pfB_*.txt && /usr/bin/tar -jcvf {$pfb['aliasarchive']} pfB_*.txt >/dev/null 2>&1"); - $msg = "\n\nArchiving Aliastable Folder"; + $msg = "\n\nArchiving Aliastable Folder\n"; } elseif ($mode == "conf") { // Check conf file for earlyshellcmd @@ -362,10 +363,16 @@ function pfb_aliastables($mode) { $msg = "\n** Adding earlyshellcmd **\n"; } } + conf_mount_ro(); } else { - // Remove Aliastables archive and earlyshellcmd if found. - @unlink_if_exists("{$pfb['aliasarchive']}"); + if (file_exists("{$pfb['aliasarchive']}")) { + // Remove Aliastables archive if found. + conf_mount_rw(); + @unlink_if_exists("{$pfb['aliasarchive']}"); + conf_mount_ro(); + } + // Remove earlyshellcmd if found. if (is_array($config['system']['earlyshellcmd'])) { $a_earlyshellcmd = &$config['system']['earlyshellcmd']; if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { @@ -2231,6 +2238,7 @@ function sync_package_pfblockerng($cron = "") { unset ($other_rules,$fother_rules,$permit_rules,$fpermit_rules,$match_rules,$fmatch_rules); } + ################################# # Closing Processes # ################################# diff --git a/config/pfblockerng/pfblockerng.inc.bak b/config/pfblockerng/pfblockerng.inc.bak new file mode 100644 index 00000000..da5a5261 --- /dev/null +++ b/config/pfblockerng/pfblockerng.inc.bak @@ -0,0 +1,2701 @@ + /tmp/pfblog; /bin/mv -f /tmp/pfblog {$pfb['log']}"); + } +} + + +# Record Log Messsages to pfBlockerNG Log File and/or Error Log File. +function pfb_logger($log, $type) { + global $g,$pfb,$pfbarr; + + $now = date("m/d/y G:i:s", time()); + + # Only log timestamp if new + if (preg_match("/NOW/", $log)) { + if ($now == $pfb['pnow']) { + $log = str_replace("[ NOW ]", "", "{$log}"); + } else { + $log = str_replace("NOW", $now, "{$log}"); + } + $pfb['pnow'] = "{$now}"; + } + + if ($type == 2) { + @file_put_contents("{$pfb['log']}", "{$log}", FILE_APPEND); + @file_put_contents("{$pfb['errlog']}", "{$log}", FILE_APPEND); + } elseif ($type == 3) { + @file_put_contents("{$pfb['geolog']}", "{$log}", FILE_APPEND); + } else { + @file_put_contents("{$pfb['log']}", "{$log}", FILE_APPEND); + } +} + + +# Determine Folder Location for 'List' +function pfb_determine_list_detail($list) { + global $g,$pfb,$pfbarr; + $pfbarr = array(); + + if (in_array($list,array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { + $pfbarr['skip'] = FALSE; + $pfbarr['folder'] = "{$pfb['matchdir']}"; + } elseif (in_array($list,array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) { + $pfbarr['skip'] = FALSE; + $pfbarr['folder'] = "{$pfb['permitdir']}"; + } elseif ($list == "Alias_Native") { + $pfbarr['skip'] = FALSE; + $pfbarr['folder'] = "{$pfb['nativedir']}"; + } else { + # Deny + $pfbarr['skip'] = TRUE; + $pfbarr['folder'] = "{$pfb['denydir']}"; + } + + // Collect proper Alias Table Description (Alias Only vs AutoRules) + if (preg_match("/Alias/", $list)) { + $pfbarr['descr'] = ""; + } else { + $pfbarr['descr'] = " Auto "; + } + + return $pfbarr; +} + +# Create Suppression Alias +function pfb_create_suppression_alias() { + global $config; + + // Collect existing pfsense alias(s) + if (is_array($config['aliases']['alias'])) { + foreach($config['aliases']['alias'] as $exalias) { + $new_aliases[] = $exalias; + } + } + // Create New pfBlockerNGSuppress Alias + $new_aliases[] = array( "name" => "pfBlockerNGSuppress", + "address" => "", + "descr" => "pfBlockerNG Suppression List (24|32 CIDR only)", + "type" => "network", + "detail" => "" + ); + $config['aliases']['alias'] = $new_aliases; + write_config(); +} + + +# Create Suppression file from Alias +function pfb_create_suppression_file() { + global $config,$pfb; + + // Find pfBlockerNGSuppress Array ID Number + $pfb['found'] = FALSE; + if (is_array($config['aliases']['alias'])) { + $pfb_id = 0; + foreach ($config['aliases']['alias'] as $alias) { + if ($alias['name'] == "pfBlockerNGSuppress") { + $pfb['found'] = TRUE; + break; + } + $pfb_id++; + } + + if ($pfb['found']) { + $pfb_suppress = str_replace(" ", "\n", $config['aliases']['alias'][$pfb_id]['address']); + if (!empty($pfb_suppress)) + @file_put_contents("{$pfb['supptxt']}",$pfb_suppress, LOCK_EX); + } else { + # Delete Suppression File if Alias is Empty. + unlink_if_exists("{$pfb['supptxt']}"); + } + } + + // Call Function to Create Suppression Alias. + if (!$pfb['found']) + pfb_create_suppression_alias(); +} + + +// 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; +} + + +// Archive Aliastables for NanoBSD and RAMDisk Installations +function pfb_aliastables($mode) { + global $g,$config,$pfb; + $earlyshellcmd = "/usr/local/pkg/pfblockerng/pfblockerng.sh aliastables"; + $msg = ""; + + // Only Execute function if Platform is NanoBSD or Ramdisks are used. + if (($g['platform'] != "pfSense") || isset($config['system']['use_mfs_tmpvar'])) { + conf_mount_rw(); + if ($mode == "update") { + // Archive Aliastable Folder + exec ("cd {$pfb['aliasdir']}; ls -A pfB_*.txt && /usr/bin/tar -jcvf {$pfb['aliasarchive']} pfB_*.txt >/dev/null 2>&1"); + $msg = "\n\nArchiving Aliastable Folder\n"; + } + elseif ($mode == "conf") { + // Check conf file for earlyshellcmd + if (is_array($config['system']['earlyshellcmd'])) { + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (!preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { + $a_earlyshellcmd[] = "{$earlyshellcmd}"; + $msg = "\n** Adding earlyshellcmd **\n"; + } + } + else { + $config['system']['earlyshellcmd'] = "{$earlyshellcmd}"; + $msg = "\n** Adding earlyshellcmd **\n"; + } + } + conf_mount_ro(); + } + else { + if (file_exists("{$pfb['aliasarchive']}")) { + // Remove Aliastables archive if found. + conf_mount_rw(); + @unlink_if_exists("{$pfb['aliasarchive']}"); + conf_mount_ro(); + } + // Remove earlyshellcmd if found. + if (is_array($config['system']['earlyshellcmd'])) { + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { + $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); + $msg = "\n** Removing earlyshellcmd **\n"; + } + } + } + + if ($msg != "") + pfb_logger("{$msg}","1"); +} + + +# Main pfBlockerNG Function +function sync_package_pfblockerng($cron = "") { + + global $g,$config,$pfb,$pfbarr; + pfb_global(); + + # Detect Boot Process or Update via CRON + if (isset($_POST) && $cron == "") { + if (!preg_match("/\w+/",$_POST['__csrf_magic'])) { + log_error("[pfBlockerNG] Sync terminated during boot process."); + return; + } + } + log_error("[pfBlockerNG] Starting sync process."); + + // Force Update - Set 'Save' variable when 'No Updates' found. + if ($cron == "noupdates") { + $pfb['save'] = TRUE; + } + + # Start of pfBlockerNG Logging to 'pfblockerng.log' + if ($pfb['enable'] == "on" && !$pfb['save']) { + $log = " UPDATE PROCESS START [ NOW ]\n"; + pfb_logger("{$log}","1"); + } else { + if ($cron != "noupdates") { + $log = "\n**Saving Configuration [ NOW ] ...\n"; + pfb_logger("{$log}","1"); + } + } + + // Call function for NanoBSD/Ramdisk processes. + pfb_aliastables("conf"); + + # Collect pfSense Max Table Size Entry + $pfb['table_limit'] = ($config['system']['maximumtableentries'] != "" ? $config['system']['maximumtableentries'] : "2000000"); + + # If Table limit not defined, set Default to 2M + $config['system']['maximumtableentries'] = "{$pfb['table_limit']}"; + + # Collect local web gui configuration + $pfb['weblocal'] = ($config['system']['webgui']['protocol'] != "" ? $config['system']['webgui']['protocol'] : "http"); + $pfb['port'] = $config['system']['webgui']['port']; + if ($pfb['port'] == "") { + if ($config['system']['webgui']['protocol'] == "http") { + $pfb['port'] = "80"; + } else { + $pfb['port'] = "443"; + } + } + $pfb['weblocal'] .= "://127.0.0.1:{$pfb['port']}/pfblockerng/pfblockerng.php"; + + # Define Inbound/Outbound Action is not user selected. + $pfb['deny_action_inbound'] = ($pfb['config']['inbound_deny_action'] != "" ? $pfb['config']['inbound_deny_action'] : "block"); + $pfb['deny_action_outbound'] = ($pfb['config']['outbound_deny_action'] != "" ? $pfb['config']['outbound_deny_action'] : "reject"); + + # Validation check to see if the Original pfBlocker package is Enabled + $pfb['validate']= $pfb['config']['pfblocker_cb']; + # User Defined CRON Start Minute + $pfb['min'] = $pfb['config']['pfb_min']; + # Reloads Existing Blocklists without Downloading New Lists + $pfb['reuse'] = $pfb['config']['pfb_reuse']; + # Enable OpenVPN AutoRules + $pfb['openvpn'] = $pfb['config']['openvpn_action']; + # Enable/Disable Floating Auto-Rules + $pfb['float'] = $pfb['config']['enable_float']; + # Enable Remove of Duplicate IPs utilizing Grepcidr + $pfb['dup'] = $pfb['config']['enable_dup']; + # Order of the Auto-Rules + $pfb['order'] = $pfb['config']['pass_order']; + # Suffix used for Auto-Rules + $pfb['suffix'] = $pfb['config']['autorule_suffix']; + + # Reputation Variables + $pfb['config_rep'] = $config['installedpackages']['pfblockerngreputation']['config'][0]; + + # Enable/Disable Reputation + $pfb['rep'] = $pfb['config_rep']['enable_rep']; + # Enable/Disable 'pDup' + $pfb['pdup'] = $pfb['config_rep']['enable_pdup']; + # Enable/Disable 'dDup' + $pfb['dedup'] = ($pfb['config_rep']['enable_dedup'] != "" ? $pfb['config_rep']['enable_dedup'] : "x"); + # 'Max' variable setting for Reputation + $pfb['max'] = ($pfb['config_rep']['p24_max_var'] != "" ? $pfb['config_rep']['p24_max_var'] : "x"); + # 'dMax' variable setting for Reputation + $pfb['dmax'] = ($pfb['config_rep']['p24_dmax_var'] != "" ? $pfb['config_rep']['p24_dmax_var'] : "x"); + # 'pMax' variable setting for Reputation + $pfb['pmax'] = ($pfb['config_rep']['p24_pmax_var'] != "" ? $pfb['config_rep']['p24_pmax_var'] : "x"); + # Action for Whitelist Country Category + $pfb['ccwhite'] = $pfb['config_rep']['ccwhite']; + # Action for Blacklist Country Category + $pfb['ccblack'] = $pfb['config_rep']['ccblack']; + # List of Countries in the Whitelist Category + $pfb['ccexclude']= ($pfb['config_rep']['ccexclude'] != "" ? $pfb['config_rep']['ccexclude'] : "x"); + # Emerging Threats IQRisk Block Categories + $pfb['etblock'] = ($pfb['config_rep']['etblock'] != "" ? $pfb['config_rep']['etblock'] : "x"); + # Emerging Threats IQRisk Match Categories + $pfb['etmatch'] = ($pfb['config_rep']['etmatch'] != "" ? $pfb['config_rep']['etmatch'] : "x"); + # Perform a Force Update on ET Categories + $pfb['etupdate']= $pfb['config_rep']['et_update']; + + # Variables + + # Starting Variable to Skip rep, pdup and dedeup functions if no changes are required + $pfb['dupcheck'] = FALSE; + ## $pfb['save'] is used to determine if User pressed "Save" Button to avoid Collision with CRON. + ## This is defined in each pfBlockerNG XML Files + + # Validation Check to ensure pfBlocker and pfBlockerNG are not running at the same time. + if ($pfb['validate'] == "") { + # Collect pfBlocker Enabled Status from config file + $pfb['validate_chk'] = $config['installedpackages']['pfblocker']['config'][0]['enable_cb']; + if ($pfb['validate_chk'] == "on") { + $log = "\n The Package 'pfBlocker' is currently Enabled. Either Disable pfBlocker, or 'Disable Validation Check' in pfBlockerNG \n"; + pfb_logger("{$log}","1"); + return; + } + } + + + ################################# + # 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", + "Proxy and Satellite" => "pfB_PS" + ); + + #create rules vars and arrays + # Array used to Collect Changes to Aliases to be saved to Config + $new_aliases = array(); + $new_aliases_list = array(); + $continent_existing = array(); + $continent_new = array(); + $permit_inbound = array(); + $permit_outbound = array(); + $deny_inbound = array(); + $deny_outbound = array(); + # An Array of all Aliases (Active and non-Active) + $aliases_list = array(); + # This is an Array of Aliases that Have Updated Lists via CRON/Force Update when 'Reputation' disabled. + $pfb_alias_lists = array(); + # This is an Array of All Active Aliases used when 'Reputation' enabled + $pfb_alias_lists_all = array(); + + # Base Rule Array + $base_rule_reg = array( "id" => "", + "tag" => "", + "tagged" => "", + "max" => "", + "max-src-nodes" => "", + "max-src-conn" => "", + "max-src-states"=> "", + "statetimeout" => "", + "statetype" => "keep state", + "os" => "" + ); + + # Floating Rules, Base Rule Array + $base_rule_float = array("id" => "", + "tag" => "", + "tagged" => "", + "quick" => "yes", + "floating" => "yes", + "max" => "", + "max-src-nodes" => "", + "max-src-conn" => "", + "max-src-states"=> "", + "statetimeout" => "", + "statetype" => "keep state", + "os" => "" + ); + + + ######################################### + # Configure Rule Suffix # + ######################################### + + # Discover if any Rules are AutoRules (If no AutoRules found, $pfb['autorules'] is FALSE, Skip Rules Re-Order ) + # To configure Auto Rule Suffix. pfBlockerNG must be disabled to change Suffix and to avoid Duplicate Rules + $pfb['autorules'] = FALSE; + $pfb['found'] = FALSE; + foreach ($continents as $continent => $pfb_alias) { + if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'])) { + $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0]; + if ($continent_config['action'] != "Disabled" && in_array($continent_config['action'],array('Deny_Both','Deny_Inbound','Deny_Outbound','Match_Both','Match_Inbound','Match_Outbound','Permit_Both','Permit_Inbound','Permit_Outbound'))) { + $pfb['autorules'] = TRUE; + $pfb['found'] = TRUE; + break; + } + } + } + + $list_type = array ("pfblockernglistsv4", "pfblockernglistsv6"); + foreach ($list_type as $ip_type) { + if ($config['installedpackages'][$ip_type]['config'] != "" && !$pfb['found']) { + foreach($config['installedpackages'][$ip_type]['config'] as $list) { + if ($list['action'] != "Disabled" && in_array($list['action'],array('Deny_Both','Deny_Inbound','Deny_Outbound','Match_Both','Match_Inbound','Match_Outbound','Permit_Both','Permit_Inbound','Permit_Outbound'))) { + $pfb['autorules'] = TRUE; + break; + } + } + } + } + + #Configure Auto Rule Suffix. pfBlockerNG must be disabled to change Suffix and to avoid Duplicate Rules + # Count Number of Rules with 'pfB_' + $count = 0; + if (is_array($config['filter']['rule'])) { + foreach ($config['filter']['rule'] as $rule) { + # Collect any pre-existing Suffix + if (preg_match("/pfB_\w+(\s.*)/",$rule['descr'], $pfb_suffix_real) && $count == 0) { + $pfb_suffix_match = $pfb_suffix_real[1]; + } + # Query for Existing pfB Rules + if (preg_match("/pfB_/",$rule['descr'])) { + $count++; + break; + } + } + } + + # Change Suffix only if No pfB Rules Found and Auto Rules are Enabled. + if ($pfb['autorules'] && $count == 0) { + switch ($pfb['suffix']) { + case "autorule": + $pfb['suffix'] = " auto rule"; + break; + case "standard": + $pfb['suffix'] = ""; + break; + case "ar": + $pfb['suffix'] = " AR"; + break; + } + } else { + if ($pfb['autorules']) { + # Use existing Suffix Match + $pfb['suffix'] = $pfb_suffix_match; + } else { + # Leave Rule Suffix 'Blank' + $pfb['suffix'] = ""; + } + } + + + ######################################################### + # Configure INBOUND/OUTBOUND INTERFACES # + ######################################################### + + # Collect pfSense Interface Order + $ifaces = get_configured_interface_list(); + + if (!empty($pfb['config']['inbound_interface'])) { + # Sort Interface Array to match pfSense Interface order to allow Floating Rules to populate. + $selected_interfaces = explode(",",$pfb['config']['inbound_interface']); + # Sort pfBlockerNG Interface order to pfSense Interface Order + $sort_interfaces = array_intersect($ifaces, $selected_interfaces); + $implode_interfaces = ltrim(implode(",",$sort_interfaces), ","); + # CSV String for Inbound Interfaces for 'pfB_' Match Rules + $pfb['inbound_floating'] = $implode_interfaces; + $pfb['inbound_interfaces_float'] = explode(" ",$implode_interfaces); + + # Assign Inbound Base Rule/Interfaces + if ($pfb['float'] == "on") { + # Define Base Firewall Floating Rules Settings + $base_rule = $base_rule_float; + $pfb['inbound_interfaces'] = $pfb['inbound_interfaces_float']; + } else { + # Define Base Firewall Rules Settings + $base_rule = $base_rule_reg; + $pfb['inbound_interfaces'] = explode(",",$pfb['config']['inbound_interface']); + } + } else { + # Define Empty Variable/Array + $pfb['inbound_interfaces_float'] = ""; + $pfb['inbound_interfaces'] = array(); + } + + if (!empty($pfb['config']['outbound_interface'])) { + # Sort Interface Array to match pfSense Interface order to allow Floating Rules to populate. + $selected_interfaces = explode(",",$pfb['config']['outbound_interface']); + # Sort pfBlockerNG Interface order to pfSense Interface Order + $sort_interfaces = array_intersect($ifaces, $selected_interfaces); + // If OpenVPN Interfaces are not in dropdown menu + if ($pfb['openvpn'] == "on" && $config['openvpn']['openvpn-server'] || $pfb['openvpn'] == "on" && $config['openvpn']['openvpn-client']) + if (!in_array("openvpn",$sort_interfaces)) + array_push($sort_interfaces, "openvpn"); + $implode_interfaces = ltrim(implode(",",$sort_interfaces), ","); + # CSV String for Outbound Interfaces for 'pfB_' Match Rules + $pfb['outbound_floating'] = $implode_interfaces; + $pfb['outbound_interfaces_float'] = explode(" ",$implode_interfaces); + + # Assign Outbound Base Rule/Interfaces + if ($pfb['float'] == "on") { + $base_rule = $base_rule_float; + $pfb['outbound_interfaces'] = $pfb['outbound_interfaces_float']; + } else { + $base_rule = $base_rule_reg; + $pfb['outbound_interfaces'] = explode(",",$pfb['config']['outbound_interface']); + // If OpenVPN Interfaces are not in dropdown menu + if ($pfb['openvpn'] == "on" && $config['openvpn']['openvpn-server'] || $pfb['openvpn'] == "on" && $config['openvpn']['openvpn-client']) + if (!in_array("openvpn",$sort_interfaces)) + array_push($pfb['outbound_interfaces'], "openvpn"); + } + } else { + # Define Empty Variable/Array + $pfb['outbound_interfaces_float'] = ""; + $pfb['outbound_interfaces'] = array(); + } + + + ################################################# + # Clear Removed Lists from Masterfiles # + ################################################# + + # Process to keep Masterfiles in Sync with Valid Lists from config.conf file. + $pfb['sync_master'] = TRUE; + + # Don't execute this function when pfBlockerNG is Disabled and 'Keep Blocklists' is enabled. + if ($pfb['enable'] == "" && $pfb['keep'] == "on") + $pfb['sync_master'] = FALSE; + + if ($pfb['sync_master']) { + $pfb['existing']['match']['type'] = "match"; + $pfb['existing']['permit']['type'] = "permit"; + $pfb['existing']['deny']['type'] = "deny"; + $pfb['existing']['native']['type'] = "native"; + $pfb['existing']['match']['folder'] = "{$pfb['matchdir']}"; + $pfb['existing']['permit']['folder'] = "{$pfb['permitdir']}"; + $pfb['existing']['deny']['folder'] = "{$pfb['denydir']}"; + $pfb['existing']['native']['folder'] = "{$pfb['nativedir']}"; + $pfb['actual']['match']['type'] = "match"; + $pfb['actual']['permit']['type'] = "permit"; + $pfb['actual']['deny']['type'] = "deny"; + $pfb['actual']['native']['type'] = "native"; + $pfb['actual']['match']['folder'] = "{$pfb['matchdir']}"; + $pfb['actual']['permit']['folder'] = "{$pfb['permitdir']}"; + $pfb['actual']['deny']['folder'] = "{$pfb['denydir']}"; + $pfb['actual']['native']['folder'] = "{$pfb['nativedir']}"; + + // Find all Enabled Continents Lists + foreach ($continents as $continent => $pfb_alias) { + if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config']) && $pfb['enable'] == "on") { + $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0]; + if ($continent_config['action'] != "Disabled") { + $cont_type = array ("countries4" => "_v4", "countries6" => "_v6"); + foreach ($cont_type as $c_type => $vtype) { + if ($continent_config[$c_type] != "") { + # Set Parameters for 'Match', 'Permit', 'Native' and 'Deny' + if (in_array($continent_config['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { + $pfb['existing']['match'][] = "{$pfb_alias}{$vtype}"; + } elseif (in_array($continent_config['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))){ + $pfb['existing']['permit'][] = "{$pfb_alias}{$vtype}"; + } elseif ($continent_config['action'] == "Alias_Native") { + $pfb['existing']['native'][] = "{$pfb_alias}{$vtype}"; + } else { + $pfb['existing']['deny'][] = "{$pfb_alias}{$vtype},"; // Add Trailing ',' + } + } + } + } + } + } + + # Find all Enabled IPv4/IPv6 Lists + $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); + foreach ($list_type as $ip_type => $vtype) { + if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { + foreach ($config['installedpackages'][$ip_type]['config'] as $list) { + if (is_array($list['row']) && $list['action'] != "Disabled") { + foreach ($list['row'] as $row) { + if ($vtype == "_v4") { + $pfb_alias = "{$row['header']}"; + } else { + $pfb_alias = "{$row['header']}_v6"; + } + # Collect Enabled Lists + if ($row['url'] != "" && $row['state'] != "Disabled") { + # Set Parameters for 'Match', 'Permit', 'Native' and 'Deny' + if (in_array($list['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { + $pfb['existing']['match'][] = "{$pfb_alias}"; + } elseif (in_array($list['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) { + $pfb['existing']['permit'][] = "{$pfb_alias}"; + } elseif ($list['action'] == "Alias_Native") { + $pfb['existing']['native'][] = "{$pfb_alias}"; + } else { + $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ',' + } + } + } + } + } + } + } + + # Find all Enabled IPv4 'Custom List' Header Names and Check if 'Emerging Threats Update' and 'Custom List Update' Needs Force Updating + $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); + foreach ($list_type as $ip_type => $vtype) { + if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { + $count = -1; + foreach ($config['installedpackages'][$ip_type]['config'] as $list) { + if (is_array($list['row']) && $list['action'] != "Disabled") { + $count++; + # Check if 'Emerging Threats Update' Needs Updating before next CRON Event. + if (is_array($list['row']) && $row['state'] != "Disabled" && $pfb['etupdate'] == "enabled" && $vtype == "_v4") { + foreach ($list['row'] as $row) { + $aliasname = $row['header']; + if ($row['format'] == "et") { + unlink_if_exists("{$pfb['denydir']}/{$aliasname}.txt"); + $config['installedpackages']['pfblockerngreputation']['config'][0]['et_update'] = "disabled"; + break; + } + } + } + } + + # Collect Enabled Custom List Box Aliases + if (pfbng_text_area_decode($list['custom']) != "") { + if ($vtype == "_v4") { + $pfb_alias = "{$list['aliasname']}_custom"; + } else { + $pfb_alias = "{$list['aliasname']}_custom_v6"; + } + # Determine Folder Location for 'List' + if (in_array($list['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { + $pfb['existing']['match'][] = "{$pfb_alias}"; + $pfbfolder = "{$pfb['matchdir']}"; + } elseif (in_array($list['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) { + $pfb['existing']['permit'][] = "{$pfb_alias}"; + $pfbfolder = "{$pfb['permitdir']}"; + } elseif ($list['action'] == "Alias_Native") { + $pfb['existing']['native'][] = "{$pfb_alias}"; + $pfbfolder = "{$pfb['nativedir']}"; + } else { + $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ',' + $pfbfolder = "{$pfb['denydir']}"; + } + # Determine if 'Custom List' Needs Force Updating before next CRON Event. + if ($list['custom_update'] == "enabled") { + unlink_if_exists("{$pfbfolder}/{$pfb_alias}.txt"); + # Uncheck 'Enabled' in List 'Custom_update' Setting + $config['installedpackages'][$ip_type]['config'][$count]['custom_update'] = "disabled"; + } + } + } + } + } + + # Collect all .txt file Names for each List Type + $list_types = array('match' => $pfb['matchdir'], 'permit' => $pfb['permitdir'], 'deny' => $pfb['denydir'], 'native' => $pfb['nativedir']); + foreach ($list_types as $type => $pfbfolder) { + $pfb_files = glob("$pfbfolder/*.txt"); + foreach ($pfb_files as $pfb_list) { + $pfb_file = basename($pfb_list,".txt"); + if ($type == "deny") { + $pfb['actual'][$type][] = "{$pfb_file},"; // Add Trailing ',' + } else { + $pfb['actual'][$type][] = "{$pfb_file}"; + } + } + } + + # Flag to execute pfctl and Rules Ordering + $pfb['remove'] = FALSE; + # Execute Final Summary as a List was Removed + $pfb['summary'] = FALSE; + + # Process to Remove Lists from Masterfile/DB Folder if they do not Exist + if (isset($pfb['existing'])) { + foreach ($pfb['existing'] as $pfb_exist) { + $existing_type = $pfb_exist['type']; + $pfbfolder = $pfb_exist['folder']; + foreach ($pfb['actual'] as $pfb_act) { + $actual_type = $pfb_act['type']; + if ($existing_type == $actual_type) { + switch ($existing_type) { + case "deny": + $results = array_diff($pfb_act, $pfb_exist); + $f_result = implode($results); + if ($f_result != "") { + $log = "[ Removing List(s) : {$f_result} ]\n"; + pfb_logger("{$log}","1"); + # Script to Remove un-associated Lists + exec ("{$pfb['script']} remove x x x {$f_result} >> {$pfb['log']} 2>&1"); + $pfb['summary'] = TRUE; + $pfb['remove'] = TRUE; + } + break; + case "match": + case "permit": + case "native": + $results = array_diff($pfb_act, $pfb_exist); + # This variable ($f_result) used in next section below. + $f_result = implode($results); + if (!empty($results)) { + foreach ($results as $pfb_results) { + $log = "[ Removing List(s) : {$pfb_results} ]\n"; + pfb_logger("{$log}","1"); + unlink_if_exists("{$pfbfolder}/{$pfb_results}.txt"); + } + $pfb['summary'] = TRUE; + $pfb['remove'] = TRUE; + } + break; + } + + # Allow Rebuilding of Changed Aliase to purge 'SKIP' Lists (when pfBlockerNG is Enabled) + $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); + foreach ($list_type as $ip_type => $vtype) { + if ($f_result != "" && $pfb['enable'] == "on") { + foreach ($results as $removed_header) { + if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { + foreach ($config['installedpackages'][$ip_type]['config'] as $list) { + $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']); + if (is_array($list['row'])) { + foreach ($list['row'] as $row) { + $removed = rtrim($removed_header, ','); + if ($row['header'] == $removed) { + $pfb['summary'] = TRUE; + $pfb['remove'] = TRUE; + # Add Alias to Update Array + $pfb_alias_lists[] = "{$alias}"; + $pfb_alias_lists_all[] = "{$alias}"; + } + } + } + } + } + } + } + } + } + } + } + } + } + + ######################################################### + # Clear Match/Pass/ET/Original Files/Folders # + ######################################################### + + # When pfBlockerNG is Disabled and 'Keep Blocklists' is Disabled. + if ($pfb['enable'] == "" && $pfb['keep'] == "" && !$pfb['install']) { + $log = "\n Removing DB Files/Folders \n"; + pfb_logger("{$log}","1"); + + unlink_if_exists("{$pfb['dbdir']}/masterfile"); + unlink_if_exists("{$pfb['dbdir']}/mastercat"); + unlink_if_exists("{$pfb['supptxt']}"); + rmdir_recursive("{$pfb['origdir']}"); + rmdir_recursive("{$pfb['matchdir']}"); + rmdir_recursive("{$pfb['permitdir']}"); + rmdir_recursive("{$pfb['denydir']}"); + rmdir_recursive("{$pfb['nativedir']}"); + rmdir_recursive("{$pfb['etdir']}"); + } + + + ######################################### + # Create Suppression Txt File # + ######################################### + + if ($pfb['enable'] == "on" && $pfb['supp'] == "on") + pfb_create_suppression_file(); + + + ################################# + # Assign Countries # + ################################# + + foreach ($continents as $continent => $pfb_alias) { + if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'])) { + $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0]; + if ($continent_config['action'] != "Disabled" && $pfb['enable'] == "on") { + + # Determine Folder Location for Alias (return array $pfbarr) + pfb_determine_list_detail($continent_config['action']); + $pfb['skip'] = $pfbarr['skip']; + $pfb_descr = $pfbarr['descr']; + $pfbfolder = $pfbarr['folder']; + + // Determine if Continent Lists require Action (IPv4 and IPv6) + $cont_type = array ("countries4" => "_v4", "countries6" => "_v6"); + foreach ($cont_type as $c_type => $vtype) { + + $continent = ""; + if ($continent_config[$c_type] != "") { + + // Collect Selected ISO Country Files + foreach (explode(",", $continent_config[$c_type]) as $iso) { + if ($iso != "" && file_exists($pfb['ccdir'] .'/' . $iso . $vtype . '.txt')) { + $continent .= file_get_contents ($pfb['ccdir'] . '/' . $iso . $vtype . '.txt'); + } + } + + if (file_exists($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig')) + $continent_existing = preg_replace('/\s/', '', file ($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig')); + + // Collect New Continent Data for comparison. Cleanup Array for Comparison + $continent_new = preg_split ('/$\R?^/m', $continent); + $line = count ( $continent_new ) - 1; + $match = $continent_new[$line]; + $continent_new[$line] = rtrim($match, "\n"); + + # Check if pfBlockerNG pfctl Continent Tables are Empty (pfBlockerNG was Disabled w/ "keep", then Re-enabled) + $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$pfb_alias}{$vtype} | awk '/Addresses/ {s+=$2}; END {print s}'"); + if (empty($pfctlck) && file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt')) { + $file_cont = file_get_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt'); + @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$file_cont, LOCK_EX); + # PFCTL - Update Only Aliases that have been updated. ('Reputation' Disabled) + $pfb_alias_lists[] = "{$pfb_alias}{$vtype}"; + } + + # Collect Active Alias Lists (Used for pfctl Update when 'Reputation' is enabled). + $pfb_alias_lists_all[] = "{$pfb_alias}{$vtype}"; + + // Compare Existing (Original File) and New Continent Data + if ($continent_new === $continent_existing && !empty($pfctlck) && file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt') && $pfb['reuse'] == "") { + # Format Log into clean Tab Spaces + $string_final = "{$pfb_alias}{$vtype}"; + if (strlen($string_final) > 10) { + $log_tab = "\t"; + } else { + $log_tab = "\t\t"; + } + + if (!$pfb['save']) { + $log = "\n[ {$pfb_alias}{$vtype} ] {$log_tab} exists, Reloading File [ NOW ]\n"; + pfb_logger("{$log}","1"); + } + } else { + // Do not proceed with Changes on User 'Save' + if (!$pfb['save']) { + $log = "\n[ {$pfb_alias}{$vtype} ] {$log_tab} Changes Found... Updating \n"; + pfb_logger("{$log}","1"); + + # Test to Skip d-dup and p-dup functions when changes are found. + $pfb['dupcheck'] = TRUE; + + $pfb_alias_lists[] = "{$pfb_alias}{$vtype}"; + + // Script to call Duplication Check Process only on IPv4 + if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") { + // Copy Continent Data to 'lists' folder for duplication processing + @file_put_contents($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig',$continent, LOCK_EX); + @file_put_contents($pfb['denydir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); + exec ("{$pfb['script']} continent {$pfb_alias}{$vtype} >> {$pfb['log']} 2>&1"); + $continent = file_get_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt'); + @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); + } else { + @file_put_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); + @file_put_contents($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig',$continent, LOCK_EX); + @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); + } + + # Check if File Exists and is >0 in Size and Save alias file + $file_chk = "0"; + $cont_chk = "{$pfbfolder}/{$pfb_alias}{$vtype}.txt"; + if (file_exists($cont_chk) && @filesize($cont_chk) >0) + $file_chk = exec ("/usr/bin/grep -cv '^#\|^$' {$cont_chk}"); + + if ($file_chk == "0" || $file_chk == "1") { + $new_file = "1.1.1.1\n"; + @file_put_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt', $new_file, LOCK_EX); + @file_put_contents($pfb['aliasdir'] . "/" . $pfb_alias . $vtype . ".txt", $new_file, LOCK_EX); + $log = "[ {$pfb_alias}{$vtype} ] Found no Unique IPs, Adding '1.1.1.1' to avoid Empty File\n"; + pfb_logger("{$log}","1"); + } + } + } + + + if (file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt')) { + #Create alias config + $new_aliases_list[] = "{$pfb_alias}{$vtype}"; + + $pfb_contlog = $continent_config['aliaslog']; + + $new_aliases[] = array( "name" => "{$pfb_alias}{$vtype}", + "url" => "{$pfb['weblocal']}?pfb={$pfb_alias}{$vtype}", + "updatefreq" => "32", + "address" => "", + "descr" => "pfBlockerNG {$vtype} {$pfb_descr} Country Alias", + "type" => "urltable", + "detail" => "DO NOT EDIT THIS ALIAS" + ); + + #Create rule if action permits + switch ($continent_config['action']) { + case "Deny_Both": + case "Deny_Outbound": + $rule = $base_rule; + $rule['type'] = "{$pfb['deny_action_outbound']}"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr']= "{$pfb_alias}{$vtype}{$pfb['suffix']}"; + $rule['source'] = array("any" => ""); + $rule['destination'] = array ("address" => "{$pfb_alias}{$vtype}"); + if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") + $rule['log'] = ""; + $deny_outbound[] = $rule; + if ($continent_config['action'] != "Deny_Both") + break; + case "Deny_Inbound": + $rule = $base_rule; + $rule['type'] = "{$pfb['deny_action_inbound']}"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; + $rule['source'] = array("address" => "{$pfb_alias}{$vtype}"); + $rule['destination'] = array ("any" => ""); + if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") + $rule['log'] = ""; + $deny_inbound[] = $rule; + break; + case "Permit_Both": + case "Permit_Outbound": + $rule = $base_rule; + $rule['type'] = "pass"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; + $rule['source'] = array ("any" => ""); + $rule['destination'] = array("address" => "{$pfb_alias}{$vtype}"); + if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") + $rule['log'] = ""; + $permit_outbound[] = $rule; + if ($continent_config['action'] != "Permit_Both") + break; + case "Permit_Inbound": + $rule = $base_rule; + $rule['type'] = "pass"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; + $rule['source'] = array("address"=> "{$pfb_alias}{$vtype}"); + $rule['destination'] = array ("any" => ""); + if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") + $rule['log'] = ""; + $permit_inbound[] = $rule; + break; + case "Match_Both": + case "Match_Outbound": + $rule = $base_rule_float; + $rule['type'] = "match"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + $rule['direction'] = "any"; + $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; + $rule['source'] = array ("any" => ""); + $rule['destination'] = array ("address" => "{$pfb_alias}{$vtype}"); + if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") + $rule['log'] = ""; + $match_outbound[] = $rule; + if ($list['action'] != "Match_Both") + break; + case "Match_Inbound": + $rule = $base_rule_float; + $rule['type'] = "match"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + $rule['direction'] = "any"; + $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; + $rule['source'] = array ("address" => "{$pfb_alias}{$vtype}"); + $rule['destination'] = array ( "any" => ""); + if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") + $rule['log'] = ""; + $match_inbound[] = $rule; + break; + } + } else { + #unlink continent list if any + unlink_if_exists($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt'); + } + } + } + } + #mark pfctl aliastable for cleanup + if (!in_array($pfb_alias, $aliases_list)) { + $aliases_list[] = "{$pfb_alias}{$vtype}"; + } + } + } + # UNSET variables + unset ($continent, $continent_existing, $continent_new); + + ################################################# + # Download and Collect IPv4/IPv6 lists # + ################################################# + + # IPv4 REGEX Definitions + $pfb['range'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))-((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))/'; + $pfb['block'] = '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[ 0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.([0]{1})\s+/'; + $pfb['cidr'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/[0-9]{2})/'; + $pfb['single'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s+/'; + $pfb['s_html'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/'; + + # IPv4 preg_replace Regex Filter array + $pfb_ipreg = array(); + $pfb_ipreg[0] = '/\b0+(?=\d)/'; # Remove any Leading Zeros in each Octet + $pfb_ipreg[1] = '/\s/'; # Remove any Whitespaces + $pfb_ipreg[2] = '/127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/'; # Remove any Loopback Addresses 127/8 + $pfb_ipreg[3] = '/0\.0\.0\.0\/32/'; # Remove 0.0.0.0/32 + $pfb_ipreg[4] = '/0\.0\.0\.0/'; # Remove 0.0.0.0 + + # IPv6 REGEX Definitions -- ** Still Needs some Adjustment on Regex Definition for IPv6 ** + # https://mebsd.com/coding-snipits/php-regex-ipv6-with-preg_match.html + $pattern1 = '([A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}'; + $pattern2 = '[A-Fa-f0-9]{1,4}::([A-Fa-f0-9]{1,4}:){0,5}[A-Fa-f0-9]{1,4}'; + $pattern3 = '([A-Fa-f0-9]{1,4}:){2}:([A-Fa-f0-9]{1,4}:){0,4}[A-Fa-f0-9]{1,4}'; + $pattern4 = '([A-Fa-f0-9]{1,4}:){3}:([A-Fa-f0-9]{1,4}:){0,3}[A-Fa-f0-9]{1,4}'; + $pattern5 = '([A-Fa-f0-9]{1,4}:){4}:([A-Fa-f0-9]{1,4}:){0,2}[A-Fa-f0-9]{1,4}'; + $pattern6 = '([A-Fa-f0-9]{1,4}:){5}:([A-Fa-f0-9]{1,4}:){0,1}[A-Fa-f0-9]{1,4}'; + $pattern7 = '([A-Fa-f0-9]{1,4}:){6}:[A-Fa-f0-9]{1,4}'; + $pattern8 = '[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}::\/[0-9]{2}'; + $pattern9 = '[A-Fa-f0-9]{1,4}:([A-Fa-f0-9]{1,4}::)\/[0-9]{2}'; + $pattern10 = '[A-Fa-f0-9]{1,4}::\/[0-9]{2}'; + $pfb['ipv6'] = "/($pattern1)|($pattern2)|($pattern3)|($pattern4)|($pattern5)|($pattern6)|($pattern7)|($pattern8)|($pattern9)|($pattern10)/"; + + $pfb['supp_update'] = FALSE; + $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); + foreach ($list_type as $ip_type => $vtype) { + if ($config['installedpackages'][$ip_type]['config'] != "") { + foreach ($config['installedpackages'][$ip_type]['config'] as $list) { + if ($list['action'] != "Disabled" && $pfb['enable'] == "on" && !$pfb['save'] && is_array($list['row'])) { + # Capture Alias Name + $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']); + foreach ($list['row'] as $row) { + if ($row['url'] != "" && $row['state'] != "Disabled") { + + # Determine Folder Location for Alias (return array $pfbarr) + pfb_determine_list_detail($list['action']); + $pfb['skip'] = $pfbarr['skip']; + $pfbfolder = $pfbarr['folder']; + + if ($vtype == "_v4") { + $header_url = "{$row['header']}"; + } else { + $header_url = "{$row['header']}_v6"; + } + + # Format Log into clean Tab Spaces + if (strlen($header_url) > 10) { + $log_tab = "\t"; + } else { + $log_tab = "\t\t"; + } + + // Empty Header Field Validation Check + 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"; + } else { + $log = "\n[ {$header_url} ] {$log_tab} exists, Reloading File [ NOW ]\n"; + } + pfb_logger("{$log}","1"); + } else { + if ($pfb['reuse'] == "on" && file_exists($pfb['origdir'] . '/' . $header_url . '.orig')) { + $log = "\n[ {$header_url} ] {$log_tab} Using Previously Downloaded File [ NOW ]\n"; + } else { + $log = "\n[ {$header_url} ] {$log_tab} Downloading New File [ NOW ]\n"; + } + pfb_logger("{$log}","1"); + + # Perform Remote URL Date/Time Stamp checks + $host = @parse_url($row['url']); + $list_url = "{$row['url']}"; + if ($row['format'] != "rsync" || $row['format'] != "html") { + if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) { + $remote_tds = "local"; + } else { + $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers($list_url))); + $remote_tds = preg_replace("/^Last-Modified: /","", $remote_tds); + } + } + + $url_list = array(); + if ($row['format'] == "gz" || $row['format'] == "gz_2") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.gz"; + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + # File Exists/Reuse + } else { + $url_gz = "{$row['url']}"; + $file_gz = @file_get_contents($url_gz); + @file_put_contents($file_dwn, $file_gz, LOCK_EX); + if ($remote_tds == "local") + $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); + $remote_stamp = strtotime($remote_tds); + if (!empty($remote_stamp) && file_exists($file_dwn)) + touch ($file_dwn, $remote_stamp); + } + $url_list = @gzfile($file_dwn); + } + + # IBlock Large Files mixed with IPs and Domains. PHP mem of 256M can't handle very large Files. + if ($row['format'] == "gz_lg") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.gz"; + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + # File Exists/Reuse + } else { + $url_gz = "{$row['url']}"; + $file_gz = @file_get_contents($url_gz); + @file_put_contents($file_dwn, $file_gz, LOCK_EX); + exec ("/usr/bin/gunzip -c {$file_dwn} | /usr/bin/sed 's/^.*://' | /usr/bin/grep -v '[a-zA-Z]\|^$\|^#' > {$pfb['origdir']}/{$header_url}.orig"); + if ($remote_tds == "local") + $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); + $remote_stamp = strtotime($remote_tds); + if (!empty($remote_stamp) && file_exists($file_dwn)) + touch ($file_dwn, $remote_stamp); + } + $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig'); + } + + elseif ($row['format'] == "zip") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.zip"; + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + # File Exists/Reuse + } else { + $url_zip = "{$row['url']}"; + if (!$file_zip = @file_get_contents($url_zip)) { + $error = error_get_last(); + $log = "\n [ {$header_url} ] {$error['message']} \n"; + pfb_logger("{$log}","2"); + } else { + @file_put_contents($file_dwn, $file_zip, LOCK_EX); + if ($remote_tds == "local") + $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); + $remote_stamp = strtotime($remote_tds); + if (!empty($remote_stamp) && file_exists($file_dwn)) + touch ($file_dwn, $remote_stamp); + } + } + $zip_out = "{$pfb['origdir']}/{$header_url}.orig"; + exec ("/usr/bin/tar -xOf {$file_dwn} | tr ',' '\n' > {$zip_out}"); + $url_list = @file($zip_out); + } + + elseif ($row['format'] == "et") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.gz"; + # Script to Call ET IQRISK Process + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + # File Exists/Reuse + } else { + $url_et = "{$row['url']}"; + $file_et = @file_get_contents($url_et); + @file_put_contents($file_dwn, $file_et, LOCK_EX); + if ($remote_tds == "local") + $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); + $remote_stamp = strtotime($remote_tds); + if (!empty($remote_stamp) && file_exists($file_dwn)) + touch ($file_dwn, $remote_stamp); + } + exec ("{$pfb['script']} et {$header_url} x x x x x {$pfb['etblock']} {$pfb['etmatch']} >> {$pfb['log']} 2>&1"); + $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig'); + } + + elseif ($row['format'] == "xlsx") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.zip"; + # Script to Call XLSX Process + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + # File Exists/Reuse + } else { + $url_xlsx = "{$row['url']}"; + $file_xlsx = @file_get_contents($url_xlsx); + @file_put_contents($file_dwn, $file_xlsx, LOCK_EX); + if ($remote_tds == "local") + $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); + $remote_stamp = strtotime($remote_tds); + if (!empty($remote_stamp) && file_exists($file_dwn)) + touch ($file_dwn, $remote_stamp); + } + exec ("{$pfb['script']} xlsx {$header_url} >> {$pfb['log']} 2>&1"); + $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig'); + } + + elseif ($row['format'] == "txt") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.orig"; + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + $url_list = @file($file_dwn); + } else { + $url_other = @file($row['url']); + $url_list = $url_other; + @file_put_contents($file_dwn, $url_other, LOCK_EX); + if ($remote_tds == "local") + $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); + $remote_stamp = strtotime($remote_tds); + if (!empty($remote_stamp) && file_exists($file_dwn)) + touch ($file_dwn, $remote_stamp); + } + } + + elseif ($row['format'] == "html" || $row['format'] == "block") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.raw"; + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + # File Exists/Reuse + $return = 0; + } else { + $url_html = "{$row['url']}"; + exec ("/usr/bin/fetch -v -o {$file_dwn} -T 20 {$url_html}",$output,$return); + } + if ($return == 0) + $url_list = @file($file_dwn); + } + + elseif ($row['format'] == "rsync") { + $file_dwn = "{$pfb['origdir']}/{$header_url}.orig"; + if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { + # File Exists/Reuse + } else { + $url_rsync = "{$row['url']}"; + exec ("/usr/local/bin/rsync --timeout=5 {$url_rsync} {$file_dwn}"); + } + $url_list = @file($file_dwn); + } + + #extract range lists + $new_file = ""; + if (!empty($url_list)) { + if ($row['format'] == "gz" && $vtype == "_v4") { + foreach ($url_list as $line) { + if (!preg_match("/^#/", $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_temp2($matches[1],$matches[2]); + if (!empty($a_cidr)) { + foreach ($a_cidr as $cidr) { + $new_file .= preg_replace($pfb_ipreg,'',$cidr) . "\n"; + } + } + } + } + } + } + + elseif ($row['format'] == "block" && $vtype == "_v4") { + foreach ($url_list as $line) { + if (!preg_match("/^#/", $line)) { + # Block Type '218.77.79.0 218.77.79.255 24' + if (preg_match($pfb['block'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "/24\n"; + } + } + } + } + + elseif ($row['format'] == "html" && $vtype == "_v4") { + foreach ($url_list as $line) { + if (!preg_match("/^#/", $line)) { + # CIDR format 192.168.0.0/16 + if (preg_match($pfb['cidr'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + # Single ip addresses + elseif (preg_match($pfb['s_html'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + } + } + } + + elseif ($vtype == "_v6") { + foreach ($url_list as $line) { + if (!preg_match("/^#/", $line)) { + # IPv6 Regex Match + if (preg_match($pfb['ipv6'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + } + } + } + + else { + foreach ($url_list as $line) { + if (!preg_match("/^#/", $line)) { + # CIDR format 192.168.0.0/16 + if (preg_match($pfb['cidr'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + # Single ip addresses + elseif (preg_match($pfb['single'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + } + } + } + } + + # Check to see if Blocklist actually Failed Download or has no IPs listed. + if ($row['format'] == "html" || $row['format'] == "block") { + $url_chk = $file_dwn; + } else { + $url_chk = "{$pfb['origdir']}/{$header_url}.orig"; + } + + # Check if File Exists and is >0 in Size + $file_chk = ""; + if (file_exists($url_chk) && @filesize($url_chk) >0) + $file_chk = exec ("/usr/bin/grep -cv '^#\|^$' {$url_chk}"); + + if ($file_chk == "0") { + $new_file = "1.1.1.1\n"; + $url_other = $new_file; + $log = "[ {$header_url} ] Found no IPs, Adding '1.1.1.1' to avoid Download FAIL\n"; + pfb_logger("{$log}","1"); + } + + if ($new_file != "") { + if ($row['format'] == "gz" || $row['format'] == "gz_2" || $row['format'] == "html" || $row['format'] == "block") { + # Re-Save these formats as original file + $url_other = $new_file; + @file_put_contents($pfb['origdir'] . '/' . $header_url . '.orig',$url_other, LOCK_EX); + } + + # Save List to '.txt' format in appropriate Folder + @file_put_contents($pfbfolder . '/' .$header_url . '.txt',$new_file, LOCK_EX); + + if ($pfb['rep'] == "on" && $pfb['skip'] && $vtype == "_v4") { + # Script to Call p24 Process + exec ("{$pfb['script']} p24 {$header_url} {$pfb['max']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1"); + } + + if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") { + # Script to call Duplication Check Process + exec ("{$pfb['script']} duplicate {$header_url} >> {$pfb['log']} 2>&1"); + } + + # PFCTL - Update Only Aliases that have been updated only. + $pfb_alias_lists[] = "{$alias}"; + # Launch d-dup and p-dup functions when changes are found. + if ($pfb['skip'] && $vtype == "_v4") + $pfb['dupcheck'] = TRUE; + # Enable Suppression Process due to Updates + if ($pfb['supp'] == "on" && $vtype == "_v4") + $pfb['supp_update'] = TRUE; + + } else { + # Log FAILED Downloads and Check if Firewall or Snort/Suricata is Blocking Host + $log = "\n [ {$alias} {$header_url} ] Download FAIL [ NOW ]\n"; + pfb_logger("{$log}","2"); + + # Rebuild Previous List File from contents of Masterfile + if ($pfb['skip'] && $vtype == "_v4") { + # Search with trailing Whitespace to match exact Header in Masterfile + $header_url2 = $header_url . "[[:space:]]"; + $file_chk = exec ("/usr/bin/grep {$header_url2} {$pfb['master']} | grep -c ^"); + + if (!file_exists($pfbfolder . '/' . $header_url . '.txt') && @$file_chk > 0 && file_exists($pfb['master'])) { + $log = " [ {$alias} {$header_url} ] Found: {$file_chk} Line(s), Restoring previous List from Master \n"; + pfb_logger("{$log}","2"); + exec ("/usr/bin/grep {$header_url2} {$pfb['master']} | cut -d' ' -f2 > {$pfbfolder}/{$header_url}.txt"); + } + } + # A "Space" string Variable + $sp = " "; + $ip = @gethostbyname($host['host']); + $ip2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", "\"^$1\.$2\.$3\.\"", $ip); + + # Only Perform these Checks if they are not "localfiles" + if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) { + $log = " [ {$alias} {$header_url} ] Local File Failure \n"; + pfb_logger("{$log}","2"); + } else { + # only perform these steps if an 'IP' is found. + if (!empty($ip)) { + // Query for Exact IP Match + $result_b1 = array(); + $pfb_b1 = exec ("/usr/bin/grep ^{$ip} {$pfbfolder}/*", $result_b1); + // Query for First Three IP Octet Matches + $result_b2 = array(); + $pfb_b2 = exec ("/usr/bin/grep {$ip2} {$pfbfolder}/*", $result_b2); + // Query Snort/Suricata snort2c IP Block Table + $snort_pfb = exec("/sbin/pfctl -t snort2c -T show | grep {$ip}"); + + # If an exact IP Match is not found report any First Three IP Octets. + if (!empty($result_b1)) { + $final_b1 = implode("\n ", $result_b1); + $log = " [ {$alias} {$header_url}, {$ip} ] Firewall IP Block Found in : \n{$sp}{$final_b1}\n"; + pfb_logger("{$log}","2"); + } else { + if (!empty($result_b2)) { + $final_b2 = implode("\n ", $result_b2); + $log = " [ {$alias} {$header_url}, {$ip} ] *Potential* Firewall IP Block Found in : \n{$sp}{$final_b2}\n"; + pfb_logger("{$log}","2"); + } + } + if (!empty($snort_pfb)) { + $log = " [ {$alias} {$header_url}, {$ip} ] snort2c IP Block Found in : [ {$snort_pfb} ]\n"; + pfb_logger("{$log}","2"); + } + } else { + $log = " [ {$alias} {$header_url} ] No host IP found \n"; + pfb_logger("{$log}","2"); + } + } + } + # UNSET variables + unset ($file_gz,$file_zip,$file_et,$file_xlsx,$url_other,$url_list); + } + } + } + #check custom network list + if (pfbng_text_area_decode($list['custom']) != "") { + + if ($vtype == "_v4") { + $aliascustom = "{$list['aliasname']}_custom"; + } else { + $aliascustom = "{$list['aliasname']}_custom_v6"; + } + + # Format Log into clean Tab Spaces + if (strlen($aliascustom) > 10) { + $log_tab = "\t"; + } else { + $log_tab = "\t\t"; + } + + # Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled. + $pfb_alias_lists_all[] = "{$alias}"; + + # Determine Folder Location for Alias (return array $pfbarr) + pfb_determine_list_detail($list['action']); + $pfb['skip'] = $pfbarr['skip']; + $pfbfolder = $pfbarr['folder']; + + if (file_exists($pfbfolder . '/' . $aliascustom . '.txt') && $pfb['reuse'] == "") { + $log = "\n[ {$aliascustom} ] {$log_tab} exists, Reloading File [ NOW ]\n"; + pfb_logger("{$log}","1"); + } else { + $url_list = array(); + $log = "\n[ {$aliascustom} ] {$log_tab} Loading Custom File [ NOW ]\n"; + pfb_logger("{$log}","1"); + + $custom_list = pfbng_text_area_decode($list['custom']) . "\n"; + @file_put_contents($pfb['origdir'] . '/' . $aliascustom . '.orig', $custom_list, LOCK_EX); + $url_list = @file($pfb['origdir'] . '/' . $aliascustom . '.orig'); + + $new_file = ""; + if (!empty($url_list)) { + foreach ($url_list as $line) { + if ($vtype == "_v4") { + # CIDR format 192.168.0.0/16 + if (preg_match($pfb['cidr'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + # Single ip addresses + elseif (preg_match($pfb['s_html'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + # Network range 192.168.0.0-192.168.0.254 + elseif (preg_match($pfb['range'],$line,$matches)) { + $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"; + } + } + } + } else { + # IPv6 Regex + if (preg_match($pfb['ipv6'],$line,$matches)) { + $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; + } + } + } + + } + if ($new_file != "") { + # PFCTL - Collect Only Aliases that have been updated only. + $pfb_alias_lists[] = "{$alias}"; + # Collect Updated lists for Suppression Process + @file_put_contents($pfbfolder . '/'. $aliascustom . '.txt',$new_file, LOCK_EX); + # Enable Suppression Process due to Updates + if ($pfb['supp'] == "on" && $vtype == "_v4") + $pfb['supp_update'] = TRUE; + if ($pfb['rep'] == "on" && $pfb['skip'] && $vtype == "_v4") { + # Script to Call p24 Process + exec ("{$pfb['script']} p24 {$aliascustom} {$pfb['max']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1"); + } + if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") { + # Script to call Duplication Check Process + exec ("{$pfb['script']} duplicate {$aliascustom} >> {$pfb['log']} 2>&1"); + } + } else { + $log = "[ {$aliascustom} ] Custom List Error ]\n"; + pfb_logger("{$log}","1"); + } + } + } + } + } + } + } + + + ################################# + # REPUTATION PROCESSES # + ################################# + + # IP Reputation processes (pdup and ddup) + if ($pfb['pdup'] == "on" && $pfb['dupcheck'] && !$pfb['save'] && $pfb['enable'] == "on") { + # Script to run pdup process + exec ("{$pfb['script']} pdup x {$pfb['pmax']} >> {$pfb['log']} 2>&1"); + } + if ($pfb['dedup'] == "on" && $pfb['dupcheck'] && !$pfb['save'] && $pfb['enable'] == "on") { + # Script to run dedup process + exec ("{$pfb['script']} dedup x {$pfb['dmax']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1"); + } + + ################################# + # CONFIGURE ALIASES # + ################################# + + $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); + foreach ($list_type as $ip_type => $vtype) { + if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { + $runonce = 0; + foreach ($config['installedpackages'][$ip_type]['config'] as $list) { + $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']); + + # Determine Folder Location for Alias (return array $pfbarr) + pfb_determine_list_detail($list['action']); + $pfb['skip'] = $pfbarr['skip']; + $pfb_descr = $pfbarr['descr']; + $pfbfolder = $pfbarr['folder']; + + // Re-Save Only Aliases that have been updated only. + // When 'Reputation' is used, all Aliases need to be Updated. + $final_alias = array(); + if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") { + if (!empty($pfb_alias_lists_all)) + $final_alias = array_unique($pfb_alias_lists_all); + } else { + if (!empty($pfb_alias_lists)) + $final_alias = array_unique($pfb_alias_lists); + } + + if ($list['action'] != "Disabled") { + #remove empty lists files if any + if (is_array($list['row'])) { + $update = 0; + ${$alias} = ""; + foreach ($list['row'] as $row) { + if ($row['url'] != "" && $row['state'] != "Disabled") { + if ($vtype == "_v4") { + $header_url = "{$row['header']}"; + } else { + $header_url = "{$row['header']}_v6"; + } + $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$alias} | awk '/Addresses/ {s+=$2}; END {print s}'"); + + # Update Alias if List File Exists and its been updated or if the Alias URL Table is Empty. + if (file_exists($pfbfolder . "/" . $header_url . ".txt") && in_array($alias, $final_alias) || file_exists($pfbfolder . "/" . $header_url . ".txt") && empty($pfctlck)) { + # Script to run Suppression process (Print Header Only) + if ($pfb['supp'] == "on" && $vtype == "_v4" && $runonce == 0 && $pfb['supp_update']) { + exec ("{$pfb['script']} suppress x x x suppressheader >> {$pfb['log']} 2>&1"); + $runonce++; + } + # Script to run Suppression Process (Body) + if ($pfb['supp'] == "on" && $vtype == "_v4" && $pfb['supp_update']) { + if ($pfb['dup'] == "on" || !$pfb['skip']) { + # Execute if Duplication Process is Enabled or List is Permit or Match + exec ("{$pfb['script']} suppress x x x {$header_url}\|{$pfbfolder}/ >> {$pfb['log']} 2>&1"); + } else { + # Execute if Duplication Process is Disabled + exec ("{$pfb['script']} suppress x x off {$header_url}\|{$pfbfolder}/ >> {$pfb['log']} 2>&1"); + } + } + ${$alias} .= file_get_contents($pfbfolder . '/' . $header_url . '.txt'); + $update++; + } + } + } + } + + #check custom network list + if ($vtype == "_v4") { + $aliasname = "{$list['aliasname']}_custom"; + } else { + $aliasname = "{$list['aliasname']}_custom_v6"; + } + + # Update Alias if List File Exists and its been updated or if the Alias URL Table is Empty. + $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$alias} | awk '/Addresses/ {s+=$2}; END {print s}'"); + + if (pfbng_text_area_decode($list['custom']) != "") { + if (file_exists($pfbfolder . "/" . $aliasname . ".txt") && in_array($alias, $final_alias) || file_exists($pfbfolder . "/" . $aliasname . ".txt") && empty($pfctlck)) { + ${$alias} .= file_get_contents($pfbfolder . '/' . $aliasname . '.txt'); + $update++; + } + } + # Determine Validity of Alias URL Tables/Rules. ie: Don't create Empty URL Tables or Aliases + if (${$alias} == "" && empty($pfctlck)) { + unlink_if_exists($pfb['aliasdir'] . '/' . $alias. '.txt'); + } else { + // Save Only Aliases that have been updated. + if ($update > 0) { + @file_put_contents($pfb['aliasdir'] . '/' . $alias. '.txt',${$alias}, LOCK_EX); + } + + $alias_log = $list['aliaslog']; + #create alias + $new_aliases_list[] = "{$alias}"; + + $new_aliases[] = array( "name" => "{$alias}", + "url" => "{$pfb['weblocal']}?pfb={$alias}", + "updatefreq" => "32", + "address" => "", + "descr" => "pfBlockerNG {$pfb_descr} List Alias", + "type" => "urltable", + "detail" => "DO NOT EDIT THIS ALIAS" + ); + + #Create rule if action permits + switch ($list['action']) { + case "Deny_Both": + case "Deny_Outbound": + $rule = $base_rule; + $rule['type'] = "{$pfb['deny_action_outbound']}"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr'] = "{$alias}{$pfb['suffix']}"; + $rule['source'] = array ("any" => ""); + $rule['destination'] = array ("address" => "{$alias}"); + if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") + $rule['log'] = ""; + $deny_outbound[] = $rule; + if ($list['action'] != "Deny_Both") + break; + case "Deny_Inbound": + $rule = $base_rule; + $rule['type'] = "{$pfb['deny_action_inbound']}"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr'] = "{$alias}{$pfb['suffix']}"; + $rule['source'] = array("address" => "{$alias}"); + $rule['destination'] = array ("any" => ""); + if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") + $rule['log'] = ""; + $deny_inbound[] = $rule; + break; + case "Permit_Both": + case "Permit_Outbound": + $rule = $base_rule; + $rule['type'] = "pass"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr'] = "{$alias}{$pfb['suffix']}"; + $rule['source'] = array ("any" => ""); + $rule['destination'] = array ("address" => "{$alias}"); + if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") + $rule['log'] = ""; + $permit_outbound[] = $rule; + if ($list['action'] != "Permit_Both") + break; + case "Permit_Inbound": + $rule = $base_rule; + $rule['type'] = "pass"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + if ($pfb['float'] == "on") + $rule['direction'] = "any"; + $rule['descr'] = "{$alias}{$pfb['suffix']}"; + $rule['source'] = array ("address" => "{$alias}"); + $rule['destination'] = array ("any" => ""); + if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") + $rule['log'] = ""; + $permit_inbound[] = $rule; + break; + case "Match_Both": + case "Match_Outbound": + $rule = $base_rule_float; + $rule['type'] = "match"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + $rule['direction'] = "any"; + $rule['descr'] = "{$alias}{$pfb['suffix']}"; + $rule['source'] = array ("any" => ""); + $rule['destination'] = array ("address" => "{$alias}"); + if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") + $rule['log'] = ""; + $match_outbound[] = $rule; + if ($list['action'] != "Match_Both") + break; + case "Match_Inbound": + $rule = $base_rule_float; + $rule['type'] = "match"; + if ($vtype == "_v6") + $rule['ipprotocol'] = "inet6"; + $rule['direction'] = "any"; + $rule['descr'] = "{$alias}{$pfb['suffix']}"; + $rule['source'] = array ("address" => "{$alias}"); + $rule['destination'] = array ("any" => ""); + if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") + $rule['log'] = ""; + $match_inbound[] = $rule; + break; + } + } + #mark pfctl aliastable for cleanup + if (!in_array($alias, $aliases_list)) { + $aliases_list[] = "{$alias}"; + } + } else { + #unlink previous pfblockerNG alias list if any + unlink_if_exists($pfb['aliasdir'] . '/' . $alias . '.txt'); + } + } + } + } + # Clear Variables + ${$alias} = ""; + + + ######################################### + # UPDATE pfSense ALIAS TABLES # + ######################################### + + #update pfsense alias table + if (is_array($config['aliases']['alias'])) { + foreach ($config['aliases']['alias'] as $cbalias) { + if (preg_match("/pfB_/",$cbalias['name'])) { + #mark pfctl aliastable for cleaning + if (!in_array($cbalias['name'], $aliases_list)) { + $aliases_list[] = $cbalias['name']; #mark aliastable for cleaning + } + #remove previous aliastable file if alias is not defined any more + if (!in_array($cbalias['name'], $new_aliases_list)) { + unlink_if_exists($pfb['aliasdir'] . '/' . $cbalias['name'] . ".txt"); + } + } else { + $new_aliases[] = $cbalias; + + # Check Table Size + if (file_exists($pfb['aliasdir'] . '/' . $alias . '.txt') && $message == "") { + preg_match("/(\d+)/",exec("/usr/bin/grep -c ^ " . $pfb['aliasdir'] . '/' . $alias . '.txt'),$matches); + } + if (($matches[1] * 2.1) >= $pfb['table_limit']) { + #alias table too large + $message = "{$alias} alias table is too large. Reduce networks in list or increase 'Firewall Maximum Table Entries' value to at least " . (int)($matches[1] * 2.1) . ' in "system - advanced - Firewall/NAT" . '; + } + } + } + } + + #apply new alias table to xml + if ($message == "") { + $config['aliases']['alias'] = $new_aliases; + } + # UNSET Variables + unset($new_aliases, $cbalias); + + + ######################### + # Assign Rules # + ######################### + + # Only Execute if AutoRules are defined or if an Alias has been removed. + if ($pfb['autorules'] || $pfb['enable'] == "" || $pfb['remove']) { + if (count($deny_inbound) > 0 || count($permit_inbound) > 0 || count($match_inbound) > 0) { + if ($pfb['inbound_interfaces'] == "") { + $message = "Unable to apply rules. Inbound Interface option not configured."; + } + } + if (count($deny_outbound) > 0 || count($permit_outbound) > 0 || count($match_outbound) > 0) { + if ($pfb['outbound_interfaces'] == "") { + $message = "Unable to apply rules. Outbound Interface option not configured."; + } + } + + if ($message == "") { + $new_rules = array(); + $permit_rules = array(); + $match_rules = array(); + $other_rules = array(); + $fpermit_rules = array(); + $fmatch_rules = array(); + $fother_rules = array(); + + # Collect All Existing Rules + $rules = $config['filter']['rule']; + # Collect Existing pfSense Rules 'Pass', 'Match' and 'Other' pfSense rules into new Arrays. + if (!empty($rules)) { + foreach ($rules as $rule) { + if (!preg_match("/pfB_.*" . $pfb['suffix'] . "/",$rule['descr'])) { + // Floating rules collection 'Floating Pass/Match'. Balance to 'other' + if ($pfb['float'] == "on") { + if ($rule['type'] == "pass" && $rule['floating'] == "yes") { + $fpermit_rules[] = $rule; + } elseif ($rule['type'] == "match" && $rule['floating'] == "yes") { + $fmatch_rules[] = $rule; + } elseif ($rule['floating'] == "yes") { + $fother_rules[] = $rule; + } else { + $other_rules[] = $rule; + } + } else { + // Collect only 'Selected Inbound and Outbound Interfaces'. Balance to 'Other' + if (in_array($rule['interface'],$pfb['inbound_interfaces']) || in_array($rule['interface'],$pfb['outbound_interfaces'])) { + // Floating Rules 'off'. Collect 'Floating Other', Balance to 'Other' + if ($rule['floating'] == "yes") { + $fother_rules[] = $rule; + } elseif ($rule['type'] == "pass") { + if ($pfb['order'] == "order_0") { + $other_rules[] = $rule; + } else { + $permit_rules[] = $rule; + } + } elseif ($rule['type'] == "match") { + if ($pfb['order'] == "order_0") { + $other_rules[] = $rule; + } else { + $match_rules[] = $rule; + } + } else { + $other_rules[] = $rule; + } + } else { + if ($rule['floating'] == "yes") { + $fother_rules[] = $rule; + } else { + $other_rules[] = $rule; + } + } + } + } + } + } + + ################################################################################# + # PASS/MATCH RULES ORDER(p/m) # + # ORDER 0 - pfBlockerNG / All other Rules # + # ORDER 1 - pfSense (p/m) / pfBlockerNG (p/m) / pfBlockerNG Block/Reject # + # ORDER 2 - pfBlockerNG (p/m) / pfSense (p/m) / pfBlockerNG Block/Reject # + # ORDER 3 - pfBlockerNG (p/m) / pfBlockerNG Block/Reject / pfSense (p/m) # + ################################################################################# + + if ($pfb['float'] == "") { + if (!empty($fother_rules)) { + foreach ($fother_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + } + if (!empty($fpermit_rules) && $pfb['order'] == "order_1") { + foreach ($fpermit_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($fmatch_rules) && $pfb['order'] == "order_1") { + foreach ($fmatch_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + + # Define Inbound Interface Rules + if (!empty($pfb['inbound_interfaces'])) { + $counter = 0; + foreach ($pfb['inbound_interfaces'] as $inbound_interface) { + if (!empty($permit_rules) && $pfb['order'] == "order_1") { + foreach ($permit_rules as $cb_rules) { + if ($cb_rules['interface'] == $inbound_interface) + $new_rules[] = $cb_rules; + } + } + if (!empty($match_rules) && $pfb['order'] == "order_1") { + foreach ($match_rules as $cb_rules) { + if ($cb_rules['interface'] == $inbound_interface) + $new_rules[] = $cb_rules; + } + } + # Match Inbound Rules defined as Floating Only. + if (!empty($match_inbound) && $counter == 0) { + foreach ($match_inbound as $cb_rules) { + $cb_rules['interface'] = $pfb['inbound_floating']; + $new_rules[] = $cb_rules; + $counter ++; + } + } + if (!empty($permit_inbound)) { + foreach ($permit_inbound as $cb_rules) { + $cb_rules['interface'] = $inbound_interface; + $new_rules[] = $cb_rules; + } + } + if (!empty($fpermit_rules) && $pfb['order'] == "order_2") { + foreach ($fpermit_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($fmatch_rules) && $pfb['order'] == "order_2") { + foreach ($fmatch_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($permit_rules) && $pfb['order'] == "order_2") { + foreach ($permit_rules as $cb_rules) { + if ($cb_rules['interface'] == $inbound_interface) + $new_rules[] = $cb_rules; + } + } + if (!empty($match_rules) && $pfb['order'] == "order_2") { + foreach ($match_rules as $cb_rules) { + if ($cb_rules['interface'] == $inbound_interface) + $new_rules[] = $cb_rules; + } + } + if (!empty($deny_inbound)) { + foreach ($deny_inbound as $cb_rules) { + $cb_rules['interface'] = $inbound_interface; + $new_rules[] = $cb_rules; + } + } + } + } + + # Define Outbound Interface Rules + if (!empty($pfb['outbound_interfaces'])) { + $counter = 0; + foreach ($pfb['outbound_interfaces'] as $outbound_interface) { + if (!empty($permit_rules) && $pfb['order'] == "order_1") { + foreach ($permit_rules as $cb_rules) { + if ($cb_rules['interface'] == $outbound_interface) + $new_rules[] = $cb_rules; + } + } + if (!empty($match_rules) && $pfb['order'] == "order_1") { + foreach ($match_rules as $cb_rules) { + if ($cb_rules['interface'] == $outbound_interface) + $new_rules[] = $cb_rules; + } + } + # Match Outbound Rules defined as Floating Only. + if (!empty($match_outbound) && $counter == 0) { + foreach ($match_outbound as $cb_rules) { + $cb_rules['interface'] = $pfb['outbound_floating']; + $new_rules[] = $cb_rules; + $counter++; + } + } + if (!empty($permit_outbound)) { + foreach ($permit_outbound as $cb_rules) { + $cb_rules['interface'] = $outbound_interface; + $new_rules[] = $cb_rules; + } + } + if (!empty($permit_rules) && $pfb['order'] == "order_2") { + foreach ($permit_rules as $cb_rules) { + if ($cb_rules['interface'] == $outbound_interface) + $new_rules[] = $cb_rules; + } + } + if (!empty($match_rules) && $pfb['order'] == "order_2") { + foreach ($match_rules as $cb_rules) { + if ($cb_rules['interface'] == $outbound_interface) + $new_rules[] = $cb_rules; + } + } + if (!empty($deny_outbound)) { + foreach ($deny_outbound as $cb_rules) { + $cb_rules['interface'] = $outbound_interface; + $new_rules[] = $cb_rules; + } + } + } + } + + if (!empty($fpermit_rules) && $pfb['order'] == "order_0") { + foreach ($fpermit_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($fmatch_rules) && $pfb['order'] == "order_0") { + foreach ($fmatch_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($fpermit_rules) && $pfb['order'] == "order_3") { + foreach ($fpermit_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($fmatch_rules) && $pfb['order'] == "order_3") { + foreach ($fmatch_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($permit_rules) && $pfb['order'] == "order_3") { + foreach ($permit_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if (!empty($match_rules) && $pfb['order'] == "order_3") { + foreach ($match_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + if ($pfb['float'] == "on") { + if (!empty($fother_rules)) { + foreach ($fother_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + } + if (!empty($other_rules)) { + foreach ($other_rules as $cb_rules) { + $new_rules[] = $cb_rules; + } + } + + # Save New Rule Order to Config + $config['filter']['rule'] = $new_rules; + } + $log = "\n {$message} \n"; + pfb_logger("{$log}","1"); + + # UNSET arrays + unset ($cb_rules,$permit_inbound,$permit_outbound,$deny_inbound,$deny_outbound,$match_inbound,$match_outbound); + unset ($other_rules,$fother_rules,$permit_rules,$fpermit_rules,$match_rules,$fmatch_rules); + } + + + ################################# + # Closing Processes # + ################################# + + #uncheck Reusing Existing Downloads Check box + if (!$pfb['save'] && $pfb['enable'] == "on") + $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = ""; + + # Save all Changes to pfSense config file + write_config(); + + # If 'Rule Changes' are found, utilize the 'filter_configure()' function, if not, utilize 'pfctl replace' command + if ($pfb['autorules'] && $rules != $new_rules || $pfb['enable'] == "" || $pfb['remove']) { + require_once("filter.inc"); + + if (!$pfb['save']) { + $log = "\n===[ Aliastables / Rules ]================================\n\n"; + pfb_logger("{$log}","1"); + + $log = "Firewall Rule Changes Found, Applying Filter Reload \n"; + pfb_logger("{$log}","1"); + } + + # Remove all pfBlockerNG Alias tables + if (!empty($aliases_list)) { + foreach ($aliases_list as $table) { + exec ("/sbin/pfctl -t " . escapeshellarg($table) . " -T kill 2>&1", $pfb_null); + } + } + + #load filter file which will create the pfctl tables + filter_configure(); + + // Call function for NanoBSD/Ramdisk processes. + pfb_aliastables("update"); + } else { + # Don't Execute on User 'Save' + if (!$pfb['save']) { + + $log = "\n===[ Aliastables / Rules ]================================\n\n"; + pfb_logger("{$log}","1"); + + $log = "No Changes to Firewall Rules, Skipping Filter Reload \n"; + pfb_logger("{$log}","1"); + + // Re-Save Only Aliases that have been updated only. + // When 'Reputation' is used, all Aliases Need to be Updated. + $final_alias = array(); + if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") { + if (!empty($pfb_alias_lists_all)) + $final_alias = array_unique($pfb_alias_lists_all); + } else { + if (!empty($pfb_alias_lists)) + $final_alias = array_unique($pfb_alias_lists); + } + + if (!empty($final_alias)) { + foreach ($final_alias as $final) { + $log = "\n Updating: {$final} \n"; + pfb_logger("{$log}","1"); + $result_pfctl = ""; + exec ("/sbin/pfctl -t " . escapeshellarg($final) . " -T replace -f " . $pfb['aliasdir'] . "/" . escapeshellarg($final) . ".txt 2>&1", $result_pfctl); + $log = implode($result_pfctl); + pfb_logger("{$log}","1"); + } + + // Call function for NanoBSD/Ramdisk processes. + pfb_aliastables("update"); + } else { + $log = "\nNo Changes to Aliases, Skipping pfctl Update \n"; + pfb_logger("{$log}","1"); + } + } + } + # UNSET Variables + unset($rules, $new_rules); + + #sync config + pfblockerng_sync_on_changes(); + + ################################# + # FINAL REPORTING # + ################################# + + # Only run with CRON or Force Invoked Process + if ((!$pfb['save'] && $pfb['dupcheck'] && $pfb['enable'] == "on") || $pfb['summary']) { + # Script to run Final Script Processes. + exec ("{$pfb['script']} closing {$pfb['dup']} >> {$pfb['log']} 2>&1"); + } + + if ($pfb['enable'] == "on" && !$pfb['save']) { + $log = "\n\n UPDATE PROCESS ENDED [ NOW ]\n"; + pfb_logger("{$log}","1"); + } + + + ######################################### + # Define/Apply CRON Jobs # + ######################################### + + # Clear any existing pfBlockerNG Cron Jobs + install_cron_job("pfblockerng.php cron", false); + + # Replace Cron job with any User Changes to $pfb_min + if ($pfb['enable'] == "on") { + # Define pfBlockerNG CRON Job + $pfb_cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php cron >> {$pfb['log']} 2>&1"; + # $pfb['min'] ( User Defined Variable. Variable defined at start of Script ) + $pfb_hour = "*"; + $pfb_mday = "*"; + $pfb_month = "*"; + $pfb_wday = "*"; + $pfb_who = "root"; + + install_cron_job($pfb_cmd, true, $pfb['min'], $pfb_hour, $pfb_mday, $pfb_month, $pfb_wday, $pfb_who); + } + + # Clear any existing pfBlockerNG MaxMind CRON Job + install_cron_job("pfblockerng.php dc", false); + + if ($pfb['enable'] == "on") { + # Define pfBlockerNG MaxMind CRON Job + $pfb_gcmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php dc >> {$pfb['geolog']} 2>&1"; + + # MaxMind GeoIP Cron Hour is randomized between 0-23 Hour to minimize effect on MaxMind Website + + $pfb_gmin = "0"; + $pfb_ghour = rand(0,23); + $pfb_gmday = "1,2,3,4,5,6,7"; + $pfb_gmonth = "*"; + $pfb_gwday = "2"; + $pfb_gwho = "root"; + + install_cron_job($pfb_gcmd, true, $pfb_gmin, $pfb_ghour, $pfb_gmday, $pfb_gmonth, $pfb_gwday, $pfb_gwho); + } +} + + +function pfblockerng_validate_input($post, &$input_errors) { + global $config; + foreach ($post as $key => $value) { + if (empty($value)) + continue; + if ($key == "message_size_limit" && !is_numeric($value)) + $input_errors[] = "Message size limit must be numeric."; + if ($key == "process_limit" && !is_numeric($value)) + $input_errors[] = "Process limit must be numeric."; + if ($key == "freq" && (!preg_match("/^\d+(h|m|d)$/",$value) || $value == 0)) + $input_errors[] = "A valid number with a time reference is required for the field 'Frequency'"; + if (substr($key, 0, 2) == "dc" && !is_hostname($value)) + $input_errors[] = "{$value} is not a valid host name."; + if (substr($key, 0, 6) == "domain" && is_numeric(substr($key, 6))) { + if (!is_domain($value)) + $input_errors[] = "{$value} is not a valid domain name."; + } else if (substr($key, 0, 12) == "mailserverip" && is_numeric(substr($key, 12))) { + if (empty($post['domain' . substr($key, 12)])) + $input_errors[] = "Domain for {$value} cannot be blank."; + if (!is_ipaddr($value) && !is_hostname($value)) + $input_errors[] = "{$value} is not a valid IP address or host name."; + } + } +} + + +function pfblockerng_php_install_command() { + require_once("/usr/local/www/pfblockerng/pfblockerng.php"); + 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. + @rename("{$pfb['dbdir']}/countrycodes.tar.bz2", "{$pfb['ccdir']}/countrycodes.tar.bz2"); + 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"); + + 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(); + update_output_window(gettext("Creating pfBlockerNG Continenet XML Files...")); + 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'])) { + // Restore previous Widget setting if "Keep" is enabled. + $config['widgets']['sequence'] = $pfb['widgets']; + } else { + $widgets = $config['widgets']['sequence']; + if (!preg_match("/pfblockerng-container/", $widgets)) { + if (empty($widgets)) { + $config['widgets']['sequence'] = "pfblockerng-container:col2:show"; + } else { + $config['widgets']['sequence'] .= ",pfblockerng-container:col2:show"; + } + } + } +} + + +function pfblockerng_php_deinstall_command() { + require_once("config.inc"); + global $config,$pfb; + + # Set these two variables to Disable pfBlockerNG on De-Install + $pfb['save'] = TRUE; + $pfb['install'] = TRUE; + sync_package_pfblockerng(); + rmdir_recursive("/usr/local/pkg/pfblockerng"); + rmdir_recursive("/usr/local/www/pfblockerng"); + + # Maintain pfBlockerNG Settings and Database Files if $pfb['keep'] is ON. + if ($pfb['keep'] != "on") { + # Remove pfBlockerNG Log and DB Folder + rmdir_recursive("{$pfb['dbdir']}"); + rmdir_recursive("{$pfb['logdir']}"); + + // Remove Aliastables archive and earlyshellcmd if found. + @unlink_if_exists("{$pfb['aliasarchive']}"); + if (is_array($config['system']['earlyshellcmd'])) { + $a_earlyshellcmd = &$config['system']['earlyshellcmd']; + if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { + $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); + } + } + + # Remove Settings from Config + if (is_array($config['installedpackages']['pfblockerng'])) + unset($config['installedpackages']['pfblockerng']); + if (is_array($config['installedpackages']['pfblockerngglobal'])) + unset($config['installedpackages']['pfblockerngglobal']); + if (is_array($config['installedpackages']['pfblockerngsync'])) + unset($config['installedpackages']['pfblockerngsync']); + if (is_array($config['installedpackages']['pfblockerngreputation'])) + unset($config['installedpackages']['pfblockerngreputation']); + if (is_array($config['installedpackages']['pfblockernglistsv4'])) + unset($config['installedpackages']['pfblockernglistsv4']); + if (is_array($config['installedpackages']['pfblockernglistsv6'])) + unset($config['installedpackages']['pfblockernglistsv6']); + if (is_array($config['installedpackages']['pfblockerngafrica'])) + unset($config['installedpackages']['pfblockerngafrica']); + if (is_array($config['installedpackages']['pfblockerngantartica'])) + unset($config['installedpackages']['pfblockerngantartica']); + if (is_array($config['installedpackages']['pfblockerngasia'])) + unset($config['installedpackages']['pfblockerngasia']); + if (is_array($config['installedpackages']['pfblockerngeurope'])) + unset($config['installedpackages']['pfblockerngeurope']); + if (is_array($config['installedpackages']['pfblockerngnorthamerica'])) + unset($config['installedpackages']['pfblockerngnorthamerica']); + if (is_array($config['installedpackages']['pfblockerngoceania'])) + unset($config['installedpackages']['pfblockerngoceania']); + if (is_array($config['installedpackages']['pfblockerngsouthamerica'])) + 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) + $pfb['widgets'] = $config['widgets']['sequence']; + if (!empty($pfb['widgets'])) { + $widgetlist = explode(",", $pfb['widgets']); + foreach ($widgetlist as $key => $widget) { + if (strstr($widget, "pfblockerng-container")) { + unset($widgetlist[$key]); + break; + } + } + $config['widgets']['sequence'] = implode(",", $widgetlist); + } + update_output_window(gettext("pfBlockerNG has been Uninstalled")); +} + +/* Uses XMLRPC to synchronize the changes to a remote node */ +function pfblockerng_sync_on_changes() { + global $config, $g, $pfb_sync; + + // Create Array of Sync Settings and exit if Sync is Disabled. + if (is_array($config['installedpackages']['pfblockerngsync']['config'][0])) { + $pfb_sync = $config['installedpackages']['pfblockerngsync']['config'][0]; + if ($pfb_sync['varsynconchanges'] == "disabled" || $pfb_sync['varsynconchanges'] == "") + return; + + $synctimeout = $pfb_sync['varsynctimeout']; + } else { + return; + } + + log_error("[pfBlockerNG] XMLRPC sync is starting."); + + if (is_array($config['installedpackages']['pfblockerngsync']['config'])) { + switch ($pfb_sync['varsynconchanges']) { + case "manual": + if (is_array($pfb_sync[row])) { + $rs = $pfb_sync[row]; + } else { + log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured."); + return; + } + break; + case "auto": + if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){ + $system_carp = $config['installedpackages']['carpsettings']['config'][0]; + $rs[0]['varsyncipaddress'] = $system_carp['synchronizetoip']; + $rs[0]['varsyncusername'] = $system_carp['username']; + $rs[0]['varsyncpassword'] = $system_carp['password']; + + // XMLRPC sync is currently only supported over connections using the same protocol and port as this system + if ($config['system']['webgui']['protocol'] == "http") { + $rs[0]['varsyncprotocol'] = "http"; + } else { + $rs[0]['varsyncprotocol'] = "https"; + } + + if ($system_carp['synchronizetoip'] == "") { + log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured."); + return; + } + } else { + log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured."); + return; + } + break; + default: + return; + break; + } + if (is_array($rs)) { + foreach ($rs as $sh) { + // Only Sync Enabled Replication Targets + if ($sh['varsyncdestinenable'] == "ON") { + $sync_to_ip = $sh['varsyncipaddress']; + $port = $sh['varsyncport']; + $password = htmlspecialchars($sh['varsyncpassword']); + $protocol = $sh['varsyncprotocol']; + + if (!empty($sh['varsyncusername'])) { + $username = $sh['varsyncusername']; + } else { + $username = "admin"; + } + + pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout); + } + } + if ($success) + log_error("[pfBlockerNG] XMLRPC sync completed successfully."); + } + } +} + + +/* Do the actual XMLRPC sync */ +function pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout) { + global $config, $g, $pfb_sync; + $success = TRUE; + + /* Exit on missing parameters */ + if (empty($sync_to_ip) || empty($password)) { + log_error("[pfBlockerNG] XMLRPC sync parameter missing (host IP or password) ... aborting xmlrpc sync"); + $success = FALSE; + return $success; + } + + /* Do not attempt a package sync while booting up or installing package */ + if ($g['booting'] || $g['pfblockerng_postinstall']) { + log_error("[pfBlockerNG] XMLRPC sync to Replication targets terminated during boot up or during package reinstallation."); + $success = FALSE; + return $success; + } + + // Validate Replication Target IP Address and Port Settings + if (!is_ipaddr($sync_to_ip) || !is_port($port)) { + log_error("[pfBlockerNG] XMLRPC sync terminated due to mis-configured Replication Target IP Address or Port settings."); + $success = FALSE; + return $success; + } + + /* Test key variables and set defaults if empty */ + if (empty($synctimeout)) + $synctimeout = 150; + + $url = "{$protocol}://{$sync_to_ip}"; + + if ($port == "") { $port = $config['system']['webgui']['port']; }; + /* If port is empty lets rely on the protocol selection */ + if ($port == "") { + if ($config['system']['webgui']['protocol'] == "http") { + $port = "80"; + } else { + $port = "443"; + } + } + /* xml will hold the sections to sync */ + $xml = array(); + // If User Disabled, remove 'General Tab Customizations' from Sync + if ($config['installedpackages']['pfblockerngsync']['config'][0]['syncinterfaces'] == "") + $xml['pfblockerng'] = $config['installedpackages']['pfblockerng']; + $xml['pfblockerngreputation'] = $config['installedpackages']['pfblockerngreputation']; + $xml['pfblockernglistsv4'] = $config['installedpackages']['pfblockernglistsv4']; + $xml['pfblockernglistsv6'] = $config['installedpackages']['pfblockernglistsv6']; + $xml['pfblockerngtopspammers'] = $config['installedpackages']['pfblockerngtopspammers']; + $xml['pfblockerngafrica'] = $config['installedpackages']['pfblockerngafrica']; + $xml['pfblockerngantartica'] = $config['installedpackages']['pfblockerngantartica']; + $xml['pfblockerngasia'] = $config['installedpackages']['pfblockerngasia']; + $xml['pfblockerngeurope'] = $config['installedpackages']['pfblockerngeurope']; + $xml['pfblockerngnorthamerica'] = $config['installedpackages']['pfblockerngnorthamerica']; + $xml['pfblockerngoceania'] = $config['installedpackages']['pfblockerngoceania']; + $xml['pfblockerngsouthamerica'] = $config['installedpackages']['pfblockerngsouthamerica']; + $xml['pfblockerngproxyandsatellite'] = $config['installedpackages']['pfblockerngproxyandsatellite']; + + /* assemble xmlrpc payload */ + $params = array( + XML_RPC_encode($password), + XML_RPC_encode($xml) + ); + + /* set a few variables needed for sync code borrowed from filter.inc */ + log_error("[pfBlockerNG] XMLRPC syncing to {$url}:{$port}."); + $method = 'pfsense.merge_installedpackages_section_xmlrpc'; + $msg = new XML_RPC_Message($method, $params); + $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); + $cli->setCredentials($username, $password); + if ($g['debug']) { + $cli->setDebug(1); + } + + /* send our XMLRPC message and timeout after defined sync timeout value */ + $resp = $cli->send($msg, $synctimeout); + $error = ""; + if (!$resp) { + log_error("[pfBlockerNG] XMLRPC communications error occurred while attempting sync with {$url}:{$port}."); + file_notice("sync_settings", $error, "pfBlockerNG Settings Sync", ""); + $success = FALSE; + return $success; + } elseif ($resp->faultCode()) { + $cli->setDebug(1); + $resp = $cli->send($msg, $synctimeout); + log_error("[pfBlockerNG] XMLRPC Error received while attempting sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString()); + file_notice("sync_settings", $error, "pfBlockerNG Settings Sync", ""); + $success = FALSE; + return $success; + } else { + log_error("[pfBlockerNG] XMLRPC sync successfully completed with {$url}:{$port}."); + } + return $success; +} +?> \ No newline at end of file -- cgit v1.2.3 From 2cab177606c166b66b0040db866749630de9240b Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Sun, 22 Feb 2015 19:55:09 -0500 Subject: pfBlockerNG - Remove bak file again! !!!! Remove bak file added by fat fingers!!!! --- config/pfblockerng/pfblockerng.inc.bak | 2701 -------------------------------- 1 file changed, 2701 deletions(-) delete mode 100644 config/pfblockerng/pfblockerng.inc.bak diff --git a/config/pfblockerng/pfblockerng.inc.bak b/config/pfblockerng/pfblockerng.inc.bak deleted file mode 100644 index da5a5261..00000000 --- a/config/pfblockerng/pfblockerng.inc.bak +++ /dev/null @@ -1,2701 +0,0 @@ - /tmp/pfblog; /bin/mv -f /tmp/pfblog {$pfb['log']}"); - } -} - - -# Record Log Messsages to pfBlockerNG Log File and/or Error Log File. -function pfb_logger($log, $type) { - global $g,$pfb,$pfbarr; - - $now = date("m/d/y G:i:s", time()); - - # Only log timestamp if new - if (preg_match("/NOW/", $log)) { - if ($now == $pfb['pnow']) { - $log = str_replace("[ NOW ]", "", "{$log}"); - } else { - $log = str_replace("NOW", $now, "{$log}"); - } - $pfb['pnow'] = "{$now}"; - } - - if ($type == 2) { - @file_put_contents("{$pfb['log']}", "{$log}", FILE_APPEND); - @file_put_contents("{$pfb['errlog']}", "{$log}", FILE_APPEND); - } elseif ($type == 3) { - @file_put_contents("{$pfb['geolog']}", "{$log}", FILE_APPEND); - } else { - @file_put_contents("{$pfb['log']}", "{$log}", FILE_APPEND); - } -} - - -# Determine Folder Location for 'List' -function pfb_determine_list_detail($list) { - global $g,$pfb,$pfbarr; - $pfbarr = array(); - - if (in_array($list,array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { - $pfbarr['skip'] = FALSE; - $pfbarr['folder'] = "{$pfb['matchdir']}"; - } elseif (in_array($list,array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) { - $pfbarr['skip'] = FALSE; - $pfbarr['folder'] = "{$pfb['permitdir']}"; - } elseif ($list == "Alias_Native") { - $pfbarr['skip'] = FALSE; - $pfbarr['folder'] = "{$pfb['nativedir']}"; - } else { - # Deny - $pfbarr['skip'] = TRUE; - $pfbarr['folder'] = "{$pfb['denydir']}"; - } - - // Collect proper Alias Table Description (Alias Only vs AutoRules) - if (preg_match("/Alias/", $list)) { - $pfbarr['descr'] = ""; - } else { - $pfbarr['descr'] = " Auto "; - } - - return $pfbarr; -} - -# Create Suppression Alias -function pfb_create_suppression_alias() { - global $config; - - // Collect existing pfsense alias(s) - if (is_array($config['aliases']['alias'])) { - foreach($config['aliases']['alias'] as $exalias) { - $new_aliases[] = $exalias; - } - } - // Create New pfBlockerNGSuppress Alias - $new_aliases[] = array( "name" => "pfBlockerNGSuppress", - "address" => "", - "descr" => "pfBlockerNG Suppression List (24|32 CIDR only)", - "type" => "network", - "detail" => "" - ); - $config['aliases']['alias'] = $new_aliases; - write_config(); -} - - -# Create Suppression file from Alias -function pfb_create_suppression_file() { - global $config,$pfb; - - // Find pfBlockerNGSuppress Array ID Number - $pfb['found'] = FALSE; - if (is_array($config['aliases']['alias'])) { - $pfb_id = 0; - foreach ($config['aliases']['alias'] as $alias) { - if ($alias['name'] == "pfBlockerNGSuppress") { - $pfb['found'] = TRUE; - break; - } - $pfb_id++; - } - - if ($pfb['found']) { - $pfb_suppress = str_replace(" ", "\n", $config['aliases']['alias'][$pfb_id]['address']); - if (!empty($pfb_suppress)) - @file_put_contents("{$pfb['supptxt']}",$pfb_suppress, LOCK_EX); - } else { - # Delete Suppression File if Alias is Empty. - unlink_if_exists("{$pfb['supptxt']}"); - } - } - - // Call Function to Create Suppression Alias. - if (!$pfb['found']) - pfb_create_suppression_alias(); -} - - -// 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; -} - - -// Archive Aliastables for NanoBSD and RAMDisk Installations -function pfb_aliastables($mode) { - global $g,$config,$pfb; - $earlyshellcmd = "/usr/local/pkg/pfblockerng/pfblockerng.sh aliastables"; - $msg = ""; - - // Only Execute function if Platform is NanoBSD or Ramdisks are used. - if (($g['platform'] != "pfSense") || isset($config['system']['use_mfs_tmpvar'])) { - conf_mount_rw(); - if ($mode == "update") { - // Archive Aliastable Folder - exec ("cd {$pfb['aliasdir']}; ls -A pfB_*.txt && /usr/bin/tar -jcvf {$pfb['aliasarchive']} pfB_*.txt >/dev/null 2>&1"); - $msg = "\n\nArchiving Aliastable Folder\n"; - } - elseif ($mode == "conf") { - // Check conf file for earlyshellcmd - if (is_array($config['system']['earlyshellcmd'])) { - $a_earlyshellcmd = &$config['system']['earlyshellcmd']; - if (!preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { - $a_earlyshellcmd[] = "{$earlyshellcmd}"; - $msg = "\n** Adding earlyshellcmd **\n"; - } - } - else { - $config['system']['earlyshellcmd'] = "{$earlyshellcmd}"; - $msg = "\n** Adding earlyshellcmd **\n"; - } - } - conf_mount_ro(); - } - else { - if (file_exists("{$pfb['aliasarchive']}")) { - // Remove Aliastables archive if found. - conf_mount_rw(); - @unlink_if_exists("{$pfb['aliasarchive']}"); - conf_mount_ro(); - } - // Remove earlyshellcmd if found. - if (is_array($config['system']['earlyshellcmd'])) { - $a_earlyshellcmd = &$config['system']['earlyshellcmd']; - if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { - $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); - $msg = "\n** Removing earlyshellcmd **\n"; - } - } - } - - if ($msg != "") - pfb_logger("{$msg}","1"); -} - - -# Main pfBlockerNG Function -function sync_package_pfblockerng($cron = "") { - - global $g,$config,$pfb,$pfbarr; - pfb_global(); - - # Detect Boot Process or Update via CRON - if (isset($_POST) && $cron == "") { - if (!preg_match("/\w+/",$_POST['__csrf_magic'])) { - log_error("[pfBlockerNG] Sync terminated during boot process."); - return; - } - } - log_error("[pfBlockerNG] Starting sync process."); - - // Force Update - Set 'Save' variable when 'No Updates' found. - if ($cron == "noupdates") { - $pfb['save'] = TRUE; - } - - # Start of pfBlockerNG Logging to 'pfblockerng.log' - if ($pfb['enable'] == "on" && !$pfb['save']) { - $log = " UPDATE PROCESS START [ NOW ]\n"; - pfb_logger("{$log}","1"); - } else { - if ($cron != "noupdates") { - $log = "\n**Saving Configuration [ NOW ] ...\n"; - pfb_logger("{$log}","1"); - } - } - - // Call function for NanoBSD/Ramdisk processes. - pfb_aliastables("conf"); - - # Collect pfSense Max Table Size Entry - $pfb['table_limit'] = ($config['system']['maximumtableentries'] != "" ? $config['system']['maximumtableentries'] : "2000000"); - - # If Table limit not defined, set Default to 2M - $config['system']['maximumtableentries'] = "{$pfb['table_limit']}"; - - # Collect local web gui configuration - $pfb['weblocal'] = ($config['system']['webgui']['protocol'] != "" ? $config['system']['webgui']['protocol'] : "http"); - $pfb['port'] = $config['system']['webgui']['port']; - if ($pfb['port'] == "") { - if ($config['system']['webgui']['protocol'] == "http") { - $pfb['port'] = "80"; - } else { - $pfb['port'] = "443"; - } - } - $pfb['weblocal'] .= "://127.0.0.1:{$pfb['port']}/pfblockerng/pfblockerng.php"; - - # Define Inbound/Outbound Action is not user selected. - $pfb['deny_action_inbound'] = ($pfb['config']['inbound_deny_action'] != "" ? $pfb['config']['inbound_deny_action'] : "block"); - $pfb['deny_action_outbound'] = ($pfb['config']['outbound_deny_action'] != "" ? $pfb['config']['outbound_deny_action'] : "reject"); - - # Validation check to see if the Original pfBlocker package is Enabled - $pfb['validate']= $pfb['config']['pfblocker_cb']; - # User Defined CRON Start Minute - $pfb['min'] = $pfb['config']['pfb_min']; - # Reloads Existing Blocklists without Downloading New Lists - $pfb['reuse'] = $pfb['config']['pfb_reuse']; - # Enable OpenVPN AutoRules - $pfb['openvpn'] = $pfb['config']['openvpn_action']; - # Enable/Disable Floating Auto-Rules - $pfb['float'] = $pfb['config']['enable_float']; - # Enable Remove of Duplicate IPs utilizing Grepcidr - $pfb['dup'] = $pfb['config']['enable_dup']; - # Order of the Auto-Rules - $pfb['order'] = $pfb['config']['pass_order']; - # Suffix used for Auto-Rules - $pfb['suffix'] = $pfb['config']['autorule_suffix']; - - # Reputation Variables - $pfb['config_rep'] = $config['installedpackages']['pfblockerngreputation']['config'][0]; - - # Enable/Disable Reputation - $pfb['rep'] = $pfb['config_rep']['enable_rep']; - # Enable/Disable 'pDup' - $pfb['pdup'] = $pfb['config_rep']['enable_pdup']; - # Enable/Disable 'dDup' - $pfb['dedup'] = ($pfb['config_rep']['enable_dedup'] != "" ? $pfb['config_rep']['enable_dedup'] : "x"); - # 'Max' variable setting for Reputation - $pfb['max'] = ($pfb['config_rep']['p24_max_var'] != "" ? $pfb['config_rep']['p24_max_var'] : "x"); - # 'dMax' variable setting for Reputation - $pfb['dmax'] = ($pfb['config_rep']['p24_dmax_var'] != "" ? $pfb['config_rep']['p24_dmax_var'] : "x"); - # 'pMax' variable setting for Reputation - $pfb['pmax'] = ($pfb['config_rep']['p24_pmax_var'] != "" ? $pfb['config_rep']['p24_pmax_var'] : "x"); - # Action for Whitelist Country Category - $pfb['ccwhite'] = $pfb['config_rep']['ccwhite']; - # Action for Blacklist Country Category - $pfb['ccblack'] = $pfb['config_rep']['ccblack']; - # List of Countries in the Whitelist Category - $pfb['ccexclude']= ($pfb['config_rep']['ccexclude'] != "" ? $pfb['config_rep']['ccexclude'] : "x"); - # Emerging Threats IQRisk Block Categories - $pfb['etblock'] = ($pfb['config_rep']['etblock'] != "" ? $pfb['config_rep']['etblock'] : "x"); - # Emerging Threats IQRisk Match Categories - $pfb['etmatch'] = ($pfb['config_rep']['etmatch'] != "" ? $pfb['config_rep']['etmatch'] : "x"); - # Perform a Force Update on ET Categories - $pfb['etupdate']= $pfb['config_rep']['et_update']; - - # Variables - - # Starting Variable to Skip rep, pdup and dedeup functions if no changes are required - $pfb['dupcheck'] = FALSE; - ## $pfb['save'] is used to determine if User pressed "Save" Button to avoid Collision with CRON. - ## This is defined in each pfBlockerNG XML Files - - # Validation Check to ensure pfBlocker and pfBlockerNG are not running at the same time. - if ($pfb['validate'] == "") { - # Collect pfBlocker Enabled Status from config file - $pfb['validate_chk'] = $config['installedpackages']['pfblocker']['config'][0]['enable_cb']; - if ($pfb['validate_chk'] == "on") { - $log = "\n The Package 'pfBlocker' is currently Enabled. Either Disable pfBlocker, or 'Disable Validation Check' in pfBlockerNG \n"; - pfb_logger("{$log}","1"); - return; - } - } - - - ################################# - # 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", - "Proxy and Satellite" => "pfB_PS" - ); - - #create rules vars and arrays - # Array used to Collect Changes to Aliases to be saved to Config - $new_aliases = array(); - $new_aliases_list = array(); - $continent_existing = array(); - $continent_new = array(); - $permit_inbound = array(); - $permit_outbound = array(); - $deny_inbound = array(); - $deny_outbound = array(); - # An Array of all Aliases (Active and non-Active) - $aliases_list = array(); - # This is an Array of Aliases that Have Updated Lists via CRON/Force Update when 'Reputation' disabled. - $pfb_alias_lists = array(); - # This is an Array of All Active Aliases used when 'Reputation' enabled - $pfb_alias_lists_all = array(); - - # Base Rule Array - $base_rule_reg = array( "id" => "", - "tag" => "", - "tagged" => "", - "max" => "", - "max-src-nodes" => "", - "max-src-conn" => "", - "max-src-states"=> "", - "statetimeout" => "", - "statetype" => "keep state", - "os" => "" - ); - - # Floating Rules, Base Rule Array - $base_rule_float = array("id" => "", - "tag" => "", - "tagged" => "", - "quick" => "yes", - "floating" => "yes", - "max" => "", - "max-src-nodes" => "", - "max-src-conn" => "", - "max-src-states"=> "", - "statetimeout" => "", - "statetype" => "keep state", - "os" => "" - ); - - - ######################################### - # Configure Rule Suffix # - ######################################### - - # Discover if any Rules are AutoRules (If no AutoRules found, $pfb['autorules'] is FALSE, Skip Rules Re-Order ) - # To configure Auto Rule Suffix. pfBlockerNG must be disabled to change Suffix and to avoid Duplicate Rules - $pfb['autorules'] = FALSE; - $pfb['found'] = FALSE; - foreach ($continents as $continent => $pfb_alias) { - if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'])) { - $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0]; - if ($continent_config['action'] != "Disabled" && in_array($continent_config['action'],array('Deny_Both','Deny_Inbound','Deny_Outbound','Match_Both','Match_Inbound','Match_Outbound','Permit_Both','Permit_Inbound','Permit_Outbound'))) { - $pfb['autorules'] = TRUE; - $pfb['found'] = TRUE; - break; - } - } - } - - $list_type = array ("pfblockernglistsv4", "pfblockernglistsv6"); - foreach ($list_type as $ip_type) { - if ($config['installedpackages'][$ip_type]['config'] != "" && !$pfb['found']) { - foreach($config['installedpackages'][$ip_type]['config'] as $list) { - if ($list['action'] != "Disabled" && in_array($list['action'],array('Deny_Both','Deny_Inbound','Deny_Outbound','Match_Both','Match_Inbound','Match_Outbound','Permit_Both','Permit_Inbound','Permit_Outbound'))) { - $pfb['autorules'] = TRUE; - break; - } - } - } - } - - #Configure Auto Rule Suffix. pfBlockerNG must be disabled to change Suffix and to avoid Duplicate Rules - # Count Number of Rules with 'pfB_' - $count = 0; - if (is_array($config['filter']['rule'])) { - foreach ($config['filter']['rule'] as $rule) { - # Collect any pre-existing Suffix - if (preg_match("/pfB_\w+(\s.*)/",$rule['descr'], $pfb_suffix_real) && $count == 0) { - $pfb_suffix_match = $pfb_suffix_real[1]; - } - # Query for Existing pfB Rules - if (preg_match("/pfB_/",$rule['descr'])) { - $count++; - break; - } - } - } - - # Change Suffix only if No pfB Rules Found and Auto Rules are Enabled. - if ($pfb['autorules'] && $count == 0) { - switch ($pfb['suffix']) { - case "autorule": - $pfb['suffix'] = " auto rule"; - break; - case "standard": - $pfb['suffix'] = ""; - break; - case "ar": - $pfb['suffix'] = " AR"; - break; - } - } else { - if ($pfb['autorules']) { - # Use existing Suffix Match - $pfb['suffix'] = $pfb_suffix_match; - } else { - # Leave Rule Suffix 'Blank' - $pfb['suffix'] = ""; - } - } - - - ######################################################### - # Configure INBOUND/OUTBOUND INTERFACES # - ######################################################### - - # Collect pfSense Interface Order - $ifaces = get_configured_interface_list(); - - if (!empty($pfb['config']['inbound_interface'])) { - # Sort Interface Array to match pfSense Interface order to allow Floating Rules to populate. - $selected_interfaces = explode(",",$pfb['config']['inbound_interface']); - # Sort pfBlockerNG Interface order to pfSense Interface Order - $sort_interfaces = array_intersect($ifaces, $selected_interfaces); - $implode_interfaces = ltrim(implode(",",$sort_interfaces), ","); - # CSV String for Inbound Interfaces for 'pfB_' Match Rules - $pfb['inbound_floating'] = $implode_interfaces; - $pfb['inbound_interfaces_float'] = explode(" ",$implode_interfaces); - - # Assign Inbound Base Rule/Interfaces - if ($pfb['float'] == "on") { - # Define Base Firewall Floating Rules Settings - $base_rule = $base_rule_float; - $pfb['inbound_interfaces'] = $pfb['inbound_interfaces_float']; - } else { - # Define Base Firewall Rules Settings - $base_rule = $base_rule_reg; - $pfb['inbound_interfaces'] = explode(",",$pfb['config']['inbound_interface']); - } - } else { - # Define Empty Variable/Array - $pfb['inbound_interfaces_float'] = ""; - $pfb['inbound_interfaces'] = array(); - } - - if (!empty($pfb['config']['outbound_interface'])) { - # Sort Interface Array to match pfSense Interface order to allow Floating Rules to populate. - $selected_interfaces = explode(",",$pfb['config']['outbound_interface']); - # Sort pfBlockerNG Interface order to pfSense Interface Order - $sort_interfaces = array_intersect($ifaces, $selected_interfaces); - // If OpenVPN Interfaces are not in dropdown menu - if ($pfb['openvpn'] == "on" && $config['openvpn']['openvpn-server'] || $pfb['openvpn'] == "on" && $config['openvpn']['openvpn-client']) - if (!in_array("openvpn",$sort_interfaces)) - array_push($sort_interfaces, "openvpn"); - $implode_interfaces = ltrim(implode(",",$sort_interfaces), ","); - # CSV String for Outbound Interfaces for 'pfB_' Match Rules - $pfb['outbound_floating'] = $implode_interfaces; - $pfb['outbound_interfaces_float'] = explode(" ",$implode_interfaces); - - # Assign Outbound Base Rule/Interfaces - if ($pfb['float'] == "on") { - $base_rule = $base_rule_float; - $pfb['outbound_interfaces'] = $pfb['outbound_interfaces_float']; - } else { - $base_rule = $base_rule_reg; - $pfb['outbound_interfaces'] = explode(",",$pfb['config']['outbound_interface']); - // If OpenVPN Interfaces are not in dropdown menu - if ($pfb['openvpn'] == "on" && $config['openvpn']['openvpn-server'] || $pfb['openvpn'] == "on" && $config['openvpn']['openvpn-client']) - if (!in_array("openvpn",$sort_interfaces)) - array_push($pfb['outbound_interfaces'], "openvpn"); - } - } else { - # Define Empty Variable/Array - $pfb['outbound_interfaces_float'] = ""; - $pfb['outbound_interfaces'] = array(); - } - - - ################################################# - # Clear Removed Lists from Masterfiles # - ################################################# - - # Process to keep Masterfiles in Sync with Valid Lists from config.conf file. - $pfb['sync_master'] = TRUE; - - # Don't execute this function when pfBlockerNG is Disabled and 'Keep Blocklists' is enabled. - if ($pfb['enable'] == "" && $pfb['keep'] == "on") - $pfb['sync_master'] = FALSE; - - if ($pfb['sync_master']) { - $pfb['existing']['match']['type'] = "match"; - $pfb['existing']['permit']['type'] = "permit"; - $pfb['existing']['deny']['type'] = "deny"; - $pfb['existing']['native']['type'] = "native"; - $pfb['existing']['match']['folder'] = "{$pfb['matchdir']}"; - $pfb['existing']['permit']['folder'] = "{$pfb['permitdir']}"; - $pfb['existing']['deny']['folder'] = "{$pfb['denydir']}"; - $pfb['existing']['native']['folder'] = "{$pfb['nativedir']}"; - $pfb['actual']['match']['type'] = "match"; - $pfb['actual']['permit']['type'] = "permit"; - $pfb['actual']['deny']['type'] = "deny"; - $pfb['actual']['native']['type'] = "native"; - $pfb['actual']['match']['folder'] = "{$pfb['matchdir']}"; - $pfb['actual']['permit']['folder'] = "{$pfb['permitdir']}"; - $pfb['actual']['deny']['folder'] = "{$pfb['denydir']}"; - $pfb['actual']['native']['folder'] = "{$pfb['nativedir']}"; - - // Find all Enabled Continents Lists - foreach ($continents as $continent => $pfb_alias) { - if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config']) && $pfb['enable'] == "on") { - $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0]; - if ($continent_config['action'] != "Disabled") { - $cont_type = array ("countries4" => "_v4", "countries6" => "_v6"); - foreach ($cont_type as $c_type => $vtype) { - if ($continent_config[$c_type] != "") { - # Set Parameters for 'Match', 'Permit', 'Native' and 'Deny' - if (in_array($continent_config['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { - $pfb['existing']['match'][] = "{$pfb_alias}{$vtype}"; - } elseif (in_array($continent_config['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))){ - $pfb['existing']['permit'][] = "{$pfb_alias}{$vtype}"; - } elseif ($continent_config['action'] == "Alias_Native") { - $pfb['existing']['native'][] = "{$pfb_alias}{$vtype}"; - } else { - $pfb['existing']['deny'][] = "{$pfb_alias}{$vtype},"; // Add Trailing ',' - } - } - } - } - } - } - - # Find all Enabled IPv4/IPv6 Lists - $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); - foreach ($list_type as $ip_type => $vtype) { - if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { - foreach ($config['installedpackages'][$ip_type]['config'] as $list) { - if (is_array($list['row']) && $list['action'] != "Disabled") { - foreach ($list['row'] as $row) { - if ($vtype == "_v4") { - $pfb_alias = "{$row['header']}"; - } else { - $pfb_alias = "{$row['header']}_v6"; - } - # Collect Enabled Lists - if ($row['url'] != "" && $row['state'] != "Disabled") { - # Set Parameters for 'Match', 'Permit', 'Native' and 'Deny' - if (in_array($list['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { - $pfb['existing']['match'][] = "{$pfb_alias}"; - } elseif (in_array($list['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) { - $pfb['existing']['permit'][] = "{$pfb_alias}"; - } elseif ($list['action'] == "Alias_Native") { - $pfb['existing']['native'][] = "{$pfb_alias}"; - } else { - $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ',' - } - } - } - } - } - } - } - - # Find all Enabled IPv4 'Custom List' Header Names and Check if 'Emerging Threats Update' and 'Custom List Update' Needs Force Updating - $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); - foreach ($list_type as $ip_type => $vtype) { - if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { - $count = -1; - foreach ($config['installedpackages'][$ip_type]['config'] as $list) { - if (is_array($list['row']) && $list['action'] != "Disabled") { - $count++; - # Check if 'Emerging Threats Update' Needs Updating before next CRON Event. - if (is_array($list['row']) && $row['state'] != "Disabled" && $pfb['etupdate'] == "enabled" && $vtype == "_v4") { - foreach ($list['row'] as $row) { - $aliasname = $row['header']; - if ($row['format'] == "et") { - unlink_if_exists("{$pfb['denydir']}/{$aliasname}.txt"); - $config['installedpackages']['pfblockerngreputation']['config'][0]['et_update'] = "disabled"; - break; - } - } - } - } - - # Collect Enabled Custom List Box Aliases - if (pfbng_text_area_decode($list['custom']) != "") { - if ($vtype == "_v4") { - $pfb_alias = "{$list['aliasname']}_custom"; - } else { - $pfb_alias = "{$list['aliasname']}_custom_v6"; - } - # Determine Folder Location for 'List' - if (in_array($list['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) { - $pfb['existing']['match'][] = "{$pfb_alias}"; - $pfbfolder = "{$pfb['matchdir']}"; - } elseif (in_array($list['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) { - $pfb['existing']['permit'][] = "{$pfb_alias}"; - $pfbfolder = "{$pfb['permitdir']}"; - } elseif ($list['action'] == "Alias_Native") { - $pfb['existing']['native'][] = "{$pfb_alias}"; - $pfbfolder = "{$pfb['nativedir']}"; - } else { - $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ',' - $pfbfolder = "{$pfb['denydir']}"; - } - # Determine if 'Custom List' Needs Force Updating before next CRON Event. - if ($list['custom_update'] == "enabled") { - unlink_if_exists("{$pfbfolder}/{$pfb_alias}.txt"); - # Uncheck 'Enabled' in List 'Custom_update' Setting - $config['installedpackages'][$ip_type]['config'][$count]['custom_update'] = "disabled"; - } - } - } - } - } - - # Collect all .txt file Names for each List Type - $list_types = array('match' => $pfb['matchdir'], 'permit' => $pfb['permitdir'], 'deny' => $pfb['denydir'], 'native' => $pfb['nativedir']); - foreach ($list_types as $type => $pfbfolder) { - $pfb_files = glob("$pfbfolder/*.txt"); - foreach ($pfb_files as $pfb_list) { - $pfb_file = basename($pfb_list,".txt"); - if ($type == "deny") { - $pfb['actual'][$type][] = "{$pfb_file},"; // Add Trailing ',' - } else { - $pfb['actual'][$type][] = "{$pfb_file}"; - } - } - } - - # Flag to execute pfctl and Rules Ordering - $pfb['remove'] = FALSE; - # Execute Final Summary as a List was Removed - $pfb['summary'] = FALSE; - - # Process to Remove Lists from Masterfile/DB Folder if they do not Exist - if (isset($pfb['existing'])) { - foreach ($pfb['existing'] as $pfb_exist) { - $existing_type = $pfb_exist['type']; - $pfbfolder = $pfb_exist['folder']; - foreach ($pfb['actual'] as $pfb_act) { - $actual_type = $pfb_act['type']; - if ($existing_type == $actual_type) { - switch ($existing_type) { - case "deny": - $results = array_diff($pfb_act, $pfb_exist); - $f_result = implode($results); - if ($f_result != "") { - $log = "[ Removing List(s) : {$f_result} ]\n"; - pfb_logger("{$log}","1"); - # Script to Remove un-associated Lists - exec ("{$pfb['script']} remove x x x {$f_result} >> {$pfb['log']} 2>&1"); - $pfb['summary'] = TRUE; - $pfb['remove'] = TRUE; - } - break; - case "match": - case "permit": - case "native": - $results = array_diff($pfb_act, $pfb_exist); - # This variable ($f_result) used in next section below. - $f_result = implode($results); - if (!empty($results)) { - foreach ($results as $pfb_results) { - $log = "[ Removing List(s) : {$pfb_results} ]\n"; - pfb_logger("{$log}","1"); - unlink_if_exists("{$pfbfolder}/{$pfb_results}.txt"); - } - $pfb['summary'] = TRUE; - $pfb['remove'] = TRUE; - } - break; - } - - # Allow Rebuilding of Changed Aliase to purge 'SKIP' Lists (when pfBlockerNG is Enabled) - $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); - foreach ($list_type as $ip_type => $vtype) { - if ($f_result != "" && $pfb['enable'] == "on") { - foreach ($results as $removed_header) { - if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { - foreach ($config['installedpackages'][$ip_type]['config'] as $list) { - $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']); - if (is_array($list['row'])) { - foreach ($list['row'] as $row) { - $removed = rtrim($removed_header, ','); - if ($row['header'] == $removed) { - $pfb['summary'] = TRUE; - $pfb['remove'] = TRUE; - # Add Alias to Update Array - $pfb_alias_lists[] = "{$alias}"; - $pfb_alias_lists_all[] = "{$alias}"; - } - } - } - } - } - } - } - } - } - } - } - } - } - - ######################################################### - # Clear Match/Pass/ET/Original Files/Folders # - ######################################################### - - # When pfBlockerNG is Disabled and 'Keep Blocklists' is Disabled. - if ($pfb['enable'] == "" && $pfb['keep'] == "" && !$pfb['install']) { - $log = "\n Removing DB Files/Folders \n"; - pfb_logger("{$log}","1"); - - unlink_if_exists("{$pfb['dbdir']}/masterfile"); - unlink_if_exists("{$pfb['dbdir']}/mastercat"); - unlink_if_exists("{$pfb['supptxt']}"); - rmdir_recursive("{$pfb['origdir']}"); - rmdir_recursive("{$pfb['matchdir']}"); - rmdir_recursive("{$pfb['permitdir']}"); - rmdir_recursive("{$pfb['denydir']}"); - rmdir_recursive("{$pfb['nativedir']}"); - rmdir_recursive("{$pfb['etdir']}"); - } - - - ######################################### - # Create Suppression Txt File # - ######################################### - - if ($pfb['enable'] == "on" && $pfb['supp'] == "on") - pfb_create_suppression_file(); - - - ################################# - # Assign Countries # - ################################# - - foreach ($continents as $continent => $pfb_alias) { - if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'])) { - $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0]; - if ($continent_config['action'] != "Disabled" && $pfb['enable'] == "on") { - - # Determine Folder Location for Alias (return array $pfbarr) - pfb_determine_list_detail($continent_config['action']); - $pfb['skip'] = $pfbarr['skip']; - $pfb_descr = $pfbarr['descr']; - $pfbfolder = $pfbarr['folder']; - - // Determine if Continent Lists require Action (IPv4 and IPv6) - $cont_type = array ("countries4" => "_v4", "countries6" => "_v6"); - foreach ($cont_type as $c_type => $vtype) { - - $continent = ""; - if ($continent_config[$c_type] != "") { - - // Collect Selected ISO Country Files - foreach (explode(",", $continent_config[$c_type]) as $iso) { - if ($iso != "" && file_exists($pfb['ccdir'] .'/' . $iso . $vtype . '.txt')) { - $continent .= file_get_contents ($pfb['ccdir'] . '/' . $iso . $vtype . '.txt'); - } - } - - if (file_exists($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig')) - $continent_existing = preg_replace('/\s/', '', file ($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig')); - - // Collect New Continent Data for comparison. Cleanup Array for Comparison - $continent_new = preg_split ('/$\R?^/m', $continent); - $line = count ( $continent_new ) - 1; - $match = $continent_new[$line]; - $continent_new[$line] = rtrim($match, "\n"); - - # Check if pfBlockerNG pfctl Continent Tables are Empty (pfBlockerNG was Disabled w/ "keep", then Re-enabled) - $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$pfb_alias}{$vtype} | awk '/Addresses/ {s+=$2}; END {print s}'"); - if (empty($pfctlck) && file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt')) { - $file_cont = file_get_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt'); - @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$file_cont, LOCK_EX); - # PFCTL - Update Only Aliases that have been updated. ('Reputation' Disabled) - $pfb_alias_lists[] = "{$pfb_alias}{$vtype}"; - } - - # Collect Active Alias Lists (Used for pfctl Update when 'Reputation' is enabled). - $pfb_alias_lists_all[] = "{$pfb_alias}{$vtype}"; - - // Compare Existing (Original File) and New Continent Data - if ($continent_new === $continent_existing && !empty($pfctlck) && file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt') && $pfb['reuse'] == "") { - # Format Log into clean Tab Spaces - $string_final = "{$pfb_alias}{$vtype}"; - if (strlen($string_final) > 10) { - $log_tab = "\t"; - } else { - $log_tab = "\t\t"; - } - - if (!$pfb['save']) { - $log = "\n[ {$pfb_alias}{$vtype} ] {$log_tab} exists, Reloading File [ NOW ]\n"; - pfb_logger("{$log}","1"); - } - } else { - // Do not proceed with Changes on User 'Save' - if (!$pfb['save']) { - $log = "\n[ {$pfb_alias}{$vtype} ] {$log_tab} Changes Found... Updating \n"; - pfb_logger("{$log}","1"); - - # Test to Skip d-dup and p-dup functions when changes are found. - $pfb['dupcheck'] = TRUE; - - $pfb_alias_lists[] = "{$pfb_alias}{$vtype}"; - - // Script to call Duplication Check Process only on IPv4 - if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") { - // Copy Continent Data to 'lists' folder for duplication processing - @file_put_contents($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig',$continent, LOCK_EX); - @file_put_contents($pfb['denydir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); - exec ("{$pfb['script']} continent {$pfb_alias}{$vtype} >> {$pfb['log']} 2>&1"); - $continent = file_get_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt'); - @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); - } else { - @file_put_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); - @file_put_contents($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig',$continent, LOCK_EX); - @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX); - } - - # Check if File Exists and is >0 in Size and Save alias file - $file_chk = "0"; - $cont_chk = "{$pfbfolder}/{$pfb_alias}{$vtype}.txt"; - if (file_exists($cont_chk) && @filesize($cont_chk) >0) - $file_chk = exec ("/usr/bin/grep -cv '^#\|^$' {$cont_chk}"); - - if ($file_chk == "0" || $file_chk == "1") { - $new_file = "1.1.1.1\n"; - @file_put_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt', $new_file, LOCK_EX); - @file_put_contents($pfb['aliasdir'] . "/" . $pfb_alias . $vtype . ".txt", $new_file, LOCK_EX); - $log = "[ {$pfb_alias}{$vtype} ] Found no Unique IPs, Adding '1.1.1.1' to avoid Empty File\n"; - pfb_logger("{$log}","1"); - } - } - } - - - if (file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt')) { - #Create alias config - $new_aliases_list[] = "{$pfb_alias}{$vtype}"; - - $pfb_contlog = $continent_config['aliaslog']; - - $new_aliases[] = array( "name" => "{$pfb_alias}{$vtype}", - "url" => "{$pfb['weblocal']}?pfb={$pfb_alias}{$vtype}", - "updatefreq" => "32", - "address" => "", - "descr" => "pfBlockerNG {$vtype} {$pfb_descr} Country Alias", - "type" => "urltable", - "detail" => "DO NOT EDIT THIS ALIAS" - ); - - #Create rule if action permits - switch ($continent_config['action']) { - case "Deny_Both": - case "Deny_Outbound": - $rule = $base_rule; - $rule['type'] = "{$pfb['deny_action_outbound']}"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr']= "{$pfb_alias}{$vtype}{$pfb['suffix']}"; - $rule['source'] = array("any" => ""); - $rule['destination'] = array ("address" => "{$pfb_alias}{$vtype}"); - if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") - $rule['log'] = ""; - $deny_outbound[] = $rule; - if ($continent_config['action'] != "Deny_Both") - break; - case "Deny_Inbound": - $rule = $base_rule; - $rule['type'] = "{$pfb['deny_action_inbound']}"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; - $rule['source'] = array("address" => "{$pfb_alias}{$vtype}"); - $rule['destination'] = array ("any" => ""); - if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") - $rule['log'] = ""; - $deny_inbound[] = $rule; - break; - case "Permit_Both": - case "Permit_Outbound": - $rule = $base_rule; - $rule['type'] = "pass"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; - $rule['source'] = array ("any" => ""); - $rule['destination'] = array("address" => "{$pfb_alias}{$vtype}"); - if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") - $rule['log'] = ""; - $permit_outbound[] = $rule; - if ($continent_config['action'] != "Permit_Both") - break; - case "Permit_Inbound": - $rule = $base_rule; - $rule['type'] = "pass"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; - $rule['source'] = array("address"=> "{$pfb_alias}{$vtype}"); - $rule['destination'] = array ("any" => ""); - if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") - $rule['log'] = ""; - $permit_inbound[] = $rule; - break; - case "Match_Both": - case "Match_Outbound": - $rule = $base_rule_float; - $rule['type'] = "match"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - $rule['direction'] = "any"; - $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; - $rule['source'] = array ("any" => ""); - $rule['destination'] = array ("address" => "{$pfb_alias}{$vtype}"); - if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") - $rule['log'] = ""; - $match_outbound[] = $rule; - if ($list['action'] != "Match_Both") - break; - case "Match_Inbound": - $rule = $base_rule_float; - $rule['type'] = "match"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - $rule['direction'] = "any"; - $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}"; - $rule['source'] = array ("address" => "{$pfb_alias}{$vtype}"); - $rule['destination'] = array ( "any" => ""); - if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled") - $rule['log'] = ""; - $match_inbound[] = $rule; - break; - } - } else { - #unlink continent list if any - unlink_if_exists($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt'); - } - } - } - } - #mark pfctl aliastable for cleanup - if (!in_array($pfb_alias, $aliases_list)) { - $aliases_list[] = "{$pfb_alias}{$vtype}"; - } - } - } - # UNSET variables - unset ($continent, $continent_existing, $continent_new); - - ################################################# - # Download and Collect IPv4/IPv6 lists # - ################################################# - - # IPv4 REGEX Definitions - $pfb['range'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))-((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))/'; - $pfb['block'] = '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[ 0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.([0]{1})\s+/'; - $pfb['cidr'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/[0-9]{2})/'; - $pfb['single'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s+/'; - $pfb['s_html'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/'; - - # IPv4 preg_replace Regex Filter array - $pfb_ipreg = array(); - $pfb_ipreg[0] = '/\b0+(?=\d)/'; # Remove any Leading Zeros in each Octet - $pfb_ipreg[1] = '/\s/'; # Remove any Whitespaces - $pfb_ipreg[2] = '/127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/'; # Remove any Loopback Addresses 127/8 - $pfb_ipreg[3] = '/0\.0\.0\.0\/32/'; # Remove 0.0.0.0/32 - $pfb_ipreg[4] = '/0\.0\.0\.0/'; # Remove 0.0.0.0 - - # IPv6 REGEX Definitions -- ** Still Needs some Adjustment on Regex Definition for IPv6 ** - # https://mebsd.com/coding-snipits/php-regex-ipv6-with-preg_match.html - $pattern1 = '([A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}'; - $pattern2 = '[A-Fa-f0-9]{1,4}::([A-Fa-f0-9]{1,4}:){0,5}[A-Fa-f0-9]{1,4}'; - $pattern3 = '([A-Fa-f0-9]{1,4}:){2}:([A-Fa-f0-9]{1,4}:){0,4}[A-Fa-f0-9]{1,4}'; - $pattern4 = '([A-Fa-f0-9]{1,4}:){3}:([A-Fa-f0-9]{1,4}:){0,3}[A-Fa-f0-9]{1,4}'; - $pattern5 = '([A-Fa-f0-9]{1,4}:){4}:([A-Fa-f0-9]{1,4}:){0,2}[A-Fa-f0-9]{1,4}'; - $pattern6 = '([A-Fa-f0-9]{1,4}:){5}:([A-Fa-f0-9]{1,4}:){0,1}[A-Fa-f0-9]{1,4}'; - $pattern7 = '([A-Fa-f0-9]{1,4}:){6}:[A-Fa-f0-9]{1,4}'; - $pattern8 = '[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}::\/[0-9]{2}'; - $pattern9 = '[A-Fa-f0-9]{1,4}:([A-Fa-f0-9]{1,4}::)\/[0-9]{2}'; - $pattern10 = '[A-Fa-f0-9]{1,4}::\/[0-9]{2}'; - $pfb['ipv6'] = "/($pattern1)|($pattern2)|($pattern3)|($pattern4)|($pattern5)|($pattern6)|($pattern7)|($pattern8)|($pattern9)|($pattern10)/"; - - $pfb['supp_update'] = FALSE; - $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); - foreach ($list_type as $ip_type => $vtype) { - if ($config['installedpackages'][$ip_type]['config'] != "") { - foreach ($config['installedpackages'][$ip_type]['config'] as $list) { - if ($list['action'] != "Disabled" && $pfb['enable'] == "on" && !$pfb['save'] && is_array($list['row'])) { - # Capture Alias Name - $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']); - foreach ($list['row'] as $row) { - if ($row['url'] != "" && $row['state'] != "Disabled") { - - # Determine Folder Location for Alias (return array $pfbarr) - pfb_determine_list_detail($list['action']); - $pfb['skip'] = $pfbarr['skip']; - $pfbfolder = $pfbarr['folder']; - - if ($vtype == "_v4") { - $header_url = "{$row['header']}"; - } else { - $header_url = "{$row['header']}_v6"; - } - - # Format Log into clean Tab Spaces - if (strlen($header_url) > 10) { - $log_tab = "\t"; - } else { - $log_tab = "\t\t"; - } - - // Empty Header Field Validation Check - 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"; - } else { - $log = "\n[ {$header_url} ] {$log_tab} exists, Reloading File [ NOW ]\n"; - } - pfb_logger("{$log}","1"); - } else { - if ($pfb['reuse'] == "on" && file_exists($pfb['origdir'] . '/' . $header_url . '.orig')) { - $log = "\n[ {$header_url} ] {$log_tab} Using Previously Downloaded File [ NOW ]\n"; - } else { - $log = "\n[ {$header_url} ] {$log_tab} Downloading New File [ NOW ]\n"; - } - pfb_logger("{$log}","1"); - - # Perform Remote URL Date/Time Stamp checks - $host = @parse_url($row['url']); - $list_url = "{$row['url']}"; - if ($row['format'] != "rsync" || $row['format'] != "html") { - if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) { - $remote_tds = "local"; - } else { - $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers($list_url))); - $remote_tds = preg_replace("/^Last-Modified: /","", $remote_tds); - } - } - - $url_list = array(); - if ($row['format'] == "gz" || $row['format'] == "gz_2") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.gz"; - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - # File Exists/Reuse - } else { - $url_gz = "{$row['url']}"; - $file_gz = @file_get_contents($url_gz); - @file_put_contents($file_dwn, $file_gz, LOCK_EX); - if ($remote_tds == "local") - $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); - $remote_stamp = strtotime($remote_tds); - if (!empty($remote_stamp) && file_exists($file_dwn)) - touch ($file_dwn, $remote_stamp); - } - $url_list = @gzfile($file_dwn); - } - - # IBlock Large Files mixed with IPs and Domains. PHP mem of 256M can't handle very large Files. - if ($row['format'] == "gz_lg") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.gz"; - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - # File Exists/Reuse - } else { - $url_gz = "{$row['url']}"; - $file_gz = @file_get_contents($url_gz); - @file_put_contents($file_dwn, $file_gz, LOCK_EX); - exec ("/usr/bin/gunzip -c {$file_dwn} | /usr/bin/sed 's/^.*://' | /usr/bin/grep -v '[a-zA-Z]\|^$\|^#' > {$pfb['origdir']}/{$header_url}.orig"); - if ($remote_tds == "local") - $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); - $remote_stamp = strtotime($remote_tds); - if (!empty($remote_stamp) && file_exists($file_dwn)) - touch ($file_dwn, $remote_stamp); - } - $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig'); - } - - elseif ($row['format'] == "zip") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.zip"; - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - # File Exists/Reuse - } else { - $url_zip = "{$row['url']}"; - if (!$file_zip = @file_get_contents($url_zip)) { - $error = error_get_last(); - $log = "\n [ {$header_url} ] {$error['message']} \n"; - pfb_logger("{$log}","2"); - } else { - @file_put_contents($file_dwn, $file_zip, LOCK_EX); - if ($remote_tds == "local") - $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); - $remote_stamp = strtotime($remote_tds); - if (!empty($remote_stamp) && file_exists($file_dwn)) - touch ($file_dwn, $remote_stamp); - } - } - $zip_out = "{$pfb['origdir']}/{$header_url}.orig"; - exec ("/usr/bin/tar -xOf {$file_dwn} | tr ',' '\n' > {$zip_out}"); - $url_list = @file($zip_out); - } - - elseif ($row['format'] == "et") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.gz"; - # Script to Call ET IQRISK Process - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - # File Exists/Reuse - } else { - $url_et = "{$row['url']}"; - $file_et = @file_get_contents($url_et); - @file_put_contents($file_dwn, $file_et, LOCK_EX); - if ($remote_tds == "local") - $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); - $remote_stamp = strtotime($remote_tds); - if (!empty($remote_stamp) && file_exists($file_dwn)) - touch ($file_dwn, $remote_stamp); - } - exec ("{$pfb['script']} et {$header_url} x x x x x {$pfb['etblock']} {$pfb['etmatch']} >> {$pfb['log']} 2>&1"); - $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig'); - } - - elseif ($row['format'] == "xlsx") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.zip"; - # Script to Call XLSX Process - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - # File Exists/Reuse - } else { - $url_xlsx = "{$row['url']}"; - $file_xlsx = @file_get_contents($url_xlsx); - @file_put_contents($file_dwn, $file_xlsx, LOCK_EX); - if ($remote_tds == "local") - $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); - $remote_stamp = strtotime($remote_tds); - if (!empty($remote_stamp) && file_exists($file_dwn)) - touch ($file_dwn, $remote_stamp); - } - exec ("{$pfb['script']} xlsx {$header_url} >> {$pfb['log']} 2>&1"); - $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig'); - } - - elseif ($row['format'] == "txt") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.orig"; - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - $url_list = @file($file_dwn); - } else { - $url_other = @file($row['url']); - $url_list = $url_other; - @file_put_contents($file_dwn, $url_other, LOCK_EX); - if ($remote_tds == "local") - $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn)); - $remote_stamp = strtotime($remote_tds); - if (!empty($remote_stamp) && file_exists($file_dwn)) - touch ($file_dwn, $remote_stamp); - } - } - - elseif ($row['format'] == "html" || $row['format'] == "block") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.raw"; - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - # File Exists/Reuse - $return = 0; - } else { - $url_html = "{$row['url']}"; - exec ("/usr/bin/fetch -v -o {$file_dwn} -T 20 {$url_html}",$output,$return); - } - if ($return == 0) - $url_list = @file($file_dwn); - } - - elseif ($row['format'] == "rsync") { - $file_dwn = "{$pfb['origdir']}/{$header_url}.orig"; - if ($pfb['reuse'] == "on" && file_exists($file_dwn)) { - # File Exists/Reuse - } else { - $url_rsync = "{$row['url']}"; - exec ("/usr/local/bin/rsync --timeout=5 {$url_rsync} {$file_dwn}"); - } - $url_list = @file($file_dwn); - } - - #extract range lists - $new_file = ""; - if (!empty($url_list)) { - if ($row['format'] == "gz" && $vtype == "_v4") { - foreach ($url_list as $line) { - if (!preg_match("/^#/", $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_temp2($matches[1],$matches[2]); - if (!empty($a_cidr)) { - foreach ($a_cidr as $cidr) { - $new_file .= preg_replace($pfb_ipreg,'',$cidr) . "\n"; - } - } - } - } - } - } - - elseif ($row['format'] == "block" && $vtype == "_v4") { - foreach ($url_list as $line) { - if (!preg_match("/^#/", $line)) { - # Block Type '218.77.79.0 218.77.79.255 24' - if (preg_match($pfb['block'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "/24\n"; - } - } - } - } - - elseif ($row['format'] == "html" && $vtype == "_v4") { - foreach ($url_list as $line) { - if (!preg_match("/^#/", $line)) { - # CIDR format 192.168.0.0/16 - if (preg_match($pfb['cidr'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - # Single ip addresses - elseif (preg_match($pfb['s_html'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - } - } - } - - elseif ($vtype == "_v6") { - foreach ($url_list as $line) { - if (!preg_match("/^#/", $line)) { - # IPv6 Regex Match - if (preg_match($pfb['ipv6'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - } - } - } - - else { - foreach ($url_list as $line) { - if (!preg_match("/^#/", $line)) { - # CIDR format 192.168.0.0/16 - if (preg_match($pfb['cidr'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - # Single ip addresses - elseif (preg_match($pfb['single'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - } - } - } - } - - # Check to see if Blocklist actually Failed Download or has no IPs listed. - if ($row['format'] == "html" || $row['format'] == "block") { - $url_chk = $file_dwn; - } else { - $url_chk = "{$pfb['origdir']}/{$header_url}.orig"; - } - - # Check if File Exists and is >0 in Size - $file_chk = ""; - if (file_exists($url_chk) && @filesize($url_chk) >0) - $file_chk = exec ("/usr/bin/grep -cv '^#\|^$' {$url_chk}"); - - if ($file_chk == "0") { - $new_file = "1.1.1.1\n"; - $url_other = $new_file; - $log = "[ {$header_url} ] Found no IPs, Adding '1.1.1.1' to avoid Download FAIL\n"; - pfb_logger("{$log}","1"); - } - - if ($new_file != "") { - if ($row['format'] == "gz" || $row['format'] == "gz_2" || $row['format'] == "html" || $row['format'] == "block") { - # Re-Save these formats as original file - $url_other = $new_file; - @file_put_contents($pfb['origdir'] . '/' . $header_url . '.orig',$url_other, LOCK_EX); - } - - # Save List to '.txt' format in appropriate Folder - @file_put_contents($pfbfolder . '/' .$header_url . '.txt',$new_file, LOCK_EX); - - if ($pfb['rep'] == "on" && $pfb['skip'] && $vtype == "_v4") { - # Script to Call p24 Process - exec ("{$pfb['script']} p24 {$header_url} {$pfb['max']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1"); - } - - if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") { - # Script to call Duplication Check Process - exec ("{$pfb['script']} duplicate {$header_url} >> {$pfb['log']} 2>&1"); - } - - # PFCTL - Update Only Aliases that have been updated only. - $pfb_alias_lists[] = "{$alias}"; - # Launch d-dup and p-dup functions when changes are found. - if ($pfb['skip'] && $vtype == "_v4") - $pfb['dupcheck'] = TRUE; - # Enable Suppression Process due to Updates - if ($pfb['supp'] == "on" && $vtype == "_v4") - $pfb['supp_update'] = TRUE; - - } else { - # Log FAILED Downloads and Check if Firewall or Snort/Suricata is Blocking Host - $log = "\n [ {$alias} {$header_url} ] Download FAIL [ NOW ]\n"; - pfb_logger("{$log}","2"); - - # Rebuild Previous List File from contents of Masterfile - if ($pfb['skip'] && $vtype == "_v4") { - # Search with trailing Whitespace to match exact Header in Masterfile - $header_url2 = $header_url . "[[:space:]]"; - $file_chk = exec ("/usr/bin/grep {$header_url2} {$pfb['master']} | grep -c ^"); - - if (!file_exists($pfbfolder . '/' . $header_url . '.txt') && @$file_chk > 0 && file_exists($pfb['master'])) { - $log = " [ {$alias} {$header_url} ] Found: {$file_chk} Line(s), Restoring previous List from Master \n"; - pfb_logger("{$log}","2"); - exec ("/usr/bin/grep {$header_url2} {$pfb['master']} | cut -d' ' -f2 > {$pfbfolder}/{$header_url}.txt"); - } - } - # A "Space" string Variable - $sp = " "; - $ip = @gethostbyname($host['host']); - $ip2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", "\"^$1\.$2\.$3\.\"", $ip); - - # Only Perform these Checks if they are not "localfiles" - if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) { - $log = " [ {$alias} {$header_url} ] Local File Failure \n"; - pfb_logger("{$log}","2"); - } else { - # only perform these steps if an 'IP' is found. - if (!empty($ip)) { - // Query for Exact IP Match - $result_b1 = array(); - $pfb_b1 = exec ("/usr/bin/grep ^{$ip} {$pfbfolder}/*", $result_b1); - // Query for First Three IP Octet Matches - $result_b2 = array(); - $pfb_b2 = exec ("/usr/bin/grep {$ip2} {$pfbfolder}/*", $result_b2); - // Query Snort/Suricata snort2c IP Block Table - $snort_pfb = exec("/sbin/pfctl -t snort2c -T show | grep {$ip}"); - - # If an exact IP Match is not found report any First Three IP Octets. - if (!empty($result_b1)) { - $final_b1 = implode("\n ", $result_b1); - $log = " [ {$alias} {$header_url}, {$ip} ] Firewall IP Block Found in : \n{$sp}{$final_b1}\n"; - pfb_logger("{$log}","2"); - } else { - if (!empty($result_b2)) { - $final_b2 = implode("\n ", $result_b2); - $log = " [ {$alias} {$header_url}, {$ip} ] *Potential* Firewall IP Block Found in : \n{$sp}{$final_b2}\n"; - pfb_logger("{$log}","2"); - } - } - if (!empty($snort_pfb)) { - $log = " [ {$alias} {$header_url}, {$ip} ] snort2c IP Block Found in : [ {$snort_pfb} ]\n"; - pfb_logger("{$log}","2"); - } - } else { - $log = " [ {$alias} {$header_url} ] No host IP found \n"; - pfb_logger("{$log}","2"); - } - } - } - # UNSET variables - unset ($file_gz,$file_zip,$file_et,$file_xlsx,$url_other,$url_list); - } - } - } - #check custom network list - if (pfbng_text_area_decode($list['custom']) != "") { - - if ($vtype == "_v4") { - $aliascustom = "{$list['aliasname']}_custom"; - } else { - $aliascustom = "{$list['aliasname']}_custom_v6"; - } - - # Format Log into clean Tab Spaces - if (strlen($aliascustom) > 10) { - $log_tab = "\t"; - } else { - $log_tab = "\t\t"; - } - - # Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled. - $pfb_alias_lists_all[] = "{$alias}"; - - # Determine Folder Location for Alias (return array $pfbarr) - pfb_determine_list_detail($list['action']); - $pfb['skip'] = $pfbarr['skip']; - $pfbfolder = $pfbarr['folder']; - - if (file_exists($pfbfolder . '/' . $aliascustom . '.txt') && $pfb['reuse'] == "") { - $log = "\n[ {$aliascustom} ] {$log_tab} exists, Reloading File [ NOW ]\n"; - pfb_logger("{$log}","1"); - } else { - $url_list = array(); - $log = "\n[ {$aliascustom} ] {$log_tab} Loading Custom File [ NOW ]\n"; - pfb_logger("{$log}","1"); - - $custom_list = pfbng_text_area_decode($list['custom']) . "\n"; - @file_put_contents($pfb['origdir'] . '/' . $aliascustom . '.orig', $custom_list, LOCK_EX); - $url_list = @file($pfb['origdir'] . '/' . $aliascustom . '.orig'); - - $new_file = ""; - if (!empty($url_list)) { - foreach ($url_list as $line) { - if ($vtype == "_v4") { - # CIDR format 192.168.0.0/16 - if (preg_match($pfb['cidr'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - # Single ip addresses - elseif (preg_match($pfb['s_html'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - # Network range 192.168.0.0-192.168.0.254 - elseif (preg_match($pfb['range'],$line,$matches)) { - $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"; - } - } - } - } else { - # IPv6 Regex - if (preg_match($pfb['ipv6'],$line,$matches)) { - $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n"; - } - } - } - - } - if ($new_file != "") { - # PFCTL - Collect Only Aliases that have been updated only. - $pfb_alias_lists[] = "{$alias}"; - # Collect Updated lists for Suppression Process - @file_put_contents($pfbfolder . '/'. $aliascustom . '.txt',$new_file, LOCK_EX); - # Enable Suppression Process due to Updates - if ($pfb['supp'] == "on" && $vtype == "_v4") - $pfb['supp_update'] = TRUE; - if ($pfb['rep'] == "on" && $pfb['skip'] && $vtype == "_v4") { - # Script to Call p24 Process - exec ("{$pfb['script']} p24 {$aliascustom} {$pfb['max']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1"); - } - if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") { - # Script to call Duplication Check Process - exec ("{$pfb['script']} duplicate {$aliascustom} >> {$pfb['log']} 2>&1"); - } - } else { - $log = "[ {$aliascustom} ] Custom List Error ]\n"; - pfb_logger("{$log}","1"); - } - } - } - } - } - } - } - - - ################################# - # REPUTATION PROCESSES # - ################################# - - # IP Reputation processes (pdup and ddup) - if ($pfb['pdup'] == "on" && $pfb['dupcheck'] && !$pfb['save'] && $pfb['enable'] == "on") { - # Script to run pdup process - exec ("{$pfb['script']} pdup x {$pfb['pmax']} >> {$pfb['log']} 2>&1"); - } - if ($pfb['dedup'] == "on" && $pfb['dupcheck'] && !$pfb['save'] && $pfb['enable'] == "on") { - # Script to run dedup process - exec ("{$pfb['script']} dedup x {$pfb['dmax']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1"); - } - - ################################# - # CONFIGURE ALIASES # - ################################# - - $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6"); - foreach ($list_type as $ip_type => $vtype) { - if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") { - $runonce = 0; - foreach ($config['installedpackages'][$ip_type]['config'] as $list) { - $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']); - - # Determine Folder Location for Alias (return array $pfbarr) - pfb_determine_list_detail($list['action']); - $pfb['skip'] = $pfbarr['skip']; - $pfb_descr = $pfbarr['descr']; - $pfbfolder = $pfbarr['folder']; - - // Re-Save Only Aliases that have been updated only. - // When 'Reputation' is used, all Aliases need to be Updated. - $final_alias = array(); - if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") { - if (!empty($pfb_alias_lists_all)) - $final_alias = array_unique($pfb_alias_lists_all); - } else { - if (!empty($pfb_alias_lists)) - $final_alias = array_unique($pfb_alias_lists); - } - - if ($list['action'] != "Disabled") { - #remove empty lists files if any - if (is_array($list['row'])) { - $update = 0; - ${$alias} = ""; - foreach ($list['row'] as $row) { - if ($row['url'] != "" && $row['state'] != "Disabled") { - if ($vtype == "_v4") { - $header_url = "{$row['header']}"; - } else { - $header_url = "{$row['header']}_v6"; - } - $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$alias} | awk '/Addresses/ {s+=$2}; END {print s}'"); - - # Update Alias if List File Exists and its been updated or if the Alias URL Table is Empty. - if (file_exists($pfbfolder . "/" . $header_url . ".txt") && in_array($alias, $final_alias) || file_exists($pfbfolder . "/" . $header_url . ".txt") && empty($pfctlck)) { - # Script to run Suppression process (Print Header Only) - if ($pfb['supp'] == "on" && $vtype == "_v4" && $runonce == 0 && $pfb['supp_update']) { - exec ("{$pfb['script']} suppress x x x suppressheader >> {$pfb['log']} 2>&1"); - $runonce++; - } - # Script to run Suppression Process (Body) - if ($pfb['supp'] == "on" && $vtype == "_v4" && $pfb['supp_update']) { - if ($pfb['dup'] == "on" || !$pfb['skip']) { - # Execute if Duplication Process is Enabled or List is Permit or Match - exec ("{$pfb['script']} suppress x x x {$header_url}\|{$pfbfolder}/ >> {$pfb['log']} 2>&1"); - } else { - # Execute if Duplication Process is Disabled - exec ("{$pfb['script']} suppress x x off {$header_url}\|{$pfbfolder}/ >> {$pfb['log']} 2>&1"); - } - } - ${$alias} .= file_get_contents($pfbfolder . '/' . $header_url . '.txt'); - $update++; - } - } - } - } - - #check custom network list - if ($vtype == "_v4") { - $aliasname = "{$list['aliasname']}_custom"; - } else { - $aliasname = "{$list['aliasname']}_custom_v6"; - } - - # Update Alias if List File Exists and its been updated or if the Alias URL Table is Empty. - $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$alias} | awk '/Addresses/ {s+=$2}; END {print s}'"); - - if (pfbng_text_area_decode($list['custom']) != "") { - if (file_exists($pfbfolder . "/" . $aliasname . ".txt") && in_array($alias, $final_alias) || file_exists($pfbfolder . "/" . $aliasname . ".txt") && empty($pfctlck)) { - ${$alias} .= file_get_contents($pfbfolder . '/' . $aliasname . '.txt'); - $update++; - } - } - # Determine Validity of Alias URL Tables/Rules. ie: Don't create Empty URL Tables or Aliases - if (${$alias} == "" && empty($pfctlck)) { - unlink_if_exists($pfb['aliasdir'] . '/' . $alias. '.txt'); - } else { - // Save Only Aliases that have been updated. - if ($update > 0) { - @file_put_contents($pfb['aliasdir'] . '/' . $alias. '.txt',${$alias}, LOCK_EX); - } - - $alias_log = $list['aliaslog']; - #create alias - $new_aliases_list[] = "{$alias}"; - - $new_aliases[] = array( "name" => "{$alias}", - "url" => "{$pfb['weblocal']}?pfb={$alias}", - "updatefreq" => "32", - "address" => "", - "descr" => "pfBlockerNG {$pfb_descr} List Alias", - "type" => "urltable", - "detail" => "DO NOT EDIT THIS ALIAS" - ); - - #Create rule if action permits - switch ($list['action']) { - case "Deny_Both": - case "Deny_Outbound": - $rule = $base_rule; - $rule['type'] = "{$pfb['deny_action_outbound']}"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr'] = "{$alias}{$pfb['suffix']}"; - $rule['source'] = array ("any" => ""); - $rule['destination'] = array ("address" => "{$alias}"); - if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") - $rule['log'] = ""; - $deny_outbound[] = $rule; - if ($list['action'] != "Deny_Both") - break; - case "Deny_Inbound": - $rule = $base_rule; - $rule['type'] = "{$pfb['deny_action_inbound']}"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr'] = "{$alias}{$pfb['suffix']}"; - $rule['source'] = array("address" => "{$alias}"); - $rule['destination'] = array ("any" => ""); - if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") - $rule['log'] = ""; - $deny_inbound[] = $rule; - break; - case "Permit_Both": - case "Permit_Outbound": - $rule = $base_rule; - $rule['type'] = "pass"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr'] = "{$alias}{$pfb['suffix']}"; - $rule['source'] = array ("any" => ""); - $rule['destination'] = array ("address" => "{$alias}"); - if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") - $rule['log'] = ""; - $permit_outbound[] = $rule; - if ($list['action'] != "Permit_Both") - break; - case "Permit_Inbound": - $rule = $base_rule; - $rule['type'] = "pass"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - if ($pfb['float'] == "on") - $rule['direction'] = "any"; - $rule['descr'] = "{$alias}{$pfb['suffix']}"; - $rule['source'] = array ("address" => "{$alias}"); - $rule['destination'] = array ("any" => ""); - if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") - $rule['log'] = ""; - $permit_inbound[] = $rule; - break; - case "Match_Both": - case "Match_Outbound": - $rule = $base_rule_float; - $rule['type'] = "match"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - $rule['direction'] = "any"; - $rule['descr'] = "{$alias}{$pfb['suffix']}"; - $rule['source'] = array ("any" => ""); - $rule['destination'] = array ("address" => "{$alias}"); - if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") - $rule['log'] = ""; - $match_outbound[] = $rule; - if ($list['action'] != "Match_Both") - break; - case "Match_Inbound": - $rule = $base_rule_float; - $rule['type'] = "match"; - if ($vtype == "_v6") - $rule['ipprotocol'] = "inet6"; - $rule['direction'] = "any"; - $rule['descr'] = "{$alias}{$pfb['suffix']}"; - $rule['source'] = array ("address" => "{$alias}"); - $rule['destination'] = array ("any" => ""); - if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled") - $rule['log'] = ""; - $match_inbound[] = $rule; - break; - } - } - #mark pfctl aliastable for cleanup - if (!in_array($alias, $aliases_list)) { - $aliases_list[] = "{$alias}"; - } - } else { - #unlink previous pfblockerNG alias list if any - unlink_if_exists($pfb['aliasdir'] . '/' . $alias . '.txt'); - } - } - } - } - # Clear Variables - ${$alias} = ""; - - - ######################################### - # UPDATE pfSense ALIAS TABLES # - ######################################### - - #update pfsense alias table - if (is_array($config['aliases']['alias'])) { - foreach ($config['aliases']['alias'] as $cbalias) { - if (preg_match("/pfB_/",$cbalias['name'])) { - #mark pfctl aliastable for cleaning - if (!in_array($cbalias['name'], $aliases_list)) { - $aliases_list[] = $cbalias['name']; #mark aliastable for cleaning - } - #remove previous aliastable file if alias is not defined any more - if (!in_array($cbalias['name'], $new_aliases_list)) { - unlink_if_exists($pfb['aliasdir'] . '/' . $cbalias['name'] . ".txt"); - } - } else { - $new_aliases[] = $cbalias; - - # Check Table Size - if (file_exists($pfb['aliasdir'] . '/' . $alias . '.txt') && $message == "") { - preg_match("/(\d+)/",exec("/usr/bin/grep -c ^ " . $pfb['aliasdir'] . '/' . $alias . '.txt'),$matches); - } - if (($matches[1] * 2.1) >= $pfb['table_limit']) { - #alias table too large - $message = "{$alias} alias table is too large. Reduce networks in list or increase 'Firewall Maximum Table Entries' value to at least " . (int)($matches[1] * 2.1) . ' in "system - advanced - Firewall/NAT" . '; - } - } - } - } - - #apply new alias table to xml - if ($message == "") { - $config['aliases']['alias'] = $new_aliases; - } - # UNSET Variables - unset($new_aliases, $cbalias); - - - ######################### - # Assign Rules # - ######################### - - # Only Execute if AutoRules are defined or if an Alias has been removed. - if ($pfb['autorules'] || $pfb['enable'] == "" || $pfb['remove']) { - if (count($deny_inbound) > 0 || count($permit_inbound) > 0 || count($match_inbound) > 0) { - if ($pfb['inbound_interfaces'] == "") { - $message = "Unable to apply rules. Inbound Interface option not configured."; - } - } - if (count($deny_outbound) > 0 || count($permit_outbound) > 0 || count($match_outbound) > 0) { - if ($pfb['outbound_interfaces'] == "") { - $message = "Unable to apply rules. Outbound Interface option not configured."; - } - } - - if ($message == "") { - $new_rules = array(); - $permit_rules = array(); - $match_rules = array(); - $other_rules = array(); - $fpermit_rules = array(); - $fmatch_rules = array(); - $fother_rules = array(); - - # Collect All Existing Rules - $rules = $config['filter']['rule']; - # Collect Existing pfSense Rules 'Pass', 'Match' and 'Other' pfSense rules into new Arrays. - if (!empty($rules)) { - foreach ($rules as $rule) { - if (!preg_match("/pfB_.*" . $pfb['suffix'] . "/",$rule['descr'])) { - // Floating rules collection 'Floating Pass/Match'. Balance to 'other' - if ($pfb['float'] == "on") { - if ($rule['type'] == "pass" && $rule['floating'] == "yes") { - $fpermit_rules[] = $rule; - } elseif ($rule['type'] == "match" && $rule['floating'] == "yes") { - $fmatch_rules[] = $rule; - } elseif ($rule['floating'] == "yes") { - $fother_rules[] = $rule; - } else { - $other_rules[] = $rule; - } - } else { - // Collect only 'Selected Inbound and Outbound Interfaces'. Balance to 'Other' - if (in_array($rule['interface'],$pfb['inbound_interfaces']) || in_array($rule['interface'],$pfb['outbound_interfaces'])) { - // Floating Rules 'off'. Collect 'Floating Other', Balance to 'Other' - if ($rule['floating'] == "yes") { - $fother_rules[] = $rule; - } elseif ($rule['type'] == "pass") { - if ($pfb['order'] == "order_0") { - $other_rules[] = $rule; - } else { - $permit_rules[] = $rule; - } - } elseif ($rule['type'] == "match") { - if ($pfb['order'] == "order_0") { - $other_rules[] = $rule; - } else { - $match_rules[] = $rule; - } - } else { - $other_rules[] = $rule; - } - } else { - if ($rule['floating'] == "yes") { - $fother_rules[] = $rule; - } else { - $other_rules[] = $rule; - } - } - } - } - } - } - - ################################################################################# - # PASS/MATCH RULES ORDER(p/m) # - # ORDER 0 - pfBlockerNG / All other Rules # - # ORDER 1 - pfSense (p/m) / pfBlockerNG (p/m) / pfBlockerNG Block/Reject # - # ORDER 2 - pfBlockerNG (p/m) / pfSense (p/m) / pfBlockerNG Block/Reject # - # ORDER 3 - pfBlockerNG (p/m) / pfBlockerNG Block/Reject / pfSense (p/m) # - ################################################################################# - - if ($pfb['float'] == "") { - if (!empty($fother_rules)) { - foreach ($fother_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - } - if (!empty($fpermit_rules) && $pfb['order'] == "order_1") { - foreach ($fpermit_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($fmatch_rules) && $pfb['order'] == "order_1") { - foreach ($fmatch_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - - # Define Inbound Interface Rules - if (!empty($pfb['inbound_interfaces'])) { - $counter = 0; - foreach ($pfb['inbound_interfaces'] as $inbound_interface) { - if (!empty($permit_rules) && $pfb['order'] == "order_1") { - foreach ($permit_rules as $cb_rules) { - if ($cb_rules['interface'] == $inbound_interface) - $new_rules[] = $cb_rules; - } - } - if (!empty($match_rules) && $pfb['order'] == "order_1") { - foreach ($match_rules as $cb_rules) { - if ($cb_rules['interface'] == $inbound_interface) - $new_rules[] = $cb_rules; - } - } - # Match Inbound Rules defined as Floating Only. - if (!empty($match_inbound) && $counter == 0) { - foreach ($match_inbound as $cb_rules) { - $cb_rules['interface'] = $pfb['inbound_floating']; - $new_rules[] = $cb_rules; - $counter ++; - } - } - if (!empty($permit_inbound)) { - foreach ($permit_inbound as $cb_rules) { - $cb_rules['interface'] = $inbound_interface; - $new_rules[] = $cb_rules; - } - } - if (!empty($fpermit_rules) && $pfb['order'] == "order_2") { - foreach ($fpermit_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($fmatch_rules) && $pfb['order'] == "order_2") { - foreach ($fmatch_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($permit_rules) && $pfb['order'] == "order_2") { - foreach ($permit_rules as $cb_rules) { - if ($cb_rules['interface'] == $inbound_interface) - $new_rules[] = $cb_rules; - } - } - if (!empty($match_rules) && $pfb['order'] == "order_2") { - foreach ($match_rules as $cb_rules) { - if ($cb_rules['interface'] == $inbound_interface) - $new_rules[] = $cb_rules; - } - } - if (!empty($deny_inbound)) { - foreach ($deny_inbound as $cb_rules) { - $cb_rules['interface'] = $inbound_interface; - $new_rules[] = $cb_rules; - } - } - } - } - - # Define Outbound Interface Rules - if (!empty($pfb['outbound_interfaces'])) { - $counter = 0; - foreach ($pfb['outbound_interfaces'] as $outbound_interface) { - if (!empty($permit_rules) && $pfb['order'] == "order_1") { - foreach ($permit_rules as $cb_rules) { - if ($cb_rules['interface'] == $outbound_interface) - $new_rules[] = $cb_rules; - } - } - if (!empty($match_rules) && $pfb['order'] == "order_1") { - foreach ($match_rules as $cb_rules) { - if ($cb_rules['interface'] == $outbound_interface) - $new_rules[] = $cb_rules; - } - } - # Match Outbound Rules defined as Floating Only. - if (!empty($match_outbound) && $counter == 0) { - foreach ($match_outbound as $cb_rules) { - $cb_rules['interface'] = $pfb['outbound_floating']; - $new_rules[] = $cb_rules; - $counter++; - } - } - if (!empty($permit_outbound)) { - foreach ($permit_outbound as $cb_rules) { - $cb_rules['interface'] = $outbound_interface; - $new_rules[] = $cb_rules; - } - } - if (!empty($permit_rules) && $pfb['order'] == "order_2") { - foreach ($permit_rules as $cb_rules) { - if ($cb_rules['interface'] == $outbound_interface) - $new_rules[] = $cb_rules; - } - } - if (!empty($match_rules) && $pfb['order'] == "order_2") { - foreach ($match_rules as $cb_rules) { - if ($cb_rules['interface'] == $outbound_interface) - $new_rules[] = $cb_rules; - } - } - if (!empty($deny_outbound)) { - foreach ($deny_outbound as $cb_rules) { - $cb_rules['interface'] = $outbound_interface; - $new_rules[] = $cb_rules; - } - } - } - } - - if (!empty($fpermit_rules) && $pfb['order'] == "order_0") { - foreach ($fpermit_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($fmatch_rules) && $pfb['order'] == "order_0") { - foreach ($fmatch_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($fpermit_rules) && $pfb['order'] == "order_3") { - foreach ($fpermit_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($fmatch_rules) && $pfb['order'] == "order_3") { - foreach ($fmatch_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($permit_rules) && $pfb['order'] == "order_3") { - foreach ($permit_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if (!empty($match_rules) && $pfb['order'] == "order_3") { - foreach ($match_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - if ($pfb['float'] == "on") { - if (!empty($fother_rules)) { - foreach ($fother_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - } - if (!empty($other_rules)) { - foreach ($other_rules as $cb_rules) { - $new_rules[] = $cb_rules; - } - } - - # Save New Rule Order to Config - $config['filter']['rule'] = $new_rules; - } - $log = "\n {$message} \n"; - pfb_logger("{$log}","1"); - - # UNSET arrays - unset ($cb_rules,$permit_inbound,$permit_outbound,$deny_inbound,$deny_outbound,$match_inbound,$match_outbound); - unset ($other_rules,$fother_rules,$permit_rules,$fpermit_rules,$match_rules,$fmatch_rules); - } - - - ################################# - # Closing Processes # - ################################# - - #uncheck Reusing Existing Downloads Check box - if (!$pfb['save'] && $pfb['enable'] == "on") - $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = ""; - - # Save all Changes to pfSense config file - write_config(); - - # If 'Rule Changes' are found, utilize the 'filter_configure()' function, if not, utilize 'pfctl replace' command - if ($pfb['autorules'] && $rules != $new_rules || $pfb['enable'] == "" || $pfb['remove']) { - require_once("filter.inc"); - - if (!$pfb['save']) { - $log = "\n===[ Aliastables / Rules ]================================\n\n"; - pfb_logger("{$log}","1"); - - $log = "Firewall Rule Changes Found, Applying Filter Reload \n"; - pfb_logger("{$log}","1"); - } - - # Remove all pfBlockerNG Alias tables - if (!empty($aliases_list)) { - foreach ($aliases_list as $table) { - exec ("/sbin/pfctl -t " . escapeshellarg($table) . " -T kill 2>&1", $pfb_null); - } - } - - #load filter file which will create the pfctl tables - filter_configure(); - - // Call function for NanoBSD/Ramdisk processes. - pfb_aliastables("update"); - } else { - # Don't Execute on User 'Save' - if (!$pfb['save']) { - - $log = "\n===[ Aliastables / Rules ]================================\n\n"; - pfb_logger("{$log}","1"); - - $log = "No Changes to Firewall Rules, Skipping Filter Reload \n"; - pfb_logger("{$log}","1"); - - // Re-Save Only Aliases that have been updated only. - // When 'Reputation' is used, all Aliases Need to be Updated. - $final_alias = array(); - if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") { - if (!empty($pfb_alias_lists_all)) - $final_alias = array_unique($pfb_alias_lists_all); - } else { - if (!empty($pfb_alias_lists)) - $final_alias = array_unique($pfb_alias_lists); - } - - if (!empty($final_alias)) { - foreach ($final_alias as $final) { - $log = "\n Updating: {$final} \n"; - pfb_logger("{$log}","1"); - $result_pfctl = ""; - exec ("/sbin/pfctl -t " . escapeshellarg($final) . " -T replace -f " . $pfb['aliasdir'] . "/" . escapeshellarg($final) . ".txt 2>&1", $result_pfctl); - $log = implode($result_pfctl); - pfb_logger("{$log}","1"); - } - - // Call function for NanoBSD/Ramdisk processes. - pfb_aliastables("update"); - } else { - $log = "\nNo Changes to Aliases, Skipping pfctl Update \n"; - pfb_logger("{$log}","1"); - } - } - } - # UNSET Variables - unset($rules, $new_rules); - - #sync config - pfblockerng_sync_on_changes(); - - ################################# - # FINAL REPORTING # - ################################# - - # Only run with CRON or Force Invoked Process - if ((!$pfb['save'] && $pfb['dupcheck'] && $pfb['enable'] == "on") || $pfb['summary']) { - # Script to run Final Script Processes. - exec ("{$pfb['script']} closing {$pfb['dup']} >> {$pfb['log']} 2>&1"); - } - - if ($pfb['enable'] == "on" && !$pfb['save']) { - $log = "\n\n UPDATE PROCESS ENDED [ NOW ]\n"; - pfb_logger("{$log}","1"); - } - - - ######################################### - # Define/Apply CRON Jobs # - ######################################### - - # Clear any existing pfBlockerNG Cron Jobs - install_cron_job("pfblockerng.php cron", false); - - # Replace Cron job with any User Changes to $pfb_min - if ($pfb['enable'] == "on") { - # Define pfBlockerNG CRON Job - $pfb_cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php cron >> {$pfb['log']} 2>&1"; - # $pfb['min'] ( User Defined Variable. Variable defined at start of Script ) - $pfb_hour = "*"; - $pfb_mday = "*"; - $pfb_month = "*"; - $pfb_wday = "*"; - $pfb_who = "root"; - - install_cron_job($pfb_cmd, true, $pfb['min'], $pfb_hour, $pfb_mday, $pfb_month, $pfb_wday, $pfb_who); - } - - # Clear any existing pfBlockerNG MaxMind CRON Job - install_cron_job("pfblockerng.php dc", false); - - if ($pfb['enable'] == "on") { - # Define pfBlockerNG MaxMind CRON Job - $pfb_gcmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php dc >> {$pfb['geolog']} 2>&1"; - - # MaxMind GeoIP Cron Hour is randomized between 0-23 Hour to minimize effect on MaxMind Website - - $pfb_gmin = "0"; - $pfb_ghour = rand(0,23); - $pfb_gmday = "1,2,3,4,5,6,7"; - $pfb_gmonth = "*"; - $pfb_gwday = "2"; - $pfb_gwho = "root"; - - install_cron_job($pfb_gcmd, true, $pfb_gmin, $pfb_ghour, $pfb_gmday, $pfb_gmonth, $pfb_gwday, $pfb_gwho); - } -} - - -function pfblockerng_validate_input($post, &$input_errors) { - global $config; - foreach ($post as $key => $value) { - if (empty($value)) - continue; - if ($key == "message_size_limit" && !is_numeric($value)) - $input_errors[] = "Message size limit must be numeric."; - if ($key == "process_limit" && !is_numeric($value)) - $input_errors[] = "Process limit must be numeric."; - if ($key == "freq" && (!preg_match("/^\d+(h|m|d)$/",$value) || $value == 0)) - $input_errors[] = "A valid number with a time reference is required for the field 'Frequency'"; - if (substr($key, 0, 2) == "dc" && !is_hostname($value)) - $input_errors[] = "{$value} is not a valid host name."; - if (substr($key, 0, 6) == "domain" && is_numeric(substr($key, 6))) { - if (!is_domain($value)) - $input_errors[] = "{$value} is not a valid domain name."; - } else if (substr($key, 0, 12) == "mailserverip" && is_numeric(substr($key, 12))) { - if (empty($post['domain' . substr($key, 12)])) - $input_errors[] = "Domain for {$value} cannot be blank."; - if (!is_ipaddr($value) && !is_hostname($value)) - $input_errors[] = "{$value} is not a valid IP address or host name."; - } - } -} - - -function pfblockerng_php_install_command() { - require_once("/usr/local/www/pfblockerng/pfblockerng.php"); - 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. - @rename("{$pfb['dbdir']}/countrycodes.tar.bz2", "{$pfb['ccdir']}/countrycodes.tar.bz2"); - 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"); - - 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(); - update_output_window(gettext("Creating pfBlockerNG Continenet XML Files...")); - 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'])) { - // Restore previous Widget setting if "Keep" is enabled. - $config['widgets']['sequence'] = $pfb['widgets']; - } else { - $widgets = $config['widgets']['sequence']; - if (!preg_match("/pfblockerng-container/", $widgets)) { - if (empty($widgets)) { - $config['widgets']['sequence'] = "pfblockerng-container:col2:show"; - } else { - $config['widgets']['sequence'] .= ",pfblockerng-container:col2:show"; - } - } - } -} - - -function pfblockerng_php_deinstall_command() { - require_once("config.inc"); - global $config,$pfb; - - # Set these two variables to Disable pfBlockerNG on De-Install - $pfb['save'] = TRUE; - $pfb['install'] = TRUE; - sync_package_pfblockerng(); - rmdir_recursive("/usr/local/pkg/pfblockerng"); - rmdir_recursive("/usr/local/www/pfblockerng"); - - # Maintain pfBlockerNG Settings and Database Files if $pfb['keep'] is ON. - if ($pfb['keep'] != "on") { - # Remove pfBlockerNG Log and DB Folder - rmdir_recursive("{$pfb['dbdir']}"); - rmdir_recursive("{$pfb['logdir']}"); - - // Remove Aliastables archive and earlyshellcmd if found. - @unlink_if_exists("{$pfb['aliasarchive']}"); - if (is_array($config['system']['earlyshellcmd'])) { - $a_earlyshellcmd = &$config['system']['earlyshellcmd']; - if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) { - $a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT); - } - } - - # Remove Settings from Config - if (is_array($config['installedpackages']['pfblockerng'])) - unset($config['installedpackages']['pfblockerng']); - if (is_array($config['installedpackages']['pfblockerngglobal'])) - unset($config['installedpackages']['pfblockerngglobal']); - if (is_array($config['installedpackages']['pfblockerngsync'])) - unset($config['installedpackages']['pfblockerngsync']); - if (is_array($config['installedpackages']['pfblockerngreputation'])) - unset($config['installedpackages']['pfblockerngreputation']); - if (is_array($config['installedpackages']['pfblockernglistsv4'])) - unset($config['installedpackages']['pfblockernglistsv4']); - if (is_array($config['installedpackages']['pfblockernglistsv6'])) - unset($config['installedpackages']['pfblockernglistsv6']); - if (is_array($config['installedpackages']['pfblockerngafrica'])) - unset($config['installedpackages']['pfblockerngafrica']); - if (is_array($config['installedpackages']['pfblockerngantartica'])) - unset($config['installedpackages']['pfblockerngantartica']); - if (is_array($config['installedpackages']['pfblockerngasia'])) - unset($config['installedpackages']['pfblockerngasia']); - if (is_array($config['installedpackages']['pfblockerngeurope'])) - unset($config['installedpackages']['pfblockerngeurope']); - if (is_array($config['installedpackages']['pfblockerngnorthamerica'])) - unset($config['installedpackages']['pfblockerngnorthamerica']); - if (is_array($config['installedpackages']['pfblockerngoceania'])) - unset($config['installedpackages']['pfblockerngoceania']); - if (is_array($config['installedpackages']['pfblockerngsouthamerica'])) - 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) - $pfb['widgets'] = $config['widgets']['sequence']; - if (!empty($pfb['widgets'])) { - $widgetlist = explode(",", $pfb['widgets']); - foreach ($widgetlist as $key => $widget) { - if (strstr($widget, "pfblockerng-container")) { - unset($widgetlist[$key]); - break; - } - } - $config['widgets']['sequence'] = implode(",", $widgetlist); - } - update_output_window(gettext("pfBlockerNG has been Uninstalled")); -} - -/* Uses XMLRPC to synchronize the changes to a remote node */ -function pfblockerng_sync_on_changes() { - global $config, $g, $pfb_sync; - - // Create Array of Sync Settings and exit if Sync is Disabled. - if (is_array($config['installedpackages']['pfblockerngsync']['config'][0])) { - $pfb_sync = $config['installedpackages']['pfblockerngsync']['config'][0]; - if ($pfb_sync['varsynconchanges'] == "disabled" || $pfb_sync['varsynconchanges'] == "") - return; - - $synctimeout = $pfb_sync['varsynctimeout']; - } else { - return; - } - - log_error("[pfBlockerNG] XMLRPC sync is starting."); - - if (is_array($config['installedpackages']['pfblockerngsync']['config'])) { - switch ($pfb_sync['varsynconchanges']) { - case "manual": - if (is_array($pfb_sync[row])) { - $rs = $pfb_sync[row]; - } else { - log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured."); - return; - } - break; - case "auto": - if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){ - $system_carp = $config['installedpackages']['carpsettings']['config'][0]; - $rs[0]['varsyncipaddress'] = $system_carp['synchronizetoip']; - $rs[0]['varsyncusername'] = $system_carp['username']; - $rs[0]['varsyncpassword'] = $system_carp['password']; - - // XMLRPC sync is currently only supported over connections using the same protocol and port as this system - if ($config['system']['webgui']['protocol'] == "http") { - $rs[0]['varsyncprotocol'] = "http"; - } else { - $rs[0]['varsyncprotocol'] = "https"; - } - - if ($system_carp['synchronizetoip'] == "") { - log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured."); - return; - } - } else { - log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured."); - return; - } - break; - default: - return; - break; - } - if (is_array($rs)) { - foreach ($rs as $sh) { - // Only Sync Enabled Replication Targets - if ($sh['varsyncdestinenable'] == "ON") { - $sync_to_ip = $sh['varsyncipaddress']; - $port = $sh['varsyncport']; - $password = htmlspecialchars($sh['varsyncpassword']); - $protocol = $sh['varsyncprotocol']; - - if (!empty($sh['varsyncusername'])) { - $username = $sh['varsyncusername']; - } else { - $username = "admin"; - } - - pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout); - } - } - if ($success) - log_error("[pfBlockerNG] XMLRPC sync completed successfully."); - } - } -} - - -/* Do the actual XMLRPC sync */ -function pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout) { - global $config, $g, $pfb_sync; - $success = TRUE; - - /* Exit on missing parameters */ - if (empty($sync_to_ip) || empty($password)) { - log_error("[pfBlockerNG] XMLRPC sync parameter missing (host IP or password) ... aborting xmlrpc sync"); - $success = FALSE; - return $success; - } - - /* Do not attempt a package sync while booting up or installing package */ - if ($g['booting'] || $g['pfblockerng_postinstall']) { - log_error("[pfBlockerNG] XMLRPC sync to Replication targets terminated during boot up or during package reinstallation."); - $success = FALSE; - return $success; - } - - // Validate Replication Target IP Address and Port Settings - if (!is_ipaddr($sync_to_ip) || !is_port($port)) { - log_error("[pfBlockerNG] XMLRPC sync terminated due to mis-configured Replication Target IP Address or Port settings."); - $success = FALSE; - return $success; - } - - /* Test key variables and set defaults if empty */ - if (empty($synctimeout)) - $synctimeout = 150; - - $url = "{$protocol}://{$sync_to_ip}"; - - if ($port == "") { $port = $config['system']['webgui']['port']; }; - /* If port is empty lets rely on the protocol selection */ - if ($port == "") { - if ($config['system']['webgui']['protocol'] == "http") { - $port = "80"; - } else { - $port = "443"; - } - } - /* xml will hold the sections to sync */ - $xml = array(); - // If User Disabled, remove 'General Tab Customizations' from Sync - if ($config['installedpackages']['pfblockerngsync']['config'][0]['syncinterfaces'] == "") - $xml['pfblockerng'] = $config['installedpackages']['pfblockerng']; - $xml['pfblockerngreputation'] = $config['installedpackages']['pfblockerngreputation']; - $xml['pfblockernglistsv4'] = $config['installedpackages']['pfblockernglistsv4']; - $xml['pfblockernglistsv6'] = $config['installedpackages']['pfblockernglistsv6']; - $xml['pfblockerngtopspammers'] = $config['installedpackages']['pfblockerngtopspammers']; - $xml['pfblockerngafrica'] = $config['installedpackages']['pfblockerngafrica']; - $xml['pfblockerngantartica'] = $config['installedpackages']['pfblockerngantartica']; - $xml['pfblockerngasia'] = $config['installedpackages']['pfblockerngasia']; - $xml['pfblockerngeurope'] = $config['installedpackages']['pfblockerngeurope']; - $xml['pfblockerngnorthamerica'] = $config['installedpackages']['pfblockerngnorthamerica']; - $xml['pfblockerngoceania'] = $config['installedpackages']['pfblockerngoceania']; - $xml['pfblockerngsouthamerica'] = $config['installedpackages']['pfblockerngsouthamerica']; - $xml['pfblockerngproxyandsatellite'] = $config['installedpackages']['pfblockerngproxyandsatellite']; - - /* assemble xmlrpc payload */ - $params = array( - XML_RPC_encode($password), - XML_RPC_encode($xml) - ); - - /* set a few variables needed for sync code borrowed from filter.inc */ - log_error("[pfBlockerNG] XMLRPC syncing to {$url}:{$port}."); - $method = 'pfsense.merge_installedpackages_section_xmlrpc'; - $msg = new XML_RPC_Message($method, $params); - $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port); - $cli->setCredentials($username, $password); - if ($g['debug']) { - $cli->setDebug(1); - } - - /* send our XMLRPC message and timeout after defined sync timeout value */ - $resp = $cli->send($msg, $synctimeout); - $error = ""; - if (!$resp) { - log_error("[pfBlockerNG] XMLRPC communications error occurred while attempting sync with {$url}:{$port}."); - file_notice("sync_settings", $error, "pfBlockerNG Settings Sync", ""); - $success = FALSE; - return $success; - } elseif ($resp->faultCode()) { - $cli->setDebug(1); - $resp = $cli->send($msg, $synctimeout); - log_error("[pfBlockerNG] XMLRPC Error received while attempting sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString()); - file_notice("sync_settings", $error, "pfBlockerNG Settings Sync", ""); - $success = FALSE; - return $success; - } else { - log_error("[pfBlockerNG] XMLRPC sync successfully completed with {$url}:{$port}."); - } - return $success; -} -?> \ No newline at end of file -- cgit v1.2.3 From 9a6b7bef7abb3861316b542b15e7efe5e3a0c699 Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Sun, 22 Feb 2015 19:58:51 -0500 Subject: pfBlockerNG - Remove Dev version Variable. --- config/pfblockerng/pfblockerng_alerts.php | 1 - 1 file changed, 1 deletion(-) diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index e092b25c..2342f5b2 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -167,7 +167,6 @@ if ($_POST['filterlogentries_submit']) { $filterfieldsarray[9] = $_POST['filterlogentries_srcport'] ? $_POST['filterlogentries_srcport'] : null; $filterfieldsarray[10] = $_POST['filterlogentries_dstport'] ? $_POST['filterlogentries_dstport'] : null; - $filterfieldsarray[90] = $_POST['filterlogentries_dnsbl'] ? $_POST['filterlogentries_dnsbl'] : null; $filterfieldsarray[99] = $_POST['filterlogentries_date'] ? $_POST['filterlogentries_date'] : null; } -- cgit v1.2.3 From 5b2458ab4a43cf8e44567d1e0ed19c7bcece660b Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Sun, 22 Feb 2015 20:06:26 -0500 Subject: pfBlockerNG - Alerts Tab cosmetic changes Remove extra line Add missing semi-colon ; --- config/pfblockerng/pfblockerng_alerts.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index 2342f5b2..d14ad3a7 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -578,8 +578,7 @@ if ($savemsg) { -- cgit v1.2.3 From 043aab28a4e872069e5592fe407a01f77c8cb81e Mon Sep 17 00:00:00 2001 From: BBcan177 Date: Mon, 23 Feb 2015 01:27:47 -0500 Subject: pfBlockerNG - Mods to Alerts Tab JS Variable - Define $mycounter variable to avoid a potential JS error when its empty. --- config/pfblockerng/pfblockerng_alerts.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php index d14ad3a7..dd968bfc 100644 --- a/config/pfblockerng/pfblockerng_alerts.php +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -934,6 +934,8 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) { $counter++; if ($counter > 0 && $rtype == "block") { $mycounter = $counter; + } else { + $mycounter = 0; } } } -- cgit v1.2.3
    @@ -473,6 +529,71 @@ if ($savemsg) { ', '');?>
+ " onclick="enable_showFilter();" /> +    +
+ + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
', '');?>   +

+
+
" title="" /> +    " title="" /> +    " onclick="enable_hideFilter();" title="" />
+
+
{$fields[99]} {$fields[2]} {$rule}{$proto}{$fields[6]} {$src_icons}{$fields[97]}{$srcport}
{$hostname['src']}
{$dst_icons}{$fields[98]}{$dstport}
{$hostname['dst']}
{$country}
- -
', '');?>   +
', '');?>