aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
Diffstat (limited to 'config')
-rw-r--r--config/pfblockerng/geoipupdate.sh171
-rw-r--r--config/pfblockerng/index.php50
-rw-r--r--config/pfblockerng/pfblockerng.inc5654
-rw-r--r--config/pfblockerng/pfblockerng.php1011
-rw-r--r--config/pfblockerng/pfblockerng.priv.inc9
-rw-r--r--config/pfblockerng/pfblockerng.sh1610
-rw-r--r--config/pfblockerng/pfblockerng.widget.php392
-rw-r--r--config/pfblockerng/pfblockerng.xml217
-rw-r--r--config/pfblockerng/pfblockerng_alerts.php1317
-rw-r--r--config/pfblockerng/pfblockerng_alerts_ar.php52
-rw-r--r--config/pfblockerng/pfblockerng_diag_dns.php320
-rw-r--r--config/pfblockerng/pfblockerng_dnsbl.xml597
-rw-r--r--config/pfblockerng/pfblockerng_dnsbl_easylist.xml284
-rw-r--r--config/pfblockerng/pfblockerng_dnsbl_lists.xml333
-rw-r--r--config/pfblockerng/pfblockerng_extra.inc131
-rw-r--r--config/pfblockerng/pfblockerng_install.inc181
-rw-r--r--config/pfblockerng/pfblockerng_log.php119
-rw-r--r--config/pfblockerng/pfblockerng_sync.xml77
-rw-r--r--config/pfblockerng/pfblockerng_threats.php142
-rw-r--r--config/pfblockerng/pfblockerng_top20.xml96
-rw-r--r--config/pfblockerng/pfblockerng_update.php246
-rw-r--r--config/pfblockerng/pfblockerng_v4lists.xml251
-rw-r--r--config/pfblockerng/pfblockerng_v6lists.xml267
23 files changed, 8422 insertions, 5105 deletions
diff --git a/config/pfblockerng/geoipupdate.sh b/config/pfblockerng/geoipupdate.sh
deleted file mode 100644
index 39c08f70..00000000
--- a/config/pfblockerng/geoipupdate.sh
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/bin/sh
-#
-# pfBlockerNG MaxMind GeoLite GeoIP Updater Script - By BBcan177@gmail.com
-# Copyright (C) 2015 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.
-
-pfs_version=$(cat /etc/version | cut -c 1-3)
-
-# Application Locations
-pathfetch=/usr/bin/fetch
-pathtar=/usr/bin/tar
-pathgunzip=/usr/bin/gunzip
-
-# Folder Locations
-pathdb=/var/db/pfblockerng
-pathlog=/var/log/pfblockerng
-if [ "${pfs_version}" = "2.2" ]; then
- mtype=$(/usr/bin/uname -m)
- pathshare=/usr/pbi/pfblockerng-$mtype/share/GeoIP
-else
- pathshare=/usr/local/share/GeoIP
-fi
-
-# File Locations
-errorlog=$pathlog/geoip.log
-geoipdat=/GeoIP.dat
-geoipdatv6=/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 $pathshare$geoipdat.gz -T 20 $URL
-if [ "$?" -eq "0" ]; then
- $pathgunzip -f $pathshare$geoipdat.gz
- echo; echo " ( MaxMind IPv4 GeoIP.dat has been updated )"; echo
- echo "Current Date/Timestamp:"
- /bin/ls -alh $pathshare$geoipdat
- 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 $pathshare$geoipdatv6.gz -T 20 $URL
-if [ "$?" -eq "0" ]; then
- $pathgunzip -f $pathshare$geoipdatv6.gz
- echo; echo " ( MaxMind IPv6 GeoIPv6.dat has been updated )"; echo
- echo "Current Date/Timestamp:"
- /bin/ls -alh $pathshare$geoipdatv6
- 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
diff --git a/config/pfblockerng/index.php b/config/pfblockerng/index.php
new file mode 100644
index 00000000..804932d2
--- /dev/null
+++ b/config/pfblockerng/index.php
@@ -0,0 +1,50 @@
+<?php
+/*
+ index.php
+
+ pfBlockerNG (DNSBL)
+ Copyright (c) 2015 BBcan177@gmail.com
+ All rights reserved.
+*/
+header("Cache-Control: private, no-store, no-cache, must-revalidate, max-age=0");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+header("Expires: Sat, 26 Jul 2014 05:00:00 GMT");
+header("Content-Type: image/gif");
+echo base64_decode('R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==');
+
+// Record DNSBL HTTP Alert to logfile
+$datereq = date('M d H:i:s', $_SERVER['REQUEST_TIME']);
+$req_agent = str_replace(',', '', "{$_SERVER['HTTP_REFERER']} | {$_SERVER['REQUEST_URI']} | {$_SERVER['HTTP_USER_AGENT']}");
+$log = htmlspecialchars("DNSBL Reject,{$datereq},{$_SERVER['HTTP_HOST']},{$_SERVER['REMOTE_ADDR']},{$req_agent}\n");
+if (!empty($log)) {
+ @file_put_contents('/var/log/pfblockerng/dnsbl.log', "{$log}", FILE_APPEND | LOCK_EX);
+}
+
+// Query DNSBL Alias for Domain List.
+$query = str_replace('.', '\.', htmlspecialchars($_SERVER['HTTP_HOST']));
+exec("/usr/bin/grep -l ' \"{$query} 60 IN A' /var/db/pfblockerng/dnsblalias/*", $match);
+$pfb_query = strstr($match[0], 'DNSBL', FALSE);
+
+if (!empty($pfb_query)) {
+ // Increment DNSBL Alias Counter
+ $dnsbl_info = '/var/db/pfblockerng/dnsbl_info';
+ if (($handle = fopen("{$dnsbl_info}", 'r')) !== FALSE) {
+ flock($handle, LOCK_EX);
+ $pfb_output = fopen("{$dnsbl_info}.bk", 'w');
+ flock($pfb_output, LOCK_EX);
+
+ // Find line with corresponding DNSBL Aliasname
+ while (($line = fgetcsv($handle)) !== FALSE) {
+ if ($line[0] == $pfb_query) {
+ $line[3] += 1;
+ }
+ fputcsv($pfb_output, $line);
+ }
+
+ fclose($pfb_output);
+ fclose($handle);
+ @rename("{$dnsbl_info}.bk", "{$dnsbl_info}");
+ }
+}
+?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc
index 646e54ca..f1242ca3 100644
--- a/config/pfblockerng/pfblockerng.inc
+++ b/config/pfblockerng/pfblockerng.inc
@@ -3,13 +3,11 @@
pfBlockerNG.inc
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 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
+ Copyright (c) 2011-2012 Marcello Coutinho
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -37,209 +35,343 @@
*/
-//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');
+require_once('service-utils.inc');
+require_once('/usr/local/pkg/pfblockerng/pfblockerng_extra.inc'); // 'include functions' not yet merged into pfSense
+
+global $g, $config, $pfb;
+
+$pfs_version = substr(trim(file_get_contents('/etc/version')), 0, 3);
+if ($pfs_version == '2.2') {
+ $pfb['prefix'] = '/usr/pbi/pfblockerng-' . php_uname('m');
+} else {
+ $pfb['prefix'] = '/usr/local';
+}
+
+// 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['nativedir'] = "{$pfb['dbdir']}/native";
+$pfb['denydir'] = "{$pfb['dbdir']}/deny";
+$pfb['matchdir'] = "{$pfb['dbdir']}/match";
+$pfb['permitdir'] = "{$pfb['dbdir']}/permit";
+$pfb['origdir'] = "{$pfb['dbdir']}/original";
+$pfb['dnsdir'] = "{$pfb['dbdir']}/dnsbl";
+$pfb['dnsorigdir'] = "{$pfb['dbdir']}/dnsblorig";
+$pfb['dnsalias'] = "{$pfb['dbdir']}/dnsblalias";
+$pfb['geoipshare'] = "{$pfb['prefix']}/share/GeoIP";
+$pfb['ccdir'] = "{$pfb['prefix']}/share/GeoIP/cc";
+
+// Application Paths
+$pfb['grep'] = '/usr/bin/grep';
+$pfb['awk'] = '/usr/bin/awk';
+$pfb['cut'] = '/usr/bin/cut';
+$pfb['sed'] = '/usr/bin/sed';
+$pfb['cat'] = '/bin/cat';
+$pfb['ls'] = '/bin/ls';
+$pfb['pfctl'] = '/sbin/pfctl';
+
+// Folder Array
+$pfb['folder_array'] = array( "{$pfb['dbdir']}", "{$pfb['logdir']}", "{$pfb['ccdir']}", "{$pfb['origdir']}", "{$pfb['nativedir']}",
+ "{$pfb['denydir']}", "{$pfb['matchdir']}","{$pfb['permitdir']}", "{$pfb['aliasdir']}",
+ "{$pfb['dnsdir']}", "{$pfb['dnsorigdir']}", "{$pfb['dnsalias']}");
+// Files
+$pfb['errlog'] = "{$pfb['logdir']}/error.log";
+$pfb['extraslog'] = "{$pfb['logdir']}/extras.log";
+$pfb['log'] = "{$pfb['logdir']}/pfblockerng.log";
+$pfb['dnslog'] = "{$pfb['logdir']}/dnsbl.log";
+$pfb['dnserrlog'] = "{$pfb['logdir']}/dnsbl_error.log";
+$pfb['master'] = "{$pfb['dbdir']}/masterfile";
+$pfb['supptxt'] = "{$pfb['dbdir']}/pfbsuppression.txt";
+$pfb['dnsbl_info'] = "{$pfb['dbdir']}/dnsbl_info";
+$pfb['dnsbl_conf'] = '/var/unbound/pfb_dnsbl_lighty.conf';
+$pfb['dnsbl_cert'] = '/var/unbound/dnsbl_cert.pem';
+$pfb['script'] = '/usr/local/pkg/pfblockerng/pfblockerng.sh';
+$pfb['aliasarchive'] = "{$pfb['prefix']}/etc/aliastables.tar.bz2";
+
+// Unbound files and folders
+$pfb['dnsbl_file'] = '/var/unbound/pfb_dnsbl'; // Filename Extension not referenced
+$pfb['dnsbldir'] = '/var/unbound';
+
+// Array definitions
+$pfb['continents'] = array ( 'Africa' => 'pfB_Africa',
+ 'Antartica' => 'pfB_Antartica',
+ 'Asia' => 'pfB_Asia',
+ 'Europe' => 'pfB_Europe',
+ 'North America' => 'pfB_NAmerica',
+ 'Oceania' => 'pfB_Oceania',
+ 'South America' => 'pfB_SAmerica',
+ 'Top Spammers' => 'pfB_Top',
+ 'Proxy and Satellite' => 'pfB_PS'
+ );
-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");
+// Base rule array
+$pfb['base_rule_reg'] = array('ipprotocol' => 'inet');
-// [ $pfb ] pfBlockerNG Global Array for Paths and Variables. This needs to be called to get the Updated Settings.
+// Floating rules, base rule array
+$pfb['base_rule_float'] = array('quick' => 'yes', 'floating' => 'yes', 'ipprotocol' => 'inet');
+
+// Define Arrays for managing the mastefile
+foreach (array('existing', 'actual') as $pftype) {
+ $pfb[$pftype]['match'] = array('type' => 'match', 'folder' => "{$pfb['matchdir']}");
+ $pfb[$pftype]['permit'] = array('type' => 'permit', 'folder' => "{$pfb['permitdir']}");
+ $pfb[$pftype]['deny'] = array('type' => 'deny', 'folder' => "{$pfb['denydir']}");
+ $pfb[$pftype]['native'] = array('type' => 'native', 'folder' => "{$pfb['nativedir']}");
+ $pfb[$pftype]['dnsbl'] = array('type' => 'dnsbl', 'folder' => "{$pfb['dnsdir']}");
+}
+
+// Default cURL options
+$pfb['curl_defaults'] = array( CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 Chrome/43.0.2357.65 Safari/537.36',
+ CURLOPT_SSL_CIPHER_LIST => 'TLSv1.2, TLSv1',
+ CURLOPT_FOLLOWLOCATION => true,
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLOPT_SSL_VERIFYHOST => true,
+ CURLOPT_FRESH_CONNECT => true,
+ CURLOPT_FILETIME => true,
+ CURLOPT_CONNECTTIMEOUT => 15,
+ );
+
+$pfb['rfc7231'] = array(100 => '100 Continue', 101 => '101 Switching Protocols', 102 => '102 Processing',
+
+ 200 => '200 OK', 201 => '201 Created', 202 => '202 Accepted',
+ 203 => '203 Non-Authoritative Info', 204 => '204 No Content', 205 => '205 Reset Content',
+ 206 => '206 Partial Content', 207 => '207 Multi-Status', 208 => '208 Already Reported',
+ 226 => '226 IM Used',
+
+ 300 => '300 Multiple Choices', 301 => '301 Moved Permanently', 302 => '302 Found',
+ 303 => '303 See Other', 304 => '304 Not Modified', 305 => '305 Use Proxy',
+ 306 => '306 Switch Proxy', 307 => '307 Temporary Redirect', 308 => '308 Permanent Redirect',
+
+ 400 => '400 Bad Request', 401 => '401 Unauthorized', 402 => '402 Payment Required',
+ 403 => '403 Forbidden', 404 => '404 Not Found', 405 => '405 Method Not Allowed',
+ 406 => '406 Not Acceptable', 407 => '407 Proxy Authentication Required', 408 => '408 Request Timeout',
+ 409 => '409 Conflict', 410 => '410 Gone', 411 => '411 Length Required',
+ 412 => '412 Precondition Failed', 413 => '413 Request Entity Too Large', 414 => '414 Request-URI Too Long',
+ 415 => '415 Unsupported Media Type', 416 => '416 Requested Range Not Satisfiable', 417 => '417 Expectation Failed',
+ 418 => '418 Im a teapot', 419 => '419 Authentication Timeout', 420 => '420 Method Failure',
+ 421 => '421 Misdirected Request', 422 => '422 Unprocessable Entity', 423 => '423 Locked',
+ 424 => '424 Failed Dependency', 426 => '426 Upgrade Required', 428 => '428 Precondition Required',
+ 429 => '429 Too Many Requests', 431 => '431 Request Header Fields Large', 440 => '440 Login Timeout',
+ 444 => '444 No Response', 449 => '449 Retry With', 450 => '450 Blocked Windows Parental Controls',
+ 451 => '451 Unavailable Legal Reasons', 494 => '494 Request Header too Large', 495 => '495 Cert Error',
+ 496 => '496 No Cert', 497 => '497 HTTP to HTTPS', 498 => '498 Token expired/invalid',
+ 499 => '499 Client Closed Request',
+
+ 500 => '500 Internal Server Error', 501 => '501 Not Implemented', 502 => '502 Bad Gateway',
+ 503 => '503 Service Unavailable', 504 => '504 Gateway Timeout', 505 => '505 HTTP Version Not Supported',
+ 506 => '506 Variant Also Negotiates', 507 => '507 Insufficient Storage', 508 => '508 Loop Detected',
+ 509 => '509 Bandwidth Limit Exceeded', 510 => '510 Not Extended', 511 => '511 Network Authentication Required',
+ 598 => '598 Network read timeout error',599 => '599 Network connect timeout error'
+ );
+
+
+// [ $pfb ] pfBlockerNG global array. This needs to be called to get the updated settings.
function pfb_global() {
- global $g,$config,$pfb;
+ global $g, $config, $pfb;
- $pfs_version = substr(trim(file_get_contents("/etc/version")),0,3);
+ // Create folders if not exist.
+ foreach ($pfb['folder_array'] as $folder) {
+ safe_mkdir("{$folder}", 0755);
+ }
- if ($pfs_version == "2.2") {
- $prefix = "/usr/pbi/pfblockerng-" . php_uname("m");
- } else {
- $prefix = "/usr/local";
- }
-
- // 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['nativedir'] = "{$pfb['dbdir']}/native";
- $pfb['denydir'] = "{$pfb['dbdir']}/deny";
- $pfb['matchdir'] = "{$pfb['dbdir']}/match";
- $pfb['permitdir'] = "{$pfb['dbdir']}/permit";
- $pfb['origdir'] = "{$pfb['dbdir']}/original";
- $pfb['ccdir'] = "{$prefix}/share/GeoIP";
-
- // Create Folders if not Exist.
- $folder_array = array ("{$pfb['dbdir']}","{$pfb['logdir']}","{$pfb['ccdir']}","{$pfb['origdir']}","{$pfb['nativedir']}","{$pfb['denydir']}","{$pfb['matchdir']}","{$pfb['permitdir']}","{$pfb['aliasdir']}");
- 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';
- $pfb['aliasarchive'] = "{$prefix}/etc/aliastables.tar.bz2";
-
- // General Variables
+ // General variables
$pfb['config'] = $config['installedpackages']['pfblockerng']['config'][0];
+ $pfb['dnsblconfig'] = $config['installedpackages']['pfblockerngdnsblsettings']['config'][0];
+
+ $pfb['enable'] = $pfb['config']['enable_cb']; // Enable/Disable of pfBlockerNG
+ $pfb['keep'] = $pfb['config']['pfb_keep']; // Keep blocklists on pfBlockerNG Disable
+ $pfb['supp'] = $pfb['config']['suppression']; // Enable Suppression
+ $pfb['logmax'] = $pfb['config']['log_maxlines']; // Max lines in pfblockerng.log file
+ $pfb['cc'] = $pfb['config']['database_cc']; // Disable Country database CRON updates
+ $pfb['min'] = $pfb['config']['pfb_min']; // User defined CRON start minute
+ $pfb['hour'] = $pfb['config']['pfb_hour']; // Start hour of the scheduler
+ $pfb['interval'] = $pfb['config']['pfb_interval']; // Hour cycle for scheduler
+ $pfb['24hour'] = $pfb['config']['pfb_dailystart']; // Start hour of the 'Once a day' schedule
+ $pfb['iplocal'] = $config['interfaces']['lan']['ipaddr']; // Lan IP address
+ $pfb['dnsbl'] = $pfb['dnsblconfig']['pfb_dnsbl']; // Enabled state of DNSBL
+ $pfb['dnsbl_port'] = $pfb['dnsblconfig']['pfb_dnsport'] ?: ''; // Lighttpd web server http port setting
+ $pfb['dnsbl_port_ssl'] = $pfb['dnsblconfig']['pfb_dnsport_ssl']?: ''; // Lighttpd web server https port setting
+
+ // Restore previous download on failure (default to 'on')
+ $pfb['restore'] = $pfb['config']['restore_feed'] != '' ? $pfb['config']['restore_feed'] : 'on';
+ // Max daily download failure threshold (default to '0')
+ $pfb['skipfeed'] = $pfb['config']['skipfeed'] != '' ? $pfb['config']['skipfeed'] : 0;
+
+ if (isset($config['unbound']['enable'])) {
+ $pfb['unbound_state'] = 'on';
+ } else {
+ $pfb['unbound_state'] = '';
+ }
- // 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'];
- // Lan IP Address
- $pfb['iplocal'] = $config['interfaces']['lan']['ipaddr'];
- // Disable Country Database CRON Updates
- $pfb['cc'] = $pfb['config']['database_cc'];
-
- // User Defined CRON Start Minute
- $pfb['min'] = $pfb['config']['pfb_min'];
- // Start hour of the Scheduler
- $pfb['hour'] = $pfb['config']['pfb_hour'];
- // Hour cycle for Scheduler
- $pfb['interval'] = $pfb['config']['pfb_interval'];
- // Start hour of the 'Once a day' Schedule
- $pfb['24hour'] = $pfb['config']['pfb_dailystart'];
-
- // Set pfBlockerNG to Disabled on 'Re-Install'
+ // cURL - system proxy server setttings, if configured
+ if (!empty($config['system'][proxyurl])) {
+ $pfb['curl_defaults'][CURLOPT_PROXY] = $config['system']['proxyurl'];
+ if (!empty($config['system'][proxyport])) {
+ $pfb['curl_defaults'][CURLOPT_PROXYPORT] = $config['system']['proxyport'];
+ }
+ if (!empty($config['system']['proxyuser']) && !empty($config['system']['proxypass'])) {
+ $pfb['curl_defaults'][CURLOPT_PROXYAUTH] = 'CURLAUTH_ANY | CURLAUTH_ANYSAFE';
+ $pfb['curl_defaults'][CURLOPT_PROXYUSERPWD] = "{$config['system']['proxyuser']}:{$config['system']['proxypass']}";
+ }
+ }
+
+ // Set pfBlockerNG to disabled on 're-install'
if (isset($pfb['install']) && $pfb['install']) {
- $pfb['enable'] = "";
- $pfb['install'] = FALSE;
+ $pfb['enable'] = $pfb['dnsbl'] = '';
+ $pfb['install'] = FALSE;
}
}
pfb_global();
-// Set Max PHP Memory Setting
+// DNSBL Lighttpd HTTPS Daemon (Scans Lighttpd dnsbl_error.log for requested https domain names)
+if ($argv[1] == 'dnsbl') {
+ pfb_livetail($pfb['dnserrlog'], 'dnsbl');
+ exit;
+}
+
+// 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 to decode alias custom entry box.
function pfbng_text_area_decode($text) {
$customlist = explode("\r\n", base64_decode($text));
- foreach ($customlist as $line) {
- if (substr(trim($line), 0, 1) != '#' && !empty($line)) {
- if (strpos($line, '#')) {
- $custom .= trim(strstr($line, '#', TRUE)) . "\n";
- } else {
- $custom .= $line . "\n";
+ if (!empty($customlist)) {
+ foreach ($customlist as $line) {
+ if (substr(trim($line), 0, 1) != '#' && !empty($line)) {
+ if (strpos($line, '#') !== FALSE) {
+ $custom .= trim(strstr($line, '#', TRUE)) . "\n";
+ } else {
+ $custom .= $line . "\n";
+ }
}
}
+ return $custom;
}
- return $custom;
}
-// Manage Log File Line Limit
+// Manage log files line limit
function pfb_log_mgmt() {
global $pfb;
pfb_global();
- if ($pfb['logmax'] == "nolimit") {
- // Skip Log Mgmt
+ if ($pfb['logmax'] == 'nolimit') {
+ // Skip Log mgmt
} else {
- if (file_exists($pfb['log'])) {
- exec("/usr/bin/tail -n {$pfb['logmax']} {$pfb['log']} > /tmp/pfblog; /bin/mv -f /tmp/pfblog {$pfb['log']}");
+ foreach (array('log', 'errlog', 'dnslog', 'extraslog') as $logtype) {
+ if (file_exists($pfb[$logtype])) {
+ exec("/usr/bin/tail -n {$pfb['logmax']} {$pfb[$logtype]} > /tmp/pfblog; /bin/mv -f /tmp/pfblog $pfb[$logtype]");
+ }
}
}
}
-// Record Log Messsages to pfBlockerNG Log File and/or Error Log File.
-function pfb_logger($log, $type) {
- global $g,$pfb,$pfbarr;
+// Record log messsages to pfBlockerNG log file and/or error log file.
+function pfb_logger($log, $logtype) {
+ global $g, $pfb;
- $now = date("m/d/y G:i:s", time());
+ $now = date('m/d/y G:i:s', time());
// Only log timestamp if new
- if (preg_match("/NOW/", $log)) {
+ if (strpos($log, 'NOW') !== FALSE) {
if ($now == $pfb['pnow']) {
- $log = str_replace("[ NOW ]", "", "{$log}");
+ $log = str_replace('[ NOW ]', '', "{$log}");
} else {
- $log = str_replace("NOW", $now, "{$log}");
+ $log = str_replace('NOW', $now, "{$log}");
}
$pfb['pnow'] = "{$now}";
}
- if ($type == 2) {
+ if ($logtype == 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);
+ } elseif ($logtype == 3) {
+ @file_put_contents("{$pfb['extraslog']}", "{$log}", FILE_APPEND);
} else {
@file_put_contents("{$pfb['log']}", "{$log}", FILE_APPEND);
}
}
-// Determine 'List' Details
-function pfb_determine_list_detail($list="", $header_url="", $confconfig="", $key="") {
- global $pfb,$pfbarr,$config;
+// Determine 'list' details
+function pfb_determine_list_detail($list='', $header='', $confconfig='', $key='') {
+ global $config, $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']}";
+ switch($list) {
+ case 'Deny_Both':
+ case 'Deny_Inbound':
+ case 'Deny_Outbound':
+ case 'Alias_Deny':
+ $pfbarr = array('adv' => TRUE, 'folder' => "{$pfb['denydir']}", 'orig' => "{$pfb['origdir']}", 'reuse' => "{$pfb['reuse']}");
+ break;
+ case 'unbound':
+ $pfbarr = array('adv' => FALSE, 'folder' => "{$pfb['dnsdir']}", 'orig' => "{$pfb['dnsorigdir']}", 'reuse' => "{$pfb['reuse_dnsbl']}");
+ break;
+ case 'Permit_Both':
+ case 'Permit_Inbound':
+ case 'Permit_Outbound':
+ case 'Alias_Permit':
+ $pfbarr = array('adv' => FALSE, 'folder' => "{$pfb['permitdir']}", 'orig' => "{$pfb['origdir']}", 'reuse' => "{$pfb['reuse']}");
+ break;
+ case 'Match_Both':
+ case 'Match_Inbound':
+ case 'Match_Outbound':
+ case 'Alias_Match':
+ $pfbarr = array('adv' => FALSE, 'folder' => "{$pfb['matchdir']}", 'orig' => "{$pfb['origdir']}", 'reuse' => "{$pfb['reuse']}");
+ break;
+ case 'Alias_Native':
+ $pfbarr = array('adv' => FALSE, 'folder' => "{$pfb['nativedir']}", 'orig' => "{$pfb['origdir']}", 'reuse' => "{$pfb['reuse']}");
+ break;
}
- // Collect proper Alias Table Description (Alias Only vs AutoRules)
- if (preg_match("/Alias/", $list)) {
- $pfbarr['descr'] = "";
+ // Collect proper alias table description (alias only vs autorules)
+ if (strpos($list, 'Alias') !== FALSE) {
+ $pfbarr['descr'] = '';
} else {
- $pfbarr['descr'] = " Auto ";
+ $pfbarr['descr'] = ' Auto ';
}
- // Determine length of Header to format log Output
- if (strlen($header_url) > 19) {
- $pfbarr['logtab'] = "";
- }
- elseif (strlen($header_url) > 11) {
+ // Determine length of header to format log output
+ $tabtype = strlen($header);
+ if ($tabtype > 19) {
+ $pfbarr['logtab'] = '';
+ } elseif ($tabtype > 11) {
$pfbarr['logtab'] = "\t";
- }
- elseif (strlen($header_url) < 4) {
+ } elseif ($tabtype < 4) {
$pfbarr['logtab'] = "\t\t\t";
- }
- else {
+ } else {
$pfbarr['logtab'] = "\t\t";
}
- if ($confconfig != "") {
- // Configure Autoports/Protocol and Auto Destination if required.
+ if (!empty($confconfig)) {
+ // Configure autoports/protocol and auto destination if required.
$autotype = array( 'autoports' => 'aliasports', 'autodest' => 'aliasdest');
- $aports = ""; $adest = "";
+ $aports = ''; $adest = '';
$pfbarr['aproto'] = $config['installedpackages'][$confconfig]['config'][$key]['autoproto'];
foreach ($autotype as $akey => $atype) {
- if ($config['installedpackages'][$confconfig]['config'][$key][$akey] == "on" && is_array($config['aliases']['alias'])) {
+ if ($config['installedpackages'][$confconfig]['config'][$key][$akey] == 'on' && isset($config['aliases']['alias'])) {
foreach ($config['aliases']['alias'] as $palias) {
if ($palias['name'] == $config['installedpackages'][$confconfig]['config'][$key][$atype]) {
if (!empty($palias['address'])) {
switch($akey) {
- case "autoports":
+ case 'autoports':
$pfbarr['aports'] = $config['installedpackages'][$confconfig]['config'][$key][$atype];
break;
- case "autodest":
+ case 'autodest':
$pfbarr['adest'] = $config['installedpackages'][$confconfig]['config'][$key][$atype];
break;
}
@@ -253,11 +385,11 @@ function pfb_determine_list_detail($list="", $header_url="", $confconfig="", $ke
}
-// Determine if Cron Task requires updating
+// Determine if cron task requires updating
function pfblockerng_cron_exists($crontask, $pfb_min, $pfb_hour) {
global $config;
- if (is_array($config['cron']['item'])) {
+ if (isset($config['cron']['item'])) {
foreach ($config['cron']['item'] as $item) {
if (strpos($item['command'], $crontask) !== FALSE) {
if ($item['minute'] != $pfb_min) {
@@ -282,278 +414,1174 @@ function pfblockerng_cron_exists($crontask, $pfb_min, $pfb_hour) {
function pfb_cron_base_hour() {
global $pfb;
- if ($pfb['interval'] == 1) {
- return;
+ switch($pfb['interval']) {
+ case 1:
+ return;
+ break;
+ case 2:
+ $j = 11; $k = 2;
+ break;
+ case 3:
+ $j = 7; $k = 3;
+ break;
+ case 4:
+ $j = 5; $k = 4;
+ break;
+ case 6:
+ $j = 3; $k = 6;
+ break;
+ case 8:
+ $j = 2; $k = 8;
+ break;
+ case 12:
+ $j = 1; $k = 12;
+ break;
+ case 24:
+ return array($pfb['24hour']);
+ break;
+ default:
+ $pfb['interval'] = 1;
+ return;
}
- if ($pfb['interval'] == 2) {
- // 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);
- }
- $sch2 = explode(",", $sch2);
- sort($sch2);
- return $sch2;
- }
-
- if ($pfb['interval'] == 3) {
- // 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);
- }
- $sch3 = explode(",", $sch3);
- sort($sch3);
- return $sch3;
- }
-
- if ($pfb['interval'] == 4) {
- // 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);
- }
- $sch4 = explode(",", $sch4);
- sort($sch4);
- return $sch4;
- }
-
- if ($pfb['interval'] == 6) {
- // 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);
- }
- $sch6 = explode(",", $sch6);
- sort($sch6);
- return $sch6;
- }
-
- if ($pfb['interval'] == 8) {
- // 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);
- }
- $sch8 = explode(",", $sch8);
- sort($sch8);
- return $sch8;
- }
-
- if ($pfb['interval'] == 12) {
- // 12 Hour Schedule Converter
- $shour = intval(substr($pfb['hour'], 0, 2));
- $sch12 = strval($shour) . ",";
- $shour += 12;
- if ($shour >= 24)
+ $shour = intval(substr($pfb['hour'], 0, 2));
+ $sch = strval($shour);
+
+ for ($i=0; $i < $j; $i++) {
+ $shour += $k;
+ if ($shour >= 24) {
$shour -= 24;
- $sch12 .= strval($shour);
- $sch12 = explode(",", $sch12);
- sort($sch12);
- return $sch12;
+ }
+ $sch .= ',' . strval($shour);
}
- if ($pfb['interval'] == 24) {
- return array($pfb['24hour']);
- }
-
- // Default to hourly schedule
- $pfb['interval'] = 1;
- return;
+ $sch = explode(',', $sch);
+ sort($sch);
+ return $sch;
}
-// Create Suppression Alias
+// 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;
- }
+ // Reload config.xml to get any recent changes
+ $config = parse_config(true);
+
+ // Collect existing pfSense alias(es)
+ if (isset($config['aliases']['alias'])) {
+ $new_aliases = &$config['aliases']['alias'];
}
- // Create New pfBlockerNGSuppress Alias
- $new_aliases[] = array( "name" => "pfBlockerNGSuppress",
- "address" => "",
- "descr" => "pfBlockerNG Suppression List (24|32 CIDR only)",
- "type" => "network",
- "detail" => ""
+
+ // 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;
- $pfb['cron_mod'] = TRUE;
+ write_config('pfBlockerNG: saving suppression alias');
}
-// Create Suppression file from Alias
+// 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;
+ global $config, $pfb;
+
+ // Find pfBlockerNGSuppress array ID number
+ $pfbfound = FALSE;
+ if (isset($config['aliases']['alias'])) {
+ foreach ($config['aliases']['alias'] as $key => $alias) {
+ if ($alias['name'] == 'pfBlockerNGSuppress') {
+ $pfbfound = TRUE;
break;
}
- $pfb_id++;
}
- if ($pfb['found']) {
- $pfb_suppress = str_replace(" ", "\n", $config['aliases']['alias'][$pfb_id]['address']);
+ if ($pfbfound) {
+ $pfb_suppress = str_replace(' ', "\n", $config['aliases']['alias'][$key]['address']);
if (!empty($pfb_suppress)) {
@file_put_contents("{$pfb['supptxt']}", $pfb_suppress, LOCK_EX);
} else {
unlink_if_exists("{$pfb['supptxt']}");
}
} else {
- // Delete Suppression File if Alias is Empty.
+ // Delete suppression file if alias is empty.
unlink_if_exists("{$pfb['supptxt']}");
}
}
- // Call Function to Create Suppression Alias.
- if (!$pfb['found']) {
+ // Call function to create suppression alias.
+ if (!$pfbfound) {
pfb_create_suppression_alias();
}
}
-// IPv6 Range to CIDR function used courtesey from:
-// https://github.com/stilez/pfsense-leases/blob/50cc0fa81dba5fe91bcddaea016c245d1b8479cc/etc/inc/util.inc
-function ip_range_to_subnet_array_temp2($ip1, $ip2) {
-
- if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2)) {
- $proto = 'ipv4'; // for clarity
- $bits = 32;
- $ip1bin = decbin(ip2long32($ip1));
- $ip2bin = decbin(ip2long32($ip2));
- } elseif (is_ipaddrv6($ip1) && is_ipaddrv6($ip2)) {
- $proto = 'ipv6';
- $bits = 128;
- $ip1bin = Net_IPv6::_ip2Bin($ip1);
- $ip2bin = Net_IPv6::_ip2Bin($ip2);
- } else
- return array();
-
- // it's *crucial* that binary strings are guaranteed the expected length; do this for certainty even though for IPv6 it's redundant
- $ip1bin = str_pad($ip1bin, $bits, '0', STR_PAD_LEFT);
- $ip2bin = str_pad($ip2bin, $bits, '0', STR_PAD_LEFT);
-
- if ($ip1bin === $ip2bin)
- return array($ip1 . '/' . $bits);
+// Create DNSBL VIP and NAT rules, lighttpd conf and services
+function pfb_create_dnsbl($mode) {
+ global $config, $pfb;
+
+ // Reload config.xml to get any recent changes
+ $config = parse_config(true);
+
+ $new_nat = $new_vip = $pfb_ex_nat = $pfb_ex_vip = $dnsbl_ex_nat = $dnsbl_ex_vip = array();
+ $pfb['dnsbl_vip_changed'] = $pfbupdate = FALSE;
+
+ if ((!empty($pfb['dnsbl_port']) && !empty($pfb['dnsbl_port_ssl']) && !empty($pfb['dnsbl_vip']) && $mode == 'enable') || $mode == 'disable') {
+
+ // DNSBL NAT rules generation
+ $pfbfound = FALSE;
+ // Collect existing pfSense NAT rules
+ if (isset($config['nat']['rule'])) {
+ foreach ($config['nat']['rule'] as $ex_nat) {
+ if (strpos($ex_nat['descr'], 'pfB DNSBL') !== FALSE) {
+ // Collect DNSBL NAT rules
+ $dnsbl_ex_nat[] = $ex_nat;
+ $pfbfound = TRUE;
+ } else {
+ // Collect all 'other' NAT rules
+ $pfb_ex_nat[] = $ex_nat;
+ }
+ }
+ }
+
+ if ($mode == 'enable') {
+ // Generate new DNSBL NAT per DNSBL listening ports
+ $selected_ports = array("{$pfb['dnsbl_port']}" => '80', "{$pfb['dnsbl_port_ssl']}" => '443');
+ foreach ($selected_ports as $port => $lport) {
+ $dnsbl_new_nat[] = array ( 'source' => array('any' => ''),
+ 'destination' => array('address' => "{$pfb['dnsbl_vip']}", 'port' => "{$lport}"),
+ 'protocol' => 'tcp',
+ 'target' => '127.0.0.1',
+ 'local-port' => "{$port}",
+ 'interface' => "{$pfb['dnsbl_iface']}",
+ 'descr' => 'pfB DNSBL - DO NOT EDIT',
+ 'associated-rule-id' => '',
+ 'natreflection' => 'purenat'
+ );
+ }
+
+ // Compare existing to new and if they are not identical update
+ if ($dnsbl_ex_nat !== $dnsbl_new_nat) {
+ $pfbupdate = TRUE;
+ $new_nat = array_merge($pfb_ex_nat, $dnsbl_new_nat);
+ } else {
+ $new_nat = array_merge($pfb_ex_nat, $dnsbl_ex_nat);
+ }
+ } else {
+ $new_nat = array_merge($pfb_ex_nat, $new_nat);
+ // Update when DNSBL NAT found but is now disabled.
+ if ($pfbfound) {
+ $pfbupdate = TRUE;
+ }
+ }
+
+ // DNSBL VIP generation
+ $dnsbl_new_vip[] = array ( 'mode' => 'ipalias',
+ 'interface' => "{$pfb['dnsbl_iface']}",
+ 'descr' => 'pfB DNSBL - DO NOT EDIT',
+ 'type' => 'single',
+ 'subnet_bits' => '32',
+ 'subnet' => "{$pfb['dnsbl_vip']}"
+ );
+
+ $pfbfound = FALSE;
+ // Collect existing pfSense VIPs
+ if (isset($config['virtualip']['vip'])) {
+ foreach ($config['virtualip']['vip'] as $ex_vip) {
+ if (strpos($ex_vip['descr'], 'pfB DNSBL') !== FALSE) {
+ // Collect DNSBL VIP
+ $dnsbl_ex_vip[] = $ex_vip;
+ $pfbfound = TRUE;
+ } else {
+ // Collect all 'other' VIPs
+ $pfb_ex_vip[] = $ex_vip;
+ }
+ }
+ }
+
+ if ($mode == 'enable') {
+ // Compare existing to new and if they are not identical update
+ if ($dnsbl_ex_vip !== $dnsbl_new_vip) {
+ $pfb['dnsbl_vip_changed'] = TRUE;
+ $pfbupdate = TRUE;
+ $new_vip = array_merge($pfb_ex_vip, $dnsbl_new_vip);
+ } else {
+ $new_vip = array_merge($pfb_ex_vip, $dnsbl_ex_vip);
+ }
+ } else {
+ $new_vip = array_merge($pfb_ex_vip, $new_vip);
+ // Update when DNSBL NAT found but is now disabled.
+ if ($pfbfound) {
+ $pfbupdate = TRUE;
+ }
+ }
+
+ // Only create DNSBL lighttpd conf file if not exists, or listening port changed
+ if (!file_exists($pfb['dnsbl_conf']) && $mode == 'enable' || $pfbupdate && $mode == 'enable') {
+
+// Create Lighttpd conf file for DNSBL
+$pfb_conf = <<<EOF
+#
+#pfBlockerNG Lighttpd DNSBL configuration file
+#
+server.bind = "0.0.0.0"
+server.port = "{$pfb['dnsbl_port']}"
+server.event-handler = "freebsd-kqueue"
+server.network-backend = "freebsd-sendfile"
+server.dir-listing = "disable"
+server.document-root = "/usr/local/www/pfblockerng/www/"
+server.errorlog = "/var/log/pfblockerng/dnsbl_error.log"
+server.pid-file = "/var/run/dnsbl.pid"
+server.modules = ( "mod_access", "mod_fastcgi", "mod_rewrite" )
+
+server.indexfiles = ( "index.php" )
+mimetype.assign = ( ".html" => "text/html", ".gif" => "image/gif" )
+url.access-deny = ( "~", ".inc" )
+fastcgi.server = ( ".php" => ( "localhost" => ( "socket" => "/var/run/php-fpm.socket", "broken-scriptfilename" => "enable" ) ) )
+
+debug.log-condition-handling = "enable"
+
+\$HTTP["host"] =~ ".*" {
+ url.rewrite-once = ( ".*" => "index.php" )
+}
+
+\$SERVER["socket"] == "0.0.0.0:{$pfb['dnsbl_port_ssl']}" {
+ ssl.engine = "enable"
+ ssl.pemfile = "{$pfb['dnsbl_cert']}"
+ ssl.use-sslv2 = "disable"
+ ssl.use-sslv3 = "disable"
+ ssl.honor-cipher-order = "enable"
+ ssl.cipher-list = "AES128+EECDH:AES256+EECDH:AES128+EDH:AES256+EDH:AES128-SHA:AES256-SHA:!aNULL:!eNULL:!DSS"
+
+ \$HTTP["host"] =~ ".*" {
+ url.rewrite-once = ( ".*" => "index.php" )
+ }
+}
+
+EOF;
+ $log = "\nSaving new DNSBL web server configuration to port [ {$pfb['dnsbl_port']} & {$pfb['dnsbl_port_ssl']} ]\n";
+ pfb_logger("{$log}", 1);
+
+ $pfbupdate = TRUE;
+ @file_put_contents($pfb['dnsbl_conf'], $pfb_conf, LOCK_EX);
+ unset($pfb_conf);
+ }
+
+ // Update config.xml, if changes required
+ if ($pfbupdate) {
+ $log = "Saving pfSense config...\n";
+ pfb_logger("{$log}", 1);
+ $config['nat']['rule'] = $new_nat;
+ $config['virtualip']['vip'] = $new_vip;
+ write_config('pfBlockerNG: saving DNSBL changes');
+
+ // Execute ifconfig to enable VIP address
+ $iface = get_real_interface("{$pfb['dnsbl_iface']}");
+ if (!empty($iface) && !empty($pfb['dnsbl_vip'])) {
+ mwexec('/sbin/ifconfig ' . escapeshellarg($iface) . ' inet '. escapeshellarg("{$pfb['dnsbl_vip']}") . '/32 alias');
+ $log = "VIP address configured. Widget Packet statistics reset.\n";
+ pfb_logger("{$log}", 1);
+ filter_configure();
+ } else {
+ $log = "DNSBL ifconfig error : Interface:{$iface}, VIP:{$pfb['dnsbl_iface']}\n";
+ pfb_logger("{$log}", 1);
+ }
+ }
+ }
+
+ // Save settings, restart services as required
+ if ($mode == 'enable') {
+ // Remove any existing and create link for DNSBL lighttpd executable
+ unlink_if_exists('/usr/local/sbin/lighttpd_pfb');
+ link('/usr/local/sbin/lighttpd', '/usr/local/sbin/lighttpd_pfb');
+
+ // Create DNSBL SSL certificate
+ if (!file_exists ("{$pfb['dnsbl_cert']}")) {
+ $log = "New DNSBL Cert Created.\n";
+ pfb_logger("{$log}", 1);
+ exec("/usr/bin/openssl req -new -x509 -keyout {$pfb['dnsbl_cert']} -out {$pfb['dnsbl_cert']} -days 3650 -nodes");
+ }
+
+ if ($pfbupdate || !is_service_running ('dnsbl')) {
+ $log = "Restarting Service DNSBL...\n";
+ pfb_logger("{$log}", 1);
+ restart_service('dnsbl');
+ }
+ } else {
+ // Determine if VIP exists
+ if (isset($config['virtualip']['vip'])) {
+ foreach ($config['virtualip']['vip'] as $ex_vip) {
+ if (strpos($ex_vip['descr'], 'pfB DNSBL') !== FALSE) {
+ // Execute ifconfig to remove VIP address
+ $iface = get_real_interface("{$pfb['dnsbl_iface']}");
+ if (!empty($iface) && !empty($pfb['dnsbl_vip'])) {
+ mwexec('/sbin/ifconfig ' . escapeshellarg($iface) . ' delete ' . escapeshellarg("{$pfb['dnsbl_vip']}"));
+ filter_configure();
+ }
+ }
+ }
+ }
+
+ if (is_service_running('dnsbl')) {
+ pfb_logger("Stop Service DNSBL\n", 1);
+ stop_service('dnsbl');
+ }
+ }
+}
+
+
+// Define DNSBL Unbound include settings
+function pfb_unbound_dnsbl($mode) {
+ global $config, $pfb;
+
+ // Reload config.xml to get any recent changes
+ $config = parse_config(true);
+
+ $pfbupdate = FALSE;
+ $unbound_include = "server:include: {$pfb['dnsbl_file']}.conf";
+
+ // Collect Unbound custom option pfSense conf line
+ $pfb['unboundconfig'] = &$config['unbound']['custom_options'];
+ if (!empty($pfb['unboundconfig'])) {
+ $unbound_custom = base64_decode($pfb['unboundconfig']);
+ } else {
+ $unbound_custom = '';
+ }
+
+ // Determine if DNSBL include line exists
+ if (!empty($unbound_custom)) {
+ // Append DNSBL Unbound pfSense conf integration
+ if (!strstr($unbound_custom, 'pfb_dnsbl.conf')) {
+ if ($mode == 'enabled') {
+ $pfbupdate = TRUE;
+ $unbound_custom .= "\n{$unbound_include}";
+ $log = "\nDNSBL - Adding to existing Unbound custom options\n";
+ }
+ }
+ else {
+ // Remove DNSBL Unbound pfSense conf integration when disabled
+ if ($mode == 'disabled') {
+ $custom = explode ("\n", $unbound_custom);
+ foreach ($custom as $key => $line) {
+ if (strpos($line, 'pfb_dnsbl.conf') !== FALSE) {
+ $pfbupdate = TRUE;
+ $log = "\nDNSBL - Removing DNSBL Unbound custom options\n";
+ unset($custom[$key]);
+ }
+ }
+ $unbound_custom = implode("\n", $custom);
+ }
+ }
+ }
+ else {
+ // Add DNSBL Unbound pfSense conf integration
+ if ($mode == 'enabled') {
+ $pfbupdate = TRUE;
+ $unbound_custom = "{$unbound_include}";
+ $log = "\nDNSBL - Adding Unbound custom 'include' option\n";
+ }
+ }
+
+ // Update config.xml, if changes required
+ if ($pfbupdate) {
+ pfb_logger("{$log}", 1);
+ $unbound_custom = base64_encode(str_replace("\r\n", "\n", $unbound_custom));
+ $pfb['unboundconfig'] = "{$unbound_custom}";
+ write_config('pfBlockerNG: saving Unbound config');
+ }
+}
+
+
+// Validate Unbound conf
+function pfb_validate_unbound($mode) {
+ global $g, $pfb;
+
+ if ($mode == 'enabled') {
+ $ext = '.bk';
+ } else {
+ $ext = '.*'; // Remove all DNSBL Unbound files
+ }
+
+ pfb_logger(" completed\nValidating database...", 1);
+ exec("/usr/local/sbin/unbound-checkconf {$pfb['dnsbldir']}/unbound.tmp 2>&1", $result);
+ pfb_logger(" completed [ NOW ]\n", 1);
+
+ if (preg_grep("/unbound-checkconf: no errors/", $result)) {
+ @rename("{$pfb['dnsbldir']}/unbound.tmp", "{$pfb['dnsbldir']}/unbound.conf");
+
+ // Reload Unbound Service
+ if (is_service_running('unbound')) {
+ pfb_logger('Restarting Unbound ...', 1);
+
+ $cache_dumpfile = '/var/tmp/unbound_cache';
+ unlink_if_exists("{$cache_dumpfile}");
+ $chroot_cmd = "chroot -u unbound -g unbound / /usr/local/sbin/unbound-control -c {$g['unbound_chroot_path']}/unbound.conf";
+
+ exec("{$chroot_cmd} dump_cache > $cache_dumpfile");
+ exec("{$chroot_cmd} reload");
+
+ if (file_exists($cache_dumpfile) && filesize($cache_dumpfile) > 0) {
+ exec("{$chroot_cmd} load_cache < $cache_dumpfile");
+ }
+ }
+ else {
+ pfb_logger('Starting Unbound Service...', 1);
+ // Code from services_unbound.php 'apply'
+ $retval = services_unbound_configure();
+ if ($retval == 0) {
+ clear_subsystem_dirty('unbound');
+ }
+ system_resolvconf_generate(); // Update resolv.conf
+ system_dhcpleases_configure(); // Start or restart dhcpleases
+ }
+
+ exec("/usr/local/sbin/unbound-control -c {$pfb['dnsbldir']}/unbound.conf status", $result);
+ if (preg_grep("/is running.../", $result)) {
+ pfb_logger(" completed\n", 1);
+ } else {
+ pfb_logger(" Not completed.\n", 1);
+ }
+
+ $final_cnt = exec("{$pfb['grep']} -c ^ {$pfb['dnsbldir']}/pfb_dnsbl.conf");
+ $log = "DNSBL update [ {$final_cnt} ]... completed [ NOW ]\n------------------------------------------";
+ pfb_logger("{$log}", 1);
+
+ // When pfBlockerNG is disabled and 'keep blocklists' is disabled.
+ if ($pfb['enable'] == '' && $pfb['keep'] == '' && !$pfb['install']) {
+ unlink_if_exists("{$pfb['dnsbl_file']}{$ext}");
+ }
+
+ // Persist/remove Unbound adv. custom options from pfSense conf file
+ pfb_unbound_dnsbl($mode);
+ }
+ else {
+ // Revert to previous DNSBL database
+ if ($mode == 'enabled') {
+ $log = "\nDNSBL {$mode} FAIL - restoring Unbound conf\n";
+ pfb_logger("{$log}", 2);
+ $log = htmlspecialchars(implode("\n", $result));
+ pfb_logger("{$log}", 1);
+
+ if (file_exists("{$pfb['dnsbl_file']}.bk")) {
+ @rename("{$pfb['dnsbl_file']}.bk", "{$pfb['dnsbl_file']}.conf");
+ }
+ }
+ else {
+ $log = "\nDNSBL {$mode} - Unbound conf update FAIL\n";
+ pfb_logger("{$log}", 1);
+ }
+ }
+}
+
+
+// Process Alexa database
+function pfblockerng_alexa() {
+ global $pfb;
+
+ if (empty($pfb['dnsbl_alexa_inc'])) {
+ pfb_logger("\n Alexa: No TLD Inclusions found.\n", 1);
+ return;
+ }
+
+ // Array of TLDs to include in Whitelist
+ $pfb_include = array_flip(explode(',', $pfb['dnsbl_alexa_inc']));
+
+ if (($handle = fopen("{$pfb['dbdir']}/top-1m.csv", 'r')) !== FALSE) {
+ $pfb_output = fopen("{$pfb['dbdir']}/pfbalexawhitelist.txt", 'w');
+
+ for ($x=1; $x <= $pfb['dnsbl_alexa_cnt']; ++$x) {
+ $aline = fgetcsv($handle);
+
+ // Collect Domain TLD
+ $tld = array_pop(explode('.', $aline[1]));
+
+ if (isset($pfb_include[$tld])) {
+ // Whitelist both 'www.example.com' and 'example.com'
+ if (substr($aline[1], 0, 4) == 'www.') {
+ $aline[1] = substr($aline[1], 4);
+ }
+ fwrite($pfb_output, "local-data: \"www." . $aline[1] . " 60 IN A {$pfb['dnsbl_vip']}\"\n");
+ fwrite($pfb_output, "local-data: \"" . $aline[1] . " 60 IN A {$pfb['dnsbl_vip']}\"\n");
+ }
+ else {
+ // Re-Increment $i count
+ $x = @max(0, --$x);
+ }
+ }
+ }
+ else {
+ $log = "\nAlexa conversion Failed. File: top-1m.csv, not found.\n";
+ pfb_logger("{$log}", 2);
+ }
+ fclose($handle);
+ fclose($pfb_output);
+}
+
+
+// Function to remove any leading zeros in octets and to exclude private/reserved addresses.
+function sanitize_ipaddr($ipaddr, $custom) {
+ global $pfb;
+
+ list ($subnet, $mask) = explode('/', $ipaddr);
+ $iparr = explode('.', $subnet);
+
+ foreach ($iparr as $key => $octet) {
+ // Remove any leading zeros in octets
+ if ($octet == 0) {
+ $ip[$key] = 0;
+ } else {
+ $ip[$key] = ltrim($octet, '0');
+ }
+
+ // Remove 'loopback', '0.0.0.0', and IPs ending with '255'
+ if ($ip[0] == 127 || $ip[0] == 0 || empty($ip[0]) || $ip[3] == 255) {
+ return;
+ }
+
+ if ($key == 3) {
+ // If mask is not defined and 4th octet is '0', set mask to '24'
+ if ($octet == 0 && empty($mask)) {
+ $mask = 24;
+ }
+
+ // If mask is '24', force 4th octet to '0'
+ if ($mask == 24 && $octet != 0) {
+ $ip[$key] = 0;
+ }
+ }
+ }
+
+ $mask = str_replace('32', '', $mask); // Strip '/32' mask
+ $ip_final = implode('.', $ip);
+
+ // Exclude private/reserved IPs when suppression is enabled (bypass exclusion for custom lists)
+ if ($pfb['supp'] == 'on' && !$custom) {
+ if (!filter_var($ip_final, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== FALSE) {
+ return;
+ }
+ }
+
+ if (!empty($mask)) {
+ return "{$ip_final}/{$mask}";
+ }
+ return "{$ip_final}";
+}
+
+
+// Validate IPv4 IP addresses
+function validate_ipv4($ipaddr) {
+ if (strpos($ipaddr, '/') !== FALSE) {
+ return is_subnetv4($ipaddr);
+ }
+ return is_ipaddrv4($ipaddr);
+}
+
+
+// Function to check for loopback addresses (IPv4 range: 127.0.0.0/8, excluding IPv6)
+function FILTER_FLAG_NO_LOOPBACK_RANGE($value) {
+ // http://www.php.net/manual/en/filter.filters.flags.php
+ return filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? $value : (((ip2long($value) & 0xff000000) == 0x7f000000) ? FALSE : $value);
+}
+
+
+// Explode IP for evaluations
+function ip_explode($ip) {
+
+ $ix = explode('.', $ip);
+ foreach ($ix as $key => $octet) {
+ if ($key != 3) {
+ $ix1 .= "{$octet}.";
+ }
+ }
+ array_unshift($ix, $ip);
+ $ix[] = "{$ix1}0/24";
+ $ix[] = "{$ix1}";
+
+ return $ix;
+}
+
+
+// Determine the header which Alerted an IP address and return the header name
+function find_reported_header($ip, $pfbfolder, $exclude=FALSE) {
+
+ if (substr_count($ip, ':') > 1) {
+ $query = strstr($ip, ':', true); // IPv6 Prefix
+ $type = 6;
+ } else {
+ $query = strstr($ip, '.', true); // IPv4 Octet #1
+ $type = 4;
+ }
+ $arr = $cidrs = array();
+
+ // Exclude MaxMind files for Alerts tab query; however include for Download failure queries.
+ $exclusion = "--exclude='pfB_*'";
+ if ($exclude) {
+ $exclusion = '';
+ }
+
+ exec("/usr/bin/grep '^{$query}\.' {$exclusion} {$pfbfolder}", $result);
+ if (!empty($result)) {
+ foreach ($result as $line) {
+
+ $rx = explode('.txt:', $line);
+ $arr[$rx[1]][0] = substr(strrchr($rx[0], '/'), 1); // Capture IP and header
+
+ if ($rx[1] == $ip) {
+ return array('', $arr[$rx[1]][0], TRUE); // Return header on exact IP Match
+ }
+
+ // Collect all CIDRs for analysis if Alert is from a CIDR
+ if (strpos($rx[1], '/') !== FALSE) {
+ $cidrs[] = array($rx[1], $arr[$rx[1]][0]);
+ }
+ }
+
+ // Determine which CIDR alerted the IP address
+ if (!empty($cidrs)) {
+ foreach ($cidrs as $line) {
+
+ // Determine which CIDR alerted the IP address
+ $validate = FALSE;
+ if ($type == 4) {
+ list($addr, $mask) = explode('/', $line[0]);
+ $mask = (0xffffffff << (32 - $mask)) & 0xffffffff;
+ $validate = ((ip2long($ip) & $mask) == (ip2long($addr) & $mask));
+ }
+ else {
+ $validate = (Net_IPv6::isInNetmask($ip, $line[0]));
+ }
+
+ if ($validate) {
+ // Mark all CIDRs except /24 as 'FALSE'
+ $line[2] = FALSE;
+ if (strpos($line[0], '/24') !== FALSE) {
+ $line[2] = TRUE;
+ }
+ return $line; // Return header on CIDR match
+ }
+ }
+ }
+ }
+
+ if ($exclude) {
+ return; // Return null to Download failure function
+ }
+
+ // Query for any active pfBlockerNG CRON jobs
+ exec('/bin/ps -wax', $result_cron);
+ if (preg_grep("/pfblockerng[.]php\s+?(cron|update)/", $result_cron)) {
+ return array('updating..', 'CRON Task');
+ }
+ return array('', 'no match', FALSE);
+}
+
+
+// Function to download feeds
+function pfb_download($list_url, $file_dwn, $pflex=FALSE, $header, $format, $logtype, $vtype, $timeout=300) {
+ global $pfb;
+ $http_status = '';
+
+ // Download RSYNC format
+ if ($format == 'rsync') {
+ $result = exec("/usr/local/bin/rsync --timeout=5 {$list_url} {$file_dwn}.raw");
+ if ($result == 0) {
+ $http_status = '200 OK';
+ } else {
+ $log = "\n RSYNC Failed...\n";
+ pfb_logger("{$log}", "{$logtype}");
+ return FALSE;
+ }
+ }
+ elseif ($format == 'whois') {
+ // Convert a Domain name/AS into its respective IP addresses
+ exec("{$pfb['script']} whoisconvert {$header} {$vtype} {$list_url} {$elog}");
+ return TRUE;
+ }
+ else {
+ // Determine if URL is a localfile
+ $host = @parse_url("{$list_url}");
+ if (in_array($host['host'], array('127.0.0.1', $pfb['iplocal'], ''))) {
+ $lof = 'local';
+ } else {
+ $lof = '';
+ }
+
+ // Download localfile format
+ if ($lof == 'local') {
+ if (!$file_data = @file_get_contents($list_url)) {
+ $error = error_get_last();
+ $log = "\n[ {$header} ] {$error['message']}\n";
+ pfb_logger("{$log}", "{$logtype}");
+ return FALSE;
+ } else {
+ // Save original downloaded file
+ @file_put_contents("{$file_dwn}.raw", $file_data, LOCK_EX);
+ $http_status = '200 OK';
+ }
+ }
- if (strcmp($ip1bin, $ip2bin) > 0)
- list ($ip1bin, $ip2bin) = array($ip2bin, $ip1bin); // swap contents of ip1 <= ip2
+ // Download using cURL
+ else {
+ if (($fhandle = fopen("{$file_dwn}.raw", 'w')) !== FALSE) {
+ if (!($ch = curl_init($list_url))) {
+ $log = "\nFailed to create cURL resource... Exiting...\n";
+ pfb_logger("{$log}", "{$logtype}");
+ return FALSE;
+ }
- $rangesubnets = array();
- $netsize = 0;
+ curl_setopt_array($ch, $pfb['curl_defaults']); // Load curl default settings
+ curl_setopt($ch, CURLOPT_FILE, $fhandle); // Add $fhandle setting to cURL
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // Set cURL download timeout
+ curl_setopt($ch, CURLOPT_ENCODING, 'gzip'); // Request 'gzip' encoding from server if available
+
+ // Attempt 3 Downloads before failing.
+ for ($retries = 1; $retries <= 3; $retries++) {
+ if (curl_exec($ch)) {
+ // Collect remote timestamp.
+ $remote_stamp = curl_getinfo($ch, CURLINFO_FILETIME);
+ break; // Break on success
+ }
- 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"
+ $curl_error = curl_errno($ch);
+ if ($logtype != 3) {
+ pfb_logger(" cURL Error: {$curl_error}\n", 1);
+ } else {
+ pfb_logger(" {$header}\t\tcURL Error: {$curl_error}\n\n", 3);
+ }
- // 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
+ /* 'Flex' Downgrade cURL errors - [ 35 - GET_SERVER_HELLO:sslv3 ]
+ [ 51 - NO alternative certificate ]
+ [ 60 - Local Issuer Certificate Subject ] */
+
+ // Allow downgrade of cURL settings 'Flex' after 1st failure, if user configured.
+ if ($retries == 1 && $pflex && in_array($curl_error, array( '35', '51', '60'))) {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1.2, TLSv1, SSLv3');
+ $log = "\n[ ! ] Downgrading SSL settings (Flex) ";
+ pfb_logger("{$log}", 1);
+ }
+ else {
+ $log = curl_error($ch) . " Retry in 5 seconds...\n";
+ pfb_logger("{$log}", "{$logtype}");
+ sleep(5);
+ pfb_logger('.', "{$logtype}");
+ }
+ }
+
+ // Collect RFC7231 http status code
+ $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+
+ if (isset($pfb['rfc7231'][$http_status])) {
+ if ($logtype != 3) {
+ pfb_logger(". {$pfb['rfc7231'][$http_status]}", 1);
+ } else {
+ pfb_logger(" {$header}\t\t{$pfb['rfc7231'][$http_status]}\n", 3);
+ }
+ } else {
+ if ($logtype != 3) {
+ pfb_logger(". unknown http status code ", 2);
+ } else {
+ pfb_logger(". unknown http status code ", 3);
+ }
+ }
+ curl_close($ch);
+ }
+ fclose($fhandle);
}
+ }
- // 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;
+ if ($http_status == '200 OK') {
+ // Collect file mime-type
+ $file_type = exec("/usr/bin/file -b --mime-type {$file_dwn}.raw");
+ unset($retval);
+
+ // Decompress file if required
+ if ($file_type == 'application/x-gzip') {
+ if ($logtype == 3) {
+ // Extras - MaxMind downloads
+ @rename("{$file_dwn}.raw", strstr("{$file_dwn}.raw", '.raw', TRUE));
+ exec("/usr/bin/gunzip -dfq {$file_dwn} {$pfb['geoipshare']}");
+ return TRUE;
+ }
+ else {
+ pfb_logger('.', 1);
+ $pfb_output = fopen("{$file_dwn}.orig", 'w');
+ if (($fhandle = gzopen("{$file_dwn}.raw", 'r')) !== FALSE) {
+ if (($fhandle = gzopen("{$file_dwn}.raw", 'r')) !== FALSE) {
+ while (($line = gzgets($fhandle, 1024)) !== FALSE) {
+ fwrite($pfb_output, $line);
+ }
+ }
+ $retval = 0;
+ }
+ gzclose($fhandle);
+ fclose($pfb_output);
+ }
}
-
- // 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);
+ elseif ($file_type == 'application/x-bzip2') {
+ pfb_logger('.', 1);
+ exec("/usr/bin/bzip2 -dkc {$file_dwn}.raw > {$file_dwn}.orig", $output, $retval);
+ }
+ elseif ($file_type == 'application/zip') {
+ if ($logtype == 3) {
+ // Extras - MaxMind/Alexa downloads
+ exec("/usr/bin/tar -xOf {$file_dwn}.raw > {$header}");
+ unlink_if_exists("{$file_dwn}.raw");
+ return TRUE;
+ }
- // subnets are ordered by bit size. Re sort by IP ("naturally") and convert back to IPv4/IPv6
+ pfb_logger('.', 1);
+
+ // Check if ZIP archive contains xlsx files
+ $xlsxtest = exec("/usr/bin/tar -tf {$file_dwn}.raw");
+ if (strpos($xlsxtest, '.xlsx') !== FALSE) {
+ unlink_if_exists("{$file_dwn}.orig");
+ exec("{$pfb['script']} xlsx {$header} {$elog}");
+ if (file_exists("{$file_dwn}.orig")) {
+ $retval = 0;
+ }
+ } else {
+ // Process ZIP file
+ exec("/usr/bin/tar -xOf {$file_dwn}.raw | tr ',' '\n' > {$file_dwn}.orig", $output, $retval);
+ }
+ }
+ else {
+ // Uncompressed file format.
+ if ($logtype == 3) {
+ // Extras - MaxMind/Alexa downloads
+ @rename("{$file_dwn}.raw", "{$header}");
+ return TRUE;
+ } else {
+ // Rename file to 'orig' format
+ @rename("{$file_dwn}.raw", "{$file_dwn}.orig");
+ $retval = 0;
+ }
+ }
+
+ if ($retval == 0) {
+ // Set downloaded file timestamp to remote timestamp
+ if (isset($remote_stamp)) {
+ if ($remote_stamp != -1 && file_exists("{$file_dwn}.orig")) {
+ @touch("{$file_dwn}.orig", $remote_stamp);
+ }
+ else {
+ $log = "\n Remote timestamp missing ";
+ pfb_logger("{$log}", 1);
+ }
+ }
+
+ // Process Emerging Threats IQRisk if required
+ if (strpos($list_url, 'iprepdata.txt') !== FALSE) {
+ exec("{$pfb['script']} et {$header} x x x x x {$pfb['etblock']} {$pfb['etmatch']} {$elog}");
+ }
+ return TRUE;
+ }
+ else {
+ $log = " Decompression Failed\n";
+ pfb_logger("{$log}", 2);
+ return FALSE;
+ }
+ }
+ else {
+ // Download failed
+ unlink_if_exists("{$file_dwn}.raw");
+ }
+ return FALSE;
+}
+
+
+// Determine reason for download failure
+function pfb_download_failure($alias, $header, $pfbfolder, $vtype, $list_url) {
+ global $pfb;
+ $pfbfound = FALSE;
+
+ // Determine if URL is a localfile
+ $host = @parse_url("{$list_url}");
+ if (in_array($host['host'], array('127.0.0.1', $pfb['iplocal'], ''))) {
+ $lof = 'local';
+ } else {
+ $lof = '';
+ }
+
+ // Log FAILED downloads and check if firewall or Snort/Suricata is blocking host
+ $log = "\n\n [ {$alias} - {$header} ] Download FAIL [ NOW ]\n";
+ pfb_logger("{$log}", 2);
+
+ // Only perform these checks if they are not 'localfiles'
+ if ($lof == 'local') {
+ $log = " Local File Failure\n";
+ pfb_logger("{$log}", 2);
+ } else {
+ // Determine if Firewall/IDS is blocking download.
+ $ip = @gethostbyname($host);
+
+ if (!empty($ip)) {
+ // Query Firewall aliastables
+ $result = find_reported_header($ip, "{$pfbfolder}/*", TRUE);
+ if (!empty($result)) {
+ $log = " [ {$ip} ] Firewall IP block found in: [ {$result} ]\n";
+ pfb_logger("{$log}", 2);
+ $pfbfound = TRUE;
+ }
+
+ // Query Snort/Suricata snort2c IP block table
+ $result = exec("{$pfb['pfctl']} -t snort2c -T show | {$pfb['grep']} {$ip} 2>&1");
+ if (!empty($result)) {
+ $log = " [ {$ip} ] IDS IP block found!\n";
+ pfb_logger("{$log}", 2);
+ $pfbfound = TRUE;
+ }
+ }
+ else {
+ $log = " Could not determine IP address of host.\n";
+ pfb_logger("{$log}", 2);
+ }
+
+ if (!$pfbfound) {
+ $log = " Firewall and/or IDS are not blocking download.\n";
+ pfb_logger("{$log}", 2);
+ }
+ }
+
+ // On download failure, create file marker for subsequent download attempts
+ if ($pfb['restore'] == 'on' && $pfb['skipfeed'] != 0) {
+ // Call function to get all previous download fails
+ pfb_failures();
+
+ if ($pfb['failed'][$header] <= $pfb['skipfeed']) {
+ touch("{$pfbfolder}/{$header}.fail");
+ return;
+ }
+ }
+
+ unlink_if_exists("{$pfbfolder}/{$header}.fail");
+ return;
+}
- 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;
+// Collect all previously failed daily download notices
+function pfb_failures() {
+ global $pfb;
+ $pfb['failed'] = array();
+
+ if (file_exists("{$pfb['errlog']}")) {
+ exec("{$pfb['grep']} 'FAIL' {$pfb['errlog']} | {$pfb['grep']} $(date +%m/%d/%y)", $results);
+ if (!empty($results)) {
+ foreach ($results as $result) {
+ $header = explode(' ', $result);
+ $pfb['failed'][$header[4]] += 1;
+ }
+ }
}
+ return;
+}
- return $out;
+
+// Convert alias name (via ascii table number) and return a 10 digit tracker id
+function pfb_tracker($alias) {
+ for ($i = 0; $i < strlen($alias); $i++) {
+ $pfbtracker += @ord($alias[$i]);
+ }
+ return '177' . str_pad($pfbtracker, 7, '0', STR_PAD_LEFT);
}
-// Archive Aliastables for NanoBSD and RAMDisk Installations
+// Define firewall rule settings
+function pfb_firewall_rule($action, $pfb_alias, $vtype='', $pfb_log, $adest='', $aports='', $aproto='', $anot='') {
+ global $pfb;
+ $rule = array();
+
+ switch ($action) {
+ case 'Deny_Both':
+ case 'Deny_Outbound':
+ $rule = $pfb['base_rule'];
+ $rule['tracker'] = pfb_tracker("{$pfb_alias}{$vtype}deny_out");
+ $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_log == 'enabled') {
+ $rule['log'] = '';
+ }
+ $rule['created'] = array('time' => (int)microtime(true), 'username' => 'Auto');
+ $pfb['deny_outbound'][] = $rule;
+ if ($action != 'Deny_Both') {
+ break;
+ }
+ case 'Deny_Inbound':
+ $rule = $pfb['base_rule'];
+ $rule['tracker'] = pfb_tracker("{$pfb_alias}{$vtype}deny_in");
+ $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}");
+ if (!empty($adest) && !empty($aports)) {
+ $rule['destination'] = array('address' => "{$adest}", 'port' => "{$aports}");
+ } elseif (!empty($adest) && empty($aports)) {
+ $rule['destination'] = array('address' => "{$adest}");
+ } elseif (empty($adest) && !empty($aports)) {
+ $rule['destination'] = array('any' => '', 'port' => "{$aports}");
+ } else {
+ $rule['destination'] = array('any' => '');
+ }
+ if (!empty($adest) && $anot == 'on') {
+ $rule['destination']['not'] = '';
+ }
+ if (!empty($aproto)) {
+ $rule['protocol'] = "{$aproto}";
+ }
+ if ($pfb['config']['enable_log'] == 'on' || $pfb_log == 'enabled') {
+ $rule['log'] = '';
+ }
+ $rule['created'] = array('time' => (int)microtime(true), 'username' => 'Auto');
+ $pfb['deny_inbound'][] = $rule;
+ break;
+ case 'Permit_Both':
+ case 'Permit_Outbound':
+ $rule = $pfb['base_rule'];
+ $rule['type'] = 'pass';
+ $rule['tracker'] = pfb_tracker("{$pfb_alias}{$vtype}permit_out");
+ 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_log == 'enabled') {
+ $rule['log'] = '';
+ }
+ $rule['created'] = array('time' => (int)microtime(true), 'username' => 'Auto');
+ $pfb['permit_outbound'][] = $rule;
+ if ($action != 'Permit_Both') {
+ break;
+ }
+ case 'Permit_Inbound':
+ $rule = $pfb['base_rule'];
+ $rule['tracker'] = pfb_tracker("{$pfb_alias}{$vtype}permit_in");
+ $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}");
+ if (!empty($adest) && !empty($aports)) {
+ $rule['destination'] = array('address' => "{$adest}", 'port' => "{$aports}");
+ } elseif (!empty($adest) && empty($aports)) {
+ $rule['destination'] = array('address' => "{$adest}");
+ } elseif (empty($adest) && !empty($aports)) {
+ $rule['destination'] = array('any' => '', 'port' => "{$aports}");
+ } else {
+ $rule['destination'] = array('any' => '');
+ }
+ if (!empty($adest) && $anot == 'on') {
+ $rule['destination']['not'] = '';
+ }
+ if (!empty($aproto)) {
+ $rule['protocol'] = "{$aproto}";
+ }
+ if ($pfb['config']['enable_log'] == 'on' || $pfb_log == 'enabled') {
+ $rule['log'] = '';
+ }
+ $rule['created'] = array('time' => (int)microtime(true), 'username' => 'Auto');
+ $pfb['permit_inbound'][] = $rule;
+ break;
+ case 'Match_Both':
+ case 'Match_Outbound':
+ $rule = $pfb['base_rule_float'];
+ $rule['tracker'] = pfb_tracker("{$pfb_alias}{$vtype}match_out");
+ $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_log == 'enabled') {
+ $rule['log'] = '';
+ }
+ $rule['created'] = array('time' => (int)microtime(true), 'username' => 'Auto');
+ $rule['match_outbound'][] = $rule;
+ if ($action != 'Match_Both') {
+ break;
+ }
+ case 'Match_Inbound':
+ $rule = $pfb['base_rule_float'];
+ $rule['tracker'] = pfb_tracker("{$pfb_alias}{$vtype}match_in");
+ $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}");
+ if (!empty($adest) && !empty($aports)) {
+ $rule['destination'] = array('address' => "{$adest}", 'port' => "{$aports}");
+ } elseif (!empty($adest) && empty($aports)) {
+ $rule['destination'] = array('address' => "{$adest}");
+ } elseif (empty($adest) && !empty($aports)) {
+ $rule['destination'] = array('any' => '', 'port' => "{$aports}");
+ } else {
+ $rule['destination'] = array('any' => '');
+ }
+ if (!empty($adest) && $anot == 'on') {
+ $rule['destination']['not'] = '';
+ }
+ if (!empty($aproto)) {
+ $rule['protocol'] = "{$aproto}";
+ }
+ if ($pfb['config']['enable_log'] == 'on' || $pfb_log == 'enabled') {
+ $rule['log'] = '';
+ }
+ $rule['created'] = array('time' => (int)microtime(true), 'username' => 'Auto');
+ $pfb['match_inbound'][] = $rule;
+ break;
+ }
+ return;
+}
+
+
+// Archive aliastables for NanoBSD and RAMDisk installations
function pfb_aliastables($mode) {
- global $g,$config,$pfb;
- $earlyshellcmd = "/usr/local/pkg/pfblockerng/pfblockerng.sh aliastables";
- $msg = "";
+ global $g, $config, $pfb;
+ $earlyshellcmd = '/usr/local/pkg/pfblockerng/pfblockerng.sh aliastables';
+ $msg = '';
- // Only Execute function if Platform is NanoBSD or Ramdisks are used.
- if (($g['platform'] != "pfSense") || isset($config['system']['use_mfs_tmpvar'])) {
+ // Only execute function if platform is NanoBSD or Ramdisks are used.
+ if (($g['platform'] != 'pfSense') || isset($config['system']['use_mfs_tmpvar'])) {
conf_mount_rw();
- if ($mode == "update") {
- // Archive Aliastable Folder
- exec ("cd {$pfb['aliasdir']}; ls -A pfB_*.txt && /usr/bin/tar -jcvf {$pfb['aliasarchive']} pfB_*.txt >/dev/null 2>&1");
- $msg = "\n\nArchiving Aliastable Folder\n";
+ if ($mode == 'update') {
+ // Archive aliastable folder
+ exec("cd {$pfb['aliasdir']}; ls -A pfB_*.txt && /usr/bin/tar -jcvf {$pfb['aliasarchive']} pfB_*.txt >/dev/null 2>&1");
+ pfb_logger("\n\nArchiving Aliastable folder\n", 1);
}
- elseif ($mode == "conf") {
+ elseif ($mode == 'conf') {
+
+ // Reload config.xml to get any recent changes
+ $config = parse_config(true);
+
// Check conf file for earlyshellcmd
- if (is_array($config['system']['earlyshellcmd'])) {
+ if (isset($config['system']['earlyshellcmd'])) {
$a_earlyshellcmd = &$config['system']['earlyshellcmd'];
if (!preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) {
$a_earlyshellcmd[] = "{$earlyshellcmd}";
@@ -569,13 +1597,13 @@ function pfb_aliastables($mode) {
}
else {
if (file_exists("{$pfb['aliasarchive']}")) {
- // Remove Aliastables archive if found.
+ // Remove aliastables archive if found.
conf_mount_rw();
@unlink_if_exists("{$pfb['aliasarchive']}");
conf_mount_ro();
}
// Remove earlyshellcmd if found.
- if (is_array($config['system']['earlyshellcmd'])) {
+ if (isset($config['system']['earlyshellcmd'])) {
$a_earlyshellcmd = &$config['system']['earlyshellcmd'];
if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) {
$a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT);
@@ -584,250 +1612,352 @@ function pfb_aliastables($mode) {
}
}
- if ($msg != "") {
- pfb_logger("{$msg}","1");
- $pfb['cron_mod'] = TRUE;
+ if (!empty($msg)) {
+ pfb_logger("{$msg}", 1);
+ write_config('pfBlockerNG: saving earlyshellcmd');
}
}
-// Main pfBlockerNG Function
-function sync_package_pfblockerng($cron = "") {
+// Read logfile in realtime (livetail)
+// Reference: http://stackoverflow.com/questions/3218895/php-how-to-read-a-file-live-that-is-constantly-being-written-to
+function pfb_livetail($logfile, $mode) {
+ global $pfb;
- global $g,$config,$pfb,$pfbarr;
- pfb_global();
- $pfb['cron_mod'] = FALSE; // Flag to check for mods to the config.xml file.
+ if (!file_exists("{$logfile}")) {
+ touch("{$logfile}");
+ }
- // 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;
+ // Start at EOF
+ $lastpos_old = '';
+ $len = filesize("{$logfile}");
+
+ if ($mode == 'view') {
+ // Start at EOF ( - 15000)
+ if ($len > 15000) {
+ $lastpos = ($len - 15000);
+ } else {
+ $lastpos = 0;
}
}
- log_error("[pfBlockerNG] Starting sync process.");
+ else {
+ $lastpos = $len;
+ }
- // Force Update - Set 'Save' variable when 'No Updates' found.
- if ($cron == "noupdates") {
- $pfb['save'] = TRUE;
+ while (true) {
+ usleep(300000); //0.3s
+ clearstatcache(false, "{$logfile}");
+ $len = filesize("{$logfile}");
+ if ($len < $lastpos) {
+ //file deleted or reset
+ $lastpos = $len;
+ } else {
+ $f = fopen("{$logfile}", 'rb+');
+ if ($f === false) {
+ break;
+ }
+ fseek($f, $lastpos);
+
+ // 'Force Update/Cron/Reload'
+ if ($mode == 'force' || $mode == 'view') {
+ while (!feof($f)) {
+ $pfb_buffer = fread($f, 2048);
+ $pfb_output .= str_replace( array ("\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
+ if ($mode != 'view' && strpos($pfb_output, 'UPDATE PROCESS ENDED') !== FALSE) {
+ $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();
+ break;
+ }
+ }
+ else {
+ // DNSBL Lighttpd 'dnsbl_error.log' conditional log parser
+ while (($pfb_buffer = fgets($f, 1024)) !== FALSE) {
+ if (strpos($pfb_buffer, 'HTTPhost') !== FALSE) {
+ $checkpos = 0;
+ }
+
+ if ($checkpos == 3 && strpos($pfb_buffer, 'HTTP["host"]') !== FALSE) {
+ $line = strstr($pfb_buffer, ' ) compare', TRUE);
+ $line = ltrim(strstr($line, '] ( ', FALSE), '] ( ');
+ if (!empty($line)) {
+ $log = "DNSBL Reject HTTPS," . date('M d G:i:s', time()) . ",{$line}\n";
+ @file_put_contents($pfb['dnslog'], $log, FILE_APPEND | LOCK_EX);
+
+ // Query DNSBL Alias for Domain list.
+ $query = str_replace('.', '\.', $line);
+ exec("/usr/bin/grep -l ' \"{$query} 60 IN A' {$pfb['dnsalias']}/*", $match);
+ $pfb_query = strstr($match[0], 'DNSBL', FALSE);
+
+ if (!empty($pfb_query)) {
+ // Increment DNSBL Alias counter
+ if (($handle = fopen("{$pfb['dnsbl_info']}", 'r')) !== FALSE) {
+ flock($handle, LOCK_EX);
+ $pfb_output = fopen("{$pfb['dnsbl_info']}.bk", 'w');
+ flock($pfb_output, LOCK_EX);
+
+ // Find line with corresponding DNSBL Aliasname
+ while (($line = fgetcsv($handle)) !== FALSE) {
+ if ($line[0] == $pfb_query) {
+ $line[3] += 1;
+ }
+ fputcsv($pfb_output, $line);
+ }
+
+ fclose($pfb_output);
+ fclose($handle);
+ @rename ("{$pfb['dnsbl_info']}.bk", "{$pfb['dnsbl_info']}");
+ }
+ }
+ }
+ }
+ $checkpos++;
+ ob_flush();
+ flush();
+ }
+
+ // Delete parsed logfile contents
+ clearstatcache(false, "{$logfile}");
+ $tlen = filesize("{$logfile}");
+ if ($tlen > $lastpos) {
+ $tlen = $tlen - $lastpos;
+ ftruncate($f, $tlen);
+ fclose($f);
+ $lastpos = $tlen;
+ }
+ }
+ }
}
+}
+
+
+// Main pfBlockerNG function
+function sync_package_pfblockerng($cron='') {
+ global $g, $config, $pfb, $pfbarr;
+ pfb_global();
+ $pfb['conf_mod'] = FALSE; // Flag to check for mods to the config.xml file. ('$pfb_config' array to hold changes)
- // Start of pfBlockerNG Logging to 'pfblockerng.log'
- if ($pfb['enable'] == "on" && !$pfb['save']) {
+ // Detect boot process or package installation
+ if (platform_booting() || $g['pfblockerng_install']) {
+ // Create DNSBL NAT, VIP, Lighttpd service and certs if required on reboot.
+ if ($pfb['dnsbl'] == 'on') {
+ pfb_create_dnsbl('enable');
+ }
+ log_error('[pfBlockerNG] Sync terminated during boot process.');
+ return;
+ }
+ syslog(LOG_NOTICE, '[pfBlockerNG] Starting sync process.');
+
+ // Reloads existing lists without downloading new lists when defined 'on'
+ $pfb['reuse'] = $pfb['config']['pfb_reuse'];
+ $pfb['reuse_dnsbl'] = '';
+
+ // Define update process (update or reload)
+ switch ($cron) {
+ case 'noupdates':
+ // Force update - Set 'save' variable when 'No updates' found.
+ $pfb['save'] = TRUE;
+ break;
+ case 'cron':
+ if ($pfb['reuse'] == 'on') {
+ $pfb['reuse_dnsbl'] = 'on';
+ unlink_if_exists("{$pfb['dbdir']}/masterfile");
+ unlink_if_exists("{$pfb['dbdir']}/mastercat");
+ }
+ break;
+ case 'updatednsbl':
+ $pfb['reuse'] = '';
+ $pfb['reuse_dnsbl'] = 'on';
+ break;
+ case 'updateip':
+ $pfb['reuse'] = 'on';
+ $pfb['reuse_dnsbl'] = '';
+ unlink_if_exists("{$pfb['dbdir']}/masterfile");
+ unlink_if_exists("{$pfb['dbdir']}/mastercat");
+ break;
+ }
+
+ // Start of pfBlockerNG logging to 'pfblockerng.log'
+ if ($pfb['enable'] == 'on' && !$pfb['save']) {
$log = " UPDATE PROCESS START [ NOW ]\n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
} else {
- if ($cron != "noupdates") {
- $log = "\n**Saving Configuration [ NOW ] ...\n";
- pfb_logger("{$log}","1");
+ if ($cron != 'noupdates') {
+ $log = "\n**Saving configuration [ NOW ] ...\n";
+ pfb_logger("{$log}", 1);
}
}
// Call function for NanoBSD/Ramdisk processes.
- pfb_aliastables("conf");
+ pfb_aliastables('conf');
- // Collect pfSense Max Table Size Entry
+ // If table limit not defined, set default to 2M
if (empty($config['system']['maximumtableentries'])) {
- // If Table limit not defined, set Default to 2M
- $config['system']['maximumtableentries'] = "2000000";
- $pfb['cron_mod'] = TRUE;
+ $config['system']['maximumtableentries'] = '2000000';
+ write_config('pfBlockerNG: save max Firewall table entries limit');
}
$pfb['table_limit'] = $config['system']['maximumtableentries'];
// Collect local web gui configuration
- $pfb['weblocal'] = ($config['system']['webgui']['protocol'] != "" ? $config['system']['webgui']['protocol'] : "http");
+ $pfb['weblocal'] = $config['system']['webgui']['protocol'] ?: 'http';
$pfb['port'] = $config['system']['webgui']['port'];
- if ($pfb['port'] == "") {
- if ($config['system']['webgui']['protocol'] == "http") {
- $pfb['port'] = "80";
+ if (empty($pfb['port'])) {
+ if ($config['system']['webgui']['protocol'] == 'http') {
+ $pfb['port'] = '80';
} else {
- $pfb['port'] = "443";
+ $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");
-
- // 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
+ // Define Inbound/Outbound action is not user selected.
+ $pfb['deny_action_inbound'] = $pfb['config']['inbound_deny_action'] ?: 'block';
+ $pfb['deny_action_outbound'] = $pfb['config']['outbound_deny_action'] ?: 'reject';
+
+ $pfb['openvpn'] = $pfb['config']['openvpn_action']; // Enable OpenVPN autorules
+ $pfb['float'] = $pfb['config']['enable_float']; // Enable/Disable floating autorules
+ $pfb['dup'] = $pfb['config']['enable_dup']; // Enable remove of duplicate IPs utilizing grepcidr
+ $pfb['agg'] = $pfb['config']['enable_agg']; // Enable aggregation of CIDRs
+ $pfb['order'] = $pfb['config']['pass_order']; // Order of the autorules
+ $pfb['suffix'] = $pfb['config']['autorule_suffix']; // Suffix used for autorules
+ $pfb['kstates'] = $pfb['config']['killstates']; // Firewall states removal
+
+ // DNSBL settings
+ $pfb['dnsbl_vip'] = $pfb['dnsblconfig']['pfb_dnsvip'] ?: ''; // Virtual IP local address
+ $pfb['dnsbl_iface'] = $pfb['dnsblconfig']['dnsbl_interface']?: 'lan'; // VIP Local Interface setting
+ $pfb['dnsbl_ip'] = $pfb['dnsblconfig']['action'] ?: 'Disabled'; // Enable/Disable IP blocking from DNSBL lists
+ $pfb['dnsbl_rule'] = $pfb['dnsblconfig']['pfb_dnsbl_rule'] ?: 'Disabled'; // Auto create a Floating Pass Rule for other Lan subnets
+ $pfb['dnsbl_alexa'] = $pfb['dnsblconfig']['alexa_enable'] ?: 'Disabled'; // Enable Alexa whitelist
+ $pfb['dnsbl_alexa_cnt'] = $pfb['dnsblconfig']['alexa_count'] ?: '1000'; // Alexa whitelist domain setting
+ $pfb['dnsbl_alexa_inc'] = $pfb['dnsblconfig']['alexa_inclusion'] ?: ''; // Alexa TLDs inclusions for whitelisting
+
+ // 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
+ $pfb['rep'] = $pfb['config_rep']['enable_rep']; // Enable/Disable 'Max' Reputation
+ $pfb['prep'] = $pfb['config_rep']['enable_pdup']; // Enable/Disable 'pRep' Reputation
+ $pfb['drep'] = $pfb['config_rep']['enable_dedup'] ?: 'x'; // Enable/Disable 'dRep' Reputation
+ $pfb['etupdate']= $pfb['config_rep']['et_update']; // Perform a Force Update on ET categories
+ $pfb['ccwhite'] = $pfb['config_rep']['ccwhite']; // Action for whitelist Country category
+ $pfb['ccblack'] = $pfb['config_rep']['ccblack']; // Action for blacklist Country category
+
+ $pfb['etblock'] = $pfb['config_rep']['etblock'] ?: 'x'; // Emerging Threats IQRisk block categories
+ $pfb['etmatch'] = $pfb['config_rep']['etmatch'] ?: 'x'; // Emerging Threats IQRisk match categories
+ $pfb['max'] = $pfb['config_rep']['p24_max_var'] ?: 'x'; // 'Max' variable setting for Reputation
+ $pfb['dmax'] = $pfb['config_rep']['p24_dmax_var'] ?: 'x'; // 'dMax' variable setting for Reputation
+ $pfb['pmax'] = $pfb['config_rep']['p24_pmax_var'] ?: 'x'; // 'pMax' variable setting for Reputation
+ $pfb['ccexclude']= $pfb['config_rep']['ccexclude'] ?: 'x'; // List of Countries to whitelist
+
+ // Starting variable to skip Reputation functions, if no changes are required
+ $pfb['repcheck'] = FALSE;
+ // $pfb['save'] is used to determine if user pressed "save" button to avoid collision with CRON, defined in each pfBlockerNG XML file.
+
+ // For 'script' calls using exec() (used to shorten length of line)
+ $elog = ">> {$pfb['log']} 2>&1";
#################################
# Configure ARRAYS #
#################################
- $continents = array ( "Africa" => "pfB_Africa",
- "Antartica" => "pfB_Antartica",
- "Asia" => "pfB_Asia",
- "Europe" => "pfB_Europe",
- "North America" => "pfB_NAmerica",
- "Oceania" => "pfB_Oceania",
- "South America" => "pfB_SAmerica",
- "Top Spammers" => "pfB_Top",
- "Proxy and Satellite" => "pfB_PS"
- );
-
- // create rules vars and arrays
- // Array used to Collect Changes to Aliases to be saved to Config
- $new_aliases = array();
- $new_aliases_list = array();
- $continent_existing = array();
- $continent_new = array();
- $permit_inbound = array();
- $permit_outbound = array();
- $deny_inbound = array();
- $deny_outbound = array();
- // An Array of all Aliases (Active and non-Active)
- $aliases_list = array();
- // This is an Array of Aliases that Have Updated Lists via CRON/Force Update when 'Reputation' disabled.
- $pfb_alias_lists = array();
- // This is an Array of All Active Aliases used when 'Reputation' enabled
- $pfb_alias_lists_all = array();
-
- // Base Rule Array
- $base_rule_reg = array( "id" => "",
- "tag" => "",
- "tagged" => "",
- "max" => "",
- "max-src-nodes" => "",
- "max-src-conn" => "",
- "max-src-states"=> "",
- "statetimeout" => "",
- "statetype" => "keep state",
- "os" => ""
- );
-
- // Floating Rules, Base Rule Array
- $base_rule_float = array("id" => "",
- "tag" => "",
- "tagged" => "",
- "quick" => "yes",
- "floating" => "yes",
- "max" => "",
- "max-src-nodes" => "",
- "max-src-conn" => "",
- "max-src-states"=> "",
- "statetimeout" => "",
- "statetype" => "keep state",
- "os" => ""
- );
+ $new_aliases = array(); // An array of aliases (full details)
+ $new_aliases_list = array(); // An array of alias names
+ $pfb_alias_lists = array(); // An array of aliases that have updated lists via CRON/force update. ('Reputation' disabled)
+ $pfb_alias_lists_all = array(); // An array of all active aliases. ('Reputation' enabled)
#########################################
# 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
+ // 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'))) {
+ $action = array('Deny_Both', 'Deny_Inbound', 'Deny_Outbound', 'Match_Both', 'Match_Inbound',
+ 'Match_Outbound', 'Permit_Both', 'Permit_Inbound', 'Permit_Outbound');
+
+ foreach ($pfb['continents'] as $continent => $pfb_alias) {
+ if (isset($config['installedpackages']['pfblockerng' . strtolower(str_replace(' ', '', $continent))]['config'])) {
+ $continent_config = $config['installedpackages']['pfblockerng' . strtolower(str_replace(' ', '', $continent))]['config'][0];
+ if ($continent_config['action'] != 'Disabled' && in_array($continent_config['action'], $action)) {
$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;
+ if (!$pfb['autorules']) {
+ $list_type = array('pfblockernglistsv4', 'pfblockernglistsv6');
+ foreach ($list_type as $ip_type) {
+ if (isset($config['installedpackages'][$ip_type]['config'])) {
+ foreach($config['installedpackages'][$ip_type]['config'] as $list) {
+ if ($list['action'] != 'Disabled' && in_array($list['action'], $action)) {
+ $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'])) {
+ // Configure auto rule suffix. pfBlockerNG must be disabled to change suffix and to avoid duplicate rules
+ $pfbfound = FALSE;
+ if (isset($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) {
+ // 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++;
+ // Query for existing pfB rules
+ if (strpos($rule['descr'], 'pfB_') !== FALSE && $rule['descr'] != 'pfB_DNSBL_Allow_access_to_VIP') {
+ $pfbfound = TRUE;
break;
}
}
}
- // Change Suffix only if No pfB Rules Found and Auto Rules are Enabled.
- if ($pfb['autorules'] && $count == 0) {
+ // Change suffix only if no pfB rules found and autorules are enabled.
+ if ($pfb['autorules'] && !$pfbfound) {
switch ($pfb['suffix']) {
- case "autorule":
- $pfb['suffix'] = " auto rule";
+ case 'autorule':
+ $pfb['suffix'] = ' auto rule';
break;
- case "standard":
- $pfb['suffix'] = "";
+ case 'standard':
+ $pfb['suffix'] = '';
break;
- case "ar":
- $pfb['suffix'] = " AR";
+ case 'ar':
+ $pfb['suffix'] = ' AR';
break;
}
} else {
if ($pfb['autorules']) {
- // Use existing Suffix Match
+ // Use existing suffix match
$pfb['suffix'] = $pfb_suffix_match;
} else {
- // Leave Rule Suffix 'Blank'
- $pfb['suffix'] = "";
+ // Leave rule suffix 'blank'
+ $pfb['suffix'] = '';
}
}
@@ -836,69 +1966,57 @@ function sync_package_pfblockerng($cron = "") {
# Configure INBOUND/OUTBOUND INTERFACES #
#########################################################
- // Collect pfSense Interface Order
+ // 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");
+ $interface_types = array('inbound' => 'inbound_interface', 'outbound' => 'outbound_interface');
+ foreach ($interface_types as $pftype => $int_type) {
+ $int_type_s = "{$int_type}s"; // Add trailing 's' to variable name.
+
+ // Define empty variable/array
+ $pfb["{$pftype}_interfaces_float"] = '';
+ $pfb[$int_type_s] = array();
+
+ if (!empty($pfb['config'][$int_type])) {
+ // Sort interface array to match pfSense interface order to allow floating rules to populate.
+ $selected_interfaces = explode(',', $pfb['config'][$int_type]);
+ // Sort pfBlockerNG interface order to pfSense interface order
+ $sort_interfaces = array_intersect($ifaces, $selected_interfaces);
+
+ // If OpenVPN interfaces are not in pfB interface dropdown menu
+ if ($pfb['openvpn'] == 'on' && $pftype == 'outbound') {
+ if ($config['openvpn']['openvpn-server'] || $config['openvpn']['openvpn-client']) {
+ if (!in_array('openvpn', $sort_interfaces)) {
+ array_push($sort_interfaces, 'openvpn');
+ }
+ }
+ }
+ $implode_interfaces = ltrim(implode(',', $sort_interfaces), ',');
+ $pfb["{$pftype}_interfaces_float"] = explode(' ', $implode_interfaces);
+
+ // CSV string for inbound interfaces for 'pfB_' match rules
+ $pfb["{$pftype}_floating"] = $implode_interfaces;
+
+ // Assign base rule/interfaces
+ if ($pfb['float'] == 'on') {
+ // Define base firewall floating rules settings
+ $pfb['base_rule'] = $pfb['base_rule_float'];
+ $pfb[$int_type_s] = $pfb["{$pftype}_interfaces_float"];
+ } else {
+ // Define base firewall rules settings
+ $pfb['base_rule'] = $pfb['base_rule_reg'];
+ $pfb[$int_type_s] = explode(',', $pfb['config'][$int_type]);
+
+ // If OpenVPN interfaces are not in pfB interface dropdown menu
+ if ($pfb['openvpn'] == 'on' && $pftype == 'outbound') {
+ if ($config['openvpn']['openvpn-server'] || $pfb['openvpn'] == 'on' && $config['openvpn']['openvpn-client']) {
+ if (!in_array('openvpn', $sort_interfaces)) {
+ array_push($pfb["{$pftype}_interfaces"], 'openvpn');
+ }
+ }
}
}
}
- } else {
- // Define Empty Variable/Array
- $pfb['outbound_interfaces_float'] = "";
- $pfb['outbound_interfaces'] = array();
}
@@ -906,46 +2024,32 @@ function sync_package_pfblockerng($cron = "") {
# Clear Removed Lists from Masterfiles #
#################################################
- // Process to keep Masterfiles in Sync with Valid Lists from config.conf file.
+ // 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") {
+ // 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");
+ $m_action = array('Match_Both', 'Match_Inbound', 'Match_Outbound', 'Alias_Match');
+ $p_action = array('Permit_Both', 'Permit_Inbound', 'Permit_Outbound', 'Alias_Permit');
+
+ // Find all enabled Continents lists
+ foreach ($pfb['continents'] as $continent => $pfb_alias) {
+ if (isset($config['installedpackages']['pfblockerng' . strtolower(str_replace(' ', '', $continent))]['config']) && $pfb['enable'] == 'on') {
+ $continent_config = $config['installedpackages']['pfblockerng' . strtolower(str_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'))) {
+ if (!empty($continent_config[$c_type])) {
+ // Set parameters for 'Match', 'Permit', 'Native' and 'Deny' actions.
+ if (in_array($continent_config['action'], $m_action)) {
$pfb['existing']['match'][] = "{$pfb_alias}{$vtype}";
- } elseif (in_array($continent_config['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))){
+ } elseif (in_array($continent_config['action'], $p_action)){
$pfb['existing']['permit'][] = "{$pfb_alias}{$vtype}";
- } elseif ($continent_config['action'] == "Alias_Native") {
+ } elseif ($continent_config['action'] == 'Alias_Native') {
$pfb['existing']['native'][] = "{$pfb_alias}{$vtype}";
} else {
$pfb['existing']['deny'][] = "{$pfb_alias}{$vtype},"; // Add Trailing ','
@@ -956,112 +2060,102 @@ function sync_package_pfblockerng($cron = "") {
}
}
- // Find all Enabled IPv4/IPv6 Lists
- $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ // Find all enabled IPv4/IPv6 lists and DNSBL lists
+ // 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', 'pfblockerngdnsbl' => '_v4', 'pfblockerngdnsbleasylist' => '_v4');
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") {
+ if (!empty($config['installedpackages'][$ip_type]['config']) && $pfb['enable'] == 'on') {
+ foreach ($config['installedpackages'][$ip_type]['config'] as $key => $list) {
+ if (isset($list['row']) && $list['action'] != 'Disabled') {
foreach ($list['row'] as $row) {
- if ($vtype == "_v4") {
- $pfb_alias = "{$row['header']}";
+ if ($vtype == '_v4') {
+ $header = "{$row['header']}";
} else {
- $pfb_alias = "{$row['header']}_v6";
+ $header = "{$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}";
+
+ // Collect enabled lists
+ if (!empty($row['url']) && $row['state'] != 'Disabled') {
+ if (in_array($list['action'], $m_action)) {
+ $pfb['existing']['match'][] = "{$header}";
+ } elseif (in_array($list['action'], $p_action)) {
+ $pfb['existing']['permit'][] = "{$header}";
+ } elseif ($list['action'] == 'Alias_Native') {
+ $pfb['existing']['native'][] = "{$header}";
+ } elseif ($list['action'] == 'unbound') {
+ $pfb['existing']['dnsbl'][] = "{$header}";
} else {
- $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ','
+ $pfb['existing']['deny'][] = "{$header},"; // 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";
- $pfb['cron_mod'] = TRUE;
- break;
+ // Check if 'Emerging Threats' needs updating.
+ if ($pfb['etupdate'] == 'enabled' && strpos($row['url'], 'iprepdata.txt') !== FALSE) {
+ unlink_if_exists("{$pfb['denydir']}/{$header}.txt");
+ $pfb_config['installedpackages']['pfblockerngreputation']['config'][0]['et_update'] = 'disabled';
+ $pfb['conf_mod'] = TRUE;
}
}
}
}
- // Collect Enabled Custom List Box Aliases
- if (pfbng_text_area_decode($list['custom']) != "") {
- if ($vtype == "_v4") {
- $pfb_alias = "{$list['aliasname']}_custom";
+ // Collect custom list box aliases
+ if (!empty($list['custom'])) {
+ if ($vtype == '_v4') {
+ $pfb_custom = "{$list['aliasname']}_custom";
} else {
- $pfb_alias = "{$list['aliasname']}_custom_v6";
+ $pfb_custom = "{$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}";
+
+ // Determine folder location for 'list'
+ if (in_array($list['action'], $m_action)) {
+ $pfb['existing']['match'][] = "{$pfb_custom}";
$pfbfolder = "{$pfb['matchdir']}";
- } elseif (in_array($list['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) {
- $pfb['existing']['permit'][] = "{$pfb_alias}";
+ } elseif (in_array($list['action'], $p_action)) {
+ $pfb['existing']['permit'][] = "{$pfb_custom}";
$pfbfolder = "{$pfb['permitdir']}";
- } elseif ($list['action'] == "Alias_Native") {
- $pfb['existing']['native'][] = "{$pfb_alias}";
+ } elseif ($list['action'] == 'Alias_Native') {
+ $pfb['existing']['native'][] = "{$pfb_custom}";
$pfbfolder = "{$pfb['nativedir']}";
+ } elseif ($list['action'] == 'unbound') {
+ $pfb['existing']['dnsbl'][] = "{$pfb_custom}";
+ $pfbfolder = "{$pfb['dnsdir']}";
} else {
- $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ','
+ $pfb['existing']['deny'][] = "{$pfb_custom},"; // 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";
- $pfb['cron_mod'] = TRUE;
+
+ // Determine if 'Custom List' needs force updating before next CRON event.
+ if ($list['custom_update'] == 'enabled') {
+ unlink_if_exists("{$pfbfolder}/{$pfb_custom}.txt");
+ // Uncheck 'enabled' in list 'custom_update' setting
+ $pfb_config['installedpackages'][$ip_type]['config'][$key]['custom_update'] = 'disabled';
+ $pfb['conf_mod'] = TRUE;
}
}
}
}
}
- // 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) {
+ // Collect all .txt file names for each list type
+ $list_types = array( 'match' => $pfb['matchdir'], 'permit' => $pfb['permitdir'], 'deny' => $pfb['denydir'],
+ 'native' => $pfb['nativedir'], 'dnsbl' => $pfb['dnsdir']);
+
+ foreach ($list_types as $pftype => $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 ','
+ $pfb_file = basename($pfb_list, '.txt');
+ if ($pftype == 'deny') {
+ $pfb['actual'][$pftype][] = "{$pfb_file},"; // Add Trailing ','
} else {
- $pfb['actual'][$type][] = "{$pfb_file}";
+ $pfb['actual'][$pftype][] = "{$pfb_file}";
}
}
}
- // Flag to execute pfctl and Rules Ordering
- $pfb['remove'] = FALSE;
- // Execute Final Summary as a List was Removed
- $pfb['summary'] = FALSE;
+ $pfb['remove'] = FALSE; // Flag to execute pfctl and rules ordering or reload of DNSBL domains
+ $pfb['summary'] = FALSE; // Execute final summary as a list was removed
- // Process to Remove Lists from Masterfile/DB Folder if they do not Exist
+ // 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'];
@@ -1070,51 +2164,74 @@ function sync_package_pfblockerng($cron = "") {
$actual_type = $pfb_act['type'];
if ($existing_type == $actual_type) {
switch ($existing_type) {
- case "deny":
+ case 'deny':
$results = array_diff($pfb_act, $pfb_exist);
$f_result = implode($results);
- if ($f_result != "") {
+ if (!empty($f_result)) {
$log = "[ Removing List(s) : {$f_result} ]\n";
- pfb_logger("{$log}","1");
+ 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;
+ exec("{$pfb['script']} remove x x x {$f_result} {$elog}");
+ $pfb['summary'] = $pfb['remove'] = TRUE;
}
break;
- case "match":
- case "permit":
- case "native":
+ 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_result) {
- $log = "[ Removing List : {$pfb_result} ]\n";
- pfb_logger("{$log}","1");
+ $log = "[ Removing List(s) : {$pfb_result} ]\n";
+ pfb_logger("{$log}", 1);
unlink_if_exists("{$pfbfolder}/{$pfb_result}.txt");
}
- $pfb['summary'] = TRUE;
- $pfb['remove'] = TRUE;
+ $pfb['summary'] = $pfb['remove'] = TRUE;
}
break;
+ case 'dnsbl':
+ $dresults = array_diff($pfb_act, $pfb_exist);
+ if (!empty($dresults)) {
+ foreach ($dresults as $pfb_result) {
+ $log = "[ Removing List(s) : {$pfb_result} ]\n";
+ pfb_logger("{$log}", 1);
+ rmdir_recursive("{$pfb['dnsdir']}");
+ safe_mkdir("{$pfb['dnsdir']}");
+ }
+
+ // Query for any active pfBlockerNG CRON jobs
+ $result_cron = array();
+ exec('/bin/ps -wax', $result_cron);
+ if (preg_grep("/pfblockerng[.]php\s+?(cron|update)/", $result_cron)) {
+ $log = "\n ** DNSBL Reload Terminated due to active pfBlockerNG cron process\n";
+ pfb_logger("{$log}", 1);
+ } else {
+ if ($pfb['enable'] == 'on' && $pfb['dnsbl'] == 'on') {
+ pfb_logger("\n ** Running Background Reload Task\n", 1);
+ // Clear any existing pfBlockerNG Cron Jobs to avoid collision
+ install_cron_job('pfblockerng.php cron', false);
+ $cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php";
+ mwexec_bg("${cmd} updatednsbl >> {$pfb['log']} 2>&1");
+ }
+ }
+ }
}
// Allow rebuilding of changed Alias 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") {
+ if (!empty($results) && $pfb['enable'] == 'on') {
+ $list_type = array('pfblockernglistsv4' => '_v4', 'pfblockernglistsv6' => '_v6');
+ foreach ($list_type as $ip_type => $vtype) {
foreach ($results as $removed_header) {
- if ($config['installedpackages'][$ip_type]['config'] != "") {
+ if (isset($config['installedpackages'][$ip_type]['config'])) {
foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
- $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']);
- if (is_array($list['row'])) {
+ $alias = 'pfB_' . preg_replace("/\W/", '', $list['aliasname']);
+ if (!empty($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['summary'] = $pfb['remove'] = TRUE;
+ // Add Alias to update array
$pfb_alias_lists[] = "{$alias}";
$pfb_alias_lists_all[] = "{$alias}";
}
@@ -1136,19 +2253,23 @@ function sync_package_pfblockerng($cron = "") {
#########################################################
// When pfBlockerNG is Disabled and 'Keep Blocklists' is Disabled.
- if ($pfb['enable'] == "" && $pfb['keep'] == "" && !$pfb['install']) {
+ if ($pfb['enable'] == '' && $pfb['keep'] == '' && !$pfb['install']) {
$log = "\n Removing DB Files/Folders \n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
unlink_if_exists("{$pfb['dbdir']}/masterfile");
unlink_if_exists("{$pfb['dbdir']}/mastercat");
unlink_if_exists("{$pfb['supptxt']}");
+ unlink_if_exists("{$pfb['dnsbl_info']}");
rmdir_recursive("{$pfb['origdir']}");
rmdir_recursive("{$pfb['matchdir']}");
rmdir_recursive("{$pfb['permitdir']}");
rmdir_recursive("{$pfb['denydir']}");
rmdir_recursive("{$pfb['nativedir']}");
rmdir_recursive("{$pfb['etdir']}");
+ rmdir_recursive("{$pfb['dnsdir']}");
+ rmdir_recursive("{$pfb['dnsorigdir']}");
+ rmdir_recursive("{$pfb['dnsalias']}");
}
@@ -1156,271 +2277,939 @@ function sync_package_pfblockerng($cron = "") {
# Create IP Suppression Txt File #
#################################################
- if ($pfb['enable'] == "on" && $pfb['supp'] == "on") {
+ if ($pfb['enable'] == 'on' && $pfb['supp'] == 'on') {
pfb_create_suppression_file();
}
+ #########################################
+ # DNSBL - Processes #
+ #########################################
+
+ if ($pfb['dnsbl'] == 'on' && !$pfb['save']) {
+ // Terminate if DNSBL VIP is empty
+ $dnsbl_error = FALSE;
+ if (empty($pfb['dnsbl_vip']) || empty($pfb['dnsbl_port']) || empty($pfb['dnsbl_port_ssl'])) {
+ $log = "\n\n===[ DNSBL Virtual IP and/or Ports are not defined. Exiting ]======\n";
+ pfb_logger("{$log}", 1);
+ $dnsbl_error = TRUE;
+ }
+ }
+
+ if ($pfb['dnsbl'] == 'on' && !$pfb['save'] && !$dnsbl_error) {
+ $log = "\n===[ DNSBL Process ]================================================\n";
+ pfb_logger("{$log}", 1);
+
+ if (isset($config['installedpackages']['pfblockerngdnsbl']['config']) || isset($config['installedpackages']['pfblockerngdnsbleasylist']['config'])) {
+
+ // Collect existing DNSBL alias statistics
+ // CSV file format [ alias name , updated timestamp , total domain count, total blocked count ]
+ if (file_exists("{$pfb['dnsbl_info']}")) {
+ $dnsbl_info = array_map('str_getcsv', @file("{$pfb['dnsbl_info']}"));
+ } else {
+ $dnsbl_info = array();
+ }
+
+ // Rebuild DNSBL database or DNSBL statistics if files are not found
+ if (!file_exists("{$pfb['dnsbl_file']}.conf") || !file_exists($pfb['dnsbl_info'])) {
+ $log = "Missing DNSBL stats and/or Unbound DNSBL conf file - Rebuilding\n";
+ pfb_logger("{$log}", 1);
+ $pfb['reuse_dnsbl'] = 'on';
+ }
+
+ // Collect suppression list
+ $pfb_dnssupp = array();
+ if (!empty($pfb['dnsblconfig']['suppression'])) {
+ $pfb_dnssupp = explode("\n", pfbng_text_area_decode($pfb['dnsblconfig']['suppression']));
+ }
+
+ // Call Alexa whitelist process
+ if ($pfb['dnsbl_alexa'] == 'on') {
+ // Check if Alexa database exists
+ if (!file_exists("{$pfb['dbdir']}/top-1m.csv")) {
+ // Check if Alexa download already in progress
+ exec('/bin/ps -wax', $result_cron);
+ if (!preg_grep("/pfblockerng[.]php\s+al/", $result_cron)) {
+ $log = "\nAlexa Database downloading ( approx 21M ) ... Please wait ...\n";
+ pfb_logger("{$log}", 1);
+ exec("/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php al");
+ }
+ else {
+ $log = "\nAlexa download already in process...\n";
+ pfb_logger("{$log}", 1);
+ }
+ }
+
+ // Process Alexa database
+ pfblockerng_alexa();
+ }
+
+ // Collect feeds and custom list configuration and format into one array ($lists).
+ $lists = array();
+ if (isset($config['installedpackages']['pfblockerngdnsbl']['config'])) {
+ foreach ($config['installedpackages']['pfblockerngdnsbl']['config'] as $list) {
+ // If only the 'customlist' is defined. Remove the 'List row' data.
+ if (empty($list['row'][0]['url'])) {
+ unset($list['row']);
+ }
+
+ if (!empty($list['custom'])) {
+ $list['row'][] = array( 'header' => "{$list['aliasname']}_custom",
+ 'custom' => $list['custom'],
+ 'state' => 'Enabled',
+ 'update' => $list['custom_update'],
+ 'url' => 'custom'
+ );
+ }
+ $lists[] = $list;
+ }
+ }
+
+ // Add DNSBL EasyList to '$lists array'
+ if (!empty($config['installedpackages']['pfblockerngdnsbleasylist']['config'])) {
+ foreach($config['installedpackages']['pfblockerngdnsbleasylist']['config'] as $list) {
+ $lists[] = $list;
+ }
+ }
+
+ // Define DNSBL arrays and variables
+ $alias_dnsbl_all = array(); // Array of all DNSBL aliases
+ $pfb['domain_update'] = FALSE; // Flag to signal update Unbound
+
+ foreach ($lists as $list) {
+
+ // Reset variables once per alias
+ $lists_dnsbl_current = array(); // Array of all active Lists in current alias
+ $pfb['aliasupdate'] = FALSE; // Flag to signal changes to alias
+ $pfb['updateip'] = FALSE; // Flag to signal updates to DNSBL IP lists
+ $alias_cnt = 0;
+
+ if ($list['action'] != 'Disabled' && isset($list['row'])) {
+ $alias = 'DNSBL_' . preg_replace("/\W/", '', $list['aliasname']);
+ $alias_dnsbl_all[] = "{$alias}";
+ foreach ($list['row'] as $key => $row) {
+ if (!empty($row['url']) && $row['state'] != 'Disabled') {
+
+ $header = "{$row['header']}";
+ $liteparser = FALSE; // Minimal DNSBL Parser
+ $domain_data_ip = array(); // Array of IPs found in feed
+ $domain_data = ''; // List of Domains found in feed
+
+ // If row is a custom_list, set flag.
+ if (isset($row['custom'])) {
+ $custom = TRUE;
+ } else {
+ $custom = FALSE;
+ }
+
+ // EasyList - collect enabled EasyList categories
+ if (isset($list['easycat']) && !isset($easylist)) {
+ $easylist = explode(',', $list['easycat']);
+ }
+
+ // Determine 'list' details (return array $pfbarr)
+ pfb_determine_list_detail($list['action'], $header, 'pfblockerngdnsblsettings', '0');
+ $pfbadv = $pfbarr['adv'];
+ $pfbfolder = $pfbarr['folder'];
+ $pfborig = $pfbarr['orig'];
+ $pfbreuse = $pfbarr['reuse'];
+ $logtab = $pfbarr['logtab'];
+ $aports = $pfbarr['aports'];
+ $adest = $pfbarr['adest'];
+ $aproto = $pfbarr['aproto'];
+
+ // Empty header field validation check
+ if (empty($header)) {
+ $log = "\n[ {$row['url']} ]{$logtab} Header Field cannot be empty. *Skipping* \n";
+ pfb_logger("{$log}", 2);
+ continue;
+ }
+
+ if (file_exists("{$pfbfolder}/{$header}.txt") && $pfbreuse == '') {
+ if ($row['state'] == 'Hold') {
+ $log = "\n[ {$header} ]{$logtab} Static Hold [ NOW ]";
+ } else {
+ $log = "\n[ {$header} ]{$logtab} exists, Reloading [ NOW ]";
+ }
+ pfb_logger("{$log}", 1);
+
+ // Collect existing list stats
+ $lists_dnsbl_all[] = "{$row['header']}";
+ $lists_dnsbl_current[] = "{$row['header']}";
+ $list_cnt = exec("{$pfb['grep']} -c ^ {$pfbfolder}/{$header}.txt");
+ $alias_cnt = $alias_cnt + $list_cnt;
+
+ } else {
+ if ($pfbreuse == 'on' && file_exists("{$pfborig}/{$header}.orig")) {
+ $log = "\n[ {$header} ]{$logtab} Reload [ NOW ]";
+ } else {
+ $log = "\n[ {$header} ]{$logtab} Downloading update [ NOW ]";
+ }
+ pfb_logger("{$log}", 1);
+ $file_dwn = "{$pfborig}/{$header}";
+
+ if (!$custom) {
+ pfb_logger(' .', 1);
+
+ // Allow cURL SSL downgrade 'Flex' if user configured.
+ $pflex = FALSE;
+ if ($row['state'] == 'Flex') {
+ $pflex = TRUE;
+ }
+
+ // Determine if list needs to be downloaded or reuse previously downloaded file.
+ if ($pfbreuse == 'on' && file_exists("{$file_dwn}.orig")) {
+ // File exists/reuse
+ pfb_logger(' completed .', 1);
+ } else {
+ // Download file
+ if (!pfb_download($row['url'], $file_dwn, $pflex, $header,
+ $row['format'], 1, '')) {
+
+ // Determine reason for download failure
+ pfb_download_failure($alias, $header, $pfbfolder,
+ $list['vtype'], $row['url']);
+
+ // Utilize previously download file (If 'fail' marker exists)
+ if (file_exists("{$pfbfolder}/{$header}.fail") &&
+ file_exists("{$file_dwn}.orig")) {
+ pfb_logger("\n Restoring previously downloaded file\n ", 2);
+ } else {
+ continue;
+ }
+ }
+ else {
+ // Clear any previous download fail marker
+ unlink_if_exists("{$pfbfolder}/{$header}.fail");
+ }
+ }
+ }
+ else {
+ // Collect custom list data.
+ $custom_list = pfbng_text_area_decode($row['custom']);
+ @file_put_contents("{$file_dwn}.orig", $custom_list, LOCK_EX);
+ unset($custom_list);
+ $liteparser = TRUE;
+ }
+
+ // Parse downloaded file for Domain names
+
+ $e_skip = $e_found = FALSE; // Variables for Easylists
+ $fail_list = ''; $csvfail = $ipcount = $ip_cnt = 0;
+ if (($fhandle = fopen("{$file_dwn}.orig", 'r')) !== FALSE) {
+ while (($line = fgets($fhandle, 3072)) !== FALSE) {
+
+ // On 'category match', parse EasyList feed
+ if (isset($easylist)) {
+ if (substr($line, 24, 19) == 'easylist_adservers.' ||
+ substr($line, 27, 28) == 'easyprivacy_trackingservers.') {
+ $e_found = TRUE;
+ }
+ }
+ else {
+ if (strpos($line, '[Adblock Plus ') !== FALSE) {
+ pfb_logger("\n\n Terminated - Easylists can not be used.\n", 1);
+ break;
+ }
+ }
+
+ // Skip unuseable EasyList lines
+ if (isset($easylist) && !$e_found) {
+ continue;
+ }
+
+ // Remove any '^M' characters
+ if (strpos($line, "\r") !== FALSE) {
+ $line = preg_replace(array("/\^M\s+/", "/\^M/"), '', $line);
+ }
+
+ // If 'tab' character found, replace with whitespace
+ if (strpos($line, "\x09") !== FALSE) {
+ $line = str_replace("\x09", ' ', $line);
+ }
+
+ // If '%20' found, remove.
+ if (strpos($line, '%20') !== FALSE) {
+ $line = str_replace('%20', '', $line);
+ }
+
+ // If 'http(s)://' found, remove.
+ if (strpos($line, 'http://') !== FALSE || strpos($line, 'https://') !== FALSE) {
+ $line = preg_replace("(^https?://)", '', $line);
+ }
+
+ // Remove any leading/trailing whitespaces
+ $line = trim($line);
+
+ // Remove blank lines
+ if (empty($line)) {
+ continue;
+ }
+
+ // Remove comment lines and special format considerations
+ if (substr($line, 0, 1) == '#') {
+ // Exit (hpHosts) when end of domain names found.
+ if (strpos($line, 'Append critical updates below') !== FALSE) {
+ break;
+ }
+
+ // Spamhaus format validation
+ if (strpos($line, 'The Spamhaus Project Ltd') !== FALSE) {
+ $liteparser = TRUE;
+ }
+ continue;
+ }
+
+ // Convert CSV line into array
+ if (!isset($easylist) && substr_count($line, ',') >= 2) {
+ $csvline = str_getcsv($line, ',', '', '"');
+ } else {
+ $csvline = '';
+ }
+
+ // CSV parser
+ if (!isset($easylist) && count($csvline) >= 2) {
+ // Parse Phishtank CSV
+ if (strpos($csvline[2], 'www.phishtank.com/phish_detail.php') !== FALSE) {
+ $liteparser = TRUE;
+ if (count($csvline) == 8) {
+ $host = parse_url($csvline[1]);
+ $line = $host['host'];
+ } else {
+ //Record Failed attemps
+ $csvfail++;
+ $fail_list .= $line . '|';
+ continue;
+ }
+ }
+
+ // Parse Bambenek Consulting domain list
+ elseif (strpos($csvline[3], 'osint.bambenekconsulting.com') !== FALSE) {
+ $liteparser = TRUE;
+ if (count($csvline) == 4) {
+ $line = $csvline[0];
+ } else {
+ //Record Failed attemps
+ $csvfail++;
+ $fail_list .= $line . '|';
+ continue;
+ }
+ }
+
+ // Parse ET IQRisk IPRep domain list
+ elseif (!strpos($csvline[2], 'www.phishtank.com/phish_detail.php')){
+ if (strpos($csvline[1], '.') !== FALSE &&
+ (int)$csvline[1] != 0 && count($csvline) == 3) {
+ $liteparser = TRUE;
+ $line = $csvline[0];
+ }
+ }
+ }
+ $line = trim($line);
+
+ // Parser for EasyList, enable collect of selected EasyList categories
+ if (isset($easylist) && strpos($line, '! *** easylist:') !== FALSE) {
+ // Skip all previous Easylist entries
+
+ // Collect EasyList feed
+ if (substr($line, 24, 19) == 'easylist_adservers.') {
+ if (in_array('ea', $easylist) ? $e_skip = FALSE : $e_skip = TRUE);
+ }
+ elseif (substr($line, 24, 25) == 'easylist_adservers_popup.') {
+ if (in_array('eap', $easylist) ? $e_skip = FALSE : $e_skip = TRUE);
+ }
+ elseif (substr($line, 30, 16) == 'adult_adservers.') {
+ if (in_array('aa', $easylist) ? $e_skip = FALSE : $e_skip = TRUE);
+ }
+ elseif (substr($line, 30, 22) == 'adult_adservers_popup.') {
+ if (in_array('aap', $easylist) ? $e_skip = FALSE : $e_skip = TRUE);
+ }
+
+ // Collect EasyPrivacy feed
+ elseif (substr($line, 27, 28) == 'easyprivacy_trackingservers.') {
+ if (in_array('epts', $easylist) ? $e_skip = FALSE : $e_skip = TRUE);
+ }
+ elseif (substr($line, 27, 42) == 'easyprivacy_trackingservers_international.') {
+ if (in_array('epti', $easylist) ? $e_skip = FALSE : $e_skip = TRUE);
+ }
+
+ // End of useable EasyList feed
+ elseif (substr($line, 24, 20) == 'easylist_thirdparty.') {
+ break;
+ }
+ // End of useable EasyPrivacy feed
+ elseif (substr($line, 27, 23) == 'easyprivacy_thirdparty.') {
+ break;
+ }
+ }
+
+ // Parse EasyList line
+ if (isset($easylist)) {
+ if (!$e_skip) {
+ if (substr($line, 0, 2) != '||') {
+ continue;
+ }
+ if (strpos($line, '^$') !== FALSE) {
+ $line = trim(str_replace('|', '', strstr($line, '^$', TRUE)));
+ }
+ elseif (strpos($line, '^*') !== FALSE) {
+ $line = trim(str_replace('|', '', strstr($line, '^*', TRUE)));
+ }
+ else {
+ continue;
+ }
+ if (strpos($line, '/') !== FALSE) {
+ $line = strstr($line, '/', TRUE);
+ }
+ if (strpos($line, '*.') !== FALSE) {
+ $line = substr(strrchr($line, '*.'), 2);
+ }
+ $liteparser = TRUE;
+ }
+ else {
+ continue;
+ }
+ }
+
+ // Parser for all other domain feeds (Initial line preparation)
+ if (!$liteparser) {
+ // If 'space' character found, remove characters before space
+ if (strpos($line, ' ') !== FALSE) {
+ $line = strstr($line, ' ', FALSE);
+ }
+
+ // If '#' character found, remove characters after '#'
+ if (strpos($line, '#') !== FALSE) {
+ $line = strstr($line, '#', TRUE);
+ }
+
+ // Remove any leading/trailing whitespaces
+ $line = trim($line);
+
+ // If 'space' character found, remove characters after space
+ if (strpos($line, ' ') !== FALSE) {
+ $line = strstr($line, ' ', TRUE);
+ }
+
+ // If '/' character found, remove characters after '/'
+ if (strpos($line, '/') !== FALSE) {
+ $line = strstr($line, '/', TRUE);
+ }
+ } else {
+ // If 'space' character found, remove characters after space
+ if (strpos($line, ' ') !== FALSE) {
+ $line = strstr($line, ' ', TRUE);
+ }
+
+ // Remove any leading/trailing whitespaces
+ $line = trim($line);
+ }
+
+ // If special characters found, parse line for host
+ if ((strpos($line, ';') !== FALSE || strpos($line, '&') !== FALSE ||
+ strpos($line, '?') !== FALSE || strpos($line, ":") !== FALSE)) {
+ $host = parse_url($line);
+ $line = $host['host'];
+ }
+
+ // Collect any IPs found in domain feed
+ if (is_ipaddrv4($line)) {
+ if ($pfb['dnsbl_ip'] != 'Disabled') {
+ $parsed = sanitize_ipaddr($line, $custom);
+ if (validate_ipv4($parsed)) {
+ $domain_data_ip[] = $parsed;
+ $pfb['updateip'] = TRUE;
+ $ipcount++;
+ }
+ }
+ continue;
+ }
+
+ // Remove invalid domains
+ if (strpos($line, '.') === FALSE || substr($line, -1) == '.' ||
+ substr($line, 0, 1) == '.' || strpos($line, '..') !== FALSE) {
+ continue;
+ }
+
+ // Remove suppressed domain names
+ if (!in_array($line, $pfb_dnssupp)) {
+ $domain_data .= "local-data: \"" . $line . " 60 IN A {$pfb['dnsbl_vip']}\"\n";
+ }
+ }
+ }
+ fclose($fhandle);
+ unset($csvline, $easylist); // Unset variables
+
+ // Remove duplicates and save any IPs found in domain feed
+ if (!empty($domain_data_ip)) {
+ $domain_data_ip = implode("\n", array_unique($domain_data_ip)) . "\n";
+ @file_put_contents("{$pfbfolder}/{$header}.ip", $domain_data_ip, LOCK_EX);
+ $ip_cnt = exec("{$pfb['grep']} -c ^ {$pfbfolder}/{$header}.ip");
+ }
+
+ // Validate feed with Unbound-checkconf
+ if (!empty($domain_data)) {
+ $dnsbl_file = "{$pfbfolder}/{$header}";
+
+ $conf = "server:\n";
+ $conf .= "chroot: {$pfb['dnsbldir']}\n";
+ $conf .= "username: \"unbound\"\n";
+ $conf .= "directory: \"{$pfb['dnsbldir']}\"\n";
+ $conf .= "pidfile: \"/var/run/unbound.pid\"\n";
+ $conf .= "server:include: {$dnsbl_file}.bk";
+ @file_put_contents("{$pfb['dnsbldir']}/check.conf", $conf, LOCK_EX);
+
+ @file_put_contents("{$dnsbl_file}.bk", $domain_data, LOCK_EX);
+ pfb_logger('.', 1);
+
+ // Bypass Alexa whitelist if user configured
+ if ($list['filter_alexa'] == 'on' && file_exists("{$pfb['dbdir']}/pfbalexawhitelist.txt")) {
+ $pfb_alexa = 'on';
+ } else {
+ $pfb_alexa = 'Disabled';
+ }
+
+ // Call script to process domain de-duplication/Alexa whitelisting
+ exec("{$pfb['script']} domainduplicate {$header} {$pfb_alexa} {$elog}");
+
+ if ($ip_cnt > 0) {
+ $log = "IP count={$ip_cnt}\n";
+ pfb_logger("{$log}", 1);
+ }
+
+ $result = array();
+ exec("/usr/local/sbin/unbound-checkconf {$pfb['dnsbldir']}/check.conf 2>&1", $result);
+ @unlink_if_exists("{$pfb['dnsbldir']}/check.conf");
+ }
+ else {
+ $log = "\n No Domains Found\n";
+ pfb_logger("{$log}", 1);
+ continue;
+ }
+
+ // Exit further processing of feed if parse error found.
+ if (!preg_grep("/unbound-checkconf: no errors/", $result)) {
+ @unlink_if_exists("{$dnsbl_file}.bk");
+ $log = "\n[ DNSBL FAIL ] [ Skipping : {$row['header']} ]\n\n";
+ pfb_logger("{$log}", 2);
+ $log = htmlspecialchars(implode("\n", $result));
+ pfb_logger("{$log}", 1);
+ continue;
+ }
+ else {
+ // Save DNSBL feed
+ $pfb['domain_update'] = $pfb['aliasupdate'] = $pfb['summary'] = TRUE;
+ $lists_dnsbl_all[] = "{$row['header']}";
+ $lists_dnsbl_current[] = "{$row['header']}";
+ @rename("{$dnsbl_file}.bk", "{$dnsbl_file}.txt");
+ $list_cnt = exec("{$pfb['grep']} -c ^ {$dnsbl_file}.txt");
+ $alias_cnt = $alias_cnt + $list_cnt;
+
+ // Print failed domain parsing info
+ if ($csvfail > 0) {
+ $log = " * Failed Lines: {$csvfail}\n |{$fail_list}\n\n";
+ pfb_logger("{$log}", 1);
+ }
+ }
+ }
+ }
+ }
+
+ // If changes found update DNSBL alias
+ if ($pfb['aliasupdate']) {
+
+ // Create master alias file
+ $pfb_output = fopen("{$pfb['dnsalias']}/{$alias}", 'w');
+ foreach ($lists_dnsbl_current as $clist) {
+ if (($handle = fopen("{$pfbfolder}/{$clist}.txt", 'r')) !== FALSE) {
+ while (($line = fgets($handle, 3072)) !== FALSE) {
+ fwrite($pfb_output, $line);
+ }
+ }
+ fclose($handle);
+ }
+ fclose($pfb_output);
+
+ // Update domain alias statistics
+ $dns_now = date('M d G:i', time());
+ $pfbfound = FALSE;
+ foreach ($dnsbl_info as $key => $line) {
+ // Update existing alias stats
+ if ($line[0] == "{$alias}") {
+ $pfbfound = TRUE;
+ $dnsbl_info[$key][1] = "{$dns_now}";
+ $dnsbl_info[$key][2] = "{$alias_cnt}";
+ break;
+ }
+ }
+
+ if (!$pfbfound) {
+ $dnsbl_info[] = explode(',', "{$alias},{$dns_now},{$alias_cnt},0");
+ }
+ }
+ }
+ else {
+ // Record disabled alias statistics
+ $pfbfound = FALSE;
+ if (!empty($dnsbl_info)) {
+ foreach ($dnsbl_info as $line) {
+ if ($line[0] == "{$alias}") {
+ $pfbfound = TRUE;
+ break;
+ }
+ }
+ }
+ if (!$pfbfound) {
+ $dns_now = date('M d G:i', time());
+ $dnsbl_info[] = explode(',', "{$alias},{$dns_now},disabled,0");
+ }
+ }
+ }
+
+ }
+
+ // Remove any unused DNSBL aliases
+ $daliases = glob("{$pfb['dnsalias']}/*");
+ if (!empty($daliases)) {
+ foreach ($daliases as $dlist) {
+ if (!in_array(basename($dlist), $alias_dnsbl_all)) {
+ unlink_if_exists ("{$dlist}");
+ }
+ }
+ }
+
+ // Save alias statistics to file (Remove any feeds that are not referenced)
+ $handle = fopen("{$pfb['dnsbl_info']}", 'w');
+ fwrite($handle, "# Keeping this file open in a file editor will interrupt DNSBL!\n");
+ foreach ($dnsbl_info as $alias) {
+ if (in_array($alias[0], $alias_dnsbl_all)) {
+ fputcsv($handle, $alias);
+ }
+ }
+ fclose($handle);
+ }
+
+ // Create DNSBL firewall rules/alias if action permits
+ if ($pfb['enable'] == 'on' && $pfb['dnsbl'] == 'on' && $pfb['dnsbl_ip'] != 'Disabled') {
+ $new_aliases[] = array( 'name' => 'pfB_DNSBLIP',
+ 'url' => "{$pfb['weblocal']}?pfb=pfB_DNSBLIP",
+ 'updatefreq' => '32',
+ 'address' => '',
+ 'descr' => 'pfBlockerNG auto DNSBL IP Alias',
+ 'type' => 'urltable',
+ 'detail' => 'DO NOT EDIT THIS ALIAS'
+ );
+
+ // Determine 'list' details (return array $pfbarr)
+ pfb_determine_list_detail($list['action'], $header, 'pfblockerngdnsblsettings', '0');
+
+ // Define DNSBL_IP firewall rule settings
+ if ($pfb['dnsbl_ip'] != 'Alias_Deny') {
+ pfb_firewall_rule($pfb['dnsbl_ip'], 'pfB_DNSBLIP', '', $pfb['dnsblconfig']['aliaslog'],
+ $pfbarr['adest'], $pfbarr['aports'], $pfbarr['aproto'], $pfb['dnsblconfig']['autonot']);
+ }
+
+ // Collect DNSBL IP addresses into 'pfB_DNSBLIP' aliastable
+ $dnsbl_ip = glob("{$pfb['dnsdir']}/*.ip");
+ if (!empty($dnsbl_ip)) {
+ if ($pfb['updateip'] || !file_exists("{$pfb['aliasdir']}/pfB_DNSBLIP.txt")) {
+ $pfb_ips = fopen("{$pfb['aliasdir']}/pfB_DNSBLIP.txt", 'w');
+ foreach ($dnsbl_ip as $d_ip) {
+ if (($handle = fopen("{$d_ip}", 'r')) !== FALSE) {
+ while (($line = fgets($handle, 1024)) !== FALSE) {
+ fwrite($pfb_ips, $line);
+ }
+ }
+ fclose($handle);
+ }
+ fclose($pfb_ips);
+ }
+
+ // Update DNSBL_IPs aliastable
+ if ($pfb['updateip'] && file_exists("{$pfb['aliasdir']}/pfB_DNSBLIP.txt")) {
+ $result = '';
+ $list_cnt = exec("{$pfb['grep']} -c ^ {$pfb['aliasdir']}/pfB_DNSBLIP.txt");
+ exec("{$pfb['pfctl']} -t pfB_DNSBLIP -T replace -f {$pfb['aliasdir']}/pfB_DNSBLIP.txt 2>&1", $result);
+
+ $log = "\n[ DNSBL_IP ]\t\t Updating aliastable [ NOW ]\n------------------------------------------\n";
+ $log .= implode($result);
+
+ $log .= "\nTotal IP count = {$list_cnt}\n------------------------------------------";
+ pfb_logger("{$log}", 1);
+ }
+ }
+ else {
+ // Flush DNSBL IPs aliastable when empty
+ exec("{$pfb['pfctl']} -t pfB_DNSBLIP -T flush 2>&1", $result);
+ // Add empty placeholder '1.1.1.1' to aliastable
+ exec("{$pfb['pfctl']} -t pfB_DNSBLIP -T add 1.1.1.1");
+ @file_put_contents("{$pfb['aliasdir']}/pfB_DNSBLIP.txt", "1.1.1.1\n", LOCK_EX);
+ }
+ }
+ else {
+ // Remove 'DNSBLIP' aliastable and files
+ exec("{$pfb['pfctl']} -t pfB_DNSBLIP -T kill 2>&1", $result);
+ unlink_if_exists("{$pfb['aliasdir']}/pfB_DNSBLIP.txt");
+ }
+
+ #########################################
+ # UPDATE Unbound DNS Database #
+ #########################################
+
+ if ($pfb['domain_update']) {
+ if (!empty($lists_dnsbl_all)) {
+ pfb_logger("\n\n------------------------------------------\nAssembling database...", 1);
+ $pfb_output = fopen("{$pfb['dnsbl_file']}.raw", 'w');
+ foreach ($lists_dnsbl_all as $current_list) {
+ if (($handle = fopen("{$pfb['dnsdir']}/{$current_list}.txt", 'r')) !== FALSE) {
+ while (($line = fgets($handle, 3072)) !== FALSE) {
+ fwrite($pfb_output, $line);
+ }
+ }
+ fclose($handle);
+ }
+ fclose($pfb_output);
+
+ // Perform sort and uniq on DNSBL database File. Validation of file required before use.
+ exec("{$pfb['cat']} {$pfb['dnsbl_file']}.raw | /usr/bin/sort | /usr/bin/uniq > {$pfb['dnsbl_file']}.tmp && /bin/rm -f {$pfb['dnsbl_file']}.raw");
+ }
+ else {
+ $log = "\nDNSBL not Updated!\n";
+ pfb_logger("{$log}", 1);
+ }
+ }
+
+
+ #################################
+ # UNBOUND INTEGRATION #
+ #################################
+
+ $pfbupdate = FALSE;
+ if (file_exists("{$pfb['dnsbldir']}/unbound.conf")) {
+ $conf = file("{$pfb['dnsbldir']}/unbound.conf");
+ }
+
+ if ($pfb['enable'] == 'on' && $pfb['dnsbl'] == 'on' && $pfb['unbound_state'] == 'on') {
+ // If new domain updates found, backup existing DNSBL domain feed
+ if ($pfb['domain_update']) {
+ if (file_exists ("{$pfb['dnsbl_file']}.conf")) {
+ @copy("{$pfb['dnsbl_file']}.conf", "{$pfb['dnsbl_file']}.bk");
+ }
+ @rename("{$pfb['dnsbl_file']}.tmp", "{$pfb['dnsbl_file']}.conf");
+ @file_put_contents("{$pfb['dnsbldir']}/unbound.tmp", $conf, LOCK_EX);
+ }
+
+ // Add 'include:' line in Unbound conf file if not found
+ if (isset($conf) && !strstr(implode($conf), 'pfb_dnsbl.conf')) {
+ if (file_exists("{$pfb['dnsbl_file']}.conf")) {
+ $log = " Adding Unbound Server:Include line...";
+ pfb_logger("{$log}", 1);
+
+ $pfbupdate = TRUE;
+ $conf[] = "# Unbound custom options\n\nserver:include: {$pfb['dnsbl_file']}.conf\n";
+ @file_put_contents("{$pfb['dnsbldir']}/unbound.tmp", $conf, LOCK_EX);
+ }
+ }
+
+ // Validate new Unbound conf file before use.
+ if ($pfb['domain_update'] || $pfbupdate) {
+ pfb_validate_unbound('enabled');
+ }
+
+ // Create DNSBL NAT and VIP and lighttpd web server conf if required.
+ pfb_create_dnsbl('enable');
+ }
+ else {
+ // When DNSBL is disabled and not during an installation.
+ if ($pfb['dnsbl'] == '' && !$pfb['install']) {
+ // Remove 'Unbound' conf integration
+ if (isset($conf) && stripos(implode($conf), 'pfb_dnsbl.conf') !== FALSE) {
+ $pfbupdate = FALSE;
+ foreach ($conf as $key => $line) {
+ if (strpos($line, 'pfb_dnsbl.conf') !== FALSE) {
+ $pfbupdate = TRUE;
+ unset ($conf[$key]);
+ }
+ }
+ if ($pfbupdate) {
+ @file_put_contents("{$pfb['dnsbldir']}/unbound.tmp", $conf, LOCK_EX);
+ // Validate new Unbound conf file before use.
+ pfb_validate_unbound('disabled');
+ }
+ }
+
+ // Remove DNSBL NAT, VIP and lighttpd service
+ pfb_create_dnsbl('disable');
+
+ // Remove 'DNSBL_IPs' aliastable
+ exec("{$pfb['pfctl']} -t pfB_DNSBLIP -T kill 2>&1", $result);
+ unlink_if_exists("{$pfb['aliasdir']}/pfB_DNSBLIP.txt");
+ }
+
+
+ // Use applicable log message
+ if (!$pfbupdate) {
+ if (!$pfb['save']) {
+ $log = "\n** DNSBL Disabled **\n";
+ pfb_logger("{$log}", 1);
+ }
+ } else {
+ $log = "\n\n===[ DNSBL Disabled ]==========================================\n";
+ pfb_logger("{$log}", 1);
+ }
+ }
+ unset($conf);
+ unlink_if_exists("{$pfb['dnsbl_file']}.bk");
+
#################################
# 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];
- $cc_name = 'pfblockerng' . strtolower(preg_replace('/ /','',$continent));
- if ($continent_config['action'] != "Disabled" && $pfb['enable'] == "on") {
+ if (!$pfb['save']) {
+ $log = "\n\n===[ Continent Process ]============================================\n";
+ pfb_logger("{$log}", 1);
+ }
- // Determine if Continent Lists require Action (IPv4 and IPv6)
- $cont_type = array ("countries4" => "_v4", "countries6" => "_v6");
+ foreach ($pfb['continents'] as $continent => $pfb_alias) {
+ if (isset($config['installedpackages']['pfblockerng' . strtolower(str_replace(' ', '', $continent))]['config'])) {
+ $continent_config = $config['installedpackages']['pfblockerng' . strtolower(str_replace(' ', '', $continent))]['config'][0];
+ $cc_name = 'pfblockerng' . strtolower(str_replace(' ', '', $continent));
+ if ($continent_config['action'] != 'Disabled' && $pfb['enable'] == 'on') {
+
+ // Determine if Continent lists require action (IPv4 and IPv6)
+ $cont_type = array('countries4' => '_v4', 'countries6' => '_v6');
foreach ($cont_type as $c_type => $vtype) {
- // Determine 'List' details (return array $pfbarr)
- pfb_determine_list_detail($continent_config['action'], "{$pfb_alias}{$vtype}", $cc_name, "0");
- $pfb['skip'] = $pfbarr['skip'];
- $pfb_descr = $pfbarr['descr'];
+ // Determine 'list' details (return array $pfbarr)
+ pfb_determine_list_detail($continent_config['action'], "{$pfb_alias}{$vtype}", $cc_name, '0');
+ $pfbadv = $pfbarr['adv'];
+ $pfbdescr = $pfbarr['descr'];
$pfbfolder = $pfbarr['folder'];
- $log_tab = $pfbarr['logtab'];
+ $pfborig = $pfbarr['orig'];
+ $logtab = $pfbarr['logtab'];
$aports = $pfbarr['aports'];
$adest = $pfbarr['adest'];
$aproto = $pfbarr['aproto'];
- $continent = "";
- if ($continent_config[$c_type] != "") {
+ $continent_ex = array(); // An array of existing Continent IPs
+ $continent = array(); // An array of updated Continent IPs
+
+ if (!empty($continent_config[$c_type])) {
+ $ccfile = "{$pfb_alias}{$vtype}";
- // 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');
+ // Collect selected ISO Country ISOs
+ foreach (explode(',', $continent_config[$c_type]) as $iso) {
+ $isofile = "{$pfb['ccdir']}/{$iso}{$vtype}.txt";
+
+ if (!empty($iso) && file_exists("{$isofile}")) {
+ $cc_iso = file("{$isofile}", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ $continent = array_merge($continent, $cc_iso);
}
}
- if (file_exists($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig')) {
- $continent_existing = preg_replace('/\s/', '', file ($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig'));
+ // Collect existing Continent data
+ if (file_exists("{$pfborig}/{$ccfile}.orig")) {
+ $continent_ex = file("{$pfborig}/{$ccfile}.orig", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
}
- // 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)
+
+ // Check if pfBlockerNG pfctl Continent tables are empty (pfBlockerNG was disabled w/ "keep", then re-enabled)
+ $pfctlck = exec("{$pfb['pfctl']} -vvsTables | {$pfb['grep']} -A1 {$pfb_alias}{$vtype} | {$pfb['awk']} '/Addresses/ {s+=$2}; END {print s}'");
+
+ if (empty($pfctlck) && file_exists("{$pfbfolder}/{$ccfile}.txt")) {
+ @copy("{$pfbfolder}/{$ccfile}.txt", "{$pfb['aliasdir']}/{$ccfile}.txt");
+ // Collect updated alias lists ('Reputation' disabled)
$pfb_alias_lists[] = "{$pfb_alias}{$vtype}";
}
- // Collect Active Alias Lists (Used for pfctl Update when 'Reputation' is enabled).
+ // 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'] == "") {
+ // Compare existing (original file) and new Continent data
+ if ($continent === $continent_ex && !empty($pfctlck) &&
+ file_exists("{$pfbfolder}/{$ccfile}.txt") && $pfb['reuse'] == '') {
if (!$pfb['save']) {
- $log = "\n[ {$pfb_alias}{$vtype} ]{$log_tab} exists, Reloading File [ NOW ]";
- pfb_logger("{$log}","1");
+ $log = "\n[ {$pfb_alias}{$vtype} ]{$logtab} exists, Reloading [ NOW ]";
+ pfb_logger("{$log}", 1);
}
} else {
- // Do not proceed with Changes on User 'Save'
+ // 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");
+ $log = "\n[ {$pfb_alias}{$vtype} ]{$logtab} Changes found... Updating\n";
+ pfb_logger("{$log}", 1);
- // Test to Skip d-dup and p-dup functions when changes are found.
- $pfb['dupcheck'] = TRUE;
+ // Execute Reputation functions, when changes are found.
+ $pfb['repcheck'] = TRUE;
+ // Collect updated alias lists ('Reputation' disabled)
$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);
+ if (!empty($continent)) {
+ $cont_string = '';
+ foreach ($continent as $ccline) {
+ $cont_string .= "{$ccline}\n";
+ }
+
+ // Save Continent data
+ @file_put_contents("{$pfborig}/{$ccfile}.orig", rtrim($cont_string, "\n"), LOCK_EX);
+ @copy("{$pfborig}/{$ccfile}.orig", "{$pfbfolder}/{$ccfile}.txt");
+
+ // Call Aggregate process
+ if ($pfb['agg'] == 'on' && $vtype == '_v4') {
+ exec("{$pfb['script']} cidr_aggregate {$ccfile} {$pfbfolder} {$elog}");
+ }
+
+ // Call Duplication process
+ if ($pfb['dup'] == 'on' && $vtype == '_v4' && $pfbadv) {
+ exec("{$pfb['script']} continent {$ccfile} {$elog}");
+ }
+
+ // Save Continent data to aliastable folder
+ @copy("{$pfbfolder}/{$ccfile}.txt", "{$pfb['aliasdir']}/{$ccfile}.txt");
}
- // Check if File Exists and is > 0 in Size and Save alias file
- $file_chk = "0";
- $cont_chk = "{$pfbfolder}/{$pfb_alias}{$vtype}.txt";
+ // Check if file exists and is > 0 in size and save alias file
+ $file_chk = 0;
+ $cont_chk = "{$pfbfolder}/{$ccfile}.txt";
if (file_exists($cont_chk) && @filesize($cont_chk) > 0) {
- $file_chk = exec ("/usr/bin/grep -cv '^#\|^$' {$cont_chk}");
+ $file_chk = exec("{$pfb['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_chk <= 1) {
+ @file_put_contents("{$pfbfolder}/{$ccfile}.txt", "1.1.1.1\n", LOCK_EX);
+ @copy("{$pfbfolder}/{$ccfile}.txt", "{$pfb['aliasdir']}/{$ccfile}.txt");
+ $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')) {
+ if (file_exists("{$pfbfolder}/{$ccfile}.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"
+ $new_aliases[] = array( 'name' => "{$pfb_alias}{$vtype}",
+ 'url' => "{$pfb['weblocal']}?pfb={$pfb_alias}{$vtype}",
+ 'updatefreq' => '32',
+ 'address' => '',
+ 'descr' => "pfBlockerNG {$vtype} {$pfbdescr} 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}");
- if (!empty($adest) && !empty($aports)) {
- $rule['destination'] = array("address" => "{$adest}", "port" => "{$aports}");
- } elseif (!empty($adest) && empty($aports)) {
- $rule['destination'] = array("address" => "{$adest}");
- } elseif (empty($adest) && !empty($aports)) {
- $rule['destination'] = array("any" => "", "port" => "{$aports}");
- } else {
- $rule['destination'] = array("any" => "");
- }
- if (!empty($adest) && $continent_config['autonot'] == "on")
- $rule['destination']['not'] = "";
- if (!empty($aproto))
- $rule['protocol'] = "{$aproto}";
- 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}");
- if (!empty($adest) && !empty($aports)) {
- $rule['destination'] = array("address" => "{$adest}", "port" => "{$aports}");
- } elseif (!empty($adest) && empty($aports)) {
- $rule['destination'] = array("address" => "{$adest}");
- } elseif (empty($adest) && !empty($aports)) {
- $rule['destination'] = array("any" => "", "port" => "{$aports}");
- } else {
- $rule['destination'] = array("any" => "");
- }
- if (!empty($adest) && $continent_config['autonot'] == "on")
- $rule['destination']['not'] = "";
- if (!empty($aproto))
- $rule['protocol'] = "{$aproto}";
- 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}");
- if (!empty($adest) && !empty($aports)) {
- $rule['destination'] = array("address" => "{$adest}", "port" => "{$aports}");
- } elseif (!empty($adest) && empty($aports)) {
- $rule['destination'] = array("address" => "{$adest}");
- } elseif (empty($adest) && !empty($aports)) {
- $rule['destination'] = array("any" => "", "port" => "{$aports}");
- } else {
- $rule['destination'] = array("any" => "");
- }
- if (!empty($adest) && $continent_config['autonot'] == "on")
- $rule['destination']['not'] = "";
- if (!empty($aproto))
- $rule['protocol'] = "{$aproto}";
- 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');
+ // Define firewall rule settings
+ pfb_firewall_rule($continent_config['action'], $pfb_alias, $vtype, $continent_config['aliaslog'],
+ $adest, $aports, $aproto, $continent_config['autonot']);
+ }
+ else {
+ // unlink Continent list
+ unlink_if_exists("{$pfb['aliasdir']}/{$ccfile}.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);
+ // Unset variables
+ unset ($continent, $continent_ex);
#################################################
# Download and Collect IPv4/IPv6 lists #
@@ -1428,511 +3217,406 @@ function sync_package_pfblockerng($cron = "") {
// IPv4 REGEX Definitions
$pfb['range'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))-((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))/';
- $pfb['block'] = '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[ 0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.([0]{1})\s+/';
- $pfb['cidr'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/([0-9]{2}|[0-9]{1})/';
- $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] = '/\/32/'; // Remove any /32 CIDR
- $pfb_ipreg[3] = '/127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/'; // Remove any Loopback Addresses 127/8
- $pfb_ipreg[4] = '/0\.0\.0\.0/'; // Remove 0.0.0.0
-
- // IPv6 REGEX Definitions -- ** Still Needs some Adjustment on Regex Definition for IPv6 **
- // https://mebsd.com/coding-snipits/php-regex-ipv6-with-preg_match.html
- $pattern1 = '([A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}';
- $pattern2 = '[A-Fa-f0-9]{1,4}::([A-Fa-f0-9]{1,4}:){0,5}[A-Fa-f0-9]{1,4}';
- $pattern3 = '([A-Fa-f0-9]{1,4}:){2}:([A-Fa-f0-9]{1,4}:){0,4}[A-Fa-f0-9]{1,4}';
- $pattern4 = '([A-Fa-f0-9]{1,4}:){3}:([A-Fa-f0-9]{1,4}:){0,3}[A-Fa-f0-9]{1,4}';
- $pattern5 = '([A-Fa-f0-9]{1,4}:){4}:([A-Fa-f0-9]{1,4}:){0,2}[A-Fa-f0-9]{1,4}';
- $pattern6 = '([A-Fa-f0-9]{1,4}:){5}:([A-Fa-f0-9]{1,4}:){0,1}[A-Fa-f0-9]{1,4}';
- $pattern7 = '([A-Fa-f0-9]{1,4}:){6}:[A-Fa-f0-9]{1,4}';
- $pattern8 = '[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}:[A-Fa-f0-9]{1,4}::\/[0-9]{2}';
- $pattern9 = '[A-Fa-f0-9]{1,4}:([A-Fa-f0-9]{1,4}::)\/[0-9]{2}';
- $pattern10 = '[A-Fa-f0-9]{1,4}::\/[0-9]{2}';
- $pfb['ipv6'] = "/($pattern1)|($pattern2)|($pattern3)|($pattern4)|($pattern5)|($pattern6)|($pattern7)|($pattern8)|($pattern9)|($pattern10)/";
-
- $pfb['supp_update'] = FALSE;
- $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
- foreach ($list_type as $ip_type => $vtype) {
- if ($config['installedpackages'][$ip_type]['config'] != "") {
- foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
- if ($list['action'] != "Disabled" && $pfb['enable'] == "on" && !$pfb['save'] && is_array($list['row'])) {
- // capture Alias Name
- $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']);
- foreach ($list['row'] as $row) {
- if ($row['url'] != "" && $row['state'] != "Disabled") {
-
- if ($vtype == "_v4") {
- $header_url = "{$row['header']}";
- } else {
- $header_url = "{$row['header']}_v6";
- }
+ $pfb['ipv4'] = '/(?:(?: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]?)(\/(3[012]|[12]?[0-9]))?/';
- // Determine 'List' details (return array $pfbarr)
- pfb_determine_list_detail($list['action'], $header_url, "", "");
- $pfb['skip'] = $pfbarr['skip'];
- $pfbfolder = $pfbarr['folder'];
- $log_tab = $pfbarr['logtab'];
+ // IPv6 REGEX Definitions - Reference: http://labs.spritelink.net/regex
+ $pfb['ipv6'] = '/((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?(\/[0-9][0-9]?|1([01][0-9]|2[0-8]))?/';
- // Empty Header Field Validation Check
- if (empty($header_url) || preg_match("/\W/",$header_url)) {
- $log = "\n [ {$row['url']} ]\n ** TERMINATED - Header contains Blank/International/Special or Spaces\n";
- pfb_logger("{$log}","2");
- continue;
- }
+ if ($pfb['enable'] == 'on' && !$pfb['save']) {
- // Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled.
- $pfb_alias_lists_all[] = "{$alias}";
+ $pfb['supp_update'] = FALSE;
+ $runonce_v4 = $runonce_v6 = TRUE;
+ $list_type = array('pfblockernglistsv4' => '_v4', 'pfblockernglistsv6' => '_v6');
+ $lists = array();
- if (file_exists($pfbfolder . '/' . $header_url . '.txt') && $pfb['reuse'] == "") {
- if ($row['state'] == "Hold") {
- $log = "\n[ {$header_url} ]{$log_tab} Static Hold [ NOW ]";
- } else {
- $log = "\n[ {$header_url} ]{$log_tab} exists, Reloading File [ NOW ]";
- }
- pfb_logger("{$log}","1");
+ // Collect lists and custom list configuration and format into one array ($lists).
+ foreach ($list_type as $ip_type => $vtype) {
+ if (!empty($config['installedpackages'][$ip_type]['config'])) {
+ foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
+ if ($vtype == '_v4') {
+ $list['vtype'] = '_v4';
+ } else {
+ $list['vtype'] = '_v6';
+ }
+
+ // If only the 'customlist' is defined. Remove the 'List row' data.
+ if (empty($list['row'][0]['url'])) {
+ unset($list['row']);
+ }
+
+ if (!empty($list['custom'])) {
+ $list['row'][] = array( 'header' => "{$list['aliasname']}_custom",
+ 'custom' => $list['custom'],
+ 'state' => 'Enabled',
+ 'update' => $list['custom_update'],
+ 'url' => 'custom'
+ );
+ }
+ $lists[] = $list;
+ }
+ }
+ }
+
+ foreach ($lists as $list) {
+ if ($runonce_v4 && $list['vtype'] == '_v4') {
+ $runonce_v4 = FALSE;
+ $log = "\n\n===[ IPv4 Process ]=================================================\n";
+ pfb_logger("{$log}", 1);
+ } elseif ($runonce_v6 && $list['vtype'] == '_v6') {
+ $runonce_v6 = FALSE;
+ $log = "\n\n===[ IPv6 Process ]=================================================\n";
+ pfb_logger("{$log}", 1);
+ }
+
+ if ($list['action'] != 'Disabled' && isset($list['row'])) {
+ // Capture alias name
+ $alias = 'pfB_' . preg_replace("/\W/", '', $list['aliasname']);
+ foreach ($list['row'] as $row) {
+ if (!empty($row['url']) && $row['state'] != 'Disabled') {
+
+ if ($list['vtype'] == '_v4') {
+ $header = "{$row['header']}";
+ } else {
+ $header = "{$row['header']}_v6";
+ }
+
+ // If row is a custom_list, set flag.
+ if (isset($row['custom'])) {
+ $custom = TRUE;
+ } else {
+ $custom = FALSE;
+ }
+
+ // Determine 'list' details (return array $pfbarr)
+ pfb_determine_list_detail($list['action'], $header, '', '');
+ $pfbadv = $pfbarr['adv'];
+ $pfbfolder = $pfbarr['folder'];
+ $pfborig = $pfbarr['orig'];
+ $pfbreuse = $pfbarr['reuse'];
+ $logtab = $pfbarr['logtab'];
+
+ // Collect active alias list (Used for pfctl update when 'Reputation' is enabled.
+ $pfb_alias_lists_all[] = "{$alias}";
+
+ if (file_exists("{$pfbfolder}/{$header}.txt") && $pfbreuse == '') {
+ if ($row['state'] == 'Hold') {
+ $log = "\n[ {$header} ]{$logtab} Static Hold [ NOW ]";
} else {
- if ($pfb['reuse'] == "on" && file_exists($pfb['origdir'] . '/' . $header_url . '.orig')) {
- $log = "\n[ {$header_url} ]{$log_tab} Using Previously Downloaded File [ NOW ]";
- } else {
- $log = "\n[ {$header_url} ]{$log_tab} Downloading New File [ NOW ]";
- }
- pfb_logger("{$log}","1");
-
- $list_url = "{$row['url']}";
- if (!$pfb['reuse'] == "on") {
- // Perform Remote URL Date/Time Stamp checks
- $host = @parse_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);
- }
- }
- }
+ $log = "\n[ {$header} ]{$logtab} exists, Reloading [ NOW ]";
+ }
+ pfb_logger("{$log}", 1);
+ } else {
+ if ($pfbreuse == 'on' && file_exists("{$pfborig}/{$header}.orig")) {
+ $log = "\n[ {$header} ]{$logtab} Reload [ NOW ]";
+ } else {
+ $log = "\n[ {$header} ]{$logtab} Downloading update [ NOW ]";
+ }
+ pfb_logger("{$log}", 1);
+ $file_dwn = "{$pfborig}/{$header}";
- $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);
+ if (!$custom) {
+ pfb_logger(' .', 1);
+
+ // Allow cURL SSL downgrade 'Flex' if user configured.
+ $pflex = FALSE;
+ if ($row['state'] == 'Flex') {
+ $pflex = TRUE;
}
- // 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);
+ // Determine if list needs to be downloaded or reuse previously downloaded file.
+ if ($pfbreuse == 'on' && file_exists("{$file_dwn}.orig")) {
+ // File exists/reuse
+
+ // Process Emerging Threats IQRisk if required
+ if (strpos($row['url'], 'iprepdata.txt') !== FALSE) {
+ exec("{$pfb['script']} et {$header} x x x x x {$pfb['etblock']} {$pfb['etmatch']} {$elog}");
}
- $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig');
- }
+ } else {
+ // Download list
+ if (!pfb_download($row['url'], $file_dwn, $pflex, $header, $row['format'],
+ 1, $list['vtype'])) {
- 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");
+ // Determine reason for download failure
+ pfb_download_failure($alias, $header, $pfbfolder, $list['vtype'], $row['url']);
+
+ // Utilize previously download file (If 'fail' marker exists)
+ if (file_exists("{$pfbfolder}/{$header}.fail") &&
+ file_exists("{$file_dwn}.orig")) {
+ pfb_logger("\n Restoring previously downloaded file contents ", 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);
+ if ($pfbadv) {
+ // Script to Remove failed lists from masterfile
+ exec("{$pfb['script']} remove x x x {$header} {$elog}");
+ }
+ continue;
}
- }
- $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);
+ // Clear any previous download fail marker
+ unlink_if_exists("{$pfbfolder}/{$header}.fail");
+ pfb_logger('.', 1);
}
- 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');
}
+ pfb_logger(' completed .', 1);
+ }
+ else {
+ if ($list['whois_convert'] == 'on') {
+ // Process Domain/AS based custom list
+ $custom_list = str_replace("\n", ',', pfbng_text_area_decode($list['custom']));
+ exec("{$pfb['script']} whoisconvert {$header} {$list['vtype']} {$custom_list} {$elog}");
+ } else {
+ // Process IP based custom list
+ $custom_list = pfbng_text_area_decode($list['custom']);
+ @file_put_contents("{$file_dwn}.orig", $custom_list, LOCK_EX);
+ }
+ pfb_logger(' . completed .', 1);
+ }
- 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');
+ $ip_data = ''; // IPs collected from feed
+ $parse_fail = 0; // Failed parsed lines from feed
+ pfb_logger('.', 1);
+
+ // Set 'auto' format for all lists, except for lists that require 'regex' parsing.
+ if ($row['format'] == 'regex') {
+ $pftype = 'regex';
+ }
+ else {
+ $url = pathinfo($row['url']);
+
+ // Strip any text after '?'
+ if (strpos($url['extension'], '?') !== FALSE) {
+ $url['extension'] = strstr($url['extension'], '?', TRUE);
}
- 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);
- }
+ // Determine if list is an IBlock list
+ if (strpos($url['dirname'], 'iblocklist') !== FALSE) {
+ $url['extension'] = 'iblock';
}
- 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);
+ // Use 'regex' IP parser for non-standard IP lists.
+ if (in_array($url['extension'], array('html', 'htm', 'php', 'aspx', 'cgi', 'csv', 'rules', ''))) {
+ $pftype = 'regex';
+ } else {
+ $pftype = 'auto';
}
+ }
- 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}");
+ if (($fhandle = fopen("{$file_dwn}.orig", 'r')) !== FALSE) {
+ while (($line = fgets($fhandle, 1024)) !== FALSE) {
+
+ // Record original line for regex matching, if required.
+ $oline = $line;
+
+ // Remove any leading/trailing whitespaces
+ $line = trim($line);
+
+ // Remove commentlines and blank lines
+ if (substr($line, 0, 1) == '#' || empty($line)) {
+ continue;
}
- $url_list = @file($file_dwn);
- }
- // extract range lists
- $new_file = "";
- if (!empty($url_list)) {
- if ($row['format'] == "gz" && $vtype == "_v4") {
- foreach ($url_list as $line) {
- if (!preg_match("/^#/", $line)) {
- // Network range 192.168.0.0-192.168.0.254
- if (preg_match($pfb['range'],$line,$matches)) {
- $a_cidr = ip_range_to_subnet_array_temp2($matches[1],$matches[2]);
- if (!empty($a_cidr)) {
- foreach ($a_cidr as $cidr) {
- $new_file .= preg_replace($pfb_ipreg,'',$cidr) . "\n";
+ $parse_error = FALSE;
+ if ($list['vtype'] == '_v4' && $pftype == 'auto') {
+
+ // IBlock - parser sample ( JKS Media, LLC:4.53.2.12-4.53.2.15 )
+ // Remove leading domain name details
+ if (strpos($line, '-') !== FALSE && strpos($line, ':') !== FALSE) {
+ $line = str_replace(':', '', strstr($line, ':', FALSE));
+ }
+
+ // If 'space' character found, remove characters after space
+ if (strpos($line, ' ') !== FALSE) {
+ $line = strstr($line, ' ', TRUE);
+ }
+
+ // If '#' character found, remove characters after '#'
+ if (strpos($line, '#') !== FALSE) {
+ $line = str_replace('#', '', strstr($line, '#', TRUE));
+ }
+
+ // Remove any leading/trailing whitespaces
+ $line = trim($line);
+
+ // Range parser
+ if (strpos($line, '-') !== FALSE) {
+ $matches = explode('-', $line);
+ if (count($matches) == 2) {
+ $a_cidr = ip_range_to_subnet_array_temp($matches[0],$matches[1]);
+ if (!empty($a_cidr)) {
+ foreach ($a_cidr as $cidr) {
+ $cidr = sanitize_ipaddr($cidr, $custom);
+ if (!empty($cidr)) {
+ if (validate_ipv4($cidr)) {
+ $ip_data .= $cidr . "\n";
+ }
+ else {
+ $parse_error = TRUE;
+ }
}
}
+ if (!$parse_error) {
+ continue;
+ }
}
}
+ else {
+ $parse_error = TRUE;
+ }
}
- }
- elseif ($row['format'] == "block" && $vtype == "_v4") {
- foreach ($url_list as $line) {
- if (!preg_match("/^#/", $line)) {
- // Block Type '218.77.79.0 218.77.79.255 24'
- if (preg_match($pfb['block'],$line,$matches)) {
- $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "/24\n";
- }
+ if (!$parse_error) {
+ // Single address parser
+ $parsed = sanitize_ipaddr($line, $custom);
+ if (validate_ipv4($parsed)) {
+ $ip_data .= $parsed . "\n";
+ continue;
+ }
+ else {
+ $parse_error = TRUE;
}
}
}
- elseif ($row['format'] == "html" && $vtype == "_v4") {
- foreach ($url_list as $line) {
- if (!preg_match("/^#/", $line)) {
- // CIDR format 192.168.0.0/16
- if (preg_match($pfb['cidr'],$line,$matches)) {
- $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
- }
- // Single ip addresses
- elseif (preg_match($pfb['s_html'],$line,$matches)) {
- $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ if ($list['vtype'] == '_v4' && ($pftype == 'regex' || $parse_error)) {
+
+ // Use regex as last alternative.
+
+ if (strpos($oline, '-') !== FALSE) {
+ // Network range 192.168.0.0-192.168.0.254
+ if (preg_match($pfb['range'], $oline, $matches)) {
+ $a_cidr = ip_range_to_subnet_array_temp($matches[1], $matches[2]);
+ if (!empty($a_cidr)) {
+ foreach ($a_cidr as $cidr) {
+ $cidr = sanitize_ipaddr($cidr, $custom);
+ if (validate_ipv4($cidr)) {
+ $ip_data .= $cidr . "\n";
+ }
+ else {
+ $parse_fail++;
+ }
+ }
}
+ continue;
}
}
- }
-
- elseif ($vtype == "_v6") {
- foreach ($url_list as $line) {
- if (!preg_match("/^#/", $line)) {
- // IPv6 Regex Match
- if (preg_match($pfb['ipv6'],$line,$matches)) {
- $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+
+ // IPv4/CIDR format 192.168.0.0 | 192.168.0.0/16
+ if (preg_match_all($pfb['ipv4'], $oline, $matches)) {
+ $matches = array_unique($matches[0]);
+ foreach ($matches as $match) {
+ $parsed = sanitize_ipaddr($match, $custom);
+ if (validate_ipv4($parsed)) {
+ $ip_data .= $parsed . "\n";
}
}
+ continue;
}
}
- else {
- foreach ($url_list as $line) {
- if (!preg_match("/^#/", $line)) {
- // Network range 192.168.0.0-192.168.0.254
- if (preg_match($pfb['range'],$line,$matches)) {
- $a_cidr = ip_range_to_subnet_array_temp2($matches[1],$matches[2]);
- if (!empty($a_cidr)) {
- foreach ($a_cidr as $cidr) {
- $new_file .= preg_replace($pfb_ipreg,'',$cidr) . "\n";
- }
- }
+ if ($list['vtype'] == '_v6') {
+ // Auto IPv6 parser
+ if ($pftype == 'auto') {
+ if (strpos($line, ':') !== FALSE) {
+ if (is_ipaddrv6($line) || is_subnet($line)) {
+ $ip_data .= $line . "\n";
+ continue;
}
- // CIDR format 192.168.0.0/16
- elseif (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";
+ }
+ }
+
+ // IPv6 Regex parser
+ if (preg_match_all($pfb['ipv6'], $oline, $matches)) {
+ $matches = array_unique($matches[0]);
+ foreach ($matches as $match) {
+ if (is_ipaddrv6($match) || is_subnet($match)) {
+ $ip_data .= $match . "\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 for parse failures
+ if (!empty($line) && !preg_match('/[a-zA-Z,;|\"\'?]/', $line)) {
+ $parse_fail++;
+ $log = "[!] Parse Errors [ {$parse_fail} ]\n";
+ pfb_logger("{$log}", 2);
}
-
- // 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}");
+ }
+ fclose($fhandle);
+ pfb_logger("\n", 1);
+
+ if (!$custom) {
+ // Check to see if list actually failed download or has no IPs listed.
+ $file_chk = '';
+ if (file_exists("{$file_dwn}.orig") && @filesize("{$file_dwn}.orig") > 0) {
+ $file_chk = exec("{$pfb['grep']} -cv '^#\|^$' {$file_dwn}.orig");
}
- 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 ($file_chk == 0) {
+ $ip_data = "1.1.1.1\n";
+ $log = " Empty file, Adding '1.1.1.1' to avoid download failure.\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 (!empty($ip_data)) {
+ // Save List to '.txt' format in appropriate folder
+ @file_put_contents("{$pfbfolder}/{$header}.txt", "{$ip_data}", 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");
+ // Call 'shell script' functions (Deny Actions only)
+ if ($pfbadv && $list['vtype'] == '_v4') {
+ $args = '';
+ // Call Process255
+ if ($pfb['dup'] == 'on' || $pfb['agg'] == 'on') {
+ $args = '_255';
}
-
- if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") {
- // Script to call Duplication Check Process
- exec ("{$pfb['script']} duplicate {$header_url} >> {$pfb['log']} 2>&1");
+ // Call Aggregate process
+ if ($pfb['agg'] == 'on') {
+ $args .= '_agg';
}
-
- // 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;
+ // Call Reputation Max process
+ if ($pfb['rep'] == 'on') {
+ $args .= '_rep';
}
- // Enable Suppression Process due to Updates
- if ($pfb['supp'] == "on" && $vtype == "_v4") {
- $pfb['supp_update'] = TRUE;
+ // Call Duplication process
+ if ($pfb['dup'] == 'on') {
+ $args .= '_dup';
}
- } 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");
- }
+ if (!empty($args)) {
+ exec("{$pfb['script']} {$args} {$header} {$pfb['max']} {$pfb['drep']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} {$elog}");
}
}
- // 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";
- }
-
- // Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled.
- $pfb_alias_lists_all[] = "{$alias}";
-
- // Determine 'List' details (return array $pfbarr)
- pfb_determine_list_detail($list['action'], $aliascustom, "", "");
- $pfb['skip'] = $pfbarr['skip'];
- $pfbfolder = $pfbarr['folder'];
- $log_tab = $pfbarr['logtab'];
-
- if (file_exists($pfbfolder . '/' . $aliascustom . '.txt') && $pfb['reuse'] == "") {
- $log = "\n[ {$aliascustom} ]{$log_tab} exists, Reloading File [ NOW ]";
- 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") {
- // Network range 192.168.0.0-192.168.0.254
- if (preg_match($pfb['range'],$line,$matches)) {
- $a_cidr = ip_range_to_subnet_array_temp2($matches[1],$matches[2]);
- if (!empty($a_cidr)) {
- foreach ($a_cidr as $cidr) {
- $new_file .= preg_replace($pfb_ipreg, '',$cidr) . "\n";
- }
- }
- }
- // CIDR format 192.168.0.0/16
- elseif (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";
- }
- } else {
- // IPv6 Regex
- if (preg_match($pfb['ipv6'],$line,$matches)) {
- $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
- }
+ if (!$pfbadv && $list['vtype'] == '_v4') {
+ // Call Aggregate process
+ if ($pfb['agg'] == 'on') {
+ exec("{$pfb['script']} cidr_aggregate {$header} {$pfbfolder} {$elog}");
}
}
- }
- if ($new_file != "") {
- // PFCTL - Collect Only Aliases that have been updated only.
+ // Collect updated alias lists ('Reputation' disabled)
$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 ($pfbadv && $list['vtype'] == '_v4') {
+ // Execute Reputation functions, when changes are found.
+ $pfb['repcheck'] = TRUE;
+
+ // Enable suppression process due to updates
+ if ($pfb['supp'] == 'on') {
+ $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");
+ } else {
+ if (!$custom) {
+ $log = "[ {$alias} {$header} ] List Error ]\n";
}
- 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 = "[ {$alias} {$header} ] Custom List Error ]\n";
}
- } else {
- $log = "[ {$aliascustom} ] Custom List Error ]\n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
}
+ // Unset variables
+ unset($ip_data);
}
}
}
@@ -1945,40 +3629,47 @@ function sync_package_pfblockerng($cron = "") {
# 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");
+ // IP Reputation processes (pMax and dMax)
+ if ($pfb['prep'] == 'on' && $pfb['repcheck'] && !$pfb['save'] && $pfb['enable'] == 'on') {
+ // Script to run prep process
+ exec("{$pfb['script']} pmax x {$pfb['pmax']} {$elog}");
}
- 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");
+ if ($pfb['drep'] == 'on' && $pfb['repcheck'] && !$pfb['save'] && $pfb['enable'] == 'on') {
+ // Script to run drep process
+ exec("{$pfb['script']} dmax x {$pfb['dmax']} {$pfb['drep']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} {$elog}");
}
- #################################
- # CONFIGURE ALIASES #
- #################################
+ #################################################
+ # CONFIGURE ALIASES AND FIREWALL RULES #
+ #################################################
- $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ $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;
+ if (!empty($config['installedpackages'][$ip_type]['config']) && $pfb['enable'] == 'on') {
+ $pfbrunonce = TRUE;
foreach ($config['installedpackages'][$ip_type]['config'] as $key => $list) {
- $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']);
+ $alias = 'pfB_' . preg_replace("/\W/", '', $list['aliasname']);
- // Determine 'List' details (return array $pfbarr)
- pfb_determine_list_detail($list['action'], "", $ip_type, $key);
- $pfb['skip'] = $pfbarr['skip'];
- $pfb_descr = $pfbarr['descr'];
+ // Skip any Alias that are 'enabled' but Lists/customlists are not defined.
+ if (empty($list['row'][0]['url']) && empty($list['custom'])) {
+ exec("{$pfb['pfctl']} -t {$alias} -T kill 2>&1", $result);
+ continue;
+ }
+
+ // Determine 'list' details (return array $pfbarr)
+ pfb_determine_list_detail($list['action'], '', $ip_type, $key);
+ $pfbadv = $pfbarr['adv'];
+ $pfbdescr = $pfbarr['descr'];
$pfbfolder = $pfbarr['folder'];
$aports = $pfbarr['aports'];
$adest = $pfbarr['adest'];
$aproto = $pfbarr['aproto'];
- // Re-Save Only Aliases that have been updated only.
- // When 'Reputation' is used, all Aliases need to be Updated.
+
+ // Only Save aliases that have been updated.
+ // When 'Reputation' is used, all aliases need to be updated.
$final_alias = array();
- if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") {
+ if ($pfb['drep'] == 'on' || $pfb['prep'] == 'on') {
if (!empty($pfb_alias_lists_all)) {
$final_alias = array_unique($pfb_alias_lists_all);
}
@@ -1988,331 +3679,212 @@ function sync_package_pfblockerng($cron = "") {
}
}
- if ($list['action'] != "Disabled") {
- // remove empty lists files if any
- if (is_array($list['row'])) {
- $update = 0;
- ${$alias} = "";
+ if ($list['action'] != 'Disabled') {
+ $pfbupdate = FALSE;
+ $alias_ips = ''; // IP Collection of all Lists in the Alias
+
+ if (isset($list['row'])) {
foreach ($list['row'] as $row) {
- if ($row['url'] != "" && $row['state'] != "Disabled") {
- if ($vtype == "_v4") {
- $header_url = "{$row['header']}";
+ if (!empty($row['url']) && $row['state'] != 'Disabled') {
+ if ($vtype == '_v4') {
+ $header = "{$row['header']}";
} else {
- $header_url = "{$row['header']}_v6";
+ $header = "{$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++;
+ $pfctlck = exec("{$pfb['pfctl']} -vvsTables | {$pfb['grep']} -A1 {$alias} | {$pfb['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}.txt") && (in_array($alias, $final_alias) || empty($pfctlck))) {
+ // Script to run suppression process (print header only)
+ if ($pfbrunonce && $pfb['supp'] == 'on' && $vtype == '_v4' && $pfb['supp_update']) {
+ exec("{$pfb['script']} suppress x x x suppressheader {$elog}");
+
+ // Process suppression for DNSBL IP table
+ if ($pfb['dnsbl'] == 'on' && $pfb['dnsbl_ip'] != 'Disabled') {
+ exec("{$pfb['script']} suppress x x x pfB_DNSBLIP\|{$pfb['aliasdir']}/ {$elog}");
+ }
+ $pfbrunonce = FALSE;
}
- // 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");
+ // Script to run suppression process (body)
+ if ($pfb['supp'] == 'on' && $vtype == '_v4' && $pfb['supp_update'] && $pfbadv) {
+ if ($pfb['dup'] == 'on') {
+ exec("{$pfb['script']} suppress x x x {$header}\|{$pfbfolder}/ {$elog}");
} else {
- // Execute if Duplication Process is Disabled
- exec ("{$pfb['script']} suppress x x off {$header_url}\|{$pfbfolder}/ >> {$pfb['log']} 2>&1");
+ exec("{$pfb['script']} suppress x x off {$header}\|{$pfbfolder}/ {$elog}");
}
}
- ${$alias} .= file_get_contents($pfbfolder . '/' . $header_url . '.txt');
- $update++;
+ $alias_ips .= file_get_contents("{$pfbfolder}/{$header}.txt");
+ $pfbupdate = TRUE;
}
}
}
}
// check custom network list
- if ($vtype == "_v4") {
+ 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}'");
+ // Update alias if list file exists and its been updated or if the alias URL table is empty.
+ $pfctlck = exec("{$pfb['pfctl']} -vvsTables | {$pfb['grep']} -A1 {$alias} | {$pfb['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++;
+ if (!empty($list['custom'])) {
+ if (file_exists("{$pfbfolder}/{$aliasname}.txt") && in_array($alias, $final_alias) ||
+ file_exists("{$pfbfolder}/{$aliasname}.txt") && empty($pfctlck)) {
+ $alias_ips .= file_get_contents("{$pfbfolder}/{$aliasname}.txt");
+ $pfbupdate = TRUE;
}
}
- // 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');
+ // Determine validity of alias URL tables/rules. ie: Don't create empty URL tables or aliases
+ if (empty($alias_ips) && 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);
+ // Save only aliases that have been updated.
+ if ($pfbupdate) {
+ @file_put_contents("{$pfb['aliasdir']}/{$alias}.txt", $alias_ips, LOCK_EX);
}
- $alias_log = $list['aliaslog'];
- // create alias
- $new_aliases_list[] = "{$alias}";
+ // Add '[s]' to Alias descriptions (Bypass States removal feature)
+ $adescr = "pfBlockerNG {$pfbdescr} List Alias";
+ if ($list['stateremoval'] == 'disabled') {
+ $adescr = "pfBlockerNG {$pfbdescr} List Alias [s]";
+ }
- $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 alias
+ $new_aliases_list[] = "{$alias}";
+ $new_aliases[] = array( 'name' => "{$alias}",
+ 'url' => "{$pfb['weblocal']}?pfb={$alias}",
+ 'updatefreq' => '32',
+ 'address' => '',
+ 'descr' => "{$adescr}",
+ '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}");
- if (!empty($adest) && !empty($aports)) {
- $rule['destination'] = array ("address" => "{$adest}", "port" => "{$aports}");
- } elseif (!empty($adest) && empty($aports)) {
- $rule['destination'] = array ("address" => "{$adest}");
- } elseif (empty($adest) && !empty($aports)) {
- $rule['destination'] = array ("any" => "", "port" => "{$aports}");
- } else {
- $rule['destination'] = array ("any" => "");
- }
- if (!empty($adest) && $list['autonot'] == "on")
- $rule['destination']['not'] = "";
- if (!empty($aproto))
- $rule['protocol'] = "{$aproto}";
- 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}");
- if (!empty($adest) && !empty($aports)) {
- $rule['destination'] = array ("address" => "{$adest}", "port" => "{$aports}");
- } elseif (!empty($adest) && empty($aports)) {
- $rule['destination'] = array ("address" => "{$adest}");
- } elseif (empty($adest) && !empty($aports)) {
- $rule['destination'] = array ("any" => "", "port" => "{$aports}");
- } else {
- $rule['destination'] = array ("any" => "");
- }
- if (!empty($adest) && $list['autonot'] == "on")
- $rule['destination']['not'] = "";
- if (!empty($aproto))
- $rule['protocol'] = "{$aproto}";
- 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}");
- if (!empty($adest) && !empty($aports)) {
- $rule['destination'] = array ("address" => "{$adest}", "port" => "{$aports}");
- } elseif (!empty($adest) && empty($aports)) {
- $rule['destination'] = array ("address" => "{$adest}");
- } elseif (empty($adest) && !empty($aports)) {
- $rule['destination'] = array ("any" => "", "port" => "{$aports}");
- } else {
- $rule['destination'] = array ("any" => "");
- }
- if (!empty($adest) && $list['autonot'] == "on")
- $rule['destination']['not'] = "";
- if (!empty($aproto))
- $rule['protocol'] = "{$aproto}";
- 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}";
+ // Define firewall rule settings
+ pfb_firewall_rule($list['action'], $alias, '', $list['aliaslog'], $adest, $aports, $aproto, $list['autonot']);
}
} else {
- // unlink previous pfblockerNG alias list if any
- unlink_if_exists($pfb['aliasdir'] . '/' . $alias . '.txt');
+ // unlink previous pfblockerNG alias list
+ unlink_if_exists("{$pfb['aliasdir']}/{$alias}.txt");
}
}
}
}
- // Clear Variables
- ${$alias} = "";
+ // Clear variables
+ $alias_ips = '';
#########################################
# UPDATE pfSense ALIAS TABLES #
#########################################
- // update pfsense alias table
- if (is_array($config['aliases']['alias'])) {
+ // Reload config.xml to get any recent changes
+ $config = parse_config(true);
+
+ $exist_aliases = $config['aliases']['alias'];
+ if (isset($config['aliases']['alias'])) {
foreach ($config['aliases']['alias'] as $cbalias) {
+
+ // Skip DNSBL IP aliastable as its updated independently
+ if ($cbalias['name'] == 'pfB_DNSBLIP') {
+ continue;
+ }
+
if (substr($cbalias['name'], 0, 4) == 'pfB_') {
- // 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
+ // Remove unreferenced pfB aliastable files
if (!in_array($cbalias['name'], $new_aliases_list)) {
- unlink_if_exists($pfb['aliasdir'] . '/' . $cbalias['name'] . ".txt");
+ unlink_if_exists("{$pfb['aliasdir']}/{$cbalias['name']}.*");
}
} 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 == "") {
+ // Update config.xml, if changes required
+ if ($exist_aliases != $new_aliases) {
$config['aliases']['alias'] = $new_aliases;
- $pfb['cron_mod'] = TRUE;
+ write_config('pfBlockerNG: saving Aliases');
}
- // UNSET Variables
- unset($new_aliases, $cbalias);
+ // Unset variables
+ unset($new_aliases, $exist_aliases);
#########################
# 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.";
+ // Only execute if autorules are defined or if an alias has been removed.
+ if ($pfb['autorules'] || $pfb['enable'] == '' || $pfb['remove']) {
+ $message = '';
+ if (count($pfb['deny_inbound']) > 0 || count($pfb['permit_inbound']) > 0 || count($pfb['match_inbound']) > 0) {
+ if (empty($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 (count($pfb['deny_outbound']) > 0 || count($pfb['permit_outbound']) > 0 || count($pfb['match_outbound']) > 0) {
+ if (empty($pfb['outbound_interfaces'])) {
+ $message .= "\n 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();
+ if (empty($message)) {
+ $new_rules = $permit_rules = $match_rules = $other_rules = $fpermit_rules = $fmatch_rules = $fother_rules = array();
+
+ // Reload config.xml to get any recent changes
+ $config = parse_config(true);
- // Collect All Existing Rules
+ // New vs old rules array comparison
+ $orig_rules_nocreated = $new_rules_nocreated = array();
+
+ // Collect all existing rules
$rules = $config['filter']['rule'];
- // Collect Existing pfSense Rules 'Pass', 'Match' and 'Other' pfSense rules into new Arrays.
+
+ // 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") {
+ foreach ($rules as $key => $rule) {
+ // Remove DNSBL floating rule
+ if ($rule['descr'] == 'pfB_DNSBL_Allow_access_to_VIP') {
+ // Remove 'created' tag
+ $orig_rules_nocreated[] = $rule;
+ unset($orig_rules_nocreated[$key]['created']);
+ continue;
+ }
+
+ // Remove all exisiting rules that start with 'pfB_' in the Rule Description
+ if (substr($rule['descr'], 0, 4) != 'pfB_') {
+ // 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") {
+ } elseif ($rule['type'] == 'match' && $rule['floating'] == 'yes') {
$fmatch_rules[] = $rule;
- } elseif ($rule['floating'] == "yes") {
+ } 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") {
+ // 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', pass, balance to 'other'
+ if ($rule['floating'] == 'yes') {
$fother_rules[] = $rule;
- } elseif ($rule['type'] == "pass") {
- if ($pfb['order'] == "order_0") {
+ } 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") {
+ if ($rule['floating'] == 'yes') {
$fother_rules[] = $rule;
} else {
$other_rules[] = $rule;
@@ -2320,6 +3892,10 @@ function sync_package_pfblockerng($cron = "") {
}
}
}
+
+ // Remove 'created' tag
+ $orig_rules_nocreated[] = $rule;
+ unset($orig_rules_nocreated[$key]['created']);
}
}
@@ -2331,78 +3907,90 @@ function sync_package_pfblockerng($cron = "") {
# ORDER 3 - pfBlockerNG (p/m) / pfBlockerNG Block/Reject / pfSense (p/m) #
#################################################################################
- if ($pfb['float'] == "") {
+ 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;
+ else {
+ if ($pfb['order'] == 'order_1') {
+ foreach (array($fpermit_rules, $fmatch_rules, $fother_rules) as $rtype) {
+ if (!empty($rtype)) {
+ foreach ($rtype 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 DNSBL 'Floating' pass rule for selected 'OPT' segments to be able to access the LAN DNSBL VIP
+ if ($pfb['enable'] == 'on' && $pfb['dnsbl'] == 'on' && $pfb['dnsbl_rule'] != 'Disabled' && !empty($pfb['dnsblconfig']['dnsbl_allow_int'])) {
+ if (isset($implode_interfaces) && isset($pfb['dnsbl_vip'])) {
+ $rule = $pfb['base_rule_float'];
+ $rule['tracker'] = pfb_tracker('pfB_DNSBL_Allow_access_to_VIP');
+ $rule['type'] = 'pass';
+ $rule['direction'] = 'any';
+ $rule['interface'] = $implode_interfaces;
+ $rule['descr'] = 'pfB_DNSBL_Allow_access_to_VIP';
+ $rule['source'] = array('any' => '');
+ $rule['destination'] = array('address' => "{$pfb['dnsbl_vip']}");
+ $rule['created'] = array('time' => (int)microtime(true), 'username' => 'Auto');
+ $new_rules[] = $rule;
}
}
- // Define Inbound Interface Rules
+ // Define inbound interface rules
if (!empty($pfb['inbound_interfaces'])) {
- $counter = 0;
+ $pfbrunonce = TRUE;
foreach ($pfb['inbound_interfaces'] as $inbound_interface) {
- if (!empty($permit_rules) && $pfb['order'] == "order_1") {
+ if ($pfb['order'] == 'order_1' && !empty($permit_rules)) {
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)
+ 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) {
+ // Match inbound rules defined as floating only.
+ if ($pfbrunonce && !empty($pfb['match_inbound'])) {
+ foreach ($pfb['match_inbound'] as $cb_rules) {
$cb_rules['interface'] = $pfb['inbound_floating'];
$new_rules[] = $cb_rules;
- $counter ++;
+ $pfbrunonce = FALSE;
}
}
- if (!empty($permit_inbound)) {
- foreach ($permit_inbound as $cb_rules) {
+ if ($pfb['order'] != 'order_0' && !empty($pfb['permit_inbound'])) {
+ foreach ($pfb['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 ($pfb['order'] == 'order_2') {
+ foreach (array($fpermit_rules, $fmatch_rules) as $rtype) {
+ if (!empty($rtype)) {
+ foreach ($rtype 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($permit_rules)) {
+ 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($pfb['deny_inbound'])) {
+ foreach ($pfb['deny_inbound'] as $cb_rules) {
+ $cb_rules['interface'] = $inbound_interface;
+ $new_rules[] = $cb_rules;
}
}
- if (!empty($deny_inbound)) {
- foreach ($deny_inbound as $cb_rules) {
+ if ($pfb['order'] == 'order_0' && !empty($pfb['permit_inbound'])) {
+ foreach ($pfb['permit_inbound'] as $cb_rules) {
$cb_rules['interface'] = $inbound_interface;
$new_rules[] = $cb_rules;
}
@@ -2410,50 +3998,46 @@ function sync_package_pfblockerng($cron = "") {
}
}
- // Define Outbound Interface Rules
+ // Define outbound interface rules
if (!empty($pfb['outbound_interfaces'])) {
- $counter = 0;
+ $pfbrunonce = TRUE;
foreach ($pfb['outbound_interfaces'] as $outbound_interface) {
- if (!empty($permit_rules) && $pfb['order'] == "order_1") {
+ if ($pfb['order'] == 'order_1' && !empty($permit_rules)) {
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)
+ 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) {
+ // Match outbound rules defined as floating only.
+ if ($pfbrunonce && !empty($pfb['match_outbound'])) {
+ foreach ($pfb['match_outbound'] as $cb_rules) {
$cb_rules['interface'] = $pfb['outbound_floating'];
$new_rules[] = $cb_rules;
- $counter++;
+ $pfbrunonce = FALSE;
}
}
- if (!empty($permit_outbound)) {
- foreach ($permit_outbound as $cb_rules) {
+ if ($pfb['order'] != 'order_0' && !empty($pfb['permit_outbound'])) {
+ foreach ($pfb['permit_outbound'] as $cb_rules) {
$cb_rules['interface'] = $outbound_interface;
$new_rules[] = $cb_rules;
}
}
- if (!empty($permit_rules) && $pfb['order'] == "order_2") {
+ if ($pfb['order'] == 'order_2' && !empty($permit_rules)) {
foreach ($permit_rules as $cb_rules) {
- if ($cb_rules['interface'] == $outbound_interface)
+ 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($pfb['deny_outbound'])) {
+ foreach ($pfb['deny_outbound'] as $cb_rules) {
+ $cb_rules['interface'] = $outbound_interface;
+ $new_rules[] = $cb_rules;
}
}
- if (!empty($deny_outbound)) {
- foreach ($deny_outbound as $cb_rules) {
+ if ($pfb['order'] == 'order_0' && !empty($pfb['permit_outbound'])) {
+ foreach ($pfb['permit_outbound'] as $cb_rules) {
$cb_rules['interface'] = $outbound_interface;
$new_rules[] = $cb_rules;
}
@@ -2461,65 +4045,56 @@ function sync_package_pfblockerng($cron = "") {
}
}
- 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 ($pfb['float'] == 'on' && in_array($pfb['order'], array('order_0', 'order_3'))) {
+ if ($pfb['order'] == 'order_0') {
+ $rule_order = array($fother_rules, $fpermit_rules, $fmatch_rules);
+ } else {
+ $rule_order = array($fpermit_rules, $fmatch_rules, $fother_rules);
}
- }
- if (!empty($fpermit_rules) && $pfb['order'] == "order_3") {
- foreach ($fpermit_rules as $cb_rules) {
- $new_rules[] = $cb_rules;
+ foreach ($rule_order as $rtype) {
+ if (!empty($rtype)) {
+ foreach ($rtype as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
}
}
- if (!empty($fmatch_rules) && $pfb['order'] == "order_3") {
- foreach ($fmatch_rules as $cb_rules) {
+ if ($pfb['float'] == 'on' && $pfb['order'] == 'order_2' && !empty($fother_rules)) {
+ foreach ($fother_rules as $cb_rules) {
$new_rules[] = $cb_rules;
}
}
- if (!empty($permit_rules) && $pfb['order'] == "order_3") {
+ if ($pfb['order'] == 'order_3' && !empty($permit_rules)) {
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;
}
- if (!empty($message)) {
- $log = "\n {$message}\n";
- pfb_logger("{$log}","1");
+
+ // Unset arrays
+ unset($pfb['permit_inbound'], $pfb['permit_outbound'], $pfb['deny_inbound'], $pfb['deny_outbound'], $pfb['match_inbound'], $pfb['match_outbound']);
+ unset($cb_rules, $other_rules, $fother_rules, $permit_rules, $fpermit_rules, $match_rules, $fmatch_rules);
+
+ // Remove 'created' tag (New vs old rules array comparison)
+ foreach ($new_rules as $key => $rule) {
+ $new_rules_nocreated[] = $rule;
+ unset($new_rules_nocreated[$key]['created']);
}
- // 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);
+ // Update config.xml, if changes required
+ if ($pfb['autorules'] && $orig_rules_nocreated != $new_rules_nocreated) {
+ $config['filter']['rule'] = $new_rules;
+ write_config('pfBlockerNG: saving Firewall rules');
+ }
}
-
- // Set flag to Update config file.
- if ($pfb['autorules'] && $rules != $new_rules) {
- $pfb['cron_mod'] = TRUE;
+ else {
+ $log = "\n\n{$message}\n";
+ pfb_logger("{$log}", 1);
}
#################################
@@ -2527,43 +4102,43 @@ function sync_package_pfblockerng($cron = "") {
#################################
// If 'Rule Changes' are found, utilize the 'filter_configure()' function, if not, utilize 'pfctl replace' command
- if ($pfb['autorules'] && $rules != $new_rules || $pfb['enable'] == "" || $pfb['remove']) {
- require_once("filter.inc");
+ if ($pfb['autorules'] && $orig_rules_nocreated != $new_rules_nocreated || $pfb['enable'] == '' || $pfb['remove']) {
+ require_once('filter.inc');
if (!$pfb['save']) {
$log = "\n===[ Aliastables / Rules ]================================\n\n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
- $log = "Firewall Rule Changes Found, Applying Filter Reload\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);
+ // Remove all pfB aliastables
+ exec("{$pfb['pfctl']} -s Tables | grep '^pfB_'", $pfb_tables);
+ if (isset($pfb_tables)) {
+ foreach ($pfb_tables as $pfb_table) {
+ exec("{$pfb['pfctl']} -t {$pfb_table} -T kill 2>&1", $result);
}
}
- // load filter file which will create the pfctl tables
- filter_configure();
+ filter_configure(); // Load filter_configure which will create the pfctl tables
+ $pfb_filter_configure = TRUE; // Flag to skip State removal function due to pf reloading
// Call function for NanoBSD/Ramdisk processes.
- pfb_aliastables("update");
+ pfb_aliastables('update');
} else {
- // Don't Execute on User 'Save'
+ // Don't execute on user 'save'
if (!$pfb['save']) {
-
- $log = "\n\n===[ Aliastables / Rules ]================================\n\n";
- pfb_logger("{$log}","1");
+ $log = "\n\n===[ Aliastables / Rules ]==========================================\n\n";
+ pfb_logger("{$log}", 1);
$log = "No Changes to Firewall Rules, Skipping Filter Reload\n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
- // Re-Save Only Aliases that have been updated only.
- // When 'Reputation' is used, all Aliases Need to be Updated.
+ // Only Save Aliases that have been updated.
+ // When 'Reputation' is used, all aliases need to be updated when any alias has been updated.
$final_alias = array();
- if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") {
+ if ($pfb['repcheck'] && ($pfb['drep'] == 'on' || $pfb['prep'] == 'on')) {
if (!empty($pfb_alias_lists_all)) {
$final_alias = array_unique($pfb_alias_lists_all);
}
@@ -2576,120 +4151,301 @@ function sync_package_pfblockerng($cron = "") {
if (!empty($final_alias)) {
foreach ($final_alias as $final) {
$log = "\n Updating: {$final}\n";
- pfb_logger("{$log}","1");
- $result_pfctl = "";
+ pfb_logger("{$log}", 1);
+ $result = '';
if (file_exists("{$pfb['aliasdir']}/{$final}.txt")) {
- exec ("/sbin/pfctl -t " . escapeshellarg($final) . " -T replace -f " . $pfb['aliasdir'] . "/" . escapeshellarg($final) . ".txt 2>&1", $result_pfctl);
- $log = implode($result_pfctl);
+ exec("{$pfb['pfctl']} -t {$final} -T replace -f {$pfb['aliasdir']}/{$final}.txt 2>&1", $result);
+ $log = implode($result);
}
else {
$log = "Aliastable file not found\n";
}
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
}
- pfb_logger("\n","1");
+ pfb_logger("\n", 1);
// Call function for NanoBSD/Ramdisk processes.
- pfb_aliastables("update");
+ pfb_aliastables('update');
} else {
$log = "No Changes to Aliases, Skipping pfctl Update\n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
}
}
}
- // UNSET Variables
- unset($rules, $new_rules);
-
- // sync config
- pfblockerng_sync_on_changes();
+ // Unset arrays
+ unset($rules, $new_rules, $orig_rules_nocreated, $new_rules_nocreated);
#################################
- # FINAL REPORTING #
+ # SAVE CONFIGURATION #
#################################
- // 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");
+ // Uncheck reusing existing downloads check box
+ if (!$pfb['save'] && $pfb['enable'] == 'on' && $pfb['config']['pfb_reuse'] == 'on') {
+ $pfb_config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = '';
+ $pfb['conf_mod'] = TRUE;
}
- if ($pfb['enable'] == "on" && !$pfb['save'] || $pfb['summary']) {
- $log = "\n UPDATE PROCESS ENDED [ NOW ]\n";
- pfb_logger("{$log}","1");
+ // Only save config.xml, if changes are found.
+ if ($pfb['conf_mod'] && isset($pfb_config)) {
+ // Reload config.xml to get any recent changes and merge/save changes.
+ $config = parse_config(true);
+ $config = array_replace_recursive($config, $pfb_config);
+ write_config('pfBlockerNG: save settings');
+ }
+
+
+ #################################
+ # KILL STATES #
+ #################################
+
+ if ($pfb['kstates'] && !$pfb_filter_configure) {
+
+ $log = "\n===[ Kill States ]==================================================\n\n";
+ pfb_logger("{$log}", 1);
+
+ $tablesin = $tablesout = array();
+ if (!empty($config['filter']['rule'])) {
+ foreach ($config['filter']['rule'] as $rule) {
+
+ // Collect all 'pfB_' Rules that are 'Block/Reject' and do not have bypass states enabled
+ if (strpos($rule['descr'], '[s]') === FALSE && ($rule['type'] == 'block' || $rule['type'] == 'reject') &&
+ (strpos($rule['source']['address'], 'pfB_') !== FALSE || strpos($rule['destination']['address'], 'pfB_') !== FALSE)) {
+
+ if (isset($rule['source']['address'])) {
+ $tablesin[] = $rule['source']['address'];
+ } else {
+ $tablesout[] = $rule['destination']['address'];
+ }
+ }
+ }
+ }
+
+ $pfb_supp = array(); // List of IPs to suppress
+
+ // Collect pfBlockerNGSuppress alias IPs
+ $pfb_suppalias = array();
+ if (isset($config['aliases']['alias'])) {
+ foreach ($config['aliases']['alias'] as $key => $alias) {
+ if ($alias['name'] == 'pfBlockerNGSuppress') {
+ // Strip any '/32' CIDR values
+ $pfb_suppalias = str_replace('/32', '', explode(' ', $config['aliases']['alias'][$key]['address']));
+ }
+ }
+
+ // Convert '/24' CIDRs
+ if (!empty($pfb_suppalias)) {
+ $pfb_suppaliascidr = array();
+ foreach ($pfb_suppalias as $key => $subnet) {
+ if (strpos($subnet, '/24') !== FALSE) {
+ $pfb_suppaliascidr = subnetv4_expand($subnet);
+ unset($pfb_suppalias[$key]);
+ }
+ }
+ $pfb_supp = array_merge($pfb_supp, $pfb_suppaliascidr);
+ }
+ $pfb_supp = array_merge($pfb_supp, $pfb_suppalias);
+ }
+
+ $pfb_supp[] = '0.0.0.0'; // Add 0.0.0.0 to suppression array
+
+ // Collect Gateway IP addresses to suppress
+ $int_gateway = get_interfaces_with_gateway();
+ if (isset($int_gateway)) {
+ foreach ($int_gateway as $gateway) {
+ $convert = get_interface_ip($gateway);
+ $pfb_supp[] = $convert;
+ }
+ }
+
+ // Collect DNS servers to suppress
+ $pfb_dnsservers = get_dns_servers();
+ if (!empty($pfb_dnsservers)) {
+ $pfb_supp = array_merge($pfb_supp, $pfb_dnsservers);
+ }
+
+ // Remove any duplicate IPs
+ $pfb_supp = array_unique($pfb_supp);
+
+ $statesin = $statesout = array();
+ exec("{$pfb['pfctl']} -s state", $s_matches);
+ if (!empty($s_matches)) {
+ foreach ($s_matches as $key => $sline) {
+
+ // SAMPLE : em0 udp 93.15.36.22:6881 -> 192.168.0.3:681 MULTIPLE:MULTIPLE
+ // SAMPLE : pppoe0 udp 35.170.3.40:57197 (192.168.0.45:681) -> 22.41.123.206:1001 MULTIPLE:MULTIPLE
+ // SAMPLE : em0 tcp 2001:65c:1398:101:124[443] <- 2001:170:2f:3e:a4c4:7b23:fe5f:b36e[52725] FIN_WAIT_2:FIN_WAIT_2
+
+ // Remove '( text )' from state line
+ if (strpos($sline, '(') !== FALSE) {
+ $s_pos1 = strpos($sline, '(');
+ $s_pos2 = strpos($sline, ')');
+ $s_len = $s_pos2 - $s_pos1 + 2;
+ $sline = substr_replace($sline, '', $s_pos1, $s_len);
+ }
+
+ if (!empty($sline)) {
+ list($int, $proto, $dir1, $sdirection, $dir2) = explode(' ', $sline);
+
+ if ($sdirection == '<-') {
+ // Inbound State
+ $s_ip = $dir1;
+ } else {
+ // Outbound State
+ $s_ip = $dir2;
+ }
+
+ // Strip port
+ if (strpos($s_ip, '[') !== FALSE) {
+ // Strip IPv6 port
+ $s_ip = strstr($s_ip, '[', TRUE);
+ } else {
+ if (strpos($s_ip, ':') !== FALSE) {
+ // Strip IPv4 port
+ $s_ip = strstr($s_ip, ':', TRUE);
+ }
+ }
+
+ // Exclude private, reserved and loopback IPs
+ if (filter_var($s_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) &&
+ filter_var($s_ip, FILTER_CALLBACK, array('options' => 'FILTER_FLAG_NO_LOOPBACK_RANGE'))) {
+ if ($sdirection == '<-') {
+ $statesin[] = $s_ip;
+ } else {
+ $statesout[] = $s_ip;
+ }
+ }
+ }
+ }
+ }
+
+ $statesin = array_unique($statesin);
+ natsort($statesin);
+ $statesout = array_unique($statesout);
+ natsort($statesout);
+
+ $pfbfound = FALSE;
+ foreach (array('<-' => $statesin, '->' => $statesout) as $s_type => $s_state_ips) {
+ foreach ($s_state_ips as $s_ip) {
+ if (!in_array($s_ip, $pfb_supp)) {
+ if ($s_type == '<-') {
+ $type = '-Inbound';
+ $s_tables = $tablesin;
+ } else {
+ $type = '-Outbound';
+ $s_tables = $tablesout;
+ }
+
+ foreach ($s_tables as $s_table) {
+ $result = substr(exec("{$pfb['pfctl']} -t {$s_table} -T test {$s_ip} 2>&1"), 0, 1);
+ if ($result > 0) {
+ $pfbfound = TRUE;
+ $log = " [ {$s_table}{$type} ] Removed state(s) for [ {$s_ip} ]\n";
+ pfb_logger("{$log}", 1);
+ foreach ($s_matches as $s_line) {
+ if (strpos($s_line, $s_type) !== FALSE && strpos($s_line, $s_ip) !== FALSE) {
+ pfb_logger(" {$s_line}\n", 1);
+ }
+ }
+
+ // Remove states
+ if ($s_type == '<-') {
+ // Kill all state entries originating from $s_ip
+ exec("{$pfb['pfctl']} -k {$s_ip}");
+ } else {
+ // Kill all state entries to the target $s_ip
+ exec("{$pfb['pfctl']} -k 0.0.0.0/0 -k {$s_ip}");
+ }
+ }
+ }
+ }
+ }
+ }
+ if ($pfbfound) {
+ pfb_logger("\n======================================================================\n", 1);
+ } else {
+ pfb_logger(" No matching states found\n======================================================================\n", 1);
+ }
}
#########################################
+ # XMLRPC - sync process #
+ #########################################
+
+ if (!platform_booting() && !$g['pfblockerng_install']) {
+ pfblockerng_sync_on_changes();
+ }
+
+ #########################################
# Define/Apply CRON Jobs #
#########################################
- // 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 )
+ // 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 )
- // Define Cron hour (Cron Interval & Start Hour)
+ // Define CRON hour (CRON interval & start hour)
if ($pfb['interval'] == 1) {
- $pfb_hour = "*";
+ $pfb_hour = '*';
} elseif ($pfb['interval'] == 24) {
$pfb_hour = $pfb['24hour'];
} else {
- $pfb_hour = implode(",", pfb_cron_base_hour());
+ $pfb_hour = implode(',', pfb_cron_base_hour());
}
- $pfb_mday = "*";
- $pfb_month = "*";
- $pfb_wday = "*";
- $pfb_who = "root";
+ $pfb_mday = '*';
+ $pfb_month = '*';
+ $pfb_wday = '*';
+ $pfb_who = 'root';
- // Determine if Cron Task requires updating
+ // Determine if CRON job requires updating
if (!pfblockerng_cron_exists($pfb_cmd, $pfb['min'], $pfb_hour)) {
install_cron_job($pfb_cmd, true, $pfb['min'], $pfb_hour, $pfb_mday, $pfb_month, $pfb_wday, $pfb_who);
}
}
else {
- // Clear any existing pfBlockerNG Cron Jobs
- install_cron_job("pfblockerng.php cron", false);
+ // Clear any existing pfBlockerNG CRON jobs
+ install_cron_job('pfblockerng.php cron', 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";
+ if ($pfb['enable'] == 'on') {
+ // Define pfBlockerNG MaxMind CRON job
+ $pfb_gcmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php dc >> {$pfb['extraslog']} 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";
+ $pfb_gmday = '1,2,3,4,5,6,7';
+ $pfb_gmonth = '*';
+ $pfb_gwday = '2';
+ $pfb_gwho = 'root';
- // Determine if Cron Task requires updating
+ // Determine if CRON job requires updating
if (!pfblockerng_cron_exists($pfb_gcmd, $pfb_gmin, 'maxmind')) {
install_cron_job($pfb_gcmd, true, $pfb_gmin, $pfb_ghour, $pfb_gmday, $pfb_gmonth, $pfb_gwday, $pfb_gwho);
}
}
else {
- // Clear any existing pfBlockerNG Cron Jobs
- install_cron_job("pfblockerng.php dc", false);
+ // Clear any existing pfBlockerNG CRON jobs
+ install_cron_job('pfblockerng.php dc', false);
}
#################################
- # Closing Processes #
+ # FINAL REPORTING #
#################################
- // uncheck Reusing Existing Downloads Check box
- if (!$pfb['save'] && $pfb['enable'] == "on" && $pfb['reuse'] == "on") {
- $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = "";
- $pfb['cron_mod'] = TRUE;
+ // Only run with CRON or Force invoked process
+ if ((!$pfb['save'] && $pfb['repcheck'] && $pfb['enable'] == 'on') || $pfb['summary']) {
+ // Script to run final script processes.
+ exec("{$pfb['script']} closing {$pfb['dup']} {$elog}");
}
- // Only save config.xml changes if changes are found.
- // Temporay to ensure all conditions are defined before fully enabling this feature
- if ($pfb['cron_mod'] || !$pfb['cron_mod']) {
- write_config("pfBlockerNG: Save settings");
+ if ($pfb['enable'] == 'on' && !$pfb['save'] || $pfb['summary']) {
+ $log = "\n UPDATE PROCESS ENDED [ NOW ]\n";
+ pfb_logger("{$log}", 1);
}
}
@@ -2699,151 +4455,191 @@ function pfblockerng_validate_input($post, &$input_errors) {
foreach ($post as $key => $value) {
- if (substr($key, 0, 3) == "url" && is_numeric( substr($key, 3, (strlen($key) - 3))) ) {
+ if (substr($key, 0, 3) == 'url' && is_numeric( substr($key, 3, (strlen($key) - 3))) ) {
if (empty($value)) {
$input_url_empty = TRUE;
continue;
}
if (substr($value, 0, 1) == ' ') {
- $input_errors[] = "Leading whitespace not allowed in URL field";
+ $input_errors[] = 'Leading whitespace not allowed in URL field';
}
}
- if (substr($key, 0, 6) == "header" && is_numeric( substr($key, 6, (strlen($key) - 6))) ) {
+ if (substr($key, 0, 6) == 'header' && is_numeric( substr($key, 6, (strlen($key) - 6))) ) {
if ($input_url_empty && empty($value)) {
$input_url_empty = FALSE;
continue;
}
if ($input_url_empty && !empty($value)) {
- $input_errors[] = "No URL Defined.";
+ $input_errors[] = 'No URL Defined.';
}
if (substr($value, 0, 1) == ' ' || empty($value)) {
- $input_errors[] = "Header field must be defined.";
+ $input_errors[] = 'Header field must be defined.';
+ }
+ }
+
+ if ($key == 'pfb_dnsbl' && $value == 'on') {
+ $pfb_dnsbl_state = TRUE;
+ }
+
+ if ($pfb_dnsbl_state) {
+ if ($key == 'pfb_dnsvip' && empty($value)) {
+ $input_errors[] = 'DNSBL VIP address must be defined.';
+ }
+ if ($key == 'pfb_dnsport' && empty($value) || $key == 'pfb_dnsport_ssl' && empty($value)) {
+ $input_errors[] = 'DNSBL Port must be defined.';
+ }
+ if ($key == 'pfb_dnsport' && !is_port($value) || $key == 'pfb_dnsport_ssl' && !is_port($value)) {
+ $input_errors[] = 'DNSBL Port must be a valid port in the range of 1 - 65535';
}
}
}
}
+
+// Function to De-Install pfBlockerNG
function pfblockerng_php_deinstall_command() {
- require_once("config.inc");
- global $config,$pfb;
+ require_once('config.inc');
+ global $config, $pfb, $static_output;
- // Set these two variables to Disable pfBlockerNG on De-Install
+ // 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");
+ 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
+ // Maintain pfBlockerNG settings and database files if $pfb['keep'] is ON.
+ if ($pfb['keep'] != 'on') {
+ // Remove pfBlockerNG log and DB folder
rmdir_recursive("{$pfb['dbdir']}");
rmdir_recursive("{$pfb['logdir']}");
- // Remove Aliastables archive and earlyshellcmd if found.
+ // Remove aliastables archive and earlyshellcmd if found.
@unlink_if_exists("{$pfb['aliasarchive']}");
- if (is_array($config['system']['earlyshellcmd'])) {
+ if (isset($config['system']['earlyshellcmd'])) {
$a_earlyshellcmd = &$config['system']['earlyshellcmd'];
if (preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd)) {
$a_earlyshellcmd = preg_grep("/pfblockerng.sh aliastables/", $a_earlyshellcmd, PREG_GREP_INVERT);
}
}
- // Remove Settings from Config
- if (is_array($config['installedpackages']['pfblockerng']))
+ // Remove settings from config
+ if (isset($config['installedpackages']['pfblockerng']))
unset($config['installedpackages']['pfblockerng']);
- if (is_array($config['installedpackages']['pfblockerngglobal']))
+ if (isset($config['installedpackages']['pfblockerngglobal']))
unset($config['installedpackages']['pfblockerngglobal']);
- if (is_array($config['installedpackages']['pfblockerngsync']))
+ if (isset($config['installedpackages']['pfblockerngsync']))
unset($config['installedpackages']['pfblockerngsync']);
- if (is_array($config['installedpackages']['pfblockerngreputation']))
+ if (isset($config['installedpackages']['pfblockerngreputation']))
unset($config['installedpackages']['pfblockerngreputation']);
- if (is_array($config['installedpackages']['pfblockernglistsv4']))
+ if (isset($config['installedpackages']['pfblockernglistsv4']))
unset($config['installedpackages']['pfblockernglistsv4']);
- if (is_array($config['installedpackages']['pfblockernglistsv6']))
+ if (isset($config['installedpackages']['pfblockernglistsv6']))
unset($config['installedpackages']['pfblockernglistsv6']);
- if (is_array($config['installedpackages']['pfblockerngafrica']))
+ if (isset($config['installedpackages']['pfblockerngdnsbl']))
+ unset($config['installedpackages']['pfblockerngdnsbl']);
+ if (isset($config['installedpackages']['pfblockerngdnsblsettings']))
+ unset($config['installedpackages']['pfblockerngdnsblsettings']);
+ if (isset($config['installedpackages']['pfblockerngdnsbleasylist']))
+ unset($config['installedpackages']['pfblockerngdnsbleasylist']);
+ if (isset($config['installedpackages']['pfblockerngafrica']))
unset($config['installedpackages']['pfblockerngafrica']);
- if (is_array($config['installedpackages']['pfblockerngantartica']))
+ if (isset($config['installedpackages']['pfblockerngantartica']))
unset($config['installedpackages']['pfblockerngantartica']);
- if (is_array($config['installedpackages']['pfblockerngasia']))
+ if (isset($config['installedpackages']['pfblockerngasia']))
unset($config['installedpackages']['pfblockerngasia']);
- if (is_array($config['installedpackages']['pfblockerngeurope']))
+ if (isset($config['installedpackages']['pfblockerngeurope']))
unset($config['installedpackages']['pfblockerngeurope']);
- if (is_array($config['installedpackages']['pfblockerngnorthamerica']))
+ if (isset($config['installedpackages']['pfblockerngnorthamerica']))
unset($config['installedpackages']['pfblockerngnorthamerica']);
- if (is_array($config['installedpackages']['pfblockerngoceania']))
+ if (isset($config['installedpackages']['pfblockerngoceania']))
unset($config['installedpackages']['pfblockerngoceania']);
- if (is_array($config['installedpackages']['pfblockerngsouthamerica']))
+ if (isset($config['installedpackages']['pfblockerngsouthamerica']))
unset($config['installedpackages']['pfblockerngsouthamerica']);
- if (is_array($config['installedpackages']['pfblockerngtopspammers']))
+ if (isset($config['installedpackages']['pfblockerngtopspammers']))
unset($config['installedpackages']['pfblockerngtopspammers']);
- if (is_array($config['installedpackages']['pfblockerngproxyandsatellite']))
+ if (isset($config['installedpackages']['pfblockerngproxyandsatellite']))
unset($config['installedpackages']['pfblockerngproxyandsatellite']);
+
+ unlink_if_exists('/usr/local/sbin/lighttpd_pfb');
+ unlink_if_exists("{$pfb['dnsbl_conf']}");
+ unlink_if_exists("{$pfb['dnsbl_cert']}");
+ unlink_if_exists("{$pfb['dnsbl_info']}");
+ unlink_if_exists("{$pfb['aliasarchive']}");
}
- // Remove Widget (code from Snort deinstall)
+ // Remove widget (code from Snort deinstall)
$pfb['widgets'] = $config['widgets']['sequence'];
if (!empty($pfb['widgets'])) {
- $widgetlist = explode(",", $pfb['widgets']);
+ $widgetlist = explode(',', $pfb['widgets']);
foreach ($widgetlist as $key => $widget) {
- if (strstr($widget, "pfblockerng-container")) {
+ if (strpos($widget, 'pfblockerng-container') !== FALSE) {
unset($widgetlist[$key]);
}
}
- $config['widgets']['sequence'] = implode(",", $widgetlist);
+ $config['widgets']['sequence'] = implode(',', $widgetlist);
+ write_config('pfBlockerNG: Remove widget');
}
- update_output_window(gettext("pfBlockerNG has been Uninstalled"));
+
+ $static_output .= 'pfBlockerNG has been uninstalled.';
+ update_output_window($static_output);
}
+
/* Uses XMLRPC to synchronize the changes to a remote node */
function pfblockerng_sync_on_changes() {
- global $config, $g, $pfb_sync;
+ global $config;
- // Create Array of Sync Settings and exit if Sync is Disabled.
- if (is_array($config['installedpackages']['pfblockerngsync']['config'][0])) {
+ // Create array of sync settings and exit if sync is disabled.
+ if (isset($config['installedpackages']['pfblockerngsync']['config'][0])) {
$pfb_sync = $config['installedpackages']['pfblockerngsync']['config'][0];
- if ($pfb_sync['varsynconchanges'] == "disabled" || $pfb_sync['varsynconchanges'] == "") {
+ if ($pfb_sync['varsynconchanges'] == 'disabled' || empty($pfb_sync['varsynconchanges'])) {
return;
}
- $synctimeout = $pfb_sync['varsynctimeout'];
+ $synctimeout = $pfb_sync['varsynctimeout'] ?: '150';
} else {
return;
}
- log_error("[pfBlockerNG] XMLRPC sync is starting.");
+ syslog(LOG_NOTICE, '[pfBlockerNG] XMLRPC sync is starting.');
- if (is_array($config['installedpackages']['pfblockerngsync']['config'])) {
+ if (isset($config['installedpackages']['pfblockerngsync']['config'])) {
switch ($pfb_sync['varsynconchanges']) {
- case "manual":
- if (is_array($pfb_sync['row'])) {
+ case 'manual':
+ if (isset($pfb_sync['row'])) {
$rs = $pfb_sync['row'];
} else {
- log_error("[pfBlockerNG] Manual XMLRPC sync is enabled but there are no replication targets configured.");
+ log_error('[pfBlockerNG] Manual 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'];
+ case 'auto':
+ if (isset($config['hasync'])) {
+ $system_carp = $config['hasync'];
+ $rs[0]['varsyncipaddress'] = $system_carp['synchronizetoip'];
+ $rs[0]['varsyncusername'] = $system_carp['username'];
+ $rs[0]['varsyncpassword'] = $system_carp['password'];
+ $rs[0]['varsyncdestinenable'] = FALSE;
// 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";
+ if ($config['system']['webgui']['protocol'] == 'http') {
+ $rs[0]['varsyncprotocol'] = 'http';
+ $rs[0]['varsyncport'] = $config['system']['webgui']['port'] ?: '80';
} else {
- $rs[0]['varsyncprotocol'] = "https";
+ $rs[0]['varsyncprotocol'] = 'https';
+ $rs[0]['varsyncport'] = $config['system']['webgui']['port'] ?: '443';
}
- if ($system_carp['synchronizetoip'] == "") {
- log_error("[pfBlockerNG] XMLRPC sync is enabled but there is no sync IP address configured.");
+ if (empty($system_carp['synchronizetoip'])) {
+ log_error('[pfBlockerNG] Auto XMLRPC sync is enabled but there is no sync IP address configured.');
return;
+ } else {
+ $rs[0]['varsyncdestinenable'] = TRUE;
}
} else {
- log_error("[pfBlockerNG] Auto XMLRPC sync is enabled but there are no replication targets configured.");
+ log_error('[pfBlockerNG] Auto XMLRPC sync is enabled but there are no replication targets configured.');
return;
}
break;
@@ -2851,27 +4647,42 @@ function pfblockerng_sync_on_changes() {
return;
break;
}
- if (is_array($rs)) {
+ if (isset($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";
+ // Only sync enabled replication targets
+ if ($sh['varsyncdestinenable']) {
+ $sync_to_ip = $sh['varsyncipaddress'];
+ $port = $sh['varsyncport'];
+ $password = $sh['varsyncpassword'];
+ $protocol = $sh['varsyncprotocol'];
+ $username = $sh['varsyncusername'] ?: 'admin';
+
+ $validate = TRUE;
+ $error = '| ';
+
+ if (empty($password)) {
+ $error .= 'Password parameter missing. | ';
+ $validate = FALSE;
+ }
+ if (!is_ipaddr($sync_to_ip) && !is_hostname($sync_to_ip) && !is_domain($sync_to_ip)) {
+ $error .= 'Mis-configured Target IP/Host address. | ';
+ $validate = FALSE;
+ }
+ if (!is_port($port)) {
+ $error .= 'Mis-configured Target Port setting. |';
+ $validate = FALSE;
}
- pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout);
+ if ($validate) {
+ pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout);
+ if ($success) {
+ syslog(LOG_NOTICE, "[pfBlockerNG] XMLRPC sync to [ {$sync_to_ip}:{port} ] completed successfully.");
+ }
+ } else {
+ log_error("[pfBlockerNG] XMLRPC sync to [ {$sync_to_ip}:{port} ] terminated due to the following error(s): {$error}");
+ }
}
}
- if ($success) {
- log_error("[pfBlockerNG] XMLRPC sync completed successfully.");
- }
}
}
}
@@ -2879,82 +4690,59 @@ function pfblockerng_sync_on_changes() {
/* Do the actual XMLRPC sync */
function pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout) {
- global $config, $g, $pfb_sync;
+ global $config, $g;
$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;
- }
+ // Take care of IPv6 literal address
+ if (is_ipaddrv6($sync_to_ip)) {
+ $sync_to_ip = "[{$sync_to_ip}]";
+ }
- /* 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'] == "") {
- if (is_array($config['installedpackages']['pfblockerng']))
+ if (isset($config['installedpackages']['pfblockerngsync']['config'][0]['syncinterfaces'])) {
+ if (isset($config['installedpackages']['pfblockerng']))
$xml['pfblockerng'] = $config['installedpackages']['pfblockerng'];
+ if (isset($config['installedpackages']['pfblockerngdnsblsettings']))
+ $xml['pfblockerngdnsblsettings']= $config['installedpackages']['pfblockerngdnsblsettings'];
}
- if (is_array($config['installedpackages']['pfblockerngreputation']))
+
+ if (isset($config['installedpackages']['pfblockerngreputation']))
$xml['pfblockerngreputation'] = $config['installedpackages']['pfblockerngreputation'];
- if (is_array($config['installedpackages']['pfblockernglistsv4']))
+ if (isset($config['installedpackages']['pfblockernglistsv4']))
$xml['pfblockernglistsv4'] = $config['installedpackages']['pfblockernglistsv4'];
- if (is_array($config['installedpackages']['pfblockernglistsv6']))
+ if (isset($config['installedpackages']['pfblockernglistsv6']))
$xml['pfblockernglistsv6'] = $config['installedpackages']['pfblockernglistsv6'];
- if (is_array($config['installedpackages']['pfblockerngtopspammers']))
+ if (isset($config['installedpackages']['pfblockerngtopspammers']))
$xml['pfblockerngtopspammers'] = $config['installedpackages']['pfblockerngtopspammers'];
- if (is_array($config['installedpackages']['pfblockerngafrica']))
+ if (isset($config['installedpackages']['pfblockerngafrica']))
$xml['pfblockerngafrica'] = $config['installedpackages']['pfblockerngafrica'];
- if (is_array($config['installedpackages']['pfblockerngantartica']))
+ if (isset($config['installedpackages']['pfblockerngantartica']))
$xml['pfblockerngantartica'] = $config['installedpackages']['pfblockerngantartica'];
- if (is_array($config['installedpackages']['pfblockerngasia']))
+ if (isset($config['installedpackages']['pfblockerngasia']))
$xml['pfblockerngasia'] = $config['installedpackages']['pfblockerngasia'];
- if (is_array($config['installedpackages']['pfblockerngeurope']))
+ if (isset($config['installedpackages']['pfblockerngeurope']))
$xml['pfblockerngeurope'] = $config['installedpackages']['pfblockerngeurope'];
- if (is_array($config['installedpackages']['pfblockerngnorthamerica']))
+ if (isset($config['installedpackages']['pfblockerngnorthamerica']))
$xml['pfblockerngnorthamerica'] = $config['installedpackages']['pfblockerngnorthamerica'];
- if (is_array($config['installedpackages']['pfblockerngoceania']))
+ if (isset($config['installedpackages']['pfblockerngoceania']))
$xml['pfblockerngoceania'] = $config['installedpackages']['pfblockerngoceania'];
- if (is_array($config['installedpackages']['pfblockerngsouthamerica']))
+ if (isset($config['installedpackages']['pfblockerngsouthamerica']))
$xml['pfblockerngsouthamerica'] = $config['installedpackages']['pfblockerngsouthamerica'];
- if (is_array($config['installedpackages']['pfblockerngproxyandsatellite']))
+ if (isset($config['installedpackages']['pfblockerngproxyandsatellite']))
$xml['pfblockerngproxyandsatellite'] = $config['installedpackages']['pfblockerngproxyandsatellite'];
+ if (isset($config['installedpackages']['pfblockerngdnsbleasylist']))
+ $xml['pfblockerngdnsbleasylist'] = $config['installedpackages']['pfblockerngdnsbleasylist'];
+ if (isset($config['installedpackages']['pfblockerngdnsbl']))
+ $xml['pfblockerngdnsbl'] = $config['installedpackages']['pfblockerngdnsbl'];
/* 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);
@@ -2965,22 +4753,18 @@ function pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $p
/* 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", "");
+ 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", "");
+ 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.php b/config/pfblockerng/pfblockerng.php
index 83b0ed8d..93578f24 100644
--- a/config/pfblockerng/pfblockerng.php
+++ b/config/pfblockerng/pfblockerng.php
@@ -3,11 +3,11 @@
pfBlockerNG.php
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Based upon pfBlocker by
- Copyright (C) 2011-2012 Marcello Coutinho
+ Copyright (c) 2011-2012 Marcello Coutinho
All rights reserved.
Hour Schedule Convertor code by
@@ -39,278 +39,332 @@
*/
-require_once("util.inc");
-require_once("functions.inc");
-require_once("pkg-utils.inc");
-require_once("globals.inc");
-require_once("services.inc");
-
-// Call Include File and Collect updated Global Settings
-if (in_array($argv[1], array( 'update','dc','uc','gc','cron' ))) {
- require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+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');
+require_once('/usr/local/pkg/pfblockerng/pfblockerng_extra.inc'); // 'include functions' not yet merged into pfSense
+
+global $config, $pfb;
+
+// Extras - MaxMind/Alexa Download URLs/filenames/settings
+$pfb['extras'][0]['url'] = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz';
+$pfb['extras'][0]['file_dwn'] = 'GeoIP.dat.gz';
+$pfb['extras'][0]['file'] = 'GeoIP.dat';
+$pfb['extras'][0]['folder'] = "{$pfb['geoipshare']}";
+
+$pfb['extras'][1]['url'] = "http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz";
+$pfb['extras'][1]['file_dwn'] = 'GeoIPv6.dat.gz';
+$pfb['extras'][1]['file'] = 'GeoIPv6.dat';
+$pfb['extras'][1]['folder'] = "{$pfb['geoipshare']}";
+
+$pfb['extras'][2]['url'] = "http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip";
+$pfb['extras'][2]['file_dwn'] = 'GeoIPCountryCSV.zip';
+$pfb['extras'][2]['file'] = 'GeoIPCountryWhois.csv';
+$pfb['extras'][2]['folder'] = "{$pfb['geoipshare']}";
+$pfb['extras'][2]['install'] = TRUE; // Flag for package installation
+
+$pfb['extras'][3]['url'] = "http://dev.maxmind.com/static/csv/codes/country_continent.csv";
+$pfb['extras'][3]['file_dwn'] = 'country_continent.csv';
+$pfb['extras'][3]['file'] = 'country_continent.csv';
+$pfb['extras'][3]['folder'] = "{$pfb['geoipshare']}";
+$pfb['extras'][3]['install'] = TRUE; // Flag for package installation
+
+$pfb['extras'][4]['url'] = "http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz";
+$pfb['extras'][4]['file_dwn'] = 'GeoIPv6.csv.gz';
+$pfb['extras'][4]['file'] = 'GeoIPv6.csv';
+$pfb['extras'][4]['folder'] = "{$pfb['geoipshare']}";
+$pfb['extras'][4]['install'] = TRUE; // Flag for package installation
+
+$pfb['extras'][5]['url'] = "https://s3.amazonaws.com/alexa-static/top-1m.csv.zip";
+$pfb['extras'][5]['file_dwn'] = 'top-1m.csv.zip';
+$pfb['extras'][5]['file'] = 'top-1m.csv';
+$pfb['extras'][5]['folder'] = "{$pfb['dbdir']}";
+
+
+// Call include file and collect updated Global settings
+if (in_array($argv[1], array('update', 'updateip', 'updatednsbl', 'dc', 'bu', 'uc', 'gc', 'al', 'cron'))) {
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);
+ // Script Arguments
+ switch($argv[1]) {
+ case 'cron': // Sync 'cron'
+ pfblockerng_sync_cron();
+ break;
+ case 'updateip': // Sync 'Force Reload IP only'
+ case 'updatednsbl': // Sync 'Force Reload DNSBL only'
+ sync_package_pfblockerng($argv[1]);
+ break;
+ case 'update': // Sync 'Force update'
+ sync_package_pfblockerng('cron');
+ break;
+ case 'dc': // Update Extras - MaxMind/Alexa database files
- // subnets are ordered by bit size. Re sort by IP ("naturally") and convert back to IPv4/IPv6
+ // If 'General Tab' skip MaxMind download setting if checked, only download binary updates for Reputation/Alerts page.
+ if (!empty($pfb['cc'])) {
+ unset($pfb['extras'][2], $pfb['extras'][3], $pfb['extras'][4]);
+ }
- ksort($rangesubnets, SORT_STRING);
- $out = array();
+ // Skip Alexa update, if disabled
+ if ($pfb['dnsbl_alexa'] == 'Disabled') {
+ unset($pfb['extras'][5]);
+ }
- 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;
+ pfblockerng_download_extras();
+ pfblockerng_uc_countries();
+ pfblockerng_get_countries();
+ break;
+ case 'bu': // Update MaxMind binary database files only.
+ unset($pfb['extras'][2], $pfb['extras'][3], $pfb['extras'][4], $pfb['extras'][5]);
+ pfblockerng_download_extras();
+ break;
+ case 'al': // Update Alexa database only.
+ unset($pfb['extras'][0], $pfb['extras'][1], $pfb['extras'][2], $pfb['extras'][3], $pfb['extras'][4]);
+ pfblockerng_download_extras();
+ break;
+ case 'uc': // Update MaxMind ISO files from local database files.
+ pfblockerng_uc_countries();
+ break;
+ case 'gc': // Update Continent XML files.
+ pfblockerng_get_countries();
+ break;
}
-
- 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, $pfbfolder) {
- global $pfb;
+// Determine if source list file has an updated timestamp
+function pfb_update_check($header, $list_url, $pfbfolder, $pfborig, $pflex, $format) {
+ global $config, $pfb;
+
+ $log = "[ {$header} ]\n";
+ pfb_logger("{$log}", 1);
$pfb['cron_update'] = FALSE;
- if ($url_format == "rsync" || $url_format == "html") {
- $log = "[ {$header_url} ]\n Skipping timestamp query\n";
- pfb_logger("{$log}","1");
- $pfb['cron_update'] = TRUE;
+ // Determine if previous download fails have exceeded threshold.
+ if ($pfb['restore'] == 'on') {
+ if ($pfb['skipfeed'] != 0) {
+ // Call function to get all previous download fails
+ pfb_failures();
+
+ if ($pfb['failed'][$header] >= $pfb['skipfeed']) {
+ $log = " Max daily download failure attempts exceeded. Clear widget 'failed downloads' to reset.\n\n";
+ pfb_logger("{$log}", 1);
+ unlink_if_exists("{$pfbfolder}/{$header}.fail");
+ return;
+ }
+ }
+
+ // Attempt download, when a previous 'fail' file marker is found.
+ if (file_exists("{$pfbfolder}/{$header}.fail")) {
+ $log = "\t\t\tPrevious download failed.\tRe-attempt download\n";
+ pfb_logger("{$log}", 1);
+ $pfb['update_cron'] = TRUE;
+ unlink_if_exists("{$pfbfolder}/{$header}.txt");
+ return;
+ }
+ }
+ else {
+ unlink_if_exists("{$pfbfolder}/{$header}.fail");
}
- 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;
+ // Check if List file doesn't exist or Format is 'whois'.
+ if (!file_exists("{$pfbfolder}/{$header}.txt") || $format == 'whois') {
+ $log = "\t\t\t\t\t\t\tUpdate Found\n";
+ pfb_logger("{$log}", 1);
+ $pfb['update_cron'] = TRUE;
+ return;
}
- $log = "[ {$header_url} ]\n";
- pfb_logger("{$log}","1");
$host = @parse_url($list_url);
- $local_file = "{$pfb['origdir']}/{$header_url}{$type}";
+ $local_file = "{$pfborig}/{$header}.orig";
+
+ // Compare previously downloaded file timestamp with remote timestamp
if (file_exists($local_file)) {
+ if ($format == 'rsync') {
+ $log = "\t\t\t\t( rsync )\t\tUpdate Found\n";
+ pfb_logger("{$log}", 1);
+ $pfb['update_cron'] = TRUE;
+ unlink_if_exists("{$pfbfolder}/{$header}.txt");
+ return;
+ }
+
// 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($list_url));
- } else {
- $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers($list_url)));
- $remote_tds = preg_replace("/^Last-Modified: /","", $remote_tds);
+ if (in_array($host['host'], array('127.0.0.1', $pfb['iplocal'], ''))) {
+ clearstatcache();
+ $remote_tds = gmdate('D, d M Y H:i:s T', @filemtime($list_url));
}
+ else {
+ // Download URL headers and compare previously downloaded file with remote timestamp
+ if (($ch = curl_init($list_url))) {
+ curl_setopt_array($ch, $pfb['curl_defaults']); // Load curl default settings
+ curl_setopt($ch, CURLOPT_NOBODY, true); // Exclude the body from the output
+ curl_setopt($ch, CURLOPT_TIMEOUT, 60);
+
+ // Allow downgrade of cURL settings if user configured
+ if ($pflex == 'Flex') {
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+ curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1.2, TLSv1, SSLv3');
+ }
- $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}") {
- $pfb['cron_update'] = TRUE;
- } else {
- $log = " Remote file unchanged. Download Terminated\n";
- pfb_logger("{$log}","1");
- $pfb['cron_update'] = FALSE;
+ // Try up to 3 times to download the file before giving up
+ for ($retries = 1; $retries <= 3; $retries++) {
+ if (curl_exec($ch)) {
+ $remote_stamp_raw = curl_getinfo($ch, CURLINFO_FILETIME);
+ break; // Break on success
+ }
+ sleep(3);
+ }
+ if ($remote_stamp_raw != -1) {
+ $remote_tds = gmdate('D, d M Y H:i:s T', $remote_stamp_raw);
+ }
+ }
+ else {
+ $remote_stamp_raw = -1;
+ }
+ curl_close($ch);
+ }
+
+ // If remote timestamp not found, Attempt md5 comparison
+ if ($remote_stamp_raw == -1) {
+ // Collect md5 checksums
+ $remote_md5 = @md5_file($list_url);
+ $local_md5 = @md5_file($local_file);
+
+ if ($remote_md5 != $local_md5) {
+ $log = "\t\t\t\t( md5 changed )\t\tUpdate Found\n";
+ pfb_logger("{$log}", 1);
+ $pfb['update_cron'] = TRUE;
+ unlink_if_exists("{$pfbfolder}/{$header}.txt");
+ return;
+ }
+ else {
+ $log = "\t( No remote timestamp/md5 unchanged )\t\tUpdate not required\n";
+ pfb_logger("{$log}", 1);
+ return;
+ }
+ }
+ else {
+ $log = " Remote timestamp: {$remote_tds}\n";
+ pfb_logger("{$log}", 1);
+ clearstatcache();
+ $local_tds = gmdate('D, d M Y H:i:s T', @filemtime($local_file));
+ $log = " Local timestamp: {$local_tds}\t";
+ pfb_logger("{$log}", 1);
+
+ if ("{$remote_tds}" != "{$local_tds}") {
+ $pfb['cron_update'] = TRUE;
+ }
+ else {
+ $log = "Update not required\n";
+ pfb_logger("{$log}", 1);
+ $pfb['cron_update'] = FALSE;
+ }
}
} else {
$pfb['cron_update'] = TRUE;
}
if ($pfb['cron_update']) {
- // Trigger CRON Process if Updates are Found.
+ // Trigger CRON process if updates are found.
$pfb['update_cron'] = TRUE;
- $log = " Updates Found\n";
- pfb_logger("{$log}","1");
- unlink_if_exists($pfbfolder . '/' . $header_url . '.txt');
+ $log = "Update Found\n";
+ pfb_logger("{$log}", 1);
+ unlink_if_exists("{$pfbfolder}/{$header}.txt");
}
+ return;
}
-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");
+// Download Extras - MaxMind/Alexa feeds via cURL
+function pfblockerng_download_extras($timeout=600) {
+ global $pfb;
+ $pfberror = FALSE;
+
+ pfb_logger("\nDownload Process Starting [ NOW ]\n", 3);
+ foreach ($pfb['extras'] as $feed) {
+ $file_dwn = "{$feed['folder']}/{$feed['file_dwn']}";
+ if (!pfb_download($feed['url'], $file_dwn, FALSE, "{$feed['folder']}/{$feed['file']}", '', 3, '', $timeout)) {
+ $log = "\nFailed to Download {$feed['file']}\n";
+ pfb_logger("{$log}", 3);
+
+ // On install, if error found when downloading MaxMind Continent lists
+ // Return error to install process to download archive from pfSense package repo
+ if ($feed['install']) {
+ $pfberror = TRUE;
+ }
+ }
}
- pfblockerng_uc_countries();
- pfblockerng_get_countries();
-
- // Remove Original Maxmind Database Files
- @unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryCSV.zip");
- @unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryWhois.csv");
- @unlink_if_exists("{$pfb['dbdir']}/GeoIPv6.csv");
- @unlink_if_exists("{$pfb['dbdir']}/country_continent.csv");
-}
+ pfb_logger("Download Process Ended [ NOW ]\n\n", 3);
-if ($argv[1] == 'uc') {
- pfblockerng_uc_countries();
+ if ($pfberror) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
}
-if ($argv[1] == 'gc') {
- pfblockerng_get_countries();
-}
-if ($argv[1] == 'cron') {
+// Function to update Lists/Feeds as per Cron
+function pfblockerng_sync_cron() {
+ global $config, $pfb, $pfbarr;
- // Call Base Hour converter
+ // Call base hour converter
$pfb_sch = pfb_cron_base_hour();
$hour = date('G');
$dow = date('N');
$pfb['update_cron'] = FALSE;
$log = " CRON PROCESS START [ NOW ]\n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
- $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ $list_type = array('pfblockernglistsv4' => '_v4', 'pfblockernglistsv6' => '_v6', 'pfblockerngdnsbl' => '_v4', 'pfblockerngdnsbleasylist' => '_v4');
foreach ($list_type as $ip_type => $vtype) {
- if ($config['installedpackages'][$ip_type]['config'] != "") {
+ if (!empty($config['installedpackages'][$ip_type]['config'])) {
foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
- if (is_array($list['row']) && $list['action'] != "Disabled") {
+ if (isset($list['row']) && $list['action'] != 'Disabled' && $list['cron'] != 'Never') {
foreach ($list['row'] as $row) {
- if ($row['url'] != "" && $row['state'] != "Disabled") {
+ if (!empty($row['url']) && $row['state'] != 'Disabled') {
- if ($vtype == "_v4") {
- $header_url = "{$row['header']}";
+ if ($vtype == '_v4') {
+ $header = "{$row['header']}";
} else {
- $header_url = "{$row['header']}_v6";
+ $header = "{$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'];
+ // Determine folder location for alias (return array $pfbarr)
+ pfb_determine_list_detail($list['action'], '', '', '');
+ $pfbfolder = $pfbarr['folder'];
+ $pfborig = $pfbarr['orig'];
- // Bypass update if state is defined as "Hold" and list file exists
- if (file_exists($pfbfolder . '/' . $header_url . '.txt') && $row['state'] == "Hold") {
+ // Bypass update if state is defined as 'Hold' and list file exists
+ if ($row['state'] == 'Hold' && file_exists("{$pfbfolder}/{$header}.txt")) {
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");
- $pfb['update_cron'] = TRUE;
- continue;
+ // Allow cURL SSL downgrade if user configured.
+ $pflex = FALSE;
+ if ($row['state'] == 'Flex') {
+ $pflex = TRUE;
}
- switch ($list_cron) {
- case "EveryDay":
+ switch ($list['cron']) {
+ case 'EveryDay':
if ($hour == $pfb['24hour']) {
- pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ pfb_update_check($header, $row['url'], $pfbfolder, $pfborig, $pflex, $row['format']);
}
break;
- case "Weekly":
- if ($hour == $pfb['24hour'] && $dow == $header_dow) {
- pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ case 'Weekly':
+ if ($hour == $pfb['24hour'] && $dow == $list['dow']) {
+ pfb_update_check($header, $row['url'], $pfbfolder, $pfborig, $pflex, $row['format']);
}
break;
default:
- if ($pfb['interval'] == "1" || in_array($hour, $pfb_sch)) {
- pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ if ($pfb['interval'] == '1' || in_array($hour, $pfb_sch)) {
+ pfb_update_check($header, $row['url'], $pfbfolder, $pfborig, $pflex, $row['format']);
}
break;
}
@@ -321,23 +375,12 @@ if ($argv[1] == 'cron') {
}
}
- // If Continents are Defined, continue with Update Process to determine if further changes are required.
- $continents = array ( "Africa" => "pfB_Africa",
- "Antartica" => "pfB_Antartica",
- "Asia" => "pfB_Asia",
- "Europe" => "pfB_Europe",
- "North America" => "pfB_NAmerica",
- "Oceania" => "pfB_Oceania",
- "South America" => "pfB_SAmerica",
- "Top Spammers" => "pfB_Top",
- "Proxy and Satellite" => "pfB_PS"
- );
-
+ // If no lists require updates, check if Continents are configured and update accordingly.
if (!$pfb['update_cron']) {
- 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") {
+ foreach ($pfb['continents'] as $continent => $pfb_alias) {
+ if (isset($config['installedpackages']['pfblockerng' . strtolower(str_replace(' ', '', $continent))]['config'])) {
+ $continent_config = $config['installedpackages']['pfblockerng' . strtolower(str_replace(' ', '', $continent))]['config'][0];
+ if ($continent_config['action'] != 'Disabled') {
$pfb['update_cron'] = TRUE;
break;
}
@@ -346,104 +389,106 @@ if ($argv[1] == 'cron') {
}
if ($pfb['update_cron']) {
- sync_package_pfblockerng("cron");
+ sync_package_pfblockerng('cron');
+ $pfb['update_cron'] = FALSE;
} else {
- sync_package_pfblockerng("noupdates");
+ sync_package_pfblockerng('noupdates');
$log = "\n No Updates required.\n CRON PROCESS ENDED\n UPDATE PROCESS ENDED\n";
- pfb_logger("{$log}","1");
+ pfb_logger("{$log}", 1);
}
- // Call Log Mgmt Function
+ // 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 to process the downloaded Maxmind Database and format into Continent txt files.
+// Function to process the downloaded MaxMind database and format into Continent txt files.
function pfblockerng_uc_countries() {
- global $g,$pfb;
+ global $pfb;
- $maxmind_cont = "{$pfb['dbdir']}/country_continent.csv";
- $maxmind_cc4 = "{$pfb['dbdir']}/GeoIPCountryWhois.csv";
- $maxmind_cc6 = "{$pfb['dbdir']}/GeoIPv6.csv";
+ $maxmind_cont = "{$pfb['geoipshare']}/country_continent.csv";
+ $maxmind_cc4 = "{$pfb['geoipshare']}/GeoIPCountryWhois.csv";
+ $maxmind_cc6 = "{$pfb['geoipshare']}/GeoIPv6.csv";
- // Create Folders if not Exist
- $folder_array = array ("{$pfb['dbdir']}","{$pfb['logdir']}","{$pfb['ccdir']}");
+ // Create folders if not exist
+ $folder_array = array ("{$pfb['dbdir']}", "{$pfb['logdir']}", "{$pfb['ccdir']}");
foreach ($folder_array as $folder) {
- safe_mkdir ("{$folder}",0755);
+ 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");
+ $now = date('m/d/y G:i:s', time());
+ $log = "Country code update Start [ NOW ]\n";
+ if (!$g['pfblockerng_install']) {
+ print "Country code update Start [ $now ]\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");
+ $log = " [ MAXMIND UPDATE FAIL, CSV missing, using previous Country code database \n";
+ if (!$g['pfblockerng_install']) {
+ 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),array($AX));
- if (($handle = fopen("{$maxmind_cont}",'r')) !== FALSE) {
- while (($cc = fgetcsv($handle)) !== FALSE) {
+ // Save Date/Time stamp to MaxMind version file
+ $local_tds4 = @gmdate('D, d M Y H:i:s T', @filemtime($maxmind_cc4));
+ $local_tds6 = @gmdate('D, d M Y H:i:s T', @filemtime($maxmind_cc6));
+ $maxmind_ver = "MaxMind GeoLite Date/Time Stamps\n";
+ $maxmind_ver .= "Local_v4 \tLast-Modified: {$local_tds4}\n";
+ $maxmind_ver .= "Local_v6 \tLast-Modified: {$local_tds6}\n";
+ @file_put_contents("{$pfb['logdir']}/maxmind_ver", $maxmind_ver, LOCK_EX);
+
+ // Collect ISO codes for each Continent
+ $log = " Processing Continent Data\n";
+ if (!$g['pfblockerng_install']) {
+ print $log;
+ }
+ pfb_logger("{$log}", 3);
+ $cont_array = array();
+ 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},";
+ 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},";
+ 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},";
+ 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},";
+ 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},";
+ 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},";
+ 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;
@@ -454,64 +499,63 @@ function pfblockerng_uc_countries() {
fclose($handle);
// Add Maxmind Anonymous Proxy and Satellite Providers to array
- $cont_array[6]['continent'] = "Proxy and Satellite";
- $cont_array[6]['iso'] = "A1,A2";
+ $cont_array[6]['continent'] = 'Proxy and Satellite';
+ $cont_array[6]['iso'] = 'A1,A2';
$cont_array[6]['file4'] = "{$pfb['ccdir']}/Proxy_Satellite_v4.txt";
$cont_array[6]['file6'] = "{$pfb['ccdir']}/Proxy_Satellite_v6.txt";
+ sort($cont_array);
+
// Collect Country ISO data and sort to Continent arrays (IPv4 and IPv6)
- foreach (array("4", "6") as $type) {
- $log = "Processing ISO IPv{$type} Continent/Country Data\n";
- print $log;
- pfb_logger("{$log}","3");
+ foreach (array('4', '6') as $type) {
+ $log = " Processing ISO IPv{$type} Continent/Country Data\n";
+ if (!$g['pfblockerng_install']) {
+ print $log;
+ }
+ pfb_logger("{$log}", 3);
- if ($type == "4") {
- $maxmind_cc = "{$pfb['dbdir']}/GeoIPCountryWhois.csv";
+ if ($type == '4') {
+ $maxmind_cc = "{$pfb['geoipshare']}/GeoIPCountryWhois.csv";
} else {
- $maxmind_cc = "{$pfb['dbdir']}/GeoIPv6.csv";
+ $maxmind_cc = "{$pfb['geoipshare']}/GeoIPv6.csv";
}
$iptype = "ip{$type}";
$filetype = "file{$type}";
- if (($handle = fopen("{$maxmind_cc}",'r')) !== FALSE) {
+ if (($handle = fopen("{$maxmind_cc}", 'r')) !== FALSE) {
while (($cc = fgetcsv($handle)) !== FALSE) {
$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][$iptype] .= $a_cidr . ",";
- $cont_array[$counter][$cc_key]['country'] = $country_key;
+ $a_cidr = implode(',', ip_range_to_subnet_array_temp($cc[0], $cc[1]));
+ foreach ($cont_array as $key => $iso) {
+ if (strpos($iso['iso'], $cc_key) !== FALSE) {
+ $cont_array[$key][$cc_key][$iptype] .= "{$a_cidr},";
+ $cont_array[$key][$cc_key]['country'] = $country_key;
continue;
}
- $counter++;
}
}
}
unset($cc);
fclose($handle);
- // Build Continent 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 IPv{$type}: " . $cont_array[$counter]['continent'] . "\n";
- $pfb_file = $cont_array[$counter][$filetype];
+ // Build Continent files
+ foreach ($cont_array as $key => $iso) {
+ $header = $pfb_file = $iso_key = '';
+ $header .= '# Generated from MaxMind Inc. on: ' . date('m/d/y G:i:s', time()) . "\n";
+ $header .= "# Continent IPv{$type}: {$cont_array[$key]['continent']}\n";
+ $pfb_file = $cont_array[$key][$filetype];
$iso_key = array_keys($iso);
- foreach ($iso_key as $key) {
- if (preg_match("/[A-Z]{2}|A1|A2/", $key)) {
- $header .= "# Country: " . $iso[$key]['country'] . "\n";
- $header .= "# ISO Code: " . $key . "\n";
- $header .= "# Total Networks: " . substr_count($iso[$key][$iptype], ",") . "\n";
- $header .= str_replace(",", "\n", $iso[$key][$iptype]);
- $iso[$key][$iptype] = "";
+
+ foreach ($iso_key as $ikey) {
+ if (strlen($ikey) == 2) {
+ $header .= "# Country: {$iso[$ikey]['country']}\n";
+ $header .= "# ISO Code: {$ikey}\n";
+ $header .= '# Total Networks: ' . substr_count($iso[$ikey][$iptype], ',') . "\n";
+ $header .= str_replace(',', "\n", $iso[$ikey][$iptype]);
+ $iso[$ikey][$iptype] = '';
}
}
- $counter++;
@file_put_contents($pfb_file, $header, LOCK_EX);
}
}
@@ -520,73 +564,92 @@ function pfblockerng_uc_countries() {
// Function to process Continent txt files and create Country ISO files and to Generate GUI XML files.
function pfblockerng_get_countries() {
- global $g,$pfb;
-
- $files = 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",
- "Proxy and Satellite" => "{$pfb['ccdir']}/Proxy_Satellite_v4.txt"
+ global $pfb;
+
+ $files = 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",
+ 'Proxy and Satellite' => "{$pfb['ccdir']}/Proxy_Satellite_v4.txt"
);
- // Collect Data to generate new continent XML Files.
- $log = "Building pfBlockerNG XML Files \n";
- print $log;
- pfb_logger("{$log}","3");
+ // Collect data to generate new continent XML files.
+ $log = " Building pfBlockerNG XML Files \n";
+ if (!$g['pfblockerng_install']) {
+ print $log;
+ }
+ pfb_logger("{$log}", 3);
foreach ($files as $cont => $file) {
// Process the following for IPv4 and IPv6
- foreach (array("4", "6") as $type) {
- $log = "IPv{$type} " . $cont . "\n";
- print $log;
- pfb_logger("{$log}","3");
+ foreach (array('4', '6') as $type) {
+ $log = " IPv{$type} {$cont}\n";
+ if (!$g['pfblockerng_install']) {
+ print $log;
+ }
+ pfb_logger("{$log}", 3);
- if ($type == "6")
- $file = preg_replace("/v4/", "v6", $file);
+ if ($type == '6') {
+ $file = str_replace('v4', 'v6', $file);
+ }
$convert = explode("\n", file_get_contents($file));
- $cont_name = preg_replace("/ /", "", $cont);
+ $cont_name = str_replace(' ', '', $cont);
$cont_name_lower = strtolower($cont_name);
$active = array("$cont" => '<active/>');
- $lastkey = count ($convert) - 1;
+ $lastkey = count($convert) - 1;
$pfb['complete'] = FALSE;
$keycount = 1;
$total = 0;
+ $xml_data = '';
foreach ($convert as $line) {
- if (preg_match("/#/",$line)) {
+ if (substr($line, 0, 1) == '#') {
if ($pfb['complete']) {
- ${'coptions' . $type}[] = $country . '-' . $isocode . ' ('. $total .') ' . ' </name><value>' . $isocode . '</value></option>';
- // Only collect IPv4 for Reputation Tab
- if ($type == "4")
- $roptions4[] = $country . '-' . $isocode . ' ('. $total .') ' . ' </name><value>' . $isocode . '</value></option>';
-
+ ${'coptions' . $type}[] = "{$country}-{$isocode} ({$total})</name><value>{$isocode}</value></option>";
+ // Only collect IPv4 for Reputation Tab
+ if ($type == '4') {
+ $roptions4[] = "{$country}-{$isocode} ({$total})</name><value>{$isocode}</value></option>";
+ }
// Save ISO data
- @file_put_contents($pfb['ccdir'] . '/' . $isocode . '_v' . $type . '.txt', $xml_data, LOCK_EX);
+ @file_put_contents("{$pfb['ccdir']}/{$isocode}_v{$type}.txt", $xml_data, LOCK_EX);
// Clear variables and restart Continent collection process
unset($total, $xml_data);
$pfb['complete'] = FALSE;
}
- if (preg_match("/Total Networks: 0/", $line)) { continue;} // Don't Display Countries with Null Data
- if (preg_match("/Country:\s(.*)/",$line, $matches)) { $country = $matches[1];}
- if (preg_match("/ISO Code:\s(.*)/",$line, $matches)) { $isocode = $matches[1];}
+ // Don't collect Countries with null data
+ if (strpos($line, 'Total Networks: 0') !== FALSE) {
+ continue;
+ }
+ if (strpos($line, 'Country: ') !== FALSE) {
+ $country = str_replace('# Country: ', '', $line);
+ }
+ if (strpos($line, 'ISO Code: ') !== FALSE) {
+ $isocode = str_replace('# ISO Code: ', '', $line);
+ }
+
}
- elseif (!preg_match("/#/",$line)) {
+ elseif (substr($line, 0, 1) != '#') {
$total++;
- if (!empty($line))
- $xml_data .= $line . "\n";
+ if (!empty($line)) {
+ $xml_data .= "{$line}\n";
+ }
$pfb['complete'] = TRUE;
}
// Save last EOF ISO IP data
if ($keycount == $lastkey) {
- if (preg_match("/Total Networks: 0/", $line)) { continue;} // Dont Display Countries with Null Data
- ${'coptions' . $type}[] = $country . '-' . $isocode . ' ('. $total .') ' . ' </name><value>' . $isocode . '</value></option>';
- if ($type == "4")
- $roptions4[] = $country . '-' . $isocode . ' ('. $total .') ' . ' </name><value>' . $isocode . '</value></option>';
- @file_put_contents($pfb['ccdir'] . '/' . $isocode . '_v' . $type . '.txt', $xml_data, LOCK_EX);
+ // Don't collect Countries with null data
+ if (strpos($line, 'Total Networks: 0') !== FALSE) {
+ continue;
+ }
+ ${'coptions' . $type}[] = "{$country}-{$isocode} ({$total})</name><value>{$isocode}</value></option>";
+ if ($type == '4') {
+ $roptions4[] = "{$country}-{$isocode} ({$total})</name><value>{$isocode}</value></option>";
+ }
+ @file_put_contents("{$pfb['ccdir']}/{$isocode}_v{$type}.txt", $xml_data, LOCK_EX);
unset($total, $xml_data);
}
$keycount++;
@@ -594,33 +657,36 @@ function pfblockerng_get_countries() {
unset ($ips, $convert);
// Sort IP Countries alphabetically and build XML <option> data for Continents tab
- if (!empty (${'coptions' . $type})) {
+ if (!empty(${'coptions' . $type})) {
sort(${'coptions' . $type}, SORT_STRING);
${'ftotal' . $type} = count(${'coptions' . $type});
$count = 1;
- ${'options' . $type} = "";
+ ${'options' . $type} = '';
foreach (${'coptions' . $type} as $option) {
- if ($count == 1) { ${'options' . $type} .= "\t" . '<option><name>' . $option . "\n"; $count++; continue;}
+ if ($count == 1) {
+ ${'options' . $type} .= "\t<option><name>{$option}\n";
+ $count++;
+ continue;
+ }
if (${'ftotal' . $type} == $count) {
- ${'options' . $type} .= "\t\t\t\t" . '<option><name>' . $option;
+ ${'options' . $type} .= "\t\t\t\t<option><name>{$option}";
} else {
- ${'options' . $type} .= "\t\t\t\t" . '<option><name>' . $option . "\n";
+ ${'options' . $type} .= "\t\t\t\t<option><name>{$option}\n";
}
$count++;
}
}
- unset (${'coptions' . $type});
+ unset(${'coptions' . $type});
}
$xml = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
-<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
<packagegui>
<copyright>
<![CDATA[
-/* \$Id\$ */
/* ========================================================================== */
/*
pfblockerng_{$cont_name}.xml
@@ -673,12 +739,12 @@ $xml = <<<EOF
<name>pfBlockerNG: {$cont_name}</name>
<tooltiptext>Configure pfBlockerNG</tooltiptext>
<section>Firewall</section>
- <url>pkg_edit.php?xml=pfblockerng_{$cont_name_lower}.xml&amp;id=0</url>
+ <url>pkg_edit.php?xml=pfblockerng_{$cont_name_lower}.xml</url>
</menu>
<tabs>
<tab>
<text>General</text>
- <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
</tab>
<tab>
<text>Update</text>
@@ -690,53 +756,70 @@ $xml = <<<EOF
</tab>
<tab>
<text>Reputation</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml</url>
</tab>
<tab>
<text>IPv4</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url>
</tab>
<tab>
<text>IPv6</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url>
+ </tab>
+ <tab>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ </tab>
+ <tab>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
</tab>
<tab>
<text>Top 20</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
+ <tab_level>2</tab_level>
+ {$active['top']}
</tab>
<tab>
<text>Africa</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml</url>
+ <tab_level>2</tab_level>
{$active['Africa']}
</tab>
<tab>
<text>Asia</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml</url>
+ <tab_level>2</tab_level>
{$active['Asia']}
</tab>
<tab>
<text>Europe</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml</url>
+ <tab_level>2</tab_level>
{$active['Europe']}
</tab>
<tab>
- <text>N.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
+ <text>North America</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml</url>
+ <tab_level>2</tab_level>
{$active['North America']}
</tab>
<tab>
<text>Oceania</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml</url>
+ <tab_level>2</tab_level>
{$active['Oceania']}
</tab>
<tab>
- <text>S.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
+ <text>South America</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml</url>
+ <tab_level>2</tab_level>
{$active['South America']}
</tab>
<tab>
- <text>P.S.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ <text>Proxy and Satellite</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml</url>
+ <tab_level>2</tab_level>
{$active['Proxy and Satellite']}
</tab>
<tab>
@@ -745,25 +828,25 @@ $xml = <<<EOF
</tab>
<tab>
<text>Sync</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml</url>
</tab>
</tabs>
<fields>
<field>
- <name><![CDATA[Continent {$cont}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Geolite Data by MaxMind Inc. - ISO 3166)]]></name>
+ <name><![CDATA[Continent {$cont}&emsp; (Geolite Data by MaxMind Inc. - ISO 3166)]]></name>
<type>listtopic</type>
</field>
<field>
<fielddescr>LINKS</fielddescr>
- <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp;
- <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
</description>
<type>info</type>
</field>
<field>
<fieldname>countries4</fieldname>
<fielddescr><![CDATA[<strong><center>Countries</center></strong><br />
- <center>Use CTRL + CLICK to unselect countries</center>]]>
+ <center>Use CTRL + CLICK to select/unselect countries</center>]]>
</fielddescr>
<type>select</type>
<options>
@@ -840,15 +923,13 @@ $xml .= <<<EOF
<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 &nbsp;&nbsp; - Alias Deny,&nbsp; Alias Permit,&nbsp; Alias Match,&nbsp; Alias Native</strong></li><br />
+ <ul><li><strong>Options &emsp;- Alias Deny,&nbsp; Alias Permit,&nbsp; Alias Match,&nbsp; 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 />]]>
+ <font color='red'>Note: </font><ul>When manually creating 'Alias' type firewall rules; <strong>Do not add</strong> (pfB_) to the
+ start of the rule description, use (pfb_) (Lowercase prefix). Manually created 'Alias' rules with 'pfB_' in the
+ description will be auto-removed by package when 'Auto' rules are defined.</ul>]]>
</description>
<fieldname>action</fieldname>
<type>select</type>
@@ -888,8 +969,8 @@ $xml .= <<<EOF
</field>
<field>
<type>info</type>
- <description><![CDATA[<font color='red'>Note: </font>In general Auto-Rules are created as follows:<br />
- <ul>Inbound &nbsp;&nbsp;- 'any' port, 'any' protocol and 'any' destination<br />
+ <description><![CDATA[<font color='red'>Note: </font>In general, Auto-Rules are created as follows:<br />
+ <ul>Inbound &emsp;- 'any' port, 'any' protocol and 'any' destination<br />
Outbound - 'any' port, 'any' protocol and 'any' destination address in the lists</ul>
Configuring the Adv. Inbound Rule settings, will allow for more customization of the Inbound Auto-Rules.<br />
<strong>Select the pfSense 'Port' and/or 'Destination' Alias below:</strong>]]>
@@ -950,7 +1031,8 @@ $xml .= <<<EOF
<field>
<fielddescr>Custom Protocol</fielddescr>
<fieldname>autoproto</fieldname>
- <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).]]></description>
+ <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).<br />
+ Do not use 'any' with Adv. Inbound Rules as it will bypass these settings!]]></description>
<type>select</type>
<options>
<option><name>any</name><value></value></option>
@@ -962,17 +1044,11 @@ $xml .= <<<EOF
<default_value></default_value>
</field>
<field>
- <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
'Force Update'</center>]]></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>
@@ -984,41 +1060,42 @@ $xml .= <<<EOF
</packagegui>
EOF;
- // Update Each Continent XML file.
- @file_put_contents('/usr/local/pkg/pfblockerng/pfblockerng_'.$cont_name.'.xml',$xml,LOCK_EX);
+ // Update each Continent XML file.
+ @file_put_contents('/usr/local/pkg/pfblockerng/pfblockerng_'.$cont_name.'.xml', $xml,LOCK_EX);
// Unset Arrays
unset (${'options4'}, ${'options6'}, $xml);
- } // End foreach 'Six Continents and Proxy/Satellite' Update XML Process
+ } // End foreach 'Six Continents and Proxy/Satellite' update XML process
- // Sort Countries IPv4 Alphabetically and Build XML <option> Data for Reputation Tab (IPv6 not used by ET IQRisk)
+ // 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);
+ $etoptions = '';
$count = 1;
- $etoptions = "";
foreach ($roptions4 as $option4) {
- if ($count == 1) { $et_options .= "\t" . '<option><name>' . $option4 . "\n"; $count++; continue; }
+ if ($count == 1) {
+ $et_options .= "\t<option><name>{$option4}\n"; $count++; continue;
+ }
if ($eoa == $count) {
- $et_options .= "\t\t\t\t" . '<option><name>' . $option4;
+ $et_options .= "\t\t\t\t<option><name>{$option4}";
} else {
- $et_options .= "\t\t\t\t" . '<option><name>' . $option4 . "\n";
+ $et_options .= "\t\t\t\t<option><name>{$option4}\n";
}
$count++;
}
-// Update pfBlockerNG_Reputation.xml file with Country Code Changes
+// 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"?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
<packagegui>
<copyright>
<![CDATA[
-/* \$Id\$ */
/* ========================================================================== */
/*
pfBlockerNG_Reputation.xml
@@ -1070,12 +1147,12 @@ $xmlrep = <<<EOF
<name>pfBlockerNG</name>
<tooltiptext>Configure pfblockerNG</tooltiptext>
<section>Firewall</section>
- <url>pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>pkg_edit.php?xml=pfblockerng.xml</url>
</menu>
<tabs>
<tab>
<text>General</text>
- <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
</tab>
<tab>
<text>Update</text>
@@ -1087,48 +1164,24 @@ $xmlrep = <<<EOF
</tab>
<tab>
<text>Reputation</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml</url>
<active/>
</tab>
<tab>
<text>IPv4</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url>
</tab>
<tab>
<text>IPv6</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Top 20</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url>
</tab>
<tab>
- <text>Africa</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
</tab>
<tab>
- <text>Asia</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Europe</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>N.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Oceania</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>S.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>P.S.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
</tab>
<tab>
<text>Logs</text>
@@ -1136,7 +1189,7 @@ $xmlrep = <<<EOF
</tab>
<tab>
<text>Sync</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml</url>
</tab>
</tabs>
<fields>
@@ -1146,8 +1199,8 @@ $xmlrep = <<<EOF
</field>
<field>
<fielddescr>LINKS</fielddescr>
- <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp;
- <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
</description>
<type>info</type>
</field>
@@ -1155,7 +1208,7 @@ $xmlrep = <<<EOF
<fielddescr><![CDATA[<strong>Why Reputation Matters:</strong>]]></fielddescr>
<type>info</type>
<description><![CDATA[By Enabling '<strong>Reputation</strong>', each Blocklist will be analyzed for Repeat Offenders in each IP Range.
- <ul>Example: &nbsp;&nbsp; x.x.x.1, x.x.x.2, x.x.x.3, x.x.x.4, x.x.x.5<br />
+ <ul>Example: &emsp;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> [ &nbsp;<strong>5</strong>&nbsp; ], 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 />
@@ -1184,7 +1237,7 @@ $xmlrep = <<<EOF
<description><![CDATA[Enables Search for Repeat Offenders in a /24 Range on <strong>Each Individual Blocklist</strong>]]></description>
</field>
<field>
- <fielddescr><![CDATA[&nbsp;&nbsp;&nbsp;[ <strong>Max</strong> ] Setting]]></fielddescr>
+ <fielddescr><![CDATA[&emsp;[ <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>
@@ -1224,7 +1277,7 @@ $xmlrep = <<<EOF
</description>
</field>
<field>
- <fielddescr><![CDATA[&nbsp;&nbsp;&nbsp;[ <strong>pMax</strong> ] Setting]]></fielddescr>
+ <fielddescr><![CDATA[&emsp;[ <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>
@@ -1245,7 +1298,7 @@ $xmlrep = <<<EOF
</description>
</field>
<field>
- <fielddescr><![CDATA[&nbsp;&nbsp;&nbsp;[ <strong>dMax</strong> ] Setting]]></fielddescr>
+ <fielddescr><![CDATA[&emsp;[ <strong>dMax</strong> ] Setting]]></fielddescr>
<fieldname>p24_dmax_var</fieldname>
<description><![CDATA[Default: <strong>5</strong><br />
Maximum number of Repeat Offenders]]></description>
@@ -1260,7 +1313,7 @@ $xmlrep = <<<EOF
</options>
</field>
<field>
- <name>Country Code Settings</name>
+ <name>Country Code Settings (max/dMax)</name>
<type>listtopic</type>
</field>
<field>
@@ -1305,11 +1358,11 @@ $xmlrep = <<<EOF
</field>
<field>
<fielddescr><![CDATA[<br /><strong>IPv4</strong><br />Country Exclusion<br />
- <br />Geolite Data by: <br />MaxMind Inc.&nbsp;&nbsp;(ISO 3166)]]></fielddescr>
+ <br />Geolite Data by: <br />MaxMind Inc.&emsp;(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>]]>
+ <strong>Use CTRL + CLICK to select/unselect countries</strong>]]>
</description>
<type>select</type>
<options>
@@ -1319,18 +1372,19 @@ $xmlrep = <<<EOF
<multiple/>
</field>
<field>
- <name>Emerging Threats IQRISK IPv4 Reputation</name>
+ <name>Proofpoint ET IQRISK IPv4 Reputation</name>
<type>listtopic</type>
</field>
<field>
<fielddescr>Subscription Pro. Blocklist</fielddescr>
<type>info</type>
- <description><![CDATA[<strong>Emerging Threats IQRisk</strong> is a Subscription Professional Reputation List.<br /><br />
+ <description><![CDATA[<strong>Proofpoint ET IQRisk</strong> is a Subscription Professional Reputation List.<br /><br />
+ <strong>The URL must include the name 'iprepdata.txt' for the filename.</strong><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 />
+ <a target="_blank" 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>
@@ -1351,7 +1405,7 @@ $xmlrep = <<<EOF
<fieldname>etblock</fieldname>
<description>
<![CDATA[Select Lists you want to BLOCK.<br />
- <strong>Use CTRL + CLICK to unselect Categories</strong>
+ <strong>Use CTRL + CLICK to select/unselect Categories</strong>
<br /><br />Any Changes will take effect at the Next Scheduled CRON Task]]>
</description>
<type>select</type>
@@ -1400,7 +1454,7 @@ $xmlrep = <<<EOF
<fieldname>etmatch</fieldname>
<description>
<![CDATA[Select Lists you want to MATCH.<br />
- <strong>Use CTRL + CLICK to unselect Categories</strong>
+ <strong>Use CTRL + CLICK to select/unselect Categories</strong>
<br /><br />Any Changes will take effect at the Next Scheduled CRON Task]]>
</description>
<type>select</type>
@@ -1459,17 +1513,11 @@ $xmlrep = <<<EOF
</options>
</field>
<field>
- <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
'Force Update'</center>]]></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>
@@ -1480,22 +1528,23 @@ $xmlrep = <<<EOF
</custom_php_resync_config_command>
</packagegui>
EOF;
- $log = "Saving pfBlockerNG Reputation TAB \n";
- print $log;
- pfb_logger("{$log}","3");
+ $log = " Saving pfBlockerNG Reputation TAB\n";
+ if (!$g['pfblockerng_install']) {
+ 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");
+ $now = date('m/d/y G.i:s', time());
+ $log = "Country Code Update Ended - [ NOW ]\n\n";
+ if (!$g['pfblockerng_install']) {
+ print "Country Code Update Ended - [ $now ]\n\n";
+ }
+ pfb_logger("{$log}", 3);
- // Unset Arrays
+ // Unset arrays
unset ($roptions4, $et_options, $xmlrep);
}
?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.priv.inc b/config/pfblockerng/pfblockerng.priv.inc
index 97cf6288..0b50ef84 100644
--- a/config/pfblockerng/pfblockerng.priv.inc
+++ b/config/pfblockerng/pfblockerng.priv.inc
@@ -17,16 +17,23 @@ $priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblocker
$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_ProxyandSatellite.xml*";
$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_sync.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_dnsbl.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_dnsbl_easylist.xml*";
$priv_list['page-firewall-pfblockerng']['match'][] = "pkg.php?xml=pfblockerng/pfblockerng_v4lists.xml*";
$priv_list['page-firewall-pfblockerng']['match'][] = "pkg.php?xml=pfblockerng/pfblockerng_v6lists.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg.php?xml=pfblockerng/pfblockerng_dnsbl_lists.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_alerts_ar.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'][] = "pfblockerng/pfblockerng_threats.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*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_extra.inc*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_install.inc*";
+$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
index 5858b08b..ace6dbfe 100644
--- a/config/pfblockerng/pfblockerng.sh
+++ b/config/pfblockerng/pfblockerng.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# pfBlockerNG IP Reputation Script - By BBcan177@gmail.com - 04-12-14
-# Copyright (C) 2015 BBcan177@gmail.com
+# Copyright (c) 2015 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
@@ -13,951 +13,951 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-pfs_version=$(cat /etc/version | cut -c 1-3)
-
-if [ "${pfs_version}" = "2.2" ]; then
+pfs_version=$(/bin/cat /etc/version | /usr/bin/cut -c 1-3)
+if [ "${pfs_version}" = '2.2' ]; then
mtype=$(/usr/bin/uname -m)
prefix="/usr/pbi/pfblockerng-${mtype}"
else
- prefix="/usr/local"
+ prefix='/usr/local'
fi
now=$(/bin/date +%m/%d/%y' '%T)
# Application Locations
pathgrepcidr="${prefix}/bin/grepcidr"
+pathaggregate="${prefix}/bin/aggregate"
+pathmwhois="${prefix}/bin/mwhois"
pathgeoip="${prefix}/bin/geoiplookup"
-
-pathtar=/usr/bin/tar
pathgunzip=/usr/bin/gunzip
+pathhost=/usr/bin/host
+pathtar=/usr/bin/tar
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')
+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
aliasarchive="${prefix}/etc/aliastables.tar.bz2"
pathgeoipdat="${prefix}/share/GeoIP/GeoIP.dat"
pfbsuppression=/var/db/pfblockerng/pfbsuppression.txt
+pfbalexa=/var/db/pfblockerng/pfbalexawhitelist.txt
masterfile=/var/db/pfblockerng/masterfile
mastercat=/var/db/pfblockerng/mastercat
geoiplog=/var/log/pfblockerng/geoip.log
errorlog=/var/log/pfblockerng/error.log
+domainmaster=/tmp/domainmaster
# Folder Locations
etdir=/var/db/pfblockerng/ET
tmpxlsx=/tmp/xlsx/
-pfbdbdir=/var/db/pfblockerng/
+pfbdb=/var/db/pfblockerng/
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/
+pfsensealias=/var/db/aliastables/
+pfbdomain=/var/db/pfblockerng/dnsbl/
-# Store "Match" d-dedups in matchdedup.txt file
+# 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
-
-PLATFORM=`cat /etc/platform`
-USE_MFS_TMPVAR=`/usr/bin/grep -c use_mfs_tmpvar /cf/conf/config.xml`
-DISK_NAME=`/bin/df /var/db/rrd | /usr/bin/tail -1 | /usr/bin/awk '{print $1;}'`
-DISK_TYPE=`/usr/bin/basename ${DISK_NAME} | /usr/bin/cut -c1-2`
-
-if [ "${PLATFORM}" != "pfSense" ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = "md" ]; then
- /etc/rc.conf_mount_rw >/dev/null 2>&1
- if [ ! -d $pfbdbdir ]; then mkdir $pfbdbdir; fi
- if [ ! -d $pfsense_alias_dir ]; then mkdir $pfsense_alias_dir; fi
+# Randomize temporary variables
+rvar="$(/usr/bin/jot -r 1 1000 100000)"
+
+tempfile=/tmp/pfbtemp1_$rvar
+tempfile2=/tmp/pfbtemp2_$rvar
+dupfile=/tmp/pfbtemp3_$rvar
+dedupfile=/tmp/pfbtemp4_$rvar
+addfile=/tmp/pfbtemp5_$rvar
+syncfile=/tmp/pfbtemp6_$rvar
+matchfile=/tmp/pfbtemp7_$rvar
+tempmatchfile=/tmp/pfbtemp8_$rvar
+
+PLATFORM="$(cat /etc/platform)"
+USE_MFS_TMPVAR="$(/usr/bin/grep -c use_mfs_tmpvar /cf/conf/config.xml)"
+DISK_NAME="$(/bin/df /var/db/rrd | /usr/bin/tail -1 | /usr/bin/awk '{print $1;}')"
+DISK_TYPE="$(/usr/bin/basename ${DISK_NAME} | /usr/bin/cut -c1-2)"
+
+if [ "${PLATFORM}" != 'pfSense' ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = 'md' ]; then
+ /etc/rc.conf_mount_rw > /dev/null 2>&1
fi
-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
-
-
-# Exit Function to set mount RO if required before Exiting
+if [ ! -d "${pfbdb}" ]; then mkdir "${pfbdb}"; fi
+if [ ! -d "${pfsensealias}" ]; then mkdir "${pfsensealias}"; fi
+if [ ! -d "${pfbmatch}" ]; then mkdir "${pfbmatch}"; fi
+if [ ! -d "${etdir}" ]; then mkdir "${etdir}"; fi
+if [ ! -d "${tmpxlsx}" ]; then mkdir "${tmpxlsx}"; fi
+
+if [ ! -f "${masterfile}" ]; then touch "${masterfile}"; fi
+if [ ! -f "${mastercat}" ]; then touch "${mastercat}"; fi
+
+
+# Exit function to set mount RO if required before exiting.
exitnow() {
- if [ "${PLATFORM}" != "pfSense" ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = "md" ]; then
- /etc/rc.conf_mount_ro >/dev/null 2>&1
+ if [ "${PLATFORM}" != 'pfSense' ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = 'md' ]; then
+ /etc/rc.conf_mount_ro > /dev/null 2>&1
fi
+
+ # Remove temp files
+ rm -f /tmp/pfbtemp?_"${rvar}"
exit
}
-##########
-# 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
- exitnow
-fi
+# Function to restore aliasables from archive on reboot. ( NanoBSD and Ramdisk installations only )
+aliastables() {
+ if [ "${PLATFORM}" != 'pfSense' ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = 'md' ]; then
+ [ -f "${aliasarchive}" ] && cd "${pfsensealias}" && /usr/bin/tar -jxvf "${aliasarchive}"
+ 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
- exitnow
-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
+# Function to write '1.1.1.1' to 'empty' final blocklist files.
+emptyfiles() {
+ emptyfiles="$(find ${pfbdeny}*.txt -size 0 2>/dev/null)"
+ for i in ${emptyfiles}; do
+ echo '1.1.1.1' > "${i}";
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
+}
+
+
+# Function to remove lists from masterfiles and delete associated files.
+remove() {
+ echo
+ for i in ${cc}; do
+ header="$(echo ${i%*,})"
+ if [ ! -z "${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}"
+ 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
+ rm -f "${pfborig}${header}"*; rm -f "${pfbdeny}${header}"*; rm -f "${pfbmatch}${header}"*;
+ rm -f "${pfbpermit}${header}"*; rm -f "${pfbnative}${header}"*
+ echo "The Following list has been REMOVED [ ${header} ]"
+ fi
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
- :
+ cut -d ' ' -f2 "${masterfile}" > "${mastercat}"
+
+ # Delete masterfiles if they are empty
+ if [ ! -s "${masterfile}" ]; then
+ rm -f "${masterfile}"; rm -f "${mastercat}"
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
-exitnow
}
-##########
+# Function to remove IPs if exists over 253 IPs in a range and replace with a single /24 block. (excl. '0' & '255')
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
-}
+ > "${dedupfile}"
+ data255="$(cut -d '.' -f 1-3 ${pfbdeny}${alias}.txt | awk '{a[$0]++}END{for(i in a){if(a[i] > 253){print i}}}')"
+ if [ ! -z "${data255}" ]; then
+ cp "${pfbdeny}${alias}.txt" "${tempfile}"
-##########
-continent() {
+ for ip in ${data255}; do
+ ii="$(echo ^${ip}. | sed 's/\./\\\./g')"
+ grep "${ii}" "${tempfile}" >> "${dedupfile}"
+ done
-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
-# Check for single alias in masterfile
-aliaslist=$(cut -d' ' -f1 $masterfile | sort | uniq); if [ "$alias" == "$aliaslist" ]; then hcheck="0"; fi
+ 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
+}
-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
+# Process to remove suppressed entries.
+suppress() {
+ if [ ! -x "${pathgrepcidr}" ]; then
+ log="Application [ grepcidr ] Not found. Cannot proceed."
+ echo "${log}" | tee -a "${errorlog}"
+ exitnow
+ fi
-grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile
+ if [ -e "${pfbsuppression}" ] && [ -s "${pfbsuppression}" ]; then
+ data="$(cat ${pfbsuppression} | sort | uniq)"
-if [ ! "$hcheck" -eq "0" ]; then
- $pathgrepcidr -vf $mastercat $pfbdeny$alias".txt" > $tempfile; mv -f $tempfile $pfbdeny$alias".txt"
-fi
+ if [ ! -z "${data}" ] && [ ! -z "${cc}" ]; then
+ if [ "${cc}" == 'suppressheader' ]; then
+ echo; echo '===[ Suppression Stats ]==================================='; echo
+ printf "%-20s %-10s %-10s %-10s\n" 'List' 'Pre' 'Suppress' 'Master'
+ echo '-----------------------------------------------------------'
+ exitnow
+ 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 "----------------------------------------------------------"
-exitnow
-}
+ alias="$(echo ${cc%|*})"
+ pfbfolder="$(echo ${cc#*|})"
+ counter=0; > "${dupfile}"
+ if [ ! -z "${alias}" ]; then
+ countg="$(grep -c ^ ${pfbfolder}${alias}.txt)"
+ cp "${pfbfolder}${alias}.txt" "${tempfile}"
-##########
-# Process to remove Suppressed Entries and RFC 1918 and Misc IPs on each downloaded Blocklist
-suppress() {
+ for ip in ${data}; do
+ found=''; dcheck='';
+ mask="$(echo ${ip##*/})"
+ iptrim="$(echo "${ip%.*}")"
+ ip="$(echo ${ip%%/*})"
+ found="$(grep -m1 ${iptrim}.0/24 ${tempfile})"
-if [ ! -x $pathgrepcidr ]; then
- echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]"
- echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" >> errorlog
- exitnow
-fi
+ # If a suppression is '/32' and a blocklist has a full '/24' block, execute the following.
+ if [ ! -z "${found}" ] && [ "${mask}" -eq 32 ]; then
+ echo " Suppression ${alias}: ${iptrim}.0/24"
+ octet4="$(echo ${ip##*.})"
+ dcheck="$(grep ${iptrim}.0/24 ${dupfile})"
-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 "----------------------------------------------------------------"
- exitnow
- fi
+ if [ -z "${dcheck}" ]; then
+ echo "${iptrim}.0/24" >> "${dupfile}"
+ counter="$((counter + 1))"
- 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/24" >> $dupfile
- counter=$(($counter + 1))
- # Add Individual IP addresses from Range excluding Suppressed IP
+ # 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))
+ 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
+
+ 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
+
+ # Remove all other suppressions from list
+ "${pathgrepcidr}" -vf "${pfbsuppression}" "${tempfile}" > "${pfbfolder}${alias}.txt"
+
+ # Update masterfiles. Don't execute if duplication process is disabled
+ if [ "${dedup}" == 'x' ]; then
+ # Don't execute if alias doesn't exist in masterfile
+ lcheck="$(grep -m1 ${alias} ${masterfile})"
+
+ if [ ! -z "${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"
+
+ countk="$(grep -c ^ ${masterfile})"
+ countx="$(grep -c ^ ${pfbfolder}${alias}.txt)"
+ counto="$((countx - counter))"
+ printf "%-20s %-10s %-10s %-10s\n" "${alias}" "${countg}" "${counto}" "${countk}"
fi
- done
+ fi
fi
-else
- if [ "$cc" == "suppressheader" ]; then
- echo; echo "===[ Suppression Stats ]========================================"; echo
- printf "%-20s %-10s %-10s %-10s %-10s\n" "List" "Pre" "RFC1918" "Suppress" "Masterfile"
- echo "----------------------------------------------------------------"
- exitnow
+}
+
+
+# Function to optimise CIDRs
+cidr_aggregate() {
+ if [ ! -x "${pathaggregate}" ]; then
+ log="Application [ aggregate ] Not found. Cannot proceed."
+ echo "${log}" | tee -a "${errorlog}"
+ return
+ fi
+
+ if [ "${agg_folder}" = true ]; then
+ # Use $3 folder path
+ pfbfolder="${max}/"
+ else
+ pfbfolder="${pfbdeny}"
+ fi
+
+ counto="$(grep -c ^ ${pfbfolder}${alias}.txt)"
+ retval="$(cat "${pfbfolder}${alias}.txt" | "${pathaggregate}" -t -p 32 -m 32 -o 32 2>&1 > ${tempfile})"
+ sed 's/\/32//' "${tempfile}" > "${pfbfolder}${alias}.txt"
+ countf="$(grep -c ^ ${pfbfolder}${alias}.txt)"
+
+ # Report errors (First two lines are informational only)
+ aggstring='aggregate: maximum prefix length permitted will be 32aggregate: prefix length of 32 bits will be used where none specified'
+ retval2=$(echo "${retval}" | tr -d '\n\r' | sed "s/${aggstring}//g")
+ if [ ! -z "${retval2}" ]; then
+ echo "${retval2}"
+ fi
+
+ if [ "${counto}" != "${countf}" ]; then
+ echo; echo ' Aggregation Stats:'
+ echo ' ------------------'
+ printf "%-10s %-10s \n" ' Original' 'Final'
+ echo ' ------------------'
+ printf "%-10s %-10s \n" " ${counto}" "${countf}"
+ echo ' ------------------'
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
-exitnow
}
-##########
-# Process to remove Duplicate Entries on each downloaded Blocklist Individually
+# Function to remove duplicate entries in each list individually.
duplicate() {
+ if [ ! -x "${pathgrepcidr}" ]; then
+ log="Application [ grepcidr ] Not found. Cannot proceed."
+ echo "${log}" | tee -a "${errorlog}"
+ exitnow
+ fi
-if [ ! -x $pathgrepcidr ]; then
- echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]"
- echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" >> errorlog
- exitnow
-fi
+ dupcheck=1
+ # Check if masterfile is empty
+ hcheck="$(grep -cv ^$ ${masterfile})"; if [ "${hcheck}" -eq 0 ]; then dupcheck=0; fi
+ # Check if alias exists in masterfile
+ lcheck="$(grep -m1 ${alias} ${masterfile})"; if [ -z "${lcheck}" ]; then dupcheck=0; fi
+ # Check for single alias in masterfile
+ aliaslist="$(cut -d ' ' -f1 ${masterfile} | sort | uniq)"; if [ "${alias}" == "${aliaslist}" ]; then hcheck=0; fi
+
+ # Only execute if 'Alias' exists in masterfile
+ if [ "${dupcheck}" -eq 1 ]; 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
-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
-# Check for single alias in masterfile
-aliaslist=$(cut -d' ' -f1 $masterfile | sort | uniq); if [ "$alias" == "$aliaslist" ]; then hcheck="0"; 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
+ # Don't execute when only a single 'Alias' exists in masterfile
+ if [ ! "${hcheck}" -eq 0 ]; then
+ sort "${pfbdeny}${alias}.txt" | uniq > "${tempfile}"; mv -f "${tempfile}" "${pfbdeny}${alias}.txt"
+ "${pathgrepcidr}" -vf "${mastercat}" "${pfbdeny}${alias}.txt" > "${tempfile}"; mv -f "${tempfile}" "${pfbdeny}${alias}.txt"
+ fi
-grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile; mv -f $tempfile $pfbdeny$alias".txt"
+ sed -e 's/^/'$alias' /' "${pfbdeny}${alias}.txt" >> "${masterfile}"
+ cut -d ' ' -f2 "${masterfile}" > "${mastercat}"
-if [ ! "$hcheck" -eq "0" ]; then
- $pathgrepcidr -vf $mastercat $pfbdeny$alias".txt" > $tempfile; mv -f $tempfile $pfbdeny$alias".txt"
-fi
+ counto="$(grep -cv '^#\|^$' ${pfborig}${alias}.orig)"
+ countm="$(grep -c ${alias} ${masterfile})"
+ countf="$(grep -c ^ ${pfbdeny}${alias}.txt)"
-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 "----------------------------------------------------------"
-exitnow
-}
+ if [ "${countm}" -eq "${countf}" ]; then
+ sanity='Pass'
+ else
+ sanity=' ==> FAILED <== '
+ fi
+ echo ' ------------------------------'
+ printf "%-10s %-10s %-10s\n" ' Original' 'Master' 'Final'
+ echo ' ------------------------------'
+ printf "%-10s %-10s %-10s %-10s\n" " ${counto}" "${countm}" "${countf}" " [ ${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
- exitnow
-fi
+# Function to remove duplicate DNSBL domain names from feeds.
+domainduplicate() {
+ # Alexa Whitelist variables
+ alexa_enable="${max}"
-# 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
+ counto="$(grep -c ^ ${pfbdomain}${alias}.bk)"
+ if [ -d "${pfbdomain}" ] && [ "$(ls -A ${pfbdomain}*.txt 2>/dev/null)" ]; then
+ sort "${pfbdomain}${alias}.bk" | uniq > "${pfbdomain}${alias}.bk2"
+ countu="$(grep -c ^ ${pfbdomain}${alias}.bk2)"
+ find "${pfbdomain}"*.txt ! -name "${alias}.txt" | xargs cat > "${domainmaster}"
-# 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
- exitnow
-fi
+ # Only execute awk command, if master domain file contains data.
+ counta="$(grep -c ^ ${domainmaster})"
+ if [ "${counta}" -gt 0 ]; then
+ awk 'FNR==NR{a[$0];next}!($0 in a)' "${domainmaster}" "${pfbdomain}${alias}.bk2" > "${pfbdomain}${alias}.bk"
+ 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 | xargs cut -d '.' -f 1-3 |
- 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
+ rm -f "${domainmaster}"; rm -f "${pfbdomain}${alias}.bk2"
+ countf="$(grep -c ^ ${pfbdomain}${alias}.bk)"
+ countd="$((countu - countf))"
+ else
+ sort "${pfbdomain}${alias}.bk" | uniq > "${pfbdomain}${alias}.bk2" && mv -f "${pfbdomain}${alias}.bk2" "${pfbdomain}${alias}.bk"
+ countf="$(grep -c ^ ${pfbdomain}${alias}.bk)"
+ countd=0; countu="${counto}"
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
+ if [ "${alexa_enable}" == 'on' ]; then
+ awk 'FNR==NR{a[$0];next}!($0 in a)' "${pfbalexa}" "${pfbdomain}${alias}.bk" > "${pfbdomain}${alias}.bk2"
+ countw="$(grep -c ^ ${pfbdomain}${alias}.bk2)"
+ counta="$((countf - countw))"
+
+ if [ "${counta}" -gt 0 ]; then
+ data="$(awk 'FNR==NR{a[$0];next}!($0 in a)' ${pfbdomain}${alias}.bk2 ${pfbdomain}${alias}.bk | \
+ cut -d '"' -f2 | cut -d ' ' -f1 | sort | uniq | tr '\n' '|')"
+ echo; echo; echo " Alexa Whitelist: ${data}"
+ mv -f "${pfbdomain}${alias}.bk2" "${pfbdomain}${alias}.bk"
+ countf="$((countw))"
+ else
+ rm -f "${pfbdomain}${alias}.bk2"
+ fi
+ else
+ counta='-'
+ fi
-# Write "1.1.1.1" to empty Final Blocklist Files
-emptyfiles=$(find $pfbdeny -size 0)
-for i in $emptyfiles; do echo "1.1.1.1" > $i; done
-exitnow
+ echo; echo ' ------------------------------------------------'
+ printf "%-10s %-10s %-10s %-10s %-10s\n" ' Original' 'Unique' '# Dups' 'Alexa' 'Final'
+ echo ' ------------------------------------------------'
+ printf "%-10s %-10s %-10s %-10s %-10s\n" " ${counto}" "${countu}" "${countd}" "${counta}" "${countf}"
+ echo ' ------------------------------------------------'
}
-##########
-# Process to perform a final De-Duplication on all of the BlockLists (Excluding Country Whitelist) ("pmax" variable).
-pdeduplication(){
+# Function to convert Domains/ASs to its respective IP addresses
+whoisconvert() {
+ if [ ! -x "${pathmwhois}" ]; then
+ log="Application [ mwhois ] Not found. Cannot proceed."
+ echo "${log}" | tee -a "${errorlog}"
+ exitnow
+ fi
-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
- exitnow
-fi
+ vtype="${max}"
+ custom_list="$(echo ${dedup} | tr ',' ' ')"
+ rm -f "${pfborig}${alias}.orig"
-# 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
- exitnow
-fi
+ if [ "${vtype}" == '_v4' ]; then
+ _type=A
+ _route=route
+ _opt=gAS
+ else
+ _type=AAAA
+ _route=route6
+ _opt=6AS
+ 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 | xargs cut -d '.' -f 1-3 |
- 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
+ for host in ${custom_list}; do
+ # Determine if host is a Domain or an AS
+ host_check="$(echo ${host} | grep '\.')"
+ if [ ! -z "${host_check}" ]; then
+ echo "### Domain: ${host} ###" >> "${pfborig}${alias}.orig"
+ ${pathhost} -t ${_type} ${host} | sed 's/^.* //' >> "${pfborig}${alias}.orig"
else
- echo $header" $ip." >> $dedupfile
+ asn="$(echo ${host} | tr -d 'AaSs')"
+ echo "### AS${asn}: ${host} ###" >> "${pfborig}${alias}.orig"
+ "${pathmwhois}" -h whois.radb.net \!"${_opt}${asn}" | tail -n +2 | tr -d '\nC' | tr ' ' '\n' >> "${pfborig}${alias}.orig"
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
-exitnow
+ echo >> "${pfborig}${alias}.orig"
+ done
}
-##########
-# Process to Split ET Pro IPREP into Category Files and Compile selected Blocked categories into Outfile
-processet() {
+# Function to check for Reputation application dependencies.
+reputation_depends() {
+ if [ ! -x "${pathgeoip}" ]; then
+ log="Application [ GeoIP ] Not found, cannot proceed. [ ${now} ]"
+ echo "${log}" | tee -a "${errorlog}"
+ return
+ fi
-if [ ! -x $pathgunzip ]; then
- echo "Application [ Gunzip ] Not found, Can't proceed."
- echo "Application [ Gunzip ] Not found, Can't proceed. [ $now ]" >> $errorlog
- exitnow
-fi
+ # Download MaxMind GeoIP.dat on first install.
+ if [ ! -f "${pathgeoipdat}" ]; then
+ echo "Downloading [ MaxMind GeoIP.dat ] [ ${now} ]" >> "${geoiplog}"
+ /usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php bu
+ 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)
- 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; 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 "-------------------------------------------"
+ # Exit if GeoIP.dat is not found
+ if [ ! -f "${pathgeoipdat}" ]; then
+ log="Database GeoIP [ GeoIP.Dat ] not found. Reputation function terminated."
+ echo "${log}" | tee -a "${errorlog}"
+ return
+ fi
- 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
-exitnow
+ # Clear variables and tempfiles
+ rm -f /tmp/pfbtemp?_"${rvar}"
+ count=0; countb=0; countm=0; counts=0; countr=0
}
-# 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
- exitnow
-fi
+# Reputation function to condense an IP range if a 'Max' amount of IP addresses are found in a /24 range per individual list.
+reputation_max() {
+ sort "${pfbdeny}${alias}.txt" | uniq > "${tempfile}"
+ data="$(cut -d '.' -f 1-3 ${tempfile} | awk -v max=${max} '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}')"
+
+ # Classify repeat offenders by Country code
+ if [ ! -z "${data}" ]; then
+ for ip in ${data}; do
+ ccheck="$(${pathgeoip} -f ${pathgeoipdat} ${ip}.1 | cut -c 24-25)"
+ case "${cc}" in
+ *$ccheck*)
+ countr="$((countr + 1))"
+ if [ "${ccwhite}" == 'match' ] || [ "${ccblack}" == 'match' ]; then
+ echo "${ip}." >> "${matchfile}"
+ fi
+ ;;
+ *)
+ count="$((count + 1))"
+ echo "${ip}." >> "${dupfile}"
+ ;;
+ esac
+ done
+ else
+ countr=0; count=0
+ fi
-if [ -s $pfborig$alias".zip" ]; then
+ # Collect match file details
+ if [ -s "${matchfile}" ] && [ "${dedup}" != 'on' ] && [ "${ccwhite}" == 'match' ]; then
+ mon="$(sed -e 's/^/^/' -e 's/\./\\\./g' ${matchfile})"
+ for ip in ${mon}; do
+ grep "${ip}" "${tempfile}" >> "${tempfile2}"
+ done
+ counts="$(grep -c ^ ${tempfile2})"
+ if [ "${ccwhite}" == 'match' ]; then
+ sed 's/$/0\/24/' "${matchfile}" >> "${tempmatchfile}"
+ sed 's/^/\!/' "${tempfile2}" >> "${tempmatchfile}"
+ fi
+ fi
- $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*
+ # If no matches found remove previous matchoutfile if exists.
+ matchoutfile="match${header}.txt"
+ if [ ! -s "${tempmatchfile}" ] && [ -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
+ countb="$(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
- 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
-exitnow
+ if [ "${count}" -gt 0 ]; then
+ echo; echo " Reputation (Max=${max}) - Range(s)"
+ cat "${dupfile}" | tr '\n' '|'; echo
+ sort "${pfbdeny}${alias}.txt" | uniq > "${tempfile}"; mv -f "${tempfile}" "${pfbdeny}${alias}.txt"
+ fi
+
+ if [ "${count}" -gt 0 ] || [ "${countr}" -gt 0 ]; then
+ echo; echo ' Reputation -Max Stats'
+ echo ' ------------------------------'
+ printf "%-17s %-10s\n" ' Blacklisted' 'Match'
+ printf "%-8s %-8s %-8s %-8s\n" ' Ranges' 'IPs' 'Ranges' 'IPs'
+ echo ' ------------------------------'
+ printf "%-8s %-8s %-8s %-8s\n" " ${count}" "${countb}" "${countr}" "${counts}"
+ echo
+ 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
+# Reputation function 'dMax' utilizing MaxMind GeoIP Country code.
+reputation_dmax() {
+ echo; echo '===[ Reputation - dMax ]======================================'
+ echo; echo " Querying for repeat offenders ( dMax=${max} ) [ ${now} ]"
+ data="$(find ${pfbdeny}*.txt ! -name pfB*.txt ! -name *_v6.txt -type f | xargs cut -d '.' -f 1-3 | \
+ awk -v max=${max} '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}' | grep -v '^1\.1\.1')"
+
+ # Classify repeat offenders by Country code
+ if [ ! -z "${data}" ]; 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*)
+ countr="$((countr + 1))"
+ if [ "${ccwhite}" == 'match' ] || [ "${ccblack}" == 'match' ]; then
+ echo "${ip}." >> "${matchfile}"
+ fi
+ ;;
+ *)
+ count="$((count + 1))"
+ echo "${ip}." >> "${dupfile}"
+ ;;
+ esac
+ done
+ else
+ countr=0; count=0
+ fi
-if [ -d "$pfborig" ] && [ "$(ls -A $pfborig)" ]; then
- fcount=$(find $pfborig*.orig | xargs cat | grep -cv '^#\|^$')
-else
- fcount=0
-fi
+ if [ "${ccwhite}" == 'match' ] && [ -s "${matchfile}" ]; then
+ echo ' Processing [ Match ] IPs'
+ match="$(sed -e 's/^/^/' -e 's/\./\\\./g' ${matchfile})"
-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 "===[ 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
+ 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}"
+ countm="$(grep -c ^ ${tempfile})"
+ counts="$((countm + counts))"
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
+
+ # Find repeat offenders in each individual blocklist outfile
+ if [ "${count}" -gt 0 ]; then
+ echo ' Processing [ Block ] IPs'
+ dup="$(cat ${dupfile})"
+
+ for ip in ${dup}; do
+ runonce=0; ii="$(echo ^${ip} | sed 's/\./\\\./g')"
+ list="$(find ${pfbdeny}*.txt ! -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 [ "${runonce}" -eq 0 ]; then
+ echo "${ip}0/24" >> "${blfile}"
+ echo "${header}" "${ip}" >> "${dedupfile}"
+ echo "${header}" "${ip}0/24" >> "${addfile}"
+ runonce=1
+ else
+ echo "${header}" "${ip}" >> "${dedupfile}"
+ fi
+ else
+ if [ "${runonce}" -eq 0 ]; then
+ matchoutfile="match${header}.txt"
+ echo "${ip}0/24" >> "${pfbmatch}${matchoutfile}"
+ sed 's/^/\!/' "${tempfile}" >> "${pfbmatch}${matchoutfile}"
+ countm="$(grep -c ^ ${pfbmatch}${matchoutfile})"
+ counts="$((countm + counts))"
+ runonce=1
+ fi
+ fi
done
- fi
+ done
+
+ # Remove repeat offenders in masterfiles
+ echo ' Removing [ Block ] IPs'
+ > "${tempfile}"; > "${tempfile2}"
+ sed 's/\./\\\./g' "${dedupfile}" > "${tempfile2}"
+ while IFS=' ' read -r ips; do grep "${ips}" "${masterfile}" >> "${tempfile}"; done < "${tempfile2}"
+ countb="$(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}"
+
+ echo; echo ' Removed the following IP ranges:'
+ sed -e 's/^.* //' -e 's/0\/24//' "${addfile}" | tr '\n' '|'; echo
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 "==============================================================="
+
+ if [ "${count}" -gt 0 ] || [ "${countr}" -gt 0 ]; then
+ echo; echo ' Reputation - dMax Stats'
+ echo ' ------------------------------'
+ printf "%-17s %-10s\n" ' Blacklisted' 'Match'
+ printf "%-8s %-8s %-8s %-8s\n" ' Ranges' 'IPs' 'Ranges' 'IPs'
+ echo ' ------------------------------'
+ printf "%-8s %-8s %-8s %-8s\n" " ${count}" "${countb}" "${countr}" "${counts}"
+
+ emptyfiles # Call emptyfiles function
+ else
+ echo ' Reputation -dMax ( None )'
fi
-fi
+}
+
+
+# Reputation function 'pMax'. (No Country code exclusions)
+reputation_pmax(){
+ echo; echo; echo '===[ Reputation - pMax ]======================================'
+ echo; echo " Querying for repeat offenders ( pMax=${max} ) [ ${now} ]"
+ data="$(find ${pfbdeny}*.txt ! -name pfB*.txt ! -name *_v6.txt -type f | xargs cut -d '.' -f 1-3 |
+ awk -v max=${max} '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}' | grep -v '^1\.1\.1')"
+
+ if [ ! -z "${data}" ]; then
+ # Find repeat offenders in each individual blocklist outfile
+ echo ' Processing [ Block ] IPs'
+ count=0
+
+ for ip in ${data}; do
+ count="$((count + 1))"
+ runonce=0; ii="$(echo ^${ip}. | sed 's/\./\\\./g')"
+ list="$(find ${pfbdeny}*.txt ! -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 [ "${runonce}" -eq 0 ]; then
+ echo "${ip}.0/24" >> "${blfile}"
+ echo "${header}" "${ip}." >> "${dedupfile}"
+ echo "${header}" "${ip}.0/24" >> "${addfile}"
+ runonce=1
+ else
+ echo "${header}" "${ip}." >> "${dedupfile}"
+ fi
+ done
+ done
-echo; echo "IPv4 Alias Table IP Total"; echo "-----------------------------"
-find $pfsense_alias_dir ! -name "*_v6.txt" -type f | xargs cat | grep -c ^
+ # Remove repeat offenders in masterfile
+ echo ' Removing [ Block ] IPs'
+ > "${tempfile}"; > "${tempfile2}"
+ sed 's/\./\\\./g' "${dedupfile}" > "${tempfile2}"
+ while IFS=' ' read -r ips; do grep "${ips}" "${masterfile}" >> "${tempfile}"; done < "${tempfile2}"
+ countb="$(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}"
+
+ echo; echo ' Removed the following IP ranges:'
+ sed -e 's/^.* //' -e 's/0\/24//' "${addfile}" | tr '\n' '|'; echo
+
+ echo; echo ' Reputation - pMax Stats'
+ echo ' ----------------'
+ printf "%-8s %-8s\n" ' Ranges' 'IPs'
+ echo ' ----------------'
+ printf "%-8s %-8s\n" " ${count}" "${countb}"
+
+ emptyfiles # Call emptyfiles function
+ else
+ echo ' Reputation -pMax ( None )'
+ fi
+}
-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
+# Function to split ET Pro IPREP into category files and compile selected blocked categories into outfile.
+processet() {
+ if [ -s "${pfborig}${alias}.orig" ]; then
+ # Remove previous ET IPRep files
+ [ -d "${etdir}" ] && [ "$(ls -A ${etdir})" ] && rm -r "${etdir}/ET_"*
+ > "${tempfile}"; > "${tempfile2}"
+
+ # ET CSV format (IP, Category, Score)
+ echo; echo; echo 'Compiling ET IPREP IQRisk based upon user selected categories'
+ while IFS=',' read i j k; do
+ # Some ET categories are not in use (For future use)
+ case "${j}" in
+ 1) echo "${i}" >> "${etdir}/ET_Cnc.txt";;
+ 2) echo "${i}" >> "${etdir}/ET_Bot.txt";;
+ 3) echo "${i}" >> "${etdir}/ET_Spam.txt";;
+ 4) echo "${i}" >> "${etdir}/ET_Drop.txt";;
+ 5) echo "${i}" >> "${etdir}/ET_Spywarecnc.txt";;
+ 6) echo "${i}" >> "${etdir}/ET_Onlinegaming.txt";;
+ 7) echo "${i}" >> "${etdir}/ET_Drivebysrc.txt";;
+ 8) echo "${i}" >> "${etdir}/ET_Cat8.txt";;
+ 9) echo "${i}" >> "${etdir}/ET_Chatserver.txt";;
+ 10) echo "${i}" >> "${etdir}/ET_Tornode.txt";;
+ 11) echo "${i}" >> "${etdir}/ET_Cat11.txt";;
+ 12) echo "${i}" >> "${etdir}/ET_Cat12.txt";;
+ 13) echo "${i}" >> "${etdir}/ET_Compromised.txt";;
+ 14) echo "${i}" >> "${etdir}/ET_Cat14.txt";;
+ 15) echo "${i}" >> "${etdir}/ET_P2P.txt";;
+ 16) echo "${i}" >> "${etdir}/ET_Proxy.txt";;
+ 17) echo "${i}" >> "${etdir}/ET_Ipcheck.txt";;
+ 18) echo "${i}" >> "$[etdir}/ET_Cat18.txt";;
+ 19) echo "${i}" >> "${etdir}/ET_Utility.txt";;
+ 20) echo "${i}" >> "${etdir}/ET_DDos.txt";;
+ 21) echo "${i}" >> "${etdir}/ET_Scanner.txt";;
+ 22) echo "${i}" >> "${etdir}/ET_Cat22.txt";;
+ 23) echo "${i}" >> "${etdir}/ET_Brute.txt";;
+ 24) echo "${i}" >> "${etdir}/ET_Fakeav.txt";;
+ 25) echo "${i}" >> "${etdir}/ET_Dyndns.txt";;
+ 26) echo "${i}" >> "${etdir}/ET_Undesireable.txt";;
+ 27) echo "${i}" >> "${etdir}/ET_Abusedtld.txt";;
+ 28) echo "${i}" >> "${etdir}/ET_Selfsignedssl.txt";;
+ 29) echo "${i}" >> "${etdir}/ET_Blackhole.txt";;
+ 30) echo "${i}" >> "${etdir}/ET_RAS.txt";;
+ 31) echo "${i}" >> "${etdir}/ET_P2Pcnc.txt";;
+ 32) echo "${i}" >> "${etdir}/ET_Sharedhosting.txt";;
+ 33) echo "${i}" >> "${etdir}/ET_Parking.txt";;
+ 34) echo "${i}" >> "${etdir}/ET_VPN.txt";;
+ 35) echo "${i}" >> "${etdir}/ET_Exesource.txt";;
+ 36) echo "${i}" >> "${etdir}/ET_Cat36.txt";;
+ 37) echo "${i}" >> "${etdir}/ET_Mobilecnc.txt";;
+ 38) echo "${i}" >> "${etdir}/ET_Mobilespyware.txt";;
+ 39) echo "${i}" >> "${etdir}/ET_Skypenode.txt";;
+ 40) echo "${i}" >> "${etdir}/ET_Bitcoin.txt";;
+ 41) echo "${i}" >> "${etdir}/ET_DDosattack.txt";;
+ *) echo "${i}" >> "${etdir}/ET_Unknown.txt";;
+ esac
+ done < "${pfborig}${alias}.orig"
+ data="$(ls ${etdir})"
+ 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 '-------------------------------------------'
-echo; echo "pfSense Table Stats"; echo "-------------------"
-$pathpfctl -s memory | grep "table-entries"
-pfctlcount=$($pathpfctl -vvsTables | awk '/Addresses/ {s+=$2}; END {print s}')
-echo "Table Usage Count " $pfctlcount
-exitnow
+ if [ -f "${tempfile}" ]; then mv -f "${tempfile}" "${pfborig}${alias}.orig"; fi
+ if [ "${etmatch}" != 'x' ]; then mv -f "${tempfile2}" "${pfbmatch}/ETMatch.txt"; fi
+ counto="$(cat ${etdir}/ET_* | grep -cv '^#\|^$')"; countf="$(grep -cv '^1\.1\.1\.1$' ${pfborig}${alias}.orig)"
+ echo; echo "All ET Folder count [ ${counto} ] Final count [ ${countf} ]"
+ else
+ echo; echo 'No ET .orig File Found!'
+ fi
}
-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 ]"
+
+# Function to extract IP addresses from XLSX files.
+processxlsx() {
+ if [ ! -x "${pathtar}" ]; then
+ log='Application [ TAR ] Not found, cannot proceed.'
+ echo "${log}" | tee -a "${errorlog}"
+ exitnow
fi
- echo
-done
-# Delete Masterfiles if they are empty
-emptychk=$(find $masterfile -size 0)
-if [ ! "$emptychk" == "" ]; then
- rm -r $masterfile; rm -r $mastercat
-fi
-exitnow
-}
+ if [ -s "${pfborig}${alias}.raw" ]; then
+ "${pathtar}" -xf "${pfborig}${alias}.raw" -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}"*
-# Process to restore aliasables from archive on reboot ( NanoBSD and Ramdisk Installations only )
-aliastables() {
- if [ "${PLATFORM}" != "pfSense" ] || [ ${USE_MFS_TMPVAR} -gt 0 ] || [ "${DISK_TYPE}" = "md" ]; then
- [ -f $aliasarchive ] && cd $pfsense_alias_dir && /usr/bin/tar -jxvf $aliasarchive
+ countf="$(grep -cv '^1\.1\.1\.1$' ${pfborig}${alias}.orig)"
+ echo; echo "Final count [ ${countf} ]"
+ else
+ echo 'XLSX download file missing'
+ echo " [ ${alias} ] XLSX download file missing [ ${now} ]" >> "${errorlog}"
fi
- exitnow
}
-##########
-# CALL APPROPRIATE PROCESSES using Script Argument $1
-case $1 in
- continent)
- continent
+# Function to report final pfBlockerNG statistics.
+closingprocess() {
+ counto=0
+ echo; echo '===[ FINAL Processing ]====================================='; echo
+ if [ -d "${pfborig}" ] && [ "$(ls -A ${pfborig})" ]; then
+ counto="$(find ${pfborig}*.orig 2>/dev/null | xargs cat | grep -cv '^#\|^$')"
+ fi
+
+ # Execute when 'de-duplication' is enabled
+ 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 " [ Original IP count ] [ ${counto} ]"
+ countm="$(grep -c ^ ${masterfile})"
+ echo; echo " [ Final IP Count ] [ ${countm} ]"; echo
+
+ s1="$(grep -cv '1\.1\.1\.1$' ${masterfile})"
+ s2="$(find ${pfbdeny}*.txt ! -name *_v6.txt -type f 2>/dev/null | xargs cat | grep -cv '^1\.1\.1\.1$')"
+ s3="$(sort ${mastercat} | uniq -d | tail -30)"
+ s4="$(find ${pfbdeny}*.txt ! -name *_v6.txt -type f 2>/dev/null | xargs cat | sort | uniq -d | tail -30 | grep -v '^1\.1\.1\.1$')"
+ else
+ echo " [ Original IP count ] [ ${counto} ]"
+ fi
+
+ if [ -d "${pfbpermit}" ] && [ "$(ls -A ${pfbpermit})" ]; then
+ echo; echo '===[ Permit List IP Counts ]========================='; echo
+ wc -l "${pfbpermit}"*.txt 2>/dev/null | sort -n -r
+ fi
+ if [ -d "${pfbmatch}" ] && [ "$(ls -A ${pfbmatch})" ]; then
+ echo; echo '===[ Match List IP Counts ]=========================='; echo
+ wc -l "${pfbmatch}"*.txt 2>/dev/null | sort -n -r
+ fi
+ if [ -d "${pfbdeny}" ] && [ "$(ls -A ${pfbdeny})" ]; then
+ echo; echo '===[ Deny List IP Counts ]==========================='; echo
+ wc -l "${pfbdeny}"*.txt 2>/dev/null | sort -n -r
+ fi
+ if [ -d "${pfbnative}" ] && [ "$(ls -A ${pfbnative})" ]; then
+ echo; echo '===[ Native List IP Counts ] ==================================='; echo
+ wc -l "${pfbnative}"*.txt 2>/dev/null | sort -n -r
+ fi
+ if [ -d "${pfbdeny}" ] && [ "$(ls -A ${pfbdeny})" ]; then
+ emptylists="$(grep '^1\.1\.1\.1$' ${pfbdeny}*.txt | 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 "${pfbdomain}" ] && [ "$(ls -A ${pfbdomain})" ]; then
+ echo; echo '===[ DNSBL Domain/IP Counts ] ==================================='; echo
+ wc -l "${pfbdomain}"* 2>/dev/null | sort -n -r
+ fi
+ if [ -d "${pfborig}" ] && [ "$(ls -A ${pfborig})" ]; then
+ echo; echo '====================[ Last Updated List Summary ]=============='; echo
+ ls -lahtr "${pfborig}"*.orig | sed -e 's/\/.*\// /' -e 's/.orig//' | awk -v OFS='\t' '{print $6" "$7,$8,$9}'
+ fi
+
+ # Execute when 'de-duplication' is enabled
+ if [ "${alias}" == 'on' ]; then
+ echo '==============================================================='; echo
+ if [ "${s1} == ${s2}" ]; then
+ echo 'Database Sanity check [ PASSED ]'
+ else
+ echo 'Database Sanity check [ FAILED ] ** These two counts should match! **'
+ echo '------------'
+ echo "Masterfile Count [ ${s1} ]"
+ echo "Deny folder Count [ ${s2} ]"; echo
+ echo 'Duplication sanity check (Pass=No IPs reported)'
+ fi
+ 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 '----------'
+ fi
+
+ echo; echo 'IPv4 alias tables IP count'; echo '-----------------------------'
+ find "${pfsensealias}"pfB_*.txt ! -name "*_v6.txt" -type f 2>/dev/null | xargs cat | grep -c ^
+
+ echo; echo 'IPv6 alias tables IP count'; echo '-----------------------------'
+ find "${pfsensealias}"pfB_*.txt -name "*_v6.txt" -type f 2>/dev/null | xargs cat | grep -c ^
+
+ echo; echo 'Alias table IP Counts'; echo '-----------------------------'
+ wc -l "${pfsensealias}"pfB_*.txt 2>/dev/null | 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}"
+}
+
+# Call appropriate processes using script argument $1.
+case "${1}" in
+ _*)
+ if [ "$(echo ${1} | grep -c '_255')" -gt 0 ]; then process255; fi
+ if [ "$(echo ${1} | grep -c '_agg')" -gt 0 ]; then cidr_aggregate; fi
+ if [ "$(echo ${1} | grep -c '_rep')" -gt 0 ]; then reputation_depends; reputation_max; fi
+ if [ "$(echo ${1} | grep -c '_dup')" -gt 0 ]; then duplicate; fi
;;
- duplicate)
- process255
+ continent)
duplicate
;;
+ domainduplicate)
+ domainduplicate
+ ;;
+ cidr_aggregate)
+ agg_folder=true
+ cidr_aggregate
+ ;;
+ whoisconvert)
+ whoisconvert
+ ;;
suppress)
suppress
;;
- p24)
- process24
- ;;
- dedup)
- deduplication
+ dmax)
+ reputation_depends
+ reputation_dmax
;;
- pdup)
- pdeduplication
+ pmax)
+ reputation_depends
+ reputation_pmax
;;
et)
processet
@@ -965,17 +965,17 @@ case $1 in
xlsx)
processxlsx
;;
- closing)
- closingprocess
- ;;
remove)
remove
;;
aliastables)
aliastables
;;
+ closing)
+ emptyfiles
+ closingprocess
+ ;;
*)
- exitnow
;;
esac
-exitnow
+exitnow \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.widget.php b/config/pfblockerng/pfblockerng.widget.php
index c9522cd7..c70bd05b 100644
--- a/config/pfblockerng/pfblockerng.widget.php
+++ b/config/pfblockerng/pfblockerng.widget.php
@@ -3,19 +3,17 @@
pfBlockerNG.widget.php
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 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)
+ Copyright (c) 2011 Thomas Schaefer
+ Copyright (c) 2011 Marcello Coutinho
Adapted From:
snort_alerts.widget.php
- Copyright (C) 2009 Jim Pingle
- mod 24-07-2012
- mod 28-02-2015 by Bill Meeks
+ Copyright (c) 2015 Electric Sheep Fencing, LLC. All rights reserved.
+ Copyright (c) 2015 Bill Meeks
Javascript and Integration modifications by J. Nieuwenhuizen
@@ -43,9 +41,9 @@
POSSIBILITY OF SUCH DAMAGE.
*/
$nocsrf = true;
-@require_once("/usr/local/www/widgets/include/widget-pfblockerng.inc");
-@require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
-@require_once("guiconfig.inc");
+@require_once('/usr/local/www/widgets/include/widget-pfblockerng.inc');
+@require_once('/usr/local/pkg/pfblockerng/pfblockerng.inc');
+@require_once('guiconfig.inc');
pfb_global();
@@ -58,71 +56,62 @@ $pfb['err'] = "<img src ='/themes/{$g['theme']}/images/icons/icon_wzd_nsaved.png
$pfb['RowOddClass'] = "style='background-color: #FFFFFF;'";
$pfb['RowEvenClass'] = "style='background-color: #F0F0F0;'";
$pfb['RowEvenClass2'] = "style='background-color: #D0D0D0;'";
-$pfb['ColClass'] = "listMRr";
+$pfb['ColClass'] = 'listMRr';
-$pfb['global'] = &$config['installedpackages']['pfblockerngglobal'];
-
-// Define default widget customizations
-if (!isset($pfb['global']['widget-maxfails'])) {
- $pfb['global']['widget-maxfails'] = '3';
-}
-if (!isset($pfb['global']['widget-maxpivot'])) {
- $pfb['global']['widget-maxpivot'] = '200';
-}
-if (!isset($pfb['global']['widget-sortcolumn'])) {
- $pfb['global']['widget-sortcolumn'] = 'none';
-}
-if (!isset($pfb['global']['widget-sortdir'])) {
- $pfb['global']['widget-sortdir'] = 'asc';
-}
-if (!isset($pfb['global']['widget-popup'])) {
- $pfb['global']['widget-popup'] = 'on';
-}
-
-// Collect variables
-if (is_array($pfb['global'])) {
- $pfb['maxfails'] = $pfb['global']['widget-maxfails'];
- $pfb['maxpivot'] = $pfb['global']['widget-maxpivot'];
- $pfb['sortcolumn'] = $pfb['global']['widget-sortcolumn'];
- $pfb['sortdir'] = $pfb['global']['widget-sortdir'];
- $pfb['popup'] = $pfb['global']['widget-popup'];
+// Widget customizations
+$wglobal_array = array('popup' => 'off', 'sortcolumn' => 'none', 'sortdir' => 'asc', 'maxfails' => 3, 'maxpivot' => 200);
+$pfb['wglobal'] = &$config['installedpackages']['pfblockerngglobal'];
+foreach ($wglobal_array as $type => $value) {
+ $pfb[$type] = $pfb['wglobal']['widget-' . "{$type}"] ?: $value;
}
// Save widget customizations
-if ($_POST) {
- if (is_numeric($_POST['pfb_maxfails'])) {
- $pfb['global']['widget-maxfails'] = $_POST['pfb_maxfails'];
- }
- if (is_numeric($_POST['pfb_maxpivot'])) {
- $pfb['global']['widget-maxpivot'] = $_POST['pfb_maxpivot'];
- }
- if (!empty($_POST['pfb_popup'])) {
- $pfb['global']['widget-popup'] = $_POST['pfb_popup'];
- }
- if (!empty($_POST['pfb_sortcolumn'])) {
- $pfb['global']['widget-sortcolumn'] = $_POST['pfb_sortcolumn'];
+if (isset($_POST['pfb_submit'])) {
+ $pfb['wglobal']['widget-popup'] = htmlspecialchars($_POST['pfb_popup']) ?: 'off';
+ $pfb['wglobal']['widget-sortcolumn'] = htmlspecialchars($_POST['pfb_sortcolumn']) ?: 'none';
+ $pfb['wglobal']['widget-sortdir'] = htmlspecialchars($_POST['pfb_sortdir']) ?: 'asc';
+
+ if (ctype_digit(htmlspecialchars($_POST['pfb_maxfails']))) {
+ $pfb['wglobal']['widget-maxfails'] = htmlspecialchars($_POST['pfb_maxfails']);
}
- if (!empty($_POST['pfb_sortdir'])) {
- $pfb['global']['widget-sortdir'] = $_POST['pfb_sortdir'];
+ if (ctype_digit(htmlspecialchars($_POST['pfb_maxpivot']))) {
+ $pfb['wglobal']['widget-maxpivot'] = htmlspecialchars($_POST['pfb_maxpivot']);
}
- write_config("pfBlockerNG: Saved Widget customizations via Dashboard");
- header("Location: ../../index.php");
+
+ write_config('pfBlockerNG: Saved Widget customizations via Dashboard');
+ header('Location: ../../index.php');
}
// Ackwnowlege failed downloads
if (isset($_POST['pfblockerngack'])) {
- exec("/usr/bin/sed -i '' 's/FAIL/Fail/g' {$pfb['errlog']}");
- header("Location: ../../index.php");
+ exec("{$pfb['sed']} -i '' 's/FAIL/Fail/g' {$pfb['errlog']}");
+ header('Location: ../../index.php');
}
// Called by Ajax to update table contents
if (isset($_GET['getNewCounts'])) {
- pfBlockerNG_get_table("js");
+ pfBlockerNG_get_table('js');
return;
}
+// Reset DNSBL Alias packet counters
+if (isset($_POST['pfblockerngdnsblclear'])) {
+ $dnsbl_info = array_map('str_getcsv', @file("{$pfb['dnsbl_info']}"));
+ if (!empty ($dnsbl_info)) {
+ $handle = fopen("{$pfb['dnsbl_info']}", 'w');
+ foreach ($dnsbl_info as $line) {
+ if (substr($line[0], 0, 1) != '#') {
+ $line[3] = '0';
+ }
+ fputcsv($handle, $line);
+ }
+ fclose ($handle);
+ }
+ header('Location: ../../index.php');
+}
+
// Sort widget table according to user configuration
-function pfbsort(&$array, $subkey="id", $sort_ascending=FALSE) {
+function pfbsort(&$array, $subkey='id', $sort_ascending=FALSE) {
if (empty($array)) {
return;
}
@@ -130,12 +119,16 @@ function pfbsort(&$array, $subkey="id", $sort_ascending=FALSE) {
$temp_array[key($array)] = array_shift($array);
}
+ if ($subkey == 'alias') {
+ $subkey = 0;
+ }
+
foreach ($array as $key => $val) {
$offset = 0;
$found = FALSE;
foreach ($temp_array as $tmp_key => $tmp_val) {
- if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) {
- $temp_array = array_merge((array)array_slice($temp_array,0,$offset), array($key => $val), array_slice($temp_array,$offset));
+ if (!$found && strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) {
+ $temp_array = array_merge((array)array_slice($temp_array, 0, $offset), array($key => $val), array_slice($temp_array, $offset));
$found = TRUE;
}
$offset++;
@@ -156,14 +149,14 @@ function pfbsort(&$array, $subkey="id", $sort_ascending=FALSE) {
// Collect all pfBlockerNG statistics
function pfBlockerNG_get_counts() {
global $config, $pfb;
- $pfb_table = array();
+ $pfb_table = $pfb_dtable = array();
/* Alias Table Definitions - 'update' - Last Updated Timestamp
'rule' - Total number of Firewall rules per alias
'count' - Total Line Count per alias
'packets' - Total number of pf packets per alias */
- exec("/sbin/pfctl -vvsTables | grep -A4 'pfB_'", $pfb_pfctl);
+ exec("{$pfb['pfctl']} -vvsTables | {$pfb['grep']} -A4 'pfB_'", $pfb_pfctl);
if (!empty($pfb_pfctl)) {
foreach($pfb_pfctl as $line) {
$line = trim(str_replace(array( '[', ']' ), '', $line));
@@ -173,9 +166,9 @@ function pfBlockerNG_get_counts() {
unset($pfb_alias);
continue;
}
- exec("/usr/bin/grep -cv '^1\.1\.1\.1' {$pfb['aliasdir']}/{$pfb_alias}.txt", $match);
+ exec("{$pfb['grep']} -cv '^1\.1\.1\.1$' {$pfb['aliasdir']}/{$pfb_alias}.txt", $match);
$pfb_table[$pfb_alias] = array('count' => $match[1], 'img' => $pfb['down']);
- exec("ls -ld {$pfb['aliasdir']}/{$pfb_alias}.txt | awk '{ print $6,$7,$8 }'", $update);
+ exec("{$pfb['ls']} -ld {$pfb['aliasdir']}/{$pfb_alias}.txt | {$pfb['awk']} '{ print $6,$7,$8 }'", $update);
$pfb_table[$pfb_alias]['update'] = $update[0];
$pfb_table[$pfb_alias]['rule'] = 0;
unset($match, $update);
@@ -198,21 +191,21 @@ function pfBlockerNG_get_counts() {
}
else {
// Error. No pf labels found.
- $pfb['pfctl'] = TRUE;
+ $pfb['pfctlerr'] = TRUE;
}
// Determine if firewall rules are defined
- if (is_array($config['filter']['rule'])) {
+ if (isset($config['filter']['rule'])) {
foreach ($config['filter']['rule'] as $rule) {
// Skip disabled rules
if (isset($rule['disabled'])) {
continue;
}
- if (stripos($rule['source']['address'], "pfb_") !== FALSE) {
+ if (stripos($rule['source']['address'], 'pfb_') !== FALSE) {
$pfb_table[$rule['source']['address']]['img'] = $pfb['up'];
$pfb_table[$rule['source']['address']]['rule'] += 1;
}
- if (stripos($rule['destination']['address'], "pfb_") !== FALSE) {
+ if (stripos($rule['destination']['address'], 'pfb_') !== FALSE) {
$pfb_table[$rule['destination']['address']]['img'] = $pfb['up'];
$pfb_table[$rule['destination']['address']]['rule'] += 1;
}
@@ -220,79 +213,115 @@ function pfBlockerNG_get_counts() {
}
// Collect packet fence rule numbers
- exec("/sbin/pfctl -vv -sr | grep 'pfB_'", $pfrules);
+ exec("{$pfb['pfctl']} -vv -sr | {$pfb['grep']} 'pfB_'", $pfrules);
if (!empty($pfrules)) {
foreach ($pfrules as $result) {
// Sample : @112(0) block return in log quick on em1 from any to <pfB_PRI1:160323> label "USER_RULE: pfB_PRI1"
- if (preg_match("/@(\d+)\(\d+\).*\<(pfB_\w+):\d+\>/", $result, $rule)) {
- $pfb_table[$rule[2]]['rules'] .= $rule[1] . '|';
+ $id = strstr($result, '(', FALSE);
+ $id = ltrim(strstr($id, ')', TRUE), '(');
+ $descr = ltrim(stristr($result, '<pfb_', FALSE), '<');
+ $descr = strstr($descr, ':', TRUE);
+
+ if (!empty($id) && !empty($descr) && strpos($pfb_table[$descr]['rules'], $id) === FALSE) {
+ $pfb_table[$descr]['rules'] .= $id . '|';
+ }
+ }
+ }
+
+ // DNSBL collect statistics
+ if ($pfb['enable'] == 'on' && $pfb['dnsbl'] == 'on' && file_exists ("{$pfb['dnsbl_info']}")) {
+ $dnsbl_info = array_map('str_getcsv', @file("{$pfb['dnsbl_info']}"));
+ if (!empty($dnsbl_info)) {
+ foreach ($dnsbl_info as $line) {
+ if (substr($line[0], 0, 1) != '#') {
+ if ($line[2] == 'disabled') {
+ $pfb_dtable[$line[0]] = array ('count' => 'disabled', 'img' => $pfb['down']);
+ } else {
+ $pfb_dtable[$line[0]] = array ('count' => $line[2], 'img' => $pfb['up']);
+ }
+ $pfb_dtable[$line[0]]['update'] = "{$line[1]}";
+ $pfb_dtable[$line[0]]['packets'] = "{$line[3]}";
+ }
}
}
}
// Sort tables per sort customization
- if ($pfb['sortcolumn'] != "none") {
- if ($pfb['sortdir'] == "asc") {
- pfbsort($pfb_table, $pfb['sortcolumn'], TRUE);
- } else {
+ if ($pfb['sortcolumn'] != 'none') {
+ if ($pfb['sortdir'] == 'asc') {
pfbsort($pfb_table, $pfb['sortcolumn'], FALSE);
+ pfbsort($pfb_dtable, $pfb['sortcolumn'], FALSE);
+ } else {
+ pfbsort($pfb_table, $pfb['sortcolumn'], TRUE);
+ pfbsort($pfb_dtable, $pfb['sortcolumn'], TRUE);
}
}
+ $pfb_table = array_merge($pfb_table, $pfb_dtable);
return $pfb_table;
}
// Called on initial load and Ajax to update table contents
-function pfBlockerNG_get_table($mode="") {
+function pfBlockerNG_get_table($mode='') {
global $pfb;
$counter = 0; $dcounter = 1; $response = '';
$pfb_table = pfBlockerNG_get_counts();
if (!empty($pfb_table)) {
foreach ($pfb_table as $pfb_alias => $values) {
- // Add firewall rules count associated with alias
- $values['img'] = $values['img'] . "<span title='Alias Firewall Rule count' ><small>({$values['rule']})</small></span>";
-
- // If packet fence errors found, display error.
- if ($pfb['pfctl']) {
- $values['img'] = $pfb['err'];
- }
-
- // Alias table popup
- if ($values['count'] > 0 && $pfb['popup'] == "on") {
- $alias_popup = rule_popup($pfb_alias, '', '', '');
- $alias_span = $alias_popup['src'];
- $alias_span_end = $alias_popup['src_end'];
- }
- else {
- $alias_span = '';
- $alias_span_end = '';
- }
+ if (strpos($pfb_alias, 'DNSBL_') !== FALSE) {
+ $alias_span = $alias_span_end = '';
+ $packets = $values['packets'];
+ $dnsbl = TRUE;
+ } else {
+ // Add firewall rules count associated with alias
+ $values['img'] = $values['img'] . "<span title='Alias Firewall Rule count' ><small>({$values['rule']})</small></span>";
+
+ // If packet fence errors found, display error.
+ if ($pfb['pfctlerr']) {
+ $values['img'] = $pfb['err'];
+ }
- // Packet column pivot to Alerts Tab
- if ($values['packets'] > 0) {
- $rules = rtrim($values['rules'], '|');
- if ($values['packets'] > $pfb['maxpivot']) {
- $aentries = $pfb['maxpivot'];
- } else {
- $aentries = $values['packets'];
+ // Alias table popup
+ if ($values['count'] > 0 && $pfb['popup'] == 'on') {
+ $alias_popup = rule_popup($pfb_alias, '', '', '');
+ $alias_span = $alias_popup['src'];
+ $alias_span_end = $alias_popup['src_end'];
+ }
+ else {
+ $alias_span = $alias_span_end = '';
}
- $packets = "<a target='_new' href='/pfblockerng/pfblockerng_alerts.php?rule={$rules}&entries={$aentries}' ";
- $packets .= "style='text-decoration: underline;' title='Click to view these packets in Alerts tab' >{$values['packets']}</a>";
- }
- else {
- $packets = $values['packets'];
+ // Packet column pivot to Alerts Tab
+ if ($values['packets'] > 0) {
+ $rules = rtrim($values['rules'], '|');
+ if ($values['packets'] > $pfb['maxpivot']) {
+ $aentries = $pfb['maxpivot'];
+ } else {
+ $aentries = $values['packets'];
+ }
+
+ $packets = "<a target='_blank' href='/pfblockerng/pfblockerng_alerts.php?rule={$rules}&entries={$aentries}' ";
+ $packets .= "title='Click to view these packets in Alerts tab' >{$values['packets']}</a>";
+ }
+ else {
+ $packets = $values['packets'];
+ }
}
- if ($mode == "js") {
- echo $response = $alias_span . $pfb_alias . $alias_span_end . "||" . $values['count'] . "||" . $packets . "||" . $values['update']
- . "||" . $values['img'] . "\n";
+ if ($mode == 'js') {
+ echo $response = "{$alias_span}{$pfb_alias}{$alias_span_end}||{$values['count']}||{$packets}||{$values['update']}||{$values['img']}\n";
}
else {
- $RowClass = $counter % 2 ? $pfb['RowEvenClass'] : $pfb['RowOddClass'];
- $counter++;
+ // Print darker shading for DNSBL
+ if ($dnsbl) {
+ $RowClass = $dcounter % 2 ? $pfb['RowEvenClass2'] : $pfb['RowOddClass'];
+ $dcounter++;
+ } else {
+ $RowClass = $counter % 2 ? $pfb['RowEvenClass'] : $pfb['RowOddClass'];
+ $counter++;
+ }
echo (" <tr {$RowClass}>
- <td class='listMRr ellipsis'>" . $alias_span . $pfb_alias . $alias_span_end . "</td>
+ <td class='listMRr ellipsis'>{$alias_span}{$pfb_alias}{$alias_span_end}</td>
<td class='listMRr' align='center'>{$values['count']}</td>
<td class='listMRr' sorttable_customkey='{$values['packets']}' align='center'>{$packets}</td>
<td class='listMRr' align='center'>{$values['update']}</td>
@@ -304,29 +333,51 @@ function pfBlockerNG_get_table($mode="") {
}
// 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.";
+if ($pfb['enable'] == 'on') {
+ $mode = 'pass';
+ $pfb_msg = 'pfBlockerNG is Active.';
+
+ if ($pfb['config']['enable_dup'] == 'on') {
+ // Check Masterfile Database Sanity
+ $db_sanity = exec("{$pfb['grep']} 'Sanity check' {$pfb['logdir']}/pfblockerng.log | {$pfb['grep']} -o 'PASSED' | tail -1");
+ if ($db_sanity != 'PASSED') {
+ $mode = 'reject';
+ $pfb_msg = 'pfBlockerNG deDuplication is out of sync. Perform a Force Reload to correct.';
+ }
+ }
+} else {
+ $mode = 'block';
+ $pfb_msg = 'pfBlockerNG is Disabled.';
+}
+$pfb_status = "/themes/{$g['theme']}/images/icons/icon_{$mode}.gif";
+
+// Status indicator if DNSBL is actively running
+if ($pfb['dnsbl'] == 'on' && $pfb['unbound_state'] == 'on' && $pfb['enable'] == 'on' &&
+ strpos(file_get_contents("{$pfb['dnsbldir']}/unbound.conf"), 'pfb_dnsbl') !== FALSE) {
+ $mode = 'pass';
+ $dnsbl_msg = 'DNSBL is Active.';
} else {
- $pfb_status = "/themes/{$g['theme']}/images/icons/icon_block.gif";
- $pfb_msg = "pfBlockerNG is Disabled.";
+ $mode = 'block';
+ $dnsbl_msg = 'DNSBL is Disabled.';
}
+$dnsbl_status = "/themes/{$g['theme']}/images/icons/icon_{$mode}.gif";
// 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'");
+$dcount = exec("{$pfb['cat']} {$pfb['denydir']}/*.txt | {$pfb['grep']} -cv '^#\|^$\|^1\.1\.1\.1$'");
+$pcount = exec("{$pfb['cat']} {$pfb['permitdir']}/*.txt | {$pfb['grep']} -cv '^#\|^$\|^1\.1\.1\.1$'");
+$mcount = exec("{$pfb['cat']} {$pfb['matchdir']}/*.txt | {$pfb['grep']} -cv '^#\|^$\|^1\.1\.1\.1$'");
+$ncount = exec("{$pfb['cat']} {$pfb['nativedir']}/*.txt | {$pfb['grep']} -cv '^#\|^$\|^1\.1\.1\.1$'");
+$scount = exec("{$pfb['grep']} -c ^ {$pfb['dnsbl_file']}.conf");
+$maxver = exec("grep -o 'Last-.*' /var/log/pfblockerng/maxmind_ver");
// Collect number of suppressed hosts
+$pfbsupp_cnt = 0;
if (file_exists("{$pfb['supptxt']}")) {
- $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}");
-} else {
- $pfbsupp_cnt = 0;
+ $pfbsupp_cnt = exec("{$pfb['grep']} -c ^ {$pfb['supptxt']}");
}
// Collect any failed downloads
-exec("grep $(date +%m/%d/%y) {$pfb['errlog']} | grep 'FAIL'", $results);
+exec("{$pfb['grep']} 'FAIL' {$pfb['errlog']} | {$pfb['grep']} $(date +%m/%d/%y)", $results);
$results = array_reverse($results);
?>
@@ -343,7 +394,7 @@ $results = array_reverse($results);
</tr>
<tr>
<td width="22%" class="vncellt" valign="top" ><input type="text" size="3" name="pfb_maxfails" class="formfld unknown" id="pfb_maxfails"
- title="Tha maximum number of Failed Download Alerts to be shown. Refer to the error.log for add'l details"
+ title="The maximum number of Failed Download Alerts to be shown. Refer to the error.log for add'l details"
value="<?= $pfb['maxfails'] ?>" /></td>
<td width="78%" class="listr" ><?=gettext("Enter number of download fails to display (default:3)");?></td>
</tr>
@@ -357,9 +408,7 @@ $results = array_reverse($results);
<td width="22" class="vncellt" valign="top" >
<select name="pfb_sortcolumn" id="pfb_sortcolumn" class="formselect" title="The Column to be sorted" >
<?php
- $pfbsort = array( 'none' => 'None', 'alias' => 'Alias', 'count' => 'Count',
- 'packets' => 'Packets', 'updated' => 'Updated'
- );
+ $pfbsort = array( 'none' => 'None', 'alias' => 'Alias', 'count' => 'Count', 'packets' => 'Packets', 'updated' => 'Updated' );
foreach ($pfbsort as $sort => $sorttype): ?>
<option value="<?=$sort; ?>" <?php if ($sort == $pfb['sortcolumn']) echo 'selected'; ?> ><?=$sorttype; ?></option>
<?php endforeach; ?>
@@ -383,40 +432,64 @@ $results = array_reverse($results);
<!-- Print widget status bar items -->
<div class="marinarea">
- <table id="pfb_table" border="0" cellspacing="0" cellpadding="0">
+ <table id="pfb_table" width="100%" border="0" cellspacing="0" cellpadding="0">
<thead>
<tr>
- <td valign="middle">&nbsp;<img src="<?= $pfb_status ?>" width="13" height="13" border="0" title="<?=gettext($pfb_msg) ?>" alt="" /></td>
- <td valign="middle">&nbsp;&nbsp;</td>
- <td valign="middle" p style="font-size:10px">
- <?php if ($dcount != 0): ?>
- <?=gettext("Deny:"); echo("&nbsp;<strong>" . $dcount . "</strong>") ?>
- <?php endif; ?>
- <?php if ($pcount != 0): ?>
- <?=gettext("&nbsp;Permit:"); echo("&nbsp;<strong>" . $pcount . "</strong>") ?>
- <?php endif; ?>
- <?php if ($mcount != 0): ?>
- <?=gettext("&nbsp;Match:"); echo("&nbsp;<strong>" . $mcount . "</strong>"); ?>
- <?php endif; ?>
- <?php if ($ncount != 0): ?>
- <?=gettext("&nbsp;Native:"); echo("&nbsp;<strong>" . $ncount . "</strong>"); ?>
- <?php endif; ?>
- <?php if ($pfbsupp_cnt != 0): ?>
- <?=gettext("&nbsp;Supp:"); echo("&nbsp;<strong>" . $pfbsupp_cnt . "</strong>"); ?>
- <?php endif; ?></td>
- <td valign="middle">&nbsp;&nbsp;</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>&nbsp;
- <td valign="top">
+ <td style="font-size:10px;white-space: nowrap;">&nbsp;<img src="<?= $pfb_status ?>"
+ width="13" height="13" border="0" title="<?=gettext($pfb_msg) ?>" alt="" />
+
+ <?=gettext("&nbsp;") ?>
+ <?php if ($dcount != 0): ?>
+ <?php echo("IP- Deny: <strong>{$dcount}</strong>"); ?>
+ <?php endif; ?>
+ <?php if ($pcount != 0): ?>
+ <?php echo("Permit: <strong>{$pcount}</strong>"); ?>
+ <?php endif; ?>
+ <?php if ($mcount != 0): ?>
+ <?php echo("Match: <strong>{$mcount}</strong>"); ?>
+ <?php endif; ?>
+ <?php if ($ncount != 0): ?>
+ <?php echo("Native: <strong>{$ncount}</strong>"); ?>
+ <?php endif; ?>
+ <?php if ($pfbsupp_cnt != 0): ?>
+ <?php echo("Supp: <strong>{$pfbsupp_cnt}</strong>"); ?>
+ <?php endif; ?>
+ <?=gettext("&nbsp;") ?>
+
+ <a target='_blank' 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>&nbsp;
+
<?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">
+ <form style="display:inline;" 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") ?>"/>
+ <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>
+
+ <?php if ($pfb['dnsbl'] == 'on'): ?> <!--Enable DNSBL widget statistics if enabled-->
+ <tr>
+ <td style="font-size:10px">&nbsp;<img src="<?= $dnsbl_status ?>" width="13" height="13" border="0"
+ title="<?=gettext($dnsbl_msg); ?>" alt="" />
+ <?php if ($scount != 0): ?>
+ <?php echo("&nbsp;&nbsp;DNSBL- <strong>{$scount}</strong>&nbsp;&nbsp;"); ?>
+ <?php endif; ?>
+ <form style="display:inline"; action="/widgets/widgets/pfblockerng.widget.php" method="post" name="widget_pfblockerng_dnsblclear">
+ <input type="hidden" value="dnsblclear" name="pfblockerngdnsblclear" />
+ <input class="vexpl" type="image" name="dnsblclearbutton" src="/themes/<?=$g['theme']; ?>/images/icons/icon_x.gif"
+ width="14" height="14" border="0" title="<?=gettext("Clear DNSBL Packets") ?>"/>
+ </form>
+ </td>
+ </tr>
+ <?php endif; ?>
+
+ <tr>
+ <td >
+ <?php echo "<br />&nbsp;MaxMind: {$maxver}"; ?>
+ </td>
+ </tr>
</thead>
</table>
</div>
@@ -426,17 +499,18 @@ $results = array_reverse($results);
<?php
// Report any failed downloads
-$counter = 0;
if (!empty($results)) {
+ $counter = 1;
+ $entries = count($results);
foreach ($results as $result) {
$RowClass = $counter % 2 ? $pfb['RowEvenClass'] : $pfb['RowOddClass'];
- echo(" <tr " . $RowClass . "><td class='" . $pfb['ColClass'] . "'>" . $result . "</td><tr>");
- $counter++;
- if ($counter > $pfb['maxfails']) {
+ if ($counter > $pfb['maxfails'] && $entries > $pfb['maxfails']) {
// To many errors stop displaying
- echo(" <tr " . $RowClass . "><td class='" . $pfb['ColClass'] . "'>" . (count($results) - $pfb['maxfails']) . " more error(s)...</td><tr>");
+ echo("<tr {$RowClass}><td class='{$pfb['ColClass']}'>" . ($entries - $pfb['maxfails']) . ' more error(s)...</td><tr>');
break;
}
+ echo("<tr {$RowClass}><td class='{$pfb['ColClass']}'>{$result}</td><tr>");
+ $counter++;
}
}
diff --git a/config/pfblockerng/pfblockerng.xml b/config/pfblockerng/pfblockerng.xml
index d3b2cb16..c7f2c068 100644
--- a/config/pfblockerng/pfblockerng.xml
+++ b/config/pfblockerng/pfblockerng.xml
@@ -1,20 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
-<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
<packagegui>
<copyright>
<![CDATA[
-/* $Id$ */
/* ======================================================================================= */
/*
pfBlockerNG.xml
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Based upon pfblocker for pfSense
- Copyright (C) 2011 Marcello Coutinho
+ Copyright (c) 2011 Marcello Coutinho
All rights reserved.
/*
/* ====================================================================================== */
@@ -49,7 +48,7 @@
<requirements>Describe your package requirements here</requirements>
<faq>Currently there are no FAQ items provided.</faq>
<name>pfblockerng</name>
- <version>1.09</version>
+ <version>2.0</version>
<title>pfBlockerNG: General Settings</title>
<include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
<addedit_string>pfBlockerNG: Save General Settings</addedit_string>
@@ -60,84 +59,91 @@
<section>Firewall</section>
<url>/pkg_edit.php?xml=pfblockerng.xml</url>
</menu>
+ <service>
+ <name>dnsbl</name>
+ <rcfile>dnsbl.sh</rcfile>
+ <executable>lighttpd_pfb</executable>
+ <description>pfBlockerNG DNSBL Web Server</description>
+ </service>
<additional_files_needed>
<item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.priv.inc</item>
<prefix>/etc/inc/priv/</prefix>
- <chmod>0644</chmod>
</additional_files_needed>
<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_install.inc</item>
<prefix>/usr/local/pkg/pfblockerng/</prefix>
</additional_files_needed>
<additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_extra.inc</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ </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_alerts_ar.php</item>
+ <prefix>/usr/local/www/pfblockerng/</prefix>
</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>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_threats.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_dnsbl.xml</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_dnsbl_lists.xml</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_dnsbl_easylist.xml</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
</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/countrycodes.tar.bz2</item>
- <prefix>/var/db/pfblockerng/</prefix>
- <chmod>0444</chmod>
</additional_files_needed>
<additional_files_needed>
<item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.sh</item>
@@ -145,14 +151,14 @@
<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>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/index.php</item>
+ <prefix>/usr/local/www/pfblockerng/www/</prefix>
<chmod>0755</chmod>
</additional_files_needed>
<tabs>
<tab>
<text>General</text>
- <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
<active/>
</tab>
<tab>
@@ -165,47 +171,23 @@
</tab>
<tab>
<text>Reputation</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml</url>
</tab>
<tab>
<text>IPv4</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url>
</tab>
<tab>
<text>IPv6</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Top20</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Africa</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Asia</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url>
</tab>
<tab>
- <text>Europe</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
</tab>
<tab>
- <text>N.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Oceania</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>S.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>P.S.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
</tab>
<tab>
<text>Logs</text>
@@ -213,7 +195,7 @@
</tab>
<tab>
<text>Sync</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml</url>
</tab>
</tabs>
<fields>
@@ -224,8 +206,8 @@
<field>
<fielddescr>LINKS</fielddescr>
<fieldname></fieldname>
- <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp;
- <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
</description>
<type>info</type>
</field>
@@ -241,7 +223,7 @@
<fieldname>pfb_keep</fieldname>
<type>checkbox</type>
<description><![CDATA[Keep Settings: <br /><font color='red'>Note:</font> - 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!<br /><br />
+ on Installation/Upgrade<br />If 'Keep Settings' is not 'enabled' on pkg Install/De-Install, all settings will be Wiped!<br /><br />
<font color='red'>Note: </font>To clear all downloaded lists, uncheck these two checkboxes and 'Save'.
re-check both boxes and run a 'Force Update']]>
</description>
@@ -258,8 +240,8 @@
<fielddescr>Hour Interval</fielddescr>
<fieldname>pfb_interval</fieldname>
<description><![CDATA[Default: <strong>Every hour</strong><br />
- Select the cron Hour Interval. The interval selected will be used with the Start min/hour below.<br />
- <strong>Ensure that all List 'Update Settings' are within the selected Interval/Start Hour Settings.</strong>]]>
+ Select the cron hour interval. The interval selected will be used with the start min/hour below.<br />
+ <strong>Ensure that all list 'Update settings' are within the selected interval/start hour settings.</strong>]]>
</description>
<type>select</type>
<options>
@@ -295,7 +277,7 @@
<fielddescr>Start Hour</fielddescr>
<fieldname>pfb_hour</fieldname>
<description><![CDATA[Default: <strong>0</strong><br />
- Select the Start Hour]]>
+ Select the start hour]]>
</description>
<type>select</type>
<options>
@@ -330,7 +312,7 @@
<field>
<fielddescr><![CDATA['Daily/Weekly'<br />Start Hour]]></fielddescr>
<fieldname>pfb_dailystart</fieldname>
- <description><![CDATA[Default: <strong>0</strong><br />This is used for the 'Daily/Weekly' Scheduler Only.]]></description>
+ <description><![CDATA[Default: <strong>0</strong><br />This is used by the 'Daily/Weekly' scheduler only.]]></description>
<type>select</type>
<options>
<option><name>0</name><value>0</value></option>
@@ -368,13 +350,19 @@
<description>Only for IPv4 Lists</description>
</field>
<field>
+ <fielddescr>Enable Aggregation of CIDRs</fielddescr>
+ <fieldname>enable_agg</fieldname>
+ <type>checkbox</type>
+ <description>Optimise CIDRs (not recommended for slow systems with large 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 /32 or /24 will need a 'Whitelist Alias' w/ List Action: 'Permit Outbound' Firewall Rule
+ <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 /32 or /24 will need a 'Whitelist alias' w/ list action: 'Permit Outbound' Firewall rule
<br />Do not use the pfBlockerNGSuppress Alias in a Firewall Rule.
This alias is used during the cron download process only.]]>
</description>
@@ -383,17 +371,44 @@
<fielddescr>Global Enable Logging</fielddescr>
<fieldname>enable_log</fieldname>
<type>checkbox</type>
- <description><![CDATA[Firewall Rule logging - Enable Global Logging to [ Status: System Logs: FIREWALL Log ]<br />
- This overrides any Log Settings in the Alias Tabs.]]>
+ <description><![CDATA[Firewall Rule logging - Enable Global logging to [ Status: System Logs: FIREWALL Log ]<br />
+ This overrides any log settings in the Alias tabs.]]>
</description>
</field>
<field>
- <fielddescr>Disable MaxMind Country Database CRON Updates</fielddescr>
+ <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><![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>Max daily download failure threshold</fielddescr>
+ <fieldname>skipfeed</fieldname>
+ <description><![CDATA[Default: <strong>0</strong> (Disabled)<br />
+ Select max daily download failure threshold via CRON. Clear widget 'failed downloads' to reset.]]>
</description>
+ <type>select</type>
+ <options>
+ <option><name>0</name><value>0</value></option>
+ <option><name>1</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>
+ </options>
+ <default_value>0</default_value>
+ </field>
+ <field>
+ <fielddescr>Restore previous download on failure</fielddescr>
+ <fieldname>restore_feed</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[Default: <strong>Enabled</strong><br />
+ When 'selected', on a download failure, the previously downloaded list is restored.]]>
+ </description>
+ <default_value>on</default_value>
</field>
<field>
<fielddescr>Logfile Size</fielddescr>
@@ -423,25 +438,26 @@
<field>
<fieldname>inbound_interface</fieldname>
<fielddescr>Interface(s)</fielddescr>
- <description>Select the Inbound interface(s) you want to Apply Auto Rules to</description>
+ <description>Select the Inbound interface(s) you want to apply auto rules to:</description>
<type>interfaces_selection</type>
<hideinterfaceregex>loopback</hideinterfaceregex>
<required/>
<multiple/>
<combinefields/>
+ <default_value>wan</default_value>
</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>
+ <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>
- <default_value>block</default_value>
<required/>
<combinefields>end</combinefields>
+ <default_value>block</default_value>
</field>
<field>
<fielddescr>Outbound Firewall Rules</fielddescr>
@@ -450,38 +466,39 @@
<field>
<fielddescr>Interface(s)</fielddescr>
<fieldname>outbound_interface</fieldname>
- <description>Select the Outbound interface(s) you want to Apply Auto Rules to</description>
+ <description>Select the Outbound interface(s) you want to apply auto rules to:</description>
<type>interfaces_selection</type>
<hideinterfaceregex>loopback</hideinterfaceregex>
<required/>
<multiple/>
<combinefields/>
+ <default_value>lan</default_value>
</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>
+ <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>
- <default_value>reject</default_value>
<required/>
+ <default_value>reject</default_value>
<combinefields>end</combinefields>
</field>
<field>
<fielddescr>OpenVPN Interface</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>
+ <description>Select to add auto-rules for OpenVPN. These will be added to 'Floating Rules' or OpenVPN rules tab.</description>
</field>
<field>
<fielddescr>Floating Rules</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 />
+ <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>
@@ -490,8 +507,8 @@
<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 />
- &nbsp;&nbsp;Selecting 'original format', sets pfBlockerNG rules at the top of the Firewall TAB.<br />
- &nbsp;&nbsp;Selecting any other 'Order' will re-order <strong>all the Rules to the format indicated!</strong>]]>
+ &emsp;Selecting 'original format', sets pfBlockerNG rules at the top of the Firewall TAB.<br />
+ &emsp;Selecting any other 'Order' will re-order <strong>all the rules to the format indicated!</strong>]]>
</description>
<type>select</type>
<options>
@@ -506,7 +523,7 @@
<fielddescr>Auto Rule Suffix</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]]>
+ Select 'Auto Rule' description suffix for auto defined rules. pfBlockerNG must be disabled to modify suffix]]>
</description>
<type>select</type>
<options>
@@ -517,6 +534,14 @@
<default_value>autorule</default_value>
</field>
<field>
+ <fielddescr>Kill States</fielddescr>
+ <fieldname>killstates</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[When 'Enabled', after a cron event or any 'Force' commands, any blocked IPs found in the <br />
+ Firewall states will be cleared.]]>
+ </description>
+ </field>
+ <field>
<name><![CDATA[Acknowledgements]]></name>
<type>listtopic</type>
</field>
@@ -525,11 +550,11 @@
<fieldname>credits</fieldname>
<type>info</type>
<description><![CDATA[<strong>pfBlockerNG </strong>
- Created in 2015 by <a target=_new href='https://forum.pfsense.org/index.php?action=profile;u=238481'>BBcan177.</a><br /><br />
+ Created in 2015 by <a target='_blank' 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]]>
+ Country database GeoLite distributed under the Creative Commons Attribution-ShareAlike 3.0 Unported License by:
+ MaxMind Inc. @ <a target='_blank' href='http://www.maxmind.com'>MaxMind.com</a>.
+ The database is automatically updated the first Tuesday of each month]]>
</description>
</field>
<field>
@@ -540,7 +565,7 @@
</description>
</field>
<field>
- <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule edits. &emsp; Changes are applied via CRON or
'Force Update'</center>]]></name>
<type>listtopic</type>
</field>
@@ -556,11 +581,15 @@
]]>
</custom_php_deinstall_command>
<custom_php_validation_command>
+ <![CDATA[
pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
</custom_php_validation_command>
<custom_php_resync_config_command>
+ <![CDATA[
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
index 7253d04d..79cd0d62 100644
--- a/config/pfblockerng/pfblockerng_alerts.php
+++ b/config/pfblockerng/pfblockerng_alerts.php
@@ -3,14 +3,14 @@
pfBlockerNG_Alerts.php
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 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) 2015 Bill Meeks
+ Copyright (c) 2015 Bill Meeks
All rights reserved.
Javascript Hostname Lookup modifications by J. Nieuwenhuizen
@@ -39,392 +39,538 @@
POSSIBILITY OF SUCH DAMAGE.
*/
-// Auto-Resolve Hostnames
-if (isset($_REQUEST['getpfhostname'])) {
- $getpfhostname = trim(htmlspecialchars($_REQUEST['getpfhostname']));
- if (strlen($getpfhostname) >= 8) {
- $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES);
- } else {
- $hostname = $getpfhostname;
- }
- if ($hostname == $getpfhostname) {
- $hostname = 'unknown';
- }
- echo $hostname;
- die;
-}
+require_once('util.inc');
+require_once('guiconfig.inc');
+require_once('/usr/local/pkg/pfblockerng/pfblockerng.inc');
-require_once("util.inc");
-require_once("guiconfig.inc");
-require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
-global $rule_list, $pfb_localsub;
+global $g, $pfb, $rule_list, $pfb_localsub;
pfb_global();
-$pfs_version = substr(trim(file_get_contents("/etc/version")),0,3);
-
-if ($pfs_version == "2.2") {
- $prefix = "/usr/pbi/pfblockerng-" . php_uname("m");
-} else {
- $prefix = "/usr/local";
-}
-
-// Application Paths
-$pathgeoip = "{$prefix}/bin/geoiplookup";
-$pathgeoip6 = "{$prefix}/bin/geoiplookup6";
+// Application paths
+$pathgeoip = "{$pfb['prefix']}/bin/geoiplookup";
+$pathgeoip6 = "{$pfb['prefix']}/bin/geoiplookup6";
-// Define File Locations
+// Define file locations
$filter_logfile = "{$g['varlog_path']}/filter.log";
-$pathgeoipdat = "{$prefix}/share/GeoIP/GeoIP.dat";
-$pathgeoipdat6 = "{$prefix}/share/GeoIP/GeoIPv6.dat";
+$pathgeoipdat = "{$pfb['geoipshare']}/GeoIP.dat";
+$pathgeoipdat6 = "{$pfb['geoipshare']}/GeoIPv6.dat";
-// Emerging Threats IQRisk Header Name Reference
-$pfb['et_header'] = TRUE;
+// Proofpoint ET IQRisk header name reference
$et_header = $config['installedpackages']['pfblockerngreputation']['config'][0]['et_header'];
+$pfb['et_header'] = TRUE;
if (empty($et_header)) {
$pfb['et_header'] = FALSE;
}
-// Collect pfBlockerNGSuppress Alias and Create pfbsuppression.txt
-if ($pfb['supp'] == "on") {
+// Collect pfBlockerNGSuppress alias and create pfbsuppression.txt
+if ($pfb['supp'] == 'on') {
pfb_create_suppression_file();
}
-// Collect Number of Suppressed Hosts
+// Collect number of suppressed hosts
+$pfbsupp_cnt = 0;
if (file_exists("{$pfb['supptxt']}")) {
- $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}");
-} else {
- $pfbsupp_cnt = 0;
+ $pfbsupp_cnt = exec("{$pfb['grep']} -c ^ {$pfb['supptxt']}");
}
-$pfb['global'] = &$config['installedpackages']['pfblockerngglobal'];
-
-if (!isset($pfb['global']['pfbdenycnt'])) {
- $pfb['global']['pfbdenycnt'] = '25';
-}
-if (!isset($pfb['global']['pfbpermitcnt'])) {
- $pfb['global']['pfbpermitcnt'] = '5';
-}
-if (!isset($pfb['global']['pfbmatchcnt'])) {
- $pfb['global']['pfbmatchcnt'] = '5';
-}
-if (!isset($pfb['global']['pfbdnscnt'])) {
- $pfb['global']['pfbdnscnt'] = '5';
-}
-if (empty($pfb['global']['alertrefresh'])) {
- $pfb['global']['alertrefresh'] = 'off';
-}
-if (empty($pfb['global']['hostlookup'])) {
- $pfb['global']['hostlookup'] = 'off';
+// Alerts tab customizations
+$aglobal_array = array('pfbdenycnt' => 25, 'pfbpermitcnt' => 5, 'pfbmatchcnt' => 5, 'pfbdnscnt' => 5, 'alertrefresh' => 'on', 'hostlookup' => 'on');
+$pfb['aglobal'] = &$config['installedpackages']['pfblockerngglobal'];
+foreach ($aglobal_array as $type => $value) {
+ ${"$type"} = $pfb['aglobal'][$type] != '' ? $pfb['aglobal'][$type] : $value;
}
+// Save Alerts tab customizations
if (isset($_POST['save'])) {
- if (!is_array($pfb['global'])) {
- $pfb['global'] = array();
- }
- $pfb['global']['alertrefresh'] = $_POST['alertrefresh'] ? 'on' : 'off';
- $pfb['global']['hostlookup'] = $_POST['hostlookup'] ? 'on' : 'off';
- if (is_numeric($_POST['pfbdenycnt'])) {
- $pfb['global']['pfbdenycnt'] = $_POST['pfbdenycnt'];
- }
- if (is_numeric($_POST['pfbpermitcnt'])) {
- $pfb['global']['pfbpermitcnt'] = $_POST['pfbpermitcnt'];
- }
- if (is_numeric($_POST['pfbmatchcnt'])) {
- $pfb['global']['pfbmatchcnt'] = $_POST['pfbmatchcnt'];
- }
- if (is_numeric($_POST['pfbdnscnt'])) {
- $pfb['global']['pfbdnscnt'] = $_POST['pfbdnscnt'];
+ $pfb['aglobal']['alertrefresh'] = htmlspecialchars($_POST['alertrefresh']) ?: 'off';
+ $pfb['aglobal']['hostlookup'] = htmlspecialchars($_POST['hostlookup']) ?: 'off';
+ unset($aglobal_array['alertrefresh'], $aglobal_array['hostlookup']);
+
+ foreach ($aglobal_array as $type => $value) {
+ if (ctype_digit(htmlspecialchars($_POST[$type]))) {
+ $pfb['aglobal'][$type] = htmlspecialchars($_POST[$type]);
+ }
}
- write_config("pfBlockerNG pkg: updated ALERTS tab settings.");
- header("Location: " . $_SERVER['PHP_SELF']);
- exit;
-}
-if (is_array($pfb['global'])) {
- $alertrefresh = $pfb['global']['alertrefresh'];
- $hostlookup = $pfb['global']['hostlookup'];
- $pfbdenycnt = $pfb['global']['pfbdenycnt'];
- $pfbpermitcnt = $pfb['global']['pfbpermitcnt'];
- $pfbmatchcnt = $pfb['global']['pfbmatchcnt'];
- $pfbdnscnt = $pfb['global']['pfbdnscnt'];
+ write_config('pfBlockerNG pkg: updated ALERTS tab settings.');
+ header('Location: /pfblockerng/pfblockerng_alerts.php');
+ exit;
}
-
-// Define Alerts Log filter Rollup window variable and collect Widget Alert Pivot details
+// Define alerts log filter rollup window variable and collect widget alert pivot details
if (isset($_REQUEST['rule'])) {
- $filterfieldsarray[0] = $_REQUEST['rule'];
- $pfbdenycnt = $pfbpermitcnt = $pfbmatchcnt = $_REQUEST['entries'];
- $pfb['filterlogentries'] = TRUE;
-}
-else {
- $pfb['filterlogentries'] = FALSE;
+ $filterfieldsarray[0] = htmlspecialchars($_REQUEST['rule']);
+ $pfbdenycnt = $pfbpermitcnt = $pfbmatchcnt = htmlspecialchars($_REQUEST['entries']);
+ $pfb['filterlogentries'] = TRUE;
+} else {
+ $pfb['filterlogentries'] = FALSE;
}
-
-function pfb_match_filter_field($flent, $fields) {
- foreach ($fields as $key => $field) {
- if ($field == null) {
- continue;
- }
- if ((strpos($field, '!') === 0)) {
- $field = substr($field, 1);
- $field_regex = str_replace('/', '\/', str_replace('\/', '/', $field));
- if (@preg_match("/{$field_regex}/i", $flent[$key])) {
- return false;
- }
- }
- else {
- $field_regex = str_replace('/', '\/', str_replace('\/', '/', $field));
- if (!@preg_match("/{$field_regex}/i", $flent[$key])) {
- return false;
- }
+// Re-enable any Alert 'filter settings' on page refresh
+if (isset($_REQUEST['refresh'])) {
+ $refresharr = unserialize(urldecode($_REQUEST['refresh']));
+ if (isset($refresharr)) {
+ foreach ($refresharr as $key => $type) {
+ $filterfieldsarray[htmlspecialchars($key)] = htmlspecialchars($type) ?: null;
}
}
- return true;
+ $pfb['filterlogentries'] = TRUE;
}
-
-if ($_POST['filterlogentries_submit']) {
- // Set flag for filtering alert entries
+// Filter Alerts based on user defined 'filter settings'
+if (isset($_POST['filterlogentries_submit'])) {
$pfb['filterlogentries'] = TRUE;
-
- // Note the order of these fields must match the order decoded from the alerts log
$filterfieldsarray = array();
- $filterfieldsarray[0] = $_POST['filterlogentries_rule'] ? $_POST['filterlogentries_rule'] : null;
- $filterfieldsarray[2] = $_POST['filterlogentries_int'] ? $_POST['filterlogentries_int'] : null;
- $filterfieldsarray[6] = strtolower($_POST['filterlogentries_proto']) ? $_POST['filterlogentries_proto'] : null;
- // Remove any zero-length spaces added to the IP address that could creep in from a copy-paste operation
- $filterfieldsarray[7] = $_POST['filterlogentries_srcip'] ? str_replace("\xE2\x80\x8B", "", $_POST['filterlogentries_srcip']) : null;
- $filterfieldsarray[8] = $_POST['filterlogentries_dstip'] ? str_replace("\xE2\x80\x8B", "", $_POST['filterlogentries_dstip']) : null;
+ foreach (array( 0 => 'rule', 2 => 'int', 6 => 'proto', 7 => 'srcip', 8 => 'dstip',
+ 9 => 'srcport', 10 => 'dstport', 90 => 'dnsbl', 99 => 'date') as $key => $type) {
- $filterfieldsarray[9] = $_POST['filterlogentries_srcport'] ? $_POST['filterlogentries_srcport'] : null;
- $filterfieldsarray[10] = $_POST['filterlogentries_dstport'] ? $_POST['filterlogentries_dstport'] : null;
- $filterfieldsarray[99] = $_POST['filterlogentries_date'] ? $_POST['filterlogentries_date'] : null;
+ $type = htmlspecialchars($_POST['filterlogentries_' . "{$type}"]) ?: null;
+ if ($key == 6) {
+ $type = strtolower("{$type}");
+ }
+ $filterfieldsarray[$key] = $type ?: null;
+ }
}
-
-if ($_POST['filterlogentries_clear']) {
- $pfb['filterlogentries'] = TRUE;
+if (isset($_POST['filterlogentries_clear'])) {
+ $pfb['filterlogentries'] = FALSE;
$filterfieldsarray = array();
}
-
-// Collect pfBlockerNG Rule Names and Number
-$rule_list = array();
-exec("/sbin/pfctl -vv -sr | grep 'pfB_'", $results);
-if (!empty($results)) {
- foreach ($results as $result) {
-
- // Find Rule Descriptions
- $descr = "";
- if (preg_match("/USER_RULE: (\w+)/",$result,$desc)) {
- $descr = $desc[1];
- }
-
- preg_match ("/@(\d+)\(/",$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
+// Add IP to the suppression alias
if (isset($_POST['addsuppress'])) {
- $ip = "";
if (isset($_POST['ip'])) {
- $ip = $_POST['ip'];
- $table = $_POST['table'];
- $descr = $_POST['descr'];
- $cidr = $_POST['cidr'];
+ $ip = htmlspecialchars($_POST['ip']);
+ $table = htmlspecialchars($_POST['table']);
+ $descr = htmlspecialchars($_POST['descr']);
+ $cidr = htmlspecialchars($_POST['cidr']);
- // If Description or CIDR field is empty, exit.
+ // If description or CIDR field is empty, exit.
if (empty($descr) || empty($cidr)) {
- header("Location: " . $_SERVER['PHP_SELF']);
+ header('Location: /pfblockerng/pfblockerng_alerts.php');
exit;
}
if (is_ipaddr($ip)) {
-
$savemsg1 = "Host IP address {$ip}";
if (is_ipaddrv4($ip)) {
- $iptrim1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.0/24', $ip);
- $iptrim2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.', $ip);
- $iptrim3 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$4', $ip);
-
- if ($cidr == "32") {
- $pfb_pfctl = exec ("/sbin/pfctl -t {$table} -T show | grep {$iptrim1} 2>&1");
-
- if ($pfb_pfctl == "") {
- $savemsg2 = " : Removed /32 entry";
- exec ("/sbin/pfctl -t {$table} -T delete {$ip}");
+ // Explode IP into evaluation strings
+ $ix = ip_explode($ip);
+
+ if ($cidr == 32) {
+ $pfb_pfctl = exec("{$pfb['pfctl']} -t {$table} -T show | grep {$ip} 2>&1");
+ if (!empty($pfb_pfctl)) {
+ $savemsg2 = ' : Removed /32 entry';
+ exec("{$pfb['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}");
+ exec("{$pfb['pfctl']} -t {$table} -T delete {$ix[5]} 2>&1", $pfb_pfctl);
+ if (preg_grep("/1\/1 addresses deleted/", $pfb_pfctl)) {
+ $savemsg2 = ' : Removed /24 entry, added 254 addr';
+ for ($k=0; $k <= 255; $k++) {
+ if ($k != $ix[4]) {
+ exec("{$pfb['pfctl']} -t {$table} -T add {$ix[6]}{$k}");
+ }
}
}
+ else {
+ $savemsg = gettext("Not Suppressed. Host IP address {$ip} is blocked by a CIDR other than /24");
+ header('Location: /pfblockerng/pfblockerng_alerts.php');
+ exit;
+ }
}
} else {
$cidr = 24;
- $savemsg2 = " : Removed /24 entry";
- exec ("/sbin/pfctl -t {$table} -T delete {$iptrim1} 2>&1", $pfb_pfctl);
+ $savemsg2 = ' : Removed /24 entry';
+ exec("{$pfb['pfctl']} -t {$table} -T delete {$ix[5]} 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}");
+ $savemsg2 = ' : Removed all entries';
+ // Remove 0-255 IP address from alias table
+ for ($j=0; $j <= 255; $j++) {
+ exec("{$pfb['pfctl']} -t {$table} -T delete {$ix[6]}{$j}");
}
}
}
}
+ elseif (is_ipaddrv6($ip)) {
+ $cidr = '';
+ $savemsg2 = ' : Removed entry';
+ exec("{$pfb['pfctl']} -t {$table} -T delete {$ip}");
+ }
+
+ // Collect pfBlockerNGSuppress alias contents
+ $pfbfound = $pfbupdate = FALSE;
+ if (isset($config['aliases']['alias'])) {
+ foreach ($config['aliases']['alias'] as $pfb_key => $alias) {
+ if ($alias['name'] == 'pfBlockerNGSuppress') {
+ $slist = array(explode(' ', $alias['address']), explode('||', $alias['detail']));
+ $pfbfound = TRUE;
+ break;
- // 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']) {
+ // Call function to create suppression alias if not found.
+ if (!$pfbfound) {
+ $pfb_key = @max($pfb_key, 0) ? ++$pfb_key : 0;
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.");
+ // Save new suppress IP to pfBlockerNGSuppress alias
+ if (in_array("{$ix[5]}", $slist[0]) || in_array("{$ip}/32", $slist[0])) {
+ $savemsg = gettext("Host IP address {$ip} already exists in the pfBlockerNG suppress table.");
} else {
- if (!$pfb['found'] && empty($pfb_sup_list)) {
- $next_id = 0;
+ if ($cidr == 24) {
+ $slist[0][] = "{$ix[5]}";
+ } elseif ($cidr == 32) {
+ $slist[0][] = "{$ip}/32";
} else {
- $next_id = count($pfb_sup_list);
+ $slist[0][] = "{$ip}";
}
- $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'] . "||";
+ $slist[1][] = $descr;
+
+ // Sort suppress list and save
+ array_multisort($slist[0], SORT_ASC, SORT_NUMERIC, $slist[1]);
+ $config['aliases']['alias'][$pfb_key]['address'] = implode(' ', $slist[0]);
+ $config['aliases']['alias'][$pfb_key]['detail'] = implode('||', $slist[1]);
+ $savemsg = gettext($savemsg1) . gettext($savemsg2) . gettext(' and added Host to the pfBlockerNG Suppress Table.');
+ $pfbupdate = TRUE;
+ }
+
+ if ($pfbupdate) {
+ // Save Suppress alias changes to pfSense config file
+ write_config("pfBlockerNG: Added {$ip} to IP Suppress List");
+ }
+ }
+ }
+}
+
+// Add domain to the suppression list
+if (isset($_POST['addsuppressdom'])) {
+ $domain = htmlspecialchars($_POST['domain']);
+ $domainparse = str_replace('.', '\.', $domain);
+ $pfb['dsupp'] = &$config['installedpackages']['pfblockerngdnsblsettings']['config'][0]['suppression'];
+
+ // Collect existing suppression list
+ $dnssupp_ex = collectsuppression();
+
+ // Query for domain in Unbound DNSBL file.
+ $dnsbl_query = exec("/usr/bin/grep -Hm1 ' \"{$domain} 60 IN A' {$pfb['dnsbl_file']}.conf");
+
+ // Save new suppress domain to suppress list.
+ if (empty($dnsbl_query)) {
+ $savemsg = gettext("Domain: [ {$domain} ] does not exist in the Unbound Resolver DNSBL");
+ exec("/usr/local/sbin/unbound-control -c {$pfb['dnsbldir']}/unbound.conf flush {$domain}.");
+ } else {
+ // Remove domain from Unbound resolver pfb_dnsbl.conf file
+ exec("{$pfb['sed']} -i '' '/ \"{$domain} 60 IN A/d' {$pfb['dnsbl_file']}.conf");
+
+ $cache_dumpfile = '/var/tmp/unbound_cache';
+ unlink_if_exists("{$cache_dumpfile}");
+ $chroot_cmd = "chroot -u unbound -g unbound / /usr/local/sbin/unbound-control -c {$g['unbound_chroot_path']}/unbound.conf";
+
+ exec("{$chroot_cmd} dump_cache > $cache_dumpfile");
+ exec("{$chroot_cmd} reload");
+
+ if (file_exists($cache_dumpfile) && filesize($cache_dumpfile) > 0) {
+ exec("{$chroot_cmd} load_cache < $cache_dumpfile");
+ }
+
+ exec("/usr/local/sbin/unbound-control -c {$pfb['dnsbldir']}/unbound.conf flush {$domain}");
+
+ if (!in_array($domain, $dnssupp_ex)) {
+ $dnssupp_ex[] = $domain;
+ $dnssupp_new = base64_encode(implode("\n", $dnssupp_ex));
+ $pfb['dsupp'] = "{$dnssupp_new}";
+ write_config("pfBlockerNG: Added {$domain} to DNSBL suppress list");
+ }
+ $savemsg = gettext("Removed Domain: [ {$domain} ] from Unbound Resolver DNSBL. You may need to flush your browsers DNS Cache");
+ }
+}
+
+// Collect pfBlockerNG rule names and tracker ids
+$rule_list = array();
+exec("{$pfb['pfctl']} -vv -sr | {$pfb['grep']} 'pfB_'", $results);
+if (!empty($results)) {
+ foreach ($results as $result) {
+
+ // Find rule tracker ids
+ $id = strstr($result, '(', FALSE);
+ $id = ltrim(strstr($id, ')', TRUE), '(');
+
+ // Find rule descriptions
+ $descr = ltrim(stristr($result, '<pfb_', FALSE), '<');
+ $descr = strstr($descr, ':', TRUE);
+
+ // Create array of rule description and tracker id
+ $rule_list['id'][] = $id;
+ $rule_list[$id]['name'] = $descr;
+ }
+}
+
+// Define common variables and arrays for report tables
+$fields_array = $pfb_local = $pfb_localsub = $dnsbl_int = $local_hosts = array();
+
+$pfblines = exec("/usr/local/sbin/clog {$filter_logfile} | {$pfb['grep']} -c ^");
+$fields_array = conv_log_filter_lite($filter_logfile, $pfblines, $pfblines, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt);
+$continents = array('pfB_Africa', 'pfB_Antartica', 'pfB_Asia', 'pfB_Europe', 'pfB_NAmerica', 'pfB_Oceania', 'pfB_SAmerica', 'pfB_Top');
+
+$supp_ip_txt = "Clicking this Suppression Icon, will immediately remove the block.\n\nSuppressing a /32 CIDR is better than suppressing the full /24";
+$supp_ip_txt .= " CIDR.\nThe Host will be added to the pfBlockerNG suppress alias table.\n\nOnly 32 or 24 CIDR IPs can be suppressed with the '+' icon.";
+$supp_ip_txt .= "\nTo manually add host(s), edit the 'pfBlockerNGSuppress' alias in the alias Tab.\nManual entries will not remove existing blocked hosts";
+
+// Collect gateway IP addresses for inbound/outbound list matching
+$int_gateway = get_interfaces_with_gateway();
+if (isset($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 (isset($config['virtualip']['vip'])) {
+ foreach ($config['virtualip']['vip'] as $list) {
+ if (!empty($list['subnet']) && !empty($list['subnet_bits'])) {
+ if ($list['subnet_bits'] >= 24) {
+ $pfb_local = array_merge(subnetv4_expand("{$list['subnet']}/{$list['subnet_bits']}"), $pfb_local);
+ } else {
+ $pfb_localsub[] = "{$list['subnet']}/{$list['subnet_bits']}";
+ }
+
+ // Collect VIP for Alerts hostlookup
+ $local_hosts[$list['subnet']] = strtolower("{$list['descr']}");
+ }
+ }
+}
+
+// Collect NAT IP addresses for inbound/outbound list matching
+if (isset($config['nat']['rule'])) {
+ foreach ($config['nat']['rule'] as $natent) {
+ $pfb_local[] = $natent['target'];
+
+ // Collect NAT for Alerts hostlookup
+ $local_hosts[$natent['target']] = strtolower("{$natent['descr']}");
+ }
+}
+
+// Collect 1:1 NAT IP addresses for inbound/outbound list matching
+if (isset($config['nat']['onetoone'])) {
+ foreach ($config['nat']['onetoone'] as $onetoone) {
+ $pfb_local[] = $onetoone['source']['address'];
+ }
+}
+
+// Convert any 'Firewall Aliases' to IP address format
+if (isset($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'];
}
+ }
+ }
+ }
+}
- // 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++;
- }
+// Collect all interface addresses for inbound/outbound list matching
+if (isset($config['interfaces'])) {
+ foreach ($config['interfaces'] as $int) {
+ if ($int['ipaddr'] != 'dhcp') {
+ if (!empty($int['ipaddr']) && !empty($int['subnet'])) {
+ if ($int['subnet'] >= 24) {
+ $pfb_local = array_merge(subnetv4_expand("{$int['ipaddr']}/{$int['subnet']}"), $pfb_local);
+ } else {
+ $pfb_localsub[] = "{$int['ipaddr']}/{$int['subnet']}";
}
- $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;
+ // Collect DNSBL Interfaces
+ $dnsbl_int[] = array("{$int['ipaddr']}/{$int['subnet']}", "{$int['descr']}");
+
+ }
+ }
+ }
+}
+
+// Remove any duplicate IPs
+$pfb_local = array_unique($pfb_local);
+$pfb_localsub = array_unique($pfb_localsub);
+
+// Collect DHCP hostnames/IPs
+$local_hosts = array();
+
+// Collect dynamic DHCP hostnames/IPs
+$leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases";
+if (file_exists("{$leasesfile}")) {
+ $leases = file("{$leasesfile}");
+ if (!empty($leases)) {
+ foreach ($leases as $line) {
+ if (strpos($line, '{') !== FALSE) {
+ $end = FALSE;
+ $data = explode(' ', $line);
+ $ip = $data[1];
+ }
+ if (strpos($line, 'client-hostname') !== FALSE) {
+ $data = explode(' ', $line);
+ $hostname = str_replace(array('"', ';'), '', $data[3]);
+ }
+ if (strpos($line, '}') !== FALSE) {
+ $end = TRUE;
}
+ if ($end) {
+ if (!empty($ip) && !empty($hostname)) {
+ $local_hosts[$ip] = $hostname;
+ }
+ $ip = $hostname = '';
+ }
+ }
+ }
+}
- if ($pfb['found'] || $pfb['update']) {
- // Save all Changes to pfsense config file
- write_config("pfBlockerNG: Added {$ip} to IP Suppress List");
+// Collect static DHCP hostnames/IPs
+if (isset($config['dhcpd'])) {
+ foreach ($config['dhcpd'] as $dhcp) {
+ if (isset($dhcp['staticmap'])) {
+ foreach ($dhcp['staticmap'] as $smap) {
+ $local_hosts[$smap['ipaddr']] = strtolower("{$smap['hostname']}");
}
}
}
}
+// Collect Unbound Host overrides
+$hosts = $config['unbound']['hosts'];
+if (isset($hosts)) {
+ foreach ($hosts as $host) {
+ $local_hosts[$host['ip']] = strtolower("{$host['descr']}");
+ }
+}
+
+// Collect configured pfSense interfaces
+$pf_int = get_configured_ip_addresses();
+if (isset($pf_int)) {
+ $local_hosts = array_merge($local_hosts, array_flip(array_filter($pf_int)));
+}
+$pf_int = get_configured_ipv6_addresses();
+if (isset($pf_int)) {
+ $local_hosts = array_merge($local_hosts, array_flip(array_filter($pf_int)));
+}
+
+// FUNCTION DEFINITIONS
+
+
+// Collect existing suppression list
+function collectsuppression() {
+ global $pfb;
+ $dnssupp_ex = array();
+
+ $custom_list = pfbng_text_area_decode($pfb['dnsblconfig']['suppression']);
+ if (!empty($custom_list)) {
+ $dnssupp_ex = array_filter( explode("\n", pfbng_text_area_decode($pfb['dnsblconfig']['suppression'])));
+ }
+ return ($dnssupp_ex);
+}
+
-// Host Resolve Function lookup
-function getpfbhostname($type = 'src', $hostip, $countme = 0) {
- $hostnames['src'] = '';
- $hostnames['dst'] = '';
- $hostnames[$type] = '<div id="gethostname_' . $countme . '" name="' . $hostip . '"></div>';
+// Host resolve function lookup
+function getpfbhostname($type = 'src', $hostip, $countme = 0, $host) {
+ global $local_hosts;
+
+ $hostnames['src'] = $hostnames['dst'] = '';
+ $hostnames[$type] = "<div id='gethostname_{$countme}' name='{$hostip}'></div>";
+
+ // Report DHCP hostnames if found.
+ if (isset($local_hosts[$host])) {
+ if ($type == 'src') {
+ $hostnames['dst'] = $local_hosts[$host];
+ } else {
+ $hostnames['src'] = $local_hosts[$host];
+ }
+ }
return $hostnames;
}
-// For subnet addresses - Determine if Alert Host 'Dest' is within a Local IP Range.
+// Function to Filter Alerts report on user defined input
+function pfb_match_filter_field($flent, $fields) {
+ if (isset($fields)) {
+ foreach ($fields as $key => $field) {
+ if (empty($field)) {
+ continue;
+ }
+
+ if (strpos($field, '!') !== FALSE) {
+ $field = substr($field, 1);
+ $field_regex = str_replace('/', '\/', str_replace('\/', '/', $field));
+ if (@preg_match("/{$field_regex}/i", $flent[$key])) {
+ return FALSE;
+ }
+ }
+ else {
+ $field_regex = str_replace('/', '\/', str_replace('\/', '/', $field));
+ if (!@preg_match("/{$field_regex}/i", $flent[$key])) {
+ return FALSE;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+
+// For subnet addresses - Determine if alert host 'dest' is within a local IP range.
function ip_in_pfb_localsub($subnet) {
global $pfb_localsub;
if (!empty($pfb_localsub)) {
foreach ($pfb_localsub as $line) {
if (ip_in_subnet($subnet, $line)) {
- return true;
+ return TRUE;
}
}
}
- return false;
+ return FALSE;
}
-// Parse Filter log for pfBlockerNG Alerts
+// Parse filter log for pfBlockerNG alerts
function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt) {
global $pfb, $rule_list, $filterfieldsarray;
$fields_array = array();
- $logarr = "";
- $denycnt = 0;
- $permitcnt = 0;
- $matchcnt = 0;
+ $denycnt = $permitcnt = $matchcnt = 0;
+ $logarr = '';
if (file_exists($logfile)) {
- exec("/usr/local/sbin/clog " . escapeshellarg($logfile) . " | grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/grep 'filterlog:' | /usr/bin/tail -r -n {$tail}", $logarr);
+ // Collect filter.log entries
+ exec("/usr/local/sbin/clog {$logfile} | {$pfb['grep']} -v '\"CLOG\"\|\"\033\"' | {$pfb['grep']} 'filterlog:' | /usr/bin/tail -r -n {$tail}", $logarr);
+ } else {
+ return;
}
- else return;
if (!empty($logarr) && !empty($rule_list['id'])) {
foreach ($logarr as $logent) {
- $pfbalert = array();
- $log_split = "";
- if (!preg_match("/(.*)\s(.*)\sfilterlog:\s(.*)$/", $logent, $log_split)) {
- continue;
+ $pfbalert = array();
+ $flog = explode(' ', $logent);
+ // Remove 'extra space' from single date entry (days 1-9)
+ if (empty($flog[1])) {
+ array_splice($flog, 1, 1);
}
+ $rule_data = explode(',', $flog[5]);
- list($all, $pfbalert[99], $host, $rule) = $log_split;
- $rule_data = explode(",", $rule);
- $pfbalert[0] = $rule_data[0]; // Rulenum
-
- // Skip Alert if Rule is not a pfBNG Alert
- if (!in_array($pfbalert[0], $rule_list['id'])) {
+ // Skip alert if rule is not a pfBNG alert
+ if (!in_array($rule_data[3], $rule_list['id'])) {
continue;
}
- $pfbalert[1] = $rule_data[4]; // Realint
- $pfbalert[3] = $rule_data[6]; // Act
- $pfbalert[4] = $rule_data[8]; // Version
+ $pfbalert[0] = $rule_data[3]; // Rulenum
+ $pfbalert[1] = $rule_data[4]; // Realint
+ $pfbalert[3] = $rule_data[6]; // Act
+ $pfbalert[4] = $rule_data[8]; // Version
- if ($pfbalert[4] == "4") {
+ if ($pfbalert[4] == 4) {
$pfbalert[5] = $rule_data[15]; // Protocol ID
$pfbalert[6] = $rule_data[16]; // Protocol
$pfbalert[7] = $rule_data[18]; // SRC IP
@@ -442,104 +588,106 @@ function conv_log_filter_lite($logfile, $nentries, $tail, $pfbdenycnt, $pfbpermi
$pfbalert[11] = $rule_data[20]; // TCP Flags
}
- if ($pfbalert[5] == "6" || $pfbalert[5] == "17") {
+ if ($pfbalert[5] == 6 || $pfbalert[5] == 17) {
// skip
} else {
- $pfbalert[9] = "";
- $pfbalert[10] = "";
- $pfbalert[11] = "";
+ $pfbalert[9] = $pfbalert[10] = $pfbalert[11] = '';
}
- // Skip Repeated Alerts
- if (($pfbalert[1] . $pfbalert[3] . $pfbalert[7] . $pfbalert[8] . $pfbalert[10]) == $previous_alert) {
+ $pfbalert[99] = "{$flog[0]} {$flog[1]} {$flog[2]}"; // Date/Timestamp
+
+ // Skip repeated alerts
+ if ("{$pfbalert[1]}{$pfbalert[3]}{$pfbalert[7]}{$pfbalert[8]}{$pfbalert[10]}" == $previous_alert) {
continue;
}
$pfbalert[2] = convert_real_interface_to_friendly_descr($rule_data[4]); // Friendly Interface Name
- $pfbalert[6] = str_replace("TCP", "TCP-", strtoupper($pfbalert[6]), $pfbalert[6]) . $pfbalert[11]; // Protocol Flags
+ $pfbalert[6] = str_replace('TCP', 'TCP-', strtoupper($pfbalert[6]), $pfbalert[6]) . $pfbalert[11]; // Protocol Flags
- // If Alerts Filtering is selected, process Filters as required.
+ // If alerts filtering is selected, process filters as required.
if ($pfb['filterlogentries'] && !pfb_match_filter_field($pfbalert, $filterfieldsarray)) {
continue;
}
- if ($pfbalert[3] == "block") {
+ if ($pfbalert[3] == 'block') {
if ($denycnt < $pfbdenycnt) {
$fields_array['Deny'][] = $pfbalert;
$denycnt++;
}
}
- elseif ($pfbalert[3] == "pass") {
+ elseif ($pfbalert[3] == 'pass') {
if ($permitcnt < $pfbpermitcnt) {
$fields_array['Permit'][] = $pfbalert;
$permitcnt++;
}
}
- elseif ($pfbalert[3] == "unkn(%u)" || $pfbalert[3] == "unkn(11)") {
+ elseif ($pfbalert[3] == 'unkn(%u)') {
if ($matchcnt < $pfbmatchcnt) {
$fields_array['Match'][] = $pfbalert;
$matchcnt++;
}
}
- // Exit function if Sufficinet Matches found.
+ // Exit function if sufficinet matches found.
if ($denycnt >= $pfbdenycnt && $permitcnt >= $pfbpermitcnt && $matchcnt >= $pfbmatchcnt) {
- unset ($pfbalert, $logarr);
+ unset($pfbalert, $logarr);
return $fields_array;
}
- // Collect Details for Repeated Alert Comparison
- $previous_alert = $pfbalert[1] . $pfbalert[3] . $pfbalert[7] . $pfbalert[8] . $pfbalert[10];
+ // Collect details for repeated alert comparison
+ $previous_alert = "{$pfbalert[1]}{$pfbalert[3]}{$pfbalert[7]}{$pfbalert[8]}{$pfbalert[10]}";
}
- unset ($pfbalert, $logarr);
+ unset($pfbalert, $logarr);
return $fields_array;
}
}
-$pgtitle = gettext("pfBlockerNG: Alerts");
-include_once("head.inc");
+
+$pgtitle = gettext('pfBlockerNG: Alerts');
+include_once('head.inc');
?>
<body link="#000000" vlink="#0000CC" alink="#000000">
-<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
+<form action="/pfblockerng/pfblockerng_alerts.php" 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=""/>
+<input type="hidden" name="domain" id="domain" value=""/>
<?php
-include_once("fbegin.inc");
+include_once('fbegin.inc');
-/* refresh every 60 secs */
+// refresh every 60 secs
if ($alertrefresh == 'on') {
- echo "<meta http-equiv=\"refresh\" content=\"60;url={$_SERVER['PHP_SELF']}\" />\n";
+ if ($pfb['filterlogentries']) {
+ // Refresh page with 'Filter options' if defined.
+ $refreshentries = urlencode(serialize($filterfieldsarray));
+ echo "<meta http-equiv=\"refresh\" content=\"60;url=/pfblockerng/pfblockerng_alerts.php?refresh={$refreshentries}\" />\n";
+ } else {
+ echo "<meta http-equiv=\"refresh\" content=\"60;url=/pfblockerng/pfblockerng_alerts.php\" />\n";
+ }
}
if ($savemsg) {
print_info_box($savemsg);
}
-$skipcount = 0; $counter = 0;
+$skipcount = $counter = $resolvecounter = 0;
?>
<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&amp;id=0");
+ $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml");
$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("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml");
$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("P.S."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&id=0");
+ $tab_array[] = array(gettext("DNSBL"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml");
+ $tab_array[] = array(gettext("Country"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml");
$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");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml");
display_top_tabs($tab_array, true);
?>
</td>
@@ -558,24 +706,29 @@ $skipcount = 0; $counter = 0;
<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.&nbsp;&nbsp;') , '<strong>', '</strong>'); ?>
+ <?php printf(gettext('%sDeny%s.&emsp;') , '<strong>', '</strong>'); ?>
+ <?php if ($pfb['dnsbl'] == "on"): ?>
+ <input name="pfbdnscnt" type="text" class="formfld unknown" id="pdbdnscnt" size="1"
+ title="Enter the number of 'DNSBL' Alerts to Show" value="<?=htmlspecialchars($pfbdnscnt);?>"/>
+ <?php printf(gettext('%sDNSBL%s.&emsp;') , '<strong>', '</strong>'); ?>
+ <?php endif; ?>
<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.&nbsp;&nbsp;'), '<strong>', '</strong>'); ?>
+ <?php printf(gettext('%sPermit%s.&emsp;'), '<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('&nbsp;&nbsp;&nbsp;&nbsp;Click to Auto-Refresh');?>&nbsp;&nbsp;<input name="alertrefresh" type="checkbox" value="on"
+ <?php echo gettext('&emsp;Auto-Refresh');?>&emsp;<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"; ?>/>&nbsp;
- <?php echo gettext('&nbsp;Click to Auto-Resolve');?>&nbsp;&nbsp;<input name="hostlookup" type="checkbox" value="on"
+ <?php echo gettext('&nbsp;Auto-Resolve');?>&emsp;<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"; ?>/>&nbsp;&nbsp;&nbsp;
+ <?php if ($config['installedpackages']['pfblockerngglobal']['hostlookup']=="on") echo "checked"; ?>/>&emsp;
<input name="save" type="submit" class="formbtns" value="Save" title="<?=gettext('Save settings');?>"/><br />
- <?php printf(gettext('Enter number of log entries to view.')); ?>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <?php printf(gettext('Enter number of log entries to view.')); ?>&emsp;
<?php printf(gettext("Currently Suppressing &nbsp; %s$pfbsupp_cnt%s &nbsp; Hosts."), '<strong>', '</strong>');?>
</td>
</tr>
@@ -587,7 +740,7 @@ $skipcount = 0; $counter = 0;
<td width="90%" class="vtable">
<input name="show_filter" id="show_filter" type="button" class="formbtns" value="<?=gettext("Show Filter");?>"
onclick="enable_showFilter();" />
- &nbsp;&nbsp;<?=gettext("Click to display advanced filtering options dialog");?>
+ &emsp;<?=gettext("Click to display advanced filtering options dialog");?>
</td>
</tr>
<tr id="filter_options_row" style="display:<?php if (!$pfb['filterlogentries']) {echo "none;";} else {echo "table-row;";} ?>">
@@ -622,7 +775,7 @@ $skipcount = 0; $counter = 0;
type="text" size="15" value="<?= $filterfieldsarray[0] ?>" /></div>
</td>
<td valign="top">
- <div align="center"><?=gettext("Destination IP Address");?></div>
+ <div align="center"><?=gettext("Destination IP Address/Domain Name");?></div>
<div align="center"><input id="filterlogentries_dstip" name="filterlogentries_dstip" class="formfld search"
type="text" size="28" value="<?= $filterfieldsarray[8] ?>" /></div>
</td>
@@ -640,10 +793,30 @@ $skipcount = 0; $counter = 0;
&nbsp;
</td>
</tr>
+
+ <?php if ($pfb['dnsbl'] == 'on'): ?>
+ <tr>
+ <td valign="top">
+ <div align="center"><?=gettext("DNSBL URL");?></div>
+ <div align="center"><input id="filterlogentries_dnsbl" name="filterlogentries_dnsbl"
+ class="formfld search" type="text" size="15" value="<?= $filterfieldsarray[90] ?>" /></div>
+ </td>
+ <td valign="top" colspan="3">
+ &nbsp;
+ </td>
+ </tr>
+ <?php else: ?>
+ <tr>
+ <td valign="top" colspan="3">
+ &nbsp;
+ </td>
+ </tr>
+ <?php endif; ?>
+
<tr>
<td colspan="3" style="vertical-align:bottom">
<br /><?printf(gettext('Regex Style Matching Only! %1$s Regular Expression Help link%2$s.'), '
- <a target="_blank" href="http://www.php.net/manual/en/book.pcre.php">', '</a>');?>&nbsp;&nbsp;
+ <a target="_blank" href="http://www.php.net/manual/en/book.pcre.php">', '</a>');?>&emsp;
<?=gettext("Precede with exclamation (!) as first character to exclude match.) ");?>
<br /><?printf(gettext("Example: ( ^80$ - Match Port 80, ^80$|^8080$ - Match both port 80 & 8080 ) "));?><br />
</td>
@@ -652,9 +825,9 @@ $skipcount = 0; $counter = 0;
<td colspan="3" style="vertical-align:bottom">
<div align="left"><input id="filterlogentries_submit" name="filterlogentries_submit" type="submit"
class="formbtns" value="<?=gettext("Apply Filter");?>" title="<?=gettext("Apply filter"); ?>" />
- &nbsp;&nbsp;&nbsp;<input id="filterlogentries_clear" name="filterlogentries_clear" type="submit"
+ &emsp;<input id="filterlogentries_clear" name="filterlogentries_clear" type="submit"
class="formbtns" value="<?=gettext("Clear");?>" title="<?=gettext("Remove filter");?>" />
- &nbsp;&nbsp;&nbsp;<input id="filterlogentries_hide" name="filterlogentries_hide" type="button"
+ &emsp;<input id="filterlogentries_hide" name="filterlogentries_hide" type="button"
class="formbtns" value="<?=gettext("Hide");?>" onclick="enable_hideFilter();"
title="<?=gettext("Hide filter options");?>" /></div>
</td>
@@ -663,166 +836,236 @@ $skipcount = 0; $counter = 0;
</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 ):
+<!--Create three output windows 'Deny', 'DNSBL', 'Permit' and 'Match'-->
+<?php foreach (array ( 'Deny' => "{$pfb['denydir']}/* {$pfb['nativedir']}/*",
+ 'DNSBL' => "{$pfb['dnsdir']}",
+ 'Permit' => "{$pfb['permitdir']}/* {$pfb['nativedir']}/*",
+ 'Match' => "{$pfb['matchdir']}/* {$pfb['nativedir']}/*" ) as $type => $pfbfolder ):
+
switch($type) {
- case "Deny":
- $rtype = "block";
+ case 'Deny':
+ $rtype = 'block';
$pfbentries = "{$pfbdenycnt}";
break;
- case "Permit":
- $rtype = "pass";
+ case 'Permit':
+ $rtype = 'pass';
$pfbentries = "{$pfbpermitcnt}";
break;
- case "Match":
- $rtype = "unkn(%u)";
+ case 'Match':
+ $rtype = 'unkn(%u)';
$pfbentries = "{$pfbmatchcnt}";
break;
+ case 'DNSBL':
+ $pfbentries = "{$pfbdnscnt}";
}
- // Skip Table output if $pfbentries is zero.
- if ($pfbentries == 0 && $skipcount != 2) {
+ // Skip table output if $pfbentries is zero.
+ if ($pfbentries == 0 && $skipcount != 3) {
$skipcount++;
continue;
}
+
+ // Print alternating line shading
+ $alertRowEvenClass = "style='background-color: #D8D8D8;'";
+ $alertRowOddClass = "style='background-color: #E8E8E8;'";
?>
<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("&nbsp;{$type}&nbsp;&nbsp; - &nbsp; Last %s Alert Entries."),"{$pfbentries}"); ?>
- <?php if ($type == "Deny"): ?>
- &nbsp;&nbsp;&nbsp;&nbsp;<?php echo gettext("Firewall Rule changes can unsync these Alerts."); ?>
- <?php endif; ?>
+ <!--Print table info-->
+ <td colspan="2" class="listtopic">
+ <?php printf(gettext("&nbsp;{$type}&emsp; - &nbsp; Last %s Alert Entries."),"{$pfbentries}"); ?>
</td>
</tr>
<td width="100%" colspan="2">
<table id="pfbAlertsTable" style="table-layout: fixed;" width="100%" class="sortable" border="0" cellpadding="0" cellspacing="0">
+
+<?php
+// Process dns array for: DNSBL and generate output
+if ($pfb['dnsbl'] == 'on' && $type == 'DNSBL') {
+?>
+
<colgroup>
- <col width="7%" align="center" axis="date">
- <col width="6%" align="center" axis="string">
- <col width="15%" align="center" axis="string">
- <col width="6%" align="center" axis="string">
- <col width="21%" align="center" axis="string">
- <col width="21%" align="center" axis="string">
- <col width="3%" align="center" axis="string">
- <col width="13%" align="center" axis="string">
+ <col width="8%" align="center" axis="date">
+ <col width="7%" align="center" axis="string">
+ <col width="12%" align="center" axis="string">
+ <col width="59%" align="center" axis="string">
+ <col width="14%" 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("Domain/Referer|URI|Agent"); ?></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;
- $resolvecounter = 0;
- $fields_array = array();
-
- $pfblines = exec("/usr/local/sbin/clog {$filter_logfile} | /usr/bin/grep -c ^");
- $fields_array = conv_log_filter_lite($filter_logfile, $pfblines, $pfblines, $pfbdenycnt, $pfbpermitcnt, $pfbmatchcnt);
- $continents = array('pfB_Africa','pfB_Antartica','pfB_Asia','pfB_Europe','pfB_NAmerica','pfB_Oceania','pfB_SAmerica','pfB_Top');
-
- $supp_ip_txt = "Clicking this Suppression Icon, will immediately remove the Block.\n\nSuppressing a /32 CIDR is better than Suppressing the full /24";
- $supp_ip_txt .= " CIDR.\nThe Host will be added to the pfBlockerNG Suppress Alias Table.\n\nOnly 32 or 24 CIDR IPs can be Suppressed with the '+' Icon.";
- $supp_ip_txt .= "\nTo manually add Host(s), edit the 'pfBlockerNGSuppress' Alias in the Alias Tab.\nManual entries will not remove existing Blocked Hosts";
-
- // Array of all Local IPs for Alert Analysis
- $pfb_local = array();
- $pfb_localsub = 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;
- }
- }
+<?php
+ $dns_array = $final = array();
+ if (file_exists("{$pfb['dnslog']}")) {
+ if (($handle = fopen("{$pfb['dnslog']}", 'r')) !== FALSE) {
+ while (($line = fgetcsv($handle)) !== FALSE) {
+
+ // Define missing data for HTTPS alerts
+ if ($line[0] == 'DNSBL Reject HTTPS') {
+ $line[3] = '<small>Unknown</small>';
+ $line[4] = ' Not available for HTTPS alerts';
+ }
- // Collect Virtual IP Aliases for Inbound/Outbound List Matching
- if (is_array($config['virtualip']['vip'])) {
- foreach ($config['virtualip']['vip'] as $list) {
- if ($list['subnet'] != "" && $list['subnet_bits'] != "") {
- if ($list['subnet_bits'] >= 24) {
- $pfb_local = array_merge(subnetv4_expand("{$list['subnet']}/{$list['subnet_bits']}"), $pfb_local);
- } else {
- $pfb_localsub[] = "{$list['subnet']}/{$list['subnet_bits']}";
+ // Remove duplicate domain/srcips
+ if (("{$line[2]}{$line[3]}") != $pdomain) {
+ $final[] = $line;
}
+ $pdomain = "{$line[2]}{$line[3]}";
}
}
- }
+ fclose($handle);
- // 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'];
+ if (!empty($final)) {
+ $dns_array = array_slice(array_reverse($final), 0, $pfbentries);
}
}
- // 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'];
- }
- }
+ if (!empty($dns_array)) {
- // 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'];
+ $supp_dom_txt = "Clicking this Suppression icon, will immediately remove the blocked domain from Unbound Resolver.\n\n";
+ $supp_dom_txt .= "To manually add Domain(s), edit the 'Domain Suppression' list in the DNSBL tab.\n";
+ $supp_dom_txt .= "Manual entries will not immediatelty remove existing blocked hosts.";
+
+ foreach ($dns_array as $aline) {
+
+ // Determine interface name based on Source IP address
+ $pfbalertdnsbl[1] = 'LAN'; // Define LAN Interface as 'default'
+ if (!empty($dnsbl_int)) {
+ foreach ($dnsbl_int as $subnet) {
+ if (strpos($aline[3], 'Unknown') !== FALSE) {
+ $pfbalertdnsbl[1] = 'Unknown';
+ break;
+ } elseif (ip_in_subnet($aline[3], $subnet[0])) {
+ $pfbalertdnsbl[1] = "{$subnet[1]}";
+ break;
}
}
}
- }
- }
- // Collect all Interface Addresses for Inbound/Outbound List Matching
- if (is_array($config['interfaces'])) {
- foreach ($config['interfaces'] as $int) {
- if ($int['ipaddr'] != "dhcp") {
- if ($int['ipaddr'] != "" && $int['subnet'] != "") {
- if ($int['subnet'] >= 24) {
- $pfb_local = array_merge(subnetv4_expand("{$int['ipaddr']}/{$int['subnet']}"), $pfb_local);
- } else {
- $pfb_localsub[] = "{$int['ipaddr']}/{$int['subnet']}";
- }
- }
+ $pfbalertdnsbl[99] = $aline[1]; // Timestamp
+
+ // SRC IP Address and Hostname
+ if (isset($local_hosts[$aline[3]])) {
+ $pfbalertdnsbl[7] = "{$aline[3]}<br /><small>{$local_hosts[$aline[3]]}</small>";
+ } else {
+ $pfbalertdnsbl[7] = $aline[3];
}
+
+ $pfbalertdnsbl[8] = $aline[2]; // Blocked Domain
+ $pfbalertdnsbl[90] = $aline[4]; // DNSBL URL
+
+ // Add 'https' icon to Domains as required.
+ $pfb_https = '';
+ if (strpos($aline[4], 'https://') !== FALSE || strpos($aline[4], 'Not available for HTTPS alerts') !== FALSE) {
+ $pfb_https = "<img src=\"/themes/{$g['theme']}/images/icons/icon_frmfld_pwd.png\" alt='' width='11' height='11' border='0'
+ title='HTTPS alerts are not fully logged due to Browser security' />";
+ }
+
+ // If alerts filtering is selected, process filters as required.
+ if ($pfb['filterlogentries'] && !pfb_match_filter_field($pfbalertdnsbl, $filterfieldsarray)) {
+ continue;
+ }
+
+ // Collect the list that contains the blocked domain
+ $domain = str_replace('.', '\.', $aline[2]);
+ $sed_cmd = "{$pfb['sed']} -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /'";
+ $pfb_query = exec("{$pfb['grep']} -Hm1 ' \"{$domain} 60 IN A' {$pfb['dnsdir']}/* | {$sed_cmd}");
+ $pfb_alias = exec("{$pfb['grep']} -Hm1 ' \"{$domain} 60 IN A' {$pfb['dnsalias']}/* | {$sed_cmd}");
+
+ if (empty($pfb_query)) {
+ $pfb_query = 'no match';
+ }
+
+ // Truncate long list names
+ $pfb_matchtitle = "The DNSBL Feed and Alias that blocked the indicated Domain.";
+ if (strlen($pfb_query) >= 17 || strlen($pfb_alias) >= 25) {
+ $pfb_matchtitle = "Feed: {$pfb_query} | Alias: {$pfb_alias}";
+ $pfb_query = substr($pfb_query, 0, 16) . '...';
+ $pfb_alias = substr($pfb_alias, 0, 24) . '...';
+ }
+
+ // Print alternating line shading
+ $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass;
+
+ $alert_dom = "<a href='/pfblockerng/pfblockerng_threats.php?domain={$aline[2]}' title=\" " . gettext("Resolve Domain via DNS lookup");
+ $alert_dom .= "\"> <img src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" width='11' height='11' border='0' ";
+ $alert_dom .= "alt=\"Icon Reverse Resolve with DNS\" style=\"cursor: pointer;\" /></a>";
+
+ // Collect existing suppression list
+ $dnssupp_ex = collectsuppression();
+ if (!in_array($pfbalertdnsbl[8], $dnssupp_ex)) {
+ $supp_dom = "<input type='image' name='addsuppressdom[]' onclick=\"domainlistid('{$domain}');\" ";
+ $supp_dom .= "src=\"../themes/{$g['theme']}/images/icons/icon_pass_add.gif\" alt='' title=\"";
+ $supp_dom .= gettext($supp_dom_txt) . "\" border='0' width='11' height='11' />&emsp;";
+ }
+ else {
+ $supp_dom = "<img src=\"../themes/{$g['theme']}/images/icons/icon_plus_d.gif\" alt='' border='0' width='11' height='11' ";
+ $supp_dom .= "title='" . gettext("This domain is already in the DNSBL Suppress List") . "' />&emsp;";
+ }
+
+ // Truncate long URLs
+ $url_title = '';
+ if (strlen($pfbalertdnsbl[90]) >= 72) {
+ $url_title = "{$pfbalertdnsbl[90]}";
+ $pfbalertdnsbl[90] = substr(str_replace(array('?', '-'), '', $pfbalertdnsbl[90]), 0, 69) . '...';
+ }
+
+ echo "<tr {$alertRowClass}>
+ <td class='listMRr' align='center'>{$pfbalertdnsbl[99]}</td>
+ <td class='listMRr' align='center'><small>{$pfbalertdnsbl[1]}</small></td>
+ <td class='listMRr' align='center'>{$pfbalertdnsbl[7]}</td>
+ <td class='listMRr' align='left' title='{$url_title}' sorttable_customkey='{$pfbalertdnsbl[8]}'>
+ {$alert_dom} {$supp_dom}{$pfbalertdnsbl[8]} {$pfb_https}<br />&emsp;&emsp;&emsp;<small>{$pfbalertdnsbl[90]}</small></td>
+ <td class='listbg' align='center' title='{$pfb_matchtitle}' style='white-space: word;'>
+ {$pfb_query}<br /><small>{$pfb_alias}</small></td></tr>";
+ $counter++;
}
}
+}
- // Remove any Duplicate IPs
- $pfb_local = array_unique($pfb_local);
- $pfb_localsub = array_unique($pfb_localsub);
+if ($type != 'DNSBL') {
+?>
+
+ <colgroup>
+ <col width="7%" align="center" axis="date">
+ <col width="6%" align="center" axis="string">
+ <col width="15%" align="center" axis="string">
+ <col width="6%" align="center" axis="string">
+ <col width="21%" align="center" axis="string">
+ <col width="21%" 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
}
-// Process Fields_array and generate Output
-if (!empty($fields_array[$type]) && !empty($rule_list)) {
- $key = 0;
+// Process fields array for: Deny/Permit/Match and generate output
+if (!empty($fields_array[$type]) && !empty($rule_list) && $type != 'DNSBL') {
foreach ($fields_array[$type] as $fields) {
- $rulenum = "";
- $alert_ip = "";
- $supp_ip = "";
- $pfb_query = "";
+ $rulenum = $alert_ip = $supp_ip = $pfb_query = '';
/* Fields_array Reference [0] = Rulenum [6] = Protocol
[1] = Real Interface [7] = SRC IP
@@ -834,205 +1077,176 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) {
$rulenum = $fields[0];
if ($counter < $pfbentries) {
- // Cleanup Port Output
- if ($fields[6] == "ICMP" || $fields[6] == "ICMPV6") {
- $srcport = "";
- $dstport = "";
+ // Cleanup port output
+ if ($fields[6] == 'ICMP' || $fields[6] == 'ICMPV6') {
+ $srcport = '';
} else {
- $srcport = ":" . $fields[9];
- $dstport = ":" . $fields[10];
+ $srcport = ":{$fields[9]}";
+ $dstport = ":{$fields[10]}";
}
- // Don't add Suppress Icon to Country Block Lines
+ // Don't add suppress icon to Country block lines
if (in_array(substr($rule_list[$rulenum]['name'], 0, -3), $continents)) {
- $pfb_query = "Country";
+ $pfb_query = 'Country';
}
- // Add DNS Resolve and Suppression Icons to External IPs only. GeoIP Code to External IPs only.
+ // Add DNS resolve and suppression icons to external IPs only. GeoIP code to external IPs only.
if (in_array($fields[8], $pfb_local) || ip_in_pfb_localsub($fields[8])) {
- // Destination is Gateway/NAT/VIP
- $rule = $rule_list[$rulenum]['name'] . "<br />(" . $rulenum .")";
+ // Destination is gateway/NAT/VIP
+ $rule = "{$rule_list[$rulenum]['name']}<br /><small>({$rulenum})</small>";
$host = $fields[7];
- $alert_ip = "<a href='/pfblockerng/pfblockerng_diag_dns.php?host={$host}' title=\" " . gettext("Resolve host via Rev. DNS lookup");
+ $alert_ip = "<a href='/pfblockerng/pfblockerng_threats.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") {
+ 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_pass_add.gif\" title=\"";
+ $supp_ip .= "src=\"../themes/{$g['theme']}/images/icons/icon_pass_add.gif\" alt='' 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[7], $counter);
+ if ($rtype == 'block' && $hostlookup == 'on') {
+ $hostname = getpfbhostname('src', $fields[7], $counter, $fields[8]);
} else {
- $hostname = "";
+ $hostname = '';
}
- $src_icons = $alert_ip . "&nbsp;" . $supp_ip . "&nbsp;";
- $dst_icons = "";
+ $src_icons_1 = "{$alert_ip}&nbsp;{$supp_ip}&nbsp;";
+ $src_icons_2 = "{$alert_ip}&nbsp;";
+ $dst_icons_1 = '';
+ $dst_icons_2 = '';
+
} else {
// Outbound
- $rule = $rule_list[$rulenum]['name'] . "<br />(" . $rulenum .")";
+ $rule = "{$rule_list[$rulenum]['name']}<br /><small>({$rulenum})</small>";
$host = $fields[8];
- $alert_ip = "<a href='/pfblockerng/pfblockerng_diag_dns.php?host={$host}' title=\"" . gettext("Resolve host via Rev. DNS lookup");
+ $alert_ip = "<a href='/pfblockerng/pfblockerng_threats.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") {
+ 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_pass_add.gif\" title=\"";
+ $supp_ip .= "src=\"../themes/{$g['theme']}/images/icons/icon_pass_add.gif\" alt='' 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[8], $counter);
+ if ($rtype == 'block' && $hostlookup == 'on') {
+ $hostname = getpfbhostname('dst', $fields[8], $counter, $fields[7]);
} else {
- $hostname = "";
+ $hostname = '';
}
- $src_icons = "";
- $dst_icons = $alert_ip . "&nbsp;" . $supp_ip . "&nbsp;";
+ $src_icons_1 = '';
+ $src_icons_2 = '';
+ $dst_icons_1 = "{$alert_ip}&nbsp;{$supp_ip}&nbsp;";
+ $dst_icons_2 = "{$alert_ip}&nbsp;";
}
- // Determine Country Code of Host
+ // Determine Country code of host
if (is_ipaddrv4($host)) {
- $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2);
+ $country = substr(exec("{$pathgeoip} -f {$pathgeoipdat} {$host}"), 23, 2);
} else {
- $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2);
+ $country = substr(exec("{$pathgeoip6} -f {$pathgeoipdat6} {$host}"), 26, 2);
}
- // IP Query Grep Exclusion
- $pfb_ex1 = "grep -v 'pfB\_\|\_v6\.txt'";
- $pfb_ex2 = "grep -v 'pfB\_\|/32\|/24\|\_v6\.txt' | grep -m1 '/'";
-
- // Find List which contains Blocked IP Host
- if (is_ipaddrv4($host) && $pfb_query != "Country") {
- // Search for exact IP Match
- $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host);
- $pfb_query = exec("/usr/bin/grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' | {$pfb_ex1}");
- // Search for IP in /24 CIDR
- if (empty($pfb_query)) {
- $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.0/24\'', $host);
- $pfb_query = exec("/usr/bin/grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}");
- }
- // Search for First Two IP Octets in CIDR Matches Only. Skip any pfB (Country Lists) or /32,/24 Addresses.
- if (empty($pfb_query)) {
- $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host);
- $pfb_query = exec("/usr/bin/grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
- }
- // Search for First Two IP Octets in CIDR Matches Only (Subtract 1 from second Octet on each loop).
- // Skip (Country Lists) or /32,/24 Addresses.
- 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("/usr/bin/grep -rH {$host1}{$host3} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
- // Break out of loop if found.
- if (!empty($pfb_query)) {
- $cnt = 6;
- }
- }
- }
- // 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("/usr/bin/grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
- }
- // Search for First Two Octets
- if (empty($pfb_query)) {
- $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host);
- $pfb_query = exec("/usr/bin/grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
+ // Find the header which alerted this host
+ if ($pfb_query != 'Country') {
+ if (strpos($rule, 'pfB_DNSBLIP') !== FALSE) {
+ $pfb_match[1] = 'DNSBLIP'; // Default pfB_DNSBLIP
+ $pfb_match[2] = '';
}
- // 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("/usr/bin/grep -Hm1 {$host1} {$pfb['etdir']}/* | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' -e 's/ET_/ET IPrep /' ");
- if (empty($pfb_query)) {
- $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1.$2.$3.0/24\'', $host);
- $pfb_query = exec("/usr/bin/grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}");
+ else {
+ // Report specific ET IQRisk details
+ if ($pfb['et_header'] && strpos($pfb_query, "{$et_header}") !== FALSE) {
+ $pfbfolder = "{$pfb['etdir']}/*";
}
- }
- }
- elseif (is_ipaddrv6($host) && $pfb_query != "Country") {
- $pfb_query = exec("/usr/bin/grep -Hm1 {$host} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | grep -v 'pfB\_'");
- }
- // Default to "No Match" if not found.
- if (empty($pfb_query)) {
- $pfb_query = "No Match";
- }
+ $pfb_query = find_reported_header($host, $pfbfolder, FALSE);
- // 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] = "";
+ // Split list column into two lines.
+ $pfb_match[1] = "{$pfb_query[1]}";
+ $pfb_match[2] = "{$pfb_query[0]}";
+
+ // Remove Suppression Icon for 'no match' and all subnets except for '/32 & /24'.
+ if ($pfb_query[2]) {
+ $src_icons = $src_icons_1;
+ $dst_icons = $dst_icons_1;
+ } else {
+ $src_icons = $src_icons_2;
+ $dst_icons = $dst_icons_2;
+ }
}
}
+ else {
+ $pfb_match[1] = 'Country';
+ $pfb_match[2] = '';
+ $src_icons = $src_icons_2; // Remove 'suppress icon'
+ $dst_icons = $dst_icons_2;
+ }
- // Add []'s to IPv6 Addresses and add a zero-width space as soft-break opportunity after each colon if we have an IPv6 address (from Snort)
- if ($fields[4] == "6") {
- $fields[97] = "[" . str_replace(":", ":&#8203;", $fields[7]) . "]";
- $fields[98] = "[" . str_replace(":", ":&#8203;", $fields[8]) . "]";
+ // Add []'s to IPv6 addresses and add a zero-width space as soft-break opportunity after each colon if we have an IPv6 address (from Snort)
+ if ($fields[4] == '6') {
+ $fields[97] = '[' . str_replace(':', ':&#8203;', $fields[7]) . ']';
+ $fields[98] = '[' . str_replace(':', ':&#8203;', $fields[8]) . ']';
}
else {
$fields[97] = $fields[7];
$fields[98] = $fields[8];
}
- // Truncate Long List Names
- $pfb_matchtitle = "Country Block Rules cannot be suppressed.\n\nTo allow a particular Country IP, either remove the particular Country or add the Host\nto a Permit Alias in the Firewall Tab.\n\nIf the IP is not listed beside the List, this means that the Block is a /32 entry.\nOnly /32 or /24 CIDR Hosts can be suppressed.\n\nIf (Duplication) Checking is not enabled. You may see /24 and /32 CIDR Blocks for a given blocked Host";
+ // Truncate long list names
+ $pfb_matchtitle = "Country Block rules cannot be Suppressed.\n\n To allow a particular Country IP, either remove the particular Country or add the host\nto a Permit Alias in the Firewall tab.\n\nIf the IP is not listed beside the list, this means that the block is a /32 entry.\nOnly /32 or /24 CIDR hosts can be suppressed.\n\nIf (Duplication) Checking is not enabled. You may see /24 and /32 CIDR blocks for a given blocked host";
if (strlen($pfb_match[1]) >= 17) {
$pfb_matchtitle = $pfb_match[1];
$pfb_match[1] = substr($pfb_match[1], 0, 16) . '...';
}
- // Print Alternating Line Shading
- $alertRowEvenClass = "style='background-color: #D8D8D8;'";
- $alertRowOddClass = "style='background-color: #E8E8E8;'";
-
+ // Print alternating line shading
$alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass;
echo "<tr {$alertRowClass}>
<td class='listMRr' align='center'>{$fields[99]}</td>
- <td class='listMRr' align='center'>{$fields[2]}</td>
+ <td class='listMRr' align='center'><small>{$fields[2]}</small></td>
<td class='listMRr' align='center' title='The pfBlockerNG Rule that Blocked this Host.'>{$rule}</td>
- <td class='listMRr' align='center'>{$fields[6]}</td>
- <td class='listMRr' align='center' sorttable_customkey='{$fields[97]}'>{$src_icons}{$fields[97]}{$srcport}<br /><small>{$hostname['src']}</small></td>
- <td class='listMRr' align='center' sorttable_customkey='{$fields[98]}'>{$dst_icons}{$fields[98]}{$dstport}<br /><small>{$hostname['dst']}</small></td>
+ <td class='listMRr' align='center'><small>{$fields[6]}</small></td>
+ <td class='listMRr' align='center' sorttable_customkey='{$fields[97]}'>{$src_icons}{$fields[97]}{$srcport}<br />
+ <small>{$hostname['src']}</small></td>
+ <td class='listMRr' align='center' sorttable_customkey='{$fields[98]}'>{$dst_icons}{$fields[98]}{$dstport}<br />
+ <small>{$hostname['dst']}</small></td>
<td class='listMRr' align='center'>{$country}</td>
- <td class='listbg' align='center' title='{$pfb_matchtitle}' style=\"font-size: 10px word-wrap:break-word;\">{$pfb_match[1]}<br />{$pfb_match[2]}</td></tr>";
+ <td class='listbg' align='center' title='{$pfb_matchtitle}' style=\"font-size: 10px word-wrap:break-word;\">
+ {$pfb_match[1]}<br /><small>{$pfb_match[2]}</small></td></tr>";
$counter++;
- if ($rtype == "block") {
+ if ($rtype == 'block') {
$resolvecounter = $counter;
}
}
}
}
?>
+
</tbody>
<tr>
- <!--Print Final Table Info-->
+ <!--Print final table info-->
<?php
if ($pfbentries != $counter) {
- $msg = " - Insufficient Firewall Alerts found.";
+ $msg = ' - Insufficient Firewall Alerts found.';
}
- echo (" <td colspan='8' style='font-size:10px; background-color: #F0F0F0;' >Found {$counter} Alert Entries {$msg}</td>");
+ if ($type == 'DNSBL') {
+ $colspan = "colspan='7'";
+ } else {
+ $colspan = "colspan='8'";
+ }
+
+ echo (" <td {$colspan} style='font-size:10px; background-color: #F0F0F0;' >Found {$counter} Alert Entries {$msg}</td>");
$counter = 0; $msg = '';
?>
</tr>
</table>
</table>
-<?php endforeach; ?> <!--End - Create Three Output Windows 'Deny', 'Permit' and 'Match'-->
+<?php endforeach; ?> <!--End - Create three output windows 'Deny', 'Permit' and 'Match'-->
<?php unset ($fields_array); ?>
</td></tr>
</table>
@@ -1041,7 +1255,7 @@ if (!empty($fields_array[$type]) && !empty($rule_list)) {
<script type="text/javascript">
//<![CDATA[
-// This function stuffs the passed HOST, Table values into hidden Form Fields for postback.
+// This function inserts the passed HOST and table values into a hidden Form fields for postback.
function hostruleid(host,table) {
document.getElementById("ip").value = host;
document.getElementById("table").value = table;
@@ -1055,10 +1269,15 @@ function hostruleid(host,table) {
}
}
-// Auto-Resolve of Alerted Hostnames
+// This function collects the domain and list for the DNSBL suppression function.
+function domainlistid(domain,domainlist) {
+ document.getElementById("domain").value = domain;
+}
+
+// Auto-resolve of alerted hostnames
function findhostnames(counter) {
getip = jQuery('#gethostname_' + counter).attr('name');
- geturl = "<?php echo $_SERVER['PHP_SELF']; ?>";
+ geturl = "/pfblockerng/pfblockerng_alerts_ar.php";
jQuery.get( geturl, { "getpfhostname": getip } )
.done(function( data ) {
jQuery('#gethostname_' + counter).prop('title' , data );
@@ -1071,7 +1290,7 @@ function findhostnames(counter) {
var alertlines = <?php echo $resolvecounter; ?>;
var autoresolve = "<?php echo $config['installedpackages']['pfblockerngglobal']['hostlookup']; ?>";
-if ( autoresolve == "on" ) {
+if ( autoresolve == 'on' ) {
for (alertcount = 0; alertcount < alertlines; alertcount++) {
setTimeout(findhostnames(alertcount), 30);
}
@@ -1089,7 +1308,7 @@ function enable_hideFilter() {
//]]>
</script>
-<?php include("fend.inc"); ?>
+<?php include('fend.inc'); ?>
</form>
</body>
</html> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_alerts_ar.php b/config/pfblockerng/pfblockerng_alerts_ar.php
new file mode 100644
index 00000000..8de850f3
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_alerts_ar.php
@@ -0,0 +1,52 @@
+<?php
+/*
+ pfBlockerNG_Alerts_AR.php
+
+ pfBlockerNG
+ Copyright (c) 2015 BBcan177@gmail.com
+ All rights reserved.
+
+ Portions of this code are based on original work done for
+ pfSense from the following contributors:
+
+ 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.
+*/
+
+// Auto-resolve hostnames
+if (isset($_REQUEST['getpfhostname'])) {
+ $getpfhostname = trim(htmlspecialchars($_REQUEST['getpfhostname']));
+ if (strlen($getpfhostname) >= 8) {
+ $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES);
+ } else {
+ $hostname = $getpfhostname;
+ }
+ if ($hostname == $getpfhostname) {
+ $hostname = 'unknown';
+ }
+ echo $hostname;
+}
+
+?>
diff --git a/config/pfblockerng/pfblockerng_diag_dns.php b/config/pfblockerng/pfblockerng_diag_dns.php
deleted file mode 100644
index fa238b7a..00000000
--- a/config/pfblockerng/pfblockerng_diag_dns.php
+++ /dev/null
@@ -1,320 +0,0 @@
-<?php
-/*
- pfBlockerNG_diag_dns.php
-
- pfBlockerNG
- Copyright (C) 2015 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++;
-}
-
-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("/usr/bin/drill {$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("/usr/bin/drill {$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("/usr/bin/drill {$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");
- }
- }
-}
-
-if ( ($_POST['host']) && ($_POST['dialog_output']) ) {
- display_host_results ($host,$resolved,$dns_speeds);
- exit;
-}
-
-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" summary="pfblockerng diag dns">
- <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" summary="tabcont">
- <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 summary="results">
- <tr><td valign="top">
- <input name="host" type="text" class="formfld unknown" id="host" size="20" value="<?=htmlspecialchars($host);?>">
- </td>
- <?php if ($resolved && $type) { ?>
- <td valign="middle">&nbsp;&nbsp;</td><td>
- <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><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 }
- }
- }
-?>
-
- <?php } ?>
- </font></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="0" cellpadding="6" cellspacing="0" summary="resolution time">
- <tr>
- <td class="listhdrr">
- <?=gettext("Server");?>
- </td>
- <td class="listhdrr">
- <?=gettext("Query time");?>
- </td>
- </tr>
-<?php
- if (is_array($dns_speeds))
- foreach ($dns_speeds as $qt):
-?>
- <tr>
- <td class="listlr">
- <?=$qt['dns_server']?>
- </td>
- <td class="listr">
- <?=$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">&nbsp;</td>
- <td width="78%">
- <br />&nbsp;
- <input name="Submit" type="submit" class="formbtn" value="<?=gettext("DNS Lookup");?>">
- </td>
- </tr>
- </table>
-</form>
-</td></tr></table>
-<?php include("fend.inc"); ?>
-</body>
-</html> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_dnsbl.xml b/config/pfblockerng/pfblockerng_dnsbl.xml
new file mode 100644
index 00000000..b6a09b62
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_dnsbl.xml
@@ -0,0 +1,597 @@
+<?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_dnsbl.xml
+
+ pfBlockerNG
+ Copyright (c) 2015 BBcan177@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>pfblockerngdnsblsettings</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: DNSBL: Settings</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <addedit_string>pfBlockerNG: Save DNSBL general settings</addedit_string>
+ <menu>
+ <name>pfBlockerNG</name>
+ <tooltiptext></tooltiptext>
+ <section>Firewall</section>
+ <configfile>pfblockerng_dnsbl.xml</configfile>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</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</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>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ </tab>
+ <tab>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</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</url>
+ </tab>
+ <tab>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ <tab_level>2</tab_level>
+ <active/>
+ </tab>
+ <tab>
+ <text>DNSBL Feeds</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_dnsbl_lists.xml</url>
+ <tab_level>2</tab_level>
+ </tab>
+ <tab>
+ <text>DNSBL EasyList</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl_easylist.xml</url>
+ <tab_level>2</tab_level>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <name><![CDATA[DNS Block List Configuration &emsp; Run 'Force Update' to deploy new Settings.]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>LINKS</fielddescr>
+ <fieldname></fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ </description>
+ <type>info</type>
+ </field>
+ <field>
+ <type>info</type>
+ <description><![CDATA[<font color='red'>Note: </font>DNSBL requires the DNS Resolver (Unbound) to be used as the DNS service.<br />
+ When a DNS request is made for a domain that is listed in DNSBL, the request is redirected to the Virtual IP address<br />
+ where an instance of Lighttpd Web Server will collect the packet statistics and push a '1x1' GIF image to the Browser.
+ If browsing is slow, check for Firewall LAN Rules/Limiters that might be blocking access to the DNSBL VIP.<br /><br />
+
+ <font color='red'>Note: </font>DNSBL will block and <u>partially</u> log Alerts for HTTPS requests.
+ To debug issues with 'False Positives', the following tools below can be used:<br /><ul>
+
+ <li>1. Browser Dev mode (F12) and goto 'Console' to review any error messages.</li>
+ <li>2. Execute the following command from pfSense Shell (Changing the interface 're1' to the pfSense Lan Interface):<br />
+ <li>&emsp;<strong>tcpdump -nnvli re1 port 53 | grep -B1 'A 10.10.10.1'</strong></li>
+ <li>3. Packet capture software such as Wireshark.</li></ul>]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr>Enable DNSBL</fielddescr>
+ <fieldname>pfb_dnsbl</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[This will enable DNS Block List for Malicious and/or unwanted Adverts Domains<br />
+ To Utilize, <strong>Unbound DNS Resolver</strong> must be enabled.]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr>DNSBL Virtual IP</fielddescr>
+ <fieldname>pfb_dnsvip</fieldname>
+ <type>input</type>
+ <size>13</size>
+ <description><![CDATA[Example ( 10.10.10.1 )<br />
+ Enter a &emsp;<strong>single IPv4 VIP address</strong> &emsp;that is RFC1918 Compliant.<br /><br />
+ This address should be in an Isolated Range than what is used in your Network.<br />
+ Rejected DNS Requests will be forwarded to this VIP (Virtual IP)<br />
+ RFC1918 Compliant - (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)]]>
+ </description>
+ <default_value>10.10.10.1</default_value>
+ </field>
+ <field>
+ <fielddescr>DNSBL Listening Port</fielddescr>
+ <fieldname>pfb_dnsport</fieldname>
+ <type>input</type>
+ <size>3</size>
+ <description><![CDATA[Example ( 8081 )<br />
+ Enter a &emsp;<strong>single PORT</strong> &emsp;that is in the range of 1 - 65535<br /><br />
+ This Port must not be in use by any other process.]]>
+ </description>
+ <default_value>8081</default_value>
+ </field>
+ <field>
+ <fielddescr>DNSBL SSL Listening Port</fielddescr>
+ <fieldname>pfb_dnsport_ssl</fieldname>
+ <type>input</type>
+ <size>3</size>
+ <description><![CDATA[Example ( 8443 )<br />
+ Enter a &emsp;<strong>single PORT</strong> &emsp;that is in the range of 1 - 65535<br /><br />
+ This Port must not be in use by any other process.]]>
+ </description>
+ <default_value>8443</default_value>
+ </field>
+ <field>
+ <fielddescr>DNSBL Listening Interface</fielddescr>
+ <fieldname>dnsbl_interface</fieldname>
+ <description><![CDATA[Select the interface you want DNSBL to Listen on.<br />
+ Default: <strong>LAN</strong> - Selected Interface should be a Local Interface only.]]>
+ </description>
+ <type>interfaces_selection</type>
+ <hideinterfaceregex>wan|loopback</hideinterfaceregex>
+ <default_value>lan</default_value>
+ </field>
+ <field>
+ <fielddescr>DNSBL Firewall Rule</fielddescr>
+ <fieldname>pfb_dnsbl_rule</fieldname>
+ <type>checkbox</type>
+ <usecolspan2/>
+ <combinefields>begin</combinefields>
+ </field>
+ <field>
+ <fieldname>dnsbl_allow_int</fieldname>
+ <description><![CDATA[This will create a 'Floating' Firewall rule to allow traffic from the Selected Interface(s) below<br />
+ to access the DNSBL VIP on the LAN interface. This is only required for multiple LAN Segments.]]>
+ </description>
+ <type>interfaces_selection</type>
+ <hideinterfaceregex>wan</hideinterfaceregex>
+ <multiple/>
+ <usecolspan2/>
+ <dontdisplayname/>
+ <combinefields>end</combinefields>
+ </field>
+ <field>
+ <name>DNSBL IP Firewall Rule Settings</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <description>Configure settings for Firewall Rules when any DNSBL Feed contain IP Addresses</description>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr>List Action</fielddescr>
+ <description><![CDATA[Default: <strong>Disabled</strong><br /><br />
+ Select the <strong>Action</strong> for Firewall Rules when any DNSBL Feed contain IP addresses.<br /><br />
+ <strong><u>'Disabled' Rule:</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>'Alias' Rule:</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.]]>
+ </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>Alias Deny</name><value>Alias_Deny</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>Advanced Inbound Firewall Rule Settings</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <type>info</type>
+ <description><![CDATA[<font color='red'>Note: </font>In general, Auto-Rules are created as follows:<br />
+ <ul>Inbound &emsp;- 'any' port, 'any' protocol and 'any' destination<br />
+ Outbound - 'any' port, 'any' protocol and 'any' destination address in the lists</ul>
+ Configuring the Adv. Inbound Rule settings, will allow for more customization of the Inbound Auto-Rules.<br />
+ <strong>Select the pfSense 'Port' and/or 'Destination' Alias below:</strong>]]>
+ </description>
+ </field>
+ <field>
+ <fieldname>autoports</fieldname>
+ <fielddescr>Enable Custom Port</fielddescr>
+ <type>checkbox</type>
+ <enablefields>aliasports</enablefields>
+ <usecolspan2/>
+ <combinefields>begin</combinefields>
+ </field>
+ <field>
+ <fielddescr>Define Alias</fielddescr>
+ <fieldname>aliasports</fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php?tab=port">Click Here to add/edit Aliases</a>
+ Do not manually enter port numbers. <br />Do not use 'pfB_' in the Port Alias name.]]>
+ </description>
+ <size>21</size>
+ <type>aliases</type>
+ <typealiases>port</typealiases>
+ <dontdisplayname/>
+ <usecolspan2/>
+ <combinefields>end</combinefields>
+ </field>
+ <field>
+ <fieldname>autodest</fieldname>
+ <fielddescr>Enable Custom Destination</fielddescr>
+ <type>checkbox</type>
+ <enablefields>aliasdest,autonot</enablefields>
+ <usecolspan2/>
+ <combinefields>begin</combinefields>
+ </field>
+ <field>
+ <fieldname>aliasdest</fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php?tab=ip">Click Here to add/edit Aliases</a>
+ Do not manually enter Addresses(es). <br />Do not use 'pfB_' in the 'IP Network Type' Alias name.]]>
+ </description>
+ <size>21</size>
+ <type>aliases</type>
+ <typealiases>network</typealiases>
+ <dontdisplayname/>
+ <usecolspan2/>
+ <combinefields/>
+ </field>
+ <field>
+ <fielddescr>Invert</fielddescr>
+ <fieldname>autonot</fieldname>
+ <description><![CDATA[<div style="padding-left: 22px;"><strong>Invert</strong> - Option to invert the sense of the match.<br />
+ ie - Not (!) Destination Address(es)</div>]]>
+ </description>
+ <type>checkbox</type>
+ <dontdisplayname/>
+ <usecolspan2/>
+ <combinefields>end</combinefields>
+ </field>
+ <field>
+ <fielddescr>Custom Protocol</fielddescr>
+ <fieldname>autoproto</fieldname>
+ <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).<br />
+ Do not use 'any' with Adv. Inbound Rules as it will bypass these settings!]]></description>
+ <type>select</type>
+ <options>
+ <option><name>any</name><value></value></option>
+ <option><name>TCP</name><value>tcp</value></option>
+ <option><name>UDP</name><value>udp</value></option>
+ <option><name>TCP/UDP</name><value>tcp/udp</value></option>
+ </options>
+ <size>4</size>
+ <default_value></default_value>
+ </field>
+ <field>
+ <name><![CDATA[Alexa Whitelist]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Enable Alexa</fielddescr>
+ <fieldname>alexa_enable</fieldname>
+ <description><![CDATA[Alexa provides a <a target="_blank" href="https://aws.amazon.com/alexa-top-sites/">Top 1 million sites list.</a>
+ (Global 1 month average traffic ranking)<br /><br />
+ Alexa can be used to whitelist the most popular domain names to avoid false positives.
+ To use this feature, select the number of 'Top Domains' to whitelist. You can also 'include' which TLDs to whitelist.<br />
+
+ <br /><font color='red'>Recommendation: </font>
+ <ul>Alexa also contains the 'Top' AD Servers, so its recommended to configure the first DNSBL Alias with AD Server<br />
+ (ie. yoyo, Adaway...) based feeds. Alexa whitelisting can be disabled for this first defined Alias.<br /><br />
+ Generally, Alexa should be used for feeds that post full URLs like PhishTank, OpenPhish or MalwarePatrol.<br /><br />
+ To bypass an Alexa domain, add the Domain to the first defined Alias 'Custom Block list' with Alexa disabled in this alias.</ul>
+
+ The complete 'Top 1M list' can be downloaded from
+ <a target=_blank href="https://s3.amazonaws.com/alexa-static/top-1m.csv.zip">Here</a> (Database is free to use.)<br />
+ When enabled, this list will be automatically updated once per month along with the MaxMind Database.]]>
+ </description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fielddescr><![CDATA[Number of Alexa<br />Top Domains to Whitelisting]]></fielddescr>
+ <fieldname>alexa_count</fieldname>
+ <description><![CDATA[<strong>Default: Top 1k</strong><br />
+ Select the <strong>number</strong> of Alexa 'Top Domain global ranking' to whitelist.]]></description>
+ <type>select</type>
+ <options>
+ <option><name>Top 100</name><value>100</value></option>
+ <option><name>Top 1k</name><value>1000</value></option>
+ <option><name>Top 10k</name><value>10000</value></option>
+ <option><name>Top 100k</name><value>100000</value></option>
+ <option><name>Top 250k</name><value>250000</value></option>
+ <option><name>Top 500k</name><value>500000</value></option>
+ <option><name>Top 750k</name><value>750000</value></option>
+ <option><name>Top 1M</name><value>1000000</value></option>
+ </options>
+ <default_value>1000</default_value>
+ </field>
+ <field>
+ <fielddescr>Alexa TLD Inclusion</fielddescr>
+ <fieldname>alexa_inclusion</fieldname>
+ <description><![CDATA[Select the TLDs for Whitelist. ( Only showing the Top 150 TLDs )<br />
+ <strong>Default: COM, NET, ORG, CA, CO, IO</strong><br /><br />
+ Detailed listing : <a target=_blank href="http://www.iana.org/domains/root/db">Root Zone top-level domains.</a> ]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>AE</name><value>ae</value></option>
+ <option><name>AERO</name><value>aero</value></option>
+ <option><name>AG</name><value>ag</value></option>
+ <option><name>AL</name><value>al</value></option>
+ <option><name>AM</name><value>am</value></option>
+ <option><name>AR</name><value>ar</value></option>
+ <option><name>AE</name><value>ae</value></option>
+ <option><name>AERO</name><value>aero</value></option>
+ <option><name>AG</name><value>ag</value></option>
+ <option><name>AL</name><value>al</value></option>
+ <option><name>AM</name><value>am</value></option>
+ <option><name>AR</name><value>ar</value></option>
+ <option><name>ASIA</name><value>asia</value></option>
+ <option><name>AT</name><value>at</value></option>
+ <option><name>AU (16)</name><value>au</value></option>
+ <option><name>AZ</name><value>az</value></option>
+ <option><name>BA</name><value>ba</value></option>
+ <option><name>BD</name><value>bd</value></option>
+ <option><name>BE</name><value>be</value></option>
+ <option><name>BG</name><value>bg</value></option>
+ <option><name>BIZ</name><value>biz</value></option>
+ <option><name>BO</name><value>bo</value></option>
+ <option><name>BR (7)</name><value>br</value></option>
+ <option><name>BY</name><value>by</value></option>
+ <option><name>BZ</name><value>bz</value></option>
+ <option><name>CA (21)</name><value>ca</value></option>
+ <option><name>CAT</name><value>cat</value></option>
+ <option><name>CC</name><value>cc</value></option>
+ <option><name>CF</name><value>cf</value></option>
+ <option><name>CH</name><value>ch</value></option>
+ <option><name>CL</name><value>cl</value></option>
+ <option><name>CLUB</name><value>club</value></option>
+ <option><name>CN (14)</name><value>cn</value></option>
+ <option><name>CO (22)</name><value>co</value></option>
+ <option><name>COM (1)</name><value>com</value></option>
+ <option><name>COOP</name><value>coop</value></option>
+ <option><name>CR</name><value>cr</value></option>
+ <option><name>CU</name><value>cu</value></option>
+ <option><name>CY</name><value>cy</value></option>
+ <option><name>CZ (23)</name><value>cz</value></option>
+ <option><name>DE (5)</name><value>de</value></option>
+ <option><name>DEV</name><value>dev</value></option>
+ <option><name>DK</name><value>dk</value></option>
+ <option><name>DO</name><value>do</value></option>
+ <option><name>DZ</name><value>dz</value></option>
+ <option><name>EC</name><value>ec</value></option>
+ <option><name>EDU</name><value>edu</value></option>
+ <option><name>EE</name><value>ee</value></option>
+ <option><name>EG</name><value>eg</value></option>
+ <option><name>ES (18)</name><value>es</value></option>
+ <option><name>EU (25)</name><value>eu</value></option>
+ <option><name>FI</name><value>fi</value></option>
+ <option><name>FM</name><value>fm</value></option>
+ <option><name>FR (12)</name><value>fr</value></option>
+ <option><name>GA</name><value>ga</value></option>
+ <option><name>GE</name><value>ge</value></option>
+ <option><name>GOV</name><value>gov</value></option>
+ <option><name>GR (20)</name><value>gr</value></option>
+ <option><name>GT</name><value>gt</value></option>
+ <option><name>GURU</name><value>guru</value></option>
+ <option><name>HK</name><value>hk</value></option>
+ <option><name>HR</name><value>hr</value></option>
+ <option><name>HU</name><value>hu</value></option>
+ <option><name>ID</name><value>id</value></option>
+ <option><name>IE</name><value>ie</value></option>
+ <option><name>IL</name><value>il</value></option>
+ <option><name>IM</name><value>im</value></option>
+ <option><name>IN (9)</name><value>in</value></option>
+ <option><name>INFO (15)</name><value>info</value></option>
+ <option><name>INT</name><value>int</value></option>
+ <option><name>IO</name><value>io</value></option>
+ <option><name>IR (13)</name><value>ir</value></option>
+ <option><name>IS</name><value>is</value></option>
+ <option><name>IT (11)</name><value>it</value></option>
+ <option><name>JO</name><value>jo</value></option>
+ <option><name>JOBS</name><value>jobs</value></option>
+ <option><name>JP (6)</name><value>jp</value></option>
+ <option><name>KE</name><value>ke</value></option>
+ <option><name>KG</name><value>kg</value></option>
+ <option><name>KR (19)</name><value>kr</value></option>
+ <option><name>KW</name><value>kw</value></option>
+ <option><name>KZ</name><value>kz</value></option>
+ <option><name>LA</name><value>la</value></option>
+ <option><name>LI</name><value>li</value></option>
+ <option><name>LINK</name><value>link</value></option>
+ <option><name>LK</name><value>lk</value></option>
+ <option><name>LT</name><value>lt</value></option>
+ <option><name>LU</name><value>lu</value></option>
+ <option><name>LV</name><value>lv</value></option>
+ <option><name>LY</name><value>ly</value></option>
+ <option><name>MA</name><value>ma</value></option>
+ <option><name>MD</name><value>md</value></option>
+ <option><name>ME</name><value>me</value></option>
+ <option><name>MK</name><value>mk</value></option>
+ <option><name>ML</name><value>ml</value></option>
+ <option><name>MN</name><value>mn</value></option>
+ <option><name>MOBI</name><value>mobi</value></option>
+ <option><name>MX</name><value>mx</value></option>
+ <option><name>MY</name><value>my</value></option>
+ <option><name>NAME</name><value>name</value></option>
+ <option><name>NET (2)</name><value>net</value></option>
+ <option><name>NG</name><value>ng</value></option>
+ <option><name>NINJA</name><value>ninja</value></option>
+ <option><name>NL (17)</name><value>nl</value></option>
+ <option><name>NO</name><value>no</value></option>
+ <option><name>NP</name><value>np</value></option>
+ <option><name>NU</name><value>nu</value></option>
+ <option><name>NZ</name><value>nz</value></option>
+ <option><name>OM</name><value>om</value></option>
+ <option><name>ORG (4)</name><value>org</value></option>
+ <option><name>PA</name><value>pa</value></option>
+ <option><name>PE</name><value>pe</value></option>
+ <option><name>PH</name><value>ph</value></option>
+ <option><name>PK</name><value>pk</value></option>
+ <option><name>PL (10)</name><value>pl</value></option>
+ <option><name>PRO</name><value>pro</value></option>
+ <option><name>PT</name><value>pt</value></option>
+ <option><name>PW</name><value>pw</value></option>
+ <option><name>PY</name><value>py</value></option>
+ <option><name>QA</name><value>qa</value></option>
+ <option><name>RO</name><value>ro</value></option>
+ <option><name>RS</name><value>rs</value></option>
+ <option><name>RU (3)</name><value>ru</value></option>
+ <option><name>SA</name><value>sa</value></option>
+ <option><name>SE</name><value>se</value></option>
+ <option><name>SG</name><value>sg</value></option>
+ <option><name>SI</name><value>si</value></option>
+ <option><name>SK</name><value>sk</value></option>
+ <option><name>SO</name><value>so</value></option>
+ <option><name>SPACE</name><value>space</value></option>
+ <option><name>SU</name><value>su</value></option>
+ <option><name>TH</name><value>th</value></option>
+ <option><name>TK</name><value>tk</value></option>
+ <option><name>TN</name><value>tn</value></option>
+ <option><name>TO</name><value>to</value></option>
+ <option><name>TODAY</name><value>today</value></option>
+ <option><name>TOP</name><value>top</value></option>
+ <option><name>TR</name><value>tr</value></option>
+ <option><name>TRAVEL</name><value>travel</value></option>
+ <option><name>TV</name><value>tv</value></option>
+ <option><name>TW (24)</name><value>tw</value></option>
+ <option><name>TZ</name><value>tz</value></option>
+ <option><name>UA</name><value>ua</value></option>
+ <option><name>UK (8)</name><value>uk</value></option>
+ <option><name>US</name><value>us</value></option>
+ <option><name>UY</name><value>uy</value></option>
+ <option><name>UZ</name><value>uz</value></option>
+ <option><name>VC</name><value>vc</value></option>
+ <option><name>VE</name><value>ve</value></option>
+ <option><name>VN</name><value>vn</value></option>
+ <option><name>WEBSITE</name><value>website</value></option>
+ <option><name>WS</name><value>ws</value></option>
+ <option><name>XN--P1AI</name><value>xn--p1ai</value></option>
+ <option><name>XXX</name><value>xxx</value></option>
+ <option><name>XYZ</name><value>xyz</value></option>
+ <option><name>ZA</name><value>za</value></option>
+ </options>
+ <default_value><![CDATA[com,net,org,ca,co,io]]></default_value>
+ <size>10</size>
+ <multiple/>
+ </field>
+ <field>
+ <name><![CDATA[Custom Domain Suppression]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Custom List</fielddescr>
+ <fieldname>suppression</fieldname>
+ <description><![CDATA[No Regex Entries Allowed!<br /><br />
+ Enter one &emsp; <strong>Domain Name</strong>&emsp; per line<br />
+ You may use "<strong>#</strong>" after any Domain name to add comments. example ( google.com # Suppress Google.com )<br />
+ This List is stored as 'Base64' format in the config.xml file.<br /><br />
+ <font color='red'>Note: </font>These entries are only suppressed when Feeds are downloaded or on a
+ <font color='red'>'Force Reload'.</font><br />
+ Use the Alerts Tab '+' Suppression icon to immediately remove a domain from Unbound DNSBL.]]>
+ </description>
+ <type>textarea</type>
+ <cols>50</cols>
+ <rows>25</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
+ 'Force Update'</center>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ <![CDATA[
+ pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ <![CDATA[
+ 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_dnsbl_easylist.xml b/config/pfblockerng/pfblockerng_dnsbl_easylist.xml
new file mode 100644
index 00000000..f416e7d8
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_dnsbl_easylist.xml
@@ -0,0 +1,284 @@
+<?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_dnsbl_easylist.xml
+
+ pfBlockerNG
+ Copyright (c) 2015 BBcan177@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>pfblockerngdnsbleasylist</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: DNSBL: EasyList</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <addedit_string>pfBlockerNG: Save DNSBL Easylist settings</addedit_string>
+ <menu>
+ <name>pfBlockerNG</name>
+ <tooltiptext></tooltiptext>
+ <section>Firewall</section>
+ <configfile>pfblockerng_dnsbl_easylist.xml</configfile>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</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</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>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ </tab>
+ <tab>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</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</url>
+ </tab>
+ <tab>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ <tab_level>2</tab_level>
+ </tab>
+ <tab>
+ <text>DNSBL Feeds</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_dnsbl_lists.xml</url>
+ <tab_level>2</tab_level>
+ </tab>
+ <tab>
+ <text>DNSBL EasyList</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl_easylist.xml</url>
+ <tab_level>2</tab_level>
+ <active/>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <name><![CDATA[DNSBL - EasyList &emsp; Run 'Force Update' to deploy new Settings.]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>LINKS</fielddescr>
+ <fieldname></fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ </description>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr>DNS GROUP Name</fielddescr>
+ <fieldname>aliasname</fieldname>
+ <description><![CDATA[Enter DNS Group Name.&emsp; Example: EasyList]]></description>
+ <type>input</type>
+ <size>20</size>
+ </field>
+ <field>
+ <fielddescr>Description</fielddescr>
+ <fieldname>description</fieldname>
+ <type>input</type>
+ <size>90</size>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>EasyList Feeds</strong>]]></fielddescr>
+ <description><![CDATA[Add Easylist Feed]]></description>
+ <fieldname></fieldname>
+ <type>rowhelper</type>
+ <rowhelper>
+ <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>
+ <option><name>FLEX</name><value>Flex</value></option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>EasyList Feed</fielddescr>
+ <fieldname>url</fieldname>
+ <type>select</type>
+ <options>
+ <option>
+ <name>EasyList w/o Elements</name>
+ <value>https://easylist-downloads.adblockplus.org/easylist_noelemhide.txt</value>
+ </option>
+ <option>
+ <name>EasyPrivacy</name>
+ <value>https://easylist-downloads.adblockplus.org/easyprivacy.txt</value>
+ </option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Header</fielddescr>
+ <fieldname>header</fieldname>
+ <type>input</type>
+ <size>15</size>
+ </rowhelperfield>
+ </rowhelper>
+ </field>
+ <field>
+ <name><![CDATA[DNSBL - EasyList Settings]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Categories</fielddescr>
+ <description><![CDATA[Select the categories you wish to block that match the EasyList Feeds selected above.<br /><br />
+ DNSBL EasyList utilizing the following hardcoded URLs:&emsp;
+ <a href="https://easylist-downloads.adblockplus.org/easylist_noelemhide.txt" target="_blank" >EasyList w/o Elements |</a>&nbsp;
+ <a href="https://easylist-downloads.adblockplus.org/easyprivacy.txt" target="_blank" >EasyPrivacy</a><br />
+ List distributed under the Creative Commons Attribution-ShareAlike License. &nbsp;
+ <a href="https://easylist.adblockplus.org/" target="_blank" >(Credits)</a><br /><br />
+ <strong>Use CTRL + CLICK to select/unselect the EasyList categories.</strong>]]>
+ </description>
+ <fieldname>easycat</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>EASYLIST Adservers</name><value>ea</value></option>
+ <option><name>EASYLIST Adservers Popup</name><value>eap</value></option>
+ <option><name>EASYLIST Adult Adservers</name><value>aa</value></option>
+ <option><name>EASYLIST Adult Adservers Popup</name><value>aap</value></option>
+ <option><name>EASYPRIVACY Tracking Servers</name><value>epts</value></option>
+ <option><name>EASYPRIVACY Tracking International</name><value>epti</value></option>
+ </options>
+ <size>6</size>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr>List Action</fielddescr>
+ <description><![CDATA[Default: <strong>Disabled</strong><br />
+ Select <strong>Unbound</strong> to enable 'DNSBL' blocking for this Alias.]]>
+ </description>
+ <fieldname>action</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>Disabled</name><value>Disabled</value></option>
+ <option><name>Unbound</name><value>unbound</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Update Frequency</fielddescr>
+ <fieldname>cron</fieldname>
+ <description><![CDATA[Default: <strong>Never</strong><br />
+ Select how often Feed will be downloaded. <strong>This must be within the Cron Interval/Start Hour settings.</strong>]]>
+ </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>Monday</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 Alexa Whitelist</fielddescr>
+ <fieldname>filter_alexa</fieldname>
+ <description>Filter Alias via Alexa</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
+ 'Force Update'</center>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ <![CDATA[
+ pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ <![CDATA[
+ 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_dnsbl_lists.xml b/config/pfblockerng/pfblockerng_dnsbl_lists.xml
new file mode 100644
index 00000000..e07ee0c1
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_dnsbl_lists.xml
@@ -0,0 +1,333 @@
+<?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_dnsbl_lists.xml
+
+ pfBlockerNG
+ Copyright (c) 2015 BBcan177@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>pfblockerngdnsbl</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: DNSBL: Lists</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <addedit_string>pfBlockerNG: Save DNSBL Feeds settings</addedit_string>
+ <menu>
+ <name>pfBlockerNG</name>
+ <section>Firewall</section>
+ <configfile>pfblockerng_dnsbl_lists.xml</configfile>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</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</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>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ </tab>
+ <tab>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</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</url>
+ </tab>
+ <tab>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ <tab_level>2</tab_level>
+ </tab>
+ <tab>
+ <text>DNSBL Feeds</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_dnsbl_lists.xml</url>
+ <tab_level>2</tab_level>
+ <active/>
+ </tab>
+ <tab>
+ <text>DNSBL EasyList</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl_easylist.xml</url>
+ <tab_level>2</tab_level>
+ </tab>
+ </tabs>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>DNS Group Name</fielddescr>
+ <fieldname>aliasname</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>DNS Group Description</fielddescr>
+ <fieldname>description</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Action</fielddescr>
+ <fieldname>action</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Frequency</fielddescr>
+ <fieldname>cron</fieldname>
+ </columnitem>
+ <addtext>Add a new Alias</addtext>
+ <movable>on</movable>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <name><![CDATA[DNS Domain Name Block List &emsp; Run 'Force Update' to deploy new Settings.]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>LINKS</fielddescr>
+ <fieldname></fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ </description>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr>DNS GROUP Name</fielddescr>
+ <fieldname>aliasname</fieldname>
+ <description><![CDATA[Enter DNS Group Name.&emsp; Example: Ads]]></description>
+ <type>input</type>
+ <size>20</size>
+ </field>
+ <field>
+ <fielddescr>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>'State'</u></strong>: Select the run state.<br /><br />
+ <strong><u>'Source'</u></strong>:
+ <ul><li><strong>'URL'</strong>: External link to source
+ &emsp;(ie: <a target="_blank" href='http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&mimetype=plaintext'>yoyo</a>,
+ <a target="_blank" href='http://someonewhocares.org/hosts/hosts'>SomeoneWhoCares</a>,
+ <a target="_blank" href='https://adaway.org/hosts.txt'>Adaway</a>)</li></ul>
+ <ul><li><strong>'Local File'</strong>: http(s)://127.0.0.1/filename
+ &emsp;<strong>or</strong>&emsp; /var/db/pfblockerng/filename</li></ul>
+ <strong><u>'Header/Label'</u></strong>: This field must be <u>unique.</u> This names the file and is referenced in the widget.
+ &emsp;(ie: hpHosts_ads, hpHosts_partial)<br /><br />
+ <strong>AdBlock Easylists <u>cannot</u> be used in this Tab</strong><br /><br />]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>DNSBL</strong>]]></fielddescr>
+ <description><![CDATA[<br /><strong>'Format'</strong>: Select the file format that URL will retrieve.<br />
+ <ul><li><strong>'auto'</strong>&emsp;- Default parser</li>
+ <li><strong>'rsync'</strong> - RSync Lists</li></ul>
+ <strong>'State'</strong>: Select the Run State for each list.<br />
+ <ul><li><strong>'ON/OFF'</strong> - Enabled / Disabled</li>
+ <li><strong>'HOLD'</strong> - Once a List has been Downloaded, list will remain Static.</li>
+ <li><strong>'FLEX'</strong> - Not Recommended - Allow lower SSL connections</li></ul>
+ <strong>'Note'</strong>: Downloaded or pfsense local file must have only one Domain Name per line.]]>
+ </description>
+ <type>rowhelper</type>
+ <sortablefields/>
+ <rowhelper>
+ <rowhelperfield>
+ <fielddescr>Format</fielddescr>
+ <fieldname>format</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>Auto</name><value>auto</value></option>
+ <option><name>RSync</name><value>rsync</value></option>
+ </options>
+ <default_value>auto</default_value>
+ </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>
+ <option><name>FLEX</name><value>Flex</value></option>
+ </options>
+ <default_value>Enabled</default_value>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Source</fielddescr>
+ <fieldname>url</fieldname>
+ <type>input</type>
+ <size>50</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Header/Label</fielddescr>
+ <fieldname>header</fieldname>
+ <type>input</type>
+ <size>15</size>
+ <sortablefields/>
+ </rowhelperfield>
+ </rowhelper>
+ </field>
+ <field>
+ <fielddescr>List Action</fielddescr>
+ <description><![CDATA[Default: <strong>Disabled</strong><br />
+ Select <strong>Unbound</strong> to enable 'Domain Name' blocking for this Alias.]]>
+ </description>
+ <fieldname>action</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>Disabled</name><value>Disabled</value></option>
+ <option><name>Unbound</name><value>unbound</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. <strong>This must be within the Cron Interval/Start Hour settings.</strong>]]>
+ </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>Monday</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 Alexa Whitelist</fielddescr>
+ <fieldname>filter_alexa</fieldname>
+ <description>Filter Alias via Alexa</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <name><![CDATA[Custom Block List]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Custom Domain Name Block List</fielddescr>
+ <fieldname>custom</fieldname>
+ <description><![CDATA[No Regex Entries Allowed!<br /><br />
+ Enter one &emsp; <strong>'Domain Name'</strong> &emsp; per line<br /><br />
+ You may use "<strong>#</strong>" after any Domain name to add comments. example ( ads.google.com # Block Google Ads )<br />
+ This List is stored as 'Base64' format in the config.xml file.]]>
+ </description>
+ <type>textarea</type>
+ <cols>80</cols>
+ <rows>20</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <fielddescr>Update Custom List</fielddescr>
+ <fieldname>custom_update</fieldname>
+ <description><![CDATA[Select - '<strong>Default</strong>' to update Custom List as per Update Frequency setting.<br />
+ Select - '<strong>Update Custom List</strong>' followed by a 'Force Update' to apply Custom List Changes.<br />
+ Cron will also resync this Custom List at the next Update Frequency.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Default</name><value>disabled</value></option>
+ <option><name>Update Custom List</name><value>enabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
+ 'Force Update'</center>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ <![CDATA[
+ pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ <![CDATA[
+ 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_extra.inc b/config/pfblockerng/pfblockerng_extra.inc
new file mode 100644
index 00000000..576f1bc8
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_extra.inc
@@ -0,0 +1,131 @@
+<?php
+/*
+ pfBlockerNG_extra.inc
+
+ pfBlockerNG
+ Copyright (c) 2015 BBcan177@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.
+
+*/
+
+// This file is used to 'include functions' not yet merged into pfSense
+
+
+// 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;
+}
+
+?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_install.inc b/config/pfblockerng/pfblockerng_install.inc
index 28fe373f..d8a2bdae 100644
--- a/config/pfblockerng/pfblockerng_install.inc
+++ b/config/pfblockerng/pfblockerng_install.inc
@@ -3,7 +3,7 @@
pfBlockerNG_install.inc
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -31,52 +31,173 @@
*/
-// Install pfBlockerNG package, launched from pfblockerng.xml
-
require_once('/usr/local/pkg/pfblockerng/pfblockerng.inc');
require_once('/usr/local/www/pfblockerng/pfblockerng.php');
-global $config, $pfb;
+global $config, $pfb, $static_output;
pfb_global();
-// Remove previously used CC folder location if exists
-@rmdir_recursive("{$pfb['dbdir']}/cc");
+function update_static_output($text) {
+ global $static_output;
+
+ $static_output .= "{$text}";
+ update_output_window("{$static_output}");
+ return;
+}
+
+
+// Set 'Install flag' to skip sync process during installations.
+$g['pfblockerng_install'] = true;
+
+// Remove previous ccdir location files if exist
+$old_ccfiles = glob('/usr/pbi/pfblockerng-' . php_uname('m') . '/share/GeoIP/*_v?.txt');
+if (!empty($old_ccfiles)) {
+ foreach ($old_ccfiles as $oldfile) {
+ unlink_if_exists("{$oldfile}");
+ }
+}
+
+update_static_output("\nDownloading MaxMind Country databases.\n This may take a minute...");
-// Uncompress Country Code File
-@copy("{$pfb['dbdir']}/countrycodes.tar.bz2", "{$pfb['ccdir']}/countrycodes.tar.bz2");
-exec("/usr/bin/tar -jx -C {$pfb['ccdir']} -f {$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");
+// Only Download the MaxMind Database files (Skip Alexa)
+unset($pfb['extras'][5]);
+
+if (!pfblockerng_download_extras()) {
+ update_static_output(" MaxMind download failed!\nFetching MaxMind archive from pfSense package repo...");
+ // Fetch archived MaxMind database
+ $url = 'https://packages.pfsense.org/packages/config/pfblockerng/countrycodes.tar.bz2';
+ exec("/usr/bin/fetch -o /tmp/countrycodes.tar.bz2 {$url}");
+ // Uncompress archived Country code file
+ exec("/usr/bin/tar -jx -C {$pfb['ccdir']} -f /tmp/countrycodes.tar.bz2");
+ update_static_output(" done.\n");
+}
+else {
+ update_static_output(" done.\n");
+}
-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..."));
+update_static_output("Converting MaxMind Country databases for pfBlockerNG.\n This may take a few minutes...");
pfblockerng_uc_countries();
-update_output_window(gettext("Creating pfBlockerNG Continent XML Files..."));
+update_static_output(" done.\nCreating pfBlockerNG Continent XML files...");
pfblockerng_get_countries();
-update_output_window(gettext("Completed Creating pfBlockerNG Continent XML Files..."));
-
-// Remove Original Maxmind Database Files
-@unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryCSV.zip");
-@unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryWhois.csv");
-@unlink_if_exists("{$pfb['dbdir']}/GeoIPv6.csv");
-@unlink_if_exists("{$pfb['dbdir']}/country_continent.csv");
-
-// Add Widget to Dashboard
-update_output_window(gettext("Adding pfBlockerNG Widget to Dashboard."));
-if ($pfb['keep'] == "on" && !empty($pfb['widgets'])) {
- // Restore previous Widget setting if "Keep" is enabled.
+
+if ($pfb['keep'] == 'on' && isset($pfb['widgets']) && strpos($pfb['widgets'], 'pfblockerng-container') !== FALSE) {
+ update_static_output(" done.\nRestoring previous pfBlockerNG Widget settings...");
+ // Restore previous widget setting if 'keep' is enabled.
$config['widgets']['sequence'] = $pfb['widgets'];
+ write_config('pfBlockerNG: Save widget');
} else {
+ update_static_output(" done.\nAdding pfBlockerNG Widget to the Dashboard...");
$widgets = $config['widgets']['sequence'];
- if (!preg_match("/pfblockerng-container/", $widgets)) {
+ if (strpos($widgets, 'pfblockerng-container') === FALSE) {
if (empty($widgets)) {
- $config['widgets']['sequence'] = "pfblockerng-container:col2:show";
+ $config['widgets']['sequence'] = 'pfblockerng-container:col2:show';
} else {
- $config['widgets']['sequence'] .= ",pfblockerng-container:col2:show";
+ $config['widgets']['sequence'] .= ',pfblockerng-container:col2:show';
}
+ write_config('pfBlockerNG: Save widget');
+ }
+}
+
+update_static_output(" done.\nRemove any existing and create link for DNSBL lighttpd executable...");
+unlink_if_exists('/usr/local/sbin/lighttpd_pfb');
+link('/usr/local/sbin/lighttpd', '/usr/local/sbin/lighttpd_pfb');
+
+update_static_output(" done.\nCreating DNSBL web server start-up script...");
+$rc = array();
+$rc['file'] = 'dnsbl.sh';
+$rc['start'] = <<<EOF
+
+ # Start DNSBL Lighttpd webserver
+ if [ -f '{$pfb['dnsbl_conf']}' ]; then
+ /usr/local/sbin/lighttpd_pfb -f '{$pfb['dnsbl_conf']}'
+ fi
+
+ # Terminate DNSBL HTTPS Daemon if found
+ pidnum="$(/bin/ps -wax | /usr/bin/grep '[p]fblockerng.inc dnsbl' | /usr/bin/awk '{print $1}')"
+ if [ ! -z "\${pidnum}" ]; then
+ /bin/kill -9 "\${pidnum}"
+ /bin/sleep 2
+ fi
+
+ # Start DNSBL HTTPS Daemon
+ /usr/local/bin/php -f /usr/local/pkg/pfblockerng/pfblockerng.inc dnsbl &
+
+EOF;
+
+$rc['stop'] = <<<EOF
+
+ # Terminate DNSBL Lighttpd webserver, if found.
+ pidnum="$(/bin/pgrep lighttpd_pfb)"
+ if [ ! -z "\${pidnum}" ]; then
+ /usr/bin/killall lighttpd_pfb
+ fi
+
+ # Terminate DNSBL HTTPS Daemon, if found.
+ pidnum="$(/bin/ps -wax | /usr/bin/grep '[p]fblockerng.inc dnsbl' | /usr/bin/awk '{print $1}')"
+ if [ ! -z "\${pidnum}" ]; then
+ /bin/kill -9 "\${pidnum}"
+ /bin/sleep 2
+ fi
+
+EOF;
+
+write_rcfile($rc);
+update_static_output(" done.\n");
+
+if ($pfb['enable'] == 'on' && $pfb['dnsbl'] == 'on' && !empty($pfb['dnsbl_port']) && !empty($pfb['dnsbl_port_ssl'])) {
+ update_static_output("Creating DNSBL web server config ...");
+
+ $pfb_conf = <<<EOF
+#
+#pfBlockerNG Lighttpd DNSBL configuration file
+#
+server.bind = "0.0.0.0"
+server.port = "{$pfb['dnsbl_port']}"
+server.event-handler = "freebsd-kqueue"
+server.network-backend = "freebsd-sendfile"
+server.dir-listing = "disable"
+server.document-root = "/usr/local/www/pfblockerng/www/"
+server.errorlog = "/var/log/pfblockerng/dnsbl_error.log"
+server.pid-file = "/var/run/dnsbl.pid"
+server.modules = ( "mod_access", "mod_fastcgi", "mod_rewrite" )
+
+server.indexfiles = ( "index.php" )
+mimetype.assign = ( ".html" => "text/html", ".gif" => "image/gif" )
+url.access-deny = ( "~", ".inc" )
+fastcgi.server = ( ".php" => ( "localhost" => ( "socket" => "/var/run/php-fpm.socket", "broken-scriptfilename" => "enable" ) ) )
+
+debug.log-condition-handling = "enable"
+
+\$HTTP["host"] =~ ".*" {
+ url.rewrite-once = ( ".*" => "index.php" )
+}
+
+\$SERVER["socket"] == "0.0.0.0:{$pfb['dnsbl_port_ssl']}" {
+ ssl.engine = "enable"
+ ssl.pemfile = "{$pfb['dnsbl_cert']}"
+ ssl.use-sslv2 = "disable"
+ ssl.use-sslv3 = "disable"
+ ssl.honor-cipher-order = "enable"
+ ssl.cipher-list = "AES128+EECDH:AES256+EECDH:AES128+EDH:AES256+EDH:AES128-SHA:AES256-SHA:!aNULL:!eNULL:!DSS"
+
+ \$HTTP["host"] =~ ".*" {
+ url.rewrite-once = ( ".*" => "index.php" )
}
}
+
+EOF;
+
+ @file_put_contents($pfb['dnsbl_conf'], $pfb_conf, LOCK_EX);
+ unset($pfb_conf);
+ update_static_output(" done.\n");
+
+ update_static_output("Starting DNSBL Service...");
+ start_service('dnsbl');
+ update_static_output(" done.\n");
+}
+
+unset($g['pfblockerng_install']); // Remove 'Install flag'
+update_static_output("Custom commands completed ... ");
return TRUE;
?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_log.php b/config/pfblockerng/pfblockerng_log.php
index a235f20a..9d823038 100644
--- a/config/pfblockerng/pfblockerng_log.php
+++ b/config/pfblockerng/pfblockerng_log.php
@@ -9,15 +9,16 @@
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
+ Copyright (c) 2015 Electric Sheep Fencing, LLC. All rights reserved.
+ Copyright (c) 2009 Robert Zelaya Sr. Developer
+ Copyright (c) 2005 Bill Marquette
+ Copyright (c) 2004-2005 Scott Ullrich
+ Copyright (c) 2004 Manuel Kasper (BSD 2 clause)
+
All rights reserved.
Adapted for Suricata by:
- Copyright (C) 2015 Bill Meeks
+ Copyright (c) 2015 Bill Meeks
All rights reserved.
Javascript and Integration modifications by J. Nieuwenhuizen
@@ -46,9 +47,9 @@
POSSIBILITY OF SUCH DAMAGE.
*/
-require_once("guiconfig.inc");
-require_once("globals.inc");
-require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+require_once('guiconfig.inc');
+require_once('globals.inc');
+require_once('/usr/local/pkg/pfblockerng/pfblockerng.inc');
pfb_global();
@@ -61,10 +62,10 @@ function getlogs($logdir, $log_extentions = array('log')) {
// Get logfiles
$log_filenames = array();
foreach ($log_extentions as $extention) {
- if ($extention <> '*') {
- $log_filenames = array_merge($log_filenames, glob($logdir . "*." . $extention));
+ if ($extention != '*') {
+ $log_filenames = array_merge($log_filenames, glob($logdir . '*.' . $extention));
} else {
- $log_filenames = array_merge($log_filenames, glob($logdir . "*"));
+ $log_filenames = array_merge($log_filenames, glob($logdir . '*'));
}
}
@@ -91,22 +92,28 @@ function getlogs($logdir, $log_extentions = array('log')) {
$pfb_logtypes = array( 'defaultlogs' => array('name' => 'Log Files',
'logdir' => "{$pfb['logdir']}/",
- 'logs' => array("pfblockerng.log", "error.log", "geoip.log", "maxmind_ver"),
+ 'logs' => array('pfblockerng.log', 'error.log', 'dnsbl.log', 'extras.log', 'maxmind_ver'),
'download' => TRUE,
'clear' => TRUE
),
'masterfiles' => array('name' => 'Masterfiles',
'logdir' => "{$pfb['dbdir']}/",
- 'logs' => array("masterfile", "mastercat"),
+ 'logs' => array('masterfile', 'mastercat'),
'download' => TRUE,
'clear' => FALSE
),
- 'originallogs' => array('name' => 'Original Files',
+ 'originallogs' => array('name' => 'Original IP Files',
'ext' => array('orig', 'raw'),
'logdir' => "{$pfb['origdir']}/",
'download' => TRUE,
'clear' => TRUE
),
+ 'origdnslogs' => array('name' => 'Original DNS Files',
+ 'ext' => array('orig', 'raw'),
+ 'logdir' => "{$pfb['dnsorigdir']}/",
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
'denylogs' => array('name' => 'Deny Files',
'ext' => 'txt',
'txt' => 'deny',
@@ -114,6 +121,13 @@ $pfb_logtypes = array( 'defaultlogs' => array('name' => 'Log Files',
'download' => TRUE,
'clear' => TRUE
),
+ 'dnsbl' => array('name' => 'DNSBL Files',
+ 'ext' => array('txt', 'ip'),
+ 'txt' => 'dnsbl',
+ 'logdir' => "{$pfb['dnsdir']}/",
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
'permitlogs' => array('name' => 'Permit Files',
'ext' => 'txt',
'txt' => 'permit',
@@ -151,13 +165,19 @@ $pfb_logtypes = array( 'defaultlogs' => array('name' => 'Log Files',
'logdir' => "{$pfb['ccdir']}/",
'download' => TRUE,
'clear' => FALSE
+ ),
+ 'unbound' => array('name' => 'Unbound',
+ 'ext' => 'conf',
+ 'logdir' => "{$pfb['dnsbldir']}/",
+ 'download' => TRUE,
+ 'clear' => FALSE
)
);
// Check logtypes
$logtypeid = 'defaultlogs';
if (isset($_POST['logtype'])) {
- $logtypeid = $_POST['logtype'];
+ $logtypeid = htmlspecialchars($_POST['logtype']);
} elseif (isset($_GET['logtype'])) {
$logtypeid = htmlspecialchars($_GET['logtype']);
}
@@ -165,17 +185,17 @@ if (isset($_POST['logtype'])) {
// Check if POST has been set
if (isset($_POST['file'])) {
clearstatcache();
- $pfb_logfilename = $_POST['file'];
+ $pfb_logfilename = htmlspecialchars($_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") . ".|";
+ 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") . ".|";
+ echo "|1|" . gettext('Failed to read log file') . ".|";
} else {
$data = base64_encode($data);
echo "|0|" . $pfb_logfilename . "|" . $data . "|";
@@ -186,7 +206,7 @@ if (isset($_POST['file'])) {
}
if (isset($_POST['logFile'])) {
- $s_logfile = $_POST['logFile'];
+ $s_logfile = htmlspecialchars($_POST['logFile']);
// Clear selected file
if (isset($_POST['clear'])) {
@@ -201,32 +221,33 @@ if (isset($_POST['logFile'])) {
header('Pragma: ');
header('Cache-Control: ');
} else {
- header("Pragma: private");
- header("Cache-Control: private, must-revalidate");
+ 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));
+ 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 = "";
+ $s_logfile = '';
}
-$pgtitle = gettext("pfBlockerNG: Log Browser");
-include_once("head.inc");
+$pgtitle = gettext('pfBlockerNG: Log Browser');
+include_once('head.inc');
?>
<body link="#000000" vlink="#0000CC" alink="#000000">
<?php
-include_once("fbegin.inc");
+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[
@@ -238,7 +259,7 @@ if ($input_errors) {
jQuery("#fbTarget").html("");
jQuery.ajax(
- "<?=$_SERVER['SCRIPT_NAME'];?>", {
+ "/pfblockerng/pfblockerng_log.php", {
type: 'POST',
data: "instance=" + jQuery("#instance").val() + "&action=load&file=" + jQuery("#logFile").val(),
complete: loadComplete
@@ -271,7 +292,7 @@ if ($input_errors) {
</script>
<?php
-echo("<form action='" . $_SERVER['PHP_SELF'] . "' method='post' id='formbrowse'>");
+echo("<form action='/pfblockerng/pfblockerng_log.php' method='post' id='formbrowse'>");
if ($savemsg) {
print_info_box($savemsg);
}
@@ -282,22 +303,16 @@ if ($savemsg) {
<td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml&amp;id=0");
+ $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml");
$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("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml");
$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("P.S."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&id=0");
+ $tab_array[] = array(gettext("DNSBL"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml");
+ $tab_array[] = array(gettext("Country"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml");
$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");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml");
display_top_tabs($tab_array, true);
?>
</td>
@@ -311,9 +326,9 @@ if ($savemsg) {
<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 :"); ?> &nbsp;
- <a href='/firewall_aliases.php' target="_blank"><?php echo gettext("Firewall Alias"); ?></a> &nbsp;
- <a href='/firewall_rules.php' target="_blank"><?php echo gettext("Firewall Rules"); ?></a> &nbsp;
+ <td colspan="3" class="vncell" align="left"><?php echo gettext("LINKS :"); ?>&emsp;
+ <a href='/firewall_aliases.php' target="_blank"><?php echo gettext("Firewall Alias"); ?></a>&emsp;
+ <a href='/firewall_rules.php' target="_blank"><?php echo gettext("Firewall Rules"); ?></a>&emsp;
<a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br /></td>
</tr>
<tr>
@@ -324,16 +339,16 @@ if ($savemsg) {
$clearable = FALSE;
$downloadable = FALSE;
foreach ($pfb_logtypes as $id => $logtype) {
- $selected = "";
+ $selected = '';
if ($id == $logtypeid) {
- $selected = " selected";
+ $selected = ' selected';
$clearable = $logtype['clear'];
$downloadable = $logtype['download'];
}
echo("<option value='" . $id . "'" . $selected . ">" . $logtype['name'] . "</option>\n");
}
?>
- </select>&nbsp;&nbsp;<?php echo gettext('Choose which type of log/file you want to view.'); ?>
+ </select>&emsp;<?php echo gettext('Choose which type of log/file you want to view.'); ?>
</td>
</tr>
<tr>
@@ -347,14 +362,14 @@ if ($savemsg) {
$logs = getlogs($pfb_logtypes[$logtypeid]['logdir'], $pfb_logtypes[$logtypeid]['ext']);
}
foreach ($logs as $log) {
- $selected = "";
+ $selected = '';
if ($log == $pfb_logfilename) {
- $selected = " selected";
+ $selected = ' selected';
}
echo("<option value='" . $pfb_logtypes[$logtypeid]['logdir'] . $log . "'" . $selected . ">" . $log . "</option>\n");
}
?>
- </select>&nbsp;&nbsp;<?php echo gettext('Choose which log/file you want to view.'); ?>
+ </select>&emsp;<?php echo gettext('Choose which log/file you want to view.'); ?>
</td>
</tr>
<tr>
@@ -424,6 +439,6 @@ if ($savemsg) {
//]]>
</script>
<?php endif; ?>
-<?php include("fend.inc"); ?>
+<?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
index 03b86dce..b5faa4ef 100644
--- a/config/pfblockerng/pfblockerng_sync.xml
+++ b/config/pfblockerng/pfblockerng_sync.xml
@@ -1,20 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
-<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<!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) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Based upon pfblocker for pfSense
- Copyright (C) 2011 Marcello Coutinho
+ Copyright (c) 2011 Marcello Coutinho
All rights reserved.
*/
/* ========================================================================== */
@@ -57,12 +56,12 @@
<name>pfBlockerNG</name>
<tooltiptext>Configure pfBlockerNG</tooltiptext>
<section>Services</section>
- <url>pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>pkg_edit.php?xml=pfblockerng.xml</url>
</menu>
<tabs>
<tab>
<text>General</text>
- <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
</tab>
<tab>
<text>Update</text>
@@ -74,47 +73,23 @@
</tab>
<tab>
<text>Reputation</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml</url>
</tab>
<tab>
<text>IPv4</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url>
</tab>
<tab>
<text>IPv6</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url>
</tab>
<tab>
- <text>Top 20</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&amp;id=0</url>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
</tab>
<tab>
- <text>Africa</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Asia</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Europe</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>N.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Oceania</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>S.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>P.S.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
</tab>
<tab>
<text>Logs</text>
@@ -122,7 +97,7 @@
</tab>
<tab>
<text>Sync</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml</url>
<active/>
</tab>
</tabs>
@@ -133,8 +108,8 @@
</field>
<field>
<fielddescr>LINKS</fielddescr>
- <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp;
- <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
</description>
<type>info</type>
</field>
@@ -163,9 +138,9 @@
<size>5</size>
</field>
<field>
- <fielddescr><![CDATA[Disable 'General Tab' sync]]></fielddescr>
+ <fielddescr><![CDATA[Disable 'General/DNSBL tab' sync]]></fielddescr>
<fieldname>syncinterfaces</fieldname>
- <description>When selected, the 'General' Tab Customizations will not be sync'd</description>
+ <description>When selected, the 'General' tab and 'DNSBL' tab customizations will not be sync'd</description>
<type>checkbox</type>
</field>
<field>
@@ -194,9 +169,9 @@
</options>
</rowhelperfield>
<rowhelperfield>
- <fielddescr>Target IP Address</fielddescr>
+ <fielddescr>Target IP/Hostname</fielddescr>
<fieldname>varsyncipaddress</fieldname>
- <description><![CDATA[IP Address of the destination host.]]></description>
+ <description><![CDATA[IP Address or Hostname of the destination host.]]></description>
<type>input</type>
<size>15</size>
</rowhelperfield>
@@ -224,23 +199,21 @@
</rowhelper>
</field>
<field>
- <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
'Force Update'</center>]]></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>
+ <![CDATA[
pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
</custom_php_validation_command>
<custom_php_resync_config_command>
+ <![CDATA[
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_threats.php b/config/pfblockerng/pfblockerng_threats.php
new file mode 100644
index 00000000..d02d100f
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_threats.php
@@ -0,0 +1,142 @@
+<?php
+/*
+ pfBlockerNG_threats.php
+
+ pfBlockerNG
+ Copyright (c) 2015 BBcan177@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('Threat Source Lookup'));
+require('guiconfig.inc');
+
+if (isset($_REQUEST['host'])) {
+ $host = htmlspecialchars($_REQUEST['host']);
+}
+
+if (isset($_REQUEST['domain'])) {
+ $domain = htmlspecialchars($_REQUEST['domain']);
+}
+
+include('head.inc');
+include('fbegin.inc');
+?>
+
+<tr>
+ <td>
+ <div id="mainarea">
+ <body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0" summary="tabcont">
+ <tbody>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Threat"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listr"><font size="3"><?php echo " {$host}{$domain}"; ?></font></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vncell"></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Threat Lookups"); ?></td>
+ </tr>
+ <tr>
+ <td width="14%" valign="top" class="vncell"></td>
+ <td width="86%" class="listr">
+ <?=gettext("NOTE:");?><br /><br />
+ <?=gettext("The following links are to external services, so their reliability cannot be guaranteed.");?><br />
+ <?=gettext("It is also recommended to open these links in a different Browser.");?><br /><br />
+
+ <?php if (isset($_REQUEST['host'])) { ?>
+
+ <a target="_blank" href="http://www.ipvoid.com/scan/<?php echo $host; ?>/">
+ <?=gettext("IPVOID");?></a><br />
+ <a target="_blank" href="http://www.tcpiputils.com/browse/ip-address/<?php echo $host; ?>/">
+ <?=gettext("TCPUtils");?></a><br />
+ <a target="_blank" href="https://www.herdprotect.com/ip-address-<?php echo $host; ?>.aspx">
+ <?=gettext("Herd Protect");?></a><br />
+ <a target="_blank" href="https://www.senderbase.org/lookup/ip/?search_string=<?php echo $host; ?>">
+ <?=gettext("SenderBase");?></a><br />
+ <a target="_blank" href="http://www.ip-tracker.org/locator/ip-lookup.php?ip=<?php echo $host; ?>">
+ <?=gettext("IP Tracker");?></a><br />
+ <a target="_blank" href="https://www.fortiguard.com/ip_rep/index.php?data=/<?php echo $host; ?>?">
+ <?=gettext("FortiGuard");?></a><br />
+ <a target="_blank" href="https://www.projecthoneypot.org/ip_<?php echo $host; ?>">
+ <?=gettext("Project HoneyPot");?></a><br />
+ <a target="_blank" href="https://www.virustotal.com/en/ip-address/<?php echo $host; ?>/information">
+ <?=gettext("VirusTotal Info");?></a><br />
+ <a target="_blank" href="https://www.mcafee.com/threat-intelligence/ip/default.aspx?ip=<?php echo $host; ?>">
+ <?=gettext("McAfee Threat Center");?></a><br />
+ <a target="_blank" href="https://sitecheck.sucuri.net/results/<?php echo $host; ?>">
+ <?=gettext("Securi SiteCheck");?></a><br />
+ <a target="_blank" href="https://www.dshield.org/ipinfo.html?IP=<?php echo $host; ?>">
+ <?=gettext("DShield Threat Lookup");?></a><br />
+ <a target="_blank" href="https://isc.sans.edu/ipinfo.html?ip=<?php echo $host; ?>">
+ <?=gettext("Internet Storm Center");?></a><br />
+ <a target="_blank" href="https://www.mywot.com/en/scorecard/<?php echo $host; ?>">
+ <?=gettext("Web of Trust (WOT) Scorecard");?></a><br />
+ <a target="_blank" href="https://quttera.com/sitescan/<?php echo $host; ?>">
+ <?=gettext("Quattera");?></a><br />
+ <a target="_blank" href="https://www.iblocklist.com/search.php?string=<?php echo $host; ?>">
+ <?=gettext("I-Block List");?></a><br />
+ <p/>
+
+ <?=gettext("Mail Server DNSRBL Lookups");?><br /><br />
+ <a target="_blank" href="https://senderscore.org/lookup.php?lookup=<?php echo $host; ?>&ipLookup=Go">
+ <?=gettext("SenderScore");?></a><br />
+ <a target="_blank" href="https://www.spamhaus.org/query/bl?ip=<?php echo $host; ?>">
+ <?=gettext("Spamhaus Blocklist");?></a><br />
+ <a target="_blank" href="https://www.spamcop.net/w3m?action=checkblock&ip=<?php echo $host; ?>">
+ <?=gettext("SPAMcop Blocklist");?></a><br />
+ <a target="_blank" href="http://multirbl.valli.org/lookup/<?php echo $host; ?>.html">
+ <?=gettext("multirbl RBL Lookup");?></a><br />
+ <a target="_blank" href="https://mxtoolbox.com/SuperTool.aspx?action=blacklist%3a<?php echo $host; ?>&run=toolpage">
+ <?=gettext("MXToolbox");?></a><br />
+
+ <?php } else { ?>
+
+ <a target="_blank" href="http://www.alexa.com/siteinfo/<?php echo $domain; ?>">
+ <?=gettext("Alexa");?></a><br />
+ <a target="_blank" href="https://www.c-sirt.org/en/incidents-on-domain/<?php echo $domain; ?>">
+ <?=gettext("C-SIRT");?></a><br />
+ <a target="_blank" href="https://www.herdprotect.com/domain-<?php echo $domain; ?>.aspx">
+ <?=gettext("HerdProtect");?></a><br />
+ <a target="_blank" href="https://sitecheck.sucuri.net/results/<?php echo $domain; ?>">
+ <?=gettext("Sucuri");?></a><br />
+
+ <?php } ?>
+
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </td>
+</tr>
+
+<?php include('fend.inc'); ?>
+</body>
+</html> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_top20.xml b/config/pfblockerng/pfblockerng_top20.xml
index 030c1385..6200a6a9 100644
--- a/config/pfblockerng/pfblockerng_top20.xml
+++ b/config/pfblockerng/pfblockerng_top20.xml
@@ -1,20 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
-<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<!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) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Based upon pfblocker for pfSense
- Copyright (C) 2011 Marcello Coutinho
+ Copyright (c) 2011 Marcello Coutinho
All rights reserved.
*/
/* ========================================================================== */
@@ -57,12 +56,12 @@
<name>pfBlockerNG</name>
<tooltiptext>Configure pfblockerNG</tooltiptext>
<section>Firewall</section>
- <url>pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>pkg_edit.php?xml=pfblockerng.xml</url>
</menu>
<tabs>
<tab>
<text>General</text>
- <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
</tab>
<tab>
<text>Update</text>
@@ -74,48 +73,64 @@
</tab>
<tab>
<text>Reputation</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml</url>
</tab>
<tab>
<text>IPv4</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url>
</tab>
<tab>
<text>IPv6</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url>
+ </tab>
+ <tab>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
+ </tab>
+ <tab>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
</tab>
<tab>
<text>Top 20</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
+ <tab_level>2</tab_level>
<active/>
</tab>
<tab>
<text>Africa</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml</url>
+ <tab_level>2</tab_level>
</tab>
<tab>
<text>Asia</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml</url>
+ <tab_level>2</tab_level>
</tab>
<tab>
<text>Europe</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml</url>
+ <tab_level>2</tab_level>
</tab>
<tab>
- <text>N.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
+ <text>North America</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml</url>
+ <tab_level>2</tab_level>
</tab>
<tab>
<text>Oceania</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml</url>
+ <tab_level>2</tab_level>
</tab>
<tab>
- <text>S.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
+ <text>South America</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml</url>
+ <tab_level>2</tab_level>
</tab>
<tab>
- <text>P.S.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ <text>Proxy and Satellite</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml</url>
+ <tab_level>2</tab_level>
</tab>
<tab>
<text>Logs</text>
@@ -123,12 +138,12 @@
</tab>
<tab>
<text>Sync</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml</url>
</tab>
</tabs>
<fields>
<field>
- <name><![CDATA[TOP 20 - Spammer Countries&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Geolite Data by Maxmind Inc. - ISO 3166)]]></name>
+ <name><![CDATA[TOP 20 - Spammer Countries&emsp; (Geolite Data by Maxmind Inc. - ISO 3166)]]></name>
<type>listtopic</type>
</field>
<field>
@@ -144,15 +159,15 @@
</field>
<field>
<fielddescr>LINKS</fielddescr>
- <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp;
- <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<a href="diag_logs_filter.php">Firewall Logs</a>]]>
</description>
<type>info</type>
</field>
<field>
<fieldname>countries4</fieldname>
<fielddescr><![CDATA[<strong><center>Top 20<br /> Spammer Countries</center></strong><br />
- <center>Use CTRL + CLICK to unselect countries</center>]]>
+ <center>Use CTRL + CLICK to select/unselect countries</center>]]>
</fielddescr>
<description><![CDATA[<center><br />IPv4 Countries</center>]]></description>
<type>select</type>
@@ -176,7 +191,7 @@
<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>
+ <option><name>Chile-CL</name><value>CL</value></option>
</options>
<size>20</size>
<multiple/>
@@ -247,11 +262,9 @@
<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 />]]>
+ <font color='red'>Note: </font><ul>When manually creating 'Alias' type firewall rules; <strong>Do not add</strong> (pfB_) to the
+ start of the rule description, use (pfb_) (Lowercase prefix). Manually created 'Alias' rules with 'pfB_' in the
+ description will be auto-removed by package when 'Auto' rules are defined.</ul>]]>
</description>
<fieldname>action</fieldname>
<type>select</type>
@@ -289,8 +302,8 @@
</field>
<field>
<type>info</type>
- <description><![CDATA[<font color='red'>Note: </font>In general Auto-Rules are created as follows:<br />
- <ul>Inbound &nbsp;&nbsp;- 'any' port, 'any' protocol and 'any' destination<br />
+ <description><![CDATA[<font color='red'>Note: </font>In general, Auto-Rules are created as follows:<br />
+ <ul>Inbound &emsp;- 'any' port, 'any' protocol and 'any' destination<br />
Outbound - 'any' port, 'any' protocol and 'any' destination address in the lists</ul>
Configuring the Adv. Inbound Rule settings, will allow for more customization of the Inbound Auto-Rules.<br />
<strong>Select the pfSense 'Port' and/or 'Destination' Alias below:</strong>]]>
@@ -351,7 +364,8 @@
<field>
<fielddescr>Custom Protocol</fielddescr>
<fieldname>autoproto</fieldname>
- <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).]]></description>
+ <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).<br />
+ Do not use 'any' with Adv. Inbound Rules as it will bypass these settings!]]></description>
<type>select</type>
<options>
<option><name>any</name><value></value></option>
@@ -363,23 +377,21 @@
<default_value></default_value>
</field>
<field>
- <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
'Force Update'</center>]]></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>
+ <![CDATA[
pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
</custom_php_validation_command>
<custom_php_resync_config_command>
+ <![CDATA[
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
index 7911a4e6..8a04f843 100644
--- a/config/pfblockerng/pfblockerng_update.php
+++ b/config/pfblockerng/pfblockerng_update.php
@@ -3,7 +3,7 @@
/* pfBlockerNG_Update.php
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Portions of this code are based on original work done for
@@ -11,8 +11,9 @@
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
+ Copyright (c) 2015 Electric Sheep Fencing, LLC. All rights reserved.
+ Copyright (c) 2005 Colin Smith
+ Copyright (c) 2004-2005 Scott Ullrich
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -39,18 +40,18 @@
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");
+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.
+// Collect pfBlockerNG log file and post live output to terminal window.
function pfbupdate_output($text) {
- $text = preg_replace("/\n/", "\\n", $text);
+ $text = str_replace("\n", "\\n", $text);
echo "\n<script type=\"text/javascript\">";
echo "\n//<![CDATA[";
echo "\nthis.document.forms[0].pfb_output.value = \"" . $text . "\";";
@@ -61,9 +62,9 @@ function pfbupdate_output($text) {
ob_flush();
}
-// Post Status Message to Terminal window.
+// Post status message to terminal window.
function pfbupdate_status($status) {
- $status = preg_replace("/\n/", "\\n", $status);
+ $status = str_replace("\n", "\\n", $status);
echo "\n<script type=\"text/javascript\">";
echo "\n//<![CDATA[";
echo "\nthis.document.forms[0].pfb_status.value=\"" . $status . "\";";
@@ -78,11 +79,10 @@ function pfbupdate_status($status) {
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"));
+ // Query for any active pfBlockerNG CRON jobs
+ exec('/bin/ps -wx', $result_cron);
+ if (preg_grep("/pfblockerng[.]php\s+?(cron|update)/", $result_cron)) {
+ pfbupdate_status(gettext("Force {$type} Terminated - Failed due to Active Running Task. Click 'View' for running process"));
exit;
}
@@ -90,103 +90,62 @@ function pfb_cron_update($type) {
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";
+ // Update status window with correct task
+ if ($type == 'update') {
+ pfbupdate_status(gettext('Running Force Update Task'));
+ } elseif ($type == 'reload') {
+ $reload_type = htmlspecialchars($_POST['rmode']);
+ pfbupdate_status(gettext("Running Force Reload Task - {$reload_type}"));
+
+ switch ($reload_type) {
+ case 'IP':
+ $type = 'updateip';
+ break;
+ case 'DNSBL':
+ $type = 'updatednsbl';
+ rmdir_recursive("{$pfb['dnsdir']}");
+ break;
+ case 'All':
+ default:
+ $type = 'update';
+ rmdir_recursive("{$pfb['dnsdir']}");
+ }
} else {
- pfbupdate_status(gettext("Running Force CRON Task"));
+ pfbupdate_status(gettext('Running Force CRON Task'));
}
// Remove any existing pfBlockerNG CRON Jobs
- install_cron_job("pfblockerng.php cron", false);
+ install_cron_job('pfblockerng.php cron', false);
- // Execute PHP Process in the Background
+ // 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( array ("\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();
- }
- }
+ // Execute Live Tail function
+ pfb_livetail($pfb['log'], 'force');
}
-$pgtitle = gettext("pfBlockerNG: Update");
-include_once("head.inc");
+$pgtitle = gettext('pfBlockerNG: Update');
+include_once('head.inc');
+include_once('fbegin.inc');
?>
<body link="#000000" vlink="#0000CC" alink="#000000">
-<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
-<?php include_once("fbegin.inc"); ?>
-
+<form action="/pfblockerng/pfblockerng_update.php" method="post">
<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&amp;id=0");
+ $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml");
$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("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml");
$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("P.S."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&id=0");
+ $tab_array[] = array(gettext("DNSBL"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml");
+ $tab_array[] = array(gettext("Country"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml");
$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");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml");
display_top_tabs($tab_array, true);
?>
</td>
@@ -195,9 +154,9 @@ include_once("head.inc");
<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 :"); ?>&nbsp;
- <a href='/firewall_aliases.php' target="_blank"><?php echo gettext("Firewall Alias"); ?></a>&nbsp;
- <a href='/firewall_rules.php' target="_blank"><?php echo gettext("Firewall Rules"); ?></a>&nbsp;
+ <td colspan="2" class="vncell" align="left"><?php echo gettext("LINKS :"); ?>&emsp;
+ <a href='/firewall_aliases.php' target="_blank"><?php echo gettext("Firewall Alias"); ?></a>&emsp;
+ <a href='/firewall_rules.php' target="_blank"><?php echo gettext("Firewall Rules"); ?></a>&emsp;
<a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br />
</td>
</tr>
@@ -207,6 +166,7 @@ include_once("head.inc");
<tr>
<td colspan="2" class="listr">
<?php
+
if ($pfb['enable'] == 'on') {
/* Legend - Time variables
@@ -293,11 +253,11 @@ include_once("head.inc");
<font size=\"3\"><span class=\"red\">&nbsp;{$nextcron}&nbsp;</span></font> time remaining.";
// Query for any active pfBlockerNG CRON jobs
- exec ('/bin/ps -wax', $result_cron);
- if (preg_grep("/pfblockerng[.]php\s+cron/", $result_cron)) {
- echo "<font size=\"2\"><span class=\"red\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
- Active pfBlockerNG CRON Job </span></font>&nbsp;&nbsp;";
- echo "<img src = '/themes/{$g['theme']}/images/icons/icon_pass.gif' width='15' height='15'
+ exec('/bin/ps -wax', $result_cron);
+ if (preg_grep("/pfblockerng[.]php\s+?(cron|update)/", $result_cron)) {
+ echo "<font size=\"2\"><span class=\"red\">&emsp;&emsp;
+ Active pfBlockerNG CRON Job </span></font>&emsp;";
+ echo "<img src = '/themes/{$g['theme']}/images/icons/icon_pass.gif' alt='' 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 time remaining";
@@ -331,7 +291,10 @@ include_once("head.inc");
<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");?>" />
+ title="<?=gettext("Run Force Reload");?>" />&emsp;<?=gettext("Reload Options:");?>
+ <input name="rmode" type="radio" value="All" <?php echo 'checked'; ?> /><?=gettext("All");?>
+ <input name="rmode" type="radio" value="IP" /><?=gettext("IP");?>
+ <input name="rmode" type="radio" value="DNSBL" /><?=gettext("DNSBL"); ?>
</td>
</tr>
<tr>
@@ -342,7 +305,7 @@ include_once("head.inc");
</tr>
<tr>
<td colspan="2" class="listr"><?php echo gettext("Selecting 'Live Log Viewer' will allow viewing a running Cron Update"); ?></td>
- </tr>
+ </tr>
<tr>
<td colspan="2" class="vncell">
<!-- Log Viewer Buttons -->
@@ -350,8 +313,8 @@ include_once("head.inc");
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 "&nbsp;&nbsp;" . gettext(" Select 'view' to open ") . "<strong>" . gettext(' pfBlockerNG ') . "</strong>" .
- gettext(" Log. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Select 'End View' to terminate the viewer.)"); ?><br /><br />
+ <?php echo "&emsp;" . gettext(" Select 'view' to open ") . "<strong>" . gettext(' pfBlockerNG ') . "</strong>" .
+ gettext(" Log. &emsp; (Select 'End View' to terminate the viewer.)"); ?><br /><br />
</td>
</tr>
<tr>
@@ -371,83 +334,38 @@ include_once("head.inc");
</div>
<?php
-include("fend.inc");
+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
+// Execute the viewer output window
+if (isset($_POST['pfbview'])) {
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( array ("\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);
- }
- }
+ pfb_livetail($pfb['log'], 'view');
}
-// End the Viewer output Window
+// End the viewer output Window
if (isset($_POST['pfbviewcancel'])) {
- clearstatcache(false,$pfb['log']);
+ clearstatcache(false, $pfb['log']);
ob_flush();
flush();
fclose("{$pfb['log']}");
}
// Execute a Force Update
-if (isset($_POST['pfbupdate']) && $pfb['enable'] == "on") {
+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") {
+// 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") {
- // Set 'Reuse' Flag for Reload process
- $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = "on";
- write_config("pfBlockerNG: Executing Force Reload");
+// Execute a reload of all aliases and lists
+if (isset($_POST['pfbreload']) && $pfb['enable'] == 'on') {
+ // Set 'Reuse' flag for reload process
+ $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = 'on';
+ write_config('pfBlockerNG: Executing Force Reload');
pfb_cron_update(reload);
}
diff --git a/config/pfblockerng/pfblockerng_v4lists.xml b/config/pfblockerng/pfblockerng_v4lists.xml
index 00747a24..9ef3626b 100644
--- a/config/pfblockerng/pfblockerng_v4lists.xml
+++ b/config/pfblockerng/pfblockerng_v4lists.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
-<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
<packagegui>
<copyright>
<![CDATA[
@@ -9,14 +9,15 @@
pfBlockerNG_v4lists.xml
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Based upon pfblocker for pfSense
- Copyright (C) 2011 Marcello Coutinho
+ Copyright (c) 2011 Marcello Coutinho
- part of pfSense (http://www.pfSense.com)
- Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com>
+ part of pfSense (http://www.pfSense.org)
+ Copyright (c) 2015 Electric Sheep Fencing, LLC. All rights reserved.
+ Copyright (c) 2004-2005 Scott Ullrich
All rights reserved.
*/
/* ========================================================================== */
@@ -64,7 +65,7 @@
<tabs>
<tab>
<text>General</text>
- <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
<tooltiptext></tooltiptext>
</tab>
<tab>
@@ -77,48 +78,24 @@
</tab>
<tab>
<text>Reputation</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml</url>
</tab>
<tab>
<text>IPv4</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url>
<active/>
</tab>
<tab>
<text>IPv6</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml</url>
</tab>
<tab>
- <text>Top 20</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&amp;id=0</url>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
</tab>
<tab>
- <text>Africa</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Asia</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Europe</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>N.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Oceania</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>S.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>P.S.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
</tab>
<tab>
<text>Logs</text>
@@ -126,51 +103,50 @@
</tab>
<tab>
<text>Sync</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml</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>
- <addtext>Add a new Alias</addtext>
- <movable>on</movable>
- </adddeleteeditpagefields>
+ <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>
+ <addtext>Add a new Alias</addtext>
+ <movable>on</movable>
+ </adddeleteeditpagefields>
<fields>
<field>
- <name><![CDATA[IPv4 Network ranges / CIDR lists &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ <name><![CDATA[IPv4 - &emsp; Run 'Force Update' to deploy new Settings.&emsp;
(When Removing or Re-configuring Lists a 'Reload' is recommended.)]]></name>
<type>listtopic</type>
</field>
<field>
<fielddescr>LINKS</fielddescr>
- <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp;
- <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<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 Alias Name.<br />
- Example: Badguys<br />
+ <description><![CDATA[Enter Alias Name ( 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 />]]>
@@ -186,37 +162,35 @@
</field>
<field>
<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 />
- &nbsp;&nbsp;http(s)://127.0.0.1/NAME_OF_FILE &nbsp;&nbsp;<strong>or</strong>&nbsp;&nbsp;
- /usr/local/www/NAME_OF_FILE &nbsp;&nbsp; (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><![CDATA[<strong><u>'Format'</u></strong>: Select the Format type.<br /><br />
+ <strong><u>'State'</u></strong>: Select the run state.<br /><br />
+ <strong><u>'Source'</u></strong>:
+ <ul><li><strong>'URL'</strong>: External link to source
+ &emsp;(ie: <a target="_blank" href='https://rules.emergingthreats.net/blockrules/compromised-ips.txt'>ET Compromised</a>,
+ <a target="_blank" href='https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt'>ET Blocked</a>,
+ <a target="_blank" href='https://www.spamhaus.org/drop/drop.txt'>Spamhaus Drop</a>)</li></ul>
+ <ul><li><strong>'Local File'</strong>: http(s)://127.0.0.1/filename
+ &emsp;<strong>or</strong>&emsp; /var/db/pfblockerng/filename</li></ul>
+ <ul><li><strong>'Country code'</strong>: /usr/pbi/pfblockerng-amd64/share/GeoIP/cc/US_v4.txt
+ &emsp;(Change 'US' to required code)</li></ul>
+ <ul><li><strong>'Whois'</strong>: Domain name or AS&emsp;(ie: facebook.com or AS13414)
+ &emsp;( <a target="_blank" href='https://asn.cymru.com/'>Click for ASN Lookup</a> )</li></ul>
+ <strong><u>'Header/Label'</u></strong>: This field must be <u>unique.</u> This names the file and is referenced in the widget.
+ &emsp;(ie: Spamhaus_drop, Spamhaus_edrop)<br /><br />]]>
</description>
</field>
<field>
<fielddescr><![CDATA[<strong>IPv4</strong> Lists]]></fielddescr>
- <description><![CDATA[<br /><strong>'Format'</strong> - Select the file format that URL will retrieve.<br />
- <ul><li><strong>'txt'</strong> Plain txt Lists</li>
- <li><strong>'gz'</strong> - IBlock GZ Lists in Range Format only</li>
- <li><strong>'gz_2'</strong> - Other GZ Lists in IP or CIDR only</li>
- <li><strong>'gz_lg'</strong> - Large IBlock GZ Lists in Range Format only</li>
- <li><strong>'zip'</strong> - ZIP'd Lists</li>
- <li><strong>'block'</strong>- IP x.x.x.0 Block type</li>
- <li><strong>'html'</strong> - Web Links</li>
- <li><strong>'xlsx'</strong> - Excel Lists</li>
- <li><strong>'rsync'</strong> - RSync Lists</li>
- <li><strong>'ET' IQRisk</strong> - Only</li></ul>
- <strong>'State'</strong> - Select the Run State for each list<br />
+ <description><![CDATA[<br /><strong>'Format'</strong>: Select the file format that URL will retrieve.<br />
+ <ul><li><strong>'auto'</strong>&emsp;- Default parser</li>
+ <li><strong>'regex'</strong> - 'Regex' style parsing (ie: html Lists)</li>
+ <li><strong>'whois'</strong> - Convert a Domain name or AS into its respective IP addresses.</li>
+ <li><strong>'rsync'</strong> - RSync Lists</li></ul>
+ <strong>'State'</strong>: Select the Run State for each list<br />
<ul><li><strong>'ON/OFF'</strong> - Enabled / Disabled</li>
- <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:
+ <li><strong>'HOLD'</strong> - Once a List has been Downloaded, list will remain Static</li>
+ <li><strong>'FLEX'</strong> - Not Recommended - Allow downgraded SSL connections</li></ul>
+ <strong>'Note'</strong>: Source lists musts follow 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>]]>
@@ -228,17 +202,12 @@
<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>Auto</name><value>auto</value></option>
+ <option><name>Regex</name><value>regex</value></option>
+ <option><name>Whois</name><value>whois</value></option>
<option><name>RSync</name><value>rsync</value></option>
- <option><name>ET</name><value>et</value></option>
</options>
+ <default_value>auto</default_value>
</rowhelperfield>
<rowhelperfield>
<fielddescr>State</fielddescr>
@@ -248,16 +217,18 @@
<option><name>ON</name><value>Enabled</value></option>
<option><name>OFF</name><value>Disabled</value></option>
<option><name>HOLD</name><value>Hold</value></option>
+ <option><name>FLEX</name><value>Flex</value></option>
</options>
+ <default_value>Enabled</default_value>
</rowhelperfield>
<rowhelperfield>
- <fielddescr>URL or pfSense local file</fielddescr>
+ <fielddescr>Source</fielddescr>
<fieldname>url</fieldname>
<type>input</type>
<size>50</size>
</rowhelperfield>
<rowhelperfield>
- <fielddescr>Header</fielddescr>
+ <fielddescr>Header/Label</fielddescr>
<fieldname>header</fieldname>
<type>input</type>
<size>15</size>
@@ -296,11 +267,9 @@
<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 />]]>
+ <font color='red'>Note: </font><ul>When manually creating 'Alias' type firewall rules; <strong>Do not add</strong> (pfB_) to the
+ start of the rule description, use (pfb_) (Lowercase prefix). Manually created 'Alias' rules with 'pfB_' in the
+ description will be auto-removed by package when 'Auto' rules are defined.</ul>]]>
</description>
<fieldname>action</fieldname>
<type>select</type>
@@ -373,13 +342,24 @@
</options>
</field>
<field>
+ <fieldname>stateremoval</fieldname>
+ <fielddescr>States Removal</fielddescr>
+ <description>With the 'Kill States' option (General Tab), you can disable States removal for this Alias.</description>
+ <type>select</type>
+ <options>
+ <option><name>Enable</name><value>enabled</value></option>
+ <option><name>Disable</name><value>disabled</value></option>
+ </options>
+ <default_value>enabled</default_value>
+ </field>
+ <field>
<name>Advanced Inbound Firewall Rule Settings</name>
<type>listtopic</type>
</field>
<field>
<type>info</type>
- <description><![CDATA[<font color='red'>Note: </font>In general Auto-Rules are created as follows:<br />
- <ul>Inbound &nbsp;&nbsp;- 'any' port, 'any' protocol and 'any' destination<br />
+ <description><![CDATA[<font color='red'>Note: </font>&emsp;In general, Auto-Rules are created as follows:<br />
+ <ul>Inbound &emsp;- 'any' port, 'any' protocol and 'any' destination<br />
Outbound - 'any' port, 'any' protocol and 'any' destination address in the lists</ul>
Configuring the Adv. Inbound Rule settings, will allow for more customization of the Inbound Auto-Rules.<br />
<strong>Select the pfSense 'Port' and/or 'Destination' Alias below:</strong>]]>
@@ -440,7 +420,8 @@
<field>
<fielddescr>Custom Protocol</fielddescr>
<fieldname>autoproto</fieldname>
- <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).]]></description>
+ <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).<br />
+ Do not use 'any' with Adv. Inbound Rules as it will bypass these settings!]]></description>
<type>select</type>
<options>
<option><name>any</name><value></value></option>
@@ -456,14 +437,38 @@
<type>listtopic</type>
</field>
<field>
- <fielddescr>IPv4 Custom Address(es)</fielddescr>
+ <type>info</type>
+ <description><![CDATA[<font color='red'>Note: </font>&emsp;Custom List can be used in <strong>ONE</strong> of two ways:<br />
+ <ul>1. IPv4 addresses entered directly into the custom list, as per the required format.</ul>
+ <ul>2. Domain names or AS numbers, which will be converted into their respective IPv4 addresses.</ul>]]>
+ </description>
+ </field>
+ <field>
+ <fieldname>whois_convert</fieldname>
+ <description><![CDATA[Select to enable 'Domain/AS' conversion.
+ <font color='red'>DO NOT</font> mix IPs with Domains/ASs in this custom list.]]>
+ </description>
+ <fielddescr>Enable Domain/AS</fielddescr>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fielddescr>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 />
+ <description><![CDATA[Please limit the size of the Custom List as this is stored as 'Base64' format in the config.xml file.<br /><br />
+ <strong>Format IPv4:</strong><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]]>
+ RFC 1918 addresses may be used in a custom list.<br />
+ You may use "<strong>#</strong>" after any IP/CIDR/Range to add comments. ie: x.x.x.x # Safe IP Address<br /><br />
+ If you select the <strong>Domain/AS</strong> checkbox above, the custom list can <strong>only</strong>
+ be used for Domain names/AS's.<br /><br />
+ <strong>Format Domain/AS:</strong><br /><br />
+ One 'Domain' or 'AS' per line.<br />
+ Domains and/or ASs can be used in the same list.<br /><br />
+ Conversion of Domains/ASs utilize <a target="_blank" href="http://www.team-cymru.org/IP-ASN-mapping.html">Team CYMRU</a>
+ and the <a target="_blank" href="http://www.radb.net/">RADb</a> whois registry.<br />
+ Configure the 'update frequency', so that it does not <strong>abuse</strong> these free services.]]>
</description>
<type>textarea</type>
<cols>50</cols>
@@ -484,23 +489,21 @@
</options>
</field>
<field>
- <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
'Force Update'</center>]]></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>
+ <![CDATA[
pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
</custom_php_validation_command>
<custom_php_resync_config_command>
+ <![CDATA[
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
index 3e9dbe6f..e5f30caa 100644
--- a/config/pfblockerng/pfblockerng_v6lists.xml
+++ b/config/pfblockerng/pfblockerng_v6lists.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
-<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
<packagegui>
<copyright>
<![CDATA[
@@ -9,14 +9,15 @@
pfBlockerNG_v6lists.xml
pfBlockerNG
- Copyright (C) 2015 BBcan177@gmail.com
+ Copyright (c) 2015 BBcan177@gmail.com
All rights reserved.
Based upon pfblocker for pfSense
- Copyright (C) 2011 Marcello Coutinho
+ Copyright (c) 2011 Marcello Coutinho
- part of pfSense (http://www.pfSense.com)
- Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com>
+ part of pfSense (http://www.pfSense.org)
+ Copyright (c) 2015 Electric Sheep Fencing, LLC. All rights reserved.
+ Copyright (c) 2004-2005 Scott Ullrich
All rights reserved.
*/
/* ========================================================================== */
@@ -64,7 +65,7 @@
<tabs>
<tab>
<text>General</text>
- <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
<tooltiptext></tooltiptext>
</tab>
<tab>
@@ -77,48 +78,24 @@
</tab>
<tab>
<text>Reputation</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml</url>
</tab>
<tab>
<text>IPv4</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml</url>
</tab>
<tab>
<text>IPv6</text>
- <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
+ <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&amp;id=0</url>
+ <text>DNSBL</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_dnsbl.xml</url>
</tab>
<tab>
- <text>Africa</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Asia</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Europe</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>N.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>Oceania</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>S.A.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
- </tab>
- <tab>
- <text>P.S.</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ <text>Country</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml</url>
</tab>
<tab>
<text>Logs</text>
@@ -126,50 +103,49 @@
</tab>
<tab>
<text>Sync</text>
- <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&amp;id=0</url>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml</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>
- <addtext>Add a new Alias</addtext>
- <movable>on</movable>
- </adddeleteeditpagefields>
+ <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>
+ <addtext>Add a new Alias</addtext>
+ <movable>on</movable>
+ </adddeleteeditpagefields>
<fields>
<field>
- <name>IPv6 Network ranges / CIDR lists</name>
+ <name><![CDATA[IPv6 - &emsp; Run 'Force Update' to deploy new Settings. &emsp;]]></name>
<type>listtopic</type>
</field>
<field>
<fielddescr>LINKS</fielddescr>
- <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp;
- <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a>&emsp;
+ <a href="/firewall_rules.php">Firewall Rules</a>&emsp;<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 Alias Name.<br />
- Example: Badguys<br />
+ <description><![CDATA[Enter Alias Name ( 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 />]]>
@@ -185,38 +161,33 @@
</field>
<field>
<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 />
- &nbsp;&nbsp;http(s)://127.0.0.1/NAME_OF_FILE &nbsp;&nbsp;<strong>or</strong>&nbsp;&nbsp;
- /usr/local/www/NAME_OF_FILE &nbsp;&nbsp; (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><![CDATA[<strong><u>'Format'</u></strong>: Select the Format type.<br /><br />
+ <strong><u>'State'</u></strong>: Select the run state.<br /><br />
+ <strong><u>'Source'</u></strong>:
+ <ul><li><strong>'URL'</strong>: External link to source
+ &emsp;(ie: <a target="_blank" href='https://lists.blocklist.de/lists/all.txt'>Blocklist.de</a>)</li></ul>
+ <ul><li><strong>'Local File'</strong>: http(s)://127.0.0.1/filename
+ &emsp;<strong>or</strong>&emsp; /var/db/pfblockerng/filename</li></ul>
+ <ul><li><strong>'Country code'</strong>: /usr/pbi/pfblockerng-amd64/share/GeoIP/cc/US_v6.txt
+ &emsp;(Change 'US' to required code)</li></ul>
+ <ul><li><strong>'Whois'</strong>: Domain name or AS&emsp;(ie: facebook.com or AS13414)
+ &emsp;( <a target="_blank" href='https://asn.cymru.com/'>Click for ASN Lookup</a> )</li></ul>
+ <strong><u>'Header/Label'</u></strong>: This field must be <u>unique.</u> This names the file and is referenced in the widget.
+ &emsp;(ie: Spamhaus_drop, Spamhaus_edrop)<br /><br />]]>
</description>
</field>
<field>
<fielddescr><![CDATA[<strong>IPv6</strong> Lists]]></fielddescr>
- <description><![CDATA[<br /><strong>'Format'</strong> - Select the file format that URL will retrieve.<br />
- <ul><li><strong>'txt'</strong> Plain txt Lists</li>
- <li><strong>'gz'</strong> - IBlock GZ Lists in Range Format only</li>
- <li><strong>'gz_2'</strong> - Other GZ Lists in IP or CIDR only</li>
- <li><strong>'zip'</strong> - ZIP'd Lists</li>
- <li><strong>'block'</strong>- IP x.x.x.0 Block type</li>
- <li><strong>'html'</strong> - Web Links</li>
- <li><strong>'xlsx'</strong> - Excel Lists</li>
- <li><strong>'rsync'</strong> - RSync Lists</li>
- <strong>'State'</strong> - Select the Run State for each list<br />
+ <description><![CDATA[<br /><strong>'Format'</strong>: Select the file format that URL will retrieve.<br />
+ <ul><li><strong>'auto'</strong>&emsp;- Default parser</li>
+ <li><strong>'regex'</strong> - 'Regex' style parsing (ie: html Lists)</li>
+ <li><strong>'whois'</strong> - Convert a Domain name or AS into its respective IP addresses.</li>
+ <li><strong>'rsync'</strong> - RSync Lists</li></ul>
+ <strong>'State'</strong>: Select the Run State for each list<br />
<ul><li><strong>'ON/OFF'</strong> - Enabled / Disabled</li>
- <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>]]>
+ <li><strong>'HOLD'</strong> - Once a List has been Downloaded, list will remain Static</li>
+ <li><strong>'FLEX'</strong> - Not Recommended - Allow downgraded SSL connections</li></ul>
+ <strong>'Note'</strong>: Downloaded or pfsense local file musts have the syntax (See customlist below)</ul>]]>
</description>
<type>rowhelper</type>
<rowhelper>
@@ -225,15 +196,12 @@
<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>Auto</name><value>auto</value></option>
+ <option><name>Regex</name><value>regex</value></option>
+ <option><name>Whois</name><value>whois</value></option>
<option><name>RSync</name><value>rsync</value></option>
</options>
+ <default_value>auto</default_value>
</rowhelperfield>
<rowhelperfield>
<fielddescr>State</fielddescr>
@@ -243,16 +211,18 @@
<option><name>ON</name><value>Enabled</value></option>
<option><name>OFF</name><value>Disabled</value></option>
<option><name>HOLD</name><value>Hold</value></option>
+ <option><name>FLEX</name><value>Flex</value></option>
</options>
+ <default_value>Enabled</default_value>
</rowhelperfield>
<rowhelperfield>
- <fielddescr>URL or pfSense local file</fielddescr>
+ <fielddescr>Source</fielddescr>
<fieldname>url</fieldname>
<type>input</type>
<size>50</size>
</rowhelperfield>
<rowhelperfield>
- <fielddescr>Header</fielddescr>
+ <fielddescr>Header/Label</fielddescr>
<fieldname>header</fieldname>
<type>input</type>
<size>15</size>
@@ -291,11 +261,9 @@
<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)&nbsp;</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 />]]>
+ <font color='red'>Note: </font><ul>When manually creating 'Alias' type firewall rules; <strong>Do not add</strong> (pfB_) to the
+ start of the rule description, use (pfb_) (Lowercase prefix). Manually created 'Alias' rules with 'pfB_' in the
+ description will be auto-removed by package when 'Auto' rules are defined.</ul>]]>
</description>
<fieldname>action</fieldname>
<type>select</type>
@@ -368,13 +336,24 @@
</options>
</field>
<field>
+ <fieldname>stateremoval</fieldname>
+ <fielddescr>States Removal</fielddescr>
+ <description>With the 'Kill States' option (General Tab), you can disable States removal for this Alias.</description>
+ <type>select</type>
+ <options>
+ <option><name>Enable</name><value>enabled</value></option>
+ <option><name>Disable</name><value>disabled</value></option>
+ </options>
+ <default_value>enabled</default_value>
+ </field>
+ <field>
<name>Advanced Inbound Firewall Rule Settings</name>
<type>listtopic</type>
</field>
<field>
<type>info</type>
- <description><![CDATA[<font color='red'>Note: </font>In general Auto-Rules are created as follows:<br />
- <ul>Inbound &nbsp;&nbsp;- 'any' port, 'any' protocol and 'any' destination<br />
+ <description><![CDATA[<font color='red'>Note: </font>&emsp;In general, Auto-Rules are created as follows:<br />
+ <ul>Inbound &emsp;- 'any' port, 'any' protocol and 'any' destination<br />
Outbound - 'any' port, 'any' protocol and 'any' destination address in the lists</ul>
Configuring the Adv. Inbound Rule settings, will allow for more customization of the Inbound Auto-Rules.<br />
<strong>Select the pfSense 'Port' and/or 'Destination' Alias below:</strong>]]>
@@ -435,7 +414,8 @@
<field>
<fielddescr>Custom Protocol</fielddescr>
<fieldname>autoproto</fieldname>
- <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).]]></description>
+ <description><![CDATA[<strong>Default: any</strong><br />Select the Protocol used for Inbound Firewall Rule(s).<br />
+ Do not use 'any' with Adv. Inbound Rules as it will bypass these settings!]]></description>
<type>select</type>
<options>
<option><name>any</name><value></value></option>
@@ -451,14 +431,51 @@
<type>listtopic</type>
</field>
<field>
- <fielddescr>IPv6 Custom Address(es)</fielddescr>
+ <type>info</type>
+ <description><![CDATA[<font color='red'>Note: </font>&emsp;Custom List can be used in <strong>ONE</strong> of two ways:<br />
+ <ul>1. IPv6 addresses entered directly into the custom list, as per the required format.</ul>
+ <ul>2. Domain names or AS numbers, which will be converted into their respective IPv6 addresses.</ul>]]>
+ </description>
+ </field>
+ <field>
+ <fieldname>whois_convert</fieldname>
+ <description><![CDATA[Select to enable 'Domain/AS' conversion.
+ <font color='red'>DO NOT</font> mix IPs with Domains/ASs in this custom list.]]>
+ </description>
+ <fielddescr>Enable Domain/AS</fielddescr>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fielddescr>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><![CDATA[Please limit the size of the Custom List as this is stored as 'Base64' format in the config.xml file.<br /><br />
+ <strong>Format IPv6:</strong><br /><br />
+
+ Source of Regex and format descriptions: <a href="http://labs.spritelink.net/regex">SpriteLink</a><br />
+ fe80:0000:0000:0000:0204:61ff:fe9d:f156 // full form of IPv6<br />
+ fe80:0:0:0:204:61ff:fe9d:f156 // drop leading zeroes<br />
+ fe80::204:61ff:fe9d:f156 // collapse multiple zeroes to :: in the IPv6 address<br />
+ fe80:0000:0000:0000:0204:61ff:254.157.241.086 // IPv4 dotted quad at the end<br />
+ fe80:0:0:0:0204:61ff:254.157.241.86 // drop leading zeroes, IPv4 dotted quad at the end<br />
+ fe80::204:61ff:254.157.241.86 // dotted quad at the end, multiple zeroes collapsed<br /><br />
+
+ In addition, the regular expression matches these IPv6 forms:<br /><br />
+
+ ::1 // localhost<br />
+ fe80:: // link-local prefix<br />
+ 2000:: // global unicast prefix<br />
+ Any slash-notation style prefix<br /><br />
+
+ Private IPv6 addresses may be used in a custom list.<br />
+ You may use "<strong>#</strong>" after any IP/CIDR/Range to add comments. ie: x::x:x:x:x # Safe IP Address<br /><br />
+ If you select the <strong>Domain/AS</strong> checkbox above, the custom list can <strong>only</strong>
+ be used for Domain names/AS's.<br /><br />
+ <strong>Format Domain/AS:</strong><br /><br />
+ One 'Domain' or 'AS' per line.<br />
+ Domains and/or ASs can be used in the same list.<br /><br />
+ Conversion of Domains/ASs utilize <a target="_blank" href="http://www.team-cymru.org/IP-ASN-mapping.html">Team CYMRU</a>
+ and the <a target="_blank" href="http://www.radb.net/">RADb</a> whois registry.<br />
+ Configure the 'update frequency', so that it does not <strong>abuse</strong> these free services.]]>
</description>
<type>textarea</type>
<cols>50</cols>
@@ -479,23 +496,21 @@
</options>
</field>
<field>
- <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ <name><![CDATA[<center>Click to SAVE Settings and/or Rule Edits. &emsp; Changes are Applied via CRON or
'Force Update'</center>]]></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>
+ <![CDATA[
pfblockerng_validate_input($_POST, $input_errors);
+ ]]>
</custom_php_validation_command>
<custom_php_resync_config_command>
+ <![CDATA[
global $pfb;
$pfb['save'] = TRUE;
sync_package_pfblockerng();
+ ]]>
</custom_php_resync_config_command>
</packagegui> \ No newline at end of file