diff options
37 files changed, 9695 insertions, 76 deletions
diff --git a/config/apcupsd/apcupsd.inc b/config/apcupsd/apcupsd.inc index 3340738a..c123861c 100644 --- a/config/apcupsd/apcupsd.inc +++ b/config/apcupsd/apcupsd.inc @@ -167,9 +167,7 @@ function sync_package_apcupsd(){ $apcupsd_start .= " if [ ! -d {$lockfile} ]; then \n"; $apcupsd_start .= " /bin/mkdir -p {$lockfile} \n"; $apcupsd_start .= " fi \n"; - $apcupsd_start .= " if [ -f {$lockfile}/LCK.. ]; then \n"; - $apcupsd_start .= " /bin/rm -f {$lockfile}/LCK.. \n"; - $apcupsd_start .= " fi \n"; + $apcupsd_start .= " /bin/rm -f {$lockfile}/*LCK* 2>/dev/null \n"; if ($apcupsd_config['killonpowerfail']=="on"){ $apcupsd_start .= " " . APCUPSD_BASE . "/sbin/apcupsd --kill-on-powerfail"; }else{ diff --git a/config/apcupsd/apcupsd.xml b/config/apcupsd/apcupsd.xml index 5ef2b946..8a42f352 100644 --- a/config/apcupsd/apcupsd.xml +++ b/config/apcupsd/apcupsd.xml @@ -40,7 +40,7 @@ <name>Apcupsd</name> <title>Services: Apcupsd (General)</title> <category>Monitoring</category> - <version>0.3.1</version> + <version>0.3.2</version> <include_file>/usr/local/pkg/apcupsd.inc</include_file> <addedit_string>Apcupsd has been created/modified.</addedit_string> <delete_string>Apcupsd has been deleted.</delete_string> @@ -334,6 +334,17 @@ UPSTYPE DEVICE Description <br> <option><name>Share</name><value>share</value></option> </options> </field> + <field> + <name>Notifications</name> + <type>listtopic</type> + </field> + <field> + <fieldname>notification_info</fieldname> + <type>info</type> + <description>In order to receive e-mail notifications, you need to configure + SMTP Email Notifications on Advanced/Notifications section, and also, + install mailreport package.</description> + </field> </fields> <custom_php_install_command>php_install_apcupsd();</custom_php_install_command> <custom_php_command_before_form></custom_php_command_before_form> diff --git a/config/bind/bind.xml b/config/bind/bind.xml index 5e5f9e9b..37c13017 100644 --- a/config/bind/bind.xml +++ b/config/bind/bind.xml @@ -185,8 +185,7 @@ <field> <fielddescr>Logging serverity</fielddescr> <fieldname>log_severity</fieldname> - <description><![CDATA[Choose logging levels for selected categories.<BR> - use CTRL+click to select/unselect.<br> + <description><![CDATA[Choose logging level for selected categories.<BR> The value 'dynamic' means assume the global level defined by either the command line parameter -d or by running rndc trace.]]></description> <type>select</type> <options> diff --git a/config/havp/antivirus.php b/config/havp/antivirus.php index 0d8cda1d..0d66a6b3 100644 --- a/config/havp/antivirus.php +++ b/config/havp/antivirus.php @@ -176,6 +176,11 @@ if ($_POST['startupdate'] != '') { # else echo "No 'start_antivirus_scanner' function found."; } +/* Clear havp access log */ +if ($_POST['clearlog_x'] != '') { + file_put_contents(HVDEF_HAVP_ACCESSLOG, ''); +} + # ------------------------------------------------------------------------------ ?> @@ -199,6 +204,7 @@ if (pfsense_version_A() == '1') { $tab_array[] = array(gettext("General page"), true, "antivirus.php"); $tab_array[] = array(gettext("HTTP proxy"), false, "pkg_edit.php?xml=havp.xml&id=0"); $tab_array[] = array(gettext("Settings"), false, "pkg_edit.php?xml=havp_avset.xml&id=0"); + $tab_array[] = array(gettext("Log"), false, "havp_log.php"); display_top_tabs($tab_array); ?> @@ -356,7 +362,7 @@ if (pfsense_version_A() == '1') { } else echo "<tr><td $stl>Not found</td></tr>"; ?> - <tr class="listr"><td class="listr" colspan="4"><?php echo get_av_statistic(); ?></td></tr> + <tr class="listr"><td class="listr" colspan="4"><?php echo get_av_statistic(); ?><?php echo "<div style='float:right;'><input title='Clear antivirus log' name='clearlog' type='image' value='havp' border=0 src='./themes/".$g['theme']."/images/icons/icon_x.gif'>"; ?><font size="-1"> Clear log</font></div></td></tr> </tbody></table> </td> </tr> diff --git a/config/havp/havp.inc b/config/havp/havp.inc index f6e37a3b..8118f695 100644 --- a/config/havp/havp.inc +++ b/config/havp/havp.inc @@ -48,7 +48,7 @@ if(!function_exists("filter_configure")) define('HV_DEBUG', 'false'); # use Clamd daemon (another - use libclam) -define('HV_USE_CLAMD', 'true'); +# define('HV_USE_CLAMD', 'true'); define('HV_CLAMD_TCPSOCKET', 'true'); # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -151,6 +151,7 @@ define('HV_SCANTEMPFILE', 'hv_scan_tempfile'); # XML fields # ------------------------------------------------------------------------------ define('F_ENABLE', 'enable'); +define('F_USECLAMD', 'useclamd'); define('F_PROXYMODE', 'proxymode'); define('F_PROXYINTERFACE', 'proxyinterface'); define('F_PROXYBINDIFACE', 'proxybindiface'); # internal var @@ -515,6 +516,8 @@ function havp_convert_pfxml_xml() # === GUI Fields === $havp_config[F_ENABLE] = ( $pfconf[F_ENABLE] === 'on' ? 'true' : 'false' ); + # ClamAV mode + $havp_config[F_USECLAMD] = $pfconf[F_USECLAMD]; # proxy $havp_config[F_PROXYMODE] = ( !empty($pfconf[F_PROXYMODE]) ? $pfconf[F_PROXYMODE] : 'standard' ); # ToDo: add check squid transparent @@ -710,9 +713,9 @@ function havp_config_havp() $conf[] = "MAXDOWNLOADSIZE {$havp_config[F_MAXDOWNLOADSIZE]}"; # $conf[] = "\n# ClamAV Library Scanner (libclamav) "; - $conf[] = "ENABLECLAMLIB " . (HV_USE_CLAMD !== 'true' ? "true" : "false"); + $conf[] = "ENABLECLAMLIB " . ($havp_config[F_USECLAMD] !== 'true' ? "true" : "false"); # use clamd, if configured - if (HV_USE_CLAMD === 'true') { + if ($havp_config[F_USECLAMD] === 'true') { $conf[] = "\n# Clamd scanner (Clam daemon)"; $conf[] = "ENABLECLAMD true"; # clamd socket @@ -1342,7 +1345,7 @@ function havp_startup_script() $s[] = "\t# start"; $s[] = "\tif [ -z \"`{$havpchk}`\" ];then"; - if (HV_USE_CLAMD === 'true') { + if ($havp_config[F_USECLAMD] === 'true') { $clampid_dir = HVDEF_CLAM_RUNDIR; $s[] = "\t\t# start clamd before (to be sure)"; $s[] = "\t\t" . HVDEF_CLAM_STARTUP_SCRIPT . " start"; @@ -1563,7 +1566,7 @@ function start_antivirus_scanner($filename) $param[] = "--max-dir-recursion=255"; # Maximum directory recursion level $param = implode(" ", $param); - if (HV_USE_CLAMD === 'true') + if ($havp_config[F_USECLAMD] === 'true') $param = "clamdscan $param $filename"; # use clamd daemon (more quickly) else $param = "clamscan $param $filename"; @@ -1702,7 +1705,7 @@ function havp_get_av_viruslog() $log = explode("\n", $log); $count = 0; foreach($log as $ln) { - if (substr_count(strtolower($ln), "virus clamd:")) + if (substr_count(strtolower($ln), "virus clam")) $s[] = $ln; } } @@ -1716,7 +1719,7 @@ function havp_get_av_statistic() if (file_exists(HVDEF_HAVP_ACCESSLOG)) { $log = file_get_contents(HVDEF_HAVP_ACCESSLOG); - $count = substr_count(strtolower($log), "virus clamd:"); + $count = substr_count(strtolower($log), "virus clam"); $s = "Found $count viruses (total)."; } diff --git a/config/havp/havp.xml b/config/havp/havp.xml index 47611030..51356862 100644 --- a/config/havp/havp.xml +++ b/config/havp/havp.xml @@ -55,6 +55,10 @@ <text>Settings</text> <url>/pkg_edit.php?xml=havp_avset.xml&id=0</url> </tab> + <tab> + <text>Log</text> + <url>/havp_log.php</url> + </tab> </tabs> <fields> <field> @@ -64,6 +68,21 @@ <type>checkbox</type> </field> <field> + <fielddescr>ClamAV mode</fielddescr> + <fieldname>useclamd</fieldname> + <description> + Select ClamAV running mode:<br> + <b>Daemon</b> - HAVP will use ClamAV as socket scanner daemon. Default option.<br> + <b>Library</b> - HAVP will use ClamAV as loaded library scanner. Note: this mode needs much more memory.<br> + </description> + <type>select</type> + <default_value>true</default_value> + <options> + <option><value>true</value><name>Daemon</name></option> + <option><value>false</value><name>Library</name></option> + </options> + </field> + <field> <fielddescr>Proxy mode</fielddescr> <fieldname>proxymode</fieldname> <description> @@ -302,4 +321,4 @@ <custom_php_deinstall_command> havp_deinstall(); </custom_php_deinstall_command> -</packagegui>
\ No newline at end of file +</packagegui> diff --git a/config/havp/havp_avset.xml b/config/havp/havp_avset.xml index 3d4372f4..1b0d5c5d 100644 --- a/config/havp/havp_avset.xml +++ b/config/havp/havp_avset.xml @@ -23,6 +23,10 @@ <url>/pkg_edit.php?xml=havp_avset.xml&id=0</url> <active/> </tab> + <tab> + <text>Log</text> + <url>/havp_log.php</url> + </tab> </tabs> <fields> <field> @@ -104,4 +108,4 @@ </custom_php_install_command> <custom_php_deinstall_command> </custom_php_deinstall_command> -</packagegui>
\ No newline at end of file +</packagegui> diff --git a/config/havp/havp_log.php b/config/havp/havp_log.php new file mode 100644 index 00000000..60c02fbf --- /dev/null +++ b/config/havp/havp_log.php @@ -0,0 +1,105 @@ +<?php +/* $Id$ */ +/* + havp_log.php + Copyright (C) 2014 Andrew Nikitin <andrey.b.nikitin@gmail.com>. + Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>. + Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require("guiconfig.inc"); + +if (file_exists("/usr/local/pkg/havp.inc")) + require_once("/usr/local/pkg/havp.inc"); +else echo "No havp.inc found"; + +$nentries = $config['syslog']['nentries']; +if (!$nentries) + $nentries = 50; + +if ($_POST['clear']) + file_put_contents(HVDEF_HAVP_ERRORLOG, ''); + +function dump_havp_errorlog($logfile, $tail) { + global $g, $config; + $sor = isset($config['syslog']['reverse']) ? "-r" : ""; + $logarr = ""; + $grepline = " "; + if (is_dir($logfile)) { + $logarr = array("File $logfile is a directory."); + } elseif(file_exists($logfile) && filesize($logfile) == 0) { + $logarr = array(" ... Log file is empty."); + } else { + exec("cat " . escapeshellarg($logfile) . "{$grepline} | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr); + } + foreach ($logarr as $logent) { + $logent = preg_split("/\s+/", $logent, 3); + echo "<tr valign=\"top\">\n"; + $entry_date_time = htmlspecialchars($logent[0] . " " . $logent[1]); + $entry_text = htmlspecialchars($logent[2]); + echo "<td class=\"listlr nowrap\" width=\"130\">{$entry_date_time}</td>\n"; + echo "<td class=\"listr\">{$entry_text}</td>\n"; + echo "</tr>\n"; + } +} + +$pgtitle = "Antivirus: HAVP log"; +include("head.inc"); + +?> + +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td> +<?php + $tab_array = array(); + $tab_array[] = array(gettext("General page"), false, "antivirus.php"); + $tab_array[] = array(gettext("HTTP proxy"), false, "pkg_edit.php?xml=havp.xml&id=0"); + $tab_array[] = array(gettext("Settings"), false, "pkg_edit.php?xml=havp_avset.xml&id=0"); + $tab_array[] = array(gettext("Log"), true, "havp_log.php"); + display_top_tabs($tab_array); +?> + </td></tr> + <tr> + <td> + <div id="mainarea"> + <table class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="0"> + <tr> + <td colspan="2" class="listtopic"> + <?php printf(gettext("Last %s HAVP log entries"), $nentries);?></td> + </tr> + <?php dump_havp_errorlog(HVDEF_HAVP_ERRORLOG, $nentries); ?> + <tr><td><br/> + <form action="havp_log.php" method="post"> + <input name="clear" type="submit" class="formbtn" value="<?=gettext("Clear log"); ?>" /></form></td></tr> + </table> + </div> + </td> + </tr> +</table> +<?php include("fend.inc"); ?> +</body> +</html> diff --git a/config/nut/nut.inc b/config/nut/nut.inc index 5a61d41a..aa0bbe13 100644 --- a/config/nut/nut.inc +++ b/config/nut/nut.inc @@ -185,6 +185,7 @@ $remoteuser = nut_config('remoteuser'); $remotepass = nut_config('remotepass'); $shutdownflag = (nut_config('powerdown') == 'on') ? '-p' : '-h'; + $custom_upsmonconf = str_replace(";", "\n", nut_config('custom_upsmonconf')); if(!($remotename && $remoteaddr && $remoteuser && $remotepass)) return false; @@ -195,6 +196,7 @@ MONITOR {$remotename}@{$remoteaddr} 1 {$remoteuser} {$remotepass} slave MINSUPPLIES 1 SHUTDOWNCMD "/sbin/shutdown {$shutdownflag} +0" POWERDOWNFLAG /etc/killpower +{$custom_upsmonconf} EOD; $stop = <<<EOD @@ -233,6 +235,10 @@ EOD; $allowuser = nut_config('allowuser'); $allowpass = nut_config('allowpass'); $shutdownflag = (nut_config('powerdown') == 'on') ? '-p' : '-h'; + $custom_upsconf = str_replace(";", "\n", nut_config('custom_upsconf')); + $custom_upsdconf = str_replace(";", "\n", nut_config('custom_upsdconf')); + $custom_upsdusers = str_replace(";", "\n", nut_config('custom_upsdusers')); + $custom_upsmonconf = str_replace(";", "\n", nut_config('custom_upsmonconf')); if(!($name && $driver && $port)) @@ -265,10 +271,12 @@ EOD; $ups_conf .= "cable={$cable}\n"; if($upstype) $ups_conf .= "upstype={$upstype}\n"; + $ups_conf .= "{$custom_upsconf}"; /* upsd.conf */ $upsd_conf = "LISTEN 127.0.0.1\n"; $upsd_conf .= "LISTEN ::1\n"; + $upsd_conf .= "{$custom_upsdconf}"; $password = uniqid("nut"); /* upsd.users */ @@ -280,6 +288,7 @@ EOD; $upsd_users .= "password = $allowpass\n"; $upsd_users .= "upsmon master\n"; } + $upsd_users .= "{$custom_upsdusers}"; if ($pfs_version == "2.1") $upsdrvctl = "/usr/local/libexec/nut/upsdrvctl"; @@ -292,6 +301,7 @@ MONITOR {$name}@localhost 1 monuser {$password} master MINSUPPLIES 1 SHUTDOWNCMD "/sbin/shutdown {$shutdownflag} +0" POWERDOWNFLAG /etc/killpower +{$custom_upsmonconf} EOD; $stop = <<<EOD @@ -366,6 +376,10 @@ EOD; $snmpdisabletransfer = (nut_config('snmpdisabletransfer') == 'on'); $allowuser = nut_config('allowuser'); $allowpass = nut_config('allowpass'); + $custom_upsconf = str_replace(";", "\n", nut_config('custom_upsconf')); + $custom_upsdconf = str_replace(";", "\n", nut_config('custom_upsdconf')); + $custom_upsdusers = str_replace(";", "\n", nut_config('custom_upsdusers')); + $custom_upsmonconf = str_replace(";", "\n", nut_config('custom_upsmonconf')); if(!($name && $driver && $port)) return false; @@ -386,10 +400,12 @@ EOD; $ups_conf .= "pollfreq={$snmpfreq}\n"; if($snmpdisabletransfer) $ups_conf .= "notransferoids=true\n"; + $ups_conf .= "{$custom_upsconf}"; /* upsd.conf */ $upsd_conf = "LISTEN 127.0.0.1\n"; $upsd_conf .= "LISTEN ::1\n"; + $upsd_conf .= "{$custom_upsdconf}"; $password = uniqid("nut"); /* upsd.users */ @@ -401,6 +417,7 @@ EOD; $upsd_users .= "password = $allowpass\n"; $upsd_users .= "upsmon master\n"; } + $upsd_users .= "{$custom_upsdusers}"; if ($pfs_version == "2.1") $upsdrvctl = "/usr/local/libexec/nut/upsdrvctl"; @@ -413,6 +430,7 @@ MONITOR {$name}@localhost 1 monuser {$password} master MINSUPPLIES 1 SHUTDOWNCMD "/sbin/shutdown {$shutdownflag} +0" POWERDOWNFLAG /etc/killpower +{$custom_upsmonconf} EOD; $stop = <<<EOD diff --git a/config/nut/nut.xml b/config/nut/nut.xml index 210d7b82..d1496a16 100644 --- a/config/nut/nut.xml +++ b/config/nut/nut.xml @@ -84,6 +84,7 @@ <chmod>0755</chmod> <item>https://packages.pfsense.org/packages/config/nut/status_nut.php</item> </additional_files_needed> + <advanced_options>enabled</advanced_options> <fields> <field> <name>General Settings</name> @@ -119,6 +120,42 @@ <type>checkbox</type> </field> <field> + <fielddescr>ups.conf options</fielddescr> + <fieldname>custom_upsconf</fieldname> + <description>Write there any custom options for ups.conf. All options must be separated by semi-colons (;).</description> + <type>textarea</type> + <cols>65</cols> + <rows>5</rows> + <advancedfield/> + </field> + <field> + <fielddescr>upsd.conf options</fielddescr> + <fieldname>custom_upsdconf</fieldname> + <description>Write there any custom options for upsd.conf. All options must be separated by semi-colons (;).</description> + <type>textarea</type> + <cols>65</cols> + <rows>5</rows> + <advancedfield/> + </field> + <field> + <fielddescr>upsd.users options</fielddescr> + <fieldname>custom_upsdusers</fieldname> + <description>Write there any custom options for upsd.users. All options must be separated by semi-colons (;).</description> + <type>textarea</type> + <cols>65</cols> + <rows>5</rows> + <advancedfield/> + </field> + <field> + <fielddescr>upsmon.conf options</fielddescr> + <fieldname>custom_upsmonconf</fieldname> + <description>Write there any custom options for upsmon.conf. All options must be separated by semi-colons (;).</description> + <type>textarea</type> + <cols>65</cols> + <rows>5</rows> + <advancedfield/> + </field> + <field> <name>Remote Access Settings - Used for Local and SNMP Types to allow access</name> <type>listtopic</type> </field> diff --git a/config/pfblockerng/countrycodes.tar.bz2 b/config/pfblockerng/countrycodes.tar.bz2 Binary files differnew file mode 100644 index 00000000..0884a882 --- /dev/null +++ b/config/pfblockerng/countrycodes.tar.bz2 diff --git a/config/pfblockerng/geoipupdate.sh b/config/pfblockerng/geoipupdate.sh new file mode 100644 index 00000000..4b8fbb63 --- /dev/null +++ b/config/pfblockerng/geoipupdate.sh @@ -0,0 +1,162 @@ +#!/bin/sh +# +# pfBlockerNG MaxMind GeoLite GeoIP Updater Script - By BBcan177@gmail.com +# Copyright (C) 2014 BBcan177@gmail.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License Version 2 as +# published by the Free Software Foundation. You may not use, modify or +# distribute this program under any other version of the GNU General +# Public License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The GeoLite databases by MaxMind Inc., are distributed under the Creative Commons +# Attribution-ShareAlike 3.0 Unported License. The attribution requirement +# may be met by including the following in all advertising and documentation +# mentioning features of or use of this database. + +# Folder Locations +pathfetch=/usr/bin/fetch +pathtar=/usr/bin/tar +pathgunzip=/usr/bin/gunzip + +# File Locations +pathdb=/var/db/pfblockerng +pathlog=/var/log/pfblockerng +errorlog=$pathlog/geoip.log +pathgeoipdatgz=$pathdb/GeoIP.dat.gz +pathgeoipdatgzv6=$pathdb/GeoIPv6.dat.gz +pathgeoipdat=$pathdb/GeoIP.dat +pathgeoipdatv6=$pathdb/GeoIPv6.dat +pathgeoipcc=$pathdb/country_continent.csv +pathgeoipcsv4=$pathdb/GeoIPCountryCSV.zip +pathgeoipcsvfinal4=$pathdb/GeoIPCountryWhois.csv +pathgeoipcsv6=$pathdb/GeoIPv6.csv.gz +pathgeoipcsvfinal6=$pathdb/GeoIPv6.csv + +if [ ! -d $pathdb ]; then mkdir $pathdb; fi +if [ ! -d $pathlog ]; then mkdir $pathlog; fi + +now=$(date) +echo; echo "$now - Updating pfBlockerNG - Country Database Files" +echo "pfBlockerNG uses GeoLite data created by MaxMind, available from http://www.maxmind.com"; echo + +#Function to update MaxMind GeoIP Binary (For Reputation Process) +binaryupdate() { + +# Download Part 1 - GeoLite IPv4 Binary Database + +echo " ** Downloading MaxMind GeoLite IPv4 Binary Database (For Reputation/Alerts Processes) **"; echo +URL="http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz" +$pathfetch -v -o $pathgeoipdatgz -T 20 $URL +if [ "$?" -eq "0" ]; then + $pathgunzip -f $pathgeoipdatgz + echo; echo " ( MaxMind IPv4 GeoIP.dat has been updated )"; echo + echo "Current Date/Timestamp:" + /bin/ls -alh $pathgeoipdat + echo +else + echo; echo " => MaxMind IPv4 GeoIP.dat Update [ FAILED ]"; echo + echo "MaxMind IPV4 Binary Update FAIL [ $now ]" >> $errorlog +fi + +# Download Part 2 - GeoLite IPv6 Binary Database + +echo; echo " ** Downloading MaxMind GeoLite IPv6 Binary Database (For Reputation/Alerts Processes) **"; echo +URL="http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz" +$pathfetch -v -o $pathgeoipdatgzv6 -T 20 $URL +if [ "$?" -eq "0" ]; then + $pathgunzip -f $pathgeoipdatgzv6 + echo; echo " ( MaxMind IPv6 GeoIPv6.dat has been updated )"; echo + echo "Current Date/Timestamp:" + /bin/ls -alh $pathgeoipdatv6 + echo +else + echo; echo " => MaxMind IPv6 GeoIPv6.dat Update [ FAILED ]"; echo + echo "MaxMind IPv6 Binary Update FAIL [ $now ]" >> $errorlog +fi +} + + +#Function to update MaxMind Country Code Files +csvupdate() { + +# Download Part 1 - CSV IPv4 Database + +echo; echo " ** Downloading MaxMind GeoLite IPv4 CSV Database **"; echo +URL="http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip" +$pathfetch -v -o $pathgeoipcsv4 -T 20 $URL +if [ "$?" -eq "0" ]; then + $pathtar -zxvf $pathgeoipcsv4 -C $pathdb + if [ "$?" -eq "0" ]; then + echo; echo " ( MaxMind GeoIPCountryWhois has been updated )"; echo + echo "Current Date/Timestamp:" + /bin/ls -alh $pathgeoipcsvfinal4 + echo + else + echo; echo " => MaxMind IPv4 GeoIPCountryWhois [ FAILED ]"; echo + echo "MaxMind CSV Database Update FAIL - Tar extract [ $now ]" >> $errorlog + fi +else + echo; echo " => MaxMind IPv4 CSV Download [ FAILED ]"; echo + echo "MaxMind CSV Database Update FAIL [ $now ]" >> $errorlog +fi + +# Download Part 2 - Country Definitions + +echo; echo " ** Downloading MaxMind GeoLite Database Country Definition File **"; echo +URL="http://dev.maxmind.com/static/csv/codes/country_continent.csv" +$pathfetch -v -o $pathgeoipcc -T 20 $URL +if [ "$?" -eq "0" ]; then + echo; echo " ( MaxMind ISO 3166 Country Codes has been updated. )"; echo + echo "Current Date/Timestamp:" + /bin/ls -alh $pathgeoipcc + echo +else + echo; echo " => MaxMind ISO 3166 Country Codes Update [ FAILED ]"; echo + echo "MaxMind ISO 3166 Country Code Update FAIL [ $now ]" >> $errorlog +fi + +# Download Part 3 - Country Definitions IPV6 + +echo " ** Downloading MaxMind GeoLite IPv6 CSV Database **"; echo +URL="http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz" +$pathfetch -v -o $pathgeoipcsv6 -T 20 $URL +if [ "$?" -eq "0" ]; then + $pathgunzip -f $pathgeoipcsv6 + echo; echo " ( MaxMind GeoIPv6.csv has been updated )"; echo + echo "Current Date/Timestamp:" + /bin/ls -alh $pathgeoipcsvfinal6 + echo +else + echo; echo " => MaxMind GeoLite IPv6 Update [ FAILED ]"; echo + echo "MaxMind GeoLite IPv6 Update FAIL [ $now ]" >> $errorlog +fi +} + + +# CALL APPROPRIATE PROCESSES using Script Argument $1 +case $1 in + bu) + binaryupdate + ;; + cu) + csvupdate + ;; + all) + binaryupdate + csvupdate + ;; + *) + exit + ;; +esac +exit
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc new file mode 100644 index 00000000..bc2ccfe1 --- /dev/null +++ b/config/pfblockerng/pfblockerng.inc @@ -0,0 +1,2505 @@ +<?php +/* + pfBlockerNG.inc + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + part of the Postfix package for pfSense + Copyright (C) 2010 Erik Fonnesbeck + Based upon pfBlocker by + Copyright (C) 2011-2012 Marcello Coutinho + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*/ + +//error_reporting(E_ALL); + +require_once("util.inc"); +require_once("functions.inc"); +require_once("pkg-utils.inc"); +require_once("pfsense-utils.inc"); +require_once("globals.inc"); +require_once("services.inc"); + +# [ $pfb ] pfBlockerNG Global Array for Paths and Variables. This needs to be called to get the Updated Settings. +function pfb_global() { + + global $g,$config,$pfb; + + # Folders + $pfb['dbdir'] = "{$g['vardb_path']}/pfblockerng"; + $pfb['aliasdir'] = "{$g['vardb_path']}/aliastables"; + $pfb['logdir'] = "{$g['varlog_path']}/pfblockerng"; + $pfb['etdir'] = "{$pfb['dbdir']}/ET"; + $pfb['ccdir'] = "{$pfb['dbdir']}/cc"; + $pfb['nativedir'] = "{$pfb['dbdir']}/native"; + $pfb['denydir'] = "{$pfb['dbdir']}/deny"; + $pfb['matchdir'] = "{$pfb['dbdir']}/match"; + $pfb['permitdir'] = "{$pfb['dbdir']}/permit"; + $pfb['origdir'] = "{$pfb['dbdir']}/original"; + + # Create Folders if not Exist. + $folder_array = array ("{$pfb['dbdir']}","{$pfb['logdir']}","{$pfb['ccdir']}","{$pfb['origdir']}","{$pfb['nativedir']}","{$pfb['denydir']}","{$pfb['matchdir']}","{$pfb['permitdir']}","{$pfb['aliasdir']}"); + foreach ($folder_array as $folder) { + safe_mkdir ("{$folder}",0755); + } + + # Files + $pfb['master'] = "{$pfb['dbdir']}/masterfile"; + $pfb['errlog'] = "{$pfb['logdir']}/error.log"; + $pfb['geolog'] = "{$pfb['logdir']}/geoip.log"; + $pfb['log'] = "{$pfb['logdir']}/pfblockerng.log"; + $pfb['supptxt'] = "{$pfb['dbdir']}/pfbsuppression.txt"; + $pfb['script'] = 'sh /usr/local/pkg/pfblockerng/pfblockerng.sh'; + + # Collect pfSense Version + $pfb['pfsenseversion'] = substr(trim(file_get_contents("/etc/version")),0,3); + + # General Variables + $pfb['config'] = $config['installedpackages']['pfblockerng']['config'][0]; + + # Enable/Disable of pfBlockerNG + $pfb['enable'] = $pfb['config']['enable_cb']; + # Keep Blocklists on pfBlockerNG Disable + $pfb['keep'] = $pfb['config']['pfb_keep']; + # Enable Suppression + $pfb['supp'] = $pfb['config']['suppression']; + # Max Lines in pfblockerng.log file + $pfb['logmax'] = $pfb['config']['log_maxlines']; + $pfb['iplocal'] = $config['interfaces']['lan']['ipaddr']; + # Disable Country Database CRON Updates + $pfb['cc'] = $pfb['config']['database_cc']; + + # Set pfBlockerNG to Disabled on 'Re-Install' + if (isset($pfb['install']) && $pfb['install']) { + $pfb['enable'] = ""; + $pfb['install'] = FALSE; + } +} + +pfb_global(); + +# Set Max PHP Memory Setting +$uname = posix_uname(); +if ($uname['machine'] == 'amd64') + ini_set('memory_limit', '256M'); + + +# Function to decode to Alias Custom Entry Box. +function pfbng_text_area_decode($text) { + return preg_replace('/\r\n/', "\n",base64_decode($text)); +} + + +# Manage Log File Line Limit +function pfb_log_mgmt() { + global $pfb; + pfb_global(); + + if ($pfb['logmax'] == "nolimit") { + # Skip Log Mgmt + } else { + exec("/usr/bin/tail -n {$pfb['logmax']} {$pfb['log']} > /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(); +} + + +# 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."); + + # Start of pfBlockerNG Logging to 'pfblockerng.log' + if ($pfb['enable'] == "on" && !$pfb['save']) { + $log = " UPDATE PROCESS START [ NOW ]\n"; + } else { + $log = "\n**Saving Configuration [ NOW ] ...\n"; + } + pfb_logger("{$log}","1"); + + # 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); + } + + # 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" + ); + + #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/'; # 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}'; + $pfb['ipv6'] = "/^($pattern1)$|^($pattern2)$|^($pattern3)$|^($pattern4)$|^($pattern5)$|^($pattern6)$|^($pattern7)$/"; + + $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"; + } + + # Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled. + $pfb_alias_lists_all[] = "{$alias}"; + + // Empty Header Field Validation Check + if (empty($header_url)) { + $log = "\n [ {$row['url']} ] {$log_tab} Header Field cannot be Empty. *Skipping* \n"; + pfb_logger("{$log}","2"); + continue; + } + + 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) { + # Network range 192.168.0.0-192.168.0.254 + if (preg_match($pfb['range'],$line,$matches)) { + $a_cidr = ip_range_to_subnet_array($matches[1],$matches[2]); + 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) { + # 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) { + # 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) { + # 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) { + # 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($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); + } + + ############################################# + # 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); + } + + + ############################################# + # 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"); + + $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(); + } 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"); + } + } else { + $log = "\n No 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"); + } +} + + +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(); + + # Uncompress Country Code File and delete Archive after extraction. + exec("cd /{$pfb['ccdir']}; /usr/bin/tar -jxvf {$pfb['ccdir']}/countrycodes.tar.bz2"); + unlink_if_exists("{$pfb['ccdir']}/countrycodes.tar.bz2"); + # Download MaxMind Files and Create Country Code files and Build Continent XML Files + update_output_window(gettext("Downloading MaxMind Country Databases. This may take a minute...")); + exec("/bin/sh /usr/local/pkg/pfblockerng/geoipupdate.sh all >> {$pfb['geolog']} 2>&1"); + 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...")); + + # 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 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']); + } + + # 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']; + + /* 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 diff --git a/config/pfblockerng/pfblockerng.js b/config/pfblockerng/pfblockerng.js new file mode 100644 index 00000000..cef0ce3b --- /dev/null +++ b/config/pfblockerng/pfblockerng.js @@ -0,0 +1,79 @@ +/* pfBlockerNG update engine */ + +// Part of pfBlockerNG by BBCan177@gmail.com (c) 2014 +// +// Javascript and Integration modifications by J. Nieuwenhuizen + + +var pfBlockerNGtimer; + +function pfBlockerNG_fetch_new_rules_callback(callback_data) { + var data_split; + var new_data_to_add = Array(); + var data = callback_data; + + data_split = data.split("\n"); + + // Loop through rows and generate replacement HTML + if (data_split.length > 1) { + for(var x=0; x<data_split.length-1; x++) { + row_split = data_split[x].split("||"); + if (row_split.length > 3) { + var line = ''; + line = '<td class="listMRr ellipsis">' + row_split[0] + '</td>'; + line += '<td class="listMRr" align="center">' + row_split[1] + '</td>'; + line += '<td class="listMRr" align="center">' + row_split[2] + '</td>'; + line += '<td class="listMRr" align="center">' + row_split[3] + '</td>'; + line += '<td class="listMRr" align="center">' + row_split[4] + '</td>'; + new_data_to_add[new_data_to_add.length] = line; + } + } + if (new_data_to_add.length > 0) { + pfBlockerNG_update_div_rows(new_data_to_add); + } + } +} + + +function pfBlockerNG_update_div_rows(data) { + var rows = jQuery('#pfbNG-entries>tr'); + + // Number of rows to move by + var move = rows.length + data.length; + if (move < 0) + move = 0; + + for (var i = rows.length - 1; i >= move; i--) { + jQuery(rows[i]).html(jQuery(rows[i - move]).html()); + } + + var tbody = jQuery('#pfbNG-entries'); + for (var i = data.length - 1; i >= 0; i--) { + if (i < rows.length) { + jQuery(rows[i]).html(data[i]); + } else { + jQuery(tbody).prepend('<tr>' + data[i] + '</tr>'); + } + } + + // Add the even/odd class to each of the rows now + // they have all been added. + rows = jQuery('#pfbNG-entries>tr'); + for (var i = 0; i < rows.length; i++) { + rows[i].className = i % 2 == 0 ? 'listMRodd' : 'listMReven'; + } +} + + +function fetch_new_pfBlockerNGcounts() { + jQuery.ajax('/widgets/widgets/pfblockerng.widget.php?getNewCounts=' + new Date().getTime(), { + type: 'GET', + dataType: 'text', + success: function(data) { + pfBlockerNG_fetch_new_rules_callback(data); + } + }); +} + +/* start local AJAX engine */ +pfBlockerNGtimer = setInterval('fetch_new_pfBlockerNGcounts()', pfBlockerNGupdateDelay);
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng.php b/config/pfblockerng/pfblockerng.php new file mode 100644 index 00000000..79f6c108 --- /dev/null +++ b/config/pfblockerng/pfblockerng.php @@ -0,0 +1,1578 @@ +<?php +/* + pfBlockerNG.php + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfBlocker by + Copyright (C) 2011-2012 Marcello Coutinho + All rights reserved. + + Hour Schedule Convertor code by + Snort Package + Copyright (c) 2014 Bill Meeks + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +*/ + +require_once("util.inc"); +require_once("functions.inc"); +require_once("pkg-utils.inc"); +require_once("globals.inc"); +require_once("services.inc"); +require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); + +pfb_global(); + +// 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_temp($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; +} + +# Set php Memory Limit +$uname = posix_uname(); +if ($uname['machine'] == "amd64") + ini_set('memory_limit', '256M'); + +function pfb_update_check($header_url, $list_url, $url_format) { + global $pfb; + + if ($url_format == "rsync" || $url_format == "html") { + $log = "[ {$header_url} ]\n Skipping timestamp query\n"; + pfb_logger("{$log}","1"); + return TRUE; + } + + switch ($url_format) { + case "gz": + case "gz_2": + case "gz_lg": + case "et": + $type = '.gz'; + break; + case "zip": + case "xlsx": + $type = '.zip'; + break; + case "txt": + $type = '.orig'; + break; + case "html": + case "block": + $type = '.raw'; + break; + } + + $log = "[ {$header_url} ]\n"; + pfb_logger("{$log}","1"); + $host = @parse_url($list_url); + $local_file = "{$pfb['origdir']}/{$header_url}{$type}"; + if (file_exists($local_file)) { + // Determine if URL is Remote or Local + if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) { + $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($local_file)); + } else { + $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers($list_url))); + $remote_tds = preg_replace("/^Last-Modified: /","", $remote_tds); + } + + $log = " Remote timestamp: {$remote_tds}\n"; + pfb_logger("{$log}","1"); + $local_tds = gmdate ("D, d M Y H:i:s T", filemtime($local_file)); + $log = " Local timestamp: {$local_tds}\n"; + pfb_logger("{$log}","1"); + if ("{$remote_tds}" != "{$local_tds}") { + return TRUE; + } else { + $log = " Remote file unchanged. Download Terminated\n"; + pfb_logger("{$log}","1"); + return FALSE; + } + } else { + return TRUE; + } +} + + +if ($argv[1] == 'update') { + sync_package_pfblockerng("cron"); +} + +if ($argv[1] == 'dc') { + # (Options - 'bu' Binary Update for Reputation/Alerts Page, 'all' for Country update and 'bu' options. + if ($pfb['cc'] == "") { + exec("/bin/sh /usr/local/pkg/pfblockerng/geoipupdate.sh all >> {$pfb['geolog']} 2>&1"); + } else { + exec("/bin/sh /usr/local/pkg/pfblockerng/geoipupdate.sh bu >> {$pfb['geolog']} 2>&1"); + } + pfblockerng_uc_countries(); + pfblockerng_get_countries(); +} + +if ($argv[1] == 'uc') { + pfblockerng_uc_countries(); +} + +if ($argv[1] == 'gc') { + pfblockerng_get_countries(); +} + +if ($argv[1] == 'cron') { + $hour = date('H'); + $dow = date('N'); + + # Start hour of the 'Once a day' Schedule + $pfb['dailystart'] = $config['installedpackages']['pfblockerng']['config'][0]['pfb_dailystart']; + # Start hour of the Scheduler + if ($config['installedpackages']['pfblockerng']['config'][0]['pfb_hour'] != "") { + $pfb['hour'] = $config['installedpackages']['pfblockerng']['config'][0]['pfb_hour']; + } else { + $pfb['hour'] = "1"; + } + $updates = 0; + + # 2 Hour Schedule Converter + $shour = intval(substr($pfb['hour'], 0, 2)); + $sch2 = strval($shour); + for ($i=0; $i<11; $i++) { + $shour += 2; + if ($shour > 24) + $shour -= 24; + $sch2 .= "," . strval($shour); + } + + # 3 Hour Schedule Converter + $shour = intval(substr($pfb['hour'], 0, 2)); + $sch3 = strval($shour); + for ($i=0; $i<7; $i++) { + $shour += 3; + if ($shour > 24) + $shour -= 24; + $sch3 .= "," . strval($shour); + } + + # 4 Hour Schedule Converter + $shour = intval(substr($pfb['hour'], 0, 2)); + $sch4 = strval($shour); + for ($i=0; $i<5; $i++) { + $shour += 4; + if ($shour > 24) + $shour -= 24; + $sch4 .= "," . strval($shour); + } + + # 6 Hour Schedule Converter + $shour = intval(substr($pfb['hour'], 0, 2)); + $sch6 = strval($shour); + for ($i=0; $i<3; $i++) { + $shour += 6; + if ($shour > 24) + $shour -= 24; + $sch6 .= "," . strval($shour); + } + + # 8 Hour Schedule Converter + $shour = intval(substr($pfb['hour'], 0, 2)); + $sch8 = strval($shour); + for ($i=0; $i<2; $i++) { + $shour += 8; + if ($shour > 24) + $shour -= 24; + $sch8 .= "," . strval($shour); + } + + # 12 Hour Schedule Converter + $shour = intval(substr($pfb['hour'], 0, 2)); + $sch12 = strval($shour) . ","; + $shour += 12; + if ($shour > 24) + $shour -= 24; + $sch12 .= strval($shour); + + $e_sch2 = explode(",", $sch2); + $e_sch3 = explode(",", $sch3); + $e_sch4 = explode(",", $sch4); + $e_sch6 = explode(",", $sch6); + $e_sch8 = explode(",", $sch8); + $e_sch12 = explode(",", $sch12); + + $log = " CRON PROCESS START [ NOW ]\n"; + pfb_logger("{$log}","1"); + + $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 (is_array($list['row']) && $list['action'] != "Disabled") { + foreach ($list['row'] as $row) { + if ($row['url'] != "" && $row['state'] != "Disabled") { + + if ($vtype == "_v4") { + $header_url = "{$row['header']}"; + } else { + $header_url = "{$row['header']}_v6"; + } + + # Determine Folder Location for Alias (return array $pfbarr) + pfb_determine_list_detail($list['action']); + $pfbfolder = $pfbarr['folder']; + + $list_cron = $list['cron']; + $list_url = $row['url']; + $header_dow = $list['dow']; + $url_format = $row['format']; + + // Bypass update if state is defined as "Hold" and list file exists + if (file_exists($pfbfolder . '/' . $header_url . '.txt') && $row['state'] == "Hold") { + continue; + } + + # Check if List file exists, if not found run Update + if (!file_exists($pfbfolder . '/' . $header_url . '.txt')) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + $updates++; + continue; + } + + switch ($list_cron) { + case "01hour": + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + break; + case "02hours": + if (in_array($hour, $e_sch2)) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + case "03hours": + if (in_array($hour, $e_sch3)) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + case "04hours": + if (in_array($hour, $e_sch4)) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + case "06hours": + if (in_array($hour, $e_sch6)) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + case "08hours": + if (in_array($hour, $e_sch8)) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + case "12hours": + if (in_array($hour, $e_sch12)) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + case "EveryDay": + if ($hour == $pfb['dailystart']) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + case "Weekly": + if ($hour == $pfb['dailystart'] && $dow == $header_dow) { + if (pfb_update_check($header_url, $list_url, $url_format)) { + $log = " Updates Found\n"; + pfb_logger("{$log}","1"); + unlink_if_exists($pfbfolder . '/' . $header_url . '.txt'); + $updates++; + } + } + break; + default: { + } + break; + } + } + } + } + } + } + } + + if ($updates > 0) { + sync_package_pfblockerng("cron"); + } else { + $log = "\n No Updates required. \n\n"; + pfb_logger("{$log}","1"); + } + + $log = " CRON PROCESS ENDED [ NOW ]\n"; + pfb_logger("{$log}","1"); + + # Call Log Mgmt Function + // If Update GUI 'Manual view' is selected. Last output will be missed. So sleep for 5 secs. + sleep(5); + pfb_log_mgmt(); +} + + +function pfblockerng_uc_countries() { + + global $g,$pfb; + pfb_global(); + + $maxmind_cont = "{$pfb['dbdir']}/country_continent.csv"; + $maxmind_cc4 = "{$pfb['dbdir']}/GeoIPCountryWhois.csv"; + $maxmind_cc6 = "{$pfb['dbdir']}/GeoIPv6.csv"; + + # Create Folders if not Exist + $folder_array = array ("{$pfb['dbdir']}","{$pfb['logdir']}","{$pfb['ccdir']}"); + foreach ($folder_array as $folder) { + safe_mkdir ("{$folder}",0755); + } + + $now = date("m/d/y G:i:s", time()); + $log = "Country Code Update Start - [ NOW ]\n\n"; + print "Country Code Update Start - [ $now ]\n\n"; + pfb_logger("{$log}","3"); + + if (!file_exists($maxmind_cont) || !file_exists($maxmind_cc4) || !file_exists($maxmind_cc6)) { + $log = " [ MAXMIND UPDATE FAIL, CSV Missing, using Previous Country Code Database \n"; + print $log; + pfb_logger("{$log}","3"); + return; + } + + # Save Date/Time Stamp to MaxMind version file + $maxmind_ver = "MaxMind GeoLite Date/Time Stamps \n\n"; + $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers("http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip"))); + $maxmind_ver .= "MaxMind_v4 \t" . $remote_tds . "\n"; + $local_tds = @gmdate ("D, d M Y H:i:s T", filemtime($maxmind_cc4)); + $maxmind_ver .= "Local_v4 \tLast-Modified: " . $local_tds . "\n\n"; + $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers("http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz"))); + $maxmind_ver .= "MaxMind_v6 \t" . $remote_tds . "\n"; + $local_tds = @gmdate ("D, d M Y H:i:s T", filemtime($maxmind_cc6)); + $maxmind_ver .= "Local_v6 \tLast-Modified: " . $local_tds . "\n"; + $maxmind_ver .= "\nThese Timestamps should *match* \n"; + @file_put_contents("{$pfb['logdir']}/maxmind_ver", $maxmind_ver); + + + // Collect ISO Codes for Each Continent + $log = "Processing Continent Data \n"; + print $log; + pfb_logger("{$log}","3"); + + $cont_array = array ( array($AF),array($AS),array($EU),array($NA),array($OC),array($SA)); + if (($handle = fopen("{$maxmind_cont}",'r')) !== FALSE) { + while (($cc = fgetcsv($handle)) !== FALSE) { + + $cc_key = $cc[0]; + $cont_key = $cc[1]; + switch ($cont_key) { + case "AF": + $cont_array[0]['continent'] = "Africa"; + $cont_array[0]['iso'] .= "{$cc_key},"; + $cont_array[0]['file4'] = "{$pfb['ccdir']}/Africa_v4.txt"; + $cont_array[0]['file6'] = "{$pfb['ccdir']}/Africa_v6.txt"; + break; + case "AS": + $cont_array[1]['continent'] = "Asia"; + $cont_array[1]['iso'] .= "{$cc_key},"; + $cont_array[1]['file4'] = "{$pfb['ccdir']}/Asia_v4.txt"; + $cont_array[1]['file6'] = "{$pfb['ccdir']}/Asia_v6.txt"; + break; + case "EU": + $cont_array[2]['continent'] = "Europe"; + $cont_array[2]['iso'] .= "{$cc_key},"; + $cont_array[2]['file4'] = "{$pfb['ccdir']}/Europe_v4.txt"; + $cont_array[2]['file6'] = "{$pfb['ccdir']}/Europe_v6.txt"; + break; + case "NA": + $cont_array[3]['continent'] = "North America"; + $cont_array[3]['iso'] .= "{$cc_key},"; + $cont_array[3]['file4'] = "{$pfb['ccdir']}/North_America_v4.txt"; + $cont_array[3]['file6'] = "{$pfb['ccdir']}/North_America_v6.txt"; + break; + case "OC": + $cont_array[4]['continent'] = "Oceania"; + $cont_array[4]['iso'] .= "{$cc_key},"; + $cont_array[4]['file4'] = "{$pfb['ccdir']}/Oceania_v4.txt"; + $cont_array[4]['file6'] = "{$pfb['ccdir']}/Oceania_v6.txt"; + break; + case "SA": + $cont_array[5]['continent'] = "South America"; + $cont_array[5]['iso'] .= "{$cc_key},"; + $cont_array[5]['file4'] = "{$pfb['ccdir']}/South_America_v4.txt"; + $cont_array[5]['file6'] = "{$pfb['ccdir']}/South_America_v6.txt"; + break; + } + } + } + unset($cc); + fclose($handle); + + // Collect Country ISO Data IPv4 and Sort to Continent Array + $log = "Processing ISO IPv4 Continent/Country Data \n"; + print $log; + pfb_logger("{$log}","3"); + + if (($handle = fopen("{$maxmind_cc4}",'r')) !== FALSE) { + while (($cc = fgetcsv($handle)) !== FALSE) { + + $ip1_key = $cc[0]; + $ip2_key = $cc[1]; + $var1_key = $cc[2]; + $var2_key = $cc[3]; + $cc_key = $cc[4]; + $country_key = $cc[5]; + $a_cidr = implode(",", ip_range_to_subnet_array_temp($cc[0],$cc[1])); + + $counter = 0; + foreach ($cont_array as $iso) { + if (preg_match("/\b$cc_key\b/", $iso['iso'])) { + $cont_array[$counter][$cc_key]['ip4'] .= $a_cidr . ","; + $cont_array[$counter][$cc_key]['country'] = $country_key; + continue; + } + $counter++; + } + } + } + unset($cc); + fclose($handle); + + // Build Continent IPv4 CIDR Files + $counter = 0; + foreach ($cont_array as $iso) { + $header = ""; + $pfb_file = ""; + $iso_key = ""; + $header .= "# Generated from MaxMind Inc. on: " . date("m/d/y G:i:s", time()) . "\n"; + $header .= "# Continent IPv4: " . $cont_array[$counter]['continent'] . "\n"; + $pfb_file = $cont_array[$counter]['file4']; + $iso_key = array_keys($iso); + foreach ($iso_key as $key) { + if (preg_match("/[A-Z]{2}/", $key)) { + $header .= "# Country: " . $iso[$key]['country'] . "\n"; + $header .= "# ISO Code: " . $key . "\n"; + $header .= "# Total Networks: " . substr_count($iso[$key]['ip4'], ",") . "\n"; + $header .= str_replace(",", "\n", $iso[$key]['ip4']); + $iso[$key]['ip4'] = ""; + } + } + $counter++; + @file_put_contents($pfb_file, $header, LOCK_EX); + } + + + // Collect Country ISO Data IPv6 and Sort to Continent Array + $log = "Processing ISO IPv6 Continent/Country Data \n"; + print $log; + pfb_logger("{$log}","3"); + + if (($handle = fopen("{$maxmind_cc6}",'r')) !== FALSE) { + while (($cc = fgetcsv($handle)) !== FALSE) { + + $ip1_key = $cc[0]; + $ip2_key = $cc[1]; + $var1_key = $cc[2]; + $var2_key = $cc[3]; + $cc_key = $cc[4]; + $country_key = $cc[5]; + $a_cidr = implode(",", ip_range_to_subnet_array_temp($cc[0],$cc[1])); + + $counter = 0; + foreach ($cont_array as $iso) { + if (preg_match("/\b$cc_key\b/", $iso['iso'])) { + $cont_array[$counter][$cc_key]['ip6'] .= $a_cidr . ","; + continue; + } + $counter++; + } + } + } + unset($cc); + fclose($handle); + + // Build Continent IPv6 Files + $counter = 0; + foreach ($cont_array as $iso) { + $header = ""; + $pfb_file = ""; + $iso_key = ""; + + $header .= "# Generated from MaxMind Inc. on: " . date("m/d/y G:i:s", time()) . "\n"; + $header .= "# Continent IPv6: " . $cont_array[$counter]['continent'] . "\n"; + $pfb_file = $cont_array[$counter]['file6']; + $iso_key = array_keys($iso); + foreach ($iso_key as $key) { + if (preg_match("/[A-Z]{2}/", $key)) { + $header .= "# Country: " . $iso[$key]['country'] . "\n"; + $header .= "# ISO Code: " . $key . "\n"; + $header .= "# Total Networks: " . substr_count($iso[$key]['ip6'], ",") . "\n"; + $header .= str_replace(",", "\n", $iso[$key]['ip6']); + $iso[$key]['ip6'] = ""; + } + } + $counter++; + @file_put_contents($pfb_file, $header, LOCK_EX); + } + unset($cont_array); +} + + +function pfblockerng_get_countries() { + + global $g,$pfb; + pfb_global(); + + # These arrays are used to collect the <option> tags for the XML Continent Files + $roptions4 = array(); + $coptions4 = array(); + $roptions6 = array(); + $coptions6 = array(); + + $files4 = array ( "Africa" => "{$pfb['ccdir']}/Africa_v4.txt", + "Asia" => "{$pfb['ccdir']}/Asia_v4.txt", + "Europe" => "{$pfb['ccdir']}/Europe_v4.txt", + "North America" => "{$pfb['ccdir']}/North_America_v4.txt", + "Oceania" => "{$pfb['ccdir']}/Oceania_v4.txt", + "South America" => "{$pfb['ccdir']}/South_America_v4.txt" + ); + + # IPv4 Collect Data to generate new continent XML Files. + $log = "Building pfBlockerNG XML Files \n"; + print $log; + pfb_logger("{$log}","3"); + + foreach ($files4 as $cont => $file) { + $log = "IPv4 " . $cont . "\n"; + print $log; + pfb_logger("{$log}","3"); + $ips = file_get_contents($file); + $convert = explode("\n", $ips); + $cont_name = preg_replace("/ /","",$cont); + $cont_name_lower = strtolower($cont_name); + $active = array( "$cont" => '<active/>'); + $total4 = 0; + $pfb['complete'] = FALSE; + + foreach ($convert as $line) { + if (preg_match("/#/",$line)) { + if ($pfb['complete']) { + $coptions4[] = $Country . '-' . $ISOCode . ' ('. $total4 .') ' . ' </name><value>' . $ISOCode . '</value></option>'; + $roptions4[] = $Country . '-' . $ISOCode . ' ('. $total4 .') ' . ' </name><value>' . $ISOCode . '</value></option>'; + + // Save ISO IPv4 Data + @file_put_contents($pfb['ccdir'] . '/' . $ISOCode . '_v4.txt',$pfb_v4,LOCK_EX); + + // Clear Variables and Restart Continent Collection process + $total4 = 0; + $pfb_v4 = ""; + $pfb['complete'] = FALSE; + } + if (preg_match("/Country:\s(.*)/",$line, $matches)) { $Country = $matches[1];} + if (preg_match("/ISO Code:\s(.*)/",$line, $matches)) { $ISOCode = $matches[1];} + } elseif (!preg_match("/#/",$line)) { + $total4++; + if (!empty($line)) + $pfb_v4 .= $line . "\n"; + $pfb['complete'] = TRUE; + } + } + unset ($ips, $convert); + + // Sort IPv4 Countries Alphabetically and Build XML <option> Data for Continents Tab + sort($coptions4, SORT_STRING); + $ftotal4 = count($coptions4); + $count = 1; + $options4 = ""; + + foreach ($coptions4 as $option4) { + if ($count == 1) { $options4 .= "\t" . '<option><name>' . $option4 . "\n"; $count++; continue;} + if ($ftotal4 == $count) { + $options4 .= "\t\t\t\t" . '<option><name>' . $option4; + } else { + $options4 .= "\t\t\t\t" . '<option><name>' . $option4 . "\n"; + } + $count++; + } + unset ($coptions4); + + // IPv6 Collect Data to generate new continent XML Files. + $file6 = preg_replace("/v4/", "v6", $file); + $ips = file_get_contents($file6); + $convert = explode("\n", $ips); + $log = "IPv6 " . $cont . "\n"; + pfb_logger("{$log}","3"); + $total6 = 0; + $pfb['complete'] = FALSE; + + foreach ($convert as $line) { + if (preg_match("/#/",$line)) { + if ($pfb['complete']) { + $coptions6[] = $Country . '-' . $ISOCode . ' ('. $total6 .') ' . ' </name><value>' . $ISOCode . '</value></option>'; + $roptions6[] = $Country . '-' . $ISOCode . ' ('. $total6 .') ' . ' </name><value>' . $ISOCode . '</value></option>'; + + // Save ISO IPv6 Data + @file_put_contents($pfb['ccdir'] . '/' . $ISOCode . '_v6.txt',$pfb_v6,LOCK_EX); + + // Clear Variables and Restart Continent Collection process + $total6 = 0; + $pfb_v6 = ""; + $pfb['complete'] = FALSE; + } + if (preg_match("/Country:\s(.*)/",$line, $matches)) { $Country = $matches[1];} + if (preg_match("/ISO Code:\s(.*)/",$line, $matches)) { $ISOCode = $matches[1];} + } elseif (!preg_match("/#/",$line)) { + $total6++; + if (!empty($line)) + $pfb_v6 .= $line . "\n"; + $pfb['complete'] = TRUE; + } + } + + // Sort IPv6 Countries Alphabetically for Continents Tab + sort($coptions6, SORT_STRING); + $ftotal6 = count($coptions6); + $count = 1; + $options6 = ""; + + foreach ($coptions6 as $option6) { + if ($count == 1) { $options6 .= "\t" . '<option><name>' . $option6 . "\n"; $count++; continue;} + if ($ftotal6 == $count) { + $options6 .= "\t\t\t\t" . '<option><name>' . $option6; + } else { + $options6 .= "\t\t\t\t" . '<option><name>' . $option6 . "\n"; + } + $count++; + } + unset ($coptions6); + + +$xml = <<<EOF +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* \$Id\$ */ +/* ========================================================================== */ +/* + pfblockerng_{$cont_name}.xml + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfblocker for pfSense + Copyright (C) 2011 Marcello Coutinho + All rights reserved. +*/ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS`` AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* ========================================================================== */ +]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfblockerng{$cont_name_lower}</name> + <version>1.0</version> + <title>pfBlockerNG: {$cont}</title> + <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file> + <menu> + <name>pfBlockerNG: {$cont_name}</name> + <tooltiptext>Configure pfBlockerNG</tooltiptext> + <section>Firewall</section> + <url>pkg_edit.php?xml=pfblockerng_{$cont_name_lower}.xml&id=0</url> + </menu> + <tabs> + <tab> + <text>General</text> + <url>/pkg_edit.php?xml=pfblockerng.xml&id=0</url> + </tab> + <tab> + <text>Update</text> + <url>/pfblockerng/pfblockerng_update.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pfblockerng/pfblockerng_alerts.php</url> + </tab> + <tab> + <text>Reputation</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0</url> + </tab> + <tab> + <text>IPv4</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url> + </tab> + <tab> + <text>IPv6</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url> + </tab> + <tab> + <text>Top 20</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0</url> + {$active['top']} + </tab> + <tab> + <text>Africa</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0</url> + {$active['Africa']} + </tab> + <tab> + <text>Asia</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0</url> + {$active['Asia']} + </tab> + <tab> + <text>Europe</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0</url> + {$active['Europe']} + </tab> + <tab> + <text>N.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0</url> + {$active['North America']} + </tab> + <tab> + <text>Oceania</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0</url> + {$active['Oceania']} + </tab> + <tab> + <text>S.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0</url> + {$active['South America']} + </tab> + <tab> + <text>Logs</text> + <url>/pfblockerng/pfblockerng_log.php</url> + </tab> + <tab> + <text>Sync</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0</url> + </tab> + </tabs> + <fields> + <field> + <name><![CDATA[Continent {$cont} (Geolite Data by MaxMind Inc. - ISO 3166)]]></name> + <type>listtopic</type> + </field> + <field> + <fielddescr>LINKS</fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> <a href="/firewall_rules.php">Firewall Rules</a> <a href="diag_logs_filter.php">Firewall Logs</a>]]> + </description> + <type>info</type> + </field> + <field> + <fielddescr><![CDATA[<br /><strong>IPv4</strong><br />Countries]]></fielddescr> + <fieldname>countries4</fieldname> + <description> + <![CDATA[Select IPv4 Countries you want to take an action on.<br /> + <strong>Use CTRL + CLICK to unselect countries</strong>]]> + </description> + <type>select</type> + <options> + {$options4} + </options> + <size>{$ftotal4}</size> + <multiple/> + </field> + <field> + <fielddescr><![CDATA[<br /><strong>IPv6</strong><br />Countries]]></fielddescr> + <fieldname>countries6</fieldname> + <description> + <![CDATA[Select IPv6 Countries you want to take an action on.<br /> + <strong>Use CTRL + CLICK to unselect countries</strong>]]> + </description> + <type>select</type> + <options> + {$options6} + </options> + <size>{$ftotal6}</size> + <multiple/> + </field> + <field> + <fielddescr>List Action</fielddescr> + <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br /> + Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br /> + <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br /> + + <strong><u>'Deny' Rules:</u></strong><br /> + 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other + interfaces. Typical uses of 'Deny' rules are:<br /> + <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li> + <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by + traffic sent in the other direction. Does not affect traffic in the other direction. </li> + <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while + still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul> + <strong><u>'Permit' Rules:</u></strong><br /> + 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create + any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br /> + <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They + override <u>almost all other</u> Firewall rules on the stated interfaces.</li> + <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a + few IPs that should be accessible.</li></ul> + <strong><u>'Match' Rules:</u></strong><br /> + 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic. + <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li> + <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul> + <strong><u>'Alias' Rules:</u></strong><br /> + <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else). + This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired. + <ul><li><strong>Options - Alias Deny, Alias Permit, Alias Match, Alias Native</strong></li><br /> + <li>'Alias Deny' can use De-Duplication and Reputation Processes if configured.</li><br /> + <li>'Alias Permit' and 'Alias Match' will be saved in the Same folder as the other Permit/Match Auto-Rules</li><br /> + <li>'Alias Native' lists are kept in their Native format without any modifications.</li></ul> + <strong>When using 'Alias' rules, change (pfB_) to ( pfb_ ) in the beginning of rule description and use the 'Exact' spelling of + the Alias (no trailing Whitespace) </strong> Custom 'Alias' rules with 'pfB_ xxx' description will be removed by package if + using Auto Rule Creation.<br /><br /><strong>Tip</strong>: You can create the Auto Rules and remove "<u>auto rule</u>" from the Rule + Descriptions, then disable Auto Rules. This method will 'KEEP' these rules from being 'Deleted' which will allow editing for a Custom + Alias Configuration<br />]]> + </description> + <fieldname>action</fieldname> + <type>select</type> + <options> + <option><name>Disabled</name><value>Disabled</value></option> + <option><name>Deny Inbound</name><value>Deny_Inbound</value></option> + <option><name>Deny Outbound</name><value>Deny_Outbound</value></option> + <option><name>Deny Both</name><value>Deny_Both</value></option> + <option><name>Permit Inbound</name><value>Permit_Inbound</value></option> + <option><name>Permit Outbound</name><value>Permit_Outbound</value></option> + <option><name>Permit Both</name><value>Permit_Both</value></option> + <option><name>Match Inbound</name><value>Match_Inbound</value></option> + <option><name>Match Outbound</name><value>Match_Outbound</value></option> + <option><name>Match Both</name><value>Match_Both</value></option> + <option><name>Alias Deny</name><value>Alias_Deny</value></option> + <option><name>Alias Permit</name><value>Alias_Permit</value></option> + <option><name>Alias Match</name><value>Alias_Match</value></option> + <option><name>Alias Native</name><value>Alias_Native</value></option> + </options> + </field> + <field> + <fielddescr>Enable Logging</fielddescr> + <fieldname>aliaslog</fieldname> + <description><![CDATA[Default:<strong>Enable</strong><br /> + Select - Logging to Status: System Logs: FIREWALL ( Log )<br /> + This can be overriden by the 'Global Logging' Option in the General Tab.]]></description> + <type>select</type> + <options> + <option><name>Enable</name><value>enabled</value></option> + <option><name>Disable</name><value>disabled</value></option> + </options> + </field> + <field> + <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. Changes are Applied via CRON or + 'Force Update'</ul>]]> + </name> + <type>listtopic</type> + </field> + </fields> + <custom_php_install_command> + pfblockerng_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + pfblockerng_php_deinstall_command(); + </custom_php_deinstall_command> + <custom_php_validation_command> + pfblockerng_validate_input(\$_POST, \$input_errors); + </custom_php_validation_command> + <custom_php_resync_config_command> + global \$pfb; + \$pfb['save'] = TRUE; + sync_package_pfblockerng(); + </custom_php_resync_config_command> +</packagegui> +EOF; + + // Update Each Continent XML file. + @file_put_contents('/usr/local/pkg/pfblockerng/pfblockerng_'.$cont_name.'.xml',$xml,LOCK_EX); + + } // End foreach 'Six Continents' Update XML Process + + + // Sort Countries IPv4 Alphabetically and Build XML <option> Data for Reputation Tab (IPv6 not used by ET IQRisk) + sort($roptions4, SORT_STRING); + $eoa = count($roptions4); + $count = 1; + $options4 = ""; + + foreach ($roptions4 as $option4) { + if ($count == 1) { $et_options .= "\t" . '<option><name>' . $option4 . "\n"; $count++; continue; } + if ($eoa == $count) { + $et_options .= "\t\t\t\t" . '<option><name>' . $option4; + } else { + $et_options .= "\t\t\t\t" . '<option><name>' . $option4 . "\n"; + } + $count++; + } + + +// Update pfBlockerNG_Reputation.xml file with Country Code Changes + + +$xmlrep = <<<EOF +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* \$Id\$ */ +/* ========================================================================== */ +/* + pfBlockerNG_Reputation.xml + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfblocker for pfSense + Copyright (C) 2011 Marcello Coutinho + All rights reserved. + +*/ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfblockerngreputation</name> + <version>1.0</version> + <title>pfBlockerNG: IPv4 Reputation</title> + <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file> + <menu> + <name>pfBlockerNG</name> + <tooltiptext>Configure pfblockerNG</tooltiptext> + <section>Firewall</section> + <url>pkg_edit.php?xml=pfblockerng.xml&id=0</url> + </menu> + <tabs> + <tab> + <text>General</text> + <url>/pkg_edit.php?xml=pfblockerng.xml&id=0</url> + </tab> + <tab> + <text>Update</text> + <url>/pfblockerng/pfblockerng_update.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pfblockerng/pfblockerng_alerts.php</url> + </tab> + <tab> + <text>Reputation</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0</url> + <active/> + </tab> + <tab> + <text>IPv4</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url> + </tab> + <tab> + <text>IPv6</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url> + </tab> + <tab> + <text>Top 20</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0</url> + </tab> + <tab> + <text>Africa</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0</url> + </tab> + <tab> + <text>Asia</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0</url> + </tab> + <tab> + <text>Europe</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0</url> + </tab> + <tab> + <text>N.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Oceania</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0</url> + </tab> + <tab> + <text>S.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Logs</text> + <url>/pfblockerng/pfblockerng_log.php</url> + </tab> + <tab> + <text>Sync</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0</url> + </tab> + </tabs> + <fields> + <field> + <name>IPv4 Reputation Preface</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>LINKS</fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> <a href="/firewall_rules.php">Firewall Rules</a> <a href="diag_logs_filter.php">Firewall Logs</a>]]> + </description> + <type>info</type> + </field> + <field> + <fielddescr><![CDATA[<strong>Why Reputation Matters:</strong>]]></fielddescr> + <fieldname>why</fieldname> + <type>info</type> + <description><![CDATA[By Enabling '<strong>Reputation</strong>', each Blocklist will be analyzed for Repeat Offenders in each IP Range. + <ul>Example: x.x.x.1, x.x.x.2, x.x.x.3, x.x.x.4, x.x.x.5<br /> + No. of <strong> Repeat Offending IPs </strong> [ <strong>5</strong> ], in a Blocklist within the same IP Range.</ul> + With '<strong>Reputation</strong> enabled, these 5 IPs will be removed and a single + <strong>x.x.x.0/24</strong> Block is used.<br /> + This will completely Block/Reject this particular range from your Firewall.<br /><br /> + Selecting Blocklists from various Threat Sources will help to highlight Repeat Offending IP Ranges,<br /> + Its Important to select a Broad Range of Blocklists that cover different types of Malicious Activity.<br /><br /> + You *may* experience some False Positives. Add any False Positive IPs manually to the<br /> + <strong>pfBlockerNGSuppress Alias</strong> or use the "+" suppression Icon in the Alerts TAB<br /><br /> + To help mitigate False Positives 'Countries' can be '<strong>Excluded</strong>' from this Process. (Refer to Country Code Settings)]]> + </description> + </field> + <field> + <name>Reputation Settings:</name> + <type>listtopic</type> + </field> + <field> + <fieldname></fieldname> + <fielddescr><![CDATA[<br /><strong>Individual List Reputation</strong><br /><br />]]></fielddescr> + <type>info</type> + <description></description> + </field> + <field> + <fielddescr><![CDATA[Enable Max]]></fielddescr> + <fieldname>enable_rep</fieldname> + <type>checkbox</type> + <description><![CDATA[Enables Search for Repeat Offenders in a /24 Range on <strong>Each Individual Blocklist</strong>]]></description> + </field> + <field> + <fielddescr><![CDATA[ [ <strong>Max</strong> ] Setting]]></fielddescr> + <fieldname>p24_max_var</fieldname> + <description><![CDATA[Default: <strong>5</strong><br /> + Maximum number of Repeat Offenders allowed in a Single IP Range]]></description> + <type>select</type> + <options> + <option><name>5</name><value>5</value></option> + <option><name>10</name><value>10</value></option> + <option><name>15</name><value>15</value></option> + <option><name>20</name><value>20</value></option> + <option><name>25</name><value>25</value></option> + <option><name>50</name><value>50</value></option> + </options> + </field> + <field> + <fieldname></fieldname> + <fielddescr><![CDATA[<br /><strong>Collective List Reputation</strong><br /><br />]]></fielddescr> + <type>info</type> + <description></description> + </field> + <field> + <fieldname></fieldname> + <type>info</type> + <description><![CDATA[Once all Blocklists are Downloaded, these two 'additional' processes <strong>[ pMax ] and [ dMax ]</strong><br /> + Can be used to Further analyze for Repeat Offenders.<br /> + <ul>Analyzing All Blocklists as a Whole:</ul> + <ul><strong>[ pMax ]</strong> will analyze for Repeat Offenders in each IP Range but will not use the Country Exclusion.<br /> + Default is 50 IPs in any Range. Having 50 Repeat Offenders IPs in any Range will Block the entire Range.<br /><br /></ul> + <ul><strong>[ dMax ]</strong> will analyze for Repeat Offenders in each IP Range. Country Exclusions will be applied.<br /> + Default is 5 IPs in any Range.</ul> + Note: <strong>MAX</strong> performs on individual Blocklists, while <strong>pMAX / dMAX</strong> + perform on all Lists together.<br />]]> + </description> + </field> + <field> + <fielddescr>Enable pMAX</fielddescr> + <fieldname>enable_pdup</fieldname> + <type>checkbox</type> + <description><![CDATA[Enables Search for Repeat Offenders in All BlockLists, <strong>Without</strong> Country Code Exclusion]]> + </description> + </field> + <field> + <fielddescr><![CDATA[ [ <strong>pMax</strong> ] Setting]]></fielddescr> + <fieldname>p24_pmax_var</fieldname> + <description><![CDATA[Default: <strong>50</strong><br />Maximum number of Repeat Offenders]]></description> + <type>select</type> + <options> + <option><name>50</name><value>50</value></option> + <option><name>25</name><value>25</value></option> + <option><name>20</name><value>20</value></option> + <option><name>15</name><value>15</value></option> + <option><name>10</name><value>10</value></option> + <option><name>5</name><value>5</value></option> + </options> + </field> + <field> + <fielddescr>Enable dMAX</fielddescr> + <fieldname>enable_dedup</fieldname> + <type>checkbox</type> + <description><![CDATA[Enables Search for Repeat Offenders in All BlockLists <strong>Using</strong> Country Code Exclusion]]> + </description> + </field> + <field> + <fielddescr><![CDATA[ [ <strong>dMax</strong> ] Setting]]></fielddescr> + <fieldname>p24_dmax_var</fieldname> + <description><![CDATA[Default: <strong>5</strong><br /> + Maximum number of Repeat Offenders]]></description> + <type>select</type> + <options> + <option><name>5</name><value>5</value></option> + <option><name>10</name><value>10</value></option> + <option><name>15</name><value>15</value></option> + <option><name>20</name><value>20</value></option> + <option><name>25</name><value>25</value></option> + <option><name>50</name><value>50</value></option> + </options> + </field> + <field> + <name>Country Code Settings</name> + <type>listtopic</type> + </field> + <field> + <fieldname>INFO</fieldname> + <type>info</type> + <description><![CDATA[When performing Queries for Repeat Offenders, you can choose to <strong>ignore</strong> Repeat Offenders in select + Countries. The Original Blocklisted IPs remain intact. All other Repeat Offending Country Ranges will be processed.<br /><br /> + Define Repeat Offending Ranges [ <strong>Action</strong> ] Available settings are:<br /> + <ul><strong>Ignore</strong>: Repeat Offenders that are in the 'ccwhite' category will be 'Ignored' (Default)</ul> + <ul><strong>Block:</strong> Repeat Offenders are set to Block the entire Repeat Offending Range(s)</ul> + <ul><strong>Match:</strong> Repeat Offenders are added to a 'Match' List which can be used in a Floating Match Rule<br /> + Selecting 'Match' will consume more processing time, so only select this option if you enable Rules for it.</ul> + '<strong>ccwhite</strong>' are Countries that are Selected to be excluded from the Repeat Offenders Search.<br /> + '<strong>ccblack</strong>' are all other Countries that are not selected.<br /><br /> + To use '<strong>Match</strong>' Lists, Create a new 'Alias' + and select one of the <strong>Action 'Match'</strong> Formats and<br /> enter the 'Localfile' as: + <ul>/var/db/pfblockerng/match/matchdedup.txt</ul>]]> + </description> + </field> + <field> + <fielddescr>ccwhite Action:</fielddescr> + <fieldname>ccwhite</fieldname> + <description><![CDATA[Default: <strong>Ignore</strong><br /> + Select the 'Action' format for ccwhite]]> + </description> + <type>select</type> + <options> + <option><name>Ignore</name><value>ignore</value></option> + <option><name>Match</name><value>match</value></option> + </options> + </field> + <field> + <fielddescr>ccblack Action:</fielddescr> + <fieldname>ccblack</fieldname> + <description><![CDATA[Default: <strong>Block</strong><br /> + Select the 'Action' format for ccblack]]> + </description> + <type>select</type> + <options> + <option><name>Block</name><value>block</value></option> + <option><name>Match</name><value>match</value></option> + </options> + </field> + <field> + <fielddescr><![CDATA[<br /><strong>IPv4</strong><br />Country Exclusion<br /> + <br />Geolite Data by:<br />MaxMind Inc. (ISO 3166)]]></fielddescr> + <fieldname>ccexclude</fieldname> + <description> + <![CDATA[Select Countries you want to <strong>Exclude</strong> from the Reputation Process.<br /> + <strong>Use CTRL + CLICK to unselect countries</strong>]]> + </description> + <type>select</type> + <options> + {$et_options} + </options> + <size>20</size> + <multiple/> + </field> + <field> + <name>Emerging Threats IQRISK IPv4 Reputation</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>Subscription Pro. Blocklist</fielddescr> + <fieldname>ETINFO</fieldname> + <type>info</type> + <description><![CDATA[<strong>Emerging Threats IQRisk</strong> is a Subscription Professional Reputation List.<br /><br /> + ET IQRisk Blocklist must be entered in the Lists Tab using the following example: + <ul>https://rules.emergingthreatspro.com/XXXXXXXXXXXXXXXX/reputation/iprepdata.txt.gz</ul> + Select the <strong>ET IQRisk'</strong> format. The URL should use the .gz File Type.<br /> + Enter your "ETPRO" code in URL. Further information can be found @ + <a target=_new href='http://emergingthreats.net/solutions/iqrisk-suite/'>ET IQRisk IP Reputation</a><br /><br /> + To use <strong>'Match'</strong> Lists, Create a new 'Alias' and select one of the <strong> + Action 'Match'</strong> Formats and <br /> + enter the 'Localfile' as: <ul>/var/db/pfblockerng/match/ETMatch.txt</ul> + ET IQRisk Individual Match Lists can be found in the following folder:<br /> + <ul>/var/db/pfblockerng/ET</ul> ]]> + </description> + </field> + <field> + <fielddescr>ET IQRisk Header Name</fielddescr> + <fieldname>et_header</fieldname> + <type>input</type> + <description><![CDATA[Enter the 'Header Name' referenced in the IPv4 List TAB for ET IQRisk IPRep.<br /> + This will be used to improve the Alerts TAB reporting for ET IPRep.]]> + </description> + </field> + <field> + <fielddescr>ET IQRISK BLOCK LISTS</fielddescr> + <fieldname>etblock</fieldname> + <description> + <![CDATA[Select Lists you want to BLOCK.<br /> + <strong>Use CTRL + CLICK to unselect Categories</strong> + <br /><br />Any Changes will take effect at the Next Scheduled CRON Task]]> + </description> + <type>select</type> + <options> + <option><name>ET CNC</name><value>ET_Cnc</value></option> + <option><name>ET BOT</name><value>ET_Bot</value></option> + <option><name>ET SPAM</name><value>ET_Spam</value></option> + <option><name>ET DROP</name><value>ET_Drop</value></option> + <option><name>ET Spyware CNC</name><value>ET_Spywarecnc</value></option> + <option><name>ET Online Gaming</name><value>ET_Onlinegaming</value></option> + <option><name>ET DrivebySRC</name><value>ET_Drivebysrc</value></option> + <option><name>ET Chat Server</name><value>ET_Chatserver</value></option> + <option><name>ET TOR Node</name><value>ET_Tornode</value></option> + <option><name>ET Compromised</name><value>ET_Compromised</value></option> + <option><name>ET P2P</name><value>ET_P2P</value></option> + <option><name>ET Proxy</name><value>ET_Proxy</value></option> + <option><name>ET IP Check</name><value>ET_Ipcheck</value></option> + <option><name>ET Utility</name><value>ET_Utility</value></option> + <option><name>ET DOS</name><value>ET_DDos</value></option> + <option><name>ET Scanner</name><value>ET_Scanner</value></option> + <option><name>ET Brute</name><value>ET_Brute</value></option> + <option><name>ET Fake AV</name><value>ET_Fakeav</value></option> + <option><name>ET DYN DNS</name><value>ET_Dyndns</value></option> + <option><name>ET Undersireable</name><value>ET_Undesireable</value></option> + <option><name>ET Abuse TLD</name><value>ET_Abusedtld</value></option> + <option><name>ET SelfSigned SSL</name><value>ET_Selfsignedssl</value></option> + <option><name>ET Blackhole</name><value>ET_Blackhole</value></option> + <option><name>ET RAS</name><value>ET_RAS</value></option> + <option><name>ET P2P CNC</name><value>ET_P2Pcnc</value></option> + <option><name>ET Shared Hosting</name><value>ET_Sharedhosting</value></option> + <option><name>ET Parking</name><value>ET_Parking</value></option> + <option><name>ET VPN</name><value>ET_VPN</value></option> + <option><name>ET EXE Source</name><value>ET_Exesource</value></option> + <option><name>ET Mobile CNC</name><value>ET_Mobilecnc</value></option> + <option><name>ET Mobile Spyware</name><value>ET_Mobilespyware</value></option> + <option><name>ET Skype Node</name><value>ET_Skypenode</value></option> + <option><name>ET Bitcoin</name><value>ET_Bitcoin</value></option> + <option><name>ET DOS Attack</name><value>ET_DDosattack</value></option> + <option><name>Unknown</name><value>ET_Unknown</value></option> + </options> + <size>35</size> + <multiple/> + </field> + <field> + <fielddescr>ET IQRISK Match LISTS</fielddescr> + <fieldname>etmatch</fieldname> + <description> + <![CDATA[Select Lists you want to MATCH.<br /> + <strong>Use CTRL + CLICK to unselect Categories</strong> + <br /><br />Any Changes will take effect at the Next Scheduled CRON Task]]> + </description> + <type>select</type> + <options> + <option><name>ET CNC</name><value>ET_Cnc</value></option> + <option><name>ET BOT</name><value>ET_Bot</value></option> + <option><name>ET SPAM</name><value>ET_Spam</value></option> + <option><name>ET DROP</name><value>ET_Drop</value></option> + <option><name>ET Spyware CNC</name><value>ET_Spywarecnc</value></option> + <option><name>ET Online Gaming</name><value>ET_Onlinegaming</value></option> + <option><name>ET DrivebySRC</name><value>ET_Drivebysrc</value></option> + <option><name>ET Chat Server</name><value>ET_Chatserver</value></option> + <option><name>ET TOR Node</name><value>ET_Tornode</value></option> + <option><name>ET Compromised</name><value>ET_Compromised</value></option> + <option><name>ET P2P</name><value>ET_P2P</value></option> + <option><name>ET Proxy</name><value>ET_Proxy</value></option> + <option><name>ET IP Check</name><value>ET_Ipcheck</value></option> + <option><name>ET Utility</name><value>ET_Utility</value></option> + <option><name>ET DOS</name><value>ET_DDos</value></option> + <option><name>ET Scanner</name><value>ET_Scanner</value></option> + <option><name>ET Brute</name><value>ET_Brute</value></option> + <option><name>ET Fake AV</name><value>ET_Fakeav</value></option> + <option><name>ET DYN DNS</name><value>ET_Dyndns</value></option> + <option><name>ET Undersireable</name><value>ET_Undesireable</value></option> + <option><name>ET Abuse TLD</name><value>ET_Abusedtld</value></option> + <option><name>ET SelfSigned SSL</name><value>ET_Selfsignedssl</value></option> + <option><name>ET Blackhole</name><value>ET_Blackhole</value></option> + <option><name>ET RAS</name><value>ET_RAS</value></option> + <option><name>ET P2P CNC</name><value>ET_P2Pcnc</value></option> + <option><name>ET Shared Hosting</name><value>ET_Sharedhosting</value></option> + <option><name>ET Parking</name><value>ET_Parking</value></option> + <option><name>ET VPN</name><value>ET_VPN</value></option> + <option><name>ET EXE Source</name><value>ET_Exesource</value></option> + <option><name>ET Mobile CNC</name><value>ET_Mobilecnc</value></option> + <option><name>ET Mobile Spyware</name><value>ET_Mobilespyware</value></option> + <option><name>ET Skype Node</name><value>ET_Skypenode</value></option> + <option><name>ET Bitcoin</name><value>ET_Bitcoin</value></option> + <option><name>ET DOS Attack</name><value>ET_DDosattack</value></option> + <option><name>Unknown</name><value>ET_Unknown</value></option> + </options> + <size>35</size> + <multiple/> + </field> + <field> + <fielddescr>Update ET Categories</fielddescr> + <fieldname>et_update</fieldname> + <description><![CDATA[Default:<strong>Disable</strong><br /> + Select - Enable ET Update if Category Changes are Made.<br /> + You can perform a 'Force Update' to enable these changes.<br /> + Cron will also resync this list at the next Scheduled Update.]]> + </description> + <type>select</type> + <options> + <option><name>Disable</name><value>disabled</value></option> + <option><name>Enable</name><value>enabled</value></option> + </options> + </field> + <field> + <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. Changes are Applied via CRON or + 'Force Update'</ul>]]></name> + <type>listtopic</type> + </field> + </fields> + <custom_php_install_command> + pfblockerng_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + pfblockerng_php_deinstall_command(); + </custom_php_deinstall_command> + <custom_php_validation_command> + pfblockerng_validate_input(\$_POST, \$input_errors); + </custom_php_validation_command> + <custom_php_resync_config_command> + global \$pfb; + \$pfb['save'] = TRUE; + sync_package_pfblockerng(); + </custom_php_resync_config_command> +</packagegui> +EOF; + # Unset Arrays + unset ($options4, $options6, $et_options); + + $log = "Saving pfBlockerNG Reputation TAB \n"; + print $log; + pfb_logger("{$log}","3"); + + // Save pfBlockerng_reputation.xml file + @file_put_contents('/usr/local/pkg/pfblockerng/pfblockerng_reputation.xml',$xmlrep,LOCK_EX); + $log = "\n Country Code - XML File Update completed.\n"; + print $log; + pfb_logger("{$log}","3"); + + $now = date("m/d/y G.i:s", time()); + $log = "Country Code Update Ended - [ NOW ]\n"; + print "Country Code Update Ended - [ $now ]\n"; + pfb_logger("{$log}","3"); +} +?>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng.priv.inc b/config/pfblockerng/pfblockerng.priv.inc new file mode 100644 index 00000000..092c34ae --- /dev/null +++ b/config/pfblockerng/pfblockerng.priv.inc @@ -0,0 +1,29 @@ +<?php + +global $priv_list; + +$priv_list['page-firewall-pfblockerng'] = array(); +$priv_list['page-firewall-pfblockerng']['name'] = "WebCfg - Firewall: pfBlockerNG"; +$priv_list['page-firewall-pfblockerng']['descr'] = "Allow access to pfBlockerNG package gui"; +$priv_list['page-firewall-pfblockerng']['match'] = array(); +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_reputation.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_v4lists.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_v6lists.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_top20.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Africa.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Asia.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Europe.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_NorthAmerica.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Oceania.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_SouthAmerica.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_sync.xml*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_update.php*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_alerts.php*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_log.php*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_diag_dns.php*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "widgets/javascript/pfblockerng.js*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "widgets/include/widget-pfblockerng.inc*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "widgets/widgets/pfblockerng.widget.php*"; +$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng.inc*"; +?>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng.sh b/config/pfblockerng/pfblockerng.sh new file mode 100644 index 00000000..c09d52e1 --- /dev/null +++ b/config/pfblockerng/pfblockerng.sh @@ -0,0 +1,927 @@ +#!/bin/sh +# pfBlockerNG IP Reputation Script - By BBcan177@gmail.com - 04-12-14 +# Copyright (C) 2014 BBcan177@gmail.com +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License Version 2 as +# published by the Free Software Foundation. You may not use, modify or +# distribute this program under any other version of the GNU General +# Public License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +now=$(/bin/date +%m/%d/%y' '%T) +mtype=$(/usr/bin/uname -m); + +# Application Paths +pathgrepcidr="/usr/pbi/pfblockerng-$mtype/bin/grepcidr" +pathgeoip="/usr/pbi/pfblockerng-$mtype/bin/geoiplookup" + +pathtar=/usr/bin/tar +pathgunzip=/usr/bin/gunzip +pathpfctl=/sbin/pfctl + +# Script Arguments +alias=$2 +max=$3 +dedup=$4 +cc=$(echo $5 | sed 's/,/, /g') +ccwhite=$(echo $6 | tr '[A-Z]' '[a-z]') +ccblack=$(echo $7 | tr '[A-Z]' '[a-z]') +etblock=$(echo $8 | sed 's/,/, /g') +etmatch=$(echo $9 | sed 's/,/, /g') + +# File Locations +pathgeoipdat=/var/db/pfblockerng/GeoIP.dat +pfbsuppression=/var/db/pfblockerng/pfbsuppression.txt +masterfile=/var/db/pfblockerng/masterfile +mastercat=/var/db/pfblockerng/mastercat +geoiplog=/var/log/pfblockerng/geoip.log +errorlog=/var/log/pfblockerng/error.log + +# Folder Locations +etdir=/var/db/pfblockerng/ET +tmpxlsx=/tmp/xlsx/ + +pfbdeny=/var/db/pfblockerng/deny/ +pfborig=/var/db/pfblockerng/original/ +pfbmatch=/var/db/pfblockerng/match/ +pfbpermit=/var/db/pfblockerng/permit/ +pfbnative=/var/db/pfblockerng/native/ +pfsense_alias_dir=/var/db/aliastables/ + +# Store "Match" d-dedups in matchdedup.txt file +matchdedup=matchdedup.txt + +tempfile=/tmp/pfbtempfile +tempfile2=/tmp/pfbtempfile2 +dupfile=/tmp//pfbduptemp +dedupfile=/tmp/pfbdeduptemp +addfile=/tmp/pfBaddfile +syncfile=/tmp/pfbsyncfile +matchfile=/tmp/pfbmatchfile +tempmatchfile=/tmp/pfbtempmatchfile + +if [ ! -f $masterfile ]; then touch $masterfile; fi +if [ ! -f $mastercat ]; then touch $mastercat; fi +if [ ! -f $tempfile ]; then touch $tempfile; fi +if [ ! -f $tempfile2 ]; then touch $tempfile2; fi +if [ ! -f $dupfile ]; then touch $dupfile; fi +if [ ! -f $dedupfile ]; then touch $dedupfile; fi +if [ ! -f $addfile ]; then touch $addfile; fi +if [ ! -f $syncfile ]; then touch $syncfile; fi +if [ ! -f $matchfile ]; then touch $matchfile; fi +if [ ! -f $tempmatchfile ]; then touch $tempmatchfile; fi +if [ ! -d $pfbmatch ]; then mkdir $pfbmatch; fi +if [ ! -d $etdir ]; then mkdir $etdir; fi +if [ ! -d $tmpxlsx ]; then mkdir $tmpxlsx; fi + +########## +# Process to condense an IP range if a "Max" amount of IP addresses are found in a /24 range per Alias Group. +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 +fi + +# Download MaxMind GeoIP.dat Binary on first Install. +if [ ! -f $pathgeoipdat ]; then + echo "Downloading [ MaxMind GeoIP.dat ] [ $now ]" >> $geoiplog + /usr/local/pkg/pfblockerng/geoipupdate.sh bu +fi +# Exit if GeoIP.dat is not found. +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 +fi + +count=$(grep -c ^ $pfbdeny$alias".txt") +echo; echo "Original File Count [ $count ]" + +grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile +> $dupfile; > $tempfile2; > $matchfile; > $tempmatchfile +data="$(cut -d '.' -f 1-3 $tempfile | awk -v max="$max" '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}')" +count=$(echo "$data" | grep -c ^); mcount=0; dcount=0; safe=0 +if [ "$data" == "" ]; then count=0; fi +matchoutfile="match"$header".txt" +# Classify Repeat Offenders by Country Code +if [ -f $pathgeoipdat ]; then + for ip in $data; do + ccheck=$($pathgeoip -f $pathgeoipdat "$ip.1" | cut -c 24-25) + case "$cc" in + *$ccheck*) + safe=$(($safe + 1)) + if [ "$ccwhite" == "match" -o "$ccblack" == "match" ]; then + echo "$ip." >> $matchfile + fi + ;; + *) + echo "$ip." >> $dupfile + ;; + esac + done +else + echo; echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping p24 Process"; echo + echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping p24 Process [ $now ]" >> $errorlog +fi +# Collect Match File Details +if [ -s "$matchfile" -a ! "$dedup" == "on" -a "$ccwhite" == "match" ]; then + mon=$(sed -e 's/^/^/' -e 's/\./\\\./g' $matchfile) + for ip in $mon; do + grep $ip $tempfile >> $tempfile2 + done + mcount=$(grep -c ^ $tempfile2) + if [ "$ccwhite" == "match" ]; then + sed 's/$/0\/24/' $matchfile >> $tempmatchfile + sed 's/^/\!/' $tempfile2 >> $tempmatchfile + fi +fi + +# If no Matches found remove previous Matchoutfile if exists. +if [ ! -s "$tempmatchfile" -a -f $matchoutfile ]; then rm -r $matchoutfile; fi +# Move Match File to the Match Folder by Individual Blocklist Name +if [ -s "$tempmatchfile" ]; then mv -f $tempmatchfile $pfbmatch$matchoutfile; fi + +# Find Repeat Offenders in each individual Blocklist Outfile +if [ -s "$dupfile" ]; then + > $tempfile2 + dup=$(sed -e 's/^/^/' -e 's/\./\\\./g' $dupfile) + for ip in $dup; do + grep $ip $tempfile >> $tempfile2 + done + dcount=$(grep -c ^ $tempfile2) + if [ "$ccblack" == "block" ]; then + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile2 $tempfile > $pfbdeny$alias".txt" + sed 's/$/0\/24/' $dupfile >> $pfbdeny$alias".txt" + elif [ "$ccblack" == "match" ]; then + sed 's/$/0\/24/' $dupfile >> $tempmatchfile + sed 's/^/\!/' $tempfile2 >> $tempmatchfile + else + : + fi +fi +if [ "$count" == "0" -a "$safe" == "0" ]; then echo; echo " Process /24 Stats [ $alias ] [ $now ] "; echo "------------------------------------------------"; fi +if [ "$count" == "0" ]; then echo "Found [ 0 ] IP range(s) over the threshold of [ $max ] p24 - CC Blacklist"; fi +if [ "$safe" == "0" ]; then echo "Found [ 0 ] IP range(s) over the threshold of [ $max ] p24 - CC Whitelist"; fi + +if [ -s "$dupfile" -o -s "$matchfile" ]; then +echo +echo " Process /24 Stats [ $alias ] [ $now ]" +echo "--------------------------------------------------------" +echo "Found [ $count ] IP range(s) over the threshold of [ $max ] on the CC Blacklist" +echo "Found [ $safe ] IP range(s) over the threshold of [ $max ] on the CC Whitelist" +echo +echo "Found [ $dcount ] CC Blacklisted IP Address(es) are being set to [ $ccblack ]" +# Skip Match Process if dedup=yes as it will create duplicates +if [ "$dedup" == "on" ]; then mcount=Skipped; fi +echo "Found [ $mcount ] CC Whitelisted IP Address(es) are being set to [ $ccwhite ]" +if [ "$ccblack" == "block" ]; then + echo; echo "Removed the following IP Ranges" + cat $dupfile | tr '\n' '|'; echo +else + echo "Skipped, CCBlack set to [ $ccblack ]" +fi +sort $pfbdeny$alias".txt" | uniq > $tempfile; mv -f $tempfile $pfbdeny$alias".txt" +echo "-------------------------------------------------------" +cocount=$(grep -cv "^1\.1\.1\.1" $pfbdeny$alias".txt") +echo "Post /24 Count [ $cocount ]"; echo +fi +} + + +########## +process255() { +# Remove IPs if exists over 255 IPs in a Range and replace with a single /24 Block +cp $pfbdeny$alias".txt" $tempfile; > $dedupfile + +data255="$(cut -d '.' -f 1-3 $tempfile | awk '{a[$0]++}END{for(i in a){if(a[i] > 255){print i}}}')" +if [ ! -z "$data255" ]; then + for ip in $data255; do + ii=$(echo "^$ip" | sed 's/\./\\\./g') + grep $ii $tempfile >> $dedupfile + done + awk 'FNR==NR{a[$0];next}!($0 in a)' $dedupfile $tempfile > $pfbdeny$alias".txt" + for ip in $data255; do echo $ip"0/24" >> $pfbdeny$alias".txt"; done +fi +} + + +########## +continent() { + +dupcheck=yes +# Check if Masterfile is Empty +hcheck=$(grep -c ^ $masterfile); if [ "$hcheck" -eq "0" ]; then dupcheck=no; fi +# Check if Alias exists in Masterfile +lcheck=$(grep -m 1 "$alias " $masterfile ); if [ "$lcheck" == "" ]; then dupcheck=no; fi + +if [ "$dupcheck" == "yes" ]; then + # Grep Alias with a trailing Space character + grep "$alias[[:space:]]" $masterfile > $tempfile + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile + cut -d' ' -f2 $masterfile > $mastercat +fi + +grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile + +if [ ! "$hcheck" -eq "0" ]; then + $pathgrepcidr -vf $mastercat $pfbdeny$alias".txt" > $tempfile; mv -f $tempfile $pfbdeny$alias".txt" +fi + +sed -e 's/^/'$alias' /' $pfbdeny$alias".txt" >> $masterfile +cut -d' ' -f2 $masterfile > $mastercat + +countg=$(grep -c ^ $pfborig$alias".orig") +countm=$(grep -c "$alias " $masterfile); counto=$(grep -c ^ $pfbdeny$alias".txt") +if [ "$countm" == "$counto" ]; then sanity="Passed"; else sanity=" ==> FAILED <== "; fi +echo "----------------------------------------------------------" +echo; echo " Post Duplication count [ $now ]" +echo "----------------------------------------------------------" +printf "%-10s %-10s %-10s %-30s\n" "Original" "Masterfile" "Outfile" "Sanity Check" +echo "----------------------------------------------------------" +printf "%-10s %-10s %-10s %-30s\n" "$countg" "$countm" "$counto" " [ $sanity ]" +echo "----------------------------------------------------------" +} + + +########## +# Process to remove Suppressed Entries and RFC 1918 and Misc IPs on each downloaded Blocklist +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 +fi + +if [ -e "$pfbsuppression" ] && [ -s "$pfbsuppression" ]; then + # Find '/24' Blocked IPs that are single addresses in the Suppressed IP Address List. + # These '/24' Are converted to single Addresses excluding the Suppressed IPs. + data="$(cat $pfbsuppression)" + if [ ! -z "$data" -a ! -z "$cc" ]; then + # Loop thru each Updated List to remove Suppression and RFC1918 Addresses + if [ "$cc" == "suppressheader" ]; then + echo; echo "===[ Suppression Stats ]========================================"; echo + printf "%-20s %-10s %-10s %-10s %-10s\n" "List" "Pre" "RFC1918" "Suppress" "Masterfile" + echo "----------------------------------------------------------------" + exit + fi + + for i in $cc; do + counter=0 + > $dupfile + alias=$(echo "${i%|*}") + pfbfolder=$(echo "${i#*|}") + + if [ ! "$alias" == "" ]; then + # Count (PRE) + countg=$(grep -c ^ $pfbfolder$alias".txt") + + grep -Ev "^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|#|$)" $pfbfolder$alias".txt" | + sort | uniq > $tempfile + # Count (Post RFC1918) + countm=$(grep -c ^ $tempfile) + + for ip in $data; do + found=""; ddcheck=""; + iptrim=$(echo $ip | cut -d '.' -f 1-3) + mask=$(echo $ip | cut -d"/" -f2) + found=$(grep -m1 $iptrim".0/24" $tempfile) + # If a Suppression is '/32' and a Blocklist has a full '/24' Block execute the following. + if [ ! "$found" == "" -a "$mask" == "32" ]; then + echo " Suppression $alias: $iptrim.0/24" + octet4=$(echo $ip | cut -d '.' -f 4 | sed 's/\/.*//') + dcheck=$(grep $iptrim".0/24" $dupfile) + if [ "$dcheck" == "" ]; then + echo $iptrim".0" >> $tempfile + echo $iptrim".0/24" >> $dupfile + counter=$(($counter + 1)) + # Add Individual IP addresses from Range excluding Suppressed IP + for i in $(/usr/bin/jot 255); do + if [ "$i" != "$octet4" ]; then + echo $iptrim"."$i >> $tempfile + counter=$(($counter + 1)) + fi + done + fi + fi + done + if [ -s $dupfile ]; then + # Remove '/24' Suppressed Ranges + awk 'FNR==NR{a[$0];next}!($0 in a)' $dupfile $tempfile > $tempfile2; mv -f $tempfile2 $tempfile + fi + # Remove All other Suppressions from Lists + $pathgrepcidr -vf $pfbsuppression $tempfile > $pfbfolder$alias".txt" + # Update Masterfiles. Don't execute if Duplication Process is Disabled + if [ "$dedup" == "x" ]; then + # Dont execute if Alias doesnt exist in Masterfile + lcheck=$(grep -m1 "$alias " $masterfile) + if [ ! "$lcheck" == "" ]; then + # Replace Masterfile with changes to List. + grep "$alias[[:space:]]" $masterfile > $tempfile + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile + sed -e 's/^/'$alias' /' $pfbfolder$alias".txt" >> $masterfile + cut -d' ' -f2 $masterfile > $mastercat + fi + fi + countk=$(grep -c ^ $masterfile) + countx=$(grep -c ^ $pfbfolder$alias".txt") + counto=$(($countx - $counter)) + printf "%-20s %-10s %-10s %-10s %-10s\n" "$alias" "$countg" "$countm" "$counto" "$countk" + fi + done + fi +else + if [ "$cc" == "suppressheader" ]; then + echo "===[ Suppression Stats ]========================================"; echo + printf "%-20s %-10s %-10s %-10s %-10s\n" "List" "Pre" "RFC1918" "Suppress" "Masterfile" + echo "----------------------------------------------------------------" + exit + fi + for i in $cc; do + alias=$(echo "${i%|*}") + pfbfolder=$(echo "${i#*|}") + + if [ ! "$alias" == "" ]; then + countg=$(grep -c ^ $pfbfolder$alias".txt") + grep -Ev "^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|#|$)" $pfbfolder$alias".txt" | + sort | uniq > $tempfile; mv -f $tempfile $pfbfolder$alias".txt" + countx=$(grep -c ^ $pfbfolder$alias".txt") + # Update Masterfiles. Don't execute if Duplication Process is Disabled or if No Suppression Changes Found + if [ "$dedup" == "x" -a "$countg" != "$countx" ]; then + # Dont execute if Alias doesnt exist in Masterfile + lcheck=$(grep -m1 "$alias " $masterfile) + if [ ! "$lcheck" == "" ]; then + # Replace Masterfile with changes to List. + grep "$alias[[:space:]]" $masterfile > $tempfile + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile + sed -e 's/^/'$alias' /' $pfbfolder$alias".txt" >> $masterfile + cut -d' ' -f2 $masterfile > $mastercat + fi + fi + countm=$(grep -c ^ $pfbfolder$alias".txt") + counto=" - " + countk=$(grep -c ^ $masterfile) + printf "%-20s %-10s %-10s %-10s %-10s\n" "$alias" "$countg" "$countm" "$counto" "$countk" + fi + done +fi +} + + +########## +# Process to remove Duplicate Entries on each downloaded Blocklist Individually +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 +fi + +dupcheck=yes +# Check if Masterfile is Empty +hcheck=$(grep -cv "^$" $masterfile); if [ "$hcheck" -eq "0" ]; then dupcheck=no; fi +# Check if Alias exists in Masterfile +lcheck=$(grep -m1 "$alias " $masterfile); if [ "$lcheck" == "" ]; then dupcheck=no; fi + +if [ "$dupcheck" == "yes" ]; then + # Grep Alias with a trailing Space character + grep "$alias[[:space:]]" $masterfile > $tempfile + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile + cut -d' ' -f2 $masterfile > $mastercat +fi + +grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile; mv -f $tempfile $pfbdeny$alias".txt" + +if [ ! "$hcheck" -eq "0" ]; then + $pathgrepcidr -vf $mastercat $pfbdeny$alias".txt" > $tempfile; mv -f $tempfile $pfbdeny$alias".txt" +fi + +sed -e 's/^/'$alias' /' $pfbdeny$alias".txt" >> $masterfile +cut -d' ' -f2 $masterfile > $mastercat + +countg=$(grep -c ^ $pfborig$alias".orig") +countm=$(grep -c "$alias " $masterfile); counto=$(grep -c ^ $pfbdeny$alias".txt") +if [ "$countm" == "$counto" ]; then sanity="Passed"; else sanity=" ==> FAILED <== "; fi +echo "----------------------------------------------------------" +printf "%-10s %-10s %-10s %-30s\n" "Original" "Masterfile" "Outfile" " [ Post Duplication count ]" +echo "----------------------------------------------------------" +printf "%-10s %-10s %-10s %-30s\n" "$countg" "$countm" "$counto" " [ $sanity ]" +echo "----------------------------------------------------------" +} + + +########## +# De-Duplication utilizing MaxMind GeoIP Country Code Whitelisting ("dmax" variable) +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 +fi + +# Download MaxMind GeoIP.dat on first Install. +if [ ! -f $pathgeoipdat ]; then + echo "Downloading [ MaxMind GeoIP.dat ] [ $now ]" >> $geoiplog + /usr/local/pkg/pfblockerng/geoipupdate.sh bu +fi + +# Exit if GeoIP.dat is not found +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 +fi + +> $tempfile; > $tempfile2; > $dupfile; > $addfile; > $dedupfile; > $matchfile; > $tempmatchfile; count=0; dcount=0; mcount=0; mmcount=0 +echo; echo "Querying for Repeat Offenders" +data="$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | cut -d '.' -f 1-3 $pfbdeny*.txt | + awk -v max="$max" '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}' | grep -v "^1\.1\.1")" +count=$(echo "$data" | grep -c ^) +if [ "$data" == "" ]; then count=0; fi +safe=0 +# Classify Repeat Offenders by Country Code +if [ -f $pathgeoipdat ]; then + echo "Classifying Repeat Offenders by GeoIP" + for ip in $data; do + ccheck=$($pathgeoip -f $pathgeoipdat "$ip.1" | cut -c 24-25) + case "$cc" in + *$ccheck*) + safe=$(($safe + 1)) + if [ "$ccwhite" == "match" -o "$ccblack" == "match" ]; then + echo "$ip." >> $matchfile + fi + ;; + *) + echo "$ip." >> $dupfile + ;; + esac + done +else + echo; echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping d-dedup Process"; echo + echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping d-dedup Process [ $now ]" >> $errorlog +fi +if [ -s "$matchfile" -a "$ccwhite" == "match" ]; then + echo "Processing [ Match ] IPs" + match=$(sed -e 's/^/^/' -e 's/\./\\\./g' $matchfile) + for mfile in $match; do + grep $mfile $pfbdeny*.txt >> $tempfile + done + sed 's/$/0\/24/' $matchfile >> $tempmatchfile + sed -e 's/.*://' -e 's/^/\!/' $tempfile >> $tempmatchfile + mv -f $tempmatchfile $pfbmatch$matchdedup + mcount=$(grep -c ^ $tempfile) + mmcount=$(($mcount + $mmcount)) +fi +# Find Repeat Offenders in each individual Blocklist Outfile +if [ -s "$dupfile" ]; then + echo "Processing [ Block ] IPs" + dup=$(cat $dupfile) + for ip in $dup; do + pcount=1; ii=$(echo "^$ip" | sed 's/\./\\\./g') + list=$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | xargs grep -al $ii) + for blfile in $list; do + header=$(echo "${blfile##*/}" | cut -d '.' -f1) + grep $ii $blfile > $tempfile + if [ "$ccblack" == "block" ]; then + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $blfile > $tempfile2; mv -f $tempfile2 $blfile + if [ "$pcount" -eq "1" ]; then + echo $ip"0/24" >> $blfile + echo $header" "$ip >> $dedupfile + echo $header" "$ip"0/24" >> $addfile + pcount=2 + else + echo $header" "$ip >> $dedupfile + fi + else + if [ "$pcount" -eq "1" ]; then + matchoutfile="match"$header".txt" + echo $ip"0/24" >> $pfbmatch$matchoutfile + sed 's/^/\!/' $tempfile >> $pfbmatch$matchoutfile + mcount=$(grep -c ^ $pfbmatch$matchoutfile) + mmcount=$(($mcount + $mmcount)) + pcount=2 + fi + fi + done + done + # Remove Repeat Offenders in Masterfiles + if [ -s "$dedupfile" ]; then + echo "Removing [ Block ] IPs" + > $tempfile; > $tempfile2 + sed 's/\./\\\./g' $dedupfile > $tempfile2 + while IFS=' ' read -r ips; do grep "$ips" $masterfile >> $tempfile; done < $tempfile2 + dcount=$(grep -c ^ $tempfile) + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile + cat $addfile >> $masterfile + cut -d' ' -f2 $masterfile > $mastercat + fi +fi + +echo; echo "d-Duplication Process [ $now ]"; echo "------------------------------------------------" +echo; echo "Found [ $count ] IP range(s) over the threshold of dmax= [ $max ]" +echo "Found [ $safe ] IP range(s) classified as Whitelisted" +echo; echo "Found [ $dcount ] CC Blacklisted IP Address(es) are being set to [ $ccblack ]" +echo "Found [ $mmcount ] CC Whitelisted IP Address(es) are being set to [ $ccwhite ]"; echo +if [ -s "$addfile" ]; then + echo; echo "Removed the following IP Ranges" + sed -e 's/^.* //' -e 's/0\/24//' $addfile | tr '\n' '|'; echo +fi +count=$(grep -c ^ $masterfile) +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 +} + + +########## +# Process to perform a final De-Duplication on all of the BlockLists (Excluding Country Whitelist) ("pmax" variable). +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 +fi + +# Download MaxMind GeoIP.dat on first Install. +if [ ! -f $pathgeoipdat ]; then + echo "Downloading [ MaxMind GeoIP.dat ] [ $now ]" >> $geoiplog + /usr/local/pkg/pfblockerng/geoipupdate.sh bu +fi +# Exit if GeoIP.dat is not found. +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 +fi + +> $tempfile; > $tempfile2; > $dupfile; > $addfile; > $dedupfile; count=0; dcount=0 +echo; echo "=====================================================================" +echo; echo "Querying for Repeat Offenders" +data="$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | cut -d '.' -f 1-3 $pfbdeny*.txt | + awk -v max="$max" '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}' | grep -v "^1\.1\.1")" +count=$(echo "$data" | grep -c ^) +if [ "$data" == "" ]; then count=0; fi +# Find Repeat Offenders in each individual Blocklist Outfile +echo "Processing [ Block ] IPs" +for ip in $data; do + pcount=1; ii=$(echo "^$ip." | sed 's/\./\\\./g') + list=$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | xargs grep -al $ii) + for blfile in $list; do + header=$(echo "${blfile##*/}" | cut -d '.' -f1) + grep $ii $blfile > $tempfile + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $blfile > $tempfile2; mv -f $tempfile2 $blfile + if [ "$pcount" -eq "1" ]; then + echo $ip".0/24" >> $blfile + echo $header" $ip." >> $dedupfile + echo $header" "$ip".0/24" >> $addfile + pcount=2 + else + echo $header" $ip." >> $dedupfile + fi + done +done +# Remove Repeat Offenders in Masterfile +if [ -s "$dedupfile" ]; then + echo "Removing [ Block ] IPs" + > $tempfile; > $tempfile2 + sed 's/\./\\\./g' $dedupfile > $tempfile2 + while IFS=' ' read -r ips; do grep "$ips" $masterfile >> $tempfile; done < $tempfile2 + dcount=$(grep -c ^ $tempfile) + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile + cat $addfile >> $masterfile + cut -d' ' -f2 $masterfile > $mastercat +fi + +echo; echo "p-Duplication Process [ $now ]"; echo "------------------------------------------------" +echo "Found [ $dcount ] IP Address(es) are being set to [ block ]" +if [ -s "$addfile" ]; then + echo; echo "Removed the following IP Ranges" + sed -e 's/^.* //' -e 's/0\/24//' $addfile | tr '\n' '|'; echo +fi +count=$(grep -c ^ $masterfile) +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 +} + + +########## +# Process to Split ET Pro IPREP into Category Files and Compile selected Blocked categories into Outfile +processet() { + +if [ ! -x $pathgunzip ]; then + echo "Application [ Gunzip ] Not found, Can't proceed." + echo "Application [ Gunzip ] Not found, Can't proceed. [ $now ]" >> $errorlog + exit +fi + +if [ -s $pfborig$alias".gz" ]; then + evar="ET_*" + # Remove Previous ET IPRep Files + [ -d $etdir ] && [ "$(ls -A $etdir)" ] && rm -r $etdir/$evar + > $tempfile; > $tempfile2 + + $pathgunzip -c $pfborig$alias".gz" > $pfborig$alias".raw" + + # ET CSV Format (IP, Category, Score) + echo; echo "Processing [ $alias ]" + while IFS="," read a b c; do + # Some ET Categories are not in use (For Future Use) + case "$b" in + 1) echo $a >> $etdir/ET_Cnc;; + 2) echo $a >> $etdir/ET_Bot;; + 3) echo $a >> $etdir/ET_Spam;; + 4) echo $a >> $etdir/ET_Drop;; + 5) echo $a >> $etdir/ET_Spywarecnc;; + 6) echo $a >> $etdir/ET_Onlinegaming;; + 7) echo $a >> $etdir/ET_Drivebysrc;; + 8) echo $a >> $etdir/ET_Cat8;; + 9) echo $a >> $etdir/ET_Chatserver;; + 10) echo $a >> $etdir/ET_Tornode;; + 11) echo $a >> $etdir/ET_Cat11;; + 12) echo $a >> $etdir/ET_Cat12;; + 13) echo $a >> $etdir/ET_Compromised;; + 14) echo $a >> $etdir/ET_Cat14;; + 15) echo $a >> $etdir/ET_P2P;; + 16) echo $a >> $etdir/ET_Proxy;; + 17) echo $a >> $etdir/ET_Ipcheck;; + 18) echo $a >> $etdir/ET_Cat18;; + 19) echo $a >> $etdir/ET_Utility;; + 20) echo $a >> $etdir/ET_DDos;; + 21) echo $a >> $etdir/ET_Scanner;; + 22) echo $a >> $etdir/ET_Cat22;; + 23) echo $a >> $etdir/ET_Brute;; + 24) echo $a >> $etdir/ET_Fakeav;; + 25) echo $a >> $etdir/ET_Dyndns;; + 26) echo $a >> $etdir/ET_Undesireable;; + 27) echo $a >> $etdir/ET_Abusedtld;; + 28) echo $a >> $etdir/ET_Selfsignedssl;; + 29) echo $a >> $etdir/ET_Blackhole;; + 30) echo $a >> $etdir/ET_RAS;; + 31) echo $a >> $etdir/ET_P2Pcnc;; + 32) echo $a >> $etdir/ET_Sharedhosting;; + 33) echo $a >> $etdir/ET_Parking;; + 34) echo $a >> $etdir/ET_VPN;; + 35) echo $a >> $etdir/ET_Exesource;; + 36) echo $a >> $etdir/ET_Cat36;; + 37) echo $a >> $etdir/ET_Mobilecnc;; + 38) echo $a >> $etdir/ET_Mobilespyware;; + 39) echo $a >> $etdir/ET_Skypenode;; + 40) echo $a >> $etdir/ET_Bitcoin;; + 41) echo $a >> $etdir/ET_DDosattack;; + *) echo $a >> $etdir/ET_Unknown;; + esac + done <"$pfborig$alias.raw" + data=$(ls $etdir) + echo "Compiling ET IP IQRisk REP Lists based upon User Selected Categories" + printf "%-10s %-25s\n" " Action" "Category" + echo "-------------------------------------------" + + for list in $data; do + case "$etblock" in + *$list*) + printf "%-10s %-25s\n" " Block: " "$list" + cat $etdir/$list >> $tempfile + ;; + esac + case "$etmatch" in + *$list*) + printf "%-10s %-25s\n" " Match: " "$list" + cat $etdir/$list >> $tempfile2 + ;; + esac + done + echo "-------------------------------------------" + + if [ -f $tempfile ]; then mv -f $tempfile $pfborig$alias".orig"; fi + if [ "$etmatch" != "x" ]; then mv -f $tempfile2 $pfbmatch/ETMatch.txt; fi + cicount=$(cat $etdir/$evar | grep -cv '^#\|^$'); cocount=$(grep -cv "^1\.1\.1\.1" $pfborig$alias".orig") + echo; echo "ET Folder count [ $cicount ] Outfile count [ $cocount ]" +else + echo; echo "No ET .GZ File Found!" +fi +} + +# Process to extract IP addresses from XLSX Files +processxlsx() { + +if [ ! -x $pathtar ]; then + echo "Application [ TAR ] Not found, Can't proceed." + echo "Application [ TAR ] Not found, Can't proceed. [ $now ]" >> $errorlog + exit +fi + +if [ -s $pfborig$alias".zip" ]; then + + $pathtar -xf $pfborig$alias".zip" -C $tmpxlsx + $pathtar -xOf $tmpxlsx*.[xX][lL][sS][xX] xl/sharedStrings.xml | + grep -aoEw "(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]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" | sort | uniq > $pfborig$alias".orig" + rm -r $tmpxlsx* + + cocount=$(grep -cv "^1\.1\.1\.1" $pfborig$alias".orig") + echo; echo "Download file count [ ZIP file ] Outfile count [ $cocount ]" +else + echo "XLSX Download File Missing" + echo " [ $alias ] XLSX Download File Missing [ $now ]" >> $errorlog +fi +} + +closingprocess() { + +# 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 + +if [ -d "$pfborig" ] && [ "$(ls -A $pfborig)" ]; then + fcount=$(find $pfborig*.orig | xargs cat | grep -cv '^#\|^$') +else + fcount=0 +fi + +if [ "$alias" == "on" ]; then + sort -o $masterfile $masterfile + sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n $mastercat > $tempfile; mv -f $tempfile $mastercat + + echo; echo; echo "===[ FINAL Processing ]====================================="; echo + echo " [ Original count ] [ $fcount ]" + count=$(grep -c ^ $masterfile) + echo; echo " [ Processed Count ] [ $count ]"; echo + + s1=$(grep -cv "1\.1\.1\.1" $masterfile) + s2=$(find $pfbdeny ! -name "*_v6.txt" -type f | xargs cat | grep -cv "^1\.1\.1\.1") + s3=$(sort $mastercat | uniq -d | tail -30) + s4=$(find $pfbdeny ! -name "*_v6.txt" -type f | xargs cat | sort | uniq -d | tail -30 | grep -v "^1\.1\.1\.1") + + if [ -d "$pfbpermit" ] && [ "$(ls -A $pfbpermit)" ]; then + echo; echo "===[ Permit List IP Counts ]========================="; echo + wc -l $pfbpermit* | sort -n -r + fi + if [ -d "$pfbmatch" ] && [ "$(ls -A $pfbmatch)" ]; then + echo; echo "===[ Match List IP Counts ]=========================="; echo + wc -l $pfbmatch* | sort -n -r + fi + if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then + echo; echo "===[ Deny List IP Counts ]==========================="; echo + wc -l $pfbdeny* | sort -n -r + fi + if [ -d "$pfbnative" ] && [ "$(ls -A $pfbnative)" ]; then + echo; echo "===[ Native List IP Counts ] ==================================="; echo + wc -l $pfbnative* | sort -n -r + fi + if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then + emptylists=$(grep "1\.1\.1\.1" $pfbdeny* | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:1.1.1.1/ /') + if [ ! -z "$emptylists" ]; then + echo; echo "====================[ Empty Lists w/1.1.1.1 ]=================="; echo + for list in $emptylists; do + echo $list + done + fi + fi + if [ -d "$pfborig" ] && [ "$(ls -A $pfborig)" ]; then + echo; echo "====================[ Last Updated List Summary ]=============="; echo + ls -lahtr $pfborig* | sed -e 's/\/.*\// /' -e 's/.orig//' | awk -v OFS='\t' '{print $6" "$7,$8,$9}' + fi + echo "==============================================================="; echo + echo "Sanity Check (Not Including IPv6) ** These two Counts should Match! **" + echo "------------" + echo "Masterfile Count [ $s1 ]" + echo "Deny folder Count [ $s2 ]"; echo + echo "Duplication Sanity Check (Pass=No IPs reported)" + echo "------------------------" + echo "Masterfile/Deny Folder Uniq check" + if [ ! -z "$s3" ]; then echo $s3; fi + echo "Deny Folder/Masterfile Uniq check" + if [ ! -z "$s4" ]; then echo $s4; fi + echo; echo "Sync Check (Pass=No IPs reported)" + echo "----------" +else + echo; echo "===[ FINAL Processing ]============================================="; echo + echo " [ Original count ] [ $fcount ]" + if [ -d "$pfbpermit" ] && [ "$(ls -A $pfbpermit)" ]; then + echo; echo "===[ Permit List IP Counts ]========================="; echo + wc -l $pfbpermit* | sort -n -r + fi + if [ -d "$pfbmatch" ] && [ "$(ls -A $pfbmatch)" ]; then + echo; echo "===[ Match List IP Counts ]=========================="; echo + wc -l $pfbmatch* | sort -n -r + fi + if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then + echo; echo "===[ Deny List IP Counts ]==========================="; echo + wc -l $pfbdeny* | sort -n -r + fi + if [ -d "$pfbnative" ] && [ "$(ls -A $pfbnative)" ]; then + echo; echo "===[ Native List IP Counts ] ==================================="; echo + wc -l $pfbnative* | sort -n -r + fi + if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then + emptylists=$(grep "1\.1\.1\.1" $pfbdeny* | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:1.1.1.1/ /') + if [ ! -z "$emptylists" ]; then + echo; echo "====================[ Empty Lists w/1.1.1.1 ]=================="; echo + for list in $emptylists; do + echo $list + done + fi + fi + if [ -d "$pfborig" ] && [ "$(ls -A $pfborig)" ]; then + echo; echo "====================[ Last Updated List Summary ]=============="; echo + ls -lahtr $pfborig* | sed -e 's/\/.*\// /' -e 's/.orig//' | awk -v OFS='\t' '{print $6" "$7,$8,$9}' + echo "===============================================================" + fi +fi + +echo; echo "IPv4 Alias Table IP Total"; echo "-----------------------------" +find $pfsense_alias_dir ! -name "*_v6.txt" -type f | xargs cat | grep -c ^ + +echo; echo "IPv6 Alias Table IP Total"; echo "-----------------------------" +find $pfsense_alias_dir -name "*_v6.txt" -type f | xargs cat | grep -c ^ + +echo; echo "Alias Table IP Counts"; echo "-----------------------------" +wc -l $pfsense_alias_dir*.txt | sort -n -r + +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 +} + +remove() { +# Remove Lists from Masterfiles and Delete Associated Files +echo +for i in $cc; do + header=$(echo "${i%*,}") + if [ ! "$header" == "" ]; then + # Make sure that Alias Exists in Masterfile before removal. + masterchk=$(grep -m1 "$header[[:space:]]" $masterfile) + if [ ! -z "$masterchk" ]; then + # Grep Header with a Trailing Space character + grep "$header[[:space:]]" $masterfile > $tempfile + awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile + cut -d' ' -f2 $masterfile > $mastercat + fi + rm -rf $pfborig$header*; rm -rf $pfbdeny$header*; rm -rf $pfbmatch$header*; rm -rf $pfbpermit$header*; rm -rf $pfbnative$header* + echo "The Following list has been REMOVED [ $header ]" + fi + echo +done + +# Delete Masterfiles if they are empty +emptychk=$(find $masterfile -size 0) +if [ ! "$emptychk" == "" ]; then + rm -r $masterfile; rm -r $mastercat +fi +} + + +########## +# CALL APPROPRIATE PROCESSES using Script Argument $1 +case $1 in + continent) + continent + ;; + duplicate) + process255 + duplicate + ;; + suppress) + suppress + ;; + p24) + process24 + ;; + dedup) + deduplication + ;; + pdup) + pdeduplication + ;; + et) + processet + ;; + xlsx) + processxlsx + ;; + closing) + closingprocess + ;; + remove) + remove + ;; + *) + exit + ;; +esac +exit
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng.widget.php b/config/pfblockerng/pfblockerng.widget.php new file mode 100644 index 00000000..647017ff --- /dev/null +++ b/config/pfblockerng/pfblockerng.widget.php @@ -0,0 +1,280 @@ +<?php +/* + pfBlockerNG.widget.php + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based Upon pfblocker : + Copyright 2011 Thomas Schaefer - Tomschaefer.org + Copyright 2011 Marcello Coutinho + Part of pfSense widgets (www.pfsense.org) + + Adapted From: + snort_alerts.widget.php + Copyright (C) 2009 Jim Pingle + mod 24-07-2012 + mod 28-02-2014 by Bill Meeks + + Javascript and Integration modifications by J. Nieuwenhuizen + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +@require_once("/usr/local/www/widgets/include/widget-pfblockerng.inc"); +@require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); +@require_once("guiconfig.inc"); +@require_once("globals.inc"); +@require_once("pfsense-utils.inc"); +@require_once("functions.inc"); + +pfb_global(); + +// Ackwnowlege Failed Downloads +if (isset($_POST['pfblockerngack'])) { + $clear = exec("/usr/bin/sed -i '' 's/FAIL/Fail/g' {$pfb['errlog']}"); + header("Location: ../../index.php"); +} + +// This function will create the counts +function pfBlockerNG_get_counts() { + global $config, $g, $pfb; + + // Collect Alias Count and Update Date/Time + $pfb_table = array(); + $out = "<img src ='/themes/{$g['theme']}/images/icons/icon_interface_down.gif' title=\"No Rules are Defined using this Alias\" alt=\"\" />"; + $in = "<img src ='/themes/{$g['theme']}/images/icons/icon_interface_up.gif' title=\"Rules are Defined using this Alias\" alt=\"\" />"; + if (is_array($config['aliases']['alias'])) { + foreach ($config['aliases']['alias'] as $cbalias) { + if (preg_match("/pfB_/", $cbalias['name'])) { + if (file_exists("{$pfb['aliasdir']}/{$cbalias['name']}.txt")) { + preg_match("/(\d+)/", exec("/usr/bin/grep -cv \"^1\.1\.1\.1\" {$pfb['aliasdir']}/{$cbalias['name']}.txt"), $matches); + $pfb_table[$cbalias['name']] = array("count" => $matches[1], "img" => $out); + $updates = exec("ls -ld {$pfb['aliasdir']}/{$cbalias['name']}.txt | awk '{ print $6,$7,$8 }'", $update); + $pfb_table[$cbalias['name']]['up'] = $updates; + } + } + } + } + + // Collect if Rules are defined using pfBlockerNG Aliases. + if (is_array($config['filter']['rule'])) { + foreach ($config['filter']['rule'] as $rule) { + if (preg_match("/pfB_/",$rule['source']['address']) || preg_match("/pfb_/",$rule['source']['address'])) { + $pfb_table[$rule['source']['address']]['img'] = $in; + } + if (preg_match("/pfB_/",$rule['destination']['address']) || preg_match("/pfb_/",$rule['destination']['address'])) { + $pfb_table[$rule['destination']['address']]['img'] = $in; + } + } + return $pfb_table; + } +} + +// Status Indicator if pfBlockerNG is Enabled/Disabled +if ("{$pfb['enable']}" == "on") { + $pfb_status = "/themes/{$g['theme']}/images/icons/icon_pass.gif"; + $pfb_msg = "pfBlockerNG is Active."; +} else { + $pfb_status = "/themes/{$g['theme']}/images/icons/icon_block.gif"; + $pfb_msg = "pfBlockerNG is Disabled."; +} + +// Collect Total IP/Cidr Counts +$dcount = exec("cat {$pfb['denydir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); +$pcount = exec("cat {$pfb['permitdir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); +$mcount = exec("cat {$pfb['matchdir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); +$ncount = exec("cat {$pfb['nativedir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'"); + +// Collect Number of Suppressed Hosts +if (file_exists("{$pfb['supptxt']}")) { + $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}"); +} else { + $pfbsupp_cnt = 0; +} + +#check rule count +#(label, evaluations,packets total, bytes total, packets in, bytes in,packets out, bytes out) +$packets = exec("/sbin/pfctl -s labels", $debug); +if (!empty($debug)) { + foreach ($debug as $line) { + // Auto-Rules start with 'pfB_', Alias Rules should start with 'pfb_' and exact spelling of Alias Name. + $line = str_replace("pfb_","pfB_",$line); + if ("{$pfb['pfsenseversion']}" >= '2.2') { + #USER_RULE: pfB_Top auto rule 8494 17 900 17 900 0 0 0 + if (preg_match("/USER_RULE: (\w+).*\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+/", $line, $matches)) { + if (isset($matches)) { + ${$matches[1]}+=$matches[2]; + } else { + ${$matches[1]} = 'Err'; + } + } + } else { + #USER_RULE: pfB_Top auto rule 1656 0 0 0 0 0 0 + if (preg_match("/USER_RULE: (\w+).*\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+/", $line, $matches)) { + if (isset($matches)) { + ${$matches[1]}+=$matches[2]; + } else { + ${$matches[1]} = 'Err'; + } + } + } + } +} + +// Called by Ajax to update alerts table contents +if (isset($_GET['getNewCounts'])) { + $response = ""; + $pfb_table = pfBlockerNG_get_counts(); + if (!empty($pfb_table)) { + foreach ($pfb_table as $alias => $values){ + if (!isset(${$alias})) { ${$alias} = "-";} + $response .= $alias . "||" . $values['count'] . "||" . ${$alias} . "||" . $values['up'] . "||" . $values['img'] . "\n"; + } + echo $response; + return; + } +} + +// Report any Failed Downloads +$results = array(); +$fails = exec("grep $(date +%m/%d/%y) {$pfb['errlog']} | grep 'FAIL'", $results); + +// Print widget Status Bar Items +?> + <div class="marinarea"> + <table border="0" cellspacing="0" cellpadding="0"> + <thead> + <tr> + <td valign="middle"> <img src="<?= $pfb_status ?>" width="13" height="13" border="0" title="<?=gettext($pfb_msg) ?>" alt="" /></td> + <td valign="middle"> </td> + <td valign="middle" p style="font-size:10px"> + <?php if ($dcount != 0): ?> + <?=gettext("Deny:"); echo(" <strong>" . $dcount . "</strong>") ?> + <?php endif; ?> + <?php if ($pcount != 0): ?> + <?=gettext(" Permit:"); echo(" <strong>" . $pcount . "</strong>") ?> + <?php endif; ?> + <?php if ($mcount != 0): ?> + <?=gettext(" Match:"); echo(" <strong>" . $mcount . "</strong>"); ?> + <?php endif; ?> + <?php if ($ncount != 0): ?> + <?=gettext(" Native:"); echo(" <strong>" . $ncount . "</strong>"); ?> + <?php endif; ?> + <?php if ($pfbsupp_cnt != 0): ?> + <?=gettext(" Supp:"); echo(" <strong>" . $pfbsupp_cnt . "</strong>"); ?> + <?php endif; ?></td> + <td valign="middle"> </td> + <td valign="top"><a href="pfblockerng/pfblockerng_log.php"><img src="/themes/<?=$g['theme']; ?>/images/icons/icon_logs.gif" width="13" height="13" border="0" title="<?=gettext("View pfBlockerNG Logs TAB") ?>" alt="" /></a> + <td valign="top"> + <?php if (!empty($results)): ?> <!--Hide "Ack" Button when Failed Downloads are Empty--> + <form action="/widgets/widgets/pfblockerng.widget.php" method="post" name="widget_pfblockerng_ack"> + <input type="hidden" value="clearack" name="pfblockerngack" /> + <input class="vexpl" type="image" name="pfblockerng_ackbutton" src="/themes/<?=$g['theme']; ?>/images/icons/icon_x.gif" width="14" height="14" border="0" title="<?=gettext("Clear Failed Downloads") ?>"/> + </form> + <?php endif; ?> + </td> + </tr> + </thead> + </table> + </div> + + <table id="pfb-tblfails" width="100%" border="0" cellspacing="0" cellpadding="0"> + <tbody id="pfb-fails"> +<?php + +if ("{$pfb['pfsenseversion']}" > '2.0') { + $alertRowEvenClass = "listMReven"; + $alertRowOddClass = "listMRodd"; + $alertColClass = "listMRr"; +} else { + $alertRowEvenClass = "listr"; + $alertRowOddClass = "listr"; + $alertColClass = "listr"; +} + +# Last errors first +$results = array_reverse($results); + +$counter = 0; +# Max errors to display +$maxfailcount = 3; +if (!empty($results)) { + foreach ($results as $result) { + $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass; + if (!isset(${$alias})) { ${$alias} = "-";} + echo(" <tr class='" . $alertRowClass . "'><td class='" . $alertColClass . "'>" . $result . "</td><tr>"); + $counter++; + if ($counter > $maxfailcount) { + # To many errors stop displaying + echo(" <tr class='" . $alertRowClass . "'><td class='" . $alertColClass . "'>" . (count($results) - $maxfailcount) . " more error(s)...</td><tr>"); + break; + } + } +} + +// Print Main Table Header +?> + </tbody> + </table> + <table id="pfb-tbl" width="100%" border="0" cellspacing="0" cellpadding="0"> + <thead> + <tr> + <th class="widgetsubheader" align="center"><?=gettext("Alias");?></th> + <th title="The count can be a mixture of Single IPs or CIDR values" class="widgetsubheader" align="center"><?=gettext("Count");?></th> + <th title="Packet Counts can be cleared by the pfSense filter_configure() function. Make sure Rule Descriptions start with 'pfB_'" class="widgetsubheader" align="center"><?=gettext("Packets");?></th> + <th title="Last Update (Date/Time) of the Alias " class="widgetsubheader" align="center"><?=gettext("Updated");?></th> + <th class="widgetsubheader" align="center"><?php echo $out; ?><?php echo $in; ?></th> + </tr> + </thead> + <tbody id="pfbNG-entries"> +<?php +// Print Main Table Body +$pfb_table = pfBlockerNG_get_counts(); +$counter=0; +if (is_array($pfb_table)) { + foreach ($pfb_table as $alias => $values) { + $evenRowClass = $counter % 2 ? " listMReven" : " listMRodd"; + if (!isset(${$alias})) { ${$alias} = "-";} + echo(" <tr class='" . $evenRowClass . "'> + <td class='listMRr ellipsis'>{$alias}</td> + <td class='listMRr' align='center'>{$values['count']}</td> + <td class='listMRr' align='center'>{${$alias}}</td> + <td class='listMRr' align='center'>{$values['up']}</td> + <td class='listMRr' align='center'>{$values['img']}</td> + </tr>"); + $counter++; + } +} + +?> +</tbody> +</table> + +<script type="text/javascript"> +//<![CDATA[ + var pfBlockerNGupdateDelay = 10000; // update every 10000 ms +//]]> +</script>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng.xml b/config/pfblockerng/pfblockerng.xml new file mode 100644 index 00000000..a8517a30 --- /dev/null +++ b/config/pfblockerng/pfblockerng.xml @@ -0,0 +1,541 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ======================================================================================= */ +/* + pfBlockerNG.xml + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfblocker for pfSense + Copyright (C) 2011 Marcello Coutinho + All rights reserved. +/* +/* ====================================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +/* +/* ====================================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfblockerng</name> + <version>1.0</version> + <title>pfBlockerNG: General Settings</title> + <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file> + <menu> + <name>pfBlockerNG</name> + <configfile>pfblockerng.xml</configfile> + <tooltiptext>Configure pfblockerNG</tooltiptext> + <section>Firewall</section> + <url>/pkg_edit.php?xml=pfblockerng.xml</url> + </menu> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.inc</item> + <prefix>/usr/local/pkg/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.php</item> + <prefix>/usr/local/www/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_alerts.php</item> + <prefix>/usr/local/www/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_update.php</item> + <prefix>/usr/local/www/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_log.php</item> + <prefix>/usr/local/www/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_diag_dns.php</item> + <prefix>/usr/local/www/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.widget.php</item> + <prefix>/usr/local/www/widgets/widgets/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/widget-pfblockerng.inc</item> + <prefix>/usr/local/www/widgets/include/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.js</item> + <prefix>/usr/local/www/widgets/javascript/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_top20.xml</item> + <prefix>/usr/local/pkg/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_v4lists.xml</item> + <prefix>/usr/local/pkg/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_v6lists.xml</item> + <prefix>/usr/local/pkg/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_sync.xml</item> + <prefix>/usr/local/pkg/pfblockerng/</prefix> + <chmod>0644</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Africa_v4.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Africa_v6.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Asia_v4.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Asia_v6.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Europe_v4.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Europe_v6.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/North_America_v4.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/North_America_v6.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Oceania_v4.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/Oceania_v6.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/South_America_v4.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/cc/South_America_v6.txt</item> + <prefix>/var/db/pfblockerng/cc/</prefix> + <chmod>0444</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.sh</item> + <prefix>/usr/local/pkg/pfblockerng/</prefix> + <chmod>0755</chmod> + </additional_files_needed> + <additional_files_needed> + <item>https://packages.pfsense.org/packages/config/pfblockerng/geoipupdate.sh</item> + <prefix>/usr/local/pkg/pfblockerng/</prefix> + <chmod>0755</chmod> + </additional_files_needed> + <tabs> + <tab> + <text>General</text> + <url>/pkg_edit.php?xml=pfblockerng.xml&id=0</url> + <active/> + </tab> + <tab> + <text>Update</text> + <url>/pfblockerng/pfblockerng_update.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pfblockerng/pfblockerng_alerts.php</url> + </tab> + <tab> + <text>Reputation</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0</url> + </tab> + <tab> + <text>IPv4</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url> + </tab> + <tab> + <text>IPv6</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url> + </tab> + <tab> + <text>Top20</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0</url> + </tab> + <tab> + <text>Africa</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0</url> + </tab> + <tab> + <text>Asia</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0</url> + </tab> + <tab> + <text>Europe</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0</url> + </tab> + <tab> + <text>N.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Oceania</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0</url> + </tab> + <tab> + <text>S.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Logs</text> + <url>/pfblockerng/pfblockerng_log.php</url> + </tab> + <tab> + <text>Sync</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0</url> + </tab> + </tabs> + <fields> + <field> + <name>pfBlockerNG General Settings</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>LINKS</fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> <a href="/firewall_rules.php">Firewall Rules</a> <a href="diag_logs_filter.php">Firewall Logs</a>]]></description> + <type>info</type> + </field> + <field> + <fielddescr><![CDATA[<strong>Enable pfBlockerNG</strong>]]></fielddescr> + <fieldname>enable_cb</fieldname> + <type>checkbox</type> + <description><![CDATA[Note - with "Keep settings" enabled, pfBlockerNG will maintain run state on Installation/Upgrade<br /> + If "Keep Settings" is not "enabled" on pkg Install/De-Install, all Settings will be Wiped!]]></description> + </field> + <field> + <fielddescr>CRON MIN Start Time</fielddescr> + <fieldname>pfb_min</fieldname> + <description><![CDATA[Default: <strong> : 00</strong><br /> + Select Cron Update Minute ]]></description> + <type>select</type> + <options> + <option><name> : 00</name><value>0</value></option> + <option><name> : 15</name><value>15</value></option> + <option><name> : 30</name><value>30</value></option> + <option><name> : 45</name><value>45</value></option> + </options> + </field> + <field> + <fielddescr>CRON Base Hour Start Time</fielddescr> + <fieldname>pfb_hour</fieldname> + <description><![CDATA[Default: <strong> 1 </strong><br /> + Select Cron Base Start Hour ]]></description> + <type>select</type> + <options> + <option><name>1</name><value>0</value></option> + <option><name>0</name><value>1</value></option> + <option><name>2</name><value>2</value></option> + <option><name>3</name><value>3</value></option> + <option><name>4</name><value>4</value></option> + <option><name>5</name><value>5</value></option> + <option><name>6</name><value>6</value></option> + <option><name>7</name><value>7</value></option> + <option><name>8</name><value>8</value></option> + <option><name>9</name><value>9</value></option> + <option><name>10</name><value>10</value></option> + <option><name>11</name><value>11</value></option> + <option><name>12</name><value>12</value></option> + <option><name>13</name><value>13</value></option> + <option><name>14</name><value>14</value></option> + <option><name>15</name><value>15</value></option> + <option><name>16</name><value>16</value></option> + <option><name>17</name><value>17</value></option> + <option><name>18</name><value>18</value></option> + <option><name>19</name><value>19</value></option> + <option><name>20</name><value>20</value></option> + <option><name>21</name><value>21</value></option> + <option><name>22</name><value>22</value></option> + <option><name>23</name><value>23</value></option> + </options> + </field> + <field> + <fielddescr>'Daily/Weekly' Start Hour</fielddescr> + <fieldname>pfb_dailystart</fieldname> + <description><![CDATA[Default: <strong> 1 </strong><br /> + Select 'Daily' Schedule Start Hour <br /> + This is used for the 'Daily/Weekly' Scheduler Only.]]></description> + <type>select</type> + <options> + <option><name>1</name><value>0</value></option> + <option><name>0</name><value>1</value></option> + <option><name>2</name><value>2</value></option> + <option><name>3</name><value>3</value></option> + <option><name>4</name><value>4</value></option> + <option><name>5</name><value>5</value></option> + <option><name>6</name><value>6</value></option> + <option><name>7</name><value>7</value></option> + <option><name>8</name><value>8</value></option> + <option><name>9</name><value>9</value></option> + <option><name>10</name><value>10</value></option> + <option><name>11</name><value>11</value></option> + <option><name>12</name><value>12</value></option> + <option><name>13</name><value>13</value></option> + <option><name>14</name><value>14</value></option> + <option><name>15</name><value>15</value></option> + <option><name>16</name><value>16</value></option> + <option><name>17</name><value>17</value></option> + <option><name>18</name><value>18</value></option> + <option><name>19</name><value>19</value></option> + <option><name>20</name><value>20</value></option> + <option><name>21</name><value>21</value></option> + <option><name>22</name><value>22</value></option> + <option><name>23</name><value>23</value></option> + </options> + </field> + <field> + <fielddescr>Remove Duplication</fielddescr> + <fieldname>enable_dup</fieldname> + <type>checkbox</type> + <description>Only for IPv4 Lists</description> + </field> + <field> + <fielddescr>Enable Suppression</fielddescr> + <fieldname>suppression</fieldname> + <type>checkbox</type> + <description><![CDATA[This will prevent Selected IPs from being Blocked. Only for IPv4 Lists (/32 and /24).<br /> + Country Blocking Lists cannot be Suppressed.<br /> + This will also remove any RFC1918 addresses from all Lists.<br /><br /> + Alerts can be Suppressed using the '+' icon in the Alerts Tab and IPs added to the 'pfBlockerNGSuppress' Alias<br /> + A Blocked IP in a CIDR other than /24 will need to be Suppressed by an 'Permit Outbound' Firewall Rule]]> + </description> + </field> + <field> + <fielddescr><![CDATA[<strong>Keep Settings</strong>/Lists After Disable/Re-Install/De-Install]]></fielddescr> + <fieldname>pfb_keep</fieldname> + <type>checkbox</type> + <description>Keep Settings and Lists intact when pfBlockerNG is Disabled or After pfBlockerNG Re-Install/De-Install</description> + </field> + <field> + <fielddescr>Global Enable Logging</fielddescr> + <fieldname>enable_log</fieldname> + <type>checkbox</type> + <description>Enable Global Logging to Status: System Logs: FIREWALL ( Log ). This overrides any Log Settings in the Alias Tabs.</description> + </field> + <field> + <fielddescr>Disable MaxMind Country Database CRON Updates</fielddescr> + <fieldname>database_cc</fieldname> + <type>checkbox</type> + <description><![CDATA[This will Disable the MaxMind Monthly Country Database Cron Update.<br /> + This does not affect the MaxMind Binary Cron Task]]> + </description> + </field> + <field> + <fielddescr>Logfile Size</fielddescr> + <fieldname>log_maxlines</fieldname> + <description><![CDATA[Default:<strong>20000</strong><br /> + Select number of Lines to Keep in Log File]]></description> + <type>select</type> + <options> + <option><name>20000</name><value>20000</value></option> + <option><name>40000</name><value>40000</value></option> + <option><name>60000</name><value>60000</value></option> + <option><name>80000</name><value>80000</value></option> + <option><name>100000</name><value>100000</value></option> + <option><name>No Limit</name><value>nolimit</value></option> + </options> + </field> + <field> + <name><![CDATA[Interface/Rules Configuration]]> </name> + <type>listtopic</type> + </field> + <field> + <fielddescr>Inbound Interface(s)</fielddescr> + <fieldname>inbound_interface</fieldname> + <description><![CDATA[Default: <strong>WAN</strong><br />Select the interface(s) you want to Apply Rules to]]></description> + <type>interfaces_selection</type> + <hideinterfaceregex>loopback</hideinterfaceregex> + <required/> + <multiple/> + </field> + <field> + <fielddescr> - Rule Action</fielddescr> + <fieldname>inbound_deny_action</fieldname> + <description><![CDATA[Default:<strong>Block</strong><br /> + Select 'Rule Action' for Inbound Rules]]></description> + <type>select</type> + <options> + <option><name>Block</name><value>block</value></option> + <option><name>Reject</name><value>reject</value></option> + </options> + </field> + <field> + <fielddescr>Outbound Interface(s)</fielddescr> + <fieldname>outbound_interface</fieldname> + <description><![CDATA[Default:<strong>LAN</strong> or none.<br />Select the interface(s) you want to Apply Rules to]]></description> + <type>interfaces_selection</type> + <hideinterfaceregex>loopback</hideinterfaceregex> + <required/> + <multiple/> + </field> + <field> + <fielddescr> - Rule Action</fielddescr> + <fieldname>outbound_deny_action</fieldname> + <description><![CDATA[Default:<strong>Reject</strong><br /> + Select 'Rule Action' for Outbound rules]]></description> + <type>select</type> + <options> + <option><name>Reject</name><value>reject</value></option> + <option><name>Block</name><value>block</value></option> + </options> + </field> + <field> + <fielddescr><![CDATA[<strong>OpenVPN Interface</strong>]]></fielddescr> + <fieldname>openvpn_action</fieldname> + <type>checkbox</type> + <description>Select to add Auto-Rules for OpenVPN. These will be added to 'Floating Rules' or OpenVPN Rules Tab.</description> + </field> + <field> + <fielddescr><![CDATA[<strong>Floating Rules</strong>]]></fielddescr> + <fieldname>enable_float</fieldname> + <type>checkbox</type> + <description><![CDATA[<strong>Enabled: </strong> Auto-Rules will be generated in the 'Floating Rules' Tab<br /><br /> + <strong>Disabled:</strong> Auto-Rules will be generated in the Selected Inbound/Outbound Interfaces<br /><br /> + <strong>Rules will be ordered by the selection below.</strong>]]></description> + </field> + <field> + <fielddescr><![CDATA[<strong>Rule Order</strong>]]></fielddescr> + <fieldname>pass_order</fieldname> + <description><![CDATA[<br />Default Order: <strong> | pfB_Block/Reject | All other Rules | (original format)<br /></strong><br /> + Select The '<strong>Order</strong>' of the Rules<br /> + Selecting 'original format', sets pfBlockerNG rules at the top of the Firewall TAB.<br /> + Selecting any other 'Order' will re-order <strong>all the Rules to the format indicated!</strong>]]></description> + <type>select</type> + <options> + <option><name>| pfB_Block/Reject | All other Rules | (original format)</name><value>order_0</value></option> + <option><name>| pfSense Pass/Match | pfB_Pass/Match | pfB_Block/Reject |</name><value>order_1</value></option> + <option><name>| pfB_Pass/Match | pfSense Pass/Match | pfB_Block/Reject |</name><value>order_2</value></option> + <option><name>| pfB_Pass/Match | pfB_Block/Reject | pfSense Pass/Match |</name><value>order_3</value></option> + </options> + </field> + <field> + <fielddescr><![CDATA[<strong>Auto Rule Suffix</strong>]]></fielddescr> + <fieldname>autorule_suffix</fieldname> + <description><![CDATA[Default:<strong>auto rule</strong><br /> + Select 'Auto Rule' Description Suffix for Auto Defined rules. pfBlockerNG Must be Disabled to Modify Suffix]]></description> + <type>select</type> + <options> + <option><name>auto rule</name><value>autorule</value></option> + <option><name>Null (no suffix)</name><value>standard</value></option> + <option><name>AR</name><value>ar</value></option> + </options> + </field> + <field> + <name><![CDATA[Acknowledgements]]> </name> + <type>listtopic</type> + </field> + <field> + <fielddescr>Credits</fielddescr> + <fieldname>credits</fieldname> + <type>info</type> + <description><![CDATA[<strong> + pfBlockerNG</strong> Created in 2014 by <a target=_new href='https://forum.pfsense.org/index.php?action=profile;u=238481'>BBcan177.</a> + <br /><br />Based upon pfBlocker by Marcello Coutinho and Tom Schaefer.<br /> + Country Database GeoLite distributed under the Creative Commons Attribution-ShareAlike 3.0 Unported License by: + MaxMind Inc. @ <a target=_new href='http://www.maxmind.com'>MaxMind.com</a>. + The Database is Automatically Updated the First Tuesday of Each Month]]></description> + </field> + <field> + <fielddescr>pfBlocker Validation Check</fielddescr> + <fieldname>pfblocker_cb</fieldname> + <type>checkbox</type> + <description>Disable pfBlockerNG if the pfBlocker package is Enabled. Click to Disable this validation check.</description> + </field> + <field> + <fielddescr>Gold Membership</fielddescr> + <type>info</type> + <description><![CDATA[If you like this package, please Support pfSense by subscribing to a <a target=_new href='https://portal.pfsense.org/gold-subscription.php'>Gold Membership</a><br /> or support the developer @ BBCan177@gmail.com]]></description> + </field> + <field> + <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. Changes are Applied via CRON or + 'Force Update'</ul>]]></name> + <type>listtopic</type> + </field> + </fields> + <custom_php_install_command> + pfblockerng_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + pfblockerng_php_deinstall_command(); + </custom_php_deinstall_command> + <custom_php_validation_command> + pfblockerng_validate_input($_POST, $input_errors); + </custom_php_validation_command> + <custom_php_resync_config_command> + global $pfb; + $pfb['save'] = TRUE; + sync_package_pfblockerng(); + </custom_php_resync_config_command> +</packagegui>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php new file mode 100644 index 00000000..1b54f8f2 --- /dev/null +++ b/config/pfblockerng/pfblockerng_alerts.php @@ -0,0 +1,761 @@ +<?php +/* + pfBlockerNG_Alerts.php + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Portions of this code are based on original work done for + pfSense from the following contributors: + + Parts based on works from Snort_alerts.php + Copyright (C) 2014 Bill Meeks + All rights reserved. + + Javascript Hostname Lookup modifications by J. Nieuwenhuizen + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("util.inc"); +require_once("guiconfig.inc"); +require_once("globals.inc"); +require_once("filter_log.inc"); +require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); + +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 = "{$pfb['dbdir']}/GeoIP.dat"; +$pathgeoipdat6 = "{$pfb['dbdir']}/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 (empty($config['installedpackages']['pfblockerngglobal']['pfbdenycnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = '25'; +if (empty($config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'])) + $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = '5'; +if (empty($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']; + if (empty($descr)) + $descr = sprintf(gettext("Entry added %s"), date('r')); + $cidr = $_POST['cidr']; + 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(); + } + } + } +} + +// Auto-Resolve Hostnames +if (isset($_REQUEST['getpfhostname'])) { + $getpfhostname = htmlspecialchars($_REQUEST['getpfhostname']); + $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES); + if ($hostname == $getpfhostname) { + $hostname = 'unknown'; + } + echo $hostname; + die; +} + + +// Host Resolve Function lookup +function getpfbhostname($type = 'src', $hostip, $countme = 0) { + $hostnames['src'] = ''; + $hostnames['dst'] = ''; + $hostnames[$type] = '<div id="gethostname_' . $countme . '" name="' . $hostip . '"></div>'; + 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; +} + + +$pgtitle = gettext("pfBlockerNG: Alerts"); +include_once("head.inc"); +?> +<body link="#000000" vlink="#0000CC" alink="#000000"> +<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> +<input type="hidden" name="ip" id="ip" value=""/> +<input type="hidden" name="table" id="table" value=""/> +<input type="hidden" name="descr" id="descr" value=""/> +<input type="hidden" name="cidr" id="cidr" value=""/> +<?php + +include_once("fbegin.inc"); + +/* refresh every 60 secs */ +if ($alertrefresh == 'on') + echo "<meta http-equiv=\"refresh\" content=\"60;url={$_SERVER['PHP_SELF']}\" />\n"; +if ($savemsg) { + print_info_box($savemsg); +} + +?> + <table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <?php + $tab_array = array(); + $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml&id=0"); + $tab_array[] = array(gettext("Update"), false, "/pfblockerng/pfblockerng_update.php"); + $tab_array[] = array(gettext("Alerts"), true, "/pfblockerng/pfblockerng_alerts.php"); + $tab_array[] = array(gettext("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0"); + $tab_array[] = array(gettext("IPv4"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml"); + $tab_array[] = array(gettext("IPv6"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml"); + $tab_array[] = array(gettext("Top 20"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0"); + $tab_array[] = array(gettext("Africa"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0"); + $tab_array[] = array(gettext("Asia"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0"); + $tab_array[] = array(gettext("Europe"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0"); + $tab_array[] = array(gettext("N.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0"); + $tab_array[] = array(gettext("Oceania"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0"); + $tab_array[] = array(gettext("S.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0"); + $tab_array[] = array(gettext("Logs"), false, "/pfblockerng/pfblockerng_log.php"); + $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0"); + display_top_tabs($tab_array, true); + ?> + </td> + </tr> + <tr> + <td><div id="mainarea"> + <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="6"> + <tr> + <td colspan="3" class="vncell" align="left"><?php echo gettext("LINKS :"); ?> + <a href='/firewall_aliases.php' target="_blank"><?php echo gettext("Firewall Alias"); ?></a> + <a href='/firewall_rules.php' target="_blank"><?php echo gettext("Firewall Rules"); ?></a> + <a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br /></td> + </tr> + <tr> + <td width="10%" class="vncell"><?php echo gettext('Alert Settings'); ?></td> + <td width="90%" class="vtable"> + <input name="pfbdenycnt" type="text" class="formfld unknown" id="pdbdenycnt" size="1" title="Enter the number of 'Deny' Alerts to Show" value="<?=htmlspecialchars($pfbdenycnt);?>"/> + <?php printf(gettext('%sDeny%s. ') , '<strong>', '</strong>'); ?> + <input name="pfbpermitcnt" type="text" class="formfld unknown" id="pdbpermitcnt" size="1" title="Enter the number of 'Permit' Alerts to Show" value="<?=htmlspecialchars($pfbpermitcnt);?>"/> + <?php printf(gettext('%sPermit%s. '), '<strong>', '</strong>'); ?> + <input name="pfbmatchcnt" type="text" class="formfld unknown" id="pdbmatchcnt" size="1" title="Enter the number of 'Match' Alerts to Show" value="<?=htmlspecialchars($pfbmatchcnt); ?>"/> + <?php printf(gettext('%sMatch%s.'), '<strong>', '</strong>'); ?> + + <?php echo gettext(' Click to Auto-Refresh');?> <input name="alertrefresh" type="checkbox" value="on" title="Click to enable Auto-Refresh of this Tab once per minute" + <?php if ($config['installedpackages']['pfblockerngglobal']['alertrefresh']=="on") echo "checked"; ?>/> + + <?php echo gettext(' Click to Auto-Resolve');?> <input name="hostlookup" type="checkbox" value="on" title="Click to enable Auto-Resolve of Hostnames. Country Blocks/Permit/Match Lists will not auto-resolve" + <?php if ($config['installedpackages']['pfblockerngglobal']['hostlookup']=="on") echo "checked"; ?>/> + <input name="save" type="submit" class="formbtns" value="Save" title="<?=gettext('Save settings');?>"/><br /> + + <?php printf(gettext('Enter number of log entries to view.')); ?> + <?php printf(gettext("Currently Suppressing %s$pfbsupp_cnt%s Hosts."), '<strong>', '</strong>');?> + </td> + </tr> +<!--Create Three Output Windows 'Deny', 'Permit' and 'Match'--> +<?php foreach (array ("Deny" => $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; + } + +?> + <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="6"> + <tr> + <!--Print Table Info--> + <td colspan="2" class="listtopic"><?php printf(gettext(" {$type} - Last %s Alert Entries."), "{$pfbentries}"); ?> + <?php if ($pfb['pfsenseversion'] >= '2.2'): ?> + <?php if (!is_array($config['syslog']) || !array_key_exists("reverse", $config['syslog'])): ?> + <?php echo gettext("Firewall Logs must be in Reverse Order."); ?> + <?php endif; ?> + <?php else: ?> + <?php echo gettext("Firewall Rule changes can unsync these Alerts."); ?> + <?php if (!is_array($config['syslog']) || !array_key_exists("reverse", $config['syslog'])): ?> + <?php echo gettext("Firewall Logs must be in Reverse Order."); ?> + <?php endif; ?> + <?php endif; ?> + </td> + </tr> + +<td width="100%" colspan="2"> +<table id="pfbAlertsTable" style="table-layout: fixed;" width="100%" class="sortable" border="0" cellpadding="0" cellspacing="0"> + <colgroup> + <col width="8%" align="center" axis="date"> + <col width="6%" align="center" axis="string"> + <col width="16%" align="center" axis="string"> + <col width="6%" align="center" axis="string"> + <col width="20%" align="center" axis="string"> + <col width="20%" align="center" axis="string"> + <col width="3%" align="center" axis="string"> + <col width="13%" align="center" axis="string"> + </colgroup> + <thead> + <tr class="sortableHeaderRowIdentifier"> + <th class="listhdrr" axis="date"><?php echo gettext("Date"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("IF"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("Rule"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("Proto"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("Source"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("Destination"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("CC"); ?></th> + <th class="listhdrr" axis="string"><?php echo gettext("List"); ?></th> + </tr> + </thead> + <tbody> +<?php + +$pfb['runonce'] = TRUE; +if (isset($pfb['load'])) + $pfb['runonce'] = FALSE; + +// Execute the following once per refresh +if ($pfb['runonce']) { + $pfb['load'] = TRUE; + $fields_array = array(); + + // pfSense versions below 2.2 have the Logfiles in two lines. + if ($pfb['pfsenseversion'] >= '2.2') { + $pfblines = exec("/usr/bin/grep -c ^ {$filter_logfile}"); + } else { + $pfblines = (exec("/usr/bin/grep -c ^ {$filter_logfile}") /2 ); + } + $fields_array = conv_log_filter($filter_logfile, $pfblines, $pfblines); + + $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)) { + foreach ($fields_array 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; + } + + $proto = str_replace("TCP", "TCP-", $fields['proto']) . $fields['tcpflags']; + + // Cleanup Port Output + if ($fields['proto'] == "ICMP") { + $srcport = $fields['srcport']; + $dstport = $fields['dstport']; + } else { + $srcport = " :" . $fields['srcport']; + $dstport = " :" . $fields['dstport']; + } + + // 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['dstip'], $pfb_local) || check_lan_dest($lan_ip,$lan_mask,$fields['dstip'],"32")) { + // Destination is Gateway/NAT/VIP + $rule = $rule_list[$rulenum]['name'] . "<br />(" . $rulenum .")"; + $host = $fields['srcip']; + + 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 .= "<a href='/pfblockerng/pfblockerng_diag_dns.php?host={$host}' title=\" " . gettext("Resolve host via Rev. DNS lookup"); + $alert_ip .= "\"> <img src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" width=\"11\" height=\"11\" border=\"0\" "; + $alert_ip .= "alt=\"Icon Reverse Resolve with DNS\" style=\"cursor: pointer;\"/></a>"; + + if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { + $supp_ip .= "<input type='image' name='addsuppress[]' onclick=\"hostruleid('{$host}','{$rule_list[$rulenum]['name']}');\" "; + $supp_ip .= "src=\"../themes/{$g['theme']}/images/icons/icon_plus.gif\" title=\""; + $supp_ip .= gettext($supp_ip_txt) . "\" border=\"0\" width='11' height='11'/>"; + } + + if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { + $hostname = getpfbhostname('src', $fields['srcip'], $counter); + } else { + $hostname = ""; + } + + $src_icons = $alert_ip . " " . $supp_ip . " "; + $dst_icons = ""; + $scc = $country; + $dcc = ""; + } else { + // Outbound + $rule = $rule_list[$rulenum]['name'] . "<br />(" . $rulenum .")"; + $host = $fields['dstip']; + + 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 .= "<a href='/pfblockerng/pfblockerng_diag_dns.php?host={$host}' title=\"" . gettext("Resolve host via Rev. DNS lookup"); + $alert_ip .= "\"> <img src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" width=\"11\" height=\"11\" border=\"0\" "; + $alert_ip .= "alt=\"Icon Reverse Resolve with DNS\" style=\"cursor: pointer;\"/></a>"; + + if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") { + $supp_ip .= "<input type='image' name='addsuppress[]' onclick=\"hostruleid('{$host}','{$rule_list[$rulenum]['name']}');\" "; + $supp_ip .= "src=\"../themes/{$g['theme']}/images/icons/icon_plus.gif\" title=\""; + $supp_ip .= gettext($supp_ip_txt) . "\" border=\"0\" width='11' height='11'/>"; + } + + if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") { + $hostname = getpfbhostname('dst', $fields['dstip'], $counter); + } else { + $hostname = ""; + } + + $src_icons = ""; + $dst_icons = $alert_ip . " " . $supp_ip . " "; + $scc = ""; + $dcc = $country; + } + + # 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] = ""; + } + } + + // Print Alternating Line Shading + if ($pfb['pfsenseversion'] > '2.0') { + $alertRowEvenClass = "listMReven"; + $alertRowOddClass = "listMRodd"; + } else { + $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 "<tr class='{$alertRowClass}'> + <td class='listMRr' align='center'>{$fields['time']}</td> + <td class='listMRr' align='center'>{$fields['interface']}</td> + <td class='listMRr' align='center' title='The pfBlockerNG Rule that Blocked this Host.'>{$rule}</td> + <td class='listMRr' align='center'>{$proto}</td> + <td nowrap='nowrap' class='listMRr' align='center' style='sorttable_customkey:{$fields['srcip']};' sorttable_customkey='{$fields['srcip']}'>{$src_icons}{$fields['srcip']}{$srcport}<br /><small>{$hostname['src']}</small></td> + <td nowrap='nowrap' class='listMRr' align='center' style='sorttable_customkey:{$fields['dstip']};' sorttable_customkey='{$fields['dstip']}'>{$dst_icons}{$fields['dstip']}{$dstport}<br /><small>{$hostname['dst']}</small></td> + <td class='listMRr' align='center'>{$countrycode}</td> + <td class='listbg' align='center' title='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' style=\"font-size: 10px word-wrap:break-word;\">{$pfb_match[1]}<br />{$pfb_match[2]}</td></tr>"; + $counter++; + if ($counter > 0 && $rtype == "block") { + $mycounter = $counter; + } + } + } +} +?> + </tbody> + </table> + </table> +<?php endforeach; ?> <!--End - Create Three Output Windows 'Deny', 'Permit' and 'Match'--> +</td></tr> +</table> + +</div> +</td> + +<script type="text/javascript"> +//<![CDATA[ + +// This function stuffs the passed HOST, Table values into hidden Form Fields for postback. +function hostruleid(host,table) { + document.getElementById("ip").value = host; + document.getElementById("table").value = table; + + var description = prompt("Please enter Suppression Description"); + document.getElementById("descr").value = description; + + var cidr = prompt("Please enter CIDR [ 32 or 24 CIDR only supported ]","32"); + document.getElementById("cidr").value = cidr; +} + +// Auto-Resolve of Alerted Hostnames +function findhostnames(counter) { + getip = jQuery('#gethostname_' + counter).attr('name'); + geturl = "<?php echo $_SERVER['PHP_SELF']; ?>"; + jQuery.get( geturl, { "getpfhostname": getip } ) + .done(function( data ) { + jQuery('#gethostname_' + counter).prop('title' , data ); + var str = data; + if(str.length > 32) str = str.substring(0,29)+"..."; + jQuery('#gethostname_' + counter).html( str ); + } + ) +} + + var lines = <?php echo $mycounter; ?>; + for (i = 0; i < lines; i++) { + findhostnames(i); + } + +//]]> +</script> +<?php include("fend.inc"); ?> +</form> +</body> +</html>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_diag_dns.php b/config/pfblockerng/pfblockerng_diag_dns.php new file mode 100644 index 00000000..b2f07464 --- /dev/null +++ b/config/pfblockerng/pfblockerng_diag_dns.php @@ -0,0 +1,318 @@ +<?php +/* + pfBlockerNG_diag_dns.php + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Original Code by: + Copyright (C) 2009 Jim Pingle (jpingle@gmail.com) + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +$pgtitle = array(gettext("pfBlockerNG"),gettext("DNS/Threat Source Lookup")); +require("guiconfig.inc"); + +$host = trim($_REQUEST['host'], " \t\n\r\0\x0B[];\"'"); +$host_esc = escapeshellarg($host); + +if (is_array($config['aliases']['alias'])) { + $a_aliases = &$config['aliases']['alias']; +} else { + $a_aliases = array(); +} +$aliasname = str_replace(array(".","-"), "_", $host); +$alias_exists = false; +$counter=0; +foreach($a_aliases as $a) { + if($a['name'] == $aliasname) { + $alias_exists = true; + $id=$counter; + } + $counter++; +} + +# Collect pfSense Version +$pfs_version = substr(trim(file_get_contents("/etc/version")), 0, 3); + +if ($pfs_version > '2.2') { + $cmd = '/usr/bin/drill'; +} else { + $cmd = '/usr/bin/dig'; +} + + +if(isset($_POST['create_alias']) && (is_hostname($host) || is_ipaddr($host))) { + if($_POST['override']) + $override = true; + $resolved = gethostbyname($host); + $type = "hostname"; + if($resolved) { + $resolved = array(); + exec("{$cmd} {$host_esc} A | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved); + $isfirst = true; + foreach($resolved as $re) { + if($re <> "") { + if(!$isfirst) + $addresses .= " "; + $addresses .= rtrim($re) . "/32"; + $isfirst = false; + } + } + $newalias = array(); + if($override) + $alias_exists = false; + if($alias_exists == false) { + $newalias['name'] = $aliasname; + $newalias['type'] = "network"; + $newalias['address'] = $addresses; + $newalias['descr'] = "Created from Diagnostics-> DNS Lookup"; + if($override) + $a_aliases[$id] = $newalias; + else + $a_aliases[] = $newalias; + write_config(); + $createdalias = true; + } + } +} + +if ($_POST) { + unset($input_errors); + + $reqdfields = explode(" ", "host"); + $reqdfieldsn = explode(",", "Host"); + + do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); + + if (!is_hostname($host) && !is_ipaddr($host)) { + $input_errors[] = gettext("Host must be a valid hostname or IP address."); + } else { + // Test resolution speed of each DNS server. + $dns_speeds = array(); + $dns_servers = array(); + exec("/usr/bin/grep nameserver /etc/resolv.conf | /usr/bin/cut -f2 -d' '", $dns_servers); + foreach ($dns_servers as $dns_server) { + $query_time = exec("{$cmd} {$host_esc} " . escapeshellarg("@" . trim($dns_server)) . " | /usr/bin/grep Query | /usr/bin/cut -d':' -f2"); + if($query_time == "") + $query_time = gettext("No response"); + $new_qt = array(); + $new_qt['dns_server'] = $dns_server; + $new_qt['query_time'] = $query_time; + $dns_speeds[] = $new_qt; + unset($new_qt); + } + } + + $type = "unknown"; + $resolved = ""; + $ipaddr = ""; + $hostname = ""; + if (!$input_errors) { + if (is_ipaddr($host)) { + $type = "ip"; + $resolved = gethostbyaddr($host); + $ipaddr = $host; + if ($host != $resolved) + $hostname = $resolved; + } elseif (is_hostname($host)) { + $type = "hostname"; + $resolved = gethostbyname($host); + if($resolved) { + $resolved = array(); + exec("{$cmd} {$host_esc} A | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved); + } + $hostname = $host; + if ($host != $resolved) + $ipaddr = $resolved[0]; + } + + if ($host == $resolved) { + $resolved = gettext("No record found"); + } + } +} + +function display_host_results ($address,$hostname,$dns_speeds) { + $map_lengths = function($element) { return strlen($element[0]); }; + + echo gettext("IP Address") . ": {$address} \n"; + echo gettext("Host Name") . ": {$hostname} \n"; + echo "\n"; + $text_table = array(); + $text_table[] = array(gettext("Server"), gettext("Query Time")); + if (is_array($dns_speeds)) { + foreach ($dns_speeds as $qt) { + $text_table[] = array(trim($qt['dns_server']), trim($qt['query_time'])); + } + } + $col0_padlength = max(array_map($map_lengths, $text_table)) + 4; + foreach ($text_table as $text_row) { + echo str_pad($text_row[0], $col0_padlength) . $text_row[1] . "\n"; + } +} + +include("head.inc"); ?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> +<?php if ($input_errors) print_input_errors($input_errors); ?> + <form action="/pfblockerng/pfblockerng_diag_dns.php" method="post" name="iform" id="iform"> + <table width="100%" border="0" cellpadding="6" cellspacing="0"> + <tr> + <td colspan="2" valign="top" class="listtopic"> <?=gettext("Resolve DNS hostname or IP");?></td> + </tr> + <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Hostname or IP");?></td> + <td width="78%" class="vtable"> + <?=$mandfldhtml;?> + <table> + <tr><td valign="top"> + <input name="host" type="text" class="formfld" id="host" size="20" value="<?=htmlspecialchars($host);?>"> + </td> + <td> + <?php if ($resolved && $type) { ?> + = <font size="+1"> +<?php + $found = 0; + if(is_array($resolved)) { + foreach($resolved as $hostitem) { + if($hostitem <> "") { + echo $hostitem . "<br/>"; + $found++; + } + } + } else { + echo $resolved; + } + if($found > 0) { ?> + <br/><font size='-2'> + <?PHP if($alias_exists) { ?> + An alias already exists for the hostname <?= htmlspecialchars($host) ?>. <br /> + <input type="hidden" name="override" value="true"/> + <input type="submit" name="create_alias" value="Overwrite Alias"/> + <?PHP } else { + if(!$createdalias) { ?> + <input type="submit" name="create_alias" value="Create Alias from These Entries"/> + <?PHP } else { ?> + Alias created with name <?= htmlspecialchars($newalias['name']) ?> + <?PHP } + } + } +?> + <font size="-1"> + + <? } ?> + </td></tr></table> + </td> + </tr> +<?php if($_POST): ?> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("Resolution time per server");?></td> + <td width="78%" class="vtable"> + <table width="170" border="1" cellpadding="2" style="border-width: 1px 1px 1px 1px; border-collapse: collapse;"> + <tr> + <td> + <b><?=gettext("Server");?></b> + </td> + <td> + <b><?=gettext("Query time");?></b> + </td> + </tr> +<?php + if(is_array($dns_speeds)) + foreach($dns_speeds as $qt): +?> + <tr> + <td> + <?=$qt['dns_server']?> + </td> + <td> + <?=$qt['query_time']?> + </td> + </tr> +<?php + endforeach; +?> + </table> + </td> + </tr> + <?php endif; ?> + <?php if (!$input_errors && $ipaddr) { ?> + <tr> + + <td width="22%" valign="top" class="vncell"><?=gettext("More Information:");?></td> + <td width="78%" class="vtable"> + <a target="_new" href ="/diag_ping.php?host=<?=htmlspecialchars($host)?>&interface=wan&count=3"><?=gettext("Ping");?></a> <br/> + <a target="_new" href ="/diag_traceroute.php?host=<?=htmlspecialchars($host)?>&ttl=18"><?=gettext("Traceroute");?></a> + <p/> + <?=gettext("NOTE: The following links are to external services, so their reliability cannot be guaranteed.");?><br/><br/> + <a target="_new" href="http://private.dnsstuff.com/tools/whois.ch?ip=<?php echo $ipaddr; ?>"><?=gettext("IP WHOIS @ DNS Stuff");?></a><br /> + <a target="_new" href="http://private.dnsstuff.com/tools/ipall.ch?ip=<?php echo $ipaddr; ?>"><?=gettext("IP Info @ DNS Stuff");?></a> + + <?=gettext("NOTE: The following links are to external services, so their reliability cannot be guaranteed.");?><br/><br/> + <a target="_new" href="http://kb.bothunter.net/ipInfo/nowait.php?IP=<?php echo $ipaddr; ?>"><?=gettext("BOTHunter");?></a><br/> + <a target="_new" href="http://www.ipvoid.com/scan/<?php echo $ipaddr; ?>/"><?=gettext("IPVOID");?></a><br/> + <a target="_new" href="http://www.tcpiputils.com/browse/ip-address/<?php echo $ipaddr; ?>/"><?=gettext("TCPUtils");?></a><br/> + <a target="_new" href="https://www.herdprotect.com/ip-address-<?php echo $ipaddr; ?>.aspx"><?=gettext("Herd Protect");?></a><br/> + <a target="_new" href="https://www.senderbase.org/lookup/ip/?search_string=<?php echo $ipaddr; ?>"><?=gettext("SenderBase");?></a><br/> + <a target="_new" href="http://www.ip-tracker.org/locator/ip-lookup.php?ip=<?php echo $ipaddr; ?>"><?=gettext("IP Tracker");?></a><br/> + + <a target="_new" href="https://www.fortiguard.com/ip_rep/index.php?data=/<?php echo $ipaddr; ?>?"><?=gettext("FortiGuard");?></a><br/> + <a target="_new" href="https://www.projecthoneypot.org/ip_<?php echo $ipaddr; ?>"><?=gettext("Project HoneyPot");?></a><br/> + <a target="_new" href="https://www.virustotal.com/en/ip-address/<?php echo $ipaddr; ?>/information"><?=gettext("VirusTotal Info");?></a><br/> + <a target="_new" href="https://www.mcafee.com/threat-intelligence/ip/default.aspx?ip=<?php echo $ipaddr; ?>"><?=gettext("McAfee Threat Center");?></a><br/> + <a target="_new" href="http://sitecheck2.sucuri.net/results/<?php echo $ipaddr; ?>"><?=gettext("Securi SiteCheck");?></a><br/> + <a target="_new" href="https://www.dshield.org/ipinfo.html?IP=<?php echo $ipaddr; ?>"><?=gettext("DShield Threat Lookup");?></a><br/> + <a target="_new" href="https://isc.sans.edu/ipinfo.html?ip=<?php echo $ipaddr; ?>"><?=gettext("Internet Storm Center");?></a><br/> + <a target="_new" href="https://www.mywot.com/en/scorecard/<?php echo $ipaddr; ?>"><?=gettext("Web of Trust (WOT) Scorecard");?></a><br/> + <a target="_new" href="https://quttera.com/sitescan/<?php echo $ipaddr; ?>"><?=gettext("Quattera");?></a><br/> + <a target="_new" href="https://www.iblocklist.com/search.php?string=<?php echo $ipaddr; ?>"><?=gettext("I-Block List");?></a><br/> + <p/> + <?=gettext("NOTE: Mail Server DNSRBL Lookups");?><br/><br/> + <a target="_new" href="https://senderscore.org/lookup.php?lookup=<?php echo $ipaddr; ?>&ipLookup=Go"><?=gettext("SenderScore");?></a><br/> + <a target="_new" href="http://www.spamhaus.org/query/bl?ip=<?php echo $ipaddr; ?>"><?=gettext("Spamhaus Blocklist");?></a><br/> + <a target="_new" href="http://www.spamcop.net/w3m?action=checkblock&ip=<?php echo $ipaddr; ?>"><?=gettext("SPAMcop Blocklist");?></a><br/> + <a target="_new" href="http://multirbl.valli.org/lookup/<?php echo $ipaddr; ?>.html"><?=gettext("multirbl RBL Lookup");?></a><br/> + <a target="_new" href="http://mxtoolbox.com/SuperTool.aspx?action=blacklist%3a<?php echo $ipaddr; ?>&run=toolpage"><?=gettext("MXToolbox");?></a><br/> + + </td> + </tr> + <?php } ?> + <tr> + <td width="22%" valign="top"> </td> + <td width="78%"> + <br/> + <input name="Submit" type="submit" class="formbtn" value="<?=gettext("DNS Lookup");?>"> + </td> + </tr> + </table> +</td></tr></table> +</form> +<?php include("fend.inc"); ?>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_log.php b/config/pfblockerng/pfblockerng_log.php new file mode 100644 index 00000000..39f9eb06 --- /dev/null +++ b/config/pfblockerng/pfblockerng_log.php @@ -0,0 +1,421 @@ +<?php +/* + pfBlockerNG_Log.php + + pfBlockerNG + Copyright (c) 2014 BBcan177@gmail.com + All rights reserved. + + Portions of this code are based on original work done for the + Snort package for pfSense from the following contributors: + + Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>. + Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. + Copyright (C) 2006 Scott Ullrich + Copyright (C) 2009 Robert Zelaya Sr. Developer + Copyright (C) 2012 Ermal Luci + All rights reserved. + + Adapted for Suricata by: + Copyright (C) 2014 Bill Meeks + All rights reserved. + + Javascript and Integration modifications by J. Nieuwenhuizen + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("guiconfig.inc"); +require_once("globals.inc"); +require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); + +pfb_global(); + +# Get log files from directory +function getlogs($logdir, $log_extentions = array('log')) { + if (!is_array($log_extentions)) { + $log_extentions = array($log_extentions); + } + + # Get logfiles + $log_filenames = array(); + foreach ($log_extentions as $extention) { + if ($extention <> '*') { + $log_filenames = array_merge($log_filenames, glob($logdir . "*." . $extention)); + } else { + $log_filenames = array_merge($log_filenames, glob($logdir . "*")); + } + } + + # Convert to filenames only + if (count($log_filenames) > 0) { + $log_totalfiles = count($log_filenames); + for ($cnt = 0; $cnt < $log_totalfiles; $cnt++) { + $log_filenames[$cnt] = basename($log_filenames[$cnt]); + } + } + + # Sort the filename + asort($log_filenames); + + # Done + return $log_filenames; +} + +# Define logtypes +# name => Displayname of the type +# ext => Log extentions (array for multiple extentions) +# logdir=> Log directory +# clear => Add clear button (TRUE/FALSE) +$pfb_logtypes = array( 'defaultlogs' => array('name' => 'Log Files', + 'logdir' => "{$pfb['logdir']}/", + 'logs' => array("pfblockerng.log", "error.log", "geoip.log", "maxmind_ver"), + 'download' => TRUE, + 'clear' => TRUE + ), + 'masterfiles' => array('name' => 'Masterfiles', + 'logdir' => "{$pfb['dbdir']}/", + 'logs' => array("masterfile", "mastercat"), + 'download' => TRUE, + 'clear' => FALSE + ), + 'originallogs' => array('name' => 'Original Files', + 'ext' => array('orig', 'raw'), + 'logdir' => "{$pfb['origdir']}/", + 'download' => TRUE, + 'clear' => TRUE + ), + 'denylogs' => array('name' => 'Deny Files', + 'ext' => 'txt', + 'txt' => 'deny', + 'logdir' => "{$pfb['denydir']}/", + 'download' => TRUE, + 'clear' => TRUE + ), + 'permitlogs' => array('name' => 'Permit Files', + 'ext' => 'txt', + 'txt' => 'permit', + 'logdir' => "{$pfb['permitdir']}/", + 'download' => TRUE, + 'clear' => TRUE + ), + 'matchlogs' => array('name' => 'Match Files', + 'ext' => 'txt', + 'txt' => 'match', + 'logdir' => "{$pfb['matchdir']}/", + 'download' => TRUE, + 'clear' => TRUE + ), + 'nativelogs' => array('name' => 'Native Files', + 'ext' => 'txt', + 'logdir' => "{$pfb['nativedir']}/", + 'download' => TRUE, + 'clear' => TRUE + ), + 'aliaslogs' => array('name' => 'Alias Files', + 'ext' => 'txt', + 'logdir' => "{$pfb['aliasdir']}/", + 'download' => TRUE, + 'clear' => FALSE + ), + 'etiprep' => array('name' => 'ET IPRep Files', + 'ext' => '*', + 'logdir' => "{$pfb['etdir']}/", + 'download' => TRUE, + 'clear' => FALSE + ) + ); + +# Check logtypes +$logtypeid = 'defaultlogs'; +if (isset($_POST['logtype'])) { + $logtypeid = $_POST['logtype']; +} elseif (isset($_GET['logtype'])) { + $logtypeid = htmlspecialchars($_GET['logtype']); +} + +# Check if POST has been set +if (isset($_POST['file'])) { + clearstatcache(); + $pfb_logfilename = $_POST['file']; + $pfb_ext = pathinfo($pfb_logfilename, PATHINFO_EXTENSION); + + # Load log + if ($_POST['action'] == 'load') { + if (!is_file($pfb_logfilename)) { + echo "|3|" . gettext("Log file is empty or does not exist") . ".|"; + } else { + $data = file_get_contents($pfb_logfilename); + if ($data === false) { + echo "|1|" . gettext("Failed to read log file") . ".|"; + } else { + $data = base64_encode($data); + echo "|0|" . $pfb_logfilename . "|" . $data . "|"; + } + } + exit; + } +} + +if (isset($_POST['logFile'])) { + $s_logfile = $_POST['logFile']; + + # Clear selected file + if (isset($_POST['clear'])) { + unlink_if_exists($s_logfile); + } + + # Download log + if (isset($_POST['download'])) { + if (file_exists($s_logfile)) { + ob_start(); //important or other posts will fail + if (isset($_SERVER['HTTPS'])) { + header('Pragma: '); + header('Cache-Control: '); + } else { + header("Pragma: private"); + header("Cache-Control: private, must-revalidate"); + } + header("Content-Type: application/octet-stream"); + header("Content-length: " . filesize($s_logfile)); + header("Content-disposition: attachment; filename = " . basename($s_logfile)); + ob_end_clean(); //important or other post will fail + readfile($s_logfile); + } + } +} else { + $s_logfile = ""; +} + +$pgtitle = gettext("pfBlockerNG: Log Browser"); +include_once("head.inc"); +?> + +<body link="#000000" vlink="#0000CC" alink="#000000"> + +<?php +include_once("fbegin.inc"); +if ($input_errors) { + print_input_errors($input_errors); +} +?> +<script type="text/javascript" src="/javascript/base64.js"></script> +<script type="text/javascript"> +//<![CDATA[ + + function loadFile() { + jQuery("#fileStatus").html("<?=gettext("Loading file"); ?> ..."); + jQuery("#fileStatusBox").show(250); + jQuery("#filePathBox").show(250); + jQuery("#fbTarget").html(""); + + jQuery.ajax( + "<?=$_SERVER['SCRIPT_NAME'];?>", { + type: 'POST', + data: "instance=" + jQuery("#instance").val() + "&action=load&file=" + jQuery("#logFile").val(), + complete: loadComplete + } + ) + } + + function loadComplete(req) { + jQuery("#fileContent").show(250); + var values = req.responseText.split("|"); + values.shift(); values.pop(); + + if(values.shift() == "0") { + var file = values.shift(); + var fileContent = Base64.decode(values.join("|")); + jQuery("#fileStatus").html("<?=gettext("File successfully loaded"); ?>."); + jQuery("#fbTarget").html(file); + jQuery("#fileRefreshBtn").show(); + jQuery("#fileContent").prop("disabled", false); + jQuery("#fileContent").val(fileContent); + } else { + jQuery("#fileStatus").html(values[0]); + jQuery("#fbTarget").html(""); + jQuery("#fileRefreshBtn").hide(); + jQuery("#fileContent").val(""); + jQuery("#fileContent").prop("disabled", true); + } + } +//]]> +</script> + +<?php +echo("<form action='" . $_SERVER['PHP_SELF'] . "' method='post' id='formbrowse'>"); +if ($savemsg) { + print_info_box($savemsg); +} +?> + +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <?php + $tab_array = array(); + $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml&id=0"); + $tab_array[] = array(gettext("Update"), false, "/pfblockerng/pfblockerng_update.php"); + $tab_array[] = array(gettext("Alerts"), false, "/pfblockerng/pfblockerng_alerts.php"); + $tab_array[] = array(gettext("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0"); + $tab_array[] = array(gettext("IPv4"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml"); + $tab_array[] = array(gettext("IPv6"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml"); + $tab_array[] = array(gettext("Top 20"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0"); + $tab_array[] = array(gettext("Africa"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0"); + $tab_array[] = array(gettext("Asia"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0"); + $tab_array[] = array(gettext("Europe"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0"); + $tab_array[] = array(gettext("N.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0"); + $tab_array[] = array(gettext("Oceania"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0"); + $tab_array[] = array(gettext("S.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0"); + $tab_array[] = array(gettext("Logs"), true, "/pfblockerng/pfblockerng_log.php"); + $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0"); + display_top_tabs($tab_array, true); + ?> + </td> + </tr> + <tr> + <td> + <div id="mainarea"> + <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="6"> + <tbody> + <tr> + <td colspan="2" class="listtopic"><?php echo gettext("Log/File Browser Selections"); ?></td> + </tr> + <tr> + <td colspan="3" class="vncell" align="left"><?php echo gettext("LINKS :"); ?> + <a href='/firewall_aliases.php' target="_blank"><?php echo gettext("Firewall Alias"); ?></a> + <a href='/firewall_rules.php' target="_blank"><?php echo gettext("Firewall Rules"); ?></a> + <a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br /></td> + </tr> + <tr> + <td width="22%" class="vncell"><?php echo gettext('Log/File type:'); ?></td> + <td width="78%" class="vtable"> + <select name="logtype" id="logtype" class="formselect" onChange="document.getElementById('formbrowse').method='post';document.getElementById('formbrowse').submit()"> + <?php + $clearable = FALSE; + $downloadable = FALSE; + foreach ($pfb_logtypes as $id => $logtype) { + $selected = ""; + if ($id == $logtypeid) { + $selected = " selected"; + $clearable = $logtype['clear']; + $downloadable = $logtype['download']; + } + echo("<option value='" . $id . "'" . $selected . ">" . $logtype['name'] . "</option>\n"); + } + ?> + </select> <?php echo gettext('Choose which type of log/file you want to view.'); ?> + </td> + </tr> + <tr> + <td width="22%" class="vncell"><?php echo gettext('Log/File selection:'); ?></td> + <td width="78%" class="vtable"> + <select name="logFile" id="logFile" class="formselect" onChange="loadFile();"> + <?php + if (isset($pfb_logtypes[$logtypeid]['logs'])) { + $logs = $pfb_logtypes[$logtypeid]['logs']; + } else { + $logs = getlogs($pfb_logtypes[$logtypeid]['logdir'], $pfb_logtypes[$logtypeid]['ext']); + } + foreach ($logs as $log) { + $selected = ""; + if ($log == $pfb_logfilename) { + $selected = " selected"; + } + echo("<option value='" . $pfb_logtypes[$logtypeid]['logdir'] . $log . "'" . $selected . ">" . $log . "</option>\n"); + } + ?> + </select> <?php echo gettext('Choose which log/file you want to view.'); ?> + </td> + </tr> + <tr> + <td colspan="2" class="listtopic"><?php echo gettext("Log/File Contents"); ?></td> + </tr> + <tr> + <td colspan="2"> + <table width="100%"> + <tbody> + <tr> + <td width="75%"> + <div style="display:none; " id="fileStatusBox"> + <div class="list" style="padding-left:15px;"> + <strong id="fileStatus"></strong> + </div> + </div> + <div style="padding-left:15px; display:none;" id="filePathBox"> + <strong><?=gettext("Log/File Path"); ?>:</strong> + <div class="list" style="display:inline;" id="fbTarget"></div> + </div> + </td> + <td align="right"> + <div style="padding-right:15px; display:none;" id="fileRefreshBtn"> + <?php + echo("<img src='../tree/page-file.png' onclick='loadFile()' title='" . gettext("Refresh current display") . "' alt='refresh' width='17' height='17' border='0' /> "); + if ($downloadable) { + echo("<input type='image' src='../tree/page-file_play.gif' name='download[]' id='download' value='Download' title='" . gettext("Download current logfile") . "' alt='download' width='17' height='17' border='0' /> "); + } + if ($clearable) { + echo("<input type='image' src='../tree/page-file_x.gif' name='clear[]' id='clear' value='Clear' title='" . gettext("Clear current logfile") . "' alt='clear' width='17' height='17' border='0' />"); + } + ?> + </div> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + <tr> + <td colspan="2"> + <table width="100%"> + <tbody> + <tr> + <td valign="top" class="label"> + <div style="background:#eeeeee;" id="fileOutput"> + <textarea id="fileContent" name="fileContent" style="width:100%;" rows="30" wrap="off" disabled></textarea> + </div> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> + </table> + </div> + </td> + </tr> +</table> +</form> + +<?php if (!isset($_POST['file'])): ?> +<script type="text/javascript"> +//<![CDATA[ + document.getElementById("logFile").selectedIndex=-1; +//]]> +</script> +<?php endif; ?> +<?php include("fend.inc"); ?> +</body> +</html>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_sync.xml b/config/pfblockerng/pfblockerng_sync.xml new file mode 100644 index 00000000..06ea40db --- /dev/null +++ b/config/pfblockerng/pfblockerng_sync.xml @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + pfBlockerNG_sync.xml + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfblocker for pfSense + Copyright (C) 2011 Marcello Coutinho + All rights reserved. +*/ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfblockerngsync</name> + <version>1.0</version> + <title>pfBlockerNG: XMLRPC Sync</title> + <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file> + <menu> + <name>pfBlockerNG</name> + <tooltiptext>Configure pfBlockerNG</tooltiptext> + <section>Services</section> + <url>pkg_edit.php?xml=pfblockerng.xml&id=0</url> + </menu> + <tabs> + <tab> + <text>General</text> + <url>/pkg_edit.php?xml=pfblockerng.xml&id=0</url> + </tab> + <tab> + <text>Update</text> + <url>/pfblockerng/pfblockerng_update.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pfblockerng/pfblockerng_alerts.php</url> + </tab> + <tab> + <text>Reputation</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0</url> + </tab> + <tab> + <text>IPv4</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url> + </tab> + <tab> + <text>IPv6</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url> + </tab> + <tab> + <text>Top 20</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0</url> + </tab> + <tab> + <text>Africa</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0</url> + </tab> + <tab> + <text>Asia</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0</url> + </tab> + <tab> + <text>Europe</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0</url> + </tab> + <tab> + <text>N.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Oceania</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0</url> + </tab> + <tab> + <text>S.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Logs</text> + <url>/pfblockerng/pfblockerng_log.php</url> + </tab> + <tab> + <text>Sync</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0</url> + <active/> + </tab> + </tabs> + <fields> + <field> + <name>pfBlockerNG XMLRPC Sync Settings</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>LINKS</fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> <a href="/firewall_rules.php">Firewall Rules</a> <a href="diag_logs_filter.php">Firewall Logs</a>]]> + </description> + <type>info</type> + </field> + <field> + <fielddescr>Enable Sync</fielddescr> + <fieldname>varsynconchanges</fieldname> + <description><![CDATA[When enabled, this will sync all configuration settings to the Replication Targets.<br /><br /> + <b>Important:</b> While using "Sync to hosts defined below", only sync from host A to B, A to C + <br /> but <b>do not</b> enable XMLRPC sync <b>to</b> A. This will result in a loop!]]> + </description> + <type>select</type> + <required/> + <default_value>disabled</default_value> + <options> + <option><name>Do not sync this package configuration</name><value>disabled</value></option> + <option><name>Sync to configured system backup server</name><value>auto</value></option> + <option><name>Sync to host(s) defined below</name><value>manual</value></option> + </options> + </field> + <field> + <fielddescr>XMLRPC Timeout</fielddescr> + <fieldname>varsynctimeout</fieldname> + <description><![CDATA[Timeout in seconds for the XMLRPC timeout. Default: 150]]></description> + <type>input</type> + <default_value>150</default_value> + <size>5</size> + </field> + <field> + <fielddescr><![CDATA[Disable 'General Tab' sync]]></fielddescr> + <fieldname>syncinterfaces</fieldname> + <description>When selected, the 'General' Tab Customizations will not be sync'd</description> + <type>checkbox</type> + </field> + <field> + <name>pfBlockerNG XMLRPC Replication Targets</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>Replication Targets</fielddescr> + <fieldname>none</fieldname> + <type>rowhelper</type> + <rowhelper> + <rowhelperfield> + <fielddescr>Enable</fielddescr> + <fieldname>varsyncdestinenable</fieldname> + <description><![CDATA[Enable this host as a replication target]]></description> + <type>checkbox</type> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Protocol</fielddescr> + <fieldname>varsyncprotocol</fieldname> + <description><![CDATA[Choose the protocol of the destination host. Probably <b>http</b> or <b>https</b>]]></description> + <type>select</type> + <default_value>HTTP</default_value> + <options> + <option><name>HTTP</name><value>http</value></option> + <option><name>HTTPS</name><value>https</value></option> + </options> + </rowhelperfield> + <rowhelperfield> + <fielddescr>IP-Address</fielddescr> + <fieldname>varsyncipaddress</fieldname> + <description><![CDATA[IP Address of the destination host.]]></description> + <type>input</type> + <size>15</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Port</fielddescr> + <fieldname>varsyncport</fieldname> + <description><![CDATA[Choose the sync port of the destination host.]]></description> + <type>input</type> + <size>3</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Admin Password</fielddescr> + <fieldname>varsyncpassword</fieldname> + <description><![CDATA[Password of the user "admin" on the destination host.]]></description> + <type>password</type> + <size>20</size> + </rowhelperfield> + </rowhelper> + </field> + <field> + <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. Changes are Applied via CRON or + 'Force Update'</ul>]]></name> + <type>listtopic</type> + </field> + </fields> + <custom_php_install_command> + pfblockerng_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + pfblockerng_php_deinstall_command(); + </custom_php_deinstall_command> + <custom_php_validation_command> + pfblockerng_validate_input($_POST, $input_errors); + </custom_php_validation_command> + <custom_php_resync_config_command> + require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); + write_config("[pfBlockerNG] XMLRPC sync configurations saved."); + pfblockerng_sync_on_changes(); + </custom_php_resync_config_command> +</packagegui>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_top20.xml b/config/pfblockerng/pfblockerng_top20.xml new file mode 100644 index 00000000..7d2cf033 --- /dev/null +++ b/config/pfblockerng/pfblockerng_top20.xml @@ -0,0 +1,290 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* $Id$ */ +/* ========================================================================== */ +/* + pfBlockerNG_Top20.xml + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfblocker for pfSense + Copyright (C) 2011 Marcello Coutinho + All rights reserved. +*/ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfblockerngtopspammers</name> + <version>1.0</version> + <title>pfBlockerNG: Top 20 Spammer Countries</title> + <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file> + <menu> + <name>pfBlockerNG</name> + <tooltiptext>Configure pfblockerNG</tooltiptext> + <section>Firewall</section> + <url>pkg_edit.php?xml=pfblockerng.xml&id=0</url> + </menu> + <tabs> + <tab> + <text>General</text> + <url>/pkg_edit.php?xml=pfblockerng.xml&id=0</url> + </tab> + <tab> + <text>Update</text> + <url>/pfblockerng/pfblockerng_update.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pfblockerng/pfblockerng_alerts.php</url> + </tab> + <tab> + <text>Reputation</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0</url> + </tab> + <tab> + <text>IPv4</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url> + </tab> + <tab> + <text>IPv6</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url> + </tab> + <tab> + <text>Top 20</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0</url> + <active/> + </tab> + <tab> + <text>Africa</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0</url> + </tab> + <tab> + <text>Asia</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0</url> + </tab> + <tab> + <text>Europe</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0</url> + </tab> + <tab> + <text>N.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Oceania</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0</url> + </tab> + <tab> + <text>S.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Logs</text> + <url>/pfblockerng/pfblockerng_log.php</url> + </tab> + <tab> + <text>Sync</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0</url> + </tab> + </tabs> + <fields> + <field> + <name><![CDATA[TOP 20 - Spammer Countries (Geolite Data by Maxmind Inc. - ISO 3166)]]></name> + <type>listtopic</type> + </field> + <field> + <fielddescr>LINKS</fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> <a href="/firewall_rules.php">Firewall Rules</a> <a href="diag_logs_filter.php">Firewall Logs</a>]]> + </description> + <type>info</type> + </field> + <field> + <fielddescr><![CDATA[<br /><strong>Top 20 IPv4</strong><br />Spammer Countries]]></fielddescr> + <fieldname>countries4</fieldname> + <description> + <![CDATA[Select Top IPv4 Spammer Countries you want to take an action on.<br /> + <strong>Use CTRL + CLICK to unselect countries</strong>]]> + </description> + <type>select</type> + <options> + <option><name>China-CN</name><value>CN</value></option> + <option><name>Russia-RU</name><value>RU</value></option> + <option><name>Japan-JP</name><value>JP</value></option> + <option><name>Ukraine-UA</name><value>UA</value></option> + <option><name>United Kingdom-GB</name><value>GB</value></option> + <option><name>Germany-DE</name><value>DE</value></option> + <option><name>Brazil-BR</name><value>BR</value></option> + <option><name>France-FR</name><value>FR</value></option> + <option><name>India-IN</name><value>IN</value></option> + <option><name>Turkey-TR</name><value>TR</value></option> + <option><name>Italy-IT</name><value>IT</value></option> + <option><name>South Korea-KR</name><value>KR</value></option> + <option><name>Poland-PL</name><value>PL</value></option> + <option><name>Spain-ES</name><value>ES</value></option> + <option><name>Vietnam-VN</name><value>VN</value></option> + <option><name>Argentina-AR</name><value>AR</value></option> + <option><name>Columbia-CO</name><value>CO</value></option> + <option><name>Taiwan-TW</name><value>TW</value></option> + <option><name>Mexico-MX</name><value>MX</value></option> + <option><name>Chilie-CL</name><value>CL</value></option> + </options> + <size>20</size> + <multiple/> + </field> + <field> + <fielddescr><![CDATA[<br /><strong>Top 20 IPv6</strong><br />Spammer Countries]]></fielddescr> + <fieldname>countries6</fieldname> + <description> + <![CDATA[Select Top IPv6 Spammer Countries you want to take an action on.<br /> + <strong>Use CTRL + CLICK to unselect countries</strong>]]> + </description> + <type>select</type> + <options> + <option><name>China-CN</name><value>CN</value></option> + <option><name>Russia-RU</name><value>RU</value></option> + <option><name>Japan-JP</name><value>JP</value></option> + <option><name>Ukraine-UA</name><value>UA</value></option> + <option><name>United Kingdom-GB</name><value>GB</value></option> + <option><name>Germany-DE</name><value>DE</value></option> + <option><name>Brazil-BR</name><value>BR</value></option> + <option><name>France-FR</name><value>FR</value></option> + <option><name>India-IN</name><value>IN</value></option> + <option><name>Turkey-TR</name><value>TR</value></option> + <option><name>Italy-IT</name><value>IT</value></option> + <option><name>South Korea-KR</name><value>KR</value></option> + <option><name>Poland-PL</name><value>PL</value></option> + <option><name>Spain-ES</name><value>ES</value></option> + <option><name>Vietnam-VN</name><value>VN</value></option> + <option><name>Argentina-AR</name><value>AR</value></option> + <option><name>Columbia-CO</name><value>CO</value></option> + <option><name>Taiwan-TW</name><value>TW</value></option> + <option><name>Mexico-MX</name><value>MX</value></option> + <option><name>Chilie-CL</name><value>CL</value></option> + </options> + <size>20</size> + <multiple/> + </field> + <field> + <fielddescr>List Action</fielddescr> + <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br /> + Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br /> + <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br /> + + <strong><u>'Deny' Rules:</u></strong><br /> + 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other + interfaces. Typical uses of 'Deny' rules are:<br /> + <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li> + <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by + traffic sent in the other direction. Does not affect traffic in the other direction. </li> + <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while + still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul> + <strong><u>'Permit' Rules:</u></strong><br /> + 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create + any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br /> + <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They + override <u>almost all other</u> Firewall rules on the stated interfaces.</li> + <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a + few IPs that should be accessible.</li></ul> + <strong><u>'Match' Rules:</u></strong><br /> + 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic. + <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li> + <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul> + <strong><u>'Alias' Rules:</u></strong><br /> + <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else). + This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired. + <ul><li><strong>Options - Alias Deny, Alias Permit, Alias Match, Alias Native</strong></li><br /> + <li>'Alias Deny' can use De-Duplication and Reputation Processes if configured.</li><br /> + <li>'Alias Permit' and 'Alias Match' will be saved in the Same folder as the other Permit/Match Auto-Rules</li><br /> + <li>'Alias Native' lists are kept in their Native format without any modifications.</li></ul> + <strong>When using 'Alias' rules, change (pfB_) to ( pfb_ ) in the beginning of rule description and Use the 'Exact' spelling of + the Alias (no trailing Whitespace) </strong> Custom 'Alias' rules with 'pfB_ xxx' description will be removed by package if + using Auto Rule Creation.<br /><br /><strong>Tip</strong>: You can create the Auto Rules and remove "<u>auto rule</u>" from the Rule + Descriptions, then disable Auto Rules. This method will 'KEEP' these rules from being 'Deleted' which will allow editing for a Custom + Alias Configuration<br />]]> + </description> + <fieldname>action</fieldname> + <type>select</type> + <options> + <option><name>Disabled</name><value>Disabled</value></option> + <option><name>Deny Inbound</name><value>Deny_Inbound</value></option> + <option><name>Deny Outbound</name><value>Deny_Outbound</value></option> + <option><name>Deny Both</name><value>Deny_Both</value></option> + <option><name>Permit Inbound</name><value>Permit_Inbound</value></option> + <option><name>Permit Outbound</name><value>Permit_Outbound</value></option> + <option><name>Permit Both</name><value>Permit_Both</value></option> + <option><name>Match Inbound</name><value>Match_Inbound</value></option> + <option><name>Match Outbound</name><value>Match_Outbound</value></option> + <option><name>Match Both</name><value>Match_Both</value></option> + <option><name>Alias Deny</name><value>Alias_Deny</value></option> + <option><name>Alias Permit</name><value>Alias_Permit</value></option> + <option><name>Alias Match</name><value>Alias_Match</value></option> + </options> + </field> + <field> + <fielddescr>Enable Logging</fielddescr> + <fieldname>aliaslog</fieldname> + <description><![CDATA[Default:<strong>Enable</strong><br /> + Select - Logging to Status: System Logs: FIREWALL ( Log )]]> + </description> + <type>select</type> + <options> + <option><name>Enable</name><value>enabled</value></option> + <option><name>Disable</name><value>disabled</value></option> + </options> + </field> + <field> + <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. Changes are Applied via CRON or + 'Force Update'</ul>]]> </name> + <type>listtopic</type> + </field> + </fields> + <custom_php_install_command> + pfblockerng_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + pfblockerng_php_deinstall_command(); + </custom_php_deinstall_command> + <custom_php_validation_command> + pfblockerng_validate_input($_POST, $input_errors); + </custom_php_validation_command> + <custom_php_resync_config_command> + global $pfb; + $pfb['save'] = TRUE; + sync_package_pfblockerng(); + </custom_php_resync_config_command> +</packagegui>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_update.php b/config/pfblockerng/pfblockerng_update.php new file mode 100644 index 00000000..dc0fab85 --- /dev/null +++ b/config/pfblockerng/pfblockerng_update.php @@ -0,0 +1,425 @@ +<?php + +/* pfBlockerNG_Update.php + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Portions of this code are based on original work done for + pfSense from the following contributors: + + pkg_mgr_install.php + Part of pfSense (https://www.pfsense.org) + Copyright (C) 2004-2010 Scott Ullrich <sullrich@gmail.com> + Copyright (C) 2005 Colin Smith + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require_once("guiconfig.inc"); +require_once("globals.inc"); +require_once("pfsense-utils.inc"); +require_once("functions.inc"); +require_once("util.inc"); +require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc"); + +pfb_global(); + +// Collect pfBlockerNG log file and post Live output to Terminal window. +function pfbupdate_output($text) { + $text = preg_replace("/\n/", "\\n", $text); + echo "\n<script type=\"text/javascript\">"; + echo "\n//<![CDATA["; + echo "\nthis.document.forms[0].pfb_output.value = \"" . $text . "\";"; + echo "\nthis.document.forms[0].pfb_output.scrollTop = this.document.forms[0].pfb_output.scrollHeight;"; + echo "\n//]]>"; + echo "\n</script>"; + /* ensure that contents are written out */ + ob_flush(); +} + +// Post Status Message to Terminal window. +function pfbupdate_status($status) { + $status = preg_replace("/\n/", "\\n", $status); + echo "\n<script type=\"text/javascript\">"; + echo "\n//<![CDATA["; + echo "\nthis.document.forms[0].pfb_status.value=\"" . $status . "\";"; + echo "\n//]]>"; + echo "\n</script>"; + /* ensure that contents are written out */ + ob_flush(); +} + + +// Function to perform a Force Update, Cron or Reload +function pfb_cron_update($type) { + + global $pfb; + + // Query for any Active pfBlockerNG CRON Jobs + $result_cron = array(); + $cron_event = exec ("/bin/ps -wx", $result_cron); + if (preg_grep("/pfblockerng[.]php\s+cron/", $result_cron) || preg_grep("/pfblockerng[.]php\s+update/", $result_cron)) { + pfbupdate_status(gettext("Force {$type} Terminated - Failed due to Active Running Task")); + exit; + } + + if (!file_exists("{$pfb['log']}")) + touch("{$pfb['log']}"); + + // Update Status Window with correct Task + if ($type == "update") { + pfbupdate_status(gettext("Running Force Update Task")); + } elseif ($type == "reload") { + pfbupdate_status(gettext("Running Force Reload Task")); + $type = "update"; + } else { + pfbupdate_status(gettext("Running Force CRON Task")); + } + + // Remove any existing pfBlockerNG CRON Jobs + install_cron_job("pfblockerng.php cron", false); + write_config(); + + // Execute PHP Process in the Background + mwexec_bg("/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php {$type} >> {$pfb['log']} 2>&1"); + + // Start at EOF + $lastpos_old = ""; + $len = filesize("{$pfb['log']}"); + $lastpos = $len; + + while (true) { + usleep(300000); //0.3s + clearstatcache(false,$pfb['log']); + $len = filesize("{$pfb['log']}"); + if ($len < $lastpos) { + //file deleted or reset + $lastpos = $len; + } else { + $f = fopen($pfb['log'], "rb"); + if ($f === false) + die(); + fseek($f, $lastpos); + + while (!feof($f)) { + + $pfb_buffer = fread($f, 2048); + $pfb_output .= str_replace( "\r", "", $pfb_buffer); + + // Refresh on new lines only. This allows Scrolling. + if ($lastpos != $lastpos_old) + pfbupdate_output($pfb_output); + $lastpos_old = $lastpos; + ob_flush(); + flush(); + } + $lastpos = ftell($f); + fclose($f); + } + // Capture Remaining Output before closing File + if (preg_match("/(UPDATE PROCESS ENDED)/",$pfb_output)) { + $f = fopen($pfb['log'], "rb"); + fseek($f, $lastpos); + $pfb_buffer = fread($f, 2048); + $pfb_output .= str_replace( "\r", "", $pfb_buffer); + pfbupdate_output($pfb_output); + clearstatcache(false,$pfb['log']); + ob_flush(); + flush(); + fclose($f); + # Call Log Mgmt Function + pfb_log_mgmt(); + die(); + } + } +} + + +$pgtitle = gettext("pfBlockerNG: Update"); +include_once("head.inc"); +?> +<body link="#000000" vlink="#0000CC" alink="#000000"> +<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> +<?php include_once("fbegin.inc"); ?> + + <table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td> + <?php + $tab_array = array(); + $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml&id=0"); + $tab_array[] = array(gettext("Update"), true, "/pfblockerng/pfblockerng_update.php"); + $tab_array[] = array(gettext("Alerts"), false, "/pfblockerng/pfblockerng_alerts.php"); + $tab_array[] = array(gettext("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0"); + $tab_array[] = array(gettext("IPv4"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml"); + $tab_array[] = array(gettext("IPv6"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml"); + $tab_array[] = array(gettext("Top 20"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0"); + $tab_array[] = array(gettext("Africa"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0"); + $tab_array[] = array(gettext("Asia"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0"); + $tab_array[] = array(gettext("Europe"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0"); + $tab_array[] = array(gettext("N.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0"); + $tab_array[] = array(gettext("Oceania"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0"); + $tab_array[] = array(gettext("S.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0"); + $tab_array[] = array(gettext("Logs"), false, "/pfblockerng/pfblockerng_log.php"); + $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0"); + display_top_tabs($tab_array, true); + ?> + </td> + </tr> + </table> + <div id="mainareapkg"> + <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="2"> + <tr> + <td colspan="2" class="vncell" align="left"><?php echo gettext("LINKS :"); ?> + <a href='/firewall_aliases.php' target="_blank"><?php echo gettext("Firewall Alias"); ?></a> + <a href='/firewall_rules.php' target="_blank"><?php echo gettext("Firewall Rules"); ?></a> + <a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br /> + </td> + </tr> + <tr> + <td colspan="2" class="listtopic"><?php echo gettext("CRON Status"); ?></td> + </tr> + <tr> + <td colspan="2" class="listr"> + <?php + // Collect Existing CRON settings + if (is_array($config['cron']['item'])) { + foreach ($config['cron']['item'] as $cron) { + if (preg_match("/usr.local.www.pfblockerng.pfblockerng.php cron/",$cron["command"])) { + $pfb_min = "{$cron['minute']}"; + break; + } + } + } + // Calculate Minutes Remaining till next CRON Event. + $currentmin = date('i'); + switch ($pfb_min) { + case "0": + $min_remain = (60 - $currentmin); + break; + case "15": + if ($currentmin < 15) { + $min_remain = (15 - $currentmin); + } else { + $min_remain = (75 - $currentmin); + } + break; + case "30": + if ($currentmin < 30) { + $min_remain = (30 - $currentmin); + } else { + $min_remain = (90 - $currentmin); + } + break; + case "45": + if ($currentmin < 45) { + $min_remain = (45 - $currentmin); + } else { + $min_remain = (105 - $currentmin); + } + break; + } + + // Default to "< 1 minute" if empty + if (empty($min_remain)) + $min_remain = "< 1"; + + // Next Scheduled Cron Time + if ($pfb_min == "0") + $pfb_min = "00"; + $nextcron = (date('H') +1) . ":{$pfb_min}"; + + // If pfBlockerNG is Disabled or Cron Task is Missing + if (empty($pfb['enable']) || empty($pfb_min)) { + $min_remain = " -- "; + $nextcron = " [ Disabled ] "; + } + + echo "NEXT Scheduled CRON Event will run at <font size=\"3\"> {$nextcron}</font> in<font size=\"3\"> + <span class=\"red\"> {$min_remain} </span></font> Minutes."; + + // Query for any Active pfBlockerNG CRON Jobs + $result_cron = array(); + $cron_event = exec ("/bin/ps -wax", $result_cron); + if (preg_grep("/pfblockerng[.]php\s+cron/", $result_cron)) { + echo "<font size=\"2\"><span class=\"red\"> + Active pfBlockerNG CRON Job </span></font> "; + echo "<img src = '/themes/{$g['theme']}/images/icons/icon_pass.gif' width='15' height='15' + border='0' title='pfBockerNG Cron Task is Running.'/>"; + } + echo "<br /><font size=\"3\"><span class=\"red\">Refresh</span></font> to update current Status and Minute(s) remaining"; + ?> + </td> + </tr> + <tr> + <td colspan="2" class="vncell"><?php echo gettext("<br />"); ?></td> + </tr> + <tr> + <td colspan="2" class="listtopic"><?php echo gettext("Update Options"); ?></td> + </tr> + <tr> + <td colspan="2" class="listr"> + <!-- Update Option Text --> + <?php echo "<span class='red'><strong>" . gettext("** AVOID ** ") . " " . "</strong></span>" . + gettext("Running these Options - when CRON is expected to RUN!") . gettext("<br /><br />") . + "<strong>" . gettext("Force Update") . "</strong>" . gettext(" will download any new Alias/Lists.") . + gettext("<br />") . "<strong>" . gettext("Force Cron") . "</strong>" . + gettext(" will download any Alias/Lists that are within the Frequency Setting (due for Update).") . gettext("<br />") . + "<strong>" . gettext("Force Reload") . "</strong>" . + gettext(" will reload all Lists using the existing Downloaded files.") . + gettext(" This is useful when Lists are out of 'sync' or Reputation changes were made.") ;?><br /> + </td> + </tr> + <tr> + <td colspan="2" class="vncell"> + <!-- Update Option Buttons --> + <input type="submit" class="formbtns" name="pfbupdate" id="pfbupdate" value="Force Update" + title="<?=gettext("Run Force Update");?>" /> + <input type="submit" class="formbtns" name="pfbcron" id="pfbcron" value="Force Cron" + title="<?=gettext("Run Force Cron Update");?>" /> + <input type="submit" class="formbtns" name="pfbreload" id="pfbreload" value="Force Reload" + title="<?=gettext("Run Force Reload");?>" /> + </td> + </tr> + <tr> + <td colspan="2" class="vncell"><?php echo gettext("<br />"); ?></td> + </tr> + <tr> + <td colspan="2" class="listtopic"><?php echo gettext("Live Log Viewer only"); ?></td> + </tr> + <tr> + <td colspan="2" class="listr"><?php echo gettext("Selecting 'Live Log Viewer' will allow viewing a running Cron Update"); ?></td> + </tr> + <tr> + <td colspan="2" class="vncell"> + <!-- Log Viewer Buttons --> + <input type="submit" class="formbtns" name="pfbview" id="pfbview" value="VIEW" + title="<?=gettext("VIEW pfBlockerNG LOG");?>"/> + <input type="submit" class="formbtns" name="pfbviewcancel" id="pfbviewcancel" value="End View" + title="<?=gettext("END VIEW of pfBlockerNG LOG");?>"/> + <?php echo " " . gettext(" Select 'view' to open ") . "<strong>" . gettext(' pfBlockerNG ') . "</strong>" . + gettext(" Log. (Select 'End View' to terminate the viewer.)"); ?><br /><br /> + </td> + </tr> + <tr> + <td class="tabcont" align="left"> + <!-- status box --> + <textarea cols="90" rows="1" name="pfb_status" id="pfb_status" + wrap="hard"><?=gettext("Log Viewer Standby");?></textarea> + </td> + </tr> + <tr> + <td> + <!-- command output box --> + <textarea cols="90" rows="35" name="pfb_output" id="pfb_output" wrap="hard"></textarea> + </td> + </tr> + </table> + </div> + +<?php +include("fend.inc"); + +// Execute the Viewer output Window +if (isset($_POST['pfbview'])) { + + if (!file_exists("{$pfb['log']}")) + touch("{$pfb['log']}"); + + // Reference: http://stackoverflow.com/questions/3218895/php-how-to-read-a-file-live-that-is-constantly-being-written-to + pfbupdate_status(gettext("Log Viewing in progress. ** Press 'END VIEW' to Exit ** ")); + $lastpos_old = ""; + $len = filesize("{$pfb['log']}"); + + // Start at EOF ( - 15000) + if ($len > 15000) { + $lastpos = ($len - 15000); + } else { + $lastpos = 0; + } + + while (true) { + usleep(300000); //0.3s + clearstatcache(false,$pfb['log']); + $len = filesize("{$pfb['log']}"); + if ($len < $lastpos) { + //file deleted or reset + $lastpos = $len; + } else { + $f = fopen($pfb['log'], "rb"); + if ($f === false) + die(); + fseek($f, $lastpos); + + while (!feof($f)) { + + $pfb_buffer = fread($f, 4096); + $pfb_output .= str_replace( "\r", "", $pfb_buffer); + + // Refresh on new lines only. This allows scrolling. + if ($lastpos != $lastpos_old) { + pfbupdate_output($pfb_output); + } + $lastpos_old = $lastpos; + ob_flush(); + flush(); + } + $lastpos = ftell($f); + fclose($f); + } + } +} + +// End the Viewer output Window +if (isset($_POST['pfbviewcancel'])) { + clearstatcache(false,$pfb['log']); + ob_flush(); + flush(); + fclose("{$pfb['log']}"); +} + +// Execute a Force Update +if (isset($_POST['pfbupdate']) && $pfb['enable'] == "on") { + pfb_cron_update(update); +} + +// Execute a CRON Command to update any Lists within the Frequency Settings +if (isset($_POST['pfbcron']) && $pfb['enable'] == "on") { + pfb_cron_update(cron); +} + +// Execute a Reload of all Aliases and Lists +if (isset($_POST['pfbreload']) && $pfb['enable'] == "on") { + $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = "on"; + write_config(); + pfb_cron_update(reload); +} + +?> +</form> +</body> +</html>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_v4lists.xml b/config/pfblockerng/pfblockerng_v4lists.xml new file mode 100644 index 00000000..17f1a14d --- /dev/null +++ b/config/pfblockerng/pfblockerng_v4lists.xml @@ -0,0 +1,422 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* ========================================================================== */ +/* + pfBlockerNG_v4lists.xml + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfblocker for pfSense + Copyright (C) 2011 Marcello Coutinho + + part of pfSense (http://www.pfSense.com) + Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com> + All rights reserved. +*/ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfblockernglistsv4</name> + <version>1.0</version> + <title>pfBlockerNG: IPv4 Alias/List Configuration</title> + <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file> + <menu> + <name>pfBlockerNG</name> + <tooltiptext></tooltiptext> + <section>Firewall</section> + <configfile>pfblockerng_v4lists.xml</configfile> + </menu> + <tabs> + <tab> + <text>General</text> + <url>/pkg_edit.php?xml=pfblockerng.xml&id=0</url> + <tooltiptext></tooltiptext> + </tab> + <tab> + <text>Update</text> + <url>/pfblockerng/pfblockerng_update.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pfblockerng/pfblockerng_alerts.php</url> + </tab> + <tab> + <text>Reputation</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0</url> + </tab> + <tab> + <text>IPv4</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url> + <active/> + </tab> + <tab> + <text>IPv6</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url> + </tab> + <tab> + <text>Top 20</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0</url> + </tab> + <tab> + <text>Africa</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0</url> + </tab> + <tab> + <text>Asia</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0</url> + </tab> + <tab> + <text>Europe</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0</url> + </tab> + <tab> + <text>N.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Oceania</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0</url> + </tab> + <tab> + <text>S.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Logs</text> + <url>/pfblockerng/pfblockerng_log.php</url> + </tab> + <tab> + <text>Sync</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0</url> + </tab> + </tabs> + <adddeleteeditpagefields> + <columnitem> + <fielddescr>Alias Name</fielddescr> + <fieldname>aliasname</fieldname> + </columnitem> + <columnitem> + <fielddescr>Alias Description</fielddescr> + <fieldname>description</fieldname> + </columnitem> + <columnitem> + <fielddescr>Action</fielddescr> + <fieldname>action</fieldname> + </columnitem> + <columnitem> + <fielddescr>Frequency</fielddescr> + <fieldname>cron</fieldname> + </columnitem> + <columnitem> + <fielddescr>Logging</fielddescr> + <fieldname>aliaslog</fieldname> + </columnitem> + </adddeleteeditpagefields> + <fields> + <field> + <name><![CDATA[IPv4 Network ranges / CIDR lists + (When Removing or Re-configuring Lists a 'Reload' is recommended.)]]></name> + <type>listtopic</type> + </field> + <field> + <fielddescr>LINKS</fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> <a href="/firewall_rules.php">Firewall Rules</a> <a href="diag_logs_filter.php">Firewall Logs</a>]]> + </description> + <type>info</type> + </field> + <field> + <fielddescr>Alias Name</fielddescr> + <fieldname>aliasname</fieldname> + <description><![CDATA[Enter lists Alias Names.<br /> + Example: Badguys<br /> + Do not include <strong>'pfBlocker' or 'pfB_'</strong> in the Alias Name, it's done by package.<br /> + <strong>International, special or space characters will be ignored in firewall alias names. + </strong><br />]]> + </description> + <type>input</type> + <size>20</size> + </field> + <field> + <fielddescr>List Description</fielddescr> + <fieldname>description</fieldname> + <type>input</type> + <size>90</size> + </field> + <field> + <fieldname>InfoLists</fieldname> + <type>info</type> + <description><![CDATA[<strong><u>'Format'</u></strong> : Select the Format Type<br /><br /> + <strong><u>'URL'</u></strong> : Add direct link to list: + Example: <a target=_new href='http://list.iblocklist.com/?list=bt_ads&fileformat=p2p&archiveformat=gz'>Ads</a>, + <a target=_new href='http://list.iblocklist.com/?list=bt_spyware&fileformat=p2p&archiveformat=gz'>Spyware</a>, + <a target=_new href='http://list.iblocklist.com/?list=bt_proxy&fileformat=p2p&archiveformat=gz'>Proxies</a> )<br /><br /> + <strong><u>'pfSense Local File'</u></strong> Format :<br /><br /> + http(s)://127.0.0.1/NAME_OF_FILE <strong>or</strong> + /usr/local/www/NAME_OF_FILE (Files can also be placed in the /var/db/pfblockerng folders)<br /><br /> + + <strong><u>'Header'</u></strong> : The <u>'Header' Field</u> must be <u>Unique</u>, it will + name the List File and it will be referenced in the pfBlockerNG Widget. + Use a Unique Prefix per 'Alias Category' followed by a unique descriptor for each List.<br /><br />]]> + </description> + </field> + <field> + <fielddescr><![CDATA[<strong>IPv4</strong> Lists]]></fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<br /><strong>'Format'</strong> - Select the file format that URL will retrieve.<br /> + + <ul><li><strong>'txt'</strong> Plain txt Lists</li><br /> + <li><strong>'gz'</strong> - IBlock GZ Lists in Range Format only.</li><br /> + <li><strong>'gz_2'</strong> - Other GZ Lists in IP or CIDR only.</li><br /> + <li><strong>'gz_lg'</strong> - Large IBlock GZ Lists in Range Format only.</li><br /> + <li><strong>'zip'</strong> - ZIP'd Lists</li><br /> + <li><strong>'block'</strong>- IP x.x.x.0 Block type</li><br /> + <li><strong>'html'</strong> - Web Links</li><br /> + <li><strong>'xlsx'</strong> - Excel Lists</li><br /> + <li><strong>'rsync'</strong> - RSync Lists</li><br /> + <li><strong>'ET' IQRisk</strong> - Only</li></ul> + <strong>'State'</strong> - Select the Run State for each list.<br /> + <ul><li><strong>'ON/OFF'</strong> - Enabled / Disabled</li><br /> + <li><strong>'HOLD'</strong> - Once a List has been Downloaded, list will remain Static.</li></ul> + <strong>'Note' -</strong> Downloaded or pfsense local file must have only one network per line and follows the syntax below: + <ul>Network ranges: <strong>172.16.1.0-172.16.1.255</strong><br /> + IP Address: <strong>172.16.1.10</strong><br /> + CIDR: <strong>172.16.1.0/24</strong></ul>]]> + </description> + <type>rowhelper</type> + <rowhelper> + <rowhelperfield> + <fielddescr>Format</fielddescr> + <fieldname>format</fieldname> + <type>select</type> + <options> + <option><name>txt</name><value>txt</value></option> + <option><name>gz</name><value>gz</value></option> + <option><name>gz_2</name><value>gz_2</value></option> + <option><name>gz_lg</name><value>gz_lg</value></option> + <option><name>zip</name><value>zip</value></option> + <option><name>block</name><value>block</value></option> + <option><name>html</name><value>html</value></option> + <option><name>xlsx</name><value>xlsx</value></option> + <option><name>RSync</name><value>rsync</value></option> + <option><name>ET</name><value>et</value></option> + </options> + </rowhelperfield> + <rowhelperfield> + <fielddescr>State</fielddescr> + <fieldname>state</fieldname> + <type>select</type> + <options> + <option><name>ON</name><value>Enabled</value></option> + <option><name>OFF</name><value>Disabled</value></option> + <option><name>HOLD</name><value>Hold</value></option> + </options> + </rowhelperfield> + <rowhelperfield> + <fielddescr>URL or pfSense local file</fielddescr> + <fieldname>url</fieldname> + <type>input</type> + <size>50</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Header</fielddescr> + <fieldname>header</fieldname> + <type>input</type> + <size>15</size> + </rowhelperfield> + </rowhelper> + </field> + <field> + <fielddescr>List Action</fielddescr> + <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br /> + Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br /> + <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br /> + + <strong><u>'Deny' Rules:</u></strong><br /> + 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other + interfaces. Typical uses of 'Deny' rules are:<br /> + <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li> + <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by + traffic sent in the other direction. Does not affect traffic in the other direction.</li> + <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while + still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul> + <strong><u>'Permit' Rules:</u></strong><br /> + 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create + any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br /> + <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They + override <u>almost all other</u> Firewall rules on the stated interfaces.</li> + <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a + few IPs that should be accessible.</li></ul> + <strong><u>'Match' Rules:</u></strong><br /> + 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic. + <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li> + <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul> + <strong><u>'Alias' Rules:</u></strong><br /> + <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else). + This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired. + <ul><li><strong>Options - Alias Deny, Alias Permit, Alias Match, Alias Native</strong></li><br /> + <li>'Alias Deny' can use De-Duplication and Reputation Processes if configured.</li><br /> + <li>'Alias Permit' and 'Alias Match' will be saved in the Same folder as the other Permit/Match Auto-Rules</li><br /> + <li>'Alias Native' lists are kept in their Native format without any modifications.</li></ul> + <strong>When using 'Alias' rules, change (pfB_) to ( pfb_ ) in the beginning of rule description and Use the 'Exact' spelling of + the Alias (no trailing Whitespace) </strong> Custom 'Alias' rules with 'pfB_ xxx' description will be removed by package if + using Auto Rule Creation.<br /><br /><strong>Tip</strong>: You can create the Auto Rules and remove "<u>auto rule</u>" from the Rule + Descriptions, then disable Auto Rules. This method will 'KEEP' these rules from being 'Deleted' which will allow editing for a Custom + Alias Configuration<br />]]> + </description> + <fieldname>action</fieldname> + <type>select</type> + <options> + <option><name>Disabled</name><value>Disabled</value></option> + <option><name>Deny Inbound</name><value>Deny_Inbound</value></option> + <option><name>Deny Outbound</name><value>Deny_Outbound</value></option> + <option><name>Deny Both</name><value>Deny_Both</value></option> + <option><name>Permit Inbound</name><value>Permit_Inbound</value></option> + <option><name>Permit Outbound</name><value>Permit_Outbound</value></option> + <option><name>Permit Both</name><value>Permit_Both</value></option> + <option><name>Match Inbound</name><value>Match_Inbound</value></option> + <option><name>Match Outbound</name><value>Match_Outbound</value></option> + <option><name>Match Both</name><value>Match_Both</value></option> + <option><name>Alias Deny</name><value>Alias_Deny</value></option> + <option><name>Alias Permit</name><value>Alias_Permit</value></option> + <option><name>Alias Match</name><value>Alias_Match</value></option> + <option><name>Alias Native</name><value>Alias_Native</value></option> + </options> + </field> + <field> + <fielddescr>Update Frequency</fielddescr> + <fieldname>cron</fieldname> + <description><![CDATA[Default:<strong>Never</strong><br /> + Select how often List files will be downloaded]]> + </description> + <type>select</type> + <options> + <option><name>Never</name><value>Never</value></option> + <option><name>Every Hour</name><value>01hour</value></option> + <option><name>Every 2 Hours</name><value>02hours</value></option> + <option><name>Every 3 Hours</name><value>03hours</value></option> + <option><name>Every 4 Hours</name><value>04hours</value></option> + <option><name>Every 6 Hours</name><value>06hours</value></option> + <option><name>Every 8 Hours</name><value>08hours</value></option> + <option><name>Every 12 Hours</name><value>12hours</value></option> + <option><name>Once a day</name><value>EveryDay</value></option> + <option><name>Weekly</name><value>Weekly</value></option> + </options> + </field> + <field> + <fielddescr>Weekly (Day of Week)</fielddescr> + <fieldname>dow</fieldname> + <description><![CDATA[Default:<strong>1</strong><br /> + Select the 'Weekly' ( Day of the Week ) to Update <br /> + This is only required for the 'Weekly' Frequency Selection. The 24 Hour Download 'Time' will be used.]]> + </description> + <type>select</type> + <options> + <option><name>Monday</name><value>1</value></option> + <option><name>Tuesday</name><value>2</value></option> + <option><name>Wednesday</name><value>3</value></option> + <option><name>Thursday</name><value>4</value></option> + <option><name>Friday</name><value>5</value></option> + <option><name>Saturday</name><value>6</value></option> + <option><name>Sunday</name><value>7</value></option> + </options> + </field> + <field> + <fielddescr>Enable Logging</fielddescr> + <fieldname>aliaslog</fieldname> + <description><![CDATA[Default:<strong>Enable</strong><br /> + Select - Logging to Status: System Logs: FIREWALL ( Log )<br /> + This can be overriden by the 'Global Logging' Option in the General Tab.]]> + </description> + <type>select</type> + <options> + <option><name>Enable</name><value>enabled</value></option> + <option><name>Disable</name><value>disabled</value></option> + </options> + </field> + <field> + <name>IPv4 Custom list</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>IPv4 Custom Address(es)</fielddescr> + <fieldname>custom</fieldname> + <description><![CDATA[Please limit the size of the Custom List as this is stored as 'Base64' format in the config.xml file.<br /> + Follow the syntax below:<br /><br /> + Network ranges: <strong>172.16.1.0-172.16.1.255</strong><br /> + IP Address: <strong>172.16.1.10</strong><br /> + CIDR: <strong>172.16.1.0/24</strong><br /><br /> + You may use "<strong>#</strong>" after any IP/CIDR/Range to add comments. ie: x.x.x.x # Safe IP Address]]> + </description> + <type>textarea</type> + <cols>50</cols> + <rows>10</rows> + <encoding>base64</encoding> + </field> + <field> + <fielddescr>Update Custom List</fielddescr> + <fieldname>custom_update</fieldname> + <description><![CDATA[Default:<strong>Disable</strong><br /> + select - Enable Update if changes are made to this List. Cron will also resync this list at the next Scheduled Update.]]> + </description> + <type>select</type> + <options> + <option><name>Disable</name><value>disabled</value></option> + <option><name>Enable</name><value>enabled</value></option> + </options> + </field> + <field> + <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. Changes are Applied via CRON or + 'Force Update'</ul>]]></name> + <type>listtopic</type> + </field> + </fields> + <custom_php_install_command> + pfblockerng_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + pfblockerng_php_deinstall_command(); + </custom_php_deinstall_command> + <custom_php_validation_command> + pfblockerng_validate_input($_POST, $input_errors); + </custom_php_validation_command> + <custom_php_resync_config_command> + global $pfb; + $pfb['save'] = TRUE; + sync_package_pfblockerng(); + </custom_php_resync_config_command> +</packagegui>
\ No newline at end of file diff --git a/config/pfblockerng/pfblockerng_v6lists.xml b/config/pfblockerng/pfblockerng_v6lists.xml new file mode 100644 index 00000000..2a381451 --- /dev/null +++ b/config/pfblockerng/pfblockerng_v6lists.xml @@ -0,0 +1,417 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd"> +<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?> +<packagegui> + <copyright> + <![CDATA[ +/* ========================================================================== */ +/* + pfBlockerNG_v6lists.xml + + pfBlockerNG + Copyright (C) 2014 BBcan177@gmail.com + All rights reserved. + + Based upon pfblocker for pfSense + Copyright (C) 2011 Marcello Coutinho + + part of pfSense (http://www.pfSense.com) + Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com> + All rights reserved. +*/ +/* ========================================================================== */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/* ========================================================================== */ + ]]> + </copyright> + <description>Describe your package here</description> + <requirements>Describe your package requirements here</requirements> + <faq>Currently there are no FAQ items provided.</faq> + <name>pfblockernglistsv6</name> + <version>1.0</version> + <title>pfBlockerNG: IPv6 Alias/List Configuration</title> + <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file> + <menu> + <name>pfBlockerNG</name> + <tooltiptext></tooltiptext> + <section>Firewall</section> + <configfile>pfblockerng_v6lists.xml</configfile> + </menu> + <tabs> + <tab> + <text>General</text> + <url>/pkg_edit.php?xml=pfblockerng.xml&id=0</url> + <tooltiptext></tooltiptext> + </tab> + <tab> + <text>Update</text> + <url>/pfblockerng/pfblockerng_update.php</url> + </tab> + <tab> + <text>Alerts</text> + <url>/pfblockerng/pfblockerng_alerts.php</url> + </tab> + <tab> + <text>Reputation</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0</url> + </tab> + <tab> + <text>IPv4</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url> + </tab> + <tab> + <text>IPv6</text> + <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url> + <active/> + </tab> + <tab> + <text>Top 20</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0</url> + </tab> + <tab> + <text>Africa</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0</url> + </tab> + <tab> + <text>Asia</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0</url> + </tab> + <tab> + <text>Europe</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0</url> + </tab> + <tab> + <text>N.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Oceania</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0</url> + </tab> + <tab> + <text>S.A.</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0</url> + </tab> + <tab> + <text>Logs</text> + <url>/pfblockerng/pfblockerng_log.php</url> + </tab> + <tab> + <text>Sync</text> + <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0</url> + </tab> + </tabs> + <adddeleteeditpagefields> + <columnitem> + <fielddescr>Alias Name</fielddescr> + <fieldname>aliasname</fieldname> + </columnitem> + <columnitem> + <fielddescr>Alias Description</fielddescr> + <fieldname>description</fieldname> + </columnitem> + <columnitem> + <fielddescr>Action</fielddescr> + <fieldname>action</fieldname> + </columnitem> + <columnitem> + <fielddescr>Frequency</fielddescr> + <fieldname>cron</fieldname> + </columnitem> + <columnitem> + <fielddescr>Logging</fielddescr> + <fieldname>aliaslog</fieldname> + </columnitem> + </adddeleteeditpagefields> + <fields> + <field> + <name>IPv6 Network ranges / CIDR lists</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>LINKS</fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> <a href="/firewall_rules.php">Firewall Rules</a> <a href="diag_logs_filter.php">Firewall Logs</a>]]> + </description> + <type>info</type> + </field> + <field> + <fielddescr>Alias Name</fielddescr> + <fieldname>aliasname</fieldname> + <description><![CDATA[Enter lists Alias Names.<br /> + Example: Badguys<br /> + Do not include <strong>'pfBlocker' or 'pfB_'</strong> in the Alias Name, it's done by package.<br /> + <strong>International, special or space characters will be ignored in firewall alias names. + </strong><br />]]> + </description> + <type>input</type> + <size>20</size> + </field> + <field> + <fielddescr>List Description</fielddescr> + <fieldname>description</fieldname> + <type>input</type> + <size>90</size> + </field> + <field> + <fieldname>InfoLists</fieldname> + <type>info</type> + <description><![CDATA[<strong><u>'Format'</u></strong> : Select the Format Type<br /><br /> + <strong><u>'URL'</u></strong> : Add direct link to list: + Example: <a target=_new href='http://list.iblocklist.com/?list=bt_ads&fileformat=p2p&archiveformat=gz'>Ads</a>, + <a target=_new href='http://list.iblocklist.com/?list=bt_spyware&fileformat=p2p&archiveformat=gz'>Spyware</a>, + <a target=_new href='http://list.iblocklist.com/?list=bt_proxy&fileformat=p2p&archiveformat=gz'>Proxies</a><br /><br /> + <strong><u>'pfSense Local File'</u></strong> Format :<br /><br /> + http(s)://127.0.0.1/NAME_OF_FILE <strong>or</strong> + /usr/local/www/NAME_OF_FILE (Files can also be placed in the /var/db/pfblockerng folders)<br /><br /> + + <strong><u>'Header'</u></strong> : The <u>'Header' Field</u> must be <u>Unique</u>, it will + name the List File and it will be referenced in the pfBlockerNG Widget. + Use a Unique Prefix per 'Alias Category' followed by a unique descriptor for each List.<br /><br />]]> + </description> + </field> + <field> + <fielddescr><![CDATA[<strong>IPv6</strong> Lists]]></fielddescr> + <fieldname>none</fieldname> + <description><![CDATA[<br /><strong>'Format'</strong> - Choose the file format that URL will retrieve.<br /> + + <ul><li><strong>'txt'</strong> Plain txt Lists</li><br /> + <li><strong>'gz'</strong> - IBlock GZ Lists in Range Format only.</li><br /> + <li><strong>'gz_2'</strong> - Other GZ Lists in IP or CIDR only.</li><br /> + <li><strong>'zip'</strong> - ZIP'd Lists</li><br /> + <li><strong>'block'</strong>- IP x.x.x.0 Block type</li><br /> + <li><strong>'html'</strong> - Web Links</li><br /> + <li><strong>'xlsx'</strong> - Excel Lists</li><br /> + <li><strong>'rsync'</strong> - RSync Lists</li><br /> + <strong>'State'</strong> - Select the Run State for each list.<br /> + <ul><li><strong>'ON/OFF'</strong> - Enabled / Disabled</li><br /> + <li><strong>'HOLD'</strong> - Once a List has been Downloaded, list will remain Static.</li></ul> + <strong>'Note' -</strong> Downloaded or pfsense local file must have only one network per line and follows the syntax below: + <ul>Network ranges: <strong> TBC </strong><br /> + IP Address: <strong> TBC </strong><br /> + CIDR: <strong> TBC </strong></ul>]]> + </description> + <type>rowhelper</type> + <rowhelper> + <rowhelperfield> + <fielddescr>Format</fielddescr> + <fieldname>format</fieldname> + <type>select</type> + <options> + <option><name>txt</name><value>txt</value></option> + <option><name>gz</name><value>gz</value></option> + <option><name>gz_2</name><value>gz_2</value></option> + <option><name>zip</name><value>zip</value></option> + <option><name>block</name><value>block</value></option> + <option><name>html</name><value>html</value></option> + <option><name>xlsx</name><value>xlsx</value></option> + <option><name>RSync</name><value>rsync</value></option> + </options> + </rowhelperfield> + <rowhelperfield> + <fielddescr>State</fielddescr> + <fieldname>state</fieldname> + <type>select</type> + <options> + <option><name>ON</name><value>Enabled</value></option> + <option><name>OFF</name><value>Disabled</value></option> + <option><name>HOLD</name><value>Hold</value></option> + </options> + </rowhelperfield> + <rowhelperfield> + <fielddescr>URL or pfSense local file</fielddescr> + <fieldname>url</fieldname> + <type>input</type> + <size>50</size> + </rowhelperfield> + <rowhelperfield> + <fielddescr>Header</fielddescr> + <fieldname>header</fieldname> + <type>input</type> + <size>15</size> + </rowhelperfield> + </rowhelper> + </field> + <field> + <fielddescr>List Action</fielddescr> + <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br /> + Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br /> + <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br /> + + <strong><u>'Deny' Rules:</u></strong><br /> + 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other + interfaces. Typical uses of 'Deny' rules are:<br /> + <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li> + <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by + traffic sent in the other direction. Does not affect traffic in the other direction.</li> + <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while + still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul> + <strong><u>'Permit' Rules:</u></strong><br /> + 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create + any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br /> + <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They + override <u>almost all other</u> Firewall rules on the stated interfaces.</li> + <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a + few IPs that should be accessible.</li></ul> + <strong><u>'Match' Rules:</u></strong><br /> + 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic. + <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li> + <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul> + <strong><u>'Alias' Rules:</u></strong><br /> + <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else). + This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired. + <ul><li><strong>Options - Alias Deny, Alias Permit, Alias Match, Alias Native</strong></li><br /> + <li>'Alias Deny' can use De-Duplication and Reputation Processes if configured.</li><br /> + <li>'Alias Permit' and 'Alias Match' will be saved in the Same folder as the other Permit/Match Auto-Rules</li><br /> + <li>'Alias Native' lists are kept in their Native format without any modifications.</li></ul> + <strong>When using 'Alias' rules, change (pfB_) to ( pfb_ ) in the beginning of rule description and Use the 'Exact' spelling of + the Alias (no trailing Whitespace) </strong> Custom 'Alias' rules with 'pfB_ xxx' description will be removed by package if + using Auto Rule Creation.<br /><br /><strong>Tip</strong>: You can create the Auto Rules and remove "<u>auto rule</u>" from the Rule + Descriptions, then disable Auto Rules. This method will 'KEEP' these rules from being 'Deleted' which will allow editing for a Custom + Alias Configuration<br />]]> + </description> + <fieldname>action</fieldname> + <type>select</type> + <options> + <option><name>Disabled</name><value>Disabled</value></option> + <option><name>Deny Inbound</name><value>Deny_Inbound</value></option> + <option><name>Deny Outbound</name><value>Deny_Outbound</value></option> + <option><name>Deny Both</name><value>Deny_Both</value></option> + <option><name>Permit Inbound</name><value>Permit_Inbound</value></option> + <option><name>Permit Outbound</name><value>Permit_Outbound</value></option> + <option><name>Permit Both</name><value>Permit_Both</value></option> + <option><name>Match Inbound</name><value>Match_Inbound</value></option> + <option><name>Match Outbound</name><value>Match_Outbound</value></option> + <option><name>Match Both</name><value>Match_Both</value></option> + <option><name>Alias Deny</name><value>Alias_Deny</value></option> + <option><name>Alias Permit</name><value>Alias_Permit</value></option> + <option><name>Alias Match</name><value>Alias_Match</value></option> + <option><name>Alias Native</name><value>Alias_Native</value></option> + </options> + </field> + <field> + <fielddescr>Update Frequency</fielddescr> + <fieldname>cron</fieldname> + <description><![CDATA[Default:<strong>Never</strong><br /> + Select how often List files will be downloaded]]> + </description> + <type>select</type> + <options> + <option><name>Never</name><value>Never</value></option> + <option><name>Every Hour</name><value>01hour</value></option> + <option><name>Every 2 Hours</name><value>02hours</value></option> + <option><name>Every 3 Hours</name><value>03hours</value></option> + <option><name>Every 4 Hours</name><value>04hours</value></option> + <option><name>Every 6 Hours</name><value>06hours</value></option> + <option><name>Every 8 Hours</name><value>08hours</value></option> + <option><name>Every 12 Hours</name><value>12hours</value></option> + <option><name>Once a day</name><value>EveryDay</value></option> + <option><name>Weekly</name><value>Weekly</value></option> + </options> + </field> + <field> + <fielddescr>Weekly (Day of Week)</fielddescr> + <fieldname>dow</fieldname> + <description><![CDATA[Default:<strong>1</strong><br /> + Select the 'Weekly' ( Day of the Week ) to Update <br /> + This is only required for the 'Weekly' Frequency Selection. The 24 Hour Download 'Time' will be used.]]> + </description> + <type>select</type> + <options> + <option><name>Monday</name><value>1</value></option> + <option><name>Tuesday</name><value>2</value></option> + <option><name>Wednesday</name><value>3</value></option> + <option><name>Thursday</name><value>4</value></option> + <option><name>Friday</name><value>5</value></option> + <option><name>Saturday</name><value>6</value></option> + <option><name>Sunday</name><value>7</value></option> + </options> + </field> + <field> + <fielddescr>Enable Logging</fielddescr> + <fieldname>aliaslog</fieldname> + <description><![CDATA[Default:<strong>Enable</strong><br /> + Select - Logging to Status: System Logs: FIREWALL ( Log )<br /> + This can be overriden by the 'Global Logging' Option in the General Tab.]]> + </description> + <type>select</type> + <options> + <option><name>Enable</name><value>enabled</value></option> + <option><name>Disable</name><value>disabled</value></option> + </options> + </field> + <field> + <name>IPv6 Custom list</name> + <type>listtopic</type> + </field> + <field> + <fielddescr>IPv6 Custom Address(es)</fielddescr> + <fieldname>custom</fieldname> + <description><![CDATA[Please limit the size of the Custom List as this is stored as 'Base64' format in the config.xml file.<br /> + Follow the syntax below:<br /><br /> + Network ranges: <strong> TBC </strong><br /> + IP Address: <strong> TBC </strong><br /> + CIDR: <strong> TBC </strong><br /><br /> + You may use "<strong>#</strong>" after any IP/CIDR/Range to add comments. # Safe IP Address]]> + </description> + <type>textarea</type> + <cols>50</cols> + <rows>10</rows> + <encoding>base64</encoding> + </field> + <field> + <fielddescr>Update Custom List</fielddescr> + <fieldname>custom_update</fieldname> + <description><![CDATA[Default:<strong>Disable</strong><br /> + Select - Enable Update if changes are made to this List. Cron will also resync this list at the next Scheduled Update.]]> + </description> + <type>select</type> + <options> + <option><name>Disable</name><value>disabled</value></option> + <option><name>Enable</name><value>enabled</value></option> + </options> + </field> + <field> + <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. Changes are Applied via CRON or + 'Force Update'</ul>]]></name> + <type>listtopic</type> + </field> + </fields> + <custom_php_install_command> + pfblockerng_php_install_command(); + </custom_php_install_command> + <custom_php_deinstall_command> + pfblockerng_php_deinstall_command(); + </custom_php_deinstall_command> + <custom_php_validation_command> + pfblockerng_validate_input($_POST, $input_errors); + </custom_php_validation_command> + <custom_php_resync_config_command> + global $pfb; + $pfb['save'] = TRUE; + sync_package_pfblockerng(); + </custom_php_resync_config_command> +</packagegui>
\ No newline at end of file diff --git a/config/pfblockerng/widget-pfblockerng.inc b/config/pfblockerng/widget-pfblockerng.inc new file mode 100644 index 00000000..1b3c7c2b --- /dev/null +++ b/config/pfblockerng/widget-pfblockerng.inc @@ -0,0 +1,7 @@ +<?php + +//set variables for custom title and link +$pfblockerng_title = "pfBlockerNG"; +$pfblockerng_title_link = "pfblockerng/pfblockerng_alerts.php"; + +?>
\ No newline at end of file diff --git a/config/squid3/34/check_ip.php b/config/squid3/34/check_ip.php index a3f07204..5865037b 100644 --- a/config/squid3/34/check_ip.php +++ b/config/squid3/34/check_ip.php @@ -3,7 +3,7 @@ /* $Id$ */ /* check_ip.php - Copyright (C) 2013-2014 Marcello Coutinho + Copyright (C) 2013-2015 Marcello Coutinho All rights reserved. Redistribution and use in source and binary forms, with or without @@ -27,6 +27,7 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +require_once("config.inc"); error_reporting(0); // stdin loop if (! defined(STDIN)) { @@ -39,40 +40,24 @@ while( !feof(STDIN)){ $line = trim(fgets(STDIN)); // %SRC -$pf_version=substr(trim(file_get_contents("/etc/version")),0,3); unset($cp_db); -if ($pf_version > 2.0){ - $dir="/var/db"; - $files=scandir($dir); - foreach ($files as $file){ - if (preg_match("/captive.*db/",$file)){ - $dbhandle = sqlite_open("$dir/$file", 0666, $error); - if ($dbhandle){ - $query = "select * from captiveportal"; - $result = sqlite_array_query($dbhandle, $query, SQLITE_ASSOC); - if ($result){ - foreach ($result as $rownum => $row){ - $cp_db[$rownum]=implode(",",$row); - } - sqlite_close($dbhandle); - } - } +$files=scandir($g['vardb_path']); +foreach ($files as $file){ + if (preg_match("/captive.*db/",$file)){ + $result=squid_cp_read_db("{$g['vardb_path']}/{$file}"); + foreach ($result as $rownum => $row){ + $cp_db[$rownum]=implode(",",$row); } - } + } } -else{ - $filename="/var/db/captiveportal.db"; - if (file_exists($filename)) - $cp_db=file($filename); -} $usuario=""; - // 1376630450,2,172.16.3.65,00:50:56:9c:00:c7,admin,e1779ea20d0a11c7,,,, + //1419045939,1419045939,2000,2000,192.168.10.11,192.168.10.11,08:00:27:5c:e1:ee,08:00:27:5c:e1:ee,marcello,marcello,605a1f46e2d64556,605a1f46e2d64556,,,,,,,,,,,first,first if (is_array($cp_db)){ foreach ($cp_db as $cpl){ $fields=explode(",",$cpl); - if ($fields[2] != "" && $fields[2]==$line) - $usuario=$fields[4]; + if ($fields[4] != "" && $fields[4]==$line) + $usuario=$fields[8]; } } if ($usuario !="") @@ -82,5 +67,22 @@ else{ fwrite (STDOUT, "{$resposta}\n"); unset($cp_db); } + +/* read captive portal DB into array */ +function squid_cp_read_db($file) { + $cpdb = array(); + $DB = new SQLite3($file); + if ($DB) { + $response = $DB->query("SELECT * FROM captiveportal"); + if ($response != FALSE) { + while ($row = $response->fetchArray()) + $cpdb[] = $row; + } + $DB->close(); + } + + return $cpdb; +} + ?> diff --git a/config/squid3/34/squid.inc b/config/squid3/34/squid.inc index a2917515..0e5a173c 100755 --- a/config/squid3/34/squid.inc +++ b/config/squid3/34/squid.inc @@ -1698,6 +1698,11 @@ function squid_resync_auth() { $conf .="http_access deny sglog\n"; } if ($auth_method == 'none' ) { + // SSL interception acl options part 2 without authentication + if ($settingsconfig['ssl_proxy'] == "on"){ + $conf .= "always_direct allow all\n"; + $conf .= "ssl_bump server-first all\n"; + } $conf .="# Setup allowed acls\n"; $allowed = array('allowed_subnets'); if ($settingsconfig['allow_interface'] == 'on') { diff --git a/config/suricata/suricata.xml b/config/suricata/suricata.xml index 3b3bf723..c510d72b 100644 --- a/config/suricata/suricata.xml +++ b/config/suricata/suricata.xml @@ -42,7 +42,7 @@ <description>Suricata IDS/IPS Package</description> <requirements>None</requirements> <name>suricata</name> - <version>2.0.4 pkg v2.1</version> + <version>2.0.4 pkg v2.1.3</version> <title>Services: Suricata IDS</title> <include_file>/usr/local/pkg/suricata/suricata.inc</include_file> <menu> diff --git a/config/suricata/suricata_etiqrisk_update.php b/config/suricata/suricata_etiqrisk_update.php index 6723ce99..70fbdb79 100644 --- a/config/suricata/suricata_etiqrisk_update.php +++ b/config/suricata/suricata_etiqrisk_update.php @@ -41,6 +41,7 @@ require_once("config.inc"); require_once("functions.inc"); require_once("/usr/local/pkg/suricata/suricata.inc"); +require("/usr/local/pkg/suricata/suricata_defs.inc"); /************************************************************************* * Hack for backwards compatibility with older 2.1.x pfSense versions * @@ -101,21 +102,22 @@ function suricata_check_iprep_md5($filename) { /* error occurred. */ /**********************************************************/ - global $et_iqrisk_url, $iqRisk_tmppath, $iprep_path; + global $iqRisk_tmppath, $iprep_path; $new_md5 = $old_md5 = ""; + $et_iqrisk_url = str_replace("_xxx_", $config['installedpackages']['suricata']['config'][0]['iqrisk_code'], ET_IQRISK_DNLD_URL); if (download_file("{$et_iqrisk_url}{$filename}.md5sum", "{$iqRisk_tmppath}{$filename}.md5") == true) { if (file_exists("{$iqRisk_tmppath}{$filename}.md5")) - $new_md5 = file_get_contents("{$iqRisk_tmppath}{$filename}.md5"); + $new_md5 = trim(file_get_contents("{$iqRisk_tmppath}{$filename}.md5")); if (file_exists("{$iprep_path}{$filename}.md5")) - $old_md5 = file_get_contents("{$iprep_path}{$filename}.md5"); + $old_md5 = trim(file_get_contents("{$iprep_path}{$filename}.md5")); if ($new_md5 != $old_md5) return TRUE; else log_error(gettext("[Suricata] IPREP file '{$filename}' is up to date.")); } else - log_error(gettext("[Suricata] An error occurred downloading {$filename}.md5sum for IPREP. Update of {$filename} file will be skipped.")); + log_error(gettext("[Suricata] An error occurred downloading {$et_iqrisk_url}{$filename}.md5sum for IPREP. Update of {$filename} file will be skipped.")); return FALSE; } @@ -128,6 +130,9 @@ $iprep_path = SURICATA_IPREP_PATH; $iqRisk_tmppath = "{$g['tmp_path']}/IQRisk/"; $success = FALSE; +if (!is_array($config['installedpackages']['suricata']['config'][0])) + $config['installedpackages']['suricata']['config'][0] = array(); + // If auto-updates of ET IQRisk are disabled, then exit if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == "off") return(0); @@ -156,8 +161,8 @@ if (suricata_check_iprep_md5("categories.txt")) { // If the files downloaded successfully, unpack them and store // the list files in the SURICATA_IPREP_PATH directory. if (file_exists("{$iqRisk_tmppath}categories.txt") && file_exists("{$iqRisk_tmppath}categories.txt.md5")) { - $new_md5 = file_get_contents("{$iqRisk_tmppath}categories.txt.md5"); - if ($new_md5 == trim(md5_file("{$iqRisk_tmppath}categories.txt"))) { + $new_md5 = trim(file_get_contents("{$iqRisk_tmppath}categories.txt.md5")); + if ($new_md5 == md5_file("{$iqRisk_tmppath}categories.txt")) { @rename("{$iqRisk_tmppath}categories.txt", "{$iprep_path}categories.txt"); @rename("{$iqRisk_tmppath}categories.txt.md5", "{$iprep_path}categories.txt.md5"); $success = TRUE; @@ -179,8 +184,8 @@ if (suricata_check_iprep_md5("iprepdata.txt.gz")) { // If the files downloaded successfully, unpack them and store // the list files in the SURICATA_IPREP_PATH directory. if (file_exists("{$iqRisk_tmppath}iprepdata.txt.gz") && file_exists("{$iqRisk_tmppath}iprepdata.txt.gz.md5")) { - $new_md5 = file_get_contents("{$iqRisk_tmppath}iprepdata.txt.gz.md5"); - if ($new_md5 == trim(md5_file("{$iqRisk_tmppath}iprepdata.txt.gz"))) { + $new_md5 = trim(file_get_contents("{$iqRisk_tmppath}iprepdata.txt.gz.md5")); + if ($new_md5 == md5_file("{$iqRisk_tmppath}iprepdata.txt.gz")) { mwexec("/usr/bin/gunzip -f {$iqRisk_tmppath}iprepdata.txt.gz"); @rename("{$iqRisk_tmppath}iprepdata.txt", "{$iprep_path}iprepdata.txt"); @rename("{$iqRisk_tmppath}iprepdata.txt.gz.md5", "{$iprep_path}iprepdata.txt.gz.md5"); diff --git a/config/suricata/suricata_ip_list_mgmt.php b/config/suricata/suricata_ip_list_mgmt.php index ee3a7009..37decaad 100644 --- a/config/suricata/suricata_ip_list_mgmt.php +++ b/config/suricata/suricata_ip_list_mgmt.php @@ -101,11 +101,14 @@ if ($_POST['save']) { /* Toggle cron task for ET IQRisk updates if setting was changed */ if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'on' && !suricata_cron_job_exists("/usr/local/pkg/suricata/suricata_etiqrisk_update.php")) { - include("/usr/local/pkg/suricata/suricata_etiqrisk_update.php"); - install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_etiqrisk_update.php", TRUE, 0, 0, "*", "*", "*", "root"); + install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_etiqrisk_update.php", TRUE, 0, "*/6", "*", "*", "*", "root"); } elseif ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'off' && suricata_cron_job_exists("/usr/local/pkg/suricata/suricata_etiqrisk_update.php")) install_cron_job("/usr/local/pkg/suricata/suricata_etiqrisk_update.php", FALSE); + + /* Peform a manual ET IQRisk file check/download */ + if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'on') + include("/usr/local/pkg/suricata/suricata_etiqrisk_update.php"); } } @@ -287,7 +290,9 @@ if ($savemsg) height="17" border="0" title="<?php echo gettext('Import/Upload an IP List');?>"/></th> </tr> </thead> - <?php foreach ($ipfiles as $file): ?> + <?php foreach ($ipfiles as $file): + if (substr(strrchr($file, "."), 1) == "md5") + continue; ?> <tr> <td class="listr"><?php echo gettext($file); ?></td> <td class="listr"><?=date('M-d Y g:i a', filemtime("{$iprep_path}{$file}")); ?></td> diff --git a/config/suricata/suricata_post_install.php b/config/suricata/suricata_post_install.php index f4a66b0b..070cf095 100644 --- a/config/suricata/suricata_post_install.php +++ b/config/suricata/suricata_post_install.php @@ -112,6 +112,10 @@ safe_mkdir(SURICATALOGDIR); safe_mkdir(SURICATA_SID_MODS_PATH); safe_mkdir(SURICATA_IPREP_PATH); +// Make sure config variable is an array +if (!is_array($config['installedpackages']['suricata']['config'][0])) + $config['installedpackages']['suricata']['config'][0] = array(); + // Download the latest GeoIP DB updates and create cron task if the feature is not disabled if ($config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] != 'off') { log_error(gettext("[Suricata] Installing free GeoIP country database files...")); @@ -123,7 +127,7 @@ if ($config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] != if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'on') { log_error(gettext("[Suricata] Installing Emerging Threats IQRisk IP List...")); include("/usr/local/pkg/suricata/suricata_etiqrisk_update.php"); - install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_etiqrisk_update.php", TRUE, 0, 0, "*", "*", "*", "root"); + install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_etiqrisk_update.php", TRUE, 0, "*/6", "*", "*", "*", "root"); } // remake saved settings if previously flagged @@ -254,8 +258,8 @@ if (empty($config['installedpackages']['suricata']['config'][0]['forcekeepsettin conf_mount_ro(); // Update Suricata package version in configuration -$config['installedpackages']['suricata']['config'][0]['suricata_config_ver'] = "2.1"; -write_config("Suricata pkg v2.1: post-install configuration saved."); +$config['installedpackages']['suricata']['config'][0]['suricata_config_ver'] = "2.1.2"; +write_config("Suricata pkg v2.1.2: post-install configuration saved."); // Done with post-install, so clear flag unset($g['suricata_postinstall']); diff --git a/pkg_config.10.xml b/pkg_config.10.xml index 17d8f1f4..72bc03c5 100644 --- a/pkg_config.10.xml +++ b/pkg_config.10.xml @@ -53,7 +53,7 @@ <descr><![CDATA[The most widely used name server software]]></descr> <website>http://www.isc.org/downloads/BIND/</website> <category>Services</category> - <version>9.9.6_1 pkg v 0.3.5</version> + <version>9.9.6_1 pkg v 0.3.6</version> <status>RC</status> <required_version>2.2</required_version> <config_file>https://packages.pfsense.org/packages/config/bind/bind.xml</config_file> @@ -138,6 +138,7 @@ <required_version>3.0</required_version> <maintainer>BBCan177@gmail.com</maintainer> <configurationfile>pfblockerng.xml</configurationfile> + <depends_on_package_pbi>pfblockerng-1.6.3_1-##ARCH##.pbi</depends_on_package_pbi> <build_pbi> <port>net/GeoIP</port> <ports_after>net-mgmt/grepcidr</ports_after> @@ -700,7 +701,7 @@ <descr>Network UPS Tools</descr> <website>http://www.networkupstools.org/</website> <category>Network Management</category> - <version>2.7.2_6 pkg 2.0.3</version> + <version>2.7.2_6 pkg 2.0.4</version> <status>BETA</status> <required_version>2.2</required_version> <maintainer>rswagoner@gmail.com</maintainer> @@ -904,11 +905,11 @@ <internal_name>squid</internal_name> <descr><![CDATA[High performance web proxy cache.<br /> It combines squid as a proxy server with its capabilities of acting as a HTTP / HTTPS reverse proxy.<br /> - It includes an Exchange-Web-Access (OWA) Assistant.]]></descr> + It includes an Exchange-Web-Access (OWA) Assistant, ssl filtering and antivirus integration via i-cap]]></descr> <pkginfolink>https://forum.pfsense.org/index.php/topic,48347.0.html</pkginfolink> <website>http://www.squid-cache.org/</website> <category>Network</category> - <version>3.4.10_2 pkg 0.2</version> + <version>3.4.10_2 pkg 0.2.1</version> <status>beta</status> <required_version>2.2</required_version> <maintainer>marcellocoutinho@gmail.com fernando@netfilter.com.br seth.mos@dds.nl mfuchs77@googlemail.com jimp@pfsense.org</maintainer> @@ -917,7 +918,7 @@ <port>www/squid</port> <ports_after>www/squid_radius_auth security/clamav www/squidclamav security/ca_root_nss www/c-icap-modules</ports_after> </build_pbi> - <build_options>c-icap_UNSET_FORCE=IPV6;squid_UNSET_FORCE=AUTH_SMB AUTH_SQL DNS_HELPER FS_COSS ESI SNMP ECAP STACKTRACES STRICT_HTTP TP_IPF TP_IPFW VIA_DB DEBUG DOCS EXAMPLES AUTH_SASL;squid_SET_FORCE=ARP_ACL AUTH_KERB AUTH_LDAP AUTH_NIS CACHE_DIGESTS DELAY_POOLS FOLLOW_XFF TP_PF WCCP WCCPV2 FS_AUFS HTCP ICAP ICMP IDENT IPV6 KQUEUE LARGEFILE SSL SSL_CRTD</build_options> + <build_options>squid_UNSET_FORCE=AUTH_SASL AUTH_SMB AUTH_SQL DEBUG DNS_HELPER ESI FS_ROCK TP_IPF NETTLE STACKTRACES VIA_DB DOCS EXAMPLES;squid_SET_FORCE=ARP_ACL AUTH_KERB AUTH_LDAP AUTH_NIS DELAY_POOLS ECAP FOLLOW_XFF FS_AUFS FS_DISKD HTCP ICAP ICMP IDENT IPV6 KQUEUE LARGEFILE SNMP SSL SSL_CRTD LAX_HTTP TP_IPFW TP_PF WCCP WCCPV2 CACHE_DIGESTS</build_options> <config_file>https://packages.pfsense.org/packages/config/squid3/34/squid.xml</config_file> <configurationfile>squid.xml</configurationfile> <depends_on_package_pbi>squid-3.4.10_2-##ARCH##.pbi</depends_on_package_pbi> @@ -1059,7 +1060,7 @@ <ports_after>security/clamav</ports_after> </build_pbi> <build_options>CLAMAVUSER=havp;CLAMAVGROUP=havp</build_options> - <version>0.91_3 pkg v1.02</version> + <version>0.91_3 pkg v1.04</version> <status>BETA</status> <required_version>2.2</required_version> <config_file>https://packages.pfsense.org/packages/config/havp/havp.xml</config_file> @@ -1418,7 +1419,7 @@ <descr>Set of programs for controlling APC UPS.</descr> <category>Services</category> <config_file>https://packages.pfsense.org/packages/config/apcupsd/apcupsd.xml</config_file> - <version>apcupsd-3.14.12_1 pkg v0.3.1</version> + <version>apcupsd-3.14.12_1 pkg v0.3.2</version> <status>BETA</status> <required_version>2.2</required_version> <configurationfile>apcupsd.xml</configurationfile> @@ -1451,7 +1452,7 @@ <website>http://suricata-ids.org/</website> <descr><![CDATA[High Performance Network IDS, IPS and Security Monitoring engine by OISF.]]></descr> <category>Security</category> - <version>2.0.4 pkg v2.1.1</version> + <version>2.0.4 pkg v2.1.3</version> <status>Stable</status> <required_version>2.2</required_version> <config_file>https://packages.pfsense.org/packages/config/suricata/suricata.xml</config_file> diff --git a/pkg_config.8.xml b/pkg_config.8.xml index 921d5db9..6c858027 100644 --- a/pkg_config.8.xml +++ b/pkg_config.8.xml @@ -53,7 +53,7 @@ <descr><![CDATA[The most widely used name server software]]></descr> <website>http://www.isc.org/downloads/BIND/</website> <category>Services</category> - <version>9.9.5P1_5 pkg v 0.3.5</version> + <version>9.9.5P1_5 pkg v 0.3.6</version> <status>RC</status> <required_version>2.1</required_version> <config_file>https://packages.pfsense.org/packages/config/bind/bind.xml</config_file> @@ -913,7 +913,7 @@ <descr>Network UPS Tools</descr> <website>http://www.networkupstools.org/</website> <category>Network Management</category> - <version>2.6.5_1 pkg 2.0.3</version> + <version>2.6.5_1 pkg 2.0.4</version> <status>BETA</status> <required_version>2.0</required_version> <maintainer>rswagoner@gmail.com</maintainer> @@ -1394,7 +1394,7 @@ <depends_on_package_pbi>havp-0.91_1-i386.pbi</depends_on_package_pbi> <build_port_path>/usr/ports/www/havp</build_port_path> <build_options>CLAMAVUSER=havp;CLAMAVGROUP=havp</build_options> - <version>0.91_1 pkg v1.02</version> + <version>0.91_1 pkg v1.04</version> <status>BETA</status> <required_version>1.2.2</required_version> <config_file>https://packages.pfsense.org/packages/config/havp/havp.xml</config_file> @@ -1861,7 +1861,7 @@ <descr>Set of programs for controlling APC UPS.</descr> <category>Services</category> <config_file>https://packages.pfsense.org/packages/config/apcupsd/apcupsd.xml</config_file> - <version>apcupsd-3.14.10_1 pkg v0.3.1</version> + <version>apcupsd-3.14.10_1 pkg v0.3.2</version> <status>BETA</status> <required_version>2.0</required_version> <configurationfile>apcupsd.xml</configurationfile> @@ -1896,7 +1896,7 @@ <website>http://suricata-ids.org/</website> <descr><![CDATA[High Performance Network IDS, IPS and Security Monitoring engine by OISF.]]></descr> <category>Security</category> - <version>2.0.4 pkg v2.1.1</version> + <version>2.0.4 pkg v2.1.3</version> <status>Stable</status> <required_version>2.1</required_version> <config_file>https://packages.pfsense.org/packages/config/suricata/suricata.xml</config_file> diff --git a/pkg_config.8.xml.amd64 b/pkg_config.8.xml.amd64 index d3850f89..d3705b7c 100644 --- a/pkg_config.8.xml.amd64 +++ b/pkg_config.8.xml.amd64 @@ -53,7 +53,7 @@ <descr><![CDATA[The most widely used name server software]]></descr> <website>http://www.isc.org/downloads/BIND/</website> <category>Services</category> - <version>9.9.5P1_5 pkg v 0.3.5</version> + <version>9.9.5P1_5 pkg v 0.3.6</version> <status>RC</status> <required_version>2.1</required_version> <config_file>https://packages.pfsense.org/packages/config/bind/bind.xml</config_file> @@ -900,7 +900,7 @@ <descr>Network UPS Tools</descr> <website>http://www.networkupstools.org/</website> <category>Network Management</category> - <version>2.6.5_1 pkg 2.0.3</version> + <version>2.6.5_1 pkg 2.0.4</version> <status>BETA</status> <required_version>2.0</required_version> <maintainer>rswagoner@gmail.com</maintainer> @@ -1381,7 +1381,7 @@ <depends_on_package_pbi>havp-0.91_1-amd64.pbi</depends_on_package_pbi> <build_port_path>/usr/ports/www/havp</build_port_path> <build_options>CLAMAVUSER=havp;CLAMAVGROUP=havp</build_options> - <version>0.91_1 pkg v1.02</version> + <version>0.91_1 pkg v1.04</version> <status>BETA</status> <required_version>1.2.2</required_version> <config_file>https://packages.pfsense.org/packages/config/havp/havp.xml</config_file> @@ -1848,7 +1848,7 @@ <descr>Set of programs for controlling APC UPS.</descr> <category>Services</category> <config_file>https://packages.pfsense.org/packages/config/apcupsd/apcupsd.xml</config_file> - <version>apcupsd-3.14.10_1 pkg v0.3.1</version> + <version>apcupsd-3.14.10_1 pkg v0.3.2</version> <status>BETA</status> <required_version>2.0</required_version> <configurationfile>apcupsd.xml</configurationfile> @@ -1883,7 +1883,7 @@ <website>http://suricata-ids.org/</website> <descr><![CDATA[High Performance Network IDS, IPS and Security Monitoring engine by OISF.]]></descr> <category>Security</category> - <version>2.0.4 pkg v2.1.1</version> + <version>2.0.4 pkg v2.1.3</version> <status>Stable</status> <required_version>2.1</required_version> <config_file>https://packages.pfsense.org/packages/config/suricata/suricata.xml</config_file> |