aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
Diffstat (limited to 'config')
-rw-r--r--config/apcupsd/apcupsd.inc4
-rw-r--r--config/apcupsd/apcupsd.xml13
-rw-r--r--config/bacula-client/bacula-client.inc9
-rw-r--r--config/bind/bind.xml3
-rw-r--r--config/haproxy-devel/haproxy.inc699
-rw-r--r--config/haproxy-devel/haproxy.xml20
-rw-r--r--config/haproxy-devel/haproxy_files.php176
-rw-r--r--config/haproxy-devel/haproxy_htmllist.inc423
-rw-r--r--config/haproxy-devel/haproxy_listeners.php135
-rw-r--r--config/haproxy-devel/haproxy_listeners_edit.php188
-rw-r--r--config/haproxy-devel/haproxy_pool_edit.php42
-rw-r--r--config/haproxy-devel/haproxy_stats.php71
-rw-r--r--config/haproxy-devel/haproxy_templates.php220
-rw-r--r--config/haproxy-devel/haproxy_utils.inc26
-rw-r--r--config/haproxy-devel/pkg/haproxy_upgrade_config.inc174
-rw-r--r--config/haproxy-devel/pkg_haproxy_tabs.inc3
-rw-r--r--config/haproxy-devel/www/javascript/haproxy_geturl.js43
-rw-r--r--config/havp/antivirus.php8
-rw-r--r--config/havp/havp.inc19
-rw-r--r--config/havp/havp.xml29
-rw-r--r--config/havp/havp_avset.xml6
-rw-r--r--config/havp/havp_log.php105
-rw-r--r--config/lightsquid/lightsquid.xml4
-rw-r--r--config/mailscanner/mailscanner.inc2
-rw-r--r--config/ntopng/ntopng.xml20
-rw-r--r--config/nut/nut.inc41
-rw-r--r--config/nut/nut.xml37
-rwxr-xr-xconfig/openvpn-client-export/vpn_openvpn_export.php2
-rw-r--r--config/pfblockerng/countrycodes.tar.bz2bin0 -> 841191 bytes
-rw-r--r--config/pfblockerng/geoipupdate.sh162
-rw-r--r--config/pfblockerng/pfblockerng.inc2616
-rw-r--r--config/pfblockerng/pfblockerng.js79
-rw-r--r--config/pfblockerng/pfblockerng.php1475
-rw-r--r--config/pfblockerng/pfblockerng.priv.inc30
-rw-r--r--config/pfblockerng/pfblockerng.sh927
-rw-r--r--config/pfblockerng/pfblockerng.widget.php280
-rw-r--r--config/pfblockerng/pfblockerng.xml495
-rw-r--r--config/pfblockerng/pfblockerng_alerts.php769
-rw-r--r--config/pfblockerng/pfblockerng_diag_dns.php318
-rw-r--r--config/pfblockerng/pfblockerng_log.php428
-rw-r--r--config/pfblockerng/pfblockerng_sync.xml246
-rw-r--r--config/pfblockerng/pfblockerng_top20.xml294
-rw-r--r--config/pfblockerng/pfblockerng_update.php426
-rw-r--r--config/pfblockerng/pfblockerng_v4lists.xml426
-rw-r--r--config/pfblockerng/pfblockerng_v6lists.xml421
-rw-r--r--config/pfblockerng/widget-pfblockerng.inc7
-rwxr-xr-xconfig/postfix/postfix_queue.php2
-rwxr-xr-xconfig/sarg/sarg_realtime.php2
-rw-r--r--config/sarg/sarg_schedule.xml2
-rw-r--r--config/siproxd.inc1
-rw-r--r--config/siproxd.xml2
-rwxr-xr-xconfig/snort/snort.inc87
-rw-r--r--config/snort/snort.priv.inc1
-rwxr-xr-xconfig/snort/snort.xml9
-rw-r--r--config/snort/snort_check_cron_misc.inc27
-rwxr-xr-xconfig/snort/snort_check_for_rule_updates.php198
-rw-r--r--config/snort/snort_conf_template.inc3
-rw-r--r--config/snort/snort_defs.inc101
-rwxr-xr-xconfig/snort/snort_download_updates.php77
-rw-r--r--config/snort/snort_generate_conf.php39
-rw-r--r--config/snort/snort_interface_logs.php18
-rwxr-xr-xconfig/snort/snort_interfaces_edit.php6
-rw-r--r--config/snort/snort_interfaces_global.php129
-rw-r--r--config/snort/snort_ip_list_mgmt.php37
-rw-r--r--config/snort/snort_ip_reputation.php14
-rw-r--r--config/snort/snort_log_mgmt.php32
-rw-r--r--config/snort/snort_migrate_config.php76
-rw-r--r--config/snort/snort_post_install.php31
-rwxr-xr-xconfig/snort/snort_preprocessors.php150
-rwxr-xr-xconfig/snort/snort_rules.php9
-rw-r--r--config/snort/snort_sid_mgmt.php11
-rw-r--r--config/squid3/34/check_ip.php56
-rwxr-xr-xconfig/squid3/34/squid.inc187
-rw-r--r--config/squid3/34/squid.xml23
-rwxr-xr-xconfig/squid3/34/squid_antivirus.xml1
-rw-r--r--config/squid3/34/squid_clwarn.php95
-rw-r--r--config/squid3/34/swapstate_check.php11
-rw-r--r--config/squidGuard-devel/squidguard_configurator.inc6
-rw-r--r--config/squidGuard/squidguard.xml2
-rw-r--r--config/squidGuard/squidguard_configurator.inc60
-rw-r--r--config/suricata/suricata.inc291
-rw-r--r--config/suricata/suricata.priv.inc6
-rw-r--r--config/suricata/suricata.xml32
-rw-r--r--config/suricata/suricata_alerts.js2
-rw-r--r--config/suricata/suricata_alerts.php29
-rw-r--r--config/suricata/suricata_alerts.widget.php71
-rw-r--r--config/suricata/suricata_app_parsers.php2
-rw-r--r--config/suricata/suricata_barnyard.php31
-rw-r--r--config/suricata/suricata_blocked.php95
-rw-r--r--config/suricata/suricata_check_cron_misc.inc32
-rw-r--r--config/suricata/suricata_check_for_rule_updates.php169
-rw-r--r--config/suricata/suricata_define_vars.php2
-rw-r--r--config/suricata/suricata_defs.inc117
-rw-r--r--config/suricata/suricata_download_updates.php14
-rw-r--r--config/suricata/suricata_etiqrisk_update.php216
-rw-r--r--config/suricata/suricata_flow_stream.php2
-rw-r--r--config/suricata/suricata_generate_yaml.php48
-rw-r--r--config/suricata/suricata_geoipupdate.php137
-rw-r--r--config/suricata/suricata_global.php42
-rw-r--r--config/suricata/suricata_interfaces.php20
-rw-r--r--config/suricata/suricata_interfaces_edit.php15
-rw-r--r--config/suricata/suricata_ip_list_mgmt.php398
-rw-r--r--config/suricata/suricata_ip_reputation.php482
-rw-r--r--config/suricata/suricata_iprep_list_browser.php99
-rw-r--r--config/suricata/suricata_logs_browser.php1
-rw-r--r--config/suricata/suricata_logs_mgmt.php5
-rw-r--r--config/suricata/suricata_migrate_config.php54
-rw-r--r--config/suricata/suricata_passlist.php3
-rw-r--r--config/suricata/suricata_passlist_edit.php3
-rw-r--r--config/suricata/suricata_post_install.php72
-rw-r--r--config/suricata/suricata_rules.php2
-rw-r--r--config/suricata/suricata_rules_flowbits.php2
-rw-r--r--config/suricata/suricata_rulesets.php33
-rw-r--r--config/suricata/suricata_sid_mgmt.php17
-rw-r--r--config/suricata/suricata_suppress.php3
-rw-r--r--config/suricata/suricata_suppress_edit.php1
-rw-r--r--config/suricata/suricata_sync.xml5
-rw-r--r--config/suricata/suricata_uninstall.php50
-rw-r--r--config/suricata/suricata_yaml_template.inc14
-rw-r--r--config/systempatches/system_patches.php2
-rw-r--r--config/systempatches/systempatches.xml2
-rw-r--r--config/vnstat2/vnstat2.inc2
-rw-r--r--config/vnstat2/vnstat_php_frontend/README4
-rw-r--r--config/vnstat2/vnstat_php_frontend/config.php22
-rw-r--r--config/vnstat2/vnstat_php_frontend/graph.php61
-rw-r--r--config/vnstat2/vnstat_php_frontend/graph_svg.php56
-rw-r--r--config/vnstat2/vnstat_php_frontend/index.php43
-rw-r--r--config/vnstat2/vnstat_php_frontend/json.php81
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/br.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/cn.php40
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/de.php40
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/es.php41
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/fi.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/fr.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/hr.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/hu.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/it.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/no.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/pl.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/ru.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/lang/sk.php39
-rw-r--r--config/vnstat2/vnstat_php_frontend/themes/dark/theme.php28
-rw-r--r--config/vnstat2/vnstat_php_frontend/themes/espresso/theme.php30
-rw-r--r--config/vnstat2/vnstat_php_frontend/themes/light/style.css32
-rw-r--r--config/vnstat2/vnstat_php_frontend/themes/light/theme.php26
-rw-r--r--config/vnstat2/vnstat_php_frontend/themes/red/theme.php28
-rw-r--r--config/vnstat2/vnstat_php_frontend/vnstat.php47
147 files changed, 15382 insertions, 1636 deletions
diff --git a/config/apcupsd/apcupsd.inc b/config/apcupsd/apcupsd.inc
index 3340738a..c123861c 100644
--- a/config/apcupsd/apcupsd.inc
+++ b/config/apcupsd/apcupsd.inc
@@ -167,9 +167,7 @@ function sync_package_apcupsd(){
$apcupsd_start .= " if [ ! -d {$lockfile} ]; then \n";
$apcupsd_start .= " /bin/mkdir -p {$lockfile} \n";
$apcupsd_start .= " fi \n";
- $apcupsd_start .= " if [ -f {$lockfile}/LCK.. ]; then \n";
- $apcupsd_start .= " /bin/rm -f {$lockfile}/LCK.. \n";
- $apcupsd_start .= " fi \n";
+ $apcupsd_start .= " /bin/rm -f {$lockfile}/*LCK* 2>/dev/null \n";
if ($apcupsd_config['killonpowerfail']=="on"){
$apcupsd_start .= " " . APCUPSD_BASE . "/sbin/apcupsd --kill-on-powerfail";
}else{
diff --git a/config/apcupsd/apcupsd.xml b/config/apcupsd/apcupsd.xml
index 5ef2b946..8a42f352 100644
--- a/config/apcupsd/apcupsd.xml
+++ b/config/apcupsd/apcupsd.xml
@@ -40,7 +40,7 @@
<name>Apcupsd</name>
<title>Services: Apcupsd (General)</title>
<category>Monitoring</category>
- <version>0.3.1</version>
+ <version>0.3.2</version>
<include_file>/usr/local/pkg/apcupsd.inc</include_file>
<addedit_string>Apcupsd has been created/modified.</addedit_string>
<delete_string>Apcupsd has been deleted.</delete_string>
@@ -334,6 +334,17 @@ UPSTYPE DEVICE Description <br>
<option><name>Share</name><value>share</value></option>
</options>
</field>
+ <field>
+ <name>Notifications</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fieldname>notification_info</fieldname>
+ <type>info</type>
+ <description>In order to receive e-mail notifications, you need to configure
+ SMTP Email Notifications on Advanced/Notifications section, and also,
+ install mailreport package.</description>
+ </field>
</fields>
<custom_php_install_command>php_install_apcupsd();</custom_php_install_command>
<custom_php_command_before_form></custom_php_command_before_form>
diff --git a/config/bacula-client/bacula-client.inc b/config/bacula-client/bacula-client.inc
index 94411809..233de4b6 100644
--- a/config/bacula-client/bacula-client.inc
+++ b/config/bacula-client/bacula-client.inc
@@ -59,7 +59,7 @@ function baculaclient_custom_php_deinstall_command(){
unlink_if_exists(BACULA_LOCALBASE."/etc/bacula-fd.conf");
// 2. Re-run sshd config generation script
- exec("/usr/local/etc/rc.d/bacula-fd.sh stop");
+ exec(BACULA_LOCALBASE . "/etc/rc.d/bacula-fd.sh stop");
conf_mount_ro();
}
@@ -67,11 +67,12 @@ function baculaclient_custom_php_write_config(){
global $g, $config;
conf_mount_rw();
//check config_file
- $startup_file="/usr/local/etc/rc.d/bacula-fd";
+ $startup_file=BACULA_LOCALBASE . "/etc/rc.d/bacula-fd";
if (file_exists($startup_file)){
$startup_script=file_get_contents($startup_file);
$startup_script=preg_replace("/NO/","YES",$startup_script);
$startup_script=preg_replace("@/usr/local/etc/bacula-fd.conf@",BACULA_LOCALBASE."/etc/bacula-fd.conf",$startup_script);
+ $startup_script=preg_replace("@" . BACULA_LOCALBASE . "/etc/bacula/bacula-fd.conf@",BACULA_LOCALBASE."/etc/bacula-fd.conf",$startup_script);
file_put_contents("{$startup_file}.sh",$startup_script,LOCK_EX);
// Ensure bacula-fd has a+rx
exec("chmod a+rx {$startup_file}.sh");
@@ -111,10 +112,10 @@ function baculaclient_custom_php_write_config(){
}
$baculaclient_conf .= "FileDaemon { \n\t Name = {$LocalDirector}-fd #\n\t FDport = {$port}\n\t WorkingDirectory = /var/db/bacula\n\t Pid Directory = /var/run\n\tMaximum Concurrent Jobs = {$jobs}\n\t}\n";
file_put_contents(BACULA_LOCALBASE."/etc/bacula-fd.conf",$baculaclient_conf,LOCK_EX);
- exec("/usr/local/etc/rc.d/bacula-fd.sh restart");
+ exec(BACULA_LOCALBASE . "/etc/rc.d/bacula-fd.sh restart");
// Mount Read-only
conf_mount_ro();
}
}
- ?> \ No newline at end of file
+ ?>
diff --git a/config/bind/bind.xml b/config/bind/bind.xml
index 5e5f9e9b..37c13017 100644
--- a/config/bind/bind.xml
+++ b/config/bind/bind.xml
@@ -185,8 +185,7 @@
<field>
<fielddescr>Logging serverity</fielddescr>
<fieldname>log_severity</fieldname>
- <description><![CDATA[Choose logging levels for selected categories.<BR>
- use CTRL+click to select/unselect.<br>
+ <description><![CDATA[Choose logging level for selected categories.<BR>
The value 'dynamic' means assume the global level defined by either the command line parameter -d or by running rndc trace.]]></description>
<type>select</type>
<options>
diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc
index 07086bd5..e9b0f9e3 100644
--- a/config/haproxy-devel/haproxy.inc
+++ b/config/haproxy-devel/haproxy.inc
@@ -1,7 +1,7 @@
<?php
/*
haproxy.inc
- Copyright (C) 2013 PiBa-NL
+ Copyright (C) 2013-2015 PiBa-NL
Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
Copyright (C) 2008 Remco Hoef
All rights reserved.
@@ -38,6 +38,13 @@ require_once("haproxy_xmlrpcsyncclient.inc");
$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
+global $a_frontendmode;
+$a_frontendmode = array();
+$a_frontendmode['http'] = array('name' => "http / https(offloading)", 'shortname' => "http/https");
+$a_frontendmode['https'] = array('name' => "ssl / https(TCP mode)", 'shortname' => "ssl/https");
+$a_frontendmode['tcp'] = array('name' => "tcp", 'shortname' => "tcp");
+$a_frontendmode['health'] = array('name' => "health", 'shortname' => "health");
+
global $a_acltypes;
$a_acltypes = array();
$a_acltypes["host_starts_with"] = array('name' => 'Host starts with:',
@@ -84,6 +91,8 @@ $a_acltypes["ssl_sni_starts_with"] = array('name' => 'Server Name Indication TLS
'mode' => 'https', 'syntax' => 'req.ssl_sni -m beg -i %1$s', 'advancedoptions' => "tcp-request content accept if { req.ssl_hello_type 1 }");
$a_acltypes["ssl_sni_ends_with"] = array('name' => 'Server Name Indication TLS extension ends with:', 'inspect-delay' => '5',
'mode' => 'https', 'syntax' => 'req.ssl_sni -m end -i %1$s', 'advancedoptions' => "tcp-request content accept if { req.ssl_hello_type 1 }");
+$a_acltypes["ssl_sni_regex"] = array('name' => 'Server Name Indication TLS extension regex:', 'inspect-delay' => '5',
+ 'mode' => 'https', 'syntax' => 'req.ssl_sni -m reg -i %1$s', 'advancedoptions' => "tcp-request content accept if { req.ssl_hello_type 1 }");
$a_acltypes["custom"] = array('name' => 'Custom acl:',
'mode' => '', 'syntax' => '%1$s');
@@ -187,6 +196,19 @@ $a_sticky_type['stick_rdp_cookie'] = array('name' => 'Stick on RDP-cookie',
'descr' => "Uses a RDP-Cookie send by the mstsc client, note that not all clients send this.",
'cookiedescr' => 'EXAMPLE: msts or mstshash');
+
+global $a_error;
+$a_error = array();
+$a_error['200'] = array('descr' => "stats or monitoring requests");
+$a_error['400'] = array('descr' => "request invalid or too large");
+$a_error['401'] = array('descr' => "authentication is required to perform the action");
+$a_error['403'] = array('descr' => "request is forbidden");
+$a_error['408'] = array('descr' => "timeout before the request is complete");
+$a_error['500'] = array('descr' => "internal error");
+$a_error['502'] = array('descr' => "server response invalid or blocked");
+$a_error['503'] = array('descr' => "no server was available to handle the request");
+$a_error['504'] = array('descr' => "timeout before the server responds");
+
if(!function_exists('group_ports')){
// function group_ports() is present in pfSense 2.2 in util.inc
/* create ranges of sequential port numbers (200:215) and remove duplicates */
@@ -237,10 +259,11 @@ function group_ports($ports) {
return $result;
}
}
-
+
function haproxy_portoralias_to_list($port_or_alias) {
// input: a port or aliasname: 80 https MyPortAlias
// returns: a array of ports and portranges 80 443 8000:8010
+
global $aliastable;
$portresult = array();
if (alias_get_type($port_or_alias) == "port") {
@@ -253,15 +276,39 @@ function haproxy_portoralias_to_list($port_or_alias) {
return $portresult;
} else if (is_portrange($port_or_alias)) {
return (array)$port_or_alias;
- } else if (is_port($port_or_alias)) {
- if (getservbyname($port_or_alias, "tcp"))
- return (array)getservbyname($port_or_alias, "tcp");
- if (getservbyname($port_or_alias, "udp"))
- return (array)getservbyname($port_or_alias, "udp");
- return (array)$port_or_alias;
+ } else {
+ $ports = explode(",", $port_or_alias);
+ foreach($ports as $port){
+ if (is_port($port)) {
+ if (getservbyname($port, "tcp"))
+ $port = getservbyname($port, "tcp");
+ if (getservbyname($port, "udp"))
+ $port = getservbyname($port, "udp");
+ $portresult[] = $port;
+ }
+ }
+ return $portresult;
}
- else
- return null;
+}
+function haproxy_addressoralias_to_list($address_or_alias) {
+ global $aliastable;
+ $result = array();
+ $alias_type = alias_get_type($address_or_alias);
+ if (!empty($alias_type)) {
+ $alias = $aliastable[$address_or_alias];
+ if ($alias_type == "url") {
+ $result = explode(' ',$alias);
+ } else
+ if ($alias_type == "network") {
+ //$result = explode(' ',$alias);
+ } else
+ if ($alias_type == "host") {
+ $result = explode(' ',$alias);
+ }
+ } else {
+ $result[] = $address_or_alias;
+ }
+ return $result;
}
function haproxy_hostoralias_to_list($host_or_alias) {
@@ -274,6 +321,20 @@ function haproxy_hostoralias_to_list($host_or_alias) {
return $result;
}
+function haproxy_get_fileslist() {
+ // returns the files array with 'keys'.
+ $result = array();
+ global $config;
+ // create a copy to not modify the original 'keyless' array
+ $a_files = $config['installedpackages']['haproxy']['files']['item'];
+ if (!is_array($a_files)) $a_files = array();
+ foreach($a_files as $file) {
+ $key = $file['name'];
+ $result[$key] = $file;
+ }
+ return $result;
+}
+
function haproxy_custom_php_deinstall_command() {
global $static_output;
$static_output .= "HAProxy, running haproxy_custom_php_deinstall_command()\n";
@@ -364,111 +425,11 @@ EOD;
$static_output .= "HAProxy, update configuration\n";
update_output_window($static_output);
-
- $writeconfigupdate = false;
- /* Do XML upgrade from haproxy 0.31 to haproxy-dev */
- if (is_array($config['installedpackages']['haproxy']['ha_servers'])) {
- $static_output .= "HAProxy, Do XML upgrade from haproxy 0.31 to haproxy-dev\n";
- update_output_window($static_output);
-
- /* We have an old config */
- $config['installedpackages']['haproxy']['ha_pools']['item'] = array();
- $a_global = &$config['installedpackages']['haproxy'];
- $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
- $a_oldservers = &$config['installedpackages']['haproxy']['ha_servers']['item'];
- $a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item'];
-
- foreach ($a_backends as $id => $be) {
- $a_backends[$id]['status'] = 'active';
- }
- $id = 0;
- foreach ($a_oldservers as $oldserver) {
- $pool=$oldserver;
- /* make server sub array */
- $server=array();
- $server['name'] = $oldserver['name'];
- $server['address'] = $oldserver['address'];
- $server['port'] = $oldserver['port'];
- $server['weight'] = $oldserver['weight'];
- $a_servers=array();
- $a_servers[]=$server;
- /* set new pool */
- $pool['name'] = "pool$id";
- $id++;
- $pool['ha_servers']['item']=$a_servers;
- /* link to frontend */
- foreach ($a_backends as $id => $be) {
- if ($a_backends[$id]['name'] == $oldserver['backend']) {
- $a_backends[$id]['backend_serverpool'] = $pool['name'];
- $pool['monitor_uri'] = $be['monitor_uri'];
- unset($a_backends[$id]['monitor_uri']);
- break;
- }
- }
- unset($pool['backend']);
- unset($pool['address']);
- unset($pool['port']);
- unset($pool['weight']);
- $a_pools[] = $pool;
- }
- unset($config['installedpackages']['haproxy']['ha_servers']);
- $writeconfigupdate = true;
- }
-
- /* XML update to: pkg v1.3 and 'pool' changed to 'backend_serverpool' because 'pool' was added to listtags() in xmlparse.inc */
- if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0,'pool')) {
- $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool array\n";
- update_output_window($static_output);
-
- foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend)
- {
- $backend_serverpool = $frontend['pool'][0];
- $frontend['backend_serverpool'] = $backend_serverpool;
- unset($frontend['pool']);
- }
- $writeconfigupdate = true;
- }
- //also move setting for existing 2.0 installations as only the new variable is used
- if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0) &&
- isset($config['installedpackages']['haproxy']['ha_backends']['item'][0]['pool'])) {
- $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool\n";
- update_output_window($static_output);
- foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend)
- {
- $backend_serverpool = $frontend['pool'];
- $frontend['backend_serverpool'] = $backend_serverpool;
- unset($frontend['pool']);
- }
- $writeconfigupdate = true;
- }
- // update config to "haproxy-devel 1.5-dev19 pkg v0.5"
- if(is_arrayset($config,'installedpackages','haproxy','ha_backends','item')) {
- $static_output .= "HAProxy, Do XML upgrade, update frontend options\n";
- update_output_window($static_output);
- foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) {
- if($bind['httpclose'] && $bind['httpclose'] == "yes" ) {
- $bind['httpclose'] = "httpclose";
- $writeconfigupdate = true;
- }
- if (!$bind['extaddr']){
- $bind['extaddr'] = "wan_ipv4";
- $writeconfigupdate = true;
- }
- if ($bind['extaddr'] == "localhost"){
- $bind['extaddr'] = "localhost_ipv4";
- $writeconfigupdate = true;
- }
- if ($bind['extaddr'] == "any"){
- $bind['extaddr'] = "any_ipv4";
- $writeconfigupdate = true;
- }
- }
- }
- if ($writeconfigupdate) {
- $static_output .= "HAProxy, write updated config\n";
- update_output_window($static_output);
- write_config("HAProxy, update xml config version");
- }
+
+ // call from external file, so it is surely from the newly downloaded version
+ // this avoids a problem with php cache that loaded haproxy.inc during uninstalling the old version
+ require_once('haproxy_upgrade_config.inc');
+ haproxy_upgrade_config();
$static_output .= "HAProxy, conf_mount_ro\n";
update_output_window($static_output);
@@ -527,6 +488,17 @@ function haproxy_install_cron($should_install) {
}
}
+function haproxy_find_backend($backendname) {
+ global $config;
+ $a_backends = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+ foreach ($a_backends as &$backend) {
+ if ($backend['name'] == $backendname) {
+ return $backend;
+ }
+ }
+ return null;
+}
+
function haproxy_find_acl($name) {
global $a_acltypes;
if($a_acltypes) {
@@ -537,14 +509,16 @@ function haproxy_find_acl($name) {
}
}
-function write_backend($configpath, $fd, $name, $pool, $frontend) {
+function write_backend($configpath, $fd, $name, $pool, $backendsettings) {
+ $frontend = $backendsettings['frontend'];
+ $ipversion = $backendsettings['ipversion'];
+
if(!is_array($pool['ha_servers']['item']) && !$pool['stats_enabled']=='yes')
return;
- global $a_checktypes, $a_cookiemode;
+ global $a_checktypes, $a_cookiemode, $a_files_cache, $a_error;
$a_servers = &$pool['ha_servers']['item'];
$frontendtype = $frontend['type'];
- $frontend_ip = haproxy_interface_ip($frontend['extaddr']);
fwrite ($fd, "backend " . $name . "\n");
// https is an alias for tcp for clarity purposes
@@ -604,6 +578,23 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) {
fwrite ($fd, "\tstats\t\t\tscope " . $scope_item . "\n");
}
}
+
+ if (is_arrayset($pool,'errorfiles','item')) {
+ foreach($pool['errorfiles']['item'] as $errorfile) {
+ if (!is_array($a_files_cache))// load only once
+ $a_files_cache = haproxy_get_fileslist();
+ $file = $errorfile['errorfile'];
+ $errorcodes = explode(",",$errorfile['errorcode']);
+ foreach($errorcodes as $errorcode) {
+ $filename = "$configpath/errorfile_{$name}_{$errorcode}_{$file}";
+ $content = base64_decode($a_files_cache[$file]['content']);
+ $content = str_replace('{errormsg}', $a_error[$errorcode]['descr'], $content);
+ $content = str_replace('{errorcode}', $errorcode, $content);
+ file_put_contents($filename, $content);
+ fwrite ($fd, "\terrorfile\t\t\t" . $errorcode ." " . $filename . "\n");
+ }
+ }
+ }
}
switch($pool["persist_sticky_type"]) {
@@ -678,11 +669,18 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) {
$pool['retries'] = 3;
fwrite ($fd, "\tretries\t\t\t" . $pool['retries'] . "\n");
- if ($pool['transparent_clientip']) {
- if (is_ipaddrv4($frontend_ip))
- fwrite ($fd, "\tsource 0.0.0.0 usesrc clientip\n");
- else
- fwrite ($fd, "\tsource ipv6@ usesrc clientip\n");
+ $addrprefix = "";
+ $dnsquerytype = "A,AAAA";
+ if ($pool['transparent_clientip'] == 'yes') {
+ if ($ipversion == "ipv6") {
+ $addrprefix = "ipv6@";
+ $dnsquerytype = "AAAA";
+ }
+ if ($ipversion == "ipv4") {
+ $addrprefix = "ipv4@";
+ $dnsquerytype = "A";
+ }
+ fwrite ($fd, "\tsource $addrprefix usesrc clientip\n");
}
$uri = $pool['monitor_uri'];
@@ -710,8 +708,7 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) {
$advanced_txt = "";
}
- if ($check_type != 'none')
- {
+ if ($check_type != 'none') {
if($pool['checkinter'])
$checkinter = " check inter {$pool['checkinter']}";
else
@@ -722,8 +719,7 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) {
if ($pool['agent_check'])
$agentcheck = " agent-check agent-inter {$pool['agent_inter']} agent-port {$pool['agent_port']}";
- if (is_array($a_servers))
- {
+ if (is_array($a_servers)) {
foreach($a_servers as $be) {
if ($be['status'] == "inactive")
continue;
@@ -784,13 +780,37 @@ function write_backend($configpath, $fd, $name, $pool, $frontend) {
$maxconn = " maxconn " . $be['maxconn'];
}
+ $servers = array();
if ($be['forwardto'] && $be['forwardto'] != "") {
- $server = "/{$be['forwardto']}.socket send-proxy-v2-ssl-cn";
- } else
- $server = $be['address'].":" . $be['port'];
-
-
- fwrite ($fd, "\tserver\t\t\t" . $be['name'] . " " . $server . "$ssl$cookie$checkinter$checkport$agentcheck $isbackup$weight$maxconn$cafile$crlfile$verifynone$verifyhost$crtfile{$advanced_txt} {$be['advanced']}\n");
+ $servers[] = "/{$be['forwardto']}.socket send-proxy-v2-ssl-cn";
+ } else {
+ if (is_ipaddr($be['address'])) {
+ $servers[] = $be['address'];
+ } else if (is_hostname($be['address'])) {
+ $dnsresult_servers = haproxy_utils::query_dns($be['address'], $dnsquerytype);
+ foreach($dnsresult_servers as $dnsresult_server){
+ $servers[] = $dnsresult_server['data'];
+ }
+ }
+ }
+ $counter = 0;
+ foreach($servers as $server) {
+ if (is_ipaddr($server)) {
+ // skip ipv4 servers when using transparent client ip with ipv6 backend servers, and vice versa
+ if ($ipversion == "ipv4" && !is_ipaddrv4($server))
+ continue;
+ if ($ipversion == "ipv6" && !is_ipaddrv6($server))
+ continue;
+ if (isset($be['port']))
+ $server = $server . ":" . $be['port'];
+ }
+ $servername = $be['name'];
+ if (count($servers) > 1) {
+ $servername .= "_" . $counter;
+ }
+ fwrite ($fd, "\tserver\t\t\t" . $servername . " " . $server . "$ssl$cookie$checkinter$checkport$agentcheck $isbackup$weight$maxconn$cafile$crlfile$verifynone$verifyhost$crtfile{$advanced_txt} {$be['advanced']}\n");
+ $counter++;
+ }
}
}
fwrite ($fd, "\n");
@@ -875,6 +895,9 @@ function haproxy_write_certificate_fullchain($filename, $certid, $append = false
function haproxy_writeconf($configpath) {
global $config;
+ global $aliastable;
+ if (!isset($aliastable))
+ alias_make_table($config);
$chroot_dir = "/tmp/haproxy_chroot"; // can contain socket to forward connection from backend to frontend. "/var/empty"
make_dirs($chroot_dir);
@@ -928,7 +951,7 @@ function haproxy_writeconf($configpath) {
$localstatsport = $a_global['localstatsport'];
if ($localstatsport){
fwrite ($fd, "listen HAProxyLocalStats\n");
- fwrite ($fd, "\tbind 127.0.0.1:$localstatsport\n");
+ fwrite ($fd, "\tbind 127.0.0.1:$localstatsport name localstats\n");
fwrite ($fd, "\tmode http\n");
fwrite ($fd, "\tstats enable\n");
if (is_numeric($a_global['localstats_refreshtime']))
@@ -951,7 +974,8 @@ function haproxy_writeconf($configpath) {
if(!$frontend['backend_serverpool'])
continue;
$primaryfrontend = get_primaryfrontend($frontend);
- $bname = get_frontend_ipport($frontend);
+
+ $bname = $primaryfrontend['name'];
if (!is_array($a_bind[$bname])) {
$a_bind[$bname] = array();
$a_bind[$bname] = $primaryfrontend;
@@ -959,12 +983,14 @@ function haproxy_writeconf($configpath) {
}
//check ssl info
- if (strtolower($primaryfrontend['type']) == "http" && $frontend['ssloffload']){
+ $ssl = get_frontend_uses_ssl($frontend);
+
+ if ($ssl) {
//ssl crt ./server.pem ca-file ./ca.crt verify optional crt-ignore-err all crl-file ./ca_crl.pem
- $filename = "$configpath/{$frontend['name']}.{$frontend['port']}.pem";
+ $filename = "$configpath/{$frontend['name']}.pem";
$ssl_crt = " crt $filename";
haproxy_write_certificate_fullchain($filename, $frontend['ssloffloadcert']);
- $subfolder = "$configpath/{$frontend['name']}.{$frontend['port']}";
+ $subfolder = "$configpath/{$frontend['name']}";
$certs = $frontend['ha_certificates']['item'];
if (is_array($certs)){
if (count($certs) > 0){
@@ -1008,33 +1034,35 @@ function haproxy_writeconf($configpath) {
else
$frontendinfo = "frontend {$bind['name']}\n";
- $advancedextra = array();
+ fwrite ($fd, "{$frontendinfo}");
+ $allow_none = false;
+ $advancedextra = array();
$ca_file = "";
$first = true;
if (is_array($bind['clientcert_ca']['item'])){
+ $filename = "$configpath/clientca_{$bind['name']}.pem";
foreach($bind['clientcert_ca']['item'] as $ca){
- $filename = "$configpath/clientca_{$bind['name']}.pem";
- haproxy_write_certificate_crt($filename, $ca['cert_ca'], false, !$first);
- $first = false;
+ if (!empty($ca['cert_ca'])){
+ haproxy_write_certificate_crt($filename, $ca['cert_ca'], false, !$first);
+ $first = false;
+ } else
+ $allow_none = true;
}
- $ca_file = " ca-file $filename verify optional";
+ $verify = $allow_none ? "verify optional" : "verify required";
+ $ca_file = " ca-file $filename $verify";
}
$crl_file = "";
$first = true;
if (is_array($bind['clientcert_crl']['item'])){
+ $filename = "$configpath/clientcrl_{$bind['name']}.pem";
foreach($bind['clientcert_crl']['item'] as $ca){
- $filename = "$configpath/clientcrl_{$bind['name']}.pem";
haproxy_write_certificate_crl($filename, $ca['cert_crl'], !$first);
$first = false;
}
$crl_file = " crl-file $filename";
}
- // Prepare ports for processing by splitting
- $portss = "{$bind['port']},";
- $ports = split(",", $portss);
-
if($bind['type'] == "http") {
// ssl offloading is only possible in http mode.
$ssl_info = $bind['ssl_info'].$ca_file.$crl_file;
@@ -1043,27 +1071,22 @@ function haproxy_writeconf($configpath) {
$ssl_info = "";
$advanced_bind = "";
}
- // Initialize variable
- $listenip = "";
+ $useipv4 = false;
+ $useipv6 = false;
// Process and add bind directives for ports
- $ip = haproxy_interface_ip($bind['extaddr']);
- if ($ip){
- foreach($ports as $alias_or_port) {
- if($alias_or_port) {
- $portsnumeric = group_ports(haproxy_portoralias_to_list($alias_or_port));
- foreach($portsnumeric as $portnumeric) {
- $portnumeric = str_replace(":","-",$portnumeric);
- $listenip .= "\tbind\t\t\t$ip:{$portnumeric} {$ssl_info} {$advanced_bind}\n";
- }
- }
- }
+ $bindips = get_frontend_bindips($bind);
+ $listenip = "";
+ foreach($bindips as $bindip) {
+ $ssl = $bindip['extaddr_ssl'] == 'yes' ? $ssl_info : "";
+ $listenip .= "\tbind\t\t\t{$bindip['addr']}:{$bindip['port']} name {$bindip['addr']}:{$bindip['port']} {$ssl} {$advanced_bind} {$bindip['extaddr_advanced']}\n";
+ $useipv4 |= is_ipaddrv4($bindip['addr']);
+ $useipv6 |= is_ipaddrv6($bindip['addr']);
}
-
- fwrite ($fd, "{$frontendinfo}");
fwrite ($fd, "{$listenip}");
+
if (use_frontend_as_unixsocket($bind['name'])){
- fwrite ($fd, "\tbind /tmp/haproxy_chroot/{$bind['name']}.socket accept-proxy {$ssl_info} {$advanced_bind}\n");
+ fwrite ($fd, "\tbind /tmp/haproxy_chroot/{$bind['name']}.socket name unixsocket accept-proxy {$ssl_info} {$advanced_bind}\n");
}
// Advanced pass thru
@@ -1086,12 +1109,14 @@ function haproxy_writeconf($configpath) {
fwrite ($fd, "\tmode\t\t\t" . $backend_type . "\n");
fwrite ($fd, "\tlog\t\t\tglobal\n");
+ if ($bind['socket-stats'] == 'yes')
+ fwrite ($fd, "\toption\t\t\tsocket-stats\n");
if ($bind['dontlognull'] == 'yes')
- fwrite ($fd, "\toption\t\t\tdontlognull\n");
+ fwrite ($fd, "\toption\t\t\tdontlognull\n");
if ($bind['dontlog-normal'] == 'yes')
fwrite ($fd, "\toption\t\t\tdontlog-normal\n");
if ($bind['log-separate-errors'] == 'yes')
- fwrite ($fd, "\toption\t\t\tlog-separate-errors\n");
+ fwrite ($fd, "\toption\t\t\tlog-separate-errors\n");
if ($bind['log-detailed'] == 'yes'){
if ($backend_type == 'http')
fwrite ($fd, "\toption\t\t\thttplog\n");
@@ -1099,17 +1124,15 @@ function haproxy_writeconf($configpath) {
fwrite ($fd, "\toption\t\t\ttcplog\n");
}
- if ($backend_type == 'http')
- {
+ if ($backend_type == 'http') {
if($bind['httpclose'] && $bind['httpclose'] != "none" )
fwrite ($fd, "\toption\t\t\t{$bind['httpclose']}\n");
if($bind['forwardfor']) {
fwrite ($fd, "\toption\t\t\tforwardfor\n");
- if($bind['ssloffload'] == "yes")
- fwrite ($fd, "\treqadd X-Forwarded-Proto:\ https\n");
- else
- fwrite ($fd, "\treqadd X-Forwarded-Proto:\ http\n");
+ fwrite ($fd, "\tacl https ssl_fc\n");
+ fwrite ($fd, "\treqadd X-Forwarded-Proto:\ http if !https\n");
+ fwrite ($fd, "\treqadd X-Forwarded-Proto:\ https if https\n");
}
}
@@ -1124,24 +1147,41 @@ function haproxy_writeconf($configpath) {
// Combine the rest of the frontend configs
$default_backend = "";
+ $config_acls = "";
+ $config_usebackends = "";
+
+ $transparent_clientip = false;
+ foreach ($bind['config'] as $frontend) {
+ $backend = haproxy_find_backend($frontend['backend_serverpool']);
+ if ($backend["transparent_clientip"] == 'yes') {
+ $transparent_clientip = true;
+ break;
+ }
+ }
+ if ($transparent_clientip && $useipv4 && $useipv6) {
+ // set the src_is_ipv4 acl if needed.
+ $config_acls .= "\tacl\t\t\tsrc_is_ipv4\tsrc 0.0.0.0/0\n";
+ }
+
$inspectdelay = 0;
$i = 0;
foreach ($bind['config'] as $frontend) {
$a_acl = get_frontend_acls($frontend);
- $poolname = $frontend['backend_serverpool'] . "_" . strtolower($bind['type']);
-
- if (!isset($a_pendingpl[$poolname])) {
- $a_pendingpl[$poolname] = array();
- $a_pendingpl[$poolname]['name'] = $poolname;
- $a_pendingpl[$poolname]['backend'] = $frontend['backend_serverpool'];
- $a_pendingpl[$poolname]['frontend'] = $bind;
- }
+ $backend = haproxy_find_backend($frontend['backend_serverpool']);
+ $transparent_clientip = $backend["transparent_clientip"] == 'yes';
- // Write this out once, and must be before any backend config text
- if (($default_backend == "" || $frontend['secondary'] != 'yes') && count($a_acl) == 0 ) {
- $default_backend = $poolname;
- }
+ $ipv = array();
+ if ($transparent_clientip) {
+ if ($useipv4 && $useipv6) {
+ $ipv["ipv4"]['acl'] = " src_is_ipv4 ";
+ $ipv["ipv6"]['acl'] = " !src_is_ipv4 ";
+ } else if ($useipv6)
+ $ipv["ipv6"]['acl'] = " ";
+ else
+ $ipv["ipv4"]['acl'] = " ";
+ } else
+ $ipv["ipvANY"]['acl'] = " ";
// combine acl's with same name to allow for 'combined checks' to check for example hostname and fileextension together..
$a_acl_combine = array();
@@ -1150,48 +1190,91 @@ function haproxy_writeconf($configpath) {
$a_acl_combine[$name][] = $entry['ref'];
}
- foreach ($a_acl_combine as $a_usebackend) {
- $aclnames = "";
- foreach ($a_usebackend as $entry) {
- $acl = haproxy_find_acl($entry['expression']);
- if (!$acl)
- continue;
-
- // Filter out acls for different modes
- if ($acl['mode'] != '' && $acl['mode'] != strtolower($bind['type']))
- continue;
- if (($entry['expression'] == "source_ip") && is_alias($entry['value'])) {
- $filename = "$configpath/ipalias_{$entry['value']}.lst";
- $listitems = haproxy_hostoralias_to_list($entry['value']);
- $fd_alias = fopen("$filename", "w");
- foreach($listitems as $item)
- fwrite($fd_alias, $item."\r\n");
- fclose($fd_alias);
- $expr = "src -f $filename";
- } else
- $expr = sprintf($acl['syntax'],$entry['value'],$poolname);
-
- $aclname = $i . "_" . $entry['name'];
- $aclnames .= $aclname." ";
- fwrite ($fd, "\tacl\t\t\t" . $aclname . "\t" . $expr . "\n");
-
- if ($acl['inspect-delay'] != '')
- $inspectdelay = $acl['inspect-delay'];
-
- if ($acl['advancedoptions'] != '')
- $advancedextra[$acl['syntax']] = $acl['advancedoptions']."\n";
- $i++;
+ $y = 0;
+ foreach($ipv as $ipversion => $ipversionoptions) {
+ $certacls = array();
+ $useracls = array();
+ $poolname = $frontend['backend_serverpool'] . "_" . strtolower($bind['type'])."_".$ipversion;
+ if (!isset($a_pendingpl[$poolname])) {
+ $a_pendingpl[$poolname] = array();
+ $a_pendingpl[$poolname]['name'] = $poolname;
+ $a_pendingpl[$poolname]['backend'] = $frontend['backend_serverpool'];
+ $a_pendingpl[$poolname]['frontend'] = $bind;
+ $a_pendingpl[$poolname]['ipversion'] = $ipversion;
}
- fwrite ($fd, "\tuse_backend\t\t" . $poolname . " if " . $aclnames . "\n");
+
+ // Write this out once, and must be before any backend config text
+ if (($default_backend == "" || $frontend['secondary'] != 'yes') && count($a_acl) == 0 ) {
+ $default_backend = $poolname;
+ }
+
+ foreach ($a_acl_combine as $a_usebackend) {
+ $aclnames = "";
+ foreach ($a_usebackend as $entry) {
+ $acl = haproxy_find_acl($entry['expression']);
+ if (!$acl)
+ continue;
+
+ // Filter out acls for different modes
+ if ($acl['mode'] != '' && $acl['mode'] != strtolower($bind['type']))
+ continue;
+ if (($entry['expression'] == "source_ip") && is_alias($entry['value'])) {
+ $filename = "$configpath/ipalias_{$entry['value']}.lst";
+ $listitems = haproxy_hostoralias_to_list($entry['value']);
+ $fd_alias = fopen("$filename", "w");
+ foreach($listitems as $item)
+ fwrite($fd_alias, $item."\r\n");
+ fclose($fd_alias);
+ $expr = "src -f $filename";
+ } else
+ $expr = sprintf($acl['syntax'],$entry['value'],$poolname);
+
+ $not = $entry['not'] == "yes" ? "!" : "";
+
+ $aclname = $i . "_" . $entry['name'];
+ if ($entry['certacl'])
+ $certacls[] = $aclname . " ";
+ else
+ $useracls[$y] .= $not . $aclname . " ";
+
+ $config_acls .= "\tacl\t\t\t" . $aclname . "\t" . $expr . "\n";
+
+ if ($acl['inspect-delay'] != '')
+ $inspectdelay = $acl['inspect-delay'];
+
+ if ($acl['advancedoptions'] != '')
+ $advancedextra[$acl['syntax']] = $acl['advancedoptions']."\n";
+ $i++;
+ }
+ $y++;
+ }
+
+ if (count($certacls) == 0) $certacls[] = ""; // add empty item to enter foreach loop at least once.
+ if (count($useracls) == 0) $useracls[] = ""; // add empty item to enter foreach loop at least once.
+ $backendacl = "";
+ foreach($useracls as $useracl)
+ foreach($certacls as $certacl)
+ $backendacl .= "|| {$useracl}{$certacl}{$ipversionoptions['acl']}";
+ $backendacl = substr($backendacl, 3);
+ $config_usebackends .= "\tuse_backend\t\t" . $poolname . " if " . $backendacl . "\n";
+ //$config_usebackends .= "\tuse_backend\t\t" . $poolname . " if " . $backendacl . "\n";
}
}
- if ($default_backend)
- fwrite ($fd, "\tdefault_backend\t\t" . $default_backend . "\n");
if ($inspectdelay > 0)
fwrite ($fd, "\ttcp-request inspect-delay\t" . $inspectdelay . "\n");
+
+ // Write acl's first, so they may be used by advanced text options written by user.
+ fwrite ($fd, $config_acls);
+
foreach($advancedextra as $extra)
fwrite ($fd, "\t".$extra."\n");
+
+ // Write backends after advanced options so custom use_backend rules can be applied first.
+ fwrite ($fd, $config_usebackends);
+ if ($default_backend)
+ fwrite ($fd, "\tdefault_backend\t\t" . $default_backend . "\n");
+
fwrite ($fd, "\n");
}
}
@@ -1200,7 +1283,7 @@ function haproxy_writeconf($configpath) {
foreach ($a_pendingpl as $pending) {
foreach ($a_backends as $pool) {
if ($pending['backend'] == $pool['name']) {
- write_backend($configpath, $fd, $pending['name'], $pool, $pending['frontend']);
+ write_backend($configpath, $fd, $pending['name'], $pool, $pending);
}
}
}
@@ -1392,8 +1475,7 @@ function haproxy_plugin_certificates($pluginparams) {
$result['certificatelist'] = array();
// return a array of used certificates.
foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend) {
- $mainfrontend = get_primaryfrontend($frontend);
- if (strtolower($mainfrontend['type']) == "http" && $mainfrontend['ssloffload']) {
+ if (get_frontend_uses_ssl($frontend)) {
if ($frontend['ssloffloadacl']){
$item = array();
$cert = $frontend['ssloffloadcert'];
@@ -1581,12 +1663,65 @@ function get_primaryfrontend($frontend) {
return $mainfrontend;
}
-function get_frontend_ipport($frontend,$userfriendly=false) {
+function get_frontend_ipport($frontend, $userfriendly=false) {
$mainfrontend = get_primaryfrontend($frontend);
- $result = haproxy_interface_ip($mainfrontend['extaddr'], $userfriendly);
- if ($userfriendly and is_ipaddrv6($result))
- $result = "[{$result}]";
- return $result . ":" . $mainfrontend['port'];
+ $result = array();
+ if (!is_arrayset($mainfrontend,"a_extaddr","item"))
+ return $result;
+ foreach($mainfrontend['a_extaddr']['item'] as $extaddr) {
+ if ($extaddr['extaddr'] == 'custom'){
+ $addr = $extaddr['extaddr_custom'];
+ } else {
+ $addr = haproxy_interface_ip($extaddr['extaddr'], $userfriendly);
+ }
+ if ($userfriendly and is_ipaddrv6($addr))
+ $addr = "[{$addr}]";
+
+ $port = $extaddr['extaddr_port'];
+ $newitem = array();
+ $newitem['addr'] = $addr;
+ $newitem['port'] = $port;
+ $newitem['ssl'] = $extaddr['extaddr_ssl'];
+ $result[$addr.$port] = $newitem;
+ }
+ ksort($result);
+ return $result;
+}
+
+function get_frontend_bindips($frontend) {
+ $mainfrontend = get_primaryfrontend($frontend);
+ $result = array();
+ if (!is_arrayset($mainfrontend,"a_extaddr","item"))
+ return $result;
+ foreach($mainfrontend['a_extaddr']['item'] as $extaddr) {
+ $a_ip = array();
+ if (isset($extaddr['extaddr']) && $extaddr['extaddr'] != "custom") {
+ $a_ip[] = haproxy_interface_ip($extaddr['extaddr']);
+ } else {
+ $iporalias = $extaddr['extaddr_custom'];
+ $a_ip = haproxy_addressoralias_to_list($iporalias);
+ }
+ if ($extaddr['extaddr_ssl'] == 'yes')
+ $ssl = $ssl_info;
+ else
+ $ssl = "";
+
+ foreach($a_ip as $ip) {
+ $portsnumeric = group_ports(haproxy_portoralias_to_list($extaddr['extaddr_port']));
+ if (is_array($portsnumeric)) {
+ foreach($portsnumeric as $portnumeric) {
+ $portnumeric = str_replace(":","-",$portnumeric);
+ $newitem = array();
+ $newitem['addr'] = $ip;
+ $newitem['port'] = $portnumeric;
+ $newitem['extaddr_ssl'] = $extaddr['extaddr_ssl'];
+ $newitem['extaddr_advanced'] = $extaddr['extaddr_advanced'];
+ $result[] = $newitem;
+ }
+ }
+ }
+ }
+ return $result;
}
function haproxy_check_config() {
@@ -1599,17 +1734,20 @@ function haproxy_check_config() {
foreach($a_backends as $frontend) {
if (($frontend['status'] != 'active') || ($frontend['secondary'] == 'yes'))
continue;
- $ipport = get_frontend_ipport($frontend);
- if (isset($activefrontends[$ipport]))
- $issues['P_'.$ipport] = "Multiple primary frontends with IP:Port \"$ipport\"";
- else
- $activefrontends[$ipport] = true;
+ $ipports = get_frontend_ipport($frontend);
+ foreach($ipports as $ipport) {
+ $id = "{$ipport['addr']}:{$ipport['port']}";
+ if (isset($activefrontends[$id]))
+ $issues['P_'.$id] = "Multiple primary frontends with IP:Port \"$id\", use Shared-Frontends instead.";
+ else
+ $activefrontends[$id] = true;
+ }
}
foreach($a_backends as $frontend) {
if (($frontend['status'] != 'active') || ($frontend['secondary'] != 'yes'))
continue;
- $ipport = get_frontend_ipport($frontend);
- if (!isset($activefrontends[$ipport]))
+ $mainfrontend = get_primaryfrontend($frontend);
+ if (!isset($mainfrontend))
$issues['S_'.$frontend['name']] = "Secondary frontend \"{$frontend['name']}\" without active primary frontend.";
}
foreach ($issues as $item)
@@ -1621,6 +1759,8 @@ function get_haproxy_frontends($excludeitem="") {
global $config;
$a_frontend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
$result = array();
+ if(!is_array($a_frontend))
+ return $result;
foreach($a_frontend as &$frontend)
{
if ($frontend['secondary'])
@@ -1628,17 +1768,62 @@ function get_haproxy_frontends($excludeitem="") {
if ($frontend['name'] == $excludeitem)
continue;
- $serveradress = "{$frontend['extaddr']}:{$frontend['port']}";
- $result[$frontend['name']]['name'] = "{$frontend['name']} - {$frontend['type']} ({$serveradress})";
+ $serveraddress = get_frontend_ipport($frontend, true);
+ $serveradresstext = null;
+ foreach($serveraddress as $addr) {
+ $serveradresstext .=($serveradresstext == null ? "" : ", ") . "{$addr['addr']}:{$addr['port']}";
+ }
+ $result[$frontend['name']]['name'] = "{$frontend['name']} - {$frontend['type']} ({$serveradresstext})";
$result[$frontend['name']]['ref'] = &$frontend;
}
uasort($result, haproxy_compareByName);
return $result;
}
-function generate_cert_acl($crt, $defaultport, $nondefaultport){
- // The host header send by a browser will contain the portnumber when a nondefault port is used for the server side.
+function get_frontend_uses_ssl($frontend) {
+ $mainfrontend = get_primaryfrontend($frontend);
+ $ssl = false;
+ if (is_arrayset($mainfrontend,'a_extaddr','item')) {
+ foreach($mainfrontend['a_extaddr']['item'] as $extaddr) {
+ if ($extaddr['extaddr_ssl'] == 'yes') {
+ $ssl = true;
+ break;
+ }
+ }
+ }
+ if ($mainfrontend['name'] != $frontend['name'])
+ $ssl = $ssl && $frontend['ssloffload'] == 'yes';
+ return $ssl;
+}
+
+function get_frontend_uses_ssl_only($frontend) {
+ $mainfrontend = get_primaryfrontend($frontend);
+ if (is_arrayset($mainfrontend,'a_extaddr','item')) {
+ foreach($mainfrontend['a_extaddr']['item'] as $extaddr) {
+ if ($extaddr['extaddr_ssl'] != 'yes')
+ return false;
+ }
+ }
+ return true;
+}
+function haproxy_get_cert_acl($cert) {
+ $acl_item = array();
+
+ $cert_cn = cert_get_cn($cert['crt']);
+ $descr = haproxy_escape_acl_name($cert['descr']);
+ unset($cert);
+ $is_wildcard = substr($cert_cn, 0, 2) == "*.";
+ $cert_cn_regex = str_replace(".", "\.", $cert_cn); // escape '.' in regex.
+ $wild_regex = "";
+ if ($is_wildcard) {
+ $cert_cn_regex = "([^\.]*)" . substr($cert_cn_regex, 1);// match only subdomains directly under the wildcard
+ }
+ $cert_cn_regex = "^{$cert_cn_regex}(:([0-9]){1,5})?$";// match both with and without port.
+
+ $acl_item['descr'] = "Certificate ACL matches: {$cert_cn}";
+ $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_regex', 'value' => $cert_cn_regex, 'certacl' => true);
+ return $acl_item;
}
function get_frontend_acls($frontend) {
@@ -1655,7 +1840,7 @@ function get_frontend_acls($frontend) {
// Filter out acls for different modes
if ($acl['mode'] != '' && $acl['mode'] != strtolower($mainfrontend['type']))
continue;
-
+ $not = $entry['not'] == "yes" ? "not " : "";
$acl_item = array();
$acl_item['descr'] = $acl['name'] . ": " . $entry['value'];
$acl_item['ref'] = $entry;
@@ -1664,7 +1849,7 @@ function get_frontend_acls($frontend) {
}
}
- if (strtolower($mainfrontend['type']) == "http" && $mainfrontend['ssloffload']) {
+ if (get_frontend_uses_ssl($frontend)) {
$a_acl = &$frontend['ha_acls']['item'];
if(!is_array($a_acl))
$a_acl=array();
@@ -1674,44 +1859,14 @@ function get_frontend_acls($frontend) {
if (ifset($frontend['ssloffloadacl']) == 'yes' || ifset($frontend['ssloffloadaclnondefault']) == 'yes') {
$cert = lookup_cert($frontend['ssloffloadcert']);
- $cert_cn = cert_get_cn($cert['crt']);
- $descr = haproxy_escape_acl_name($cert['descr']);
- unset($cert);
-
- $acl_item = array();
- if (ifset($frontend['ssloffloadacl']) == 'yes' && ifset($frontend['ssloffloadaclnondefault']) == 'yes') {
- $acl_item['descr'] = "Certificate ACL match regex: ^{$cert_cn}(:([0-9]){1,5})?$";
- $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_regex', 'value' => "^{$cert_cn}(:([0-9]){1,5})?$");
- } elseif (ifset($frontend['ssloffloadaclnondefault']) == 'yes') {
- $acl_item['descr'] = "Certificate ACL starts with: {$cert_cn}:";
- $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_starts_with', 'value' => $cert_cn.":");
- } else {
- $acl_item['descr'] = "Certificate ACL match: {$cert_cn}";
- $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn);
- }
- $result[] = $acl_item;
+ $result[] = haproxy_get_cert_acl($cert);
}
- if (ifset($frontend['ssloffloadacladditional']) == 'yes' || ifset($frontend['ssloffloadacladditionalnondefault']) == 'yes') {
+ if (ifset($frontend['ssloffloadacladditional']) == 'yes') {
$certs = $frontend['ha_certificates']['item'];
if (is_array($certs)){
foreach($certs as $certref){
$cert = lookup_cert($certref['ssl_certificate']);
- $cert_cn = cert_get_cn($cert['crt']);
- $descr = haproxy_escape_acl_name($cert['descr']);
- unset($cert);
-
- $acl_item = array();
- if (ifset($frontend['ssloffloadacladditional']) == 'yes' && ifset($frontend['ssloffloadacladditionalnondefault']) == 'yes') {
- $acl_item['descr'] = "Certificate ACL match regex: ^{$cert_cn}(:([0-9]){1,5})?$";
- $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_regex', 'value' => "^({$cert_cn}(($)|(:.*)))");
- } elseif (ifset($frontend['ssloffloadacladditionalnondefault']) == 'yes') {
- $acl_item['descr'] = "Certificate ACL starts with: {$cert_cn}:";
- $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_starts_with', 'value' => $cert_cn.":");
- } else {
- $acl_item['descr'] = "Certificate ACL match: {$cert_cn}";
- $acl_item['ref'] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn);
- }
- $result[] = $acl_item;
+ $result[] = haproxy_get_cert_acl($cert);
}
}
}
diff --git a/config/haproxy-devel/haproxy.xml b/config/haproxy-devel/haproxy.xml
index acd934a7..27199ee4 100644
--- a/config/haproxy-devel/haproxy.xml
+++ b/config/haproxy-devel/haproxy.xml
@@ -90,6 +90,11 @@
<additional_files_needed>
<prefix>/usr/local/www/</prefix>
<chmod>077</chmod>
+ <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_files.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>077</chmod>
<item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_pools.php</item>
</additional_files_needed>
<additional_files_needed>
@@ -103,6 +108,11 @@
<item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_stats.php</item>
</additional_files_needed>
<additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>077</chmod>
+ <item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_templates.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
<prefix>/usr/local/pkg/</prefix>
<chmod>077</chmod>
<item>https://packages.pfsense.org/packages/config/haproxy-devel/haproxy_socketinfo.inc</item>
@@ -137,6 +147,16 @@
<chmod>077</chmod>
<item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg_haproxy_tabs.inc</item>
</additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>https://packages.pfsense.org/packages/config/haproxy-devel/pkg/haproxy_upgrade_config.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/javascript/</prefix>
+ <chmod>077</chmod>
+ <item>https://packages.pfsense.org/packages/config/haproxy-devel/www/javascript/haproxy_geturl.js</item>
+ </additional_files_needed>
<custom_delete_php_command>
</custom_delete_php_command>
<custom_add_php_command>
diff --git a/config/haproxy-devel/haproxy_files.php b/config/haproxy-devel/haproxy_files.php
new file mode 100644
index 00000000..4946a7be
--- /dev/null
+++ b/config/haproxy-devel/haproxy_files.php
@@ -0,0 +1,176 @@
+<?php
+/* $Id: load_balancer_virtual_server.php,v 1.6.2.1 2006/01/02 23:46:24 sullrich Exp $ */
+/*
+ haproxy_pools.php
+ part of pfSense (https://www.pfsense.org/)
+ Copyright (C) 2014 PiBa-NL
+ 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.
+*/
+$shortcut_section = "haproxy";
+require_once("guiconfig.inc");
+require_once("haproxy.inc");
+require_once("pkg_haproxy_tabs.inc");
+require_once("haproxy_htmllist.inc");
+
+$a_files = &$config['installedpackages']['haproxy']['files']['item'];
+if (!is_array($a_files)) $a_files = array();
+$a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+if (!is_array($a_pools)) $a_pools = array();
+
+
+$fields_files = array();
+$fields_files[0]['name']="name";
+$fields_files[0]['columnheader']="Name";
+$fields_files[0]['colwidth']="30%";
+$fields_files[0]['type']="textbox";
+$fields_files[0]['size']="20";
+
+$fields_files[1]['name']="content";
+$fields_files[1]['columnheader']="content";
+$fields_files[1]['colwidth']="70%";
+$fields_files[1]['type']="textarea";
+$fields_files[1]['size']="70";
+
+$fileslist = new HaproxyHtmlList("table_files", $fields_files);
+$fileslist->keyfield = "name";
+
+if ($_POST) {
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $result = haproxy_check_and_run($savemsg, true);
+ if ($result)
+ unlink_if_exists($d_haproxyconfdirty_path);
+ } else {
+ $a_files = $fileslist->haproxy_htmllist_get_values($fields_files);
+ $filedupcheck = array();
+
+ foreach($a_files as $key => $file) {
+ $name = $file['name'];
+ if (!preg_match("/^[a-zA-Z][a-zA-Z0-9\.\-_]*$/", $file['name']))
+ $input_errors[] = "The field 'Name' (".htmlspecialchars($file['name']).") contains invalid characters. Use only: a-zA-Z0-9.-_ and start with a letter";
+ if (isset($filedupcheck[$name]))
+ $input_errors[] = "Duplicate names are not allowed: " . htmlspecialchars($name);
+ $filedupcheck[$name] = true;
+ }
+
+ // replace references in backends to renamed 'files'
+ foreach($a_pools as &$backend) {
+ if (is_arrayset($backend,'errorfiles','item'))
+ foreach($backend['errorfiles']['item'] as &$errorfile) {
+ $found = false;
+ foreach($a_files as $key => $file) {
+ if ($errorfile['errorfile'] == $key) {
+ $errorfile['errorfile'] = $file['name'];
+ $found = true;
+ }
+ }
+ if (!$found)
+ $input_errors[] = "Errorfile marked for deletion: " . $errorfile['errorfile'] . " which is used in backend " . $backend['name'];
+ }
+ }
+ if (!$input_errors) {
+ // save config when no errors found
+ touch($d_haproxyconfdirty_path);
+ write_config($changedesc);
+ header("Location: haproxy_files.php");
+ exit;
+ }
+ }
+}
+
+$pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
+
+$pgtitle = "Services: HAProxy: Files";
+include("head.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<form action="haproxy_files.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_haproxyconfdirty_path)): ?>
+<?php print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");?><br/>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td class="tabnavtbl">
+ <?php
+ haproxy_display_top_tabs_active($haproxy_tab_array['haproxy'], "files");
+ ?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ Files can be used for errorfiles, that can return custom error pages in
+ case haproxy reports a error (like no available backend). The content needs
+ to be less than the buffer size which is typically 8kb.
+ There are 2 possible variables to use inside the template:
+ Put these variables in the content of the errorfile templates and they will be replaced by the actual errorcode / message. (include the curly braces around the text)<br/>
+ <b>{errorcode}</b> this represents the errorcode<br/>
+ <b>{errormsg}</b> this represents the human readable error<br/>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <?
+ $counter=0;
+ $fileslist->Draw($a_files);
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ &nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ </table>
+ </form>
+<script type="text/javascript">
+ totalrows = <?php echo $counter; ?>;
+<?
+ phparray_to_javascriptarray($fields_files,"fields_files",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name'));
+?>
+</script>
+
+<?php
+haproxy_htmllist_js();
+include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/haproxy-devel/haproxy_htmllist.inc b/config/haproxy-devel/haproxy_htmllist.inc
index 404e9fab..f873028e 100644
--- a/config/haproxy-devel/haproxy_htmllist.inc
+++ b/config/haproxy-devel/haproxy_htmllist.inc
@@ -34,193 +34,267 @@
require_once("config.inc");
require_once("haproxy_utils.inc");
-function haproxy_htmllist_get_values($html_list){
- $values = array();
- for($x=0; $x<99; $x++) {
- $value = array();
- $add_item = false;
- foreach($html_list as $item){
- $itemname = $item['name'];
- $value[$itemname] = $_POST[$itemname.$x];
- $add_item |= isset($_POST[$itemname.$x]);
+class HaproxyHtmlList
+{
+ /*
+ javascript 'events':
+ <tableId>_row_added(tableId, rowNr)
+ <tableId>_field_changed(tableId, rowNr, fieldId, field)
+ */
+
+ private $tablename = "";
+ private $fields = array();
+ public $editmode = false;
+ public $fields_details = null;
+ public $keyfield = "";
+
+ public function HaproxyHtmlList($tablename, $fields){
+ $this->tablename = $tablename;
+ $this->fields = $fields;
+ }
+
+ public function Draw($data){
+ $this->haproxy_htmllist($data, $this->fields, $this->editmode, $this->fields_details);
+ }
+
+ function haproxy_htmllist_get_values(){
+ $values = array();
+ for($x=0; $x<99; $x++) {
+ $value = array();
+ $add_item = false;
+ foreach($this->fields as $item){
+ $itemname = $item['name'];
+ $value[$itemname] = $_POST[$itemname.$x];
+ if ($item['type'] == 'textarea')
+ $value[$itemname] = base64_encode($value[$itemname]);
+ $add_item |= isset($_POST[$itemname.$x]);
+ }
+ if ($add_item) {
+ if ($this->keyfield != "") {
+ if (isset($_POST[$this->tablename."_key".$x]))
+ $key = $_POST[$this->tablename."_key".$x];
+ else
+ $key = $_POST[$this->keyfield.$x];
+
+ } else
+ $key = "";
+
+ if (isset($values[$key]))
+ $values[] = $value;
+ else
+ $values[$key] = $value;
+ }
}
- if ($add_item)
- $values[] = $value;
+ return $values;
}
- return $values;
-}
-function haproxy_htmllist_drawcell($item, $itemvalue, $editable, $itemnamenr = "") {
- $itemtype = $item['type'];
- if ($editable) {
+ private function haproxy_htmllist_drawcell($item, $itemvalue, $editable, $itemname, $counter) {
+ $itemnamenr = $itemname . $counter;
$itemtype = $item['type'];
- if ($itemtype == "select"){
- echo_html_select($itemnamenr, $item['items'], $itemvalue,"","updatevisibility();", "width:{$item['size']}");
- } else
- if ($itemtype == "checkbox"){
- $checked = $itemvalue=='yes' ? " checked" : "";
- echo "<input name='$itemnamenr' id='$itemnamenr' type='checkbox'$checked value='yes' size='{$item['size']}' />";
- } else
- echo "<input name='$itemnamenr' id='$itemnamenr' type='text' value='{$itemvalue}' size='{$item['size']}' />";
- } else {
- if ($itemtype == "select"){
- echo $item['items'][$itemvalue]['name'];
- } else
- if ($itemtype == "checkbox"){
- echo $itemvalue=='yes' ? gettext('yes') : gettext('no');
- } else
- echo $itemvalue;
+ if ($editable) {
+ $itemtype = $item['type'];
+ if ($itemtype == "select"){
+ echo_html_select($itemnamenr, $item['items'], $itemvalue,"","html_listitem_change(\"{$this->tablename}\",\"{$itemname}\",\"{$counter}\",this);", "width:{$item['size']}");
+ } else
+ if ($itemtype == "checkbox"){
+ $checked = $itemvalue=='yes' ? " checked" : "";
+ echo "<input onclick='html_listitem_change(\"{$this->tablename}\",\"{$itemname}\",\"{$counter}\",this);' name='$itemnamenr' id='$itemnamenr' type='checkbox'$checked value='yes' size='{$item['size']}' />";
+ } else
+ if ($itemtype == "textarea"){
+ echo "<textarea name='$itemnamenr' id='$itemnamenr' type='text' cols='{$item['size']}' rows='10'>";
+ echo htmlspecialchars(base64_decode($itemvalue));
+ echo "</textarea>";
+ } else
+ echo "<input name='$itemnamenr' id='$itemnamenr' type='text' value='{$itemvalue}' size='{$item['size']}' />";
+ } else {
+ if ($itemtype == "select"){
+ echo $item['items'][$itemvalue]['name'];
+ } else
+ if ($itemtype == "checkbox"){
+ echo $itemvalue=='yes' ? gettext('yes') : gettext('no');
+ } else
+ if ($itemtype == "textarea"){
+ echo htmlspecialchars(base64_decode($itemvalue));
+ } else
+ echo htmlspecialchars($itemvalue);
+ }
}
-}
-function haproxy_htmllist($tablename,$rowvalues,$items,$editstate=false,$itemdetails=null){
- global $g, $counter;
- echo "<table class='' width='100%' cellpadding='0' cellspacing='0' id='$tablename'>
- <tr>";
- foreach($items as $item){
- echo "<td width='{$item['colwidth']}' class='listhdrr'>{$item['columnheader']}</td>";
- }
- echo "<td width='5%' class=''></td>
- </tr>";
- if (is_array($rowvalues)){
- foreach($rowvalues as $value){
- if (!$editstate) {
- echo "<tr id='tr_view_$counter' ondblclick='editRow($counter); return false;' >";
- $leftitem = true;
- foreach($items as $item) {
- $tdclass = $leftitem ? "vtable listlr" : "vtable listr";
- echo "<td class='$tdclass'>";
+ function haproxy_htmllist($rowvalues,$items,$editstate=false,$itemdetails=null){
+ $tablename = $this->tablename;
+ global $g, $counter;
+ echo "<table class='' width='100%' cellpadding='0' cellspacing='0' id='$tablename'>
+ <tr>";
+ foreach($items as $item){
+ echo "<td width='{$item['colwidth']}' class='listhdrr'>{$item['columnheader']}</td>";
+ }
+ echo "<td width='5%' class=''></td>
+ </tr>";
+ if (is_array($rowvalues)){
+ foreach($rowvalues as $keyid => $value){
+ if ($this->keyfield != "") {
+ if (preg_match("/[^0-9]/", $keyid))
+ $itemvalue = $keyid;
+ else
+ $itemvalue = $value[$this->keyfield];
+ $key = "<input name='{$tablename}_key{$counter}' id='{$tablename}_key{$counter}' type='hidden' value='{$itemvalue}'>";
+ } else
+ $key = "";
+
+ if (!$editstate) {
+ echo "<tr id='tr_view_$counter' ondblclick='editRow($counter); return false;' >";
+ $leftitem = true;
+ foreach($items as $item) {
+ $tdclass = $leftitem ? "vtable listlr" : "vtable listr";
+ echo "<td class='$tdclass'>";
+ $itemname = $item['name'];
+ $itemvalue = $value[$itemname];
+ if (isset($item['customdrawcell'])) {
+ $item['customdrawcell']($item, $itemvalue, false);
+ } else
+ $this->haproxy_htmllist_drawcell($item, $itemvalue, false, $itemname, $counter);
+ echo "</td>";
+ $leftitem = false;
+
+ }
+ echo "
+ <td class='list'>
+ <table border='0' cellspacing='0' cellpadding='1'><tr>
+ <td valign='middle'>
+ <img src='/themes/{$g['theme']}/images/icons/icon_e.gif' title='edit entry' width='17' height='17' border='0' onclick='editRow($counter); return false;' />
+ </td>
+ <td valign='middle'>
+ <img src='/themes/{$g['theme']}/images/icons/icon_x.gif' title='delete entry' width='17' height='17' border='0' onclick='deleteRow($counter, \"$tablename\"); return false;' />
+ </td>
+ <td valign='middle'>
+ <img src='/themes/{$g['theme']}/images/icons/icon_plus.gif' title='duplicate entry' width='17' height='17' border='0' onclick='dupRow($counter, \"$tablename\"); return false;' />
+ </td></tr></table>
+ </td>";
+ echo "</tr>";
+ }
+ $displaystyle = $editstate ? "" : "display: none;";
+ echo "<tr id='tr_edit_$counter' style='$displaystyle'>";
+ foreach($items as $item){
$itemname = $item['name'];
- $itemvalue = $value[$itemname];
+ $itemvalue = $value[$itemname];
+ echo "<td class='vtable'>".$key;
if (isset($item['customdrawcell'])) {
- $item['customdrawcell']($item, $itemvalue, false);
+ $item['customdrawcell']($item, $itemvalue, true, $item['name'].$counter);
} else
- haproxy_htmllist_drawcell($item, $itemvalue, false);
+ $this->haproxy_htmllist_drawcell($item, $itemvalue, true, $itemname, $counter);
echo "</td>";
- $leftitem = false;
+ $key = "";
}
echo "
<td class='list'>
<table border='0' cellspacing='0' cellpadding='1'><tr>
<td valign='middle'>
- <img src='/themes/{$g['theme']}/images/icons/icon_e.gif' title='edit entry' width='17' height='17' border='0' onclick='editRow($counter); return false;' />
- </td>
- <td valign='middle'>
- <img src='/themes/{$g['theme']}/images/icons/icon_x.gif' title='delete entry' width='17' height='17' border='0' onclick='deleteRow($counter, \"$tablename\"); return false;' />
+ <img src='/themes/{$g['theme']}/images/icons/icon_x.gif' title='delete entry' width='17' height='17' border='0' onclick='removeRow(this); return false;' />
</td>
<td valign='middle'>
<img src='/themes/{$g['theme']}/images/icons/icon_plus.gif' title='duplicate entry' width='17' height='17' border='0' onclick='dupRow($counter, \"$tablename\"); return false;' />
</td></tr></table>
</td>";
echo "</tr>";
- }
- $displaystyle = $editstate ? "" : "display: none;";
- echo "<tr id='tr_edit_$counter' style='$displaystyle'>";
- foreach($items as $item){
- $itemname = $item['name'];
- $itemvalue = $value[$itemname];
- $itemnamenr = $itemname . $counter;
- echo "<td class='vtable'>";
- if (isset($item['customdrawcell'])) {
- $item['customdrawcell']($item, $itemvalue, true, $itemnamenr);
- } else
- haproxy_htmllist_drawcell($item, $itemvalue, true, $itemnamenr);
- echo "</td>";
- }
- echo "
- <td class='list'>
- <table border='0' cellspacing='0' cellpadding='1'><tr>
- <td valign='middle'>
- <img src='/themes/{$g['theme']}/images/icons/icon_x.gif' title='delete entry' width='17' height='17' border='0' onclick='removeRow(this); return false;' />
- </td>
- <td valign='middle'>
- <img src='/themes/{$g['theme']}/images/icons/icon_plus.gif' title='duplicate entry' width='17' height='17' border='0' onclick='dupRow($counter, \"$tablename\"); return false;' />
- </td></tr></table>
- </td>";
- echo "</tr>";
- if (isset($itemdetails)) {
- $colspan = count($items)-1;
- echo "<tr id='tr_viewdetail_$counter'>";
- ?>
- <td class='vtable listlr' style='border-bottom-width: medium;vertical-align:top;'>
- <div style="position:relative;float:right;width:11px;height:11px;">
- <a onclick="htmltable_toggle_details('<?="htmltable_{$tablename}_{$counter}_details"?>')">
- <img id="htmltable_<?="{$tablename}_{$counter}"?>_details_off" alt="Expand advanced server settings"
- src="tree/plus.gif" style="clip:rect(19px 13px 30px 2px); top:-19px;position:absolute;"/>
- </a>
- </div>
- </td>
- <?
- echo "<td class='vtable listr' colspan='$colspan' style='border-bottom-width: medium;'>";
- $itemnr = 0;
- echo "<div id='htmltable_{$tablename}_{$counter}_details_view'>";
- $itemcount = count($itemdetails);
- foreach($itemdetails as $item) {
- echo "<div style='float: left;padding-right: 2px;'>";
- $tdclass = "";//$leftitem ? "vtable listlr" : "vtable listr";
- echo $item['columnheader'] . ": ";
- $itemname = $item['name'];
- $itemvalue = $value[$itemname];
- if (isset($item['customdrawcell'])) {
- $item['customdrawcell']($item, $itemvalue, false);
- } else
- haproxy_htmllist_drawcell($item, $itemvalue, false);
- $leftitem = false;
- $itemnr++;
- if ($itemcount != $itemnr)
- echo ", ";
+ if (isset($itemdetails)) {
+ $colspan = count($items)-1;
+ echo "<tr id='tr_viewdetail_$counter'>";
+ ?>
+ <td class='vtable listlr' style='border-bottom-width: medium;vertical-align:top;'>
+ <div style="position:relative;float:right;width:11px;height:11px;">
+ <a onclick="htmltable_toggle_details('<?="htmltable_{$tablename}_{$counter}_details"?>')">
+ <img id="htmltable_<?="{$tablename}_{$counter}"?>_details_off" alt="Expand advanced server settings"
+ src="tree/plus.gif" style="clip:rect(19px 13px 30px 2px); top:-19px;position:absolute;"/>
+ </a>
+ </div>
+ </td>
+ <?
+ echo "<td class='vtable listr' colspan='$colspan' style='border-bottom-width: medium;'>";
+ $itemnr = 0;
+ echo "<div id='htmltable_{$tablename}_{$counter}_details_view'>";
+ $itemcount = count($itemdetails);
+ foreach($itemdetails as $item) {
+ echo "<div style='float: left;padding-right: 2px;'>";
+ $tdclass = "";//$leftitem ? "vtable listlr" : "vtable listr";
+ echo $item['columnheader'] . ": ";
+ $itemname = $item['name'];
+ $itemvalue = $value[$itemname];
+ if (isset($item['customdrawcell'])) {
+ $item['customdrawcell']($item, $itemvalue, false);
+ } else
+ $this->haproxy_htmllist_drawcell($item, $itemvalue, false, $itemname, $counter);
+ $leftitem = false;
+ $itemnr++;
+ if ($itemcount != $itemnr)
+ echo ", ";
+ echo "</div>";
+ }
+ echo "</div>";
+ echo "<div id='htmltable_{$tablename}_{$counter}_details_edit' style='display:none;'>";
+ echo "<table class='tabcont' style='border-collapse:collapse' border='1' cellspacing='0' >";
+ $leftitem = true;
+ foreach($itemdetails as $item) {
+ echo "<tr id='tr_edititemdetails_$counter' ondblclick='editRow($counter); return false;'>";
+ $tdclass = "";//$leftitem ? "vtable listlr" : "vtable listr";
+ echo "<td style='border-right:0' class='$tdclass'>";
+ echo "{$item['columnheader']}: ";
+ echo "</td>";
+ echo "<td style='border-left:0' class='$tdclass'>";
+ $itemname = $item['name'];
+ $itemvalue = $value[$itemname];
+ echo "{$item['description']}<br/>";
+ if (isset($item['customdrawcell'])) {
+ $item['customdrawcell']($item, $itemvalue, true, $itemname . $counter);
+ } else
+ $this->haproxy_htmllist_drawcell($item, $itemvalue, true, $itemname, $counter);
+ echo "</td>";
+ $leftitem = false;
+ echo "</tr>";
+ }
+ echo "</table>";
echo "</div>";
- }
- echo "</div>";
- echo "<div id='htmltable_{$tablename}_{$counter}_details_edit' style='display:none;'>";
- echo "<table class='tabcont' style='border-collapse:collapse' border='1' cellspacing='0' >";
- $leftitem = true;
- foreach($itemdetails as $item) {
- echo "<tr id='tr_edititemdetails_$counter' ondblclick='editRow($counter); return false;'>";
- $tdclass = "";//$leftitem ? "vtable listlr" : "vtable listr";
- echo "<td style='border-right:0' class='$tdclass'>";
- echo "{$item['columnheader']}: ";
echo "</td>";
- echo "<td style='border-left:0' class='$tdclass'>";
- $itemname = $item['name'];
- $itemvalue = $value[$itemname];
- $itemnamenr = $itemname . $counter;
- echo "{$item['description']}<br/>";
- if (isset($item['customdrawcell'])) {
- $item['customdrawcell']($item, $itemvalue, true, $itemnamenr);
- } else
- haproxy_htmllist_drawcell($item, $itemvalue, true, $itemnamenr);
+ echo "</tr>";
+ }
+ if (isset($itemdetails)) {
+ $colspan = count($items)-1;
+ echo "<tr id='htmltable_{$tablename}_{$counter}_details' style='$displaystyle' >";
+ echo "<td class='vtable listlr' style='border-bottom-width: medium;'> </td>";
+ echo "<td class='vtable listr' colspan='$colspan' style='border-bottom-width: medium;'>";
echo "</td>";
- $leftitem = false;
- echo "</tr>";
+ echo "</tr>";
}
- echo "</table>";
- echo "</div>";
- echo "</td>";
- echo "</tr>";
- }
- if (isset($itemdetails)) {
- $colspan = count($items)-1;
- echo "<tr id='htmltable_{$tablename}_{$counter}_details' style='$displaystyle' >";
- echo "<td class='vtable listlr' style='border-bottom-width: medium;'> </td>";
- echo "<td class='vtable listr' colspan='$colspan' style='border-bottom-width: medium;'>";
- echo "</td>";
- echo "</tr>";
- }
-
-
-
- $counter++;
+
+ $counter++;
+ }
}
+ echo "</table>
+ <a onclick='javascript:addRowTo(\"$tablename\"); return false;' href='#'>
+ <img border='0' src='/themes/{$g['theme']}/images/icons/icon_plus.gif' alt='' title='add another entry' />
+ </a>";
}
- echo "</table>
- <a onclick='javascript:addRowTo(\"$tablename\"); return false;' href='#'>
- <img border='0' src='/themes/{$g['theme']}/images/icons/icon_plus.gif' alt='' title='add another entry' />
- </a>";
+}
+
+function haproxy_htmllist($tablename,$rowvalues,$items,$editstate=false,$itemdetails=null){
+ $list = new HaproxyHtmlList($tablename, $items);
+ $list->haproxy_htmllist($rowvalues, $items, $editstate, $itemdetails);
+}
+
+function haproxy_htmllist_get_values($html_list){
+ $list = new HaproxyHtmlList("-", $html_list);
+ return $list->haproxy_htmllist_get_values();
}
function haproxy_htmllist_js(){
-?><script type="text/javascript">
+?><script type="text/javascript">
+ function html_listitem_change(tableId, fieldId, rowNr, field) {
+ javascript_event = tableId + "_listitem_change";
+ var fn = window[javascript_event];
+ if (typeof fn === 'function'){
+ fn(tableId, fieldId, rowNr, field);
+ }
+ }
+
function htmllist_get_select_items(prefix,tableId) {
var items;
var i = tableId.lastIndexOf('_');
@@ -248,14 +322,21 @@ function haproxy_htmllist_js(){
td.innerHTML="<input size='" + items[i]['size'] + "' name='" + items[i]['name'] + totalrows +
"' id='" + items[i]['name'] + totalrows +
"'><\/input> ";
+ } else if(items[i]['type'] == 'textarea') {
+ td.innerHTML="<textarea cols='" + items[i]['size'] + "' rows='30' name='" + items[i]['name'] + totalrows +
+ "' id='" + items[i]['name'] + totalrows +
+ "'><\/textarea> ";
} else if(items[i]['type'] == 'select') {
seltext = htmllist_get_select_options(tableId, items[i]['name']);
td.innerHTML="<select style='width:" + items[i]['size'] + "' name='" + items[i]['name'] + totalrows +
- "' id='" + items[i]['name'] + totalrows +
- "'>" + seltext + "<\/select> ";
+ "' id='" + items[i]['name'] + totalrows + "' "+
+ "onchange='html_listitem_change(\""+tableId+"\",\""+items[i]['name']+"\",\""+totalrows+"\",this);' " +
+ ">" + seltext + "<\/select> ";
} else {
- td.innerHTML="<input type='checkbox' name='" + items[i]['name'] + totalrows +
- "' id='" + items[i]['name'] + totalrows + "' value='yes'><\/input> ";
+ td.innerHTML="<input type='checkbox' name='" + items[i]['name'] + totalrows +"'"+
+ "id='" + items[i]['name'] + totalrows + "' "+
+ "onclick='html_listitem_change(\""+tableId+"\",\""+items[i]['name']+"\",\""+totalrows+"\",this);' " +
+ "value='yes'><\/input> ";
}
tr.appendChild(td);
}
@@ -290,6 +371,12 @@ function haproxy_htmllist_js(){
td.appendChild(btable);
tr.appendChild(td);
tbody.appendChild(tr);
+
+ javascript_row_added = tableId + "_row_added";
+ var fn = window[javascript_row_added];
+ if (typeof fn === 'function'){
+ fn(tableId, totalrows);
+ }
});
})();
function dupRow(rowId, tableId) {
@@ -316,6 +403,11 @@ function haproxy_htmllist_js(){
else
newEl.value = dupEl.value;
}
+ javascript_row_added = tableId + "_row_added";
+ var fn = window[javascript_row_added];
+ if (typeof fn === 'function'){
+ fn(tableId, totalrows);
+ }
}
function editRow(num) {
var trview = document.getElementById('tr_view_' + num);
@@ -327,9 +419,12 @@ function haproxy_htmllist_js(){
var view = document.getElementById("tr_view_" + rowId);
var viewdetail = document.getElementById("tr_viewdetail_" + rowId);
var edit = document.getElementById("tr_edit_" + rowId);
- view.parentNode.removeChild(view);
- viewdetail.parentNode.removeChild(viewdetail);
- edit.parentNode.removeChild(edit);
+ if (view)
+ view.parentNode.removeChild(view);
+ if (viewdetail)
+ viewdetail.parentNode.removeChild(viewdetail);
+ if (edit)
+ edit.parentNode.removeChild(edit);
}
function removeRow(el) {
var cel;
diff --git a/config/haproxy-devel/haproxy_listeners.php b/config/haproxy-devel/haproxy_listeners.php
index 1deabdbb..ef7e01c4 100644
--- a/config/haproxy-devel/haproxy_listeners.php
+++ b/config/haproxy-devel/haproxy_listeners.php
@@ -3,7 +3,7 @@
/*
haproxy_listeners.php
part of pfSense (https://www.pfsense.org/)
- Copyright (C) 2013 PiBa-NL
+ Copyright (C) 2013-2015 PiBa-NL
Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com>
All rights reserved.
@@ -36,11 +36,34 @@ require_once("certs.inc");
require_once("haproxy_utils.inc");
require_once("pkg_haproxy_tabs.inc");
+$changedesc = "Services: HAProxy: Frontends";
+
if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
$config['installedpackages']['haproxy']['ha_backends']['item'] = array();
}
$a_frontend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+if($_GET['action'] == "toggle") {
+ $id = $_GET['id'];
+ echo "$id|";
+ if (isset($a_frontend[get_frontend_id($id)])) {
+ $frontent = &$a_frontend[get_frontend_id($id)];
+ if ($frontent['status'] != "disabled"){
+ $frontent['status'] = 'disabled';
+ echo "0|";
+ }else{
+ $frontent['status'] = 'active';
+ echo "1|";
+ }
+ $changedesc .= " set frontend '$id' status to: {$frontent['status']}";
+
+ touch($d_haproxyconfdirty_path);
+ write_config($changedesc);
+ }
+ echo "ok|";
+ exit;
+}
+
if ($_POST) {
$pconfig = $_POST;
@@ -70,10 +93,6 @@ if ($_GET['act'] == "del") {
}
}
-$pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
-if ($pf_version < 2.0)
- $one_two = true;
-
$pgtitle = "Services: HAProxy: Frontends";
include("head.inc");
@@ -81,14 +100,37 @@ include("head.inc");
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<?php include("fbegin.inc"); ?>
<form action="haproxy_listeners.php" method="post">
-<?php if($one_two): ?>
-<p class="pgtitle"><?=$pgtitle?></p>
-<?php endif; ?>
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if ($savemsg) print_info_box($savemsg); ?>
-<?php if (file_exists($d_haproxyconfdirty_path)): ?>
-<?php print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");?><br/>
-<?php endif; ?>
+<?php
+$display_apply = file_exists($d_haproxyconfdirty_path) ? "" : "none";
+echo "<div id='showapplysettings' style='display: {$display_apply};'>";
+print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");
+echo "<br/></div>";
+?>
+<script type="text/javascript" language="javascript" src="/javascript/haproxy_geturl.js"></script>
+<script language="javascript">
+function toggle_on(button, image) {
+ var item = document.getElementById(button);
+ item.src = image;
+}
+
+function js_callback(req) {
+ showapplysettings.style.display = 'block';
+ if(req.content != '') {
+ var itemsplit = req.content.split("|");
+ buttonid = itemsplit[0];
+ enabled = itemsplit[1];
+ if (enabled == 1){
+ img = 'pass';
+ } else {
+ img = 'reject';
+ }
+ toggle_on('btn_'+buttonid, './themes/<?=$g['theme'];?>/images/icons/icon_'+img+'.gif');
+ }
+}
+</script>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="tabnavtbl">
<?php
@@ -100,6 +142,7 @@ include("head.inc");
<div id="mainarea">
<table class="tabcont sortable" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
+ <td width="5%" class="listhdrr">On</td>
<td width="5%" class="listhdrr">Primary</td>
<td width="20%" class="listhdrr">Advanced</td>
<td width="20%" class="listhdrr">Name</td>
@@ -107,7 +150,7 @@ include("head.inc");
<td width="20%" class="listhdrr">Address</td>
<td width="5%" class="listhdrr">Type</td>
<td width="10%" class="listhdrr">Backend</td>
- <td width="20%" class="listhdrr">Parent</td>
+ <!--td width="20%" class="listhdrr">Parent</td-->
<td width="5%" class="list"></td>
</tr>
<?php
@@ -124,10 +167,11 @@ include("head.inc");
$a_frontend_grouped = array();
foreach($a_frontend as &$frontend2) {
$mainfrontend = get_primaryfrontend($frontend2);
+ $mainname = $mainfrontend['name'];
$ipport = get_frontend_ipport($frontend2, true);
$frontend2['ipport'] = $ipport;
$frontend2['type'] = $mainfrontend['type'];
- $a_frontend_grouped[$ipport][] = $frontend2;
+ $a_frontend_grouped[$mainname][] = $frontend2;
}
ksort($a_frontend_grouped);
@@ -142,16 +186,29 @@ include("head.inc");
if ((count($a_frontend) > 1 || $last_frontend_shared) && !$first) {
?> <tr class="<?=$textgray?>"><td colspan="7">&nbsp;</td></tr> <?
}
+ $first = false;
$last_frontend_shared = count($a_frontend) > 1;
foreach ($a_frontend as $frontend) {
$frontendname = $frontend['name'];
$textgray = $frontend['status'] != 'active' ? " gray" : "";
?>
<tr class="<?=$textgray?>">
- <td class="listlr" style="<?=$frontend['secondary']=='yes'?"visibility:hidden;":""?>" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <?
+ if ($frontend['status']=='disabled'){
+ $iconfn = "reject";
+ } else {
+ $iconfn = "pass";
+ }?>
+ <a href='javascript:getURL("?id=<?=$frontendname;?>&amp;action=toggle&amp;", js_callback);'>
+ <img id="btn_<?=$frontendname;?>" src="./themes/<?= $g['theme']; ?>/images/icons/icon_<?=$iconfn;?>.gif" width="11" height="11" border="0"
+ title="<?=gettext("click to toggle enable/disable this frontend");?>" alt="icon" />
+ </a>
+ </td>
+ <td class="listr" style="<?=$frontend['secondary']=='yes'?"visibility:hidden;":""?>" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
<?=$frontend['secondary']!='yes'?"yes":"no";?>
</td>
- <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
<?
$acls = get_frontend_acls($frontend);
$isaclset = "";
@@ -161,7 +218,7 @@ include("head.inc");
if ($isaclset)
echo "<img src=\"$img_acl\" title=\"" . gettext("acl's used") . ": {$isaclset}\" border=\"0\" />";
- if (strtolower($frontend['type']) == "http" && $frontend['ssloffload']) {
+ if (get_frontend_uses_ssl($frontend)) {
$cert = lookup_cert($frontend['ssloffloadcert']);
$descr = htmlspecialchars($cert['descr']);
if (is_array($frontend['ha_certificates']) && is_array($frontend['ha_certificates']['item'])) {
@@ -182,8 +239,9 @@ include("head.inc");
if ($isadvset)
echo "<img src=\"$img_adv\" title=\"" . gettext("Advanced settings set") . ": {$isadvset}\" border=\"0\" />";
+ $backend_serverpool_hint = "";
$backend_serverpool = $frontend['backend_serverpool'];
- $backend = get_backend($backend_serverpool );
+ $backend = get_backend($backend_serverpool);
if ($backend && is_array($backend['ha_servers']) && is_array($backend['ha_servers']['item'])){
$servers = $backend['ha_servers']['item'];
$backend_serverpool_hint = gettext("Servers in pool:");
@@ -198,28 +256,53 @@ include("head.inc");
}
?>
</td>
- <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
<?=$frontend['name'];?>
</td>
- <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
<?=$frontend['desc'];?>
</td>
- <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
- <?=str_replace(" ","&nbsp;",$frontend['ipport']);?>
+ <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <?
+ $first = true;
+ foreach($frontend['ipport'] as $addr) {
+ if (!$first)
+ print "<br/>";
+ print "<div style='white-space:nowrap;'>";
+ print "{$addr['addr']}:{$addr['port']}";
+ if ($addr['ssl'] == 'yes') {
+ echo '<img src="'.$img_cert.'" title="SSL offloading" alt="SSL" border="0" height="11" width="11" />';
+ }
+ print "</div";
+ $first = false;
+ }
+ ?>
</td>
- <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
- <?=$frontend['type']?>
+ <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <?
+ if ($frontend['type'] == 'http') {
+ $mainfrontend = get_primaryfrontend($frontend);
+ $sslused = get_frontend_uses_ssl($mainfrontend);
+ $httpused = !get_frontend_uses_ssl_only($frontend);
+ if ($httpused)
+ echo "http";
+ if ($sslused) {
+ echo ($httpused ? "/" : "") . "https";
+ }
+ } else
+ echo $a_frontendmode[$frontend['type']]['shortname'];
+ ?>
</td>
- <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <td class="listr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
<div title='<?=$backend_serverpool_hint;?>'>
<a href="haproxy_pool_edit.php?id=<?=$frontend['backend_serverpool']?>">
<?=$frontend['backend_serverpool']?>
</a>
</div>
</td>
- <td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
+ <!--td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
<?=$frontend['secondary'] == 'yes' ? $frontend['primary_frontend'] : "";?>
- </td>
+ </td-->
<td class="list" nowrap>
<table border="0" cellspacing="0" cellpadding="1">
<tr>
diff --git a/config/haproxy-devel/haproxy_listeners_edit.php b/config/haproxy-devel/haproxy_listeners_edit.php
index d243ffb1..a13eca80 100644
--- a/config/haproxy-devel/haproxy_listeners_edit.php
+++ b/config/haproxy-devel/haproxy_listeners_edit.php
@@ -6,6 +6,7 @@
Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com>
Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com>
Copyright (C) 2013 PiBa-NL merging (some of the) "haproxy-devel" changes from: Marcello Coutinho <marcellocoutinho@gmail.com>
+ Copyright (C) 2013-2015 PiBa-NL
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -63,12 +64,15 @@ if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
$a_backend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
$a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+if (!is_array($a_pools))
+ $a_pools = array();
uasort($a_pools, haproxy_compareByName);
global $simplefields;
$simplefields = array('name','desc','status','secondary','primary_frontend','type','forwardfor','httpclose','extaddr','backend_serverpool',
'max_connections','client_timeout','port','ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','ssloffloadaclnondefault','advanced_bind',
'ssloffloadacladditional','ssloffloadacladditionalnondefault',
+ 'socket-stats',
'dontlognull','dontlog-normal','log-separate-errors','log-detailed');
if (isset($_POST['id']))
@@ -85,6 +89,10 @@ if (!is_numeric($id))
{
//default value for new items.
$pconfig['ssloffloadacl'] = "yes";
+ $new_item = array();
+ $new_item['extaddr'] = "wan_ipv4";
+ $new_item['extaddr_port'] = "80";
+ $pconfig['a_extaddr'][] = $new_item;
}
$servercerts = haproxy_get_certificates('server,user');
@@ -97,7 +105,7 @@ $fields_sslCertificates[0]['size']="500px";
$fields_sslCertificates[0]['items']=&$servercerts;
$certs_ca = haproxy_get_certificates('ca');
-$ca_none['']['name']="None";
+$ca_none['']['name']="(None), allows for client without a (valid) certificate to connect. Make sure to add appropriate acl's.";
$certs_ca = $ca_none + $certs_ca;
$fields_caCertificates=array();
$fields_caCertificates[0]['name']="cert_ca";
@@ -108,8 +116,8 @@ $fields_caCertificates[0]['size']="500px";
$fields_caCertificates[0]['items']=&$certs_ca;
$certs_crl = haproxy_get_crls();
-$ca_none['']['name']="None";
-$certs_crl = $ca_none + $certs_crl;
+//$ca_none['']['name']="None";
+//$certs_crl = $ca_none + $certs_crl;
$fields_crlCertificates=array();
$fields_crlCertificates[0]['name']="cert_crl";
$fields_crlCertificates[0]['columnheader']="Certificate revocation lists";
@@ -132,17 +140,56 @@ $fields_aclSelectionList[1]['type']="select";
$fields_aclSelectionList[1]['size']="10";
$fields_aclSelectionList[1]['items']=&$a_acltypes;
-$fields_aclSelectionList[2]['name']="value";
-$fields_aclSelectionList[2]['columnheader']="Value";
-$fields_aclSelectionList[2]['colwidth']="35%";
-$fields_aclSelectionList[2]['type']="textbox";
-$fields_aclSelectionList[2]['size']="35";
+$fields_aclSelectionList[2]['name']="not";
+$fields_aclSelectionList[2]['columnheader']="Not";
+$fields_aclSelectionList[2]['colwidth']="5%";
+$fields_aclSelectionList[2]['type']="checkbox";
+$fields_aclSelectionList[2]['size']="5";
+
+$fields_aclSelectionList[3]['name']="value";
+$fields_aclSelectionList[3]['columnheader']="Value";
+$fields_aclSelectionList[3]['colwidth']="35%";
+$fields_aclSelectionList[3]['type']="textbox";
+$fields_aclSelectionList[3]['size']="35";
+
+$interfaces = haproxy_get_bindable_interfaces();
+$interfaces_custom['custom']['name']="Use custom address:";
+$interfaces = $interfaces_custom + $interfaces;
+
+$fields_externalAddress=array();
+$fields_externalAddress[0]['name']="extaddr";
+$fields_externalAddress[0]['columnheader']="Listen address";
+$fields_externalAddress[0]['colwidth']="25%";
+$fields_externalAddress[0]['type']="select";
+$fields_externalAddress[0]['size']="200px";
+$fields_externalAddress[0]['items']=&$interfaces;
+$fields_externalAddress[1]['name']="extaddr_custom";
+$fields_externalAddress[1]['columnheader']="Custom address";
+$fields_externalAddress[1]['colwidth']="25%";
+$fields_externalAddress[1]['type']="textbox";
+$fields_externalAddress[1]['size']="30";
+$fields_externalAddress[2]['name']="extaddr_port";
+$fields_externalAddress[2]['columnheader']="Port";
+$fields_externalAddress[2]['colwidth']="5%";
+$fields_externalAddress[2]['type']="textbox";
+$fields_externalAddress[2]['size']="5";
+$fields_externalAddress[3]['name']="extaddr_ssl";
+$fields_externalAddress[3]['columnheader']="SSL Offloading";
+$fields_externalAddress[3]['colwidth']="10%";
+$fields_externalAddress[3]['type']="checkbox";
+$fields_externalAddress[3]['size']="50px";
+$fields_externalAddress[4]['name']="extaddr_advanced";
+$fields_externalAddress[4]['columnheader']="Advanced";
+$fields_externalAddress[4]['colwidth']="20%";
+$fields_externalAddress[4]['type']="textbox";
+$fields_externalAddress[4]['size']="30";
if (isset($id) && $a_backend[$id]) {
$pconfig['a_acl']=&$a_backend[$id]['ha_acls']['item'];
$pconfig['a_certificates']=&$a_backend[$id]['ha_certificates']['item'];
$pconfig['clientcert_ca']=&$a_backend[$id]['clientcert_ca']['item'];
$pconfig['clientcert_crl']=&$a_backend[$id]['clientcert_crl']['item'];
+ $pconfig['a_extaddr']=&$a_backend[$id]['a_extaddr']['item'];
$pconfig['advanced'] = base64_decode($a_backend[$id]['advanced']);
foreach($simplefields as $stat)
$pconfig[$stat] = $a_backend[$id][$stat];
@@ -164,8 +211,8 @@ if ($_POST) {
$pconfig = $_POST;
if ($pconfig['secondary'] != "yes") {
- $reqdfields = explode(" ", "name type port");
- $reqdfieldsn = explode(",", "Name,Type,Port");
+ $reqdfields = explode(" ", "name type");
+ $reqdfieldsn = explode(",", "Name,Type");
} else {
$reqdfields = explode(" ", "name");
$reqdfieldsn = explode(",", "Name");
@@ -208,6 +255,10 @@ if ($_POST) {
$a_acl = haproxy_htmllist_get_values($fields_aclSelectionList);
$pconfig['a_acl'] = $a_acl;
+ $a_extaddr = haproxy_htmllist_get_values($fields_externalAddress);
+ $pconfig['a_extaddr'] = $a_extaddr;
+
+
foreach($a_acl as $acl) {
$acl_name = $acl['name'];
$acl_value = $acl['value'];
@@ -247,6 +298,7 @@ if ($_POST) {
$backend['ha_certificates']['item'] = $a_certificates;
$backend['clientcert_ca']['item'] = $a_clientcert_ca;
$backend['clientcert_crl']['item'] = $a_clientcert_crl;
+ $backend['a_extaddr']['item'] = $a_extaddr;
if (isset($id) && $a_backend[$id]) {
$a_backend[$id] = $backend;
@@ -275,7 +327,6 @@ include("head.inc");
if (!isset($_GET['dup']))
$excludefrontend = $pconfig['name'];
$primaryfrontends = get_haproxy_frontends($excludefrontend);
-$interfaces = haproxy_get_bindable_interfaces();
?>
<style type="text/css">
@@ -329,6 +380,9 @@ $interfaces = haproxy_get_bindable_interfaces();
if (tableId == 'table_clientcert_crl'){
seltext = "<?=haproxy_js_select_options($certs_crl);?>";
}
+ if (tableId == 'table_extaddr'){
+ seltext = "<?=haproxy_js_select_options($interfaces);?>";
+ }
return seltext;
}
@@ -343,20 +397,26 @@ $interfaces = haproxy_get_bindable_interfaces();
}
}
}
-
function updatevisibility() {
d = document;
+ ssl = false;
ssloffload = d.getElementById("ssloffload");
+ for (i = 0; i < 99; i++) {
+ customEdit = document.getElementById("extaddr_ssl"+i);
+ if (customEdit && customEdit.checked)
+ ssl = true;
+ }
var type;
var secondary = d.getElementById("secondary");
var primary_frontend = d.getElementById("primary_frontend");
- if ((secondary !== null) && (secondary.checked))
+ if ((secondary !== null) && (secondary.checked)) {
type = primaryfrontends[primary_frontend.value]['ref']['type'];
- else
+ ssl = ssloffload.checked;
+ } else
type = d.getElementById("type").value;
- setCSSdisplay(".haproxy_ssloffloading_enabled", ssloffload.checked);
+ setCSSdisplay(".haproxy_ssloffloading_enabled", ssl);
setCSSdisplay(".haproxy_mode_http", type == "http");
if (secondary !== null) {
setCSSdisplay(".haproxy_primary", !secondary.checked);
@@ -481,25 +541,45 @@ $interfaces = haproxy_get_bindable_interfaces();
<tr class="haproxy_primary">
<td width="22%" valign="top" class="vncellreq">External address</td>
<td width="78%" class="vtable">
- <?
- echo_html_select('extaddr', $interfaces, $pconfig['extaddr']);
- ?>
+ <?
+ $counter=0;
+ $a_extaddr = $pconfig['a_extaddr'];
+ $htmllist_extadd = new HaproxyHtmlList("table_extaddr", $fields_externalAddress);
+ $htmllist_extadd->editmode = true;
+ $htmllist_extadd->Draw($a_extaddr);
+ ?>
+ <script type="text/javascript">
+ function table_extaddr_row_added(tableid, rowid){
+ new AutoSuggestControl(document.getElementById("extaddr_custom"+rowid), new StateSuggestions(address_array));
+ new AutoSuggestControl(document.getElementById("extaddr_port"+rowid), new StateSuggestions(port_array));
+ table_extaddr_listitem_change(tableid,"",rowid, null);//disables address when not set to custom.
+ }
+
+ function table_extaddr_listitem_change(tableId, fieldId, rowNr, field) {
+ if (fieldId == "extaddr" || fieldId == "") {
+ field = field || document.getElementById("extaddr"+rowNr);
+ customEdit = document.getElementById("extaddr_custom"+rowNr);
+ customdisabled = field.value == "custom" ? 0 : 1;
+ customEdit.disabled = customdisabled;
+ }
+ if (fieldId == "extaddr_ssl") {
+ updatevisibility();
+ }
+ }
+
+ </script>
<br />
<span class="vexpl">
If you want this rule to apply to another IP address than the IP address of the interface chosen above,
select it here (you need to define <a href="firewall_virtual_ip.php">Virtual IP</a> addresses on the first).
Also note that if you are trying to redirect connections on the LAN select the "any" option.
+
+ In the port to listen to, if you want to specify multiple ports, separate them with a comma (,). EXAMPLE: 80,8000
+ Or to listen on both 80 and 443 create 2 rows in the table.
</span>
</td>
</tr>
<tr class="haproxy_primary" align="left">
- <td width="22%" valign="top" class="vncellreq">External port</td>
- <td width="78%" class="vtable" colspan="2">
- <input name="port" id="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="10" maxlength="500" />
- <div>The port to listen to. To specify multiple ports, separate with a comma (,). EXAMPLE: 80,8000</div>
- </td>
- </tr>
- <tr class="haproxy_primary" align="left">
<td width="22%" valign="top" class="vncell">Max connections</td>
<td width="78%" class="vtable" colspan="2">
<input name="max_connections" type="text" <?if(isset($pconfig['max_connections'])) echo "value=\"{$pconfig['max_connections']}\"";?> size="10" maxlength="10" />
@@ -526,8 +606,8 @@ $interfaces = haproxy_get_bindable_interfaces();
<td width="22%" valign="top" class="vncellreq">Type</td>
<td width="78%" class="vtable" colspan="2">
<select name="type" id="type" onchange="updatevisibility();">
- <option value="http"<?php if($pconfig['type'] == "http") echo " SELECTED"; ?>>HTTP</option>
- <option value="https"<?php if($pconfig['type'] == "https") echo " SELECTED"; ?>>HTTPS</option>
+ <option value="http"<?php if($pconfig['type'] == "http") echo " SELECTED"; ?>>HTTP / HTTPS(offloading)</option>
+ <option value="https"<?php if($pconfig['type'] == "https") echo " SELECTED"; ?>>SSL / HTTPS(TCP mode)</option>
<option value="tcp"<?php if($pconfig['type'] == "tcp") echo " SELECTED"; ?>>TCP</option>
<option value="health"<?php if($pconfig['type'] == "health") echo " SELECTED"; ?>>Health</option>
</select><br/>
@@ -541,7 +621,6 @@ $interfaces = haproxy_get_bindable_interfaces();
<td width="22%" valign="top" class="vncell">Access Control lists</td>
<td width="78%" class="vtable" colspan="2" valign="top">
<?
- $counter=0;
$a_acl = $pconfig['a_acl'];
haproxy_htmllist("tableA_acltable", $a_acl, $fields_aclSelectionList, true);
?>
@@ -552,6 +631,17 @@ $interfaces = haproxy_get_bindable_interfaces();
</tr>
<tr class="haproxy_primary"><td>&nbsp;</td></tr>
<tr class="haproxy_primary">
+ <td colspan="2" valign="top" class="listtopic">Stats options</td>
+ </tr>
+ <tr class="haproxy_primary" align="left">
+ <td width="22%" valign="top" class="vncell">Separate sockets</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="socket-stats" name="socket-stats" type="checkbox" value="yes" <?php if ($pconfig['socket-stats']=='yes') echo "checked"; ?> onclick='updatevisibility();' />
+ Enable collecting &amp; providing separate statistics for each socket.
+ </td>
+ </tr>
+ <tr class="haproxy_primary"><td>&nbsp;</td></tr>
+ <tr class="haproxy_primary">
<td colspan="2" valign="top" class="listtopic">Logging options</td>
</tr>
<tr class="haproxy_primary" align="left">
@@ -613,10 +703,6 @@ $interfaces = haproxy_get_bindable_interfaces();
The 'forwardfor' option creates an HTTP 'X-Forwarded-For' header which
contains the client's IP address. This is useful to let the final web server
know what the client address was. (eg for statistics on domains)<br/>
- <br/>
- It is important to note that as long as HAProxy does not support keep-alive connections,
- only the first request of a connection will receive the header. For this reason,
- it is important to ensure that option httpclose is set when using this option.
</td>
</tr>
<tr align="left" class="haproxy_mode_http">
@@ -649,21 +735,24 @@ $interfaces = haproxy_get_bindable_interfaces();
<td>&nbsp;</td>
</tr>
</table>
- <table class="haproxy_mode_http" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <table class="haproxy_ssloffloading_enabled" width="100%" border="0" cellpadding="6" cellspacing="0">
<tr>
<td colspan="2" valign="top" class="listtopic">SSL Offloading</td>
</tr>
<tr align="left">
- <td width="22%" valign="top" class="vncell">Use Offloading</td>
<td width="78%" class="vtable" colspan="2">
- <input id="ssloffload" name="ssloffload" type="checkbox" value="yes" <?php if ($pconfig['ssloffload']=='yes') echo "checked";?> onclick="updatevisibility();" /><strong>Use Offloading</strong>
- <br/>
SSL Offloading will reduce web servers load by maintaining and encrypting connection with users on internet while sending and retrieving data without encrytion to internal servers.
Also more ACL rules and http logging may be configured when this option is used.
Certificates can be imported into the <a href="/system_camanager.php" target="_blank">pfSense "Certificate Authority Manager"</a>
Please be aware this possibly will not work with all web applications. Some applications will require setting the SSL checkbox on the backend server configurations so the connection to the webserver will also be a encrypted connection, in that case there will be a slight overall performance loss.
</td>
</tr>
+ <tr align="left" class="haproxy_secondary" >
+ <td width="22%" valign="top" class="vncell">Use Offloading</td>
+ <td width="78%" class="vtable" colspan="2">
+ <input id="ssloffload" name="ssloffload" type="checkbox" value="yes" <?php if ($pconfig['ssloffload']=='yes') echo "checked";?> onclick="updatevisibility();" /><strong>Specify additional certificates for this shared-frontend.</strong>
+ </td>
+ </tr>
<tr class="haproxy_ssloffloading_enabled" align="left">
<td width="22%" valign="top" class="vncell">Certificate</td>
<td width="78%" class="vtable" colspan="2">
@@ -671,10 +760,9 @@ $interfaces = haproxy_get_bindable_interfaces();
echo_html_select("ssloffloadcert", $servercerts, $pconfig['ssloffloadcert'], '<b>No Certificates defined.</b> <br/>Create one under <a href="system_certmanager.php">System &gt; Cert Manager</a>.');
?>
<br/>
- NOTE: choose the cert to use on this frontend.
+ Choose the cert to use on this frontend.
<br/>
- <input id="ssloffloadacl" name="ssloffloadacl" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacl']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. (host header matches 'CN')<br/>
- <input id="ssloffloadaclnondefault" name="ssloffloadaclnondefault" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadaclnondefault']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName for nondefault ports. (host header starts with 'CN:')
+ <input id="ssloffloadacl" name="ssloffloadacl" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacl']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. (host header matches the 'CN' of the certificate)<br/>
</td>
</tr>
<tr class="haproxy_ssloffloading_enabled">
@@ -686,8 +774,7 @@ $interfaces = haproxy_get_bindable_interfaces();
haproxy_htmllist("tableA_sslCertificates", $a_certificates, $fields_sslCertificates);
?>
<br/>
- <input id="ssloffloadacladditional" name="ssloffloadacladditional" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacladditional']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. (host header matches 'CN')<br/>
- <input id="ssloffloadacladditionalnondefault" name="ssloffloadacladditionalnondefault" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacladditionalnondefault']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName for nondefault ports. (host header starts with 'CN:')
+ <input id="ssloffloadacladditional" name="ssloffloadacladditional" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacladditional']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. (host header matches the 'CN' of the certificate)<br/>
</td>
</tr>
<tr class="haproxy_ssloffloading_enabled haproxy_primary" align="left">
@@ -700,7 +787,8 @@ $interfaces = haproxy_get_bindable_interfaces();
</td>
</tr>
<tr class="haproxy_ssloffloading_enabled haproxy_primary">
- <td class="vncell" colspan="2"><b>Client certificate verification options, leave this empty if you do want to ask for a client certificate</b></td>
+ <td class="vncell" colspan="2"><b>Client certificate verification options, leave this empty if you do not want to ask for a client certificate</b><br/>
+ The users that visit this site will need to load the client cert signed by one of the ca's listed below imported into their browser.</td>
</tr>
<tr class="haproxy_ssloffloading_enabled haproxy_primary">
<td width="22%" valign="top" class="vncell">Client verification CA certificates</td>
@@ -754,14 +842,24 @@ $interfaces = haproxy_get_bindable_interfaces();
phparray_to_javascriptarray($fields_caCertificates,"fields_ca",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name'));
phparray_to_javascriptarray($fields_crlCertificates,"fields_crl",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name'));
phparray_to_javascriptarray($fields_aclSelectionList,"fields_acltable",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name'));
+ phparray_to_javascriptarray($fields_externalAddress,"fields_extaddr",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name'));
?>
</script>
<script type="text/javascript">
totalrows = <?php echo $counter; ?>;
- updatevisibility();
- var customarray = <?= json_encode(get_alias_list(array("port", "url_ports", "urltable_ports"))) ?>;
- var oTextbox1 = new AutoSuggestControl(document.getElementById("port"), new StateSuggestions(customarray));
+ var port_array = <?= json_encode(get_alias_list(array("port", "url_ports", "urltable_ports"))) ?>;
+ var address_array = <?= json_encode(get_alias_list(array("host", "network", "openvpn", "urltable"))) ?>;
+
+
+ for(i=0;i < <?=count($a_extaddr)?>;i++){
+ new AutoSuggestControl(document.getElementById('extaddr_custom'+i), new StateSuggestions(address_array));
+ new AutoSuggestControl(document.getElementById('extaddr_port'+i), new StateSuggestions(port_array));
+ // Initially set fields disabled where needed
+ table_extaddr_listitem_change('table_extaddr','',i,null);
+ }
+
+ updatevisibility();
</script>
<?php
haproxy_htmllist_js();
diff --git a/config/haproxy-devel/haproxy_pool_edit.php b/config/haproxy-devel/haproxy_pool_edit.php
index 30079847..5e38b12d 100644
--- a/config/haproxy-devel/haproxy_pool_edit.php
+++ b/config/haproxy-devel/haproxy_pool_edit.php
@@ -42,6 +42,8 @@ if (!is_array($config['installedpackages']['haproxy']['ha_pools']['item'])) {
$a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+$a_files = haproxy_get_fileslist();
+
if (isset($_POST['id']))
$id = $_POST['id'];
else
@@ -172,6 +174,19 @@ $fields_servers_details[7]['colwidth']="15%";
$fields_servers_details[7]['type']="textbox";
$fields_servers_details[7]['size']="80";
+$fields_errorfile = array();
+$fields_errorfile[0]['name']="errorcode";
+$fields_errorfile[0]['columnheader']="errorcode(s)";
+$fields_errorfile[0]['colwidth']="15%";
+$fields_errorfile[0]['type']="textbox";
+$fields_errorfile[0]['size']="70px";
+$fields_errorfile[1]['name']="errorfile";
+$fields_errorfile[1]['columnheader']="Error Page";
+$fields_errorfile[1]['colwidth']="30%";
+$fields_errorfile[1]['type']="select";
+$fields_errorfile[1]['size']="170px";
+$fields_errorfile[1]['items']=&$a_files;
+
if (isset($id) && $a_pools[$id]) {
$pconfig['advanced'] = base64_decode($a_pools[$id]['advanced']);
$pconfig['advanced_backend'] = base64_decode($a_pools[$id]['advanced_backend']);
@@ -179,6 +194,9 @@ if (isset($id) && $a_pools[$id]) {
foreach($simplefields as $stat)
$pconfig[$stat] = $a_pools[$id][$stat];
+
+ $a_errorfiles = &$a_pools[$id]['errorfiles']['item'];
+ if (!is_array($a_errorfiles)) $a_errorfiles = array();
}
if (isset($_GET['dup']))
@@ -269,6 +287,8 @@ if ($_POST) {
$input_errors[] = "The field 'Port' value is not a number.";
}
+ $a_errorfiles = haproxy_htmllist_get_values($fields_errorfile);
+
if ($_POST['strict_transport_security'] !== "" && !is_numeric($_POST['strict_transport_security']))
$input_errors[] = "The field 'Strict-Transport-Security' is not empty or a number.";
@@ -356,6 +376,9 @@ foreach($simplefields as $field){
if (fieldname == 'forwardto')
return "<?=haproxy_js_select_options($primaryfrontends);?>";
else
+ if (fieldname == 'errorfile')
+ return "<?=haproxy_js_select_options($a_files);?>";
+ else
return "<?=haproxy_js_select_options($a_servermodes);?>";
}
@@ -767,7 +790,7 @@ set by the 'retries' parameter.</div>
<td width="78%" class="vtable" colspan="2">
<input id="persist_cookie_name" name="persist_cookie_name" type="text" <?if(isset($pconfig['persist_cookie_name'])) echo "value=\"{$pconfig['persist_cookie_name']}\"";?> size="64" /><br/>
The string name to track in Set-Cookie and Cookie HTTP headers.<br/>
- EXAMPLE: MyLoadBalanceCookie JSESSIONID PHPSESSIONID ASP.NET_SessionId
+ EXAMPLE: MyLoadBalanceCookie JSESSIONID PHPSESSID ASP.NET_SessionId
</td>
</tr>
<tr class="haproxy_cookie_visible" align="left">
@@ -920,6 +943,21 @@ set by the 'retries' parameter.</div>
</tr>
<tr><td>&nbsp;</td></tr>
<tr>
+ <td colspan="2" valign="top" class="listtopic">Error files</td>
+ </tr>
+ <tr class="" align="left" id='errorfiles'>
+ <td colspan="2" valign="top" class="vtable">
+ Use these to replace the error pages that haproxy can generate by custom pages created on the files tab.
+ For example haproxy will generate a 503 error page when no backend is available, you can replace that page here.
+ <br/>
+ <br/>
+ <?
+ haproxy_htmllist("table_errorfile", $a_errorfiles, $fields_errorfile);
+ ?>
+ </td>
+ </tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr>
<td colspan="2" valign="top" class="listtopic">Advanced</td>
</tr>
<tr class="" align="left" id='Strict-Transport-Security'>
@@ -961,9 +999,11 @@ set by the 'retries' parameter.</div>
<?
phparray_to_javascriptarray($fields_servers,"fields_servers",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name'));
phparray_to_javascriptarray($fields_servers_details,"fields_details_servers",Array('/*','/*/name','/*/type'));
+ phparray_to_javascriptarray($fields_errorfile,"fields_errorfile",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name'));
phparray_to_javascriptarray($a_checktypes,"checktypes",Array('/*','/*/name','/*/descr'));
phparray_to_javascriptarray($a_cookiemode,"cookiemode",Array('/*','/*/name','/*/descr'));
phparray_to_javascriptarray($a_sticky_type,"sticky_type",Array('/*','/*/descr','/*/cookiedescr'));
+ phparray_to_javascriptarray($a_files,"a_files",Array('/*','/*/name','/*/descr'));
?>
browser_InnerText_support = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;
diff --git a/config/haproxy-devel/haproxy_stats.php b/config/haproxy-devel/haproxy_stats.php
index 10dd136a..302793b6 100644
--- a/config/haproxy-devel/haproxy_stats.php
+++ b/config/haproxy-devel/haproxy_stats.php
@@ -32,6 +32,10 @@ require_once("haproxy_socketinfo.inc");
$pconfig = $config['installedpackages']['haproxy'];
if (isset($_GET['haproxystats']) || isset($_GET['scope']) || (isset($_POST) && isset($_POST['action']))){
+ if (!(isset($pconfig['enable']) && $pconfig['localstatsport'] && is_numeric($pconfig['localstatsport']))){
+ print 'In the "Settings" configure a internal stats port and enable haproxy for this to be functional. Also make sure the service is running.';
+ return;
+ }
$fail = false;
try{
$request = "";
@@ -79,48 +83,6 @@ if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
}
$a_frontend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
-function haproxy_add_stats_example() {
- global $config, $d_haproxyconfdirty_path;
- $a_backends = &$config['installedpackages']['haproxy']['ha_pools']['item'];
- $a_frontends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
- $webcert = haproxy_find_create_certificate("HAProxy stats default");
-
- $backend = array();
- $backend["name"] = "HAProxy_stats_ssl_backend";
- $backend["stats_enabled"] = "yes";
- $backend["stats_uri"] = "/";
- $backend["stats_refresh"] = "10";
- $a_backends[] = $backend;
- $changecount++;
-
- $frontend = array();
- $frontend["name"] = "HAProxy_stats_ssl_frontend";
- $frontend["status"] = "active";
- $frontend["type"] = "http";
- $frontend["port"] = "444";
- $frontend["extaddr"] = "lan_ipv4";
- $frontend["ssloffload"] = "yes";
- $frontend["ssloffloadcert"] = $webcert['refid'];
- $frontend["backend_serverpool"] = $backend["name"];
- $a_frontends[] = $frontend;
- $changecount++;
- $changedesc = "add new HAProxy stats example";
-
- if ($changecount > 0) {
- echo "touching: $d_haproxyconfdirty_path";
- touch($d_haproxyconfdirty_path);
- write_config($changedesc);
- }
-}
-
-if (isset($_GET['add_stats_example'])) {
- haproxy_add_stats_example();
- write_config();
- touch($d_haproxyconfdirty_path);
- header("Location: haproxy_listeners.php");
- exit;
-}
-
if ($_POST) {
if ($_POST['apply']) {
$result = haproxy_check_and_run($savemsg, true);
@@ -177,31 +139,16 @@ echo "</td>";
<br/>
As the page is forwarded through the pfSense gui, this might cause some functionality to not work.<br/>
Though the normal haproxy stats page can be tweaked more, and doesn't use a user/pass from pfSense itself.<br/>
- Some examples are configurable automatic page refresh,<br/>
- only showing certain servers, not providing admin options, and can be accessed from wherever the associated frontend is accessible.(as long as rules permit access)<br/>
- To use this or for simply an example how to use SSL-offloading configure stats on either a real backend while utilizing the 'stats uri'.
- Or create a backend specifically for serving stats, for that you can start with the 'stats example' template below.<br/>
+ Some examples are configurable automatic page refresh, only showing certain servers, not providing admin options,<br/>
+ and can be accessed from wherever the associated frontend is accessible.(as long as rules permit access)<br/>
+ To use this or for simply an example how to use SSL-offloading configure stats on either a real backend while utilizing the 'stats uri'.<br/>
+ Or create a backend specifically for serving stats, for that you can start with the 'stats example' from the template tab.<br/>
</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
<tr>
- <td colspan="2" valign="top" class="listtopic">Stats example template</td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell">Example</td>
- <td class="vtable">
- As an basic example you can use the link below to create a 'stats' frontend/backend page which offers with more options like setting user/password and 'admin mode' when you go to the backend settings.<br/>
- <a href="haproxy_stats.php?add_stats_example=1">TEMPLATE: Create stats example configuration using a frontend/backend combination with ssl</a><br/>
- <br/>
- After applying the changes made by the template use this link to visit the stats page: <a target="_blank" href="https://<?=get_interface_ip("lan");?>:444">https://pfSense-LAN-ip:444/</a>
- </td>
- </tr>
- <tr>
- <td>&nbsp;</td>
- </tr>
- <tr>
<td colspan="2" valign="top" class="listtopic">HAProxy stick-tables</td>
</tr>
<tr>
@@ -241,7 +188,7 @@ echo "</td>";
<iframe id="frame_haproxy_stats" width="1000px" height="1500px" seamless=1 src="/haproxy_stats.php?haproxystats=1<?=$request;?>"></iframe>
<? } else { ?>
<br/>
- In the "Settings" configure a internal stats port and enable haproxy for this to be functional.<br/>
+ In the "Settings" configure a internal stats port and enable haproxy for this to be functional. Also make sure the service is running.<br/>
<br/>
<? } ?>
<?}?>
diff --git a/config/haproxy-devel/haproxy_templates.php b/config/haproxy-devel/haproxy_templates.php
new file mode 100644
index 00000000..478c83a3
--- /dev/null
+++ b/config/haproxy-devel/haproxy_templates.php
@@ -0,0 +1,220 @@
+<?php
+/*
+ haproxy_templates.php
+ part of pfSense (https://www.pfsense.org/)
+ Copyright (C) 2014 PiBa-NL
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+require_once("authgui.inc");
+require_once("config.inc");
+
+$pconfig = $config['installedpackages']['haproxy'];
+require_once("guiconfig.inc");
+$shortcut_section = "haproxy";
+require_once("haproxy.inc");
+require_once("certs.inc");
+require_once("haproxy_utils.inc");
+require_once("pkg_haproxy_tabs.inc");
+
+if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
+ $config['installedpackages']['haproxy']['ha_backends']['item'] = array();
+}
+$a_frontend = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+
+function haproxy_add_stats_example() {
+ global $config, $d_haproxyconfdirty_path;
+ $a_backends = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+ $a_frontends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+ $webcert = haproxy_find_create_certificate("HAProxy stats default");
+
+ $backend = array();
+ $backend["name"] = "HAProxy_stats_ssl_backend";
+ $backend["stats_enabled"] = "yes";
+ $backend["stats_uri"] = "/";
+ $backend["stats_refresh"] = "10";
+ $a_backends[] = $backend;
+ $changecount++;
+
+ $frontend = array();
+ $frontend["name"] = "HAProxy_stats_ssl_frontend";
+ $frontend["status"] = "active";
+ $frontend["type"] = "http";
+ $frontend["a_extaddr"]["item"]["stats_name"]["extaddr"] = "lan_ipv4";
+ $frontend["a_extaddr"]["item"]["stats_name"]["extaddr_port"] = "444";
+ $frontend["a_extaddr"]["item"]["stats_name"]["extaddr_ssl"] = "yes";
+ $frontend["ssloffloadcert"] = $webcert['refid'];
+ $frontend["backend_serverpool"] = $backend["name"];
+ $a_frontends[] = $frontend;
+ $changecount++;
+ $changedesc = "add new HAProxy stats example";
+
+ if ($changecount > 0) {
+ header("Location: haproxy_listeners.php");
+ echo "touching: $d_haproxyconfdirty_path";
+ touch($d_haproxyconfdirty_path);
+ write_config($changedesc);
+ exit;
+ }
+}
+
+function template_errorfile() {
+ global $config, $d_haproxyconfdirty_path, $savemsg;
+
+ $a_files = &$config['installedpackages']['haproxy']['files']['item'];
+ if (!is_array($a_files)) $a_files = array();
+
+ $a_files_cache = haproxy_get_fileslist();
+ if (!isset($a_files_cache["ExampleErrorfile"])) {
+ $errorfile = <<<EOD
+HTTP/1.0 503 Service Unavailable
+Cache-Control: no-cache
+Connection: close
+Content-Type: text/html
+
+<html>
+ <head>
+ <title>Sorry the webserver you are trying to contact is currently not available.</title>
+ </head>
+ <body style="font-family:Arial,Helvetica,sans-serif;">
+ <div style="margin: 0 auto; width: 960px;">
+ <h2>Sorry the webserver you are trying to contact is currently not available.</h2>
+ </div>
+The error returned is [<i>{errorcode} {errormsg}</i>] please try again later.
+ </body>
+</html>
+EOD;
+ $newfile = array();
+ $newfile['name'] = "ExampleErrorfile";
+ $newfile['content'] = base64_encode($errorfile);
+ $a_files[] = $newfile;
+ $changecount++;
+ $changedesc = "Errorfile added from template";
+ } else {
+ $savemsg = "File 'ExampleErrorfile' is already configured on the Files tab.";
+ }
+
+ if ($changecount > 0) {
+ header("Location: haproxy_files.php");
+ echo "touching: $d_haproxyconfdirty_path";
+ touch($d_haproxyconfdirty_path);
+ write_config($changedesc);
+ exit;
+ }
+}
+
+if (isset($_GET['add_stats_example'])) {
+ $templateid = $_GET['add_stats_example'];
+ switch ($templateid) {
+ case "1":
+ haproxy_add_stats_example();
+ break;
+ case "2":
+ template_errorfile();
+ break;
+ }
+}
+
+if ($_POST) {
+ if ($_POST['apply']) {
+ $result = haproxy_check_and_run($savemsg, true);
+ if ($result)
+ unlink_if_exists($d_haproxyconfdirty_path);
+ }
+}
+
+$pgtitle = "Services: HAProxy: Templates";
+include("head.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<form action="haproxy_templates.php" method="post">
+<?php if($one_two): ?>
+<p class="pgtitle"><?=$pgtitle?></p>
+<?php endif; ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_haproxyconfdirty_path)): ?>
+<?php print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");?><br/>
+<?php endif; ?>
+</form>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td class="tabnavtbl">
+ <?php
+ haproxy_display_top_tabs_active($haproxy_tab_array['haproxy'], "templates");
+ ?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table class="tabcont" width="100%" height="100%" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Templates</td>
+ </tr>
+ <tr>
+ <td colspan="2">This page contains some templates that can be added into the haproxy configuration to possible ways to configure haproxy using this the webgui from this package.</td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Stats SSL frontent+backend</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">
+ <a href="haproxy_templates.php?add_stats_example=1">Create configuration</a>
+ </td>
+ <td class="vtable">
+ As an basic example you can use the link below to create a 'stats' frontend/backend page which offers with more options like setting user/password and 'admin mode' when you go to the backend settings.<br/>
+ TEMPLATE: Create stats example configuration using a frontend/backend combination with ssl<br/>
+ <br/>
+ After applying the changes made by the template use this link to visit the stats page: <a target="_blank" href="https://<?=get_interface_ip("lan");?>:444">https://pfSense-LAN-ip:444/</a>
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Errorfile</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">
+ <a href="haproxy_templates.php?add_stats_example=2">Create configuration</a>
+ </td>
+ <td class="vtable">
+ As an basic example of an errorfile with name 'ExampleErrorfile' will be added if it does not exist.
+ This file can then be used in the 'Error files' in the backend settings.
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ </tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/haproxy-devel/haproxy_utils.inc b/config/haproxy-devel/haproxy_utils.inc
index 08906bb0..4b945c06 100644
--- a/config/haproxy-devel/haproxy_utils.inc
+++ b/config/haproxy-devel/haproxy_utils.inc
@@ -2,7 +2,7 @@
/*
haproxy_utils.php
part of pfSense (https://www.pfsense.org/)
- Copyright (C) 2013 PiBa-NL
+ Copyright (C) 2013-2015 PiBa-NL
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,30 @@ require_once("config.inc");
class haproxy_utils {
public static $pf_version;
+
+ public function query_dns($host, $querytype="A,AAAA", $dnsserver = "127.0.0.1") {
+ $result = array();
+ $host = trim($host, " \t\n\r\0\x0B[];\"'");
+ $host_esc = escapeshellarg($host);
+ $types = explode(',',$querytype);
+ foreach($types as $type){
+ $resolved = gethostbyname($host);
+ if($resolved) {
+ $resolved = array();
+ if (haproxy_utils::$pf_version < '2.2')
+ exec("/usr/bin/dig {$host_esc} $type @$dnsserver | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved);
+ else
+ exec("/usr/bin/drill {$host_esc} $type @$dnsserver | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved);
+ foreach($resolved as $item) {
+ $newitem = array();
+ $newitem["typeid"] = $type;
+ $newitem["data"] = $item;
+ $result[] = $newitem;
+ }
+ }
+ }
+ return $result;
+ }
}
haproxy_utils::$pf_version = substr(trim(file_get_contents("/etc/version")),0,3);
diff --git a/config/haproxy-devel/pkg/haproxy_upgrade_config.inc b/config/haproxy-devel/pkg/haproxy_upgrade_config.inc
new file mode 100644
index 00000000..9dd575dd
--- /dev/null
+++ b/config/haproxy-devel/pkg/haproxy_upgrade_config.inc
@@ -0,0 +1,174 @@
+<?php
+/*
+ haproxy.inc
+ Copyright (C) 2015 PiBa-NL
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("pkg-utils.inc");
+
+function haproxy_upgrade_config() {
+ global $config, $static_output;
+ // for future config upgrades.
+ // make sure the version stays 'comparable'
+ if (is_arrayset($config,'installedpackages','haproxy') && isset($config['installedpackages']['haproxy']['configversion']))
+ $configversion = $config['installedpackages']['haproxy']['configversion'];
+ else
+ $configversion = "00.12";
+
+ $static_output .= "HAProxy, from version $configversion\n";
+ update_output_window($static_output);
+
+ $writeconfigupdate = false;
+ if ($configversion < "00.13") {
+ /* Do XML upgrade from haproxy 0.31 to haproxy-dev */
+ if (is_array($config['installedpackages']['haproxy']['ha_servers'])) {
+ $static_output .= "HAProxy, Do XML upgrade from haproxy 0.31 to haproxy-dev\n";
+ update_output_window($static_output);
+
+ /* We have an old config */
+ $config['installedpackages']['haproxy']['ha_pools']['item'] = array();
+ $a_global = &$config['installedpackages']['haproxy'];
+ $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item'];
+ $a_oldservers = &$config['installedpackages']['haproxy']['ha_servers']['item'];
+ $a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item'];
+
+ foreach ($a_backends as $id => $be) {
+ $a_backends[$id]['status'] = 'active';
+ }
+ $id = 0;
+ foreach ($a_oldservers as $oldserver) {
+ $pool=$oldserver;
+ /* make server sub array */
+ $server=array();
+ $server['name'] = $oldserver['name'];
+ $server['address'] = $oldserver['address'];
+ $server['port'] = $oldserver['port'];
+ $server['weight'] = $oldserver['weight'];
+ $a_servers=array();
+ $a_servers[]=$server;
+ /* set new pool */
+ $pool['name'] = "pool$id";
+ $id++;
+ $pool['ha_servers']['item']=$a_servers;
+ /* link to frontend */
+ foreach ($a_backends as $id => $be) {
+ if ($a_backends[$id]['name'] == $oldserver['backend']) {
+ $a_backends[$id]['backend_serverpool'] = $pool['name'];
+ $pool['monitor_uri'] = $be['monitor_uri'];
+ unset($a_backends[$id]['monitor_uri']);
+ break;
+ }
+ }
+ unset($pool['backend']);
+ unset($pool['address']);
+ unset($pool['port']);
+ unset($pool['weight']);
+ $a_pools[] = $pool;
+ }
+ unset($config['installedpackages']['haproxy']['ha_servers']);
+ $writeconfigupdate = true;
+ }
+
+ /* XML update to: pkg v1.3 and 'pool' changed to 'backend_serverpool' because 'pool' was added to listtags() in xmlparse.inc */
+ if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0,'pool')) {
+ $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool array\n";
+ update_output_window($static_output);
+
+ foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend)
+ {
+ $backend_serverpool = $frontend['pool'][0];
+ $frontend['backend_serverpool'] = $backend_serverpool;
+ unset($frontend['pool']);
+ }
+ $writeconfigupdate = true;
+ }
+ //also move setting for existing 2.0 installations as only the new variable is used
+ if (is_arrayset($config,'installedpackages','haproxy','ha_backends','item',0) &&
+ isset($config['installedpackages']['haproxy']['ha_backends']['item'][0]['pool'])) {
+ $static_output .= "HAProxy, Do XML upgrade, change to backend_serverpool from pool\n";
+ update_output_window($static_output);
+ foreach($config['installedpackages']['haproxy']['ha_backends']['item'] as &$frontend)
+ {
+ $backend_serverpool = $frontend['pool'];
+ $frontend['backend_serverpool'] = $backend_serverpool;
+ unset($frontend['pool']);
+ }
+ $writeconfigupdate = true;
+ }
+ // update config to "haproxy-devel 1.5-dev19 pkg v0.5"
+ if(is_arrayset($config,'installedpackages','haproxy','ha_backends','item')) {
+ $static_output .= "HAProxy, Do XML upgrade, update frontend options\n";
+ update_output_window($static_output);
+ foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) {
+ if($bind['httpclose'] && $bind['httpclose'] == "yes" ) {
+ $bind['httpclose'] = "httpclose";
+ $writeconfigupdate = true;
+ }
+ if (!$bind['extaddr']){
+ $bind['extaddr'] = "wan_ipv4";
+ $writeconfigupdate = true;
+ }
+ if ($bind['extaddr'] == "localhost"){
+ $bind['extaddr'] = "localhost_ipv4";
+ $writeconfigupdate = true;
+ }
+ if ($bind['extaddr'] == "any"){
+ $bind['extaddr'] = "any_ipv4";
+ $writeconfigupdate = true;
+ }
+ }
+ }
+ }
+ if ($configversion < "00.13") {
+ // update config to "haproxy-devel 1.5-dev19 pkg v0.13"
+ foreach ($config['installedpackages']['haproxy']['ha_backends']['item'] as &$bind) {
+ if (isset($bind['extaddr'])) {
+ $new['extaddr'] = $bind['extaddr'];
+ $new['extaddr_port'] = $bind['port'];
+ $new['extaddr_ssl'] = $bind['ssloffload'];
+ $bind['a_extaddr']['item'][] = $new;
+ }
+ unset($bind['extaddr']);
+ unset($bind['port']);
+ //unset($bind['ssloffload']);
+ }
+ $configversion = "00.13";
+ }
+ if ($configversion < "00.16") {
+ $static_output .= "HAProxy, 00.16\n";
+ $static_output .= "HAProxy, NOTICE: Changes to certificate acl's might need adjusting current config accordingly.\n";
+ $static_output .= "HAProxy, NOTICE: Certificate acls are now combined with user acls.\n";
+ update_output_window($static_output);
+ $configversion = "00.16";
+ }
+
+ $writeconfigupdate = $config['installedpackages']['haproxy']['configversion'] <> $configversion;
+ if ($writeconfigupdate) {
+ $config['installedpackages']['haproxy']['configversion'] = $configversion;
+ $static_output .= "HAProxy, write updated config to version: $configversion\n";
+ update_output_window($static_output);
+ write_config("HAProxy, update xml config version");
+ }
+}
diff --git a/config/haproxy-devel/pkg_haproxy_tabs.inc b/config/haproxy-devel/pkg_haproxy_tabs.inc
index 8cb280f8..a74ee20a 100644
--- a/config/haproxy-devel/pkg_haproxy_tabs.inc
+++ b/config/haproxy-devel/pkg_haproxy_tabs.inc
@@ -12,7 +12,10 @@ $haproxy_tab_array['haproxy'] = array();
$haproxy_tab_array['haproxy']['settings'] = Array(name => "Settings", url => "haproxy_global.php");
$haproxy_tab_array['haproxy']['frontend'] = Array(name => "Frontend", url => "haproxy_listeners.php");
$haproxy_tab_array['haproxy']['backend'] = Array(name => "Backend", url => "haproxy_pools.php");
+$haproxy_tab_array['haproxy']['files'] = Array(name => "Files", url => "haproxy_files.php");
$haproxy_tab_array['haproxy']['stats'] = Array(name => "Stats", url => "haproxy_stats.php");
+$haproxy_tab_array['haproxy']['statsfs'] = Array(name => "Stats FS", url => "haproxy_stats.php?haproxystats=1");
+$haproxy_tab_array['haproxy']['templates'] = Array(name => "Templates", url => "haproxy_templates.php");
function haproxy_display_top_tabs_active($top_tabs, $activetab) {
$tab_array = array();
diff --git a/config/haproxy-devel/www/javascript/haproxy_geturl.js b/config/haproxy-devel/www/javascript/haproxy_geturl.js
new file mode 100644
index 00000000..5df80646
--- /dev/null
+++ b/config/haproxy-devel/www/javascript/haproxy_geturl.js
@@ -0,0 +1,43 @@
+/**
+ * getURL is a proprietary Adobe function, but it's simplicity has made it very
+ * popular. If getURL is undefined we spin our own by wrapping XMLHttpRequest.
+ */
+if (typeof getURL == 'undefined') {
+ getURL = function(url, callback) {
+ if (!url)
+ throw 'No URL for getURL';
+
+ try {
+ if (typeof callback.operationComplete == 'function')
+ callback = callback.operationComplete;
+ } catch (e) {}
+ if (typeof callback != 'function')
+ throw 'No callback function for getURL "' + url + '"';
+
+ var http_request = null;
+ if (typeof XMLHttpRequest != 'undefined') {
+ http_request = new XMLHttpRequest();
+ }
+ else if (typeof ActiveXObject != 'undefined') {
+ try {
+ http_request = new ActiveXObject('Msxml2.XMLHTTP');
+ } catch (e) {
+ try {
+ http_request = new ActiveXObject('Microsoft.XMLHTTP');
+ } catch (e) {}
+ }
+ }
+ if (!http_request)
+ throw '<?=gettext("Both getURL and XMLHttpRequest are undefined"); ?>';
+
+ http_request.onreadystatechange = function() {
+ if (http_request.readyState == 4) {
+ callback( { success : true,
+ content : http_request.responseText,
+ contentType : http_request.getResponseHeader("Content-Type") } );
+ }
+ }
+ http_request.open('GET', url, true);
+ http_request.send(null);
+ }
+}
diff --git a/config/havp/antivirus.php b/config/havp/antivirus.php
index 0d8cda1d..bf5f1879 100644
--- a/config/havp/antivirus.php
+++ b/config/havp/antivirus.php
@@ -176,6 +176,11 @@ if ($_POST['startupdate'] != '') {
# else echo "No 'start_antivirus_scanner' function found.";
}
+/* Clear havp access log */
+if ($_POST['clearlog_x'] != '') {
+ file_put_contents(HVDEF_HAVP_ACCESSLOG, '');
+}
+
# ------------------------------------------------------------------------------
?>
@@ -199,6 +204,7 @@ if (pfsense_version_A() == '1') {
$tab_array[] = array(gettext("General page"), true, "antivirus.php");
$tab_array[] = array(gettext("HTTP proxy"), false, "pkg_edit.php?xml=havp.xml&amp;id=0");
$tab_array[] = array(gettext("Settings"), false, "pkg_edit.php?xml=havp_avset.xml&amp;id=0");
+ $tab_array[] = array(gettext("HAVP Log"), false, "havp_log.php");
display_top_tabs($tab_array);
?>
@@ -356,7 +362,7 @@ if (pfsense_version_A() == '1') {
}
else echo "<tr><td $stl>Not found</td></tr>";
?>
- <tr class="listr"><td class="listr" colspan="4"><?php echo get_av_statistic(); ?></td></tr>
+ <tr class="listr"><td class="listr" colspan="4"><?php echo get_av_statistic(); ?><?php echo "<div style='float:right;'><input title='Clear antivirus log' name='clearlog' type='image' value='havp' border=0 src='./themes/".$g['theme']."/images/icons/icon_x.gif'>"; ?><font size="-1">&nbsp;Clear log</font></div></td></tr>
</tbody></table>
</td>
</tr>
diff --git a/config/havp/havp.inc b/config/havp/havp.inc
index f6e37a3b..1648bcb0 100644
--- a/config/havp/havp.inc
+++ b/config/havp/havp.inc
@@ -48,7 +48,7 @@ if(!function_exists("filter_configure"))
define('HV_DEBUG', 'false');
# use Clamd daemon (another - use libclam)
-define('HV_USE_CLAMD', 'true');
+# define('HV_USE_CLAMD', 'true');
define('HV_CLAMD_TCPSOCKET', 'true');
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -151,6 +151,7 @@ define('HV_SCANTEMPFILE', 'hv_scan_tempfile');
# XML fields
# ------------------------------------------------------------------------------
define('F_ENABLE', 'enable');
+define('F_USECLAMD', 'useclamd');
define('F_PROXYMODE', 'proxymode');
define('F_PROXYINTERFACE', 'proxyinterface');
define('F_PROXYBINDIFACE', 'proxybindiface'); # internal var
@@ -515,6 +516,8 @@ function havp_convert_pfxml_xml()
# === GUI Fields ===
$havp_config[F_ENABLE] = ( $pfconf[F_ENABLE] === 'on' ? 'true' : 'false' );
+ # ClamAV mode
+ $havp_config[F_USECLAMD] = $pfconf[F_USECLAMD];
# proxy
$havp_config[F_PROXYMODE] = ( !empty($pfconf[F_PROXYMODE]) ? $pfconf[F_PROXYMODE] : 'standard' );
# ToDo: add check squid transparent
@@ -630,7 +633,7 @@ function havp_config_havp()
# log
$conf[] = "\n# log ";
$conf[] = "ACCESSLOG " . HVDEF_HAVP_ACCESSLOG;
- $conf[] = "ERRORLOG " . HVDEF_HAVP_ERRORLOG;
+ $conf[] = "ERRORLOG " . ($havp_config[F_LOG] === 'true' ? HVDEF_HAVP_ERRORLOG : "/dev/null");
# syslog
$conf[] = "\n# syslog";
$conf[] = "USESYSLOG {$havp_config[F_SYSLOG]}";
@@ -710,9 +713,9 @@ function havp_config_havp()
$conf[] = "MAXDOWNLOADSIZE {$havp_config[F_MAXDOWNLOADSIZE]}";
#
$conf[] = "\n# ClamAV Library Scanner (libclamav) ";
- $conf[] = "ENABLECLAMLIB " . (HV_USE_CLAMD !== 'true' ? "true" : "false");
+ $conf[] = "ENABLECLAMLIB " . ($havp_config[F_USECLAMD] !== 'true' ? "true" : "false");
# use clamd, if configured
- if (HV_USE_CLAMD === 'true') {
+ if ($havp_config[F_USECLAMD] === 'true') {
$conf[] = "\n# Clamd scanner (Clam daemon)";
$conf[] = "ENABLECLAMD true";
# clamd socket
@@ -1342,7 +1345,7 @@ function havp_startup_script()
$s[] = "\t# start";
$s[] = "\tif [ -z \"`{$havpchk}`\" ];then";
- if (HV_USE_CLAMD === 'true') {
+ if ($havp_config[F_USECLAMD] === 'true') {
$clampid_dir = HVDEF_CLAM_RUNDIR;
$s[] = "\t\t# start clamd before (to be sure)";
$s[] = "\t\t" . HVDEF_CLAM_STARTUP_SCRIPT . " start";
@@ -1563,7 +1566,7 @@ function start_antivirus_scanner($filename)
$param[] = "--max-dir-recursion=255"; # Maximum directory recursion level
$param = implode(" ", $param);
- if (HV_USE_CLAMD === 'true')
+ if ($havp_config[F_USECLAMD] === 'true')
$param = "clamdscan $param $filename"; # use clamd daemon (more quickly)
else $param = "clamscan $param $filename";
@@ -1702,7 +1705,7 @@ function havp_get_av_viruslog()
$log = explode("\n", $log);
$count = 0;
foreach($log as $ln) {
- if (substr_count(strtolower($ln), "virus clamd:"))
+ if (substr_count(strtolower($ln), "virus clam"))
$s[] = $ln;
}
}
@@ -1716,7 +1719,7 @@ function havp_get_av_statistic()
if (file_exists(HVDEF_HAVP_ACCESSLOG)) {
$log = file_get_contents(HVDEF_HAVP_ACCESSLOG);
- $count = substr_count(strtolower($log), "virus clamd:");
+ $count = substr_count(strtolower($log), "virus clam");
$s = "Found $count viruses (total).";
}
diff --git a/config/havp/havp.xml b/config/havp/havp.xml
index 47611030..f5afc2fe 100644
--- a/config/havp/havp.xml
+++ b/config/havp/havp.xml
@@ -55,6 +55,10 @@
<text>Settings</text>
<url>/pkg_edit.php?xml=havp_avset.xml&amp;id=0</url>
</tab>
+ <tab>
+ <text>HAVP Log</text>
+ <url>/havp_log.php</url>
+ </tab>
</tabs>
<fields>
<field>
@@ -64,6 +68,21 @@
<type>checkbox</type>
</field>
<field>
+ <fielddescr>ClamAV mode</fielddescr>
+ <fieldname>useclamd</fieldname>
+ <description>
+ Select ClamAV running mode:&lt;br&gt;
+ &lt;b&gt;Daemon&lt;/b&gt; - HAVP will use ClamAV as socket scanner daemon. Default option.&lt;br&gt;
+ &lt;b&gt;Library&lt;/b&gt; - HAVP will use ClamAV as loaded library scanner. Note: this mode needs much more memory.&lt;br&gt;
+ </description>
+ <type>select</type>
+ <default_value>true</default_value>
+ <options>
+ <option><value>true</value><name>Daemon</name></option>
+ <option><value>false</value><name>Library</name></option>
+ </options>
+ </field>
+ <field>
<fielddescr>Proxy mode</fielddescr>
<fieldname>proxymode</fieldname>
<description>
@@ -274,16 +293,16 @@
<default_value>on</default_value>
</field>
<field>
- <fielddescr>Log</fielddescr>
+ <fielddescr>HAVP Log</fielddescr>
<fieldname>log</fieldname>
- <description>Check this for enable log.</description>
+ <description>Check this for enable HAVP log.</description>
<type>checkbox</type>
<enablefields>syslog</enablefields>
</field>
<field>
- <fielddescr>Syslog</fielddescr>
+ <fielddescr>HAVP Syslog</fielddescr>
<fieldname>syslog</fieldname>
- <description>Check this for enable Syslog.</description>
+ <description>Check this for enable HAVP Syslog.</description>
<type>checkbox</type>
</field>
</fields>
@@ -302,4 +321,4 @@
<custom_php_deinstall_command>
havp_deinstall();
</custom_php_deinstall_command>
-</packagegui> \ No newline at end of file
+</packagegui>
diff --git a/config/havp/havp_avset.xml b/config/havp/havp_avset.xml
index 3d4372f4..041c6f64 100644
--- a/config/havp/havp_avset.xml
+++ b/config/havp/havp_avset.xml
@@ -23,6 +23,10 @@
<url>/pkg_edit.php?xml=havp_avset.xml&amp;id=0</url>
<active/>
</tab>
+ <tab>
+ <text>HAVP Log</text>
+ <url>/havp_log.php</url>
+ </tab>
</tabs>
<fields>
<field>
@@ -104,4 +108,4 @@
</custom_php_install_command>
<custom_php_deinstall_command>
</custom_php_deinstall_command>
-</packagegui> \ No newline at end of file
+</packagegui>
diff --git a/config/havp/havp_log.php b/config/havp/havp_log.php
new file mode 100644
index 00000000..f4a2dc2e
--- /dev/null
+++ b/config/havp/havp_log.php
@@ -0,0 +1,105 @@
+<?php
+/* $Id$ */
+/*
+ havp_log.php
+ Copyright (C) 2014 Andrew Nikitin <andrey.b.nikitin@gmail.com>.
+ Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>.
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (file_exists("/usr/local/pkg/havp.inc"))
+ require_once("/usr/local/pkg/havp.inc");
+else echo "No havp.inc found";
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+ $nentries = 50;
+
+if ($_POST['clear'])
+ file_put_contents(HVDEF_HAVP_ERRORLOG, '');
+
+function dump_havp_errorlog($logfile, $tail) {
+ global $g, $config;
+ $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+ $logarr = "";
+ $grepline = " ";
+ if (is_dir($logfile)) {
+ $logarr = array("File $logfile is a directory.");
+ } elseif(file_exists($logfile) && filesize($logfile) == 0) {
+ $logarr = array(" ... Log file is empty.");
+ } else {
+ exec("cat " . escapeshellarg($logfile) . "{$grepline} | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr);
+ }
+ foreach ($logarr as $logent) {
+ $logent = preg_split("/\s+/", $logent, 3);
+ echo "<tr valign=\"top\">\n";
+ $entry_date_time = htmlspecialchars($logent[0] . " " . $logent[1]);
+ $entry_text = htmlspecialchars($logent[2]);
+ echo "<td class=\"listlr nowrap\" width=\"130\">{$entry_date_time}</td>\n";
+ echo "<td class=\"listr\">{$entry_text}</td>\n";
+ echo "</tr>\n";
+ }
+}
+
+$pgtitle = "Antivirus: HAVP log";
+include("head.inc");
+
+?>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+<?php
+ $tab_array = array();
+ $tab_array[] = array(gettext("General page"), false, "antivirus.php");
+ $tab_array[] = array(gettext("HTTP proxy"), false, "pkg_edit.php?xml=havp.xml&amp;id=0");
+ $tab_array[] = array(gettext("Settings"), false, "pkg_edit.php?xml=havp_avset.xml&amp;id=0");
+ $tab_array[] = array(gettext("HAVP Log"), true, "havp_log.php");
+ display_top_tabs($tab_array);
+?>
+ </td></tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td colspan="2" class="listtopic">
+ <?php printf(gettext("Last %s HAVP log entries"), $nentries);?></td>
+ </tr>
+ <?php dump_havp_errorlog(HVDEF_HAVP_ERRORLOG, $nentries); ?>
+ <tr><td><br/>
+ <form action="havp_log.php" method="post">
+ <input name="clear" type="submit" class="formbtn" value="<?=gettext("Clear log"); ?>" /></form></td></tr>
+ </table>
+ </div>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/lightsquid/lightsquid.xml b/config/lightsquid/lightsquid.xml
index 203cff68..8b5b9ae9 100644
--- a/config/lightsquid/lightsquid.xml
+++ b/config/lightsquid/lightsquid.xml
@@ -186,8 +186,8 @@
&lt;input type=&quot;submit&quot; name=&quot;Submit&quot; value=&quot;Refresh full&quot;&gt;
&lt;br&gt; Press button for start background refresh (this take some time).
&lt;br&gt; &lt;span style=&quot;color: rgb(153, 51, 0);&quot;&gt; Note after installation:
- &lt;br&gt; On the first - enable log in squid package with &quot;/var/squid/logs&quot; path.
- &lt;br&gt; On the second - press Refresh button for create lightsquid reports, else you will have error diagnostic page.&lt;/span&gt;
+ &lt;br&gt; Firstly - enable log in squid package with &quot;/var/squid/logs&quot; path.
+ &lt;br&gt; Secondly - press Refresh button to create lightsquid reports, else you will have an error diagnostic page.&lt;/span&gt;
</description>
<type>select</type>
<value>lhp_none</value>
diff --git a/config/mailscanner/mailscanner.inc b/config/mailscanner/mailscanner.inc
index 31c85a6a..8418c85c 100644
--- a/config/mailscanner/mailscanner.inc
+++ b/config/mailscanner/mailscanner.inc
@@ -29,7 +29,7 @@
*/
$shortcut_section = "mailscanner";
require_once("util.inc");
-require("globals.inc");
+require_once("globals.inc");
#require("guiconfig.inc");
$pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
diff --git a/config/ntopng/ntopng.xml b/config/ntopng/ntopng.xml
index 5428d205..b656e483 100644
--- a/config/ntopng/ntopng.xml
+++ b/config/ntopng/ntopng.xml
@@ -118,6 +118,12 @@
<option><value>lanonly</value><name>Consider only LAN interface local</name></option>
</options>
</field>
+ <field>
+ <fielddescr>Historical Data Storage</fielddescr>
+ <fieldname>dump_flows</fieldname>
+ <description>Turn historical data storages on</description>
+ <type>checkbox</type>
+ </field>
</fields>
<custom_php_global_functions>
<![CDATA[
@@ -175,6 +181,11 @@
break;
}
+ // Historical Data Storage, Dump expired flows
+ if ($ntopng_config['dump_flows'] >= on) {
+ $dump_flows = "-F";
+ }
+
$pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
if ($pf_version >= 2.2) {
$redis_path = "/usr/pbi/ntopng-" . php_uname("m") . "/local/bin";
@@ -182,13 +193,13 @@
$redis_path = "/usr/pbi/ntopng-" . php_uname("m") . "/bin";
}
- $start = "ldconfig -m /usr/pbi/ntopng-i386/lib\n";
- $start .= "\t{$redis_path}/redis-server &\n";
+ $start = "ldconfig -m /usr/pbi/ntopng-" . php_uname("m") . "/lib\n";
+ $start .= "\t{$redis_path}/redis-server --dir /var/db/ntopng/ --dbfilename ntopng.rdb &\n";
// TODO:
// Add support for --data-dir /somewhere, --httpdocs-dir /somewhereelse,
// --dump-timeline (on/off) --http-port, --https-port
- $start .= "\t/usr/local/bin/ntopng -s -e {$ifaces} {$dns_mode} {$aggregations} {$local_networks} &";
+ $start .= "\t/usr/local/bin/ntopng -d /var/db/ntopng -G /var/run/ntopng.pid -s -e {$dump_flows} {$ifaces} {$dns_mode} {$aggregations} {$local_networks} &";
write_rcfile(array(
"file" => "ntopng.sh",
"start" => $start,
@@ -207,6 +218,7 @@
$ntopng_config['password'] = "admin";
$password = md5($ntopng_config['password']);
mwexec_bg("{$redis_path}/redis-cli SET user.admin.password " . escapeshellarg($password));
+ mwexec_bg("{$redis_path}/redis-cli save");
conf_mount_ro();
config_unlock();
}
@@ -237,4 +249,4 @@
}
]]>
</custom_php_validation_command>
-</packagegui> \ No newline at end of file
+</packagegui>
diff --git a/config/nut/nut.inc b/config/nut/nut.inc
index 11fb4b26..aa0bbe13 100644
--- a/config/nut/nut.inc
+++ b/config/nut/nut.inc
@@ -35,7 +35,8 @@
define('NUT_RCFILE', '/usr/local/etc/rc.d/nut.sh');
- if (substr(trim(file_get_contents("/etc/version")),0,3) == "2.0") {
+ $pfs_version = substr(trim(file_get_contents("/etc/version")),0,3);
+ if ($pfs_version == "2.0") {
define('NUT_DIR','/usr/local/etc/nut');
} else {
define('NUT_DIR', '/usr/pbi/nut-' . php_uname("m") . '/etc/nut');
@@ -184,6 +185,7 @@
$remoteuser = nut_config('remoteuser');
$remotepass = nut_config('remotepass');
$shutdownflag = (nut_config('powerdown') == 'on') ? '-p' : '-h';
+ $custom_upsmonconf = str_replace(";", "\n", nut_config('custom_upsmonconf'));
if(!($remotename && $remoteaddr && $remoteuser && $remotepass))
return false;
@@ -194,6 +196,7 @@ MONITOR {$remotename}@{$remoteaddr} 1 {$remoteuser} {$remotepass} slave
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown {$shutdownflag} +0"
POWERDOWNFLAG /etc/killpower
+{$custom_upsmonconf}
EOD;
$stop = <<<EOD
@@ -222,6 +225,8 @@ EOD;
}
function sync_package_nut_local() {
+ global $pfs_version;
+
$name = nut_config('name');
$driver = nut_config_sub('driver', 2);
$port = nut_config('port');
@@ -230,6 +235,10 @@ EOD;
$allowuser = nut_config('allowuser');
$allowpass = nut_config('allowpass');
$shutdownflag = (nut_config('powerdown') == 'on') ? '-p' : '-h';
+ $custom_upsconf = str_replace(";", "\n", nut_config('custom_upsconf'));
+ $custom_upsdconf = str_replace(";", "\n", nut_config('custom_upsdconf'));
+ $custom_upsdusers = str_replace(";", "\n", nut_config('custom_upsdusers'));
+ $custom_upsmonconf = str_replace(";", "\n", nut_config('custom_upsmonconf'));
if(!($name && $driver && $port))
@@ -262,10 +271,12 @@ EOD;
$ups_conf .= "cable={$cable}\n";
if($upstype)
$ups_conf .= "upstype={$upstype}\n";
+ $ups_conf .= "{$custom_upsconf}";
/* upsd.conf */
$upsd_conf = "LISTEN 127.0.0.1\n";
$upsd_conf .= "LISTEN ::1\n";
+ $upsd_conf .= "{$custom_upsdconf}";
$password = uniqid("nut");
/* upsd.users */
@@ -277,6 +288,12 @@ EOD;
$upsd_users .= "password = $allowpass\n";
$upsd_users .= "upsmon master\n";
}
+ $upsd_users .= "{$custom_upsdusers}";
+
+ if ($pfs_version == "2.1")
+ $upsdrvctl = "/usr/local/libexec/nut/upsdrvctl";
+ else
+ $upsdrvctl = "/usr/local/sbin/upsdrvctl";
/* upsmon.conf */
$upsmon_conf = <<<EOD
@@ -284,6 +301,7 @@ MONITOR {$name}@localhost 1 monuser {$password} master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown {$shutdownflag} +0"
POWERDOWNFLAG /etc/killpower
+{$custom_upsmonconf}
EOD;
$stop = <<<EOD
@@ -300,7 +318,7 @@ EOD;
fi
if [ `pgrep {$driver} | wc -l` != 0 ]; then
echo stopping {$driver}
- /usr/local/libexec/nut/upsdrvctl stop
+ {$upsdrvctl} stop
fi
sleep 1
if [ `pgrep {$driver} | wc -l` != 0 ]; then
@@ -319,7 +337,7 @@ if [ `pgrep {$driver} | wc -l` != 0 ]; then
fi
{$port_set}
echo starting {$driver}
- if /usr/local/libexec/nut/upsdrvctl start; then
+ if {$upsdrvctl} start; then
echo starting upsd
/usr/local/sbin/upsd {$ovr_user}
echo starting upsmon
@@ -358,6 +376,10 @@ EOD;
$snmpdisabletransfer = (nut_config('snmpdisabletransfer') == 'on');
$allowuser = nut_config('allowuser');
$allowpass = nut_config('allowpass');
+ $custom_upsconf = str_replace(";", "\n", nut_config('custom_upsconf'));
+ $custom_upsdconf = str_replace(";", "\n", nut_config('custom_upsdconf'));
+ $custom_upsdusers = str_replace(";", "\n", nut_config('custom_upsdusers'));
+ $custom_upsmonconf = str_replace(";", "\n", nut_config('custom_upsmonconf'));
if(!($name && $driver && $port))
return false;
@@ -378,10 +400,12 @@ EOD;
$ups_conf .= "pollfreq={$snmpfreq}\n";
if($snmpdisabletransfer)
$ups_conf .= "notransferoids=true\n";
+ $ups_conf .= "{$custom_upsconf}";
/* upsd.conf */
$upsd_conf = "LISTEN 127.0.0.1\n";
$upsd_conf .= "LISTEN ::1\n";
+ $upsd_conf .= "{$custom_upsdconf}";
$password = uniqid("nut");
/* upsd.users */
@@ -393,6 +417,12 @@ EOD;
$upsd_users .= "password = $allowpass\n";
$upsd_users .= "upsmon master\n";
}
+ $upsd_users .= "{$custom_upsdusers}";
+
+ if ($pfs_version == "2.1")
+ $upsdrvctl = "/usr/local/libexec/nut/upsdrvctl";
+ else
+ $upsdrvctl = "/usr/local/sbin/upsdrvctl";
/* upsmon.conf */
$upsmon_conf = <<<EOD
@@ -400,6 +430,7 @@ MONITOR {$name}@localhost 1 monuser {$password} master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown {$shutdownflag} +0"
POWERDOWNFLAG /etc/killpower
+{$custom_upsmonconf}
EOD;
$stop = <<<EOD
@@ -416,7 +447,7 @@ EOD;
fi
if [ `pgrep {$driver} | wc -l` != 0 ]; then
echo stopping {$driver}
- /usr/local/libexec/nut/upsdrvctl stop
+ {$upsdrvctl} stop
fi
sleep 1
if [ `pgrep {$driver} | wc -l` != 0 ]; then
@@ -435,7 +466,7 @@ if [ `pgrep {$driver} | wc -l` != 0 ]; then
fi
{$port_set}
echo starting {$driver}
- if /usr/local/libexec/nut/upsdrvctl start; then
+ if {$upsdrvctl} start; then
echo starting upsd
/usr/local/sbin/upsd {$ovr_user}
echo starting upsmon
diff --git a/config/nut/nut.xml b/config/nut/nut.xml
index 210d7b82..d1496a16 100644
--- a/config/nut/nut.xml
+++ b/config/nut/nut.xml
@@ -84,6 +84,7 @@
<chmod>0755</chmod>
<item>https://packages.pfsense.org/packages/config/nut/status_nut.php</item>
</additional_files_needed>
+ <advanced_options>enabled</advanced_options>
<fields>
<field>
<name>General Settings</name>
@@ -119,6 +120,42 @@
<type>checkbox</type>
</field>
<field>
+ <fielddescr>ups.conf options</fielddescr>
+ <fieldname>custom_upsconf</fieldname>
+ <description>Write there any custom options for ups.conf. All options must be separated by semi-colons (;).</description>
+ <type>textarea</type>
+ <cols>65</cols>
+ <rows>5</rows>
+ <advancedfield/>
+ </field>
+ <field>
+ <fielddescr>upsd.conf options</fielddescr>
+ <fieldname>custom_upsdconf</fieldname>
+ <description>Write there any custom options for upsd.conf. All options must be separated by semi-colons (;).</description>
+ <type>textarea</type>
+ <cols>65</cols>
+ <rows>5</rows>
+ <advancedfield/>
+ </field>
+ <field>
+ <fielddescr>upsd.users options</fielddescr>
+ <fieldname>custom_upsdusers</fieldname>
+ <description>Write there any custom options for upsd.users. All options must be separated by semi-colons (;).</description>
+ <type>textarea</type>
+ <cols>65</cols>
+ <rows>5</rows>
+ <advancedfield/>
+ </field>
+ <field>
+ <fielddescr>upsmon.conf options</fielddescr>
+ <fieldname>custom_upsmonconf</fieldname>
+ <description>Write there any custom options for upsmon.conf. All options must be separated by semi-colons (;).</description>
+ <type>textarea</type>
+ <cols>65</cols>
+ <rows>5</rows>
+ <advancedfield/>
+ </field>
+ <field>
<name>Remote Access Settings - Used for Local and SNMP Types to allow access</name>
<type>listtopic</type>
</field>
diff --git a/config/openvpn-client-export/vpn_openvpn_export.php b/config/openvpn-client-export/vpn_openvpn_export.php
index 12ce01d0..8703d2da 100755
--- a/config/openvpn-client-export/vpn_openvpn_export.php
+++ b/config/openvpn-client-export/vpn_openvpn_export.php
@@ -601,7 +601,7 @@ function useproxy_changed(obj) {
<td width="78%" class="vtable">
<select name="server" id="server" class="formselect" onchange="server_changed()">
<?php foreach($ras_server as & $server): ?>
- <option value="<?=$server['sindex'];?>"><?=$server['name'];?></option>
+ <option value="<?=$server['index'];?>"><?=$server['name'];?></option>
<?php endforeach; ?>
</select>
</td>
diff --git a/config/pfblockerng/countrycodes.tar.bz2 b/config/pfblockerng/countrycodes.tar.bz2
new file mode 100644
index 00000000..afebf58a
--- /dev/null
+++ b/config/pfblockerng/countrycodes.tar.bz2
Binary files differ
diff --git a/config/pfblockerng/geoipupdate.sh b/config/pfblockerng/geoipupdate.sh
new file mode 100644
index 00000000..4b8fbb63
--- /dev/null
+++ b/config/pfblockerng/geoipupdate.sh
@@ -0,0 +1,162 @@
+#!/bin/sh
+#
+# pfBlockerNG MaxMind GeoLite GeoIP Updater Script - By BBcan177@gmail.com
+# Copyright (C) 2014 BBcan177@gmail.com
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation. You may not use, modify or
+# distribute this program under any other version of the GNU General
+# Public License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The GeoLite databases by MaxMind Inc., are distributed under the Creative Commons
+# Attribution-ShareAlike 3.0 Unported License. The attribution requirement
+# may be met by including the following in all advertising and documentation
+# mentioning features of or use of this database.
+
+# Folder Locations
+pathfetch=/usr/bin/fetch
+pathtar=/usr/bin/tar
+pathgunzip=/usr/bin/gunzip
+
+# File Locations
+pathdb=/var/db/pfblockerng
+pathlog=/var/log/pfblockerng
+errorlog=$pathlog/geoip.log
+pathgeoipdatgz=$pathdb/GeoIP.dat.gz
+pathgeoipdatgzv6=$pathdb/GeoIPv6.dat.gz
+pathgeoipdat=$pathdb/GeoIP.dat
+pathgeoipdatv6=$pathdb/GeoIPv6.dat
+pathgeoipcc=$pathdb/country_continent.csv
+pathgeoipcsv4=$pathdb/GeoIPCountryCSV.zip
+pathgeoipcsvfinal4=$pathdb/GeoIPCountryWhois.csv
+pathgeoipcsv6=$pathdb/GeoIPv6.csv.gz
+pathgeoipcsvfinal6=$pathdb/GeoIPv6.csv
+
+if [ ! -d $pathdb ]; then mkdir $pathdb; fi
+if [ ! -d $pathlog ]; then mkdir $pathlog; fi
+
+now=$(date)
+echo; echo "$now - Updating pfBlockerNG - Country Database Files"
+echo "pfBlockerNG uses GeoLite data created by MaxMind, available from http://www.maxmind.com"; echo
+
+#Function to update MaxMind GeoIP Binary (For Reputation Process)
+binaryupdate() {
+
+# Download Part 1 - GeoLite IPv4 Binary Database
+
+echo " ** Downloading MaxMind GeoLite IPv4 Binary Database (For Reputation/Alerts Processes) **"; echo
+URL="http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz"
+$pathfetch -v -o $pathgeoipdatgz -T 20 $URL
+if [ "$?" -eq "0" ]; then
+ $pathgunzip -f $pathgeoipdatgz
+ echo; echo " ( MaxMind IPv4 GeoIP.dat has been updated )"; echo
+ echo "Current Date/Timestamp:"
+ /bin/ls -alh $pathgeoipdat
+ echo
+else
+ echo; echo " => MaxMind IPv4 GeoIP.dat Update [ FAILED ]"; echo
+ echo "MaxMind IPV4 Binary Update FAIL [ $now ]" >> $errorlog
+fi
+
+# Download Part 2 - GeoLite IPv6 Binary Database
+
+echo; echo " ** Downloading MaxMind GeoLite IPv6 Binary Database (For Reputation/Alerts Processes) **"; echo
+URL="http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz"
+$pathfetch -v -o $pathgeoipdatgzv6 -T 20 $URL
+if [ "$?" -eq "0" ]; then
+ $pathgunzip -f $pathgeoipdatgzv6
+ echo; echo " ( MaxMind IPv6 GeoIPv6.dat has been updated )"; echo
+ echo "Current Date/Timestamp:"
+ /bin/ls -alh $pathgeoipdatv6
+ echo
+else
+ echo; echo " => MaxMind IPv6 GeoIPv6.dat Update [ FAILED ]"; echo
+ echo "MaxMind IPv6 Binary Update FAIL [ $now ]" >> $errorlog
+fi
+}
+
+
+#Function to update MaxMind Country Code Files
+csvupdate() {
+
+# Download Part 1 - CSV IPv4 Database
+
+echo; echo " ** Downloading MaxMind GeoLite IPv4 CSV Database **"; echo
+URL="http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip"
+$pathfetch -v -o $pathgeoipcsv4 -T 20 $URL
+if [ "$?" -eq "0" ]; then
+ $pathtar -zxvf $pathgeoipcsv4 -C $pathdb
+ if [ "$?" -eq "0" ]; then
+ echo; echo " ( MaxMind GeoIPCountryWhois has been updated )"; echo
+ echo "Current Date/Timestamp:"
+ /bin/ls -alh $pathgeoipcsvfinal4
+ echo
+ else
+ echo; echo " => MaxMind IPv4 GeoIPCountryWhois [ FAILED ]"; echo
+ echo "MaxMind CSV Database Update FAIL - Tar extract [ $now ]" >> $errorlog
+ fi
+else
+ echo; echo " => MaxMind IPv4 CSV Download [ FAILED ]"; echo
+ echo "MaxMind CSV Database Update FAIL [ $now ]" >> $errorlog
+fi
+
+# Download Part 2 - Country Definitions
+
+echo; echo " ** Downloading MaxMind GeoLite Database Country Definition File **"; echo
+URL="http://dev.maxmind.com/static/csv/codes/country_continent.csv"
+$pathfetch -v -o $pathgeoipcc -T 20 $URL
+if [ "$?" -eq "0" ]; then
+ echo; echo " ( MaxMind ISO 3166 Country Codes has been updated. )"; echo
+ echo "Current Date/Timestamp:"
+ /bin/ls -alh $pathgeoipcc
+ echo
+else
+ echo; echo " => MaxMind ISO 3166 Country Codes Update [ FAILED ]"; echo
+ echo "MaxMind ISO 3166 Country Code Update FAIL [ $now ]" >> $errorlog
+fi
+
+# Download Part 3 - Country Definitions IPV6
+
+echo " ** Downloading MaxMind GeoLite IPv6 CSV Database **"; echo
+URL="http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz"
+$pathfetch -v -o $pathgeoipcsv6 -T 20 $URL
+if [ "$?" -eq "0" ]; then
+ $pathgunzip -f $pathgeoipcsv6
+ echo; echo " ( MaxMind GeoIPv6.csv has been updated )"; echo
+ echo "Current Date/Timestamp:"
+ /bin/ls -alh $pathgeoipcsvfinal6
+ echo
+else
+ echo; echo " => MaxMind GeoLite IPv6 Update [ FAILED ]"; echo
+ echo "MaxMind GeoLite IPv6 Update FAIL [ $now ]" >> $errorlog
+fi
+}
+
+
+# CALL APPROPRIATE PROCESSES using Script Argument $1
+case $1 in
+ bu)
+ binaryupdate
+ ;;
+ cu)
+ csvupdate
+ ;;
+ all)
+ binaryupdate
+ csvupdate
+ ;;
+ *)
+ exit
+ ;;
+esac
+exit \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.inc b/config/pfblockerng/pfblockerng.inc
new file mode 100644
index 00000000..d612dbf1
--- /dev/null
+++ b/config/pfblockerng/pfblockerng.inc
@@ -0,0 +1,2616 @@
+<?php
+/*
+ pfBlockerNG.inc
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ part of the Postfix package for pfSense
+ Copyright (C) 2010 Erik Fonnesbeck
+ Based upon pfBlocker by
+ Copyright (C) 2011-2012 Marcello Coutinho
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+//error_reporting(E_ALL);
+
+require_once("util.inc");
+require_once("functions.inc");
+require_once("pkg-utils.inc");
+require_once("pfsense-utils.inc");
+require_once("globals.inc");
+require_once("services.inc");
+
+# [ $pfb ] pfBlockerNG Global Array for Paths and Variables. This needs to be called to get the Updated Settings.
+function pfb_global() {
+
+ global $g,$config,$pfb;
+
+ # Folders
+ $pfb['dbdir'] = "{$g['vardb_path']}/pfblockerng";
+ $pfb['aliasdir'] = "{$g['vardb_path']}/aliastables";
+ $pfb['logdir'] = "{$g['varlog_path']}/pfblockerng";
+ $pfb['etdir'] = "{$pfb['dbdir']}/ET";
+ $pfb['nativedir'] = "{$pfb['dbdir']}/native";
+ $pfb['denydir'] = "{$pfb['dbdir']}/deny";
+ $pfb['matchdir'] = "{$pfb['dbdir']}/match";
+ $pfb['permitdir'] = "{$pfb['dbdir']}/permit";
+ $pfb['origdir'] = "{$pfb['dbdir']}/original";
+ $pfb['ccdir'] = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP";
+
+ # Create Folders if not Exist.
+ $folder_array = array ("{$pfb['dbdir']}","{$pfb['logdir']}","{$pfb['ccdir']}","{$pfb['origdir']}","{$pfb['nativedir']}","{$pfb['denydir']}","{$pfb['matchdir']}","{$pfb['permitdir']}","{$pfb['aliasdir']}");
+ foreach ($folder_array as $folder) {
+ safe_mkdir ("{$folder}",0755);
+ }
+
+ # Files
+ $pfb['master'] = "{$pfb['dbdir']}/masterfile";
+ $pfb['errlog'] = "{$pfb['logdir']}/error.log";
+ $pfb['geolog'] = "{$pfb['logdir']}/geoip.log";
+ $pfb['log'] = "{$pfb['logdir']}/pfblockerng.log";
+ $pfb['supptxt'] = "{$pfb['dbdir']}/pfbsuppression.txt";
+ $pfb['script'] = 'sh /usr/local/pkg/pfblockerng/pfblockerng.sh';
+
+ # Collect pfSense Version
+ $pfb['pfsenseversion'] = substr(trim(file_get_contents("/etc/version")),0,3);
+
+ # General Variables
+ $pfb['config'] = $config['installedpackages']['pfblockerng']['config'][0];
+
+ # Enable/Disable of pfBlockerNG
+ $pfb['enable'] = $pfb['config']['enable_cb'];
+ # Keep Blocklists on pfBlockerNG Disable
+ $pfb['keep'] = $pfb['config']['pfb_keep'];
+ # Enable Suppression
+ $pfb['supp'] = $pfb['config']['suppression'];
+ # Max Lines in pfblockerng.log file
+ $pfb['logmax'] = $pfb['config']['log_maxlines'];
+ $pfb['iplocal'] = $config['interfaces']['lan']['ipaddr'];
+ # Disable Country Database CRON Updates
+ $pfb['cc'] = $pfb['config']['database_cc'];
+
+ # Set pfBlockerNG to Disabled on 'Re-Install'
+ if (isset($pfb['install']) && $pfb['install']) {
+ $pfb['enable'] = "";
+ $pfb['install'] = FALSE;
+ }
+}
+
+pfb_global();
+
+# Set Max PHP Memory Setting
+$uname = posix_uname();
+if ($uname['machine'] == 'amd64')
+ ini_set('memory_limit', '256M');
+
+
+# Function to decode to Alias Custom Entry Box.
+function pfbng_text_area_decode($text) {
+ return preg_replace('/\r\n/', "\n",base64_decode($text));
+}
+
+
+# Manage Log File Line Limit
+function pfb_log_mgmt() {
+ global $pfb;
+ pfb_global();
+
+ if ($pfb['logmax'] == "nolimit") {
+ # Skip Log Mgmt
+ } else {
+ exec("/usr/bin/tail -n {$pfb['logmax']} {$pfb['log']} > /tmp/pfblog; /bin/mv -f /tmp/pfblog {$pfb['log']}");
+ }
+}
+
+
+# Record Log Messsages to pfBlockerNG Log File and/or Error Log File.
+function pfb_logger($log, $type) {
+ global $g,$pfb,$pfbarr;
+
+ $now = date("m/d/y G:i:s", time());
+
+ # Only log timestamp if new
+ if (preg_match("/NOW/", $log)) {
+ if ($now == $pfb['pnow']) {
+ $log = str_replace("[ NOW ]", "", "{$log}");
+ } else {
+ $log = str_replace("NOW", $now, "{$log}");
+ }
+ $pfb['pnow'] = "{$now}";
+ }
+
+ if ($type == 2) {
+ @file_put_contents("{$pfb['log']}", "{$log}", FILE_APPEND);
+ @file_put_contents("{$pfb['errlog']}", "{$log}", FILE_APPEND);
+ } elseif ($type == 3) {
+ @file_put_contents("{$pfb['geolog']}", "{$log}", FILE_APPEND);
+ } else {
+ @file_put_contents("{$pfb['log']}", "{$log}", FILE_APPEND);
+ }
+}
+
+
+# Determine Folder Location for 'List'
+function pfb_determine_list_detail($list) {
+ global $g,$pfb,$pfbarr;
+ $pfbarr = array();
+
+ if (in_array($list,array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) {
+ $pfbarr['skip'] = FALSE;
+ $pfbarr['folder'] = "{$pfb['matchdir']}";
+ } elseif (in_array($list,array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) {
+ $pfbarr['skip'] = FALSE;
+ $pfbarr['folder'] = "{$pfb['permitdir']}";
+ } elseif ($list == "Alias_Native") {
+ $pfbarr['skip'] = FALSE;
+ $pfbarr['folder'] = "{$pfb['nativedir']}";
+ } else {
+ # Deny
+ $pfbarr['skip'] = TRUE;
+ $pfbarr['folder'] = "{$pfb['denydir']}";
+ }
+
+ // Collect proper Alias Table Description (Alias Only vs AutoRules)
+ if (preg_match("/Alias/", $list)) {
+ $pfbarr['descr'] = "";
+ } else {
+ $pfbarr['descr'] = " Auto ";
+ }
+
+ return $pfbarr;
+}
+
+# Create Suppression Alias
+function pfb_create_suppression_alias() {
+ global $config;
+
+ // Collect existing pfsense alias(s)
+ if (is_array($config['aliases']['alias'])) {
+ foreach($config['aliases']['alias'] as $exalias) {
+ $new_aliases[] = $exalias;
+ }
+ }
+ // Create New pfBlockerNGSuppress Alias
+ $new_aliases[] = array( "name" => "pfBlockerNGSuppress",
+ "address" => "",
+ "descr" => "pfBlockerNG Suppression List (24|32 CIDR only)",
+ "type" => "network",
+ "detail" => ""
+ );
+ $config['aliases']['alias'] = $new_aliases;
+ write_config();
+}
+
+
+# Create Suppression file from Alias
+function pfb_create_suppression_file() {
+ global $config,$pfb;
+
+ // Find pfBlockerNGSuppress Array ID Number
+ $pfb['found'] = FALSE;
+ if (is_array($config['aliases']['alias'])) {
+ $pfb_id = 0;
+ foreach ($config['aliases']['alias'] as $alias) {
+ if ($alias['name'] == "pfBlockerNGSuppress") {
+ $pfb['found'] = TRUE;
+ break;
+ }
+ $pfb_id++;
+ }
+
+ if ($pfb['found']) {
+ $pfb_suppress = str_replace(" ", "\n", $config['aliases']['alias'][$pfb_id]['address']);
+ if (!empty($pfb_suppress))
+ @file_put_contents("{$pfb['supptxt']}",$pfb_suppress, LOCK_EX);
+ } else {
+ # Delete Suppression File if Alias is Empty.
+ unlink_if_exists("{$pfb['supptxt']}");
+ }
+ }
+
+ // Call Function to Create Suppression Alias.
+ if (!$pfb['found'])
+ pfb_create_suppression_alias();
+}
+
+
+// IPv6 Range to CIDR function used courtesey from:
+// https://github.com/stilez/pfsense-leases/blob/50cc0fa81dba5fe91bcddaea016c245d1b8479cc/etc/inc/util.inc
+function ip_range_to_subnet_array_temp2($ip1, $ip2) {
+
+ if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2)) {
+ $proto = 'ipv4'; // for clarity
+ $bits = 32;
+ $ip1bin = decbin(ip2long32($ip1));
+ $ip2bin = decbin(ip2long32($ip2));
+ } elseif (is_ipaddrv6($ip1) && is_ipaddrv6($ip2)) {
+ $proto = 'ipv6';
+ $bits = 128;
+ $ip1bin = Net_IPv6::_ip2Bin($ip1);
+ $ip2bin = Net_IPv6::_ip2Bin($ip2);
+ } else
+ return array();
+
+ // it's *crucial* that binary strings are guaranteed the expected length; do this for certainty even though for IPv6 it's redundant
+ $ip1bin = str_pad($ip1bin, $bits, '0', STR_PAD_LEFT);
+ $ip2bin = str_pad($ip2bin, $bits, '0', STR_PAD_LEFT);
+
+ if ($ip1bin === $ip2bin)
+ return array($ip1 . '/' . $bits);
+
+ if (strcmp($ip1bin, $ip2bin) > 0)
+ list ($ip1bin, $ip2bin) = array($ip2bin, $ip1bin); // swap contents of ip1 <= ip2
+
+ $rangesubnets = array();
+ $netsize = 0;
+
+ do {
+ // at loop start, $ip1 is guaranteed strictly less than $ip2 (important for edge case trapping and preventing accidental binary wrapround)
+ // which means the assignments $ip1 += 1 and $ip2 -= 1 will always be "binary-wrapround-safe"
+
+ // step #1 if start ip (as shifted) ends in any '1's, then it must have a single cidr to itself (any cidr would include the '0' below it)
+
+ if (substr($ip1bin, -1, 1) == '1') {
+ // the start ip must be in a separate one-IP cidr range
+ $new_subnet_ip = substr($ip1bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize);
+ $rangesubnets[$new_subnet_ip] = $bits - $netsize;
+ $n = strrpos($ip1bin, '0'); //can't be all 1's
+ $ip1bin = ($n == 0 ? '' : substr($ip1bin, 0, $n)) . '1' . str_repeat('0', $bits - $n - 1); // BINARY VERSION OF $ip1 += 1
+ }
+
+ // step #2, if end ip (as shifted) ends in any zeros then that must have a cidr to itself (as cidr cant span the 1->0 gap)
+
+ if (substr($ip2bin, -1, 1) == '0') {
+ // the end ip must be in a separate one-IP cidr range
+ $new_subnet_ip = substr($ip2bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize);
+ $rangesubnets[$new_subnet_ip] = $bits - $netsize;
+ $n = strrpos($ip2bin, '1'); //can't be all 0's
+ $ip2bin = ($n == 0 ? '' : substr($ip2bin, 0, $n)) . '0' . str_repeat('1', $bits - $n - 1); // BINARY VERSION OF $ip2 -= 1
+ // already checked for the edge case where end = start+1 and start ends in 0x1, above, so it's safe
+ }
+
+ // this is the only edge case arising from increment/decrement.
+ // it happens if the range at start of loop is exactly 2 adjacent ips, that spanned the 1->0 gap. (we will have enumerated both by now)
+
+ if (strcmp($ip2bin, $ip1bin) < 0)
+ continue;
+
+ // step #3 the start and end ip MUST now end in '0's and '1's respectively
+ // so we have a non-trivial range AND the last N bits are no longer important for CIDR purposes.
+
+ $shift = $bits - max(strrpos($ip1bin, '0'), strrpos($ip2bin, '1')); // num of low bits which are '0' in ip1 and '1' in ip2
+ $ip1bin = str_repeat('0', $shift) . substr($ip1bin, 0, $bits - $shift);
+ $ip2bin = str_repeat('0', $shift) . substr($ip2bin, 0, $bits - $shift);
+ $netsize += $shift;
+ if ($ip1bin === $ip2bin) {
+ // we're done.
+ $new_subnet_ip = substr($ip1bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize);
+ $rangesubnets[$new_subnet_ip] = $bits - $netsize;
+ continue;
+ }
+
+ // at this point there's still a remaining range, and either startip ends with '1', or endip ends with '0'. So repeat cycle.
+ } while (strcmp($ip1bin, $ip2bin) < 0);
+
+ // subnets are ordered by bit size. Re sort by IP ("naturally") and convert back to IPv4/IPv6
+
+ ksort($rangesubnets, SORT_STRING);
+ $out = array();
+
+ foreach ($rangesubnets as $ip => $netmask) {
+ if ($proto == 'ipv4') {
+ $i = str_split($ip, 8);
+ $out[] = implode('.', array( bindec($i[0]),bindec($i[1]),bindec($i[2]),bindec($i[3]))) . '/' . $netmask;
+ } else
+ $out[] = Net_IPv6::compress(Net_IPv6::_bin2Ip($ip)) . '/' . $netmask;
+ }
+
+ return $out;
+}
+
+
+# Main pfBlockerNG Function
+function sync_package_pfblockerng($cron = "") {
+
+ global $g,$config,$pfb,$pfbarr;
+ pfb_global();
+
+ # Detect Boot Process or Update via CRON
+ if (isset($_POST) && $cron == "") {
+ if (!preg_match("/\w+/",$_POST['__csrf_magic'])) {
+ log_error("[pfBlockerNG] Sync terminated during boot process.");
+ return;
+ }
+ }
+ log_error("[pfBlockerNG] Starting sync process.");
+
+ # Start of pfBlockerNG Logging to 'pfblockerng.log'
+ if ($pfb['enable'] == "on" && !$pfb['save']) {
+ $log = " UPDATE PROCESS START [ NOW ]\n";
+ } else {
+ $log = "\n**Saving Configuration [ NOW ] ...\n";
+ }
+ pfb_logger("{$log}","1");
+
+ # TBC if Required ! (Fetch Timeout in 2.2)
+
+ #apply fetch timeout to pfsense-utils.inc
+ $pfsense_utils = file_get_contents('/etc/inc/pfsense-utils.inc');
+ $new_pfsense_utils = preg_replace("/\/usr\/bin\/fetch -q/","/usr/bin/fetch -T 5 -q",$pfsense_utils);
+ if ($new_pfsense_utils != $pfsense_utils) {
+ @file_put_contents('/etc/inc/pfsense-utils.inc',$new_pfsense_utils, LOCK_EX);
+ }
+
+ # Collect pfSense Max Table Size Entry
+ $pfb['table_limit'] = ($config['system']['maximumtableentries'] != "" ? $config['system']['maximumtableentries'] : "2000000");
+
+ # If Table limit not defined, set Default to 2M
+ $config['system']['maximumtableentries'] = "{$pfb['table_limit']}";
+
+ # Collect local web gui configuration
+ $pfb['weblocal'] = ($config['system']['webgui']['protocol'] != "" ? $config['system']['webgui']['protocol'] : "http");
+ $pfb['port'] = $config['system']['webgui']['port'];
+ if ($pfb['port'] == "") {
+ if ($config['system']['webgui']['protocol'] == "http") {
+ $pfb['port'] = "80";
+ } else {
+ $pfb['port'] = "443";
+ }
+ }
+ $pfb['weblocal'] .= "://127.0.0.1:{$pfb['port']}/pfblockerng/pfblockerng.php";
+
+ # Define Inbound/Outbound Action is not user selected.
+ $pfb['deny_action_inbound'] = ($pfb['config']['inbound_deny_action'] != "" ? $pfb['config']['inbound_deny_action'] : "block");
+ $pfb['deny_action_outbound'] = ($pfb['config']['outbound_deny_action'] != "" ? $pfb['config']['outbound_deny_action'] : "reject");
+
+ # Validation check to see if the Original pfBlocker package is Enabled
+ $pfb['validate']= $pfb['config']['pfblocker_cb'];
+ # User Defined CRON Start Minute
+ $pfb['min'] = $pfb['config']['pfb_min'];
+ # Reloads Existing Blocklists without Downloading New Lists
+ $pfb['reuse'] = $pfb['config']['pfb_reuse'];
+ # Enable OpenVPN AutoRules
+ $pfb['openvpn'] = $pfb['config']['openvpn_action'];
+ # Enable/Disable Floating Auto-Rules
+ $pfb['float'] = $pfb['config']['enable_float'];
+ # Enable Remove of Duplicate IPs utilizing Grepcidr
+ $pfb['dup'] = $pfb['config']['enable_dup'];
+ # Order of the Auto-Rules
+ $pfb['order'] = $pfb['config']['pass_order'];
+ # Suffix used for Auto-Rules
+ $pfb['suffix'] = $pfb['config']['autorule_suffix'];
+
+ # Reputation Variables
+ $pfb['config_rep'] = $config['installedpackages']['pfblockerngreputation']['config'][0];
+
+ # Enable/Disable Reputation
+ $pfb['rep'] = $pfb['config_rep']['enable_rep'];
+ # Enable/Disable 'pDup'
+ $pfb['pdup'] = $pfb['config_rep']['enable_pdup'];
+ # Enable/Disable 'dDup'
+ $pfb['dedup'] = ($pfb['config_rep']['enable_dedup'] != "" ? $pfb['config_rep']['enable_dedup'] : "x");
+ # 'Max' variable setting for Reputation
+ $pfb['max'] = ($pfb['config_rep']['p24_max_var'] != "" ? $pfb['config_rep']['p24_max_var'] : "x");
+ # 'dMax' variable setting for Reputation
+ $pfb['dmax'] = ($pfb['config_rep']['p24_dmax_var'] != "" ? $pfb['config_rep']['p24_dmax_var'] : "x");
+ # 'pMax' variable setting for Reputation
+ $pfb['pmax'] = ($pfb['config_rep']['p24_pmax_var'] != "" ? $pfb['config_rep']['p24_pmax_var'] : "x");
+ # Action for Whitelist Country Category
+ $pfb['ccwhite'] = $pfb['config_rep']['ccwhite'];
+ # Action for Blacklist Country Category
+ $pfb['ccblack'] = $pfb['config_rep']['ccblack'];
+ # List of Countries in the Whitelist Category
+ $pfb['ccexclude']= ($pfb['config_rep']['ccexclude'] != "" ? $pfb['config_rep']['ccexclude'] : "x");
+ # Emerging Threats IQRisk Block Categories
+ $pfb['etblock'] = ($pfb['config_rep']['etblock'] != "" ? $pfb['config_rep']['etblock'] : "x");
+ # Emerging Threats IQRisk Match Categories
+ $pfb['etmatch'] = ($pfb['config_rep']['etmatch'] != "" ? $pfb['config_rep']['etmatch'] : "x");
+ # Perform a Force Update on ET Categories
+ $pfb['etupdate']= $pfb['config_rep']['et_update'];
+
+ # Variables
+
+ # Starting Variable to Skip rep, pdup and dedeup functions if no changes are required
+ $pfb['dupcheck'] = FALSE;
+ ## $pfb['save'] is used to determine if User pressed "Save" Button to avoid Collision with CRON.
+ ## This is defined in each pfBlockerNG XML Files
+
+ # Validation Check to ensure pfBlocker and pfBlockerNG are not running at the same time.
+ if ($pfb['validate'] == "") {
+ # Collect pfBlocker Enabled Status from config file
+ $pfb['validate_chk'] = $config['installedpackages']['pfblocker']['config'][0]['enable_cb'];
+ if ($pfb['validate_chk'] == "on") {
+ $log = "\n The Package 'pfBlocker' is currently Enabled. Either Disable pfBlocker, or 'Disable Validation Check' in pfBlockerNG \n";
+ pfb_logger("{$log}","1");
+ return;
+ }
+ }
+
+
+ #############################################
+ # Configure ARRAYS #
+ #############################################
+
+ $continents = array ( "Africa" => "pfB_Africa",
+ "Antartica" => "pfB_Antartica",
+ "Asia" => "pfB_Asia",
+ "Europe" => "pfB_Europe",
+ "North America" => "pfB_NAmerica",
+ "Oceania" => "pfB_Oceania",
+ "South America" => "pfB_SAmerica",
+ "Top Spammers" => "pfB_Top",
+ "Proxy and Satellite" => "pfB_PS"
+ );
+
+ #create rules vars and arrays
+ # Array used to Collect Changes to Aliases to be saved to Config
+ $new_aliases = array();
+ $new_aliases_list = array();
+ $continent_existing = array();
+ $continent_new = array();
+ $permit_inbound = array();
+ $permit_outbound = array();
+ $deny_inbound = array();
+ $deny_outbound = array();
+ # An Array of all Aliases (Active and non-Active)
+ $aliases_list = array();
+ # This is an Array of Aliases that Have Updated Lists via CRON/Force Update when 'Reputation' disabled.
+ $pfb_alias_lists = array();
+ # This is an Array of All Active Aliases used when 'Reputation' enabled
+ $pfb_alias_lists_all = array();
+
+ # Base Rule Array
+ $base_rule_reg = array( "id" => "",
+ "tag" => "",
+ "tagged" => "",
+ "max" => "",
+ "max-src-nodes" => "",
+ "max-src-conn" => "",
+ "max-src-states"=> "",
+ "statetimeout" => "",
+ "statetype" => "keep state",
+ "os" => ""
+ );
+
+ # Floating Rules, Base Rule Array
+ $base_rule_float = array("id" => "",
+ "tag" => "",
+ "tagged" => "",
+ "quick" => "yes",
+ "floating" => "yes",
+ "max" => "",
+ "max-src-nodes" => "",
+ "max-src-conn" => "",
+ "max-src-states"=> "",
+ "statetimeout" => "",
+ "statetype" => "keep state",
+ "os" => ""
+ );
+
+
+ #############################################
+ # Configure Rule Suffix #
+ #############################################
+
+ # Discover if any Rules are AutoRules (If no AutoRules found, $pfb['autorules'] is FALSE, Skip Rules Re-Order )
+ # To configure Auto Rule Suffix. pfBlockerNG must be disabled to change Suffix and to avoid Duplicate Rules
+ $pfb['autorules'] = FALSE;
+ $pfb['found'] = FALSE;
+ foreach ($continents as $continent => $pfb_alias) {
+ if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'])) {
+ $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0];
+ if ($continent_config['action'] != "Disabled" && in_array($continent_config['action'],array('Deny_Both','Deny_Inbound','Deny_Outbound','Match_Both','Match_Inbound','Match_Outbound','Permit_Both','Permit_Inbound','Permit_Outbound'))) {
+ $pfb['autorules'] = TRUE;
+ $pfb['found'] = TRUE;
+ break;
+ }
+ }
+ }
+
+ $list_type = array ("pfblockernglistsv4", "pfblockernglistsv6");
+ foreach ($list_type as $ip_type) {
+ if ($config['installedpackages'][$ip_type]['config'] != "" && !$pfb['found']) {
+ foreach($config['installedpackages'][$ip_type]['config'] as $list) {
+ if ($list['action'] != "Disabled" && in_array($list['action'],array('Deny_Both','Deny_Inbound','Deny_Outbound','Match_Both','Match_Inbound','Match_Outbound','Permit_Both','Permit_Inbound','Permit_Outbound'))) {
+ $pfb['autorules'] = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ #Configure Auto Rule Suffix. pfBlockerNG must be disabled to change Suffix and to avoid Duplicate Rules
+ # Count Number of Rules with 'pfB_'
+ $count = 0;
+ if (is_array($config['filter']['rule'])) {
+ foreach ($config['filter']['rule'] as $rule) {
+ # Collect any pre-existing Suffix
+ if (preg_match("/pfB_\w+(\s.*)/",$rule['descr'], $pfb_suffix_real) && $count == 0) {
+ $pfb_suffix_match = $pfb_suffix_real[1];
+ }
+ # Query for Existing pfB Rules
+ if (preg_match("/pfB_/",$rule['descr'])) {
+ $count++;
+ break;
+ }
+ }
+ }
+
+ # Change Suffix only if No pfB Rules Found and Auto Rules are Enabled.
+ if ($pfb['autorules'] && $count == 0) {
+ switch ($pfb['suffix']) {
+ case "autorule":
+ $pfb['suffix'] = " auto rule";
+ break;
+ case "standard":
+ $pfb['suffix'] = "";
+ break;
+ case "ar":
+ $pfb['suffix'] = " AR";
+ break;
+ }
+ } else {
+ if ($pfb['autorules']) {
+ # Use existing Suffix Match
+ $pfb['suffix'] = $pfb_suffix_match;
+ } else {
+ # Leave Rule Suffix 'Blank'
+ $pfb['suffix'] = "";
+ }
+ }
+
+
+ #############################################
+ # Configure INBOUND/OUTBOUND INTERFACES #
+ #############################################
+
+ # Collect pfSense Interface Order
+ $ifaces = get_configured_interface_list();
+
+ if (!empty($pfb['config']['inbound_interface'])) {
+ # Sort Interface Array to match pfSense Interface order to allow Floating Rules to populate.
+ $selected_interfaces = explode(",",$pfb['config']['inbound_interface']);
+ # Sort pfBlockerNG Interface order to pfSense Interface Order
+ $sort_interfaces = array_intersect($ifaces, $selected_interfaces);
+ $implode_interfaces = ltrim(implode(",",$sort_interfaces), ",");
+ # CSV String for Inbound Interfaces for 'pfB_' Match Rules
+ $pfb['inbound_floating'] = $implode_interfaces;
+ $pfb['inbound_interfaces_float'] = explode(" ",$implode_interfaces);
+
+ # Assign Inbound Base Rule/Interfaces
+ if ($pfb['float'] == "on") {
+ # Define Base Firewall Floating Rules Settings
+ $base_rule = $base_rule_float;
+ $pfb['inbound_interfaces'] = $pfb['inbound_interfaces_float'];
+ } else {
+ # Define Base Firewall Rules Settings
+ $base_rule = $base_rule_reg;
+ $pfb['inbound_interfaces'] = explode(",",$pfb['config']['inbound_interface']);
+ }
+ } else {
+ # Define Empty Variable/Array
+ $pfb['inbound_interfaces_float'] = "";
+ $pfb['inbound_interfaces'] = array();
+ }
+
+ if (!empty($pfb['config']['outbound_interface'])) {
+ # Sort Interface Array to match pfSense Interface order to allow Floating Rules to populate.
+ $selected_interfaces = explode(",",$pfb['config']['outbound_interface']);
+ # Sort pfBlockerNG Interface order to pfSense Interface Order
+ $sort_interfaces = array_intersect($ifaces, $selected_interfaces);
+ // If OpenVPN Interfaces are not in dropdown menu
+ if ($pfb['openvpn'] == "on" && $config['openvpn']['openvpn-server'] || $pfb['openvpn'] == "on" && $config['openvpn']['openvpn-client'])
+ if (!in_array("openvpn",$sort_interfaces))
+ array_push($sort_interfaces, "openvpn");
+ $implode_interfaces = ltrim(implode(",",$sort_interfaces), ",");
+ # CSV String for Outbound Interfaces for 'pfB_' Match Rules
+ $pfb['outbound_floating'] = $implode_interfaces;
+ $pfb['outbound_interfaces_float'] = explode(" ",$implode_interfaces);
+
+ # Assign Outbound Base Rule/Interfaces
+ if ($pfb['float'] == "on") {
+ $base_rule = $base_rule_float;
+ $pfb['outbound_interfaces'] = $pfb['outbound_interfaces_float'];
+ } else {
+ $base_rule = $base_rule_reg;
+ $pfb['outbound_interfaces'] = explode(",",$pfb['config']['outbound_interface']);
+ // If OpenVPN Interfaces are not in dropdown menu
+ if ($pfb['openvpn'] == "on" && $config['openvpn']['openvpn-server'] || $pfb['openvpn'] == "on" && $config['openvpn']['openvpn-client'])
+ if (!in_array("openvpn",$sort_interfaces))
+ array_push($pfb['outbound_interfaces'], "openvpn");
+ }
+ } else {
+ # Define Empty Variable/Array
+ $pfb['outbound_interfaces_float'] = "";
+ $pfb['outbound_interfaces'] = array();
+ }
+
+
+ #############################################
+ # Clear Removed Lists from Masterfiles #
+ #############################################
+
+ # Process to keep Masterfiles in Sync with Valid Lists from config.conf file.
+ $pfb['sync_master'] = TRUE;
+
+ # Don't execute this function when pfBlockerNG is Disabled and 'Keep Blocklists' is enabled.
+ if ($pfb['enable'] == "" && $pfb['keep'] == "on")
+ $pfb['sync_master'] = FALSE;
+
+ if ($pfb['sync_master']) {
+ $pfb['existing']['match']['type'] = "match";
+ $pfb['existing']['permit']['type'] = "permit";
+ $pfb['existing']['deny']['type'] = "deny";
+ $pfb['existing']['native']['type'] = "native";
+ $pfb['existing']['match']['folder'] = "{$pfb['matchdir']}";
+ $pfb['existing']['permit']['folder'] = "{$pfb['permitdir']}";
+ $pfb['existing']['deny']['folder'] = "{$pfb['denydir']}";
+ $pfb['existing']['native']['folder'] = "{$pfb['nativedir']}";
+ $pfb['actual']['match']['type'] = "match";
+ $pfb['actual']['permit']['type'] = "permit";
+ $pfb['actual']['deny']['type'] = "deny";
+ $pfb['actual']['native']['type'] = "native";
+ $pfb['actual']['match']['folder'] = "{$pfb['matchdir']}";
+ $pfb['actual']['permit']['folder'] = "{$pfb['permitdir']}";
+ $pfb['actual']['deny']['folder'] = "{$pfb['denydir']}";
+ $pfb['actual']['native']['folder'] = "{$pfb['nativedir']}";
+
+ // Find all Enabled Continents Lists
+ foreach ($continents as $continent => $pfb_alias) {
+ if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config']) && $pfb['enable'] == "on") {
+ $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0];
+ if ($continent_config['action'] != "Disabled") {
+ $cont_type = array ("countries4" => "_v4", "countries6" => "_v6");
+ foreach ($cont_type as $c_type => $vtype) {
+ if ($continent_config[$c_type] != "") {
+ # Set Parameters for 'Match', 'Permit', 'Native' and 'Deny'
+ if (in_array($continent_config['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) {
+ $pfb['existing']['match'][] = "{$pfb_alias}{$vtype}";
+ } elseif (in_array($continent_config['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))){
+ $pfb['existing']['permit'][] = "{$pfb_alias}{$vtype}";
+ } elseif ($continent_config['action'] == "Alias_Native") {
+ $pfb['existing']['native'][] = "{$pfb_alias}{$vtype}";
+ } else {
+ $pfb['existing']['deny'][] = "{$pfb_alias}{$vtype},"; // Add Trailing ','
+ }
+ }
+ }
+ }
+ }
+ }
+
+ # Find all Enabled IPv4/IPv6 Lists
+ $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ foreach ($list_type as $ip_type => $vtype) {
+ if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") {
+ foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
+ if (is_array($list['row']) && $list['action'] != "Disabled") {
+ foreach ($list['row'] as $row) {
+ if ($vtype == "_v4") {
+ $pfb_alias = "{$row['header']}";
+ } else {
+ $pfb_alias = "{$row['header']}_v6";
+ }
+ # Collect Enabled Lists
+ if ($row['url'] != "" && $row['state'] != "Disabled") {
+ # Set Parameters for 'Match', 'Permit', 'Native' and 'Deny'
+ if (in_array($list['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) {
+ $pfb['existing']['match'][] = "{$pfb_alias}";
+ } elseif (in_array($list['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) {
+ $pfb['existing']['permit'][] = "{$pfb_alias}";
+ } elseif ($list['action'] == "Alias_Native") {
+ $pfb['existing']['native'][] = "{$pfb_alias}";
+ } else {
+ $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ','
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ # Find all Enabled IPv4 'Custom List' Header Names and Check if 'Emerging Threats Update' and 'Custom List Update' Needs Force Updating
+ $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ foreach ($list_type as $ip_type => $vtype) {
+ if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") {
+ $count = -1;
+ foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
+ if (is_array($list['row']) && $list['action'] != "Disabled") {
+ $count++;
+ # Check if 'Emerging Threats Update' Needs Updating before next CRON Event.
+ if (is_array($list['row']) && $row['state'] != "Disabled" && $pfb['etupdate'] == "enabled" && $vtype == "_v4") {
+ foreach ($list['row'] as $row) {
+ $aliasname = $row['header'];
+ if ($row['format'] == "et") {
+ unlink_if_exists("{$pfb['denydir']}/{$aliasname}.txt");
+ $config['installedpackages']['pfblockerngreputation']['config'][0]['et_update'] = "disabled";
+ break;
+ }
+ }
+ }
+ }
+
+ # Collect Enabled Custom List Box Aliases
+ if (pfbng_text_area_decode($list['custom']) != "") {
+ if ($vtype == "_v4") {
+ $pfb_alias = "{$list['aliasname']}_custom";
+ } else {
+ $pfb_alias = "{$list['aliasname']}_custom_v6";
+ }
+ # Determine Folder Location for 'List'
+ if (in_array($list['action'],array('Match_Both','Match_Inbound','Match_Outbound','Alias_Match'))) {
+ $pfb['existing']['match'][] = "{$pfb_alias}";
+ $pfbfolder = "{$pfb['matchdir']}";
+ } elseif (in_array($list['action'],array('Permit_Both','Permit_Inbound','Permit_Outbound','Alias_Permit'))) {
+ $pfb['existing']['permit'][] = "{$pfb_alias}";
+ $pfbfolder = "{$pfb['permitdir']}";
+ } elseif ($list['action'] == "Alias_Native") {
+ $pfb['existing']['native'][] = "{$pfb_alias}";
+ $pfbfolder = "{$pfb['nativedir']}";
+ } else {
+ $pfb['existing']['deny'][] = "{$pfb_alias},"; // Add Trailing ','
+ $pfbfolder = "{$pfb['denydir']}";
+ }
+ # Determine if 'Custom List' Needs Force Updating before next CRON Event.
+ if ($list['custom_update'] == "enabled") {
+ unlink_if_exists("{$pfbfolder}/{$pfb_alias}.txt");
+ # Uncheck 'Enabled' in List 'Custom_update' Setting
+ $config['installedpackages'][$ip_type]['config'][$count]['custom_update'] = "disabled";
+ }
+ }
+ }
+ }
+ }
+
+ # Collect all .txt file Names for each List Type
+ $list_types = array('match' => $pfb['matchdir'], 'permit' => $pfb['permitdir'], 'deny' => $pfb['denydir'], 'native' => $pfb['nativedir']);
+ foreach ($list_types as $type => $pfbfolder) {
+ $pfb_files = glob("$pfbfolder/*.txt");
+ foreach ($pfb_files as $pfb_list) {
+ $pfb_file = basename($pfb_list,".txt");
+ if ($type == "deny") {
+ $pfb['actual'][$type][] = "{$pfb_file},"; // Add Trailing ','
+ } else {
+ $pfb['actual'][$type][] = "{$pfb_file}";
+ }
+ }
+ }
+
+ # Flag to execute pfctl and Rules Ordering
+ $pfb['remove'] = FALSE;
+ # Execute Final Summary as a List was Removed
+ $pfb['summary'] = FALSE;
+
+ # Process to Remove Lists from Masterfile/DB Folder if they do not Exist
+ if (isset($pfb['existing'])) {
+ foreach ($pfb['existing'] as $pfb_exist) {
+ $existing_type = $pfb_exist['type'];
+ $pfbfolder = $pfb_exist['folder'];
+ foreach ($pfb['actual'] as $pfb_act) {
+ $actual_type = $pfb_act['type'];
+ if ($existing_type == $actual_type) {
+ switch ($existing_type) {
+ case "deny":
+ $results = array_diff($pfb_act, $pfb_exist);
+ $f_result = implode($results);
+ if ($f_result != "") {
+ $log = "[ Removing List(s) : {$f_result} ]\n";
+ pfb_logger("{$log}","1");
+ # Script to Remove un-associated Lists
+ exec ("{$pfb['script']} remove x x x {$f_result} >> {$pfb['log']} 2>&1");
+ $pfb['summary'] = TRUE;
+ $pfb['remove'] = TRUE;
+ }
+ break;
+ case "match":
+ case "permit":
+ case "native":
+ $results = array_diff($pfb_act, $pfb_exist);
+ # This variable ($f_result) used in next section below.
+ $f_result = implode($results);
+ if (!empty($results)) {
+ foreach ($results as $pfb_results) {
+ $log = "[ Removing List(s) : {$pfb_results} ]\n";
+ pfb_logger("{$log}","1");
+ unlink_if_exists("{$pfbfolder}/{$pfb_results}.txt");
+ }
+ $pfb['summary'] = TRUE;
+ $pfb['remove'] = TRUE;
+ }
+ break;
+ }
+
+ # Allow Rebuilding of Changed Aliase to purge 'SKIP' Lists (when pfBlockerNG is Enabled)
+ $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ foreach ($list_type as $ip_type => $vtype) {
+ if ($f_result != "" && $pfb['enable'] == "on") {
+ foreach ($results as $removed_header) {
+ if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") {
+ foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
+ $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']);
+ if (is_array($list['row'])) {
+ foreach ($list['row'] as $row) {
+ $removed = rtrim($removed_header, ',');
+ if ($row['header'] == $removed) {
+ $pfb['summary'] = TRUE;
+ $pfb['remove'] = TRUE;
+ # Add Alias to Update Array
+ $pfb_alias_lists[] = "{$alias}";
+ $pfb_alias_lists_all[] = "{$alias}";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ##############################################
+ # Clear Match/Pass/ET/Original Files/Folders #
+ ##############################################
+
+ # When pfBlockerNG is Disabled and 'Keep Blocklists' is Disabled.
+ if ($pfb['enable'] == "" && $pfb['keep'] == "" && !$pfb['install']) {
+ $log = "\n Removing DB Files/Folders \n";
+ pfb_logger("{$log}","1");
+
+ unlink_if_exists("{$pfb['dbdir']}/masterfile");
+ unlink_if_exists("{$pfb['dbdir']}/mastercat");
+ unlink_if_exists("{$pfb['supptxt']}");
+ rmdir_recursive("{$pfb['origdir']}");
+ rmdir_recursive("{$pfb['matchdir']}");
+ rmdir_recursive("{$pfb['permitdir']}");
+ rmdir_recursive("{$pfb['denydir']}");
+ rmdir_recursive("{$pfb['nativedir']}");
+ rmdir_recursive("{$pfb['etdir']}");
+ }
+
+
+ #############################################
+ # Create Suppression Txt File #
+ #############################################
+
+ if ($pfb['enable'] == "on" && $pfb['supp'] == "on")
+ pfb_create_suppression_file();
+
+
+ #############################################
+ # Assign Countries #
+ #############################################
+
+ foreach ($continents as $continent => $pfb_alias) {
+ if (is_array($config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'])) {
+ $continent_config = $config['installedpackages']['pfblockerng' . strtolower(preg_replace('/ /','',$continent))]['config'][0];
+ if ($continent_config['action'] != "Disabled" && $pfb['enable'] == "on") {
+
+ # Determine Folder Location for Alias (return array $pfbarr)
+ pfb_determine_list_detail($continent_config['action']);
+ $pfb['skip'] = $pfbarr['skip'];
+ $pfb_descr = $pfbarr['descr'];
+ $pfbfolder = $pfbarr['folder'];
+
+ // Determine if Continent Lists require Action (IPv4 and IPv6)
+ $cont_type = array ("countries4" => "_v4", "countries6" => "_v6");
+ foreach ($cont_type as $c_type => $vtype) {
+
+ $continent = "";
+ if ($continent_config[$c_type] != "") {
+
+ // Collect Selected ISO Country Files
+ foreach (explode(",", $continent_config[$c_type]) as $iso) {
+ if ($iso != "" && file_exists($pfb['ccdir'] .'/' . $iso . $vtype . '.txt')) {
+ $continent .= file_get_contents ($pfb['ccdir'] . '/' . $iso . $vtype . '.txt');
+ }
+ }
+
+ if (file_exists($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig'))
+ $continent_existing = preg_replace('/\s/', '', file ($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig'));
+
+ // Collect New Continent Data for comparison. Cleanup Array for Comparison
+ $continent_new = preg_split ('/$\R?^/m', $continent);
+ $line = count ( $continent_new ) - 1;
+ $match = $continent_new[$line];
+ $continent_new[$line] = rtrim($match, "\n");
+
+ # Check if pfBlockerNG pfctl Continent Tables are Empty (pfBlockerNG was Disabled w/ "keep", then Re-enabled)
+ $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$pfb_alias}{$vtype} | awk '/Addresses/ {s+=$2}; END {print s}'");
+ if (empty($pfctlck) && file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt')) {
+ $file_cont = file_get_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt');
+ @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$file_cont, LOCK_EX);
+ # PFCTL - Update Only Aliases that have been updated. ('Reputation' Disabled)
+ $pfb_alias_lists[] = "{$pfb_alias}{$vtype}";
+ }
+
+ # Collect Active Alias Lists (Used for pfctl Update when 'Reputation' is enabled).
+ $pfb_alias_lists_all[] = "{$pfb_alias}{$vtype}";
+
+ // Compare Existing (Original File) and New Continent Data
+ if ($continent_new === $continent_existing && !empty($pfctlck) && file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt') && $pfb['reuse'] == "") {
+ # Format Log into clean Tab Spaces
+ $string_final = "{$pfb_alias}{$vtype}";
+ if (strlen($string_final) > 10) {
+ $log_tab = "\t";
+ } else {
+ $log_tab = "\t\t";
+ }
+
+ if (!$pfb['save']) {
+ $log = "\n[ {$pfb_alias}{$vtype} ] {$log_tab} exists, Reloading File [ NOW ]\n";
+ pfb_logger("{$log}","1");
+ }
+ } else {
+ // Do not proceed with Changes on User 'Save'
+ if (!$pfb['save']) {
+ $log = "\n[ {$pfb_alias}{$vtype} ] {$log_tab} Changes Found... Updating \n";
+ pfb_logger("{$log}","1");
+
+ # Test to Skip d-dup and p-dup functions when changes are found.
+ $pfb['dupcheck'] = TRUE;
+
+ $pfb_alias_lists[] = "{$pfb_alias}{$vtype}";
+
+ // Script to call Duplication Check Process only on IPv4
+ if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") {
+ // Copy Continent Data to 'lists' folder for duplication processing
+ @file_put_contents($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig',$continent, LOCK_EX);
+ @file_put_contents($pfb['denydir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX);
+ exec ("{$pfb['script']} continent {$pfb_alias}{$vtype} >> {$pfb['log']} 2>&1");
+ $continent = file_get_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt');
+ @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX);
+ } else {
+ @file_put_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX);
+ @file_put_contents($pfb['origdir'] . '/' . $pfb_alias . $vtype . '.orig',$continent, LOCK_EX);
+ @file_put_contents($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt',$continent, LOCK_EX);
+ }
+
+ # Check if File Exists and is >0 in Size and Save alias file
+ $file_chk = "0";
+ $cont_chk = "{$pfbfolder}/{$pfb_alias}{$vtype}.txt";
+ if (file_exists($cont_chk) && @filesize($cont_chk) >0)
+ $file_chk = exec ("/usr/bin/grep -cv '^#\|^$' {$cont_chk}");
+
+ if ($file_chk == "0" || $file_chk == "1") {
+ $new_file = "1.1.1.1\n";
+ @file_put_contents($pfbfolder . '/' . $pfb_alias . $vtype . '.txt', $new_file, LOCK_EX);
+ @file_put_contents($pfb['aliasdir'] . "/" . $pfb_alias . $vtype . ".txt", $new_file, LOCK_EX);
+ $log = "[ {$pfb_alias}{$vtype} ] Found no Unique IPs, Adding '1.1.1.1' to avoid Empty File\n";
+ pfb_logger("{$log}","1");
+ }
+ }
+ }
+
+
+ if (file_exists($pfbfolder . '/' . $pfb_alias . $vtype . '.txt')) {
+ #Create alias config
+ $new_aliases_list[] = "{$pfb_alias}{$vtype}";
+
+ $pfb_contlog = $continent_config['aliaslog'];
+
+ $new_aliases[] = array( "name" => "{$pfb_alias}{$vtype}",
+ "url" => "{$pfb['weblocal']}?pfb={$pfb_alias}{$vtype}",
+ "updatefreq" => "32",
+ "address" => "",
+ "descr" => "pfBlockerNG {$vtype} {$pfb_descr} Country Alias",
+ "type" => "urltable",
+ "detail" => "DO NOT EDIT THIS ALIAS"
+ );
+
+ #Create rule if action permits
+ switch ($continent_config['action']) {
+ case "Deny_Both":
+ case "Deny_Outbound":
+ $rule = $base_rule;
+ $rule['type'] = "{$pfb['deny_action_outbound']}";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr']= "{$pfb_alias}{$vtype}{$pfb['suffix']}";
+ $rule['source'] = array("any" => "");
+ $rule['destination'] = array ("address" => "{$pfb_alias}{$vtype}");
+ if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled")
+ $rule['log'] = "";
+ $deny_outbound[] = $rule;
+ if ($continent_config['action'] != "Deny_Both")
+ break;
+ case "Deny_Inbound":
+ $rule = $base_rule;
+ $rule['type'] = "{$pfb['deny_action_inbound']}";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}";
+ $rule['source'] = array("address" => "{$pfb_alias}{$vtype}");
+ $rule['destination'] = array ("any" => "");
+ if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled")
+ $rule['log'] = "";
+ $deny_inbound[] = $rule;
+ break;
+ case "Permit_Both":
+ case "Permit_Outbound":
+ $rule = $base_rule;
+ $rule['type'] = "pass";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}";
+ $rule['source'] = array ("any" => "");
+ $rule['destination'] = array("address" => "{$pfb_alias}{$vtype}");
+ if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled")
+ $rule['log'] = "";
+ $permit_outbound[] = $rule;
+ if ($continent_config['action'] != "Permit_Both")
+ break;
+ case "Permit_Inbound":
+ $rule = $base_rule;
+ $rule['type'] = "pass";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}";
+ $rule['source'] = array("address"=> "{$pfb_alias}{$vtype}");
+ $rule['destination'] = array ("any" => "");
+ if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled")
+ $rule['log'] = "";
+ $permit_inbound[] = $rule;
+ break;
+ case "Match_Both":
+ case "Match_Outbound":
+ $rule = $base_rule_float;
+ $rule['type'] = "match";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}";
+ $rule['source'] = array ("any" => "");
+ $rule['destination'] = array ("address" => "{$pfb_alias}{$vtype}");
+ if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled")
+ $rule['log'] = "";
+ $match_outbound[] = $rule;
+ if ($list['action'] != "Match_Both")
+ break;
+ case "Match_Inbound":
+ $rule = $base_rule_float;
+ $rule['type'] = "match";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$pfb_alias}{$vtype}{$pfb['suffix']}";
+ $rule['source'] = array ("address" => "{$pfb_alias}{$vtype}");
+ $rule['destination'] = array ( "any" => "");
+ if ($pfb['config']['enable_log'] == "on" || $pfb_contlog == "enabled")
+ $rule['log'] = "";
+ $match_inbound[] = $rule;
+ break;
+ }
+ } else {
+ #unlink continent list if any
+ unlink_if_exists($pfb['aliasdir'] . '/' . $pfb_alias . $vtype . '.txt');
+ }
+ }
+ }
+ }
+ #mark pfctl aliastable for cleanup
+ if (!in_array($pfb_alias, $aliases_list)) {
+ $aliases_list[] = "{$pfb_alias}{$vtype}";
+ }
+ }
+ }
+ # UNSET variables
+ unset ($continent, $continent_existing, $continent_new);
+
+ #############################################
+ # Download and Collect IPv4/IPv6 lists #
+ #############################################
+
+ # IPv4 REGEX Definitions
+ $pfb['range'] = '/((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))-((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))/';
+ $pfb['block'] = '/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[ 0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.([0]{1})\s+/';
+ $pfb['cidr'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)?\/[0-9]{2}/';
+ $pfb['single'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s+/';
+ $pfb['s_html'] = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/';
+
+ # IPv4 preg_replace Regex Filter array
+ $pfb_ipreg = array();
+ $pfb_ipreg[0] = '/\b0+(?=\d)/'; # Remove any Leading Zeros in each Octet
+ $pfb_ipreg[1] = '/\s/'; # Remove any Whitespaces
+ $pfb_ipreg[2] = '/127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/'; # Remove any Loopback Addresses 127/8
+ $pfb_ipreg[3] = '/0\.0\.0\.0/'; # Remove 0.0.0.0
+
+ # IPv6 REGEX Definitions -- ** Still Needs some Adjustment on Regex Definition for IPv6 **
+ # https://mebsd.com/coding-snipits/php-regex-ipv6-with-preg_match.html
+ $pattern1 = '([A-Fa-f0-9]{1,4}:){7}[A-Fa-f0-9]{1,4}';
+ $pattern2 = '([A-Fa-f0-9]{1,4}::([A-Fa-f0-9]{1,4}:){0,5}[A-Fa-f0-9]{1,4}';
+ $pattern3 = '([A-Fa-f0-9]{1,4}:){2}:([A-Fa-f0-9]{1,4}:){0,4}[A-Fa-f0-9]{1,4}';
+ $pattern4 = '([A-Fa-f0-9]{1,4}:){3}:([A-Fa-f0-9]{1,4}:){0,3}[A-Fa-f0-9]{1,4}';
+ $pattern5 = '([A-Fa-f0-9]{1,4}:){4}:([A-Fa-f0-9]{1,4}:){0,2}[A-Fa-f0-9]{1,4}';
+ $pattern6 = '([A-Fa-f0-9]{1,4}:){5}:([A-Fa-f0-9]{1,4}:){0,1}[A-Fa-f0-9]{1,4}';
+ $pattern7 = '([A-Fa-f0-9]{1,4}:){6}:[A-Fa-f0-9]{1,4}';
+ $pfb['ipv6'] = "/^($pattern1)$|^($pattern2)$|^($pattern3)$|^($pattern4)$|^($pattern5)$|^($pattern6)$|^($pattern7)$/";
+
+ $pfb['supp_update'] = FALSE;
+ $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ foreach ($list_type as $ip_type => $vtype) {
+ if ($config['installedpackages'][$ip_type]['config'] != "") {
+ foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
+ if ($list['action'] != "Disabled" && $pfb['enable'] == "on" && !$pfb['save'] && is_array($list['row'])) {
+ # Capture Alias Name
+ $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']);
+ foreach ($list['row'] as $row) {
+ if ($row['url'] != "" && $row['state'] != "Disabled") {
+
+ # Determine Folder Location for Alias (return array $pfbarr)
+ pfb_determine_list_detail($list['action']);
+ $pfb['skip'] = $pfbarr['skip'];
+ $pfbfolder = $pfbarr['folder'];
+
+ if ($vtype == "_v4") {
+ $header_url = "{$row['header']}";
+ } else {
+ $header_url = "{$row['header']}_v6";
+ }
+
+ # Format Log into clean Tab Spaces
+ if (strlen($header_url) > 10) {
+ $log_tab = "\t";
+ } else {
+ $log_tab = "\t\t";
+ }
+
+ // Empty Header Field Validation Check
+ if (empty($header_url) || preg_match("/\W/",$header_url)) {
+ $log = "\n [ {$row['url']} ]\n ** TERMINATED - Header contains Blank/International/Special or Spaces\n";
+ pfb_logger("{$log}","2");
+ continue;
+ }
+
+ # Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled.
+ $pfb_alias_lists_all[] = "{$alias}";
+
+ if (file_exists($pfbfolder . '/' . $header_url . '.txt') && $pfb['reuse'] == "") {
+ if ($row['state'] == "Hold") {
+ $log = "\n[ {$header_url} ] {$log_tab} Static Hold [ NOW ]\n";
+ } else {
+ $log = "\n[ {$header_url} ] {$log_tab} exists, Reloading File [ NOW ]\n";
+ }
+ pfb_logger("{$log}","1");
+ } else {
+ if ($pfb['reuse'] == "on" && file_exists($pfb['origdir'] . '/' . $header_url . '.orig')) {
+ $log = "\n[ {$header_url} ] {$log_tab} Using Previously Downloaded File [ NOW ]\n";
+ } else {
+ $log = "\n[ {$header_url} ] {$log_tab} Downloading New File [ NOW ]\n";
+ }
+ pfb_logger("{$log}","1");
+
+ # Perform Remote URL Date/Time Stamp checks
+ $host = @parse_url($row['url']);
+ $list_url = "{$row['url']}";
+ if ($row['format'] != "rsync" || $row['format'] != "html") {
+ if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) {
+ $remote_tds = "local";
+ } else {
+ $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers($list_url)));
+ $remote_tds = preg_replace("/^Last-Modified: /","", $remote_tds);
+ }
+ }
+
+ $url_list = array();
+ if ($row['format'] == "gz" || $row['format'] == "gz_2") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.gz";
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ # File Exists/Reuse
+ } else {
+ $url_gz = "{$row['url']}";
+ $file_gz = @file_get_contents($url_gz);
+ @file_put_contents($file_dwn, $file_gz, LOCK_EX);
+ if ($remote_tds == "local")
+ $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn));
+ $remote_stamp = strtotime($remote_tds);
+ if (!empty($remote_stamp) && file_exists($file_dwn))
+ touch ($file_dwn, $remote_stamp);
+ }
+ $url_list = @gzfile($file_dwn);
+ }
+
+ # IBlock Large Files mixed with IPs and Domains. PHP mem of 256M can't handle very large Files.
+ if ($row['format'] == "gz_lg") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.gz";
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ # File Exists/Reuse
+ } else {
+ $url_gz = "{$row['url']}";
+ $file_gz = @file_get_contents($url_gz);
+ @file_put_contents($file_dwn, $file_gz, LOCK_EX);
+ exec ("/usr/bin/gunzip -c {$file_dwn} | /usr/bin/sed 's/^.*://' | /usr/bin/grep -v '[a-zA-Z]\|^$\|^#' > {$pfb['origdir']}/{$header_url}.orig");
+ if ($remote_tds == "local")
+ $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn));
+ $remote_stamp = strtotime($remote_tds);
+ if (!empty($remote_stamp) && file_exists($file_dwn))
+ touch ($file_dwn, $remote_stamp);
+ }
+ $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig');
+ }
+
+ elseif ($row['format'] == "zip") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.zip";
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ # File Exists/Reuse
+ } else {
+ $url_zip = "{$row['url']}";
+ if (!$file_zip = @file_get_contents($url_zip)) {
+ $error = error_get_last();
+ $log = "\n [ {$header_url} ] {$error['message']} \n";
+ pfb_logger("{$log}","2");
+ } else {
+ @file_put_contents($file_dwn, $file_zip, LOCK_EX);
+ if ($remote_tds == "local")
+ $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn));
+ $remote_stamp = strtotime($remote_tds);
+ if (!empty($remote_stamp) && file_exists($file_dwn))
+ touch ($file_dwn, $remote_stamp);
+ }
+ }
+ $zip_out = "{$pfb['origdir']}/{$header_url}.orig";
+ exec ("/usr/bin/tar -xOf {$file_dwn} | tr ',' '\n' > {$zip_out}");
+ $url_list = @file($zip_out);
+ }
+
+ elseif ($row['format'] == "et") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.gz";
+ # Script to Call ET IQRISK Process
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ # File Exists/Reuse
+ } else {
+ $url_et = "{$row['url']}";
+ $file_et = @file_get_contents($url_et);
+ @file_put_contents($file_dwn, $file_et, LOCK_EX);
+ if ($remote_tds == "local")
+ $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn));
+ $remote_stamp = strtotime($remote_tds);
+ if (!empty($remote_stamp) && file_exists($file_dwn))
+ touch ($file_dwn, $remote_stamp);
+ }
+ exec ("{$pfb['script']} et {$header_url} x x x x x {$pfb['etblock']} {$pfb['etmatch']} >> {$pfb['log']} 2>&1");
+ $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig');
+ }
+
+ elseif ($row['format'] == "xlsx") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.zip";
+ # Script to Call XLSX Process
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ # File Exists/Reuse
+ } else {
+ $url_xlsx = "{$row['url']}";
+ $file_xlsx = @file_get_contents($url_xlsx);
+ @file_put_contents($file_dwn, $file_xlsx, LOCK_EX);
+ if ($remote_tds == "local")
+ $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn));
+ $remote_stamp = strtotime($remote_tds);
+ if (!empty($remote_stamp) && file_exists($file_dwn))
+ touch ($file_dwn, $remote_stamp);
+ }
+ exec ("{$pfb['script']} xlsx {$header_url} >> {$pfb['log']} 2>&1");
+ $url_list = @file($pfb['origdir'] . '/' . $header_url . '.orig');
+ }
+
+ elseif ($row['format'] == "txt") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.orig";
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ $url_list = @file($file_dwn);
+ } else {
+ $url_other = @file($row['url']);
+ $url_list = $url_other;
+ @file_put_contents($file_dwn, $url_other, LOCK_EX);
+ if ($remote_tds == "local")
+ $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($file_dwn));
+ $remote_stamp = strtotime($remote_tds);
+ if (!empty($remote_stamp) && file_exists($file_dwn))
+ touch ($file_dwn, $remote_stamp);
+ }
+ }
+
+ elseif ($row['format'] == "html" || $row['format'] == "block") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.raw";
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ # File Exists/Reuse
+ $return = 0;
+ } else {
+ $url_html = "{$row['url']}";
+ exec ("/usr/bin/fetch -v -o {$file_dwn} -T 20 {$url_html}",$output,$return);
+ }
+ if ($return == 0)
+ $url_list = @file($file_dwn);
+ }
+
+ elseif ($row['format'] == "rsync") {
+ $file_dwn = "{$pfb['origdir']}/{$header_url}.orig";
+ if ($pfb['reuse'] == "on" && file_exists($file_dwn)) {
+ # File Exists/Reuse
+ } else {
+ $url_rsync = "{$row['url']}";
+ exec ("/usr/local/bin/rsync --timeout=5 {$url_rsync} {$file_dwn}");
+ }
+ $url_list = @file($file_dwn);
+ }
+
+ #extract range lists
+ $new_file = "";
+ if (!empty($url_list)) {
+ if ($row['format'] == "gz" && $vtype == "_v4") {
+ foreach ($url_list as $line) {
+ # Network range 192.168.0.0-192.168.0.254
+ if (preg_match($pfb['range'],$line,$matches)) {
+ $a_cidr = ip_range_to_subnet_array_temp2($matches[1],$matches[2]);
+ if (!empty($a_cidr)) {
+ foreach ($a_cidr as $cidr) {
+ $new_file .= preg_replace($pfb_ipreg,'',$cidr) . "\n";
+ }
+ }
+ }
+ }
+ }
+
+ elseif ($row['format'] == "block" && $vtype == "_v4") {
+ foreach ($url_list as $line) {
+ # Block Type '218.77.79.0 218.77.79.255 24'
+ if (preg_match($pfb['block'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "/24\n";
+ }
+ }
+ }
+
+ elseif ($row['format'] == "html" && $vtype == "_v4") {
+ foreach ($url_list as $line) {
+ # CIDR format 192.168.0.0/16
+ if (preg_match($pfb['cidr'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ # Single ip addresses
+ elseif (preg_match($pfb['s_html'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ }
+ }
+
+ elseif ($vtype == "_v6") {
+ foreach ($url_list as $line) {
+ # IPv6 Regex Match
+ if (preg_match($pfb['ipv6'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ }
+ }
+
+ else {
+ foreach ($url_list as $line) {
+ # CIDR format 192.168.0.0/16
+ if (preg_match($pfb['cidr'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ # Single ip addresses
+ elseif (preg_match($pfb['single'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ }
+ }
+ }
+
+ # Check to see if Blocklist actually Failed Download or has no IPs listed.
+ if ($row['format'] == "html" || $row['format'] == "block") {
+ $url_chk = $file_dwn;
+ } else {
+ $url_chk = "{$pfb['origdir']}/{$header_url}.orig";
+ }
+
+ # Check if File Exists and is >0 in Size
+ $file_chk = "";
+ if (file_exists($url_chk) && @filesize($url_chk) >0)
+ $file_chk = exec ("/usr/bin/grep -cv '^#\|^$' {$url_chk}");
+
+ if ($file_chk == "0") {
+ $new_file = "1.1.1.1\n";
+ $url_other = $new_file;
+ $log = "[ {$header_url} ] Found no IPs, Adding '1.1.1.1' to avoid Download FAIL\n";
+ pfb_logger("{$log}","1");
+ }
+
+ if ($new_file != "") {
+ if ($row['format'] == "gz" || $row['format'] == "gz_2" || $row['format'] == "html" || $row['format'] == "block") {
+ # Re-Save these formats as original file
+ $url_other = $new_file;
+ @file_put_contents($pfb['origdir'] . '/' . $header_url . '.orig',$url_other, LOCK_EX);
+ }
+
+ # Save List to '.txt' format in appropriate Folder
+ @file_put_contents($pfbfolder . '/' .$header_url . '.txt',$new_file, LOCK_EX);
+
+ if ($pfb['rep'] == "on" && $pfb['skip'] && $vtype == "_v4") {
+ # Script to Call p24 Process
+ exec ("{$pfb['script']} p24 {$header_url} {$pfb['max']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1");
+ }
+
+ if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") {
+ # Script to call Duplication Check Process
+ exec ("{$pfb['script']} duplicate {$header_url} >> {$pfb['log']} 2>&1");
+ }
+
+ # PFCTL - Update Only Aliases that have been updated only.
+ $pfb_alias_lists[] = "{$alias}";
+ # Launch d-dup and p-dup functions when changes are found.
+ if ($pfb['skip'] && $vtype == "_v4")
+ $pfb['dupcheck'] = TRUE;
+ # Enable Suppression Process due to Updates
+ if ($pfb['supp'] == "on" && $vtype == "_v4")
+ $pfb['supp_update'] = TRUE;
+
+ } else {
+ # Log FAILED Downloads and Check if Firewall or Snort/Suricata is Blocking Host
+ $log = "\n [ {$alias} {$header_url} ] Download FAIL [ NOW ]\n";
+ pfb_logger("{$log}","2");
+
+ # Rebuild Previous List File from contents of Masterfile
+ if ($pfb['skip'] && $vtype == "_v4") {
+ # Search with trailing Whitespace to match exact Header in Masterfile
+ $header_url2 = $header_url . "[[:space:]]";
+ $file_chk = exec ("/usr/bin/grep {$header_url2} {$pfb['master']} | grep -c ^");
+
+ if (!file_exists($pfbfolder . '/' . $header_url . '.txt') && @$file_chk > 0 && file_exists($pfb['master'])) {
+ $log = " [ {$alias} {$header_url} ] Found: {$file_chk} Line(s), Restoring previous List from Master \n";
+ pfb_logger("{$log}","2");
+ exec ("/usr/bin/grep {$header_url2} {$pfb['master']} | cut -d' ' -f2 > {$pfbfolder}/{$header_url}.txt");
+ }
+ }
+ # A "Space" string Variable
+ $sp = " ";
+ $ip = @gethostbyname($host['host']);
+ $ip2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", "\"^$1\.$2\.$3\.\"", $ip);
+
+ # Only Perform these Checks if they are not "localfiles"
+ if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) {
+ $log = " [ {$alias} {$header_url} ] Local File Failure \n";
+ pfb_logger("{$log}","2");
+ } else {
+ # only perform these steps if an 'IP' is found.
+ if (!empty($ip)) {
+ // Query for Exact IP Match
+ $result_b1 = array();
+ $pfb_b1 = exec ("/usr/bin/grep ^{$ip} {$pfbfolder}/*", $result_b1);
+ // Query for First Three IP Octet Matches
+ $result_b2 = array();
+ $pfb_b2 = exec ("/usr/bin/grep {$ip2} {$pfbfolder}/*", $result_b2);
+ // Query Snort/Suricata snort2c IP Block Table
+ $snort_pfb = exec("/sbin/pfctl -t snort2c -T show | grep {$ip}");
+
+ # If an exact IP Match is not found report any First Three IP Octets.
+ if (!empty($result_b1)) {
+ $final_b1 = implode("\n ", $result_b1);
+ $log = " [ {$alias} {$header_url}, {$ip} ] Firewall IP Block Found in : \n{$sp}{$final_b1}\n";
+ pfb_logger("{$log}","2");
+ } else {
+ if (!empty($result_b2)) {
+ $final_b2 = implode("\n ", $result_b2);
+ $log = " [ {$alias} {$header_url}, {$ip} ] *Potential* Firewall IP Block Found in : \n{$sp}{$final_b2}\n";
+ pfb_logger("{$log}","2");
+ }
+ }
+ if (!empty($snort_pfb)) {
+ $log = " [ {$alias} {$header_url}, {$ip} ] snort2c IP Block Found in : [ {$snort_pfb} ]\n";
+ pfb_logger("{$log}","2");
+ }
+ } else {
+ $log = " [ {$alias} {$header_url} ] No host IP found \n";
+ pfb_logger("{$log}","2");
+ }
+ }
+ }
+ # UNSET variables
+ unset ($file_gz,$file_zip,$file_et,$file_xlsx,$url_other,$url_list);
+ }
+ }
+ }
+ #check custom network list
+ if (pfbng_text_area_decode($list['custom']) != "") {
+
+ if ($vtype == "_v4") {
+ $aliascustom = "{$list['aliasname']}_custom";
+ } else {
+ $aliascustom = "{$list['aliasname']}_custom_v6";
+ }
+
+ # Format Log into clean Tab Spaces
+ if (strlen($aliascustom) > 10) {
+ $log_tab = "\t";
+ } else {
+ $log_tab = "\t\t";
+ }
+
+ # Collect Active Alias List (Used for pfctl Update when 'Reputation' is enabled.
+ $pfb_alias_lists_all[] = "{$alias}";
+
+ # Determine Folder Location for Alias (return array $pfbarr)
+ pfb_determine_list_detail($list['action']);
+ $pfb['skip'] = $pfbarr['skip'];
+ $pfbfolder = $pfbarr['folder'];
+
+ if (file_exists($pfbfolder . '/' . $aliascustom . '.txt') && $pfb['reuse'] == "") {
+ $log = "\n[ {$aliascustom} ] {$log_tab} exists, Reloading File [ NOW ]\n";
+ pfb_logger("{$log}","1");
+ } else {
+ $url_list = array();
+ $log = "\n[ {$aliascustom} ] {$log_tab} Loading Custom File [ NOW ]\n";
+ pfb_logger("{$log}","1");
+
+ $custom_list = pfbng_text_area_decode($list['custom']) . "\n";
+ @file_put_contents($pfb['origdir'] . '/' . $aliascustom . '.orig', $custom_list, LOCK_EX);
+ $url_list = @file($pfb['origdir'] . '/' . $aliascustom . '.orig');
+
+ $new_file = "";
+ if (!empty($url_list)) {
+ foreach ($url_list as $line) {
+ if ($vtype == "_v4") {
+ # CIDR format 192.168.0.0/16
+ if (preg_match($pfb['cidr'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ # Single ip addresses
+ elseif (preg_match($pfb['s_html'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ # Network range 192.168.0.0-192.168.0.254
+ elseif (preg_match($pfb['range'],$line,$matches)) {
+ $a_cidr = ip_range_to_subnet_array_temp2($matches[1],$matches[2]);
+ if (!empty($a_cidr)) {
+ foreach ($a_cidr as $cidr) {
+ $new_file .= preg_replace($pfb_ipreg, '',$cidr) . "\n";
+ }
+ }
+ }
+ } else {
+ # IPv6 Regex
+ if (preg_match($pfb['ipv6'],$line,$matches)) {
+ $new_file .= preg_replace($pfb_ipreg, '',$matches[0]) . "\n";
+ }
+ }
+ }
+
+ }
+ if ($new_file != "") {
+ # PFCTL - Collect Only Aliases that have been updated only.
+ $pfb_alias_lists[] = "{$alias}";
+ # Collect Updated lists for Suppression Process
+ @file_put_contents($pfbfolder . '/'. $aliascustom . '.txt',$new_file, LOCK_EX);
+ # Enable Suppression Process due to Updates
+ if ($pfb['supp'] == "on" && $vtype == "_v4")
+ $pfb['supp_update'] = TRUE;
+ if ($pfb['rep'] == "on" && $pfb['skip'] && $vtype == "_v4") {
+ # Script to Call p24 Process
+ exec ("{$pfb['script']} p24 {$aliascustom} {$pfb['max']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1");
+ }
+ if ($pfb['dup'] == "on" && $pfb['skip'] && $vtype == "_v4") {
+ # Script to call Duplication Check Process
+ exec ("{$pfb['script']} duplicate {$aliascustom} >> {$pfb['log']} 2>&1");
+ }
+ } else {
+ $log = "[ {$aliascustom} ] Custom List Error ]\n";
+ pfb_logger("{$log}","1");
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ #############################################
+ # REPUTATION PROCESSES #
+ #############################################
+
+ # IP Reputation processes (pdup and ddup)
+ if ($pfb['pdup'] == "on" && $pfb['dupcheck'] && !$pfb['save'] && $pfb['enable'] == "on") {
+ # Script to run pdup process
+ exec ("{$pfb['script']} pdup x {$pfb['pmax']} >> {$pfb['log']} 2>&1");
+ }
+ if ($pfb['dedup'] == "on" && $pfb['dupcheck'] && !$pfb['save'] && $pfb['enable'] == "on") {
+ # Script to run dedup process
+ exec ("{$pfb['script']} dedup x {$pfb['dmax']} {$pfb['dedup']} {$pfb['ccexclude']} {$pfb['ccwhite']} {$pfb['ccblack']} >> {$pfb['log']} 2>&1");
+ }
+
+ #############################################
+ # CONFIGURE ALIASES #
+ #############################################
+
+ $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ foreach ($list_type as $ip_type => $vtype) {
+ if ($config['installedpackages'][$ip_type]['config'] != "" && $pfb['enable'] == "on") {
+ $runonce = 0;
+ foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
+ $alias = "pfB_" . preg_replace("/\W/","",$list['aliasname']);
+
+ # Determine Folder Location for Alias (return array $pfbarr)
+ pfb_determine_list_detail($list['action']);
+ $pfb['skip'] = $pfbarr['skip'];
+ $pfb_descr = $pfbarr['descr'];
+ $pfbfolder = $pfbarr['folder'];
+
+ // Re-Save Only Aliases that have been updated only.
+ // When 'Reputation' is used, all Aliases need to be Updated.
+ $final_alias = array();
+ if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") {
+ if (!empty($pfb_alias_lists_all))
+ $final_alias = array_unique($pfb_alias_lists_all);
+ } else {
+ if (!empty($pfb_alias_lists))
+ $final_alias = array_unique($pfb_alias_lists);
+ }
+
+ if ($list['action'] != "Disabled") {
+ #remove empty lists files if any
+ if (is_array($list['row'])) {
+ $update = 0;
+ ${$alias} = "";
+ foreach ($list['row'] as $row) {
+ if ($row['url'] != "" && $row['state'] != "Disabled") {
+ if ($vtype == "_v4") {
+ $header_url = "{$row['header']}";
+ } else {
+ $header_url = "{$row['header']}_v6";
+ }
+ $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$alias} | awk '/Addresses/ {s+=$2}; END {print s}'");
+
+ # Update Alias if List File Exists and its been updated or if the Alias URL Table is Empty.
+ if (file_exists($pfbfolder . "/" . $header_url . ".txt") && in_array($alias, $final_alias) || file_exists($pfbfolder . "/" . $header_url . ".txt") && empty($pfctlck)) {
+ # Script to run Suppression process (Print Header Only)
+ if ($pfb['supp'] == "on" && $vtype == "_v4" && $runonce == 0 && $pfb['supp_update']) {
+ exec ("{$pfb['script']} suppress x x x suppressheader >> {$pfb['log']} 2>&1");
+ $runonce++;
+ }
+ # Script to run Suppression Process (Body)
+ if ($pfb['supp'] == "on" && $vtype == "_v4" && $pfb['supp_update']) {
+ if ($pfb['dup'] == "on" || !$pfb['skip']) {
+ # Execute if Duplication Process is Enabled or List is Permit or Match
+ exec ("{$pfb['script']} suppress x x x {$header_url}\|{$pfbfolder}/ >> {$pfb['log']} 2>&1");
+ } else {
+ # Execute if Duplication Process is Disabled
+ exec ("{$pfb['script']} suppress x x off {$header_url}\|{$pfbfolder}/ >> {$pfb['log']} 2>&1");
+ }
+ }
+ ${$alias} .= file_get_contents($pfbfolder . '/' . $header_url . '.txt');
+ $update++;
+ }
+ }
+ }
+ }
+
+ #check custom network list
+ if ($vtype == "_v4") {
+ $aliasname = "{$list['aliasname']}_custom";
+ } else {
+ $aliasname = "{$list['aliasname']}_custom_v6";
+ }
+
+ # Update Alias if List File Exists and its been updated or if the Alias URL Table is Empty.
+ $pfctlck = exec ("/sbin/pfctl -vvsTables | grep -A1 {$alias} | awk '/Addresses/ {s+=$2}; END {print s}'");
+
+ if (pfbng_text_area_decode($list['custom']) != "") {
+ if (file_exists($pfbfolder . "/" . $aliasname . ".txt") && in_array($alias, $final_alias) || file_exists($pfbfolder . "/" . $aliasname . ".txt") && empty($pfctlck)) {
+ ${$alias} .= file_get_contents($pfbfolder . '/' . $aliasname . '.txt');
+ $update++;
+ }
+ }
+ # Determine Validity of Alias URL Tables/Rules. ie: Don't create Empty URL Tables or Aliases
+ if (${$alias} == "" && empty($pfctlck)) {
+ unlink_if_exists($pfb['aliasdir'] . '/' . $alias. '.txt');
+ } else {
+ // Save Only Aliases that have been updated.
+ if ($update > 0) {
+ @file_put_contents($pfb['aliasdir'] . '/' . $alias. '.txt',${$alias}, LOCK_EX);
+ }
+
+ $alias_log = $list['aliaslog'];
+ #create alias
+ $new_aliases_list[] = "{$alias}";
+
+ $new_aliases[] = array( "name" => "{$alias}",
+ "url" => "{$pfb['weblocal']}?pfb={$alias}",
+ "updatefreq" => "32",
+ "address" => "",
+ "descr" => "pfBlockerNG {$pfb_descr} List Alias",
+ "type" => "urltable",
+ "detail" => "DO NOT EDIT THIS ALIAS"
+ );
+
+ #Create rule if action permits
+ switch ($list['action']) {
+ case "Deny_Both":
+ case "Deny_Outbound":
+ $rule = $base_rule;
+ $rule['type'] = "{$pfb['deny_action_outbound']}";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$alias}{$pfb['suffix']}";
+ $rule['source'] = array ("any" => "");
+ $rule['destination'] = array ("address" => "{$alias}");
+ if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled")
+ $rule['log'] = "";
+ $deny_outbound[] = $rule;
+ if ($list['action'] != "Deny_Both")
+ break;
+ case "Deny_Inbound":
+ $rule = $base_rule;
+ $rule['type'] = "{$pfb['deny_action_inbound']}";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$alias}{$pfb['suffix']}";
+ $rule['source'] = array("address" => "{$alias}");
+ $rule['destination'] = array ("any" => "");
+ if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled")
+ $rule['log'] = "";
+ $deny_inbound[] = $rule;
+ break;
+ case "Permit_Both":
+ case "Permit_Outbound":
+ $rule = $base_rule;
+ $rule['type'] = "pass";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$alias}{$pfb['suffix']}";
+ $rule['source'] = array ("any" => "");
+ $rule['destination'] = array ("address" => "{$alias}");
+ if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled")
+ $rule['log'] = "";
+ $permit_outbound[] = $rule;
+ if ($list['action'] != "Permit_Both")
+ break;
+ case "Permit_Inbound":
+ $rule = $base_rule;
+ $rule['type'] = "pass";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ if ($pfb['float'] == "on")
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$alias}{$pfb['suffix']}";
+ $rule['source'] = array ("address" => "{$alias}");
+ $rule['destination'] = array ("any" => "");
+ if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled")
+ $rule['log'] = "";
+ $permit_inbound[] = $rule;
+ break;
+ case "Match_Both":
+ case "Match_Outbound":
+ $rule = $base_rule_float;
+ $rule['type'] = "match";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$alias}{$pfb['suffix']}";
+ $rule['source'] = array ("any" => "");
+ $rule['destination'] = array ("address" => "{$alias}");
+ if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled")
+ $rule['log'] = "";
+ $match_outbound[] = $rule;
+ if ($list['action'] != "Match_Both")
+ break;
+ case "Match_Inbound":
+ $rule = $base_rule_float;
+ $rule['type'] = "match";
+ if ($vtype == "_v6")
+ $rule['ipprotocol'] = "inet6";
+ $rule['direction'] = "any";
+ $rule['descr'] = "{$alias}{$pfb['suffix']}";
+ $rule['source'] = array ("address" => "{$alias}");
+ $rule['destination'] = array ("any" => "");
+ if ($pfb['config']['enable_log'] == "on" || $alias_log == "enabled")
+ $rule['log'] = "";
+ $match_inbound[] = $rule;
+ break;
+ }
+ }
+ #mark pfctl aliastable for cleanup
+ if (!in_array($alias, $aliases_list)) {
+ $aliases_list[] = "{$alias}";
+ }
+ } else {
+ #unlink previous pfblockerNG alias list if any
+ unlink_if_exists($pfb['aliasdir'] . '/' . $alias . '.txt');
+ }
+ }
+ }
+ }
+ # Clear Variables
+ ${$alias} = "";
+
+
+ #############################################
+ # UPDATE PfSENSE ALIAS TABLES #
+ #############################################
+
+ #update pfsense alias table
+ if (is_array($config['aliases']['alias'])) {
+ foreach ($config['aliases']['alias'] as $cbalias) {
+ if (preg_match("/pfB_/",$cbalias['name'])) {
+ #mark pfctl aliastable for cleaning
+ if (!in_array($cbalias['name'], $aliases_list)) {
+ $aliases_list[] = $cbalias['name']; #mark aliastable for cleaning
+ }
+ #remove previous aliastable file if alias is not defined any more
+ if (!in_array($cbalias['name'], $new_aliases_list)) {
+ unlink_if_exists($pfb['aliasdir'] . '/' . $cbalias['name'] . ".txt");
+ }
+ } else {
+ $new_aliases[] = $cbalias;
+
+ # Check Table Size
+ if (file_exists($pfb['aliasdir'] . '/' . $alias . '.txt') && $message == "") {
+ preg_match("/(\d+)/",exec("/usr/bin/grep -c ^ " . $pfb['aliasdir'] . '/' . $alias . '.txt'),$matches);
+ }
+ if (($matches[1] * 2.1) >= $pfb['table_limit']) {
+ #alias table too large
+ $message = "{$alias} alias table is too large. Reduce networks in list or increase 'Firewall Maximum Table Entries' value to at least " . (int)($matches[1] * 2.1) . ' in "system - advanced - Firewall/NAT" . ';
+ }
+ }
+ }
+ }
+
+ #apply new alias table to xml
+ if ($message == "") {
+ $config['aliases']['alias'] = $new_aliases;
+ }
+ # UNSET Variables
+ unset($new_aliases, $cbalias);
+
+
+ #############################################
+ # Assign rules #
+ #############################################
+
+ # Only Execute if AutoRules are defined or if an Alias has been removed.
+ if ($pfb['autorules'] || $pfb['enable'] == "" || $pfb['remove']) {
+ if (count($deny_inbound) > 0 || count($permit_inbound) > 0 || count($match_inbound) > 0) {
+ if ($pfb['inbound_interfaces'] == "") {
+ $message = "Unable to apply rules. Inbound Interface option not configured.";
+ }
+ }
+ if (count($deny_outbound) > 0 || count($permit_outbound) > 0 || count($match_outbound) > 0) {
+ if ($pfb['outbound_interfaces'] == "") {
+ $message = "Unable to apply rules. Outbound Interface option not configured.";
+ }
+ }
+
+ if ($message == "") {
+ $new_rules = array();
+ $permit_rules = array();
+ $match_rules = array();
+ $other_rules = array();
+ $fpermit_rules = array();
+ $fmatch_rules = array();
+ $fother_rules = array();
+
+ # Collect All Existing Rules
+ $rules = $config['filter']['rule'];
+ # Collect Existing pfSense Rules 'Pass', 'Match' and 'Other' pfSense rules into new Arrays.
+ if (!empty($rules)) {
+ foreach ($rules as $rule) {
+ if (!preg_match("/pfB_.*" . $pfb['suffix'] . "/",$rule['descr'])) {
+ // Floating rules collection 'Floating Pass/Match'. Balance to 'other'
+ if ($pfb['float'] == "on") {
+ if ($rule['type'] == "pass" && $rule['floating'] == "yes") {
+ $fpermit_rules[] = $rule;
+ } elseif ($rule['type'] == "match" && $rule['floating'] == "yes") {
+ $fmatch_rules[] = $rule;
+ } elseif ($rule['floating'] == "yes") {
+ $fother_rules[] = $rule;
+ } else {
+ $other_rules[] = $rule;
+ }
+ } else {
+ // Collect only 'Selected Inbound and Outbound Interfaces'. Balance to 'Other'
+ if (in_array($rule['interface'],$pfb['inbound_interfaces']) || in_array($rule['interface'],$pfb['outbound_interfaces'])) {
+ // Floating Rules 'off'. Collect 'Floating Other', Balance to 'Other'
+ if ($rule['floating'] == "yes") {
+ $fother_rules[] = $rule;
+ } elseif ($rule['type'] == "pass") {
+ if ($pfb['order'] == "order_0") {
+ $other_rules[] = $rule;
+ } else {
+ $permit_rules[] = $rule;
+ }
+ } elseif ($rule['type'] == "match") {
+ if ($pfb['order'] == "order_0") {
+ $other_rules[] = $rule;
+ } else {
+ $match_rules[] = $rule;
+ }
+ } else {
+ $other_rules[] = $rule;
+ }
+ } else {
+ if ($rule['floating'] == "yes") {
+ $fother_rules[] = $rule;
+ } else {
+ $other_rules[] = $rule;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ #################################################################################
+ # PASS/MATCH RULES ORDER(p/m) #
+ # ORDER 0 - pfBlockerNG / All other Rules #
+ # ORDER 1 - pfSense (p/m) / pfBlockerNG (p/m) / pfBlockerNG Block/Reject #
+ # ORDER 2 - pfBlockerNG (p/m) / pfSense (p/m) / pfBlockerNG Block/Reject #
+ # ORDER 3 - pfBlockerNG (p/m) / pfBlockerNG Block/Reject / pfSense (p/m) #
+ #################################################################################
+
+ if ($pfb['float'] == "") {
+ if (!empty($fother_rules)) {
+ foreach ($fother_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ }
+ if (!empty($fpermit_rules) && $pfb['order'] == "order_1") {
+ foreach ($fpermit_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($fmatch_rules) && $pfb['order'] == "order_1") {
+ foreach ($fmatch_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+
+ # Define Inbound Interface Rules
+ if (!empty($pfb['inbound_interfaces'])) {
+ $counter = 0;
+ foreach ($pfb['inbound_interfaces'] as $inbound_interface) {
+ if (!empty($permit_rules) && $pfb['order'] == "order_1") {
+ foreach ($permit_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $inbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($match_rules) && $pfb['order'] == "order_1") {
+ foreach ($match_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $inbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ # Match Inbound Rules defined as Floating Only.
+ if (!empty($match_inbound) && $counter == 0) {
+ foreach ($match_inbound as $cb_rules) {
+ $cb_rules['interface'] = $pfb['inbound_floating'];
+ $new_rules[] = $cb_rules;
+ $counter ++;
+ }
+ }
+ if (!empty($permit_inbound)) {
+ foreach ($permit_inbound as $cb_rules) {
+ $cb_rules['interface'] = $inbound_interface;
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($fpermit_rules) && $pfb['order'] == "order_2") {
+ foreach ($fpermit_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($fmatch_rules) && $pfb['order'] == "order_2") {
+ foreach ($fmatch_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($permit_rules) && $pfb['order'] == "order_2") {
+ foreach ($permit_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $inbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($match_rules) && $pfb['order'] == "order_2") {
+ foreach ($match_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $inbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($deny_inbound)) {
+ foreach ($deny_inbound as $cb_rules) {
+ $cb_rules['interface'] = $inbound_interface;
+ $new_rules[] = $cb_rules;
+ }
+ }
+ }
+ }
+
+ # Define Outbound Interface Rules
+ if (!empty($pfb['outbound_interfaces'])) {
+ $counter = 0;
+ foreach ($pfb['outbound_interfaces'] as $outbound_interface) {
+ if (!empty($permit_rules) && $pfb['order'] == "order_1") {
+ foreach ($permit_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $outbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($match_rules) && $pfb['order'] == "order_1") {
+ foreach ($match_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $outbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ # Match Outbound Rules defined as Floating Only.
+ if (!empty($match_outbound) && $counter == 0) {
+ foreach ($match_outbound as $cb_rules) {
+ $cb_rules['interface'] = $pfb['outbound_floating'];
+ $new_rules[] = $cb_rules;
+ $counter++;
+ }
+ }
+ if (!empty($permit_outbound)) {
+ foreach ($permit_outbound as $cb_rules) {
+ $cb_rules['interface'] = $outbound_interface;
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($permit_rules) && $pfb['order'] == "order_2") {
+ foreach ($permit_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $outbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($match_rules) && $pfb['order'] == "order_2") {
+ foreach ($match_rules as $cb_rules) {
+ if ($cb_rules['interface'] == $outbound_interface)
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($deny_outbound)) {
+ foreach ($deny_outbound as $cb_rules) {
+ $cb_rules['interface'] = $outbound_interface;
+ $new_rules[] = $cb_rules;
+ }
+ }
+ }
+ }
+
+ if (!empty($fpermit_rules) && $pfb['order'] == "order_0") {
+ foreach ($fpermit_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($fmatch_rules) && $pfb['order'] == "order_0") {
+ foreach ($fmatch_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($fpermit_rules) && $pfb['order'] == "order_3") {
+ foreach ($fpermit_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($fmatch_rules) && $pfb['order'] == "order_3") {
+ foreach ($fmatch_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($permit_rules) && $pfb['order'] == "order_3") {
+ foreach ($permit_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if (!empty($match_rules) && $pfb['order'] == "order_3") {
+ foreach ($match_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ if ($pfb['float'] == "on") {
+ if (!empty($fother_rules)) {
+ foreach ($fother_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+ }
+ if (!empty($other_rules)) {
+ foreach ($other_rules as $cb_rules) {
+ $new_rules[] = $cb_rules;
+ }
+ }
+
+ # Save New Rule Order to Config
+ $config['filter']['rule'] = $new_rules;
+ }
+ $log = "\n {$message} \n";
+ pfb_logger("{$log}","1");
+
+ # UNSET arrays
+ unset ($cb_rules,$permit_inbound,$permit_outbound,$deny_inbound,$deny_outbound,$match_inbound,$match_outbound);
+ unset ($other_rules,$fother_rules,$permit_rules,$fpermit_rules,$match_rules,$fmatch_rules);
+ }
+
+ #############################################
+ # Define/Apply CRON Jobs #
+ #############################################
+
+ # Clear any existing pfBlockerNG Cron Jobs
+ install_cron_job("pfblockerng.php cron", false);
+
+ # Replace Cron job with any User Changes to $pfb_min
+ if ($pfb['enable'] == "on") {
+ # Define pfBlockerNG CRON Job
+ $pfb_cmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php cron >> {$pfb['log']} 2>&1";
+ # $pfb['min'] ( User Defined Variable. Variable defined at start of Script )
+ $pfb_hour = "*";
+ $pfb_mday = "*";
+ $pfb_month = "*";
+ $pfb_wday = "*";
+ $pfb_who = "root";
+
+ install_cron_job($pfb_cmd, true, $pfb['min'], $pfb_hour, $pfb_mday, $pfb_month, $pfb_wday, $pfb_who);
+ }
+
+ # Clear any existing pfBlockerNG MaxMind CRON Job
+ install_cron_job("pfblockerng.php dc", false);
+
+ if ($pfb['enable'] == "on") {
+ # Define pfBlockerNG MaxMind CRON Job
+ $pfb_gcmd = "/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php dc >> {$pfb['geolog']} 2>&1";
+
+ # MaxMind GeoIP Cron Hour is randomized between 0-23 Hour to minimize effect on MaxMind Website
+
+ $pfb_gmin = "0";
+ $pfb_ghour = rand(0,23);
+ $pfb_gmday = "1,2,3,4,5,6,7";
+ $pfb_gmonth = "*";
+ $pfb_gwday = "2";
+ $pfb_gwho = "root";
+
+ install_cron_job($pfb_gcmd, true, $pfb_gmin, $pfb_ghour, $pfb_gmday, $pfb_gmonth, $pfb_gwday, $pfb_gwho);
+ }
+
+
+ #############################################
+ # Closing Processes #
+ #############################################
+
+ #uncheck Reusing Existing Downloads Check box
+ if (!$pfb['save'] && $pfb['enable'] == "on")
+ $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = "";
+
+ # Save all Changes to pfSense config file
+ write_config();
+
+ # If 'Rule Changes' are found, utilize the 'filter_configure()' function, if not, utilize 'pfctl replace' command
+ if ($pfb['autorules'] && $rules != $new_rules || $pfb['enable'] == "" || $pfb['remove']) {
+ require_once("filter.inc");
+
+ $log = "\n===[ Aliastables / Rules ]================================\n\n";
+ pfb_logger("{$log}","1");
+
+ $log = "Firewall Rule Changes Found, Applying Filter Reload \n";
+ pfb_logger("{$log}","1");
+
+ # Remove all pfBlockerNG Alias tables
+ if (!empty($aliases_list)) {
+ foreach ($aliases_list as $table) {
+ exec ("/sbin/pfctl -t " . escapeshellarg($table) . " -T kill 2>&1", $pfb_null);
+ }
+ }
+
+ #load filter file which will create the pfctl tables
+ filter_configure();
+ } else {
+ # Don't Execute on User 'Save'
+ if (!$pfb['save']) {
+
+ $log = "\n===[ Aliastables / Rules ]================================\n\n";
+ pfb_logger("{$log}","1");
+
+ $log = "No Changes to Firewall Rules, Skipping Filter Reload \n";
+ pfb_logger("{$log}","1");
+
+ // Re-Save Only Aliases that have been updated only.
+ // When 'Reputation' is used, all Aliases Need to be Updated.
+ $final_alias = array();
+ if ($pfb['dedup'] == "on" || $pfb['pdup'] == "on") {
+ if (!empty($pfb_alias_lists_all))
+ $final_alias = array_unique($pfb_alias_lists_all);
+ } else {
+ if (!empty($pfb_alias_lists))
+ $final_alias = array_unique($pfb_alias_lists);
+ }
+
+ if (!empty($final_alias)) {
+ foreach ($final_alias as $final) {
+ $log = "\n Updating: {$final} \n";
+ pfb_logger("{$log}","1");
+ $result_pfctl = "";
+ exec ("/sbin/pfctl -t " . escapeshellarg($final) . " -T replace -f " . $pfb['aliasdir'] . "/" . escapeshellarg($final) . ".txt 2>&1", $result_pfctl);
+ $log = implode($result_pfctl);
+ pfb_logger("{$log}","1");
+ }
+ } else {
+ $log = "\n No Changes to Aliases, Skipping pfctl Update \n";
+ pfb_logger("{$log}","1");
+ }
+ }
+ }
+ # UNSET Variables
+ unset($rules, $new_rules);
+
+ #sync config
+ pfblockerng_sync_on_changes();
+
+ #############################################
+ # FINAL REPORTING #
+ #############################################
+
+ # Only run with CRON or Force Invoked Process
+ if ((!$pfb['save'] && $pfb['dupcheck'] && $pfb['enable'] == "on") || $pfb['summary']) {
+ # Script to run Final Script Processes.
+ exec ("{$pfb['script']} closing {$pfb['dup']} >> {$pfb['log']} 2>&1");
+ }
+
+ if ($pfb['enable'] == "on" && !$pfb['save']) {
+ $log = "\n\n UPDATE PROCESS ENDED [ NOW ]\n";
+ pfb_logger("{$log}","1");
+ }
+}
+
+
+function pfblockerng_validate_input($post, &$input_errors) {
+ global $config;
+ foreach ($post as $key => $value) {
+ if (empty($value))
+ continue;
+ if ($key == "message_size_limit" && !is_numeric($value))
+ $input_errors[] = "Message size limit must be numeric.";
+ if ($key == "process_limit" && !is_numeric($value))
+ $input_errors[] = "Process limit must be numeric.";
+ if ($key == "freq" && (!preg_match("/^\d+(h|m|d)$/",$value) || $value == 0))
+ $input_errors[] = "A valid number with a time reference is required for the field 'Frequency'";
+ if (substr($key, 0, 2) == "dc" && !is_hostname($value))
+ $input_errors[] = "{$value} is not a valid host name.";
+ if (substr($key, 0, 6) == "domain" && is_numeric(substr($key, 6))) {
+ if (!is_domain($value))
+ $input_errors[] = "{$value} is not a valid domain name.";
+ } else if (substr($key, 0, 12) == "mailserverip" && is_numeric(substr($key, 12))) {
+ if (empty($post['domain' . substr($key, 12)]))
+ $input_errors[] = "Domain for {$value} cannot be blank.";
+ if (!is_ipaddr($value) && !is_hostname($value))
+ $input_errors[] = "{$value} is not a valid IP address or host name.";
+ }
+ }
+}
+
+
+function pfblockerng_php_install_command() {
+ require_once("/usr/local/www/pfblockerng/pfblockerng.php");
+ global $config,$pfb;
+ pfb_global();
+
+ // Remove previously used CC folder location if exists
+ @rmdir_recursive("{$pfb['dbdir']}/cc");
+
+ # Uncompress Country Code File and delete Archive after extraction.
+ exec("cd /{$pfb['ccdir']}; /usr/bin/tar -jxvf {$pfb['ccdir']}/countrycodes.tar.bz2");
+ unlink_if_exists("{$pfb['ccdir']}/countrycodes.tar.bz2");
+ # Download MaxMind Files and Create Country Code files and Build Continent XML Files
+ update_output_window(gettext("Downloading MaxMind Country Databases. This may take a minute..."));
+ exec("/bin/sh /usr/local/pkg/pfblockerng/geoipupdate.sh all >> {$pfb['geolog']} 2>&1");
+
+ @rename("{$pfb['dbdir']}/GeoIP.dat", "{$pfb['ccdir']}/GeoIP.dat");
+ @rename("{$pfb['dbdir']}/GeoIPv6.dat", "{$pfb['ccdir']}/GeoIPv6.dat");
+
+ update_output_window(gettext("MaxMind Country Database downloads completed..."));
+ update_output_window(gettext("Converting MaxMind Country Databases for pfBlockerNG. This may take a few minutes..."));
+ pfblockerng_uc_countries();
+ update_output_window(gettext("Creating pfBlockerNG Continenet XML Files..."));
+ pfblockerng_get_countries();
+ update_output_window(gettext("Completed Creating pfBlockerNG Continenet XML Files..."));
+
+ // Remove Original Maxmind Database Files
+ @unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryCSV.zip");
+ @unlink_if_exists("{$pfb['dbdir']}/GeoIPCountryWhois.csv");
+ @unlink_if_exists("{$pfb['dbdir']}/GeoIPv6.csv");
+ @unlink_if_exists("{$pfb['dbdir']}/country_continent.csv");
+
+ # Add Widget to Dashboard
+ update_output_window(gettext("Adding pfBlockerNG Widget to Dashboard."));
+ if ($pfb['keep'] == "on" && !empty($pfb['widgets'])) {
+ // Restore previous Widget setting if "Keep" is enabled.
+ $config['widgets']['sequence'] = $pfb['widgets'];
+ } else {
+ $widgets = $config['widgets']['sequence'];
+ if (!preg_match("/pfblockerng-container/", $widgets)) {
+ if (empty($widgets)) {
+ $config['widgets']['sequence'] = "pfblockerng-container:col2:show";
+ } else {
+ $config['widgets']['sequence'] .= ",pfblockerng-container:col2:show";
+ }
+ }
+ }
+}
+
+
+function pfblockerng_php_deinstall_command() {
+ require_once("config.inc");
+ global $config,$pfb;
+
+ # Set these two variables to Disable pfBlockerNG on De-Install
+ $pfb['save'] = TRUE;
+ $pfb['install'] = TRUE;
+ sync_package_pfblockerng();
+ rmdir_recursive("/usr/local/pkg/pfblockerng");
+ rmdir_recursive("/usr/local/www/pfblockerng");
+
+ # Maintain pfBlockerNG Settings and Database Files if $pfb['keep'] is ON.
+ if ($pfb['keep'] != "on") {
+ # Remove pfBlockerNG Log and DB Folder
+ rmdir_recursive("{$pfb['dbdir']}");
+ rmdir_recursive("{$pfb['logdir']}");
+
+ # Remove Settings from Config
+ if (is_array($config['installedpackages']['pfblockerng']))
+ unset($config['installedpackages']['pfblockerng']);
+ if (is_array($config['installedpackages']['pfblockerngglobal']))
+ unset($config['installedpackages']['pfblockerngglobal']);
+ if (is_array($config['installedpackages']['pfblockerngsync']))
+ unset($config['installedpackages']['pfblockerngsync']);
+ if (is_array($config['installedpackages']['pfblockerngreputation']))
+ unset($config['installedpackages']['pfblockerngreputation']);
+ if (is_array($config['installedpackages']['pfblockernglistsv4']))
+ unset($config['installedpackages']['pfblockernglistsv4']);
+ if (is_array($config['installedpackages']['pfblockernglistsv6']))
+ unset($config['installedpackages']['pfblockernglistsv6']);
+ if (is_array($config['installedpackages']['pfblockerngafrica']))
+ unset($config['installedpackages']['pfblockerngafrica']);
+ if (is_array($config['installedpackages']['pfblockerngantartica']))
+ unset($config['installedpackages']['pfblockerngantartica']);
+ if (is_array($config['installedpackages']['pfblockerngasia']))
+ unset($config['installedpackages']['pfblockerngasia']);
+ if (is_array($config['installedpackages']['pfblockerngeurope']))
+ unset($config['installedpackages']['pfblockerngeurope']);
+ if (is_array($config['installedpackages']['pfblockerngnorthamerica']))
+ unset($config['installedpackages']['pfblockerngnorthamerica']);
+ if (is_array($config['installedpackages']['pfblockerngoceania']))
+ unset($config['installedpackages']['pfblockerngoceania']);
+ if (is_array($config['installedpackages']['pfblockerngsouthamerica']))
+ unset($config['installedpackages']['pfblockerngsouthamerica']);
+ if (is_array($config['installedpackages']['pfblockerngtopspammers']))
+ unset($config['installedpackages']['pfblockerngtopspammers']);
+ if (is_array($config['installedpackages']['pfblockerngproxyandsatellite']))
+ unset($config['installedpackages']['pfblockerngproxyandsatellite']);
+ }
+
+ # Remove Widget (code from Snort deinstall)
+ $pfb['widgets'] = $config['widgets']['sequence'];
+ if (!empty($pfb['widgets'])) {
+ $widgetlist = explode(",", $pfb['widgets']);
+ foreach ($widgetlist as $key => $widget) {
+ if (strstr($widget, "pfblockerng-container")) {
+ unset($widgetlist[$key]);
+ break;
+ }
+ }
+ $config['widgets']['sequence'] = implode(",", $widgetlist);
+ }
+ update_output_window(gettext("pfBlockerNG has been Uninstalled"));
+}
+
+/* Uses XMLRPC to synchronize the changes to a remote node */
+function pfblockerng_sync_on_changes() {
+ global $config, $g, $pfb_sync;
+
+ // Create Array of Sync Settings and exit if Sync is Disabled.
+ if (is_array($config['installedpackages']['pfblockerngsync']['config'][0])) {
+ $pfb_sync = $config['installedpackages']['pfblockerngsync']['config'][0];
+ if ($pfb_sync['varsynconchanges'] == "disabled" || $pfb_sync['varsynconchanges'] == "")
+ return;
+
+ $synctimeout = $pfb_sync['varsynctimeout'];
+ } else {
+ return;
+ }
+
+ log_error("[pfBlockerNG] XMLRPC sync is starting.");
+
+ if (is_array($config['installedpackages']['pfblockerngsync']['config'])) {
+ switch ($pfb_sync['varsynconchanges']) {
+ case "manual":
+ if (is_array($pfb_sync[row])) {
+ $rs = $pfb_sync[row];
+ } else {
+ log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured.");
+ return;
+ }
+ break;
+ case "auto":
+ if (is_array($config['installedpackages']['carpsettings']) && is_array($config['installedpackages']['carpsettings']['config'])){
+ $system_carp = $config['installedpackages']['carpsettings']['config'][0];
+ $rs[0]['varsyncipaddress'] = $system_carp['synchronizetoip'];
+ $rs[0]['varsyncusername'] = $system_carp['username'];
+ $rs[0]['varsyncpassword'] = $system_carp['password'];
+
+ // XMLRPC sync is currently only supported over connections using the same protocol and port as this system
+ if ($config['system']['webgui']['protocol'] == "http") {
+ $rs[0]['varsyncprotocol'] = "http";
+ } else {
+ $rs[0]['varsyncprotocol'] = "https";
+ }
+
+ if ($system_carp['synchronizetoip'] == "") {
+ log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured.");
+ return;
+ }
+ } else {
+ log_error("[pfBlockerNG] XMLRPC sync is enabled but there are no replication targets configured.");
+ return;
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+ if (is_array($rs)) {
+ foreach ($rs as $sh) {
+ // Only Sync Enabled Replication Targets
+ if ($sh['varsyncdestinenable'] == "ON") {
+ $sync_to_ip = $sh['varsyncipaddress'];
+ $port = $sh['varsyncport'];
+ $password = htmlspecialchars($sh['varsyncpassword']);
+ $protocol = $sh['varsyncprotocol'];
+
+ if (!empty($sh['varsyncusername'])) {
+ $username = $sh['varsyncusername'];
+ } else {
+ $username = "admin";
+ }
+
+ pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout);
+ }
+ }
+ if ($success)
+ log_error("[pfBlockerNG] XMLRPC sync completed successfully.");
+ }
+ }
+}
+
+
+/* Do the actual XMLRPC sync */
+function pfblockerng_do_xmlrpc_sync($sync_to_ip, $port, $protocol, $username, $password, $synctimeout) {
+ global $config, $g, $pfb_sync;
+ $success = TRUE;
+
+ /* Exit on missing parameters */
+ if (empty($sync_to_ip) || empty($password)) {
+ log_error("[pfBlockerNG] XMLRPC sync parameter missing (host IP or password) ... aborting xmlrpc sync");
+ $success = FALSE;
+ return $success;
+ }
+
+ /* Do not attempt a package sync while booting up or installing package */
+ if ($g['booting'] || $g['pfblockerng_postinstall']) {
+ log_error("[pfBlockerNG] XMLRPC sync to Replication targets terminated during boot up or during package reinstallation.");
+ $success = FALSE;
+ return $success;
+ }
+
+ // Validate Replication Target IP Address and Port Settings
+ if (!is_ipaddr($sync_to_ip) || !is_port($port)) {
+ log_error("[pfBlockerNG] XMLRPC sync terminated due to mis-configured Replication Target IP Address or Port settings.");
+ $success = FALSE;
+ return $success;
+ }
+
+ /* Test key variables and set defaults if empty */
+ if (empty($synctimeout))
+ $synctimeout = 150;
+
+ $url = "{$protocol}://{$sync_to_ip}";
+
+ if ($port == "") { $port = $config['system']['webgui']['port']; };
+ /* If port is empty lets rely on the protocol selection */
+ if ($port == "") {
+ if ($config['system']['webgui']['protocol'] == "http") {
+ $port = "80";
+ } else {
+ $port = "443";
+ }
+ }
+ /* xml will hold the sections to sync */
+ $xml = array();
+ // If User Disabled, remove 'General Tab Customizations' from Sync
+ if ($config['installedpackages']['pfblockerngsync']['config'][0]['syncinterfaces'] == "")
+ $xml['pfblockerng'] = $config['installedpackages']['pfblockerng'];
+ $xml['pfblockerngreputation'] = $config['installedpackages']['pfblockerngreputation'];
+ $xml['pfblockernglistsv4'] = $config['installedpackages']['pfblockernglistsv4'];
+ $xml['pfblockernglistsv6'] = $config['installedpackages']['pfblockernglistsv6'];
+ $xml['pfblockerngtopspammers'] = $config['installedpackages']['pfblockerngtopspammers'];
+ $xml['pfblockerngafrica'] = $config['installedpackages']['pfblockerngafrica'];
+ $xml['pfblockerngantartica'] = $config['installedpackages']['pfblockerngantartica'];
+ $xml['pfblockerngasia'] = $config['installedpackages']['pfblockerngasia'];
+ $xml['pfblockerngeurope'] = $config['installedpackages']['pfblockerngeurope'];
+ $xml['pfblockerngnorthamerica'] = $config['installedpackages']['pfblockerngnorthamerica'];
+ $xml['pfblockerngoceania'] = $config['installedpackages']['pfblockerngoceania'];
+ $xml['pfblockerngsouthamerica'] = $config['installedpackages']['pfblockerngsouthamerica'];
+
+ /* assemble xmlrpc payload */
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($xml)
+ );
+
+ /* set a few variables needed for sync code borrowed from filter.inc */
+ log_error("[pfBlockerNG] XMLRPC syncing to {$url}:{$port}.");
+ $method = 'pfsense.merge_installedpackages_section_xmlrpc';
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials($username, $password);
+ if ($g['debug']) {
+ $cli->setDebug(1);
+ }
+
+ /* send our XMLRPC message and timeout after defined sync timeout value */
+ $resp = $cli->send($msg, $synctimeout);
+ $error = "";
+ if (!$resp) {
+ log_error("[pfBlockerNG] XMLRPC communications error occurred while attempting sync with {$url}:{$port}.");
+ file_notice("sync_settings", $error, "pfBlockerNG Settings Sync", "");
+ $success = FALSE;
+ return $success;
+ } elseif ($resp->faultCode()) {
+ $cli->setDebug(1);
+ $resp = $cli->send($msg, $synctimeout);
+ log_error("[pfBlockerNG] XMLRPC Error received while attempting sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString());
+ file_notice("sync_settings", $error, "pfBlockerNG Settings Sync", "");
+ $success = FALSE;
+ return $success;
+ } else {
+ log_error("[pfBlockerNG] XMLRPC sync successfully completed with {$url}:{$port}.");
+ }
+ return $success;
+}
+?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.js b/config/pfblockerng/pfblockerng.js
new file mode 100644
index 00000000..cef0ce3b
--- /dev/null
+++ b/config/pfblockerng/pfblockerng.js
@@ -0,0 +1,79 @@
+/* pfBlockerNG update engine */
+
+// Part of pfBlockerNG by BBCan177@gmail.com (c) 2014
+//
+// Javascript and Integration modifications by J. Nieuwenhuizen
+
+
+var pfBlockerNGtimer;
+
+function pfBlockerNG_fetch_new_rules_callback(callback_data) {
+ var data_split;
+ var new_data_to_add = Array();
+ var data = callback_data;
+
+ data_split = data.split("\n");
+
+ // Loop through rows and generate replacement HTML
+ if (data_split.length > 1) {
+ for(var x=0; x<data_split.length-1; x++) {
+ row_split = data_split[x].split("||");
+ if (row_split.length > 3) {
+ var line = '';
+ line = '<td class="listMRr ellipsis">' + row_split[0] + '</td>';
+ line += '<td class="listMRr" align="center">' + row_split[1] + '</td>';
+ line += '<td class="listMRr" align="center">' + row_split[2] + '</td>';
+ line += '<td class="listMRr" align="center">' + row_split[3] + '</td>';
+ line += '<td class="listMRr" align="center">' + row_split[4] + '</td>';
+ new_data_to_add[new_data_to_add.length] = line;
+ }
+ }
+ if (new_data_to_add.length > 0) {
+ pfBlockerNG_update_div_rows(new_data_to_add);
+ }
+ }
+}
+
+
+function pfBlockerNG_update_div_rows(data) {
+ var rows = jQuery('#pfbNG-entries>tr');
+
+ // Number of rows to move by
+ var move = rows.length + data.length;
+ if (move < 0)
+ move = 0;
+
+ for (var i = rows.length - 1; i >= move; i--) {
+ jQuery(rows[i]).html(jQuery(rows[i - move]).html());
+ }
+
+ var tbody = jQuery('#pfbNG-entries');
+ for (var i = data.length - 1; i >= 0; i--) {
+ if (i < rows.length) {
+ jQuery(rows[i]).html(data[i]);
+ } else {
+ jQuery(tbody).prepend('<tr>' + data[i] + '</tr>');
+ }
+ }
+
+ // Add the even/odd class to each of the rows now
+ // they have all been added.
+ rows = jQuery('#pfbNG-entries>tr');
+ for (var i = 0; i < rows.length; i++) {
+ rows[i].className = i % 2 == 0 ? 'listMRodd' : 'listMReven';
+ }
+}
+
+
+function fetch_new_pfBlockerNGcounts() {
+ jQuery.ajax('/widgets/widgets/pfblockerng.widget.php?getNewCounts=' + new Date().getTime(), {
+ type: 'GET',
+ dataType: 'text',
+ success: function(data) {
+ pfBlockerNG_fetch_new_rules_callback(data);
+ }
+ });
+}
+
+/* start local AJAX engine */
+pfBlockerNGtimer = setInterval('fetch_new_pfBlockerNGcounts()', pfBlockerNGupdateDelay); \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.php b/config/pfblockerng/pfblockerng.php
new file mode 100644
index 00000000..1db36334
--- /dev/null
+++ b/config/pfblockerng/pfblockerng.php
@@ -0,0 +1,1475 @@
+<?php
+/*
+ pfBlockerNG.php
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfBlocker by
+ Copyright (C) 2011-2012 Marcello Coutinho
+ All rights reserved.
+
+ Hour Schedule Convertor code by
+ Snort Package
+ Copyright (c) 2014 Bill Meeks
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+require_once("util.inc");
+require_once("functions.inc");
+require_once("pkg-utils.inc");
+require_once("globals.inc");
+require_once("services.inc");
+require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+
+pfb_global();
+
+// IPv6 Range to CIDR function used courtesey from:
+// https://github.com/stilez/pfsense-leases/blob/50cc0fa81dba5fe91bcddaea016c245d1b8479cc/etc/inc/util.inc
+function ip_range_to_subnet_array_temp($ip1, $ip2) {
+
+ if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2)) {
+ $proto = 'ipv4'; // for clarity
+ $bits = 32;
+ $ip1bin = decbin(ip2long32($ip1));
+ $ip2bin = decbin(ip2long32($ip2));
+ } elseif (is_ipaddrv6($ip1) && is_ipaddrv6($ip2)) {
+ $proto = 'ipv6';
+ $bits = 128;
+ $ip1bin = Net_IPv6::_ip2Bin($ip1);
+ $ip2bin = Net_IPv6::_ip2Bin($ip2);
+ } else
+ return array();
+
+ // it's *crucial* that binary strings are guaranteed the expected length; do this for certainty even though for IPv6 it's redundant
+ $ip1bin = str_pad($ip1bin, $bits, '0', STR_PAD_LEFT);
+ $ip2bin = str_pad($ip2bin, $bits, '0', STR_PAD_LEFT);
+
+ if ($ip1bin === $ip2bin)
+ return array($ip1 . '/' . $bits);
+
+ if (strcmp($ip1bin, $ip2bin) > 0)
+ list ($ip1bin, $ip2bin) = array($ip2bin, $ip1bin); // swap contents of ip1 <= ip2
+
+ $rangesubnets = array();
+ $netsize = 0;
+
+ do {
+ // at loop start, $ip1 is guaranteed strictly less than $ip2 (important for edge case trapping and preventing accidental binary wrapround)
+ // which means the assignments $ip1 += 1 and $ip2 -= 1 will always be "binary-wrapround-safe"
+
+ // step #1 if start ip (as shifted) ends in any '1's, then it must have a single cidr to itself (any cidr would include the '0' below it)
+
+ if (substr($ip1bin, -1, 1) == '1') {
+ // the start ip must be in a separate one-IP cidr range
+ $new_subnet_ip = substr($ip1bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize);
+ $rangesubnets[$new_subnet_ip] = $bits - $netsize;
+ $n = strrpos($ip1bin, '0'); //can't be all 1's
+ $ip1bin = ($n == 0 ? '' : substr($ip1bin, 0, $n)) . '1' . str_repeat('0', $bits - $n - 1); // BINARY VERSION OF $ip1 += 1
+ }
+
+ // step #2, if end ip (as shifted) ends in any zeros then that must have a cidr to itself (as cidr cant span the 1->0 gap)
+
+ if (substr($ip2bin, -1, 1) == '0') {
+ // the end ip must be in a separate one-IP cidr range
+ $new_subnet_ip = substr($ip2bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize);
+ $rangesubnets[$new_subnet_ip] = $bits - $netsize;
+ $n = strrpos($ip2bin, '1'); //can't be all 0's
+ $ip2bin = ($n == 0 ? '' : substr($ip2bin, 0, $n)) . '0' . str_repeat('1', $bits - $n - 1); // BINARY VERSION OF $ip2 -= 1
+ // already checked for the edge case where end = start+1 and start ends in 0x1, above, so it's safe
+ }
+
+ // this is the only edge case arising from increment/decrement.
+ // it happens if the range at start of loop is exactly 2 adjacent ips, that spanned the 1->0 gap. (we will have enumerated both by now)
+
+ if (strcmp($ip2bin, $ip1bin) < 0)
+ continue;
+
+ // step #3 the start and end ip MUST now end in '0's and '1's respectively
+ // so we have a non-trivial range AND the last N bits are no longer important for CIDR purposes.
+
+ $shift = $bits - max(strrpos($ip1bin, '0'), strrpos($ip2bin, '1')); // num of low bits which are '0' in ip1 and '1' in ip2
+ $ip1bin = str_repeat('0', $shift) . substr($ip1bin, 0, $bits - $shift);
+ $ip2bin = str_repeat('0', $shift) . substr($ip2bin, 0, $bits - $shift);
+ $netsize += $shift;
+ if ($ip1bin === $ip2bin) {
+ // we're done.
+ $new_subnet_ip = substr($ip1bin, $netsize, $bits - $netsize) . str_repeat('0', $netsize);
+ $rangesubnets[$new_subnet_ip] = $bits - $netsize;
+ continue;
+ }
+
+ // at this point there's still a remaining range, and either startip ends with '1', or endip ends with '0'. So repeat cycle.
+ } while (strcmp($ip1bin, $ip2bin) < 0);
+
+ // subnets are ordered by bit size. Re sort by IP ("naturally") and convert back to IPv4/IPv6
+
+ ksort($rangesubnets, SORT_STRING);
+ $out = array();
+
+ foreach ($rangesubnets as $ip => $netmask) {
+ if ($proto == 'ipv4') {
+ $i = str_split($ip, 8);
+ $out[] = implode('.', array( bindec($i[0]),bindec($i[1]),bindec($i[2]),bindec($i[3]))) . '/' . $netmask;
+ } else
+ $out[] = Net_IPv6::compress(Net_IPv6::_bin2Ip($ip)) . '/' . $netmask;
+ }
+
+ return $out;
+}
+
+# Set php Memory Limit
+$uname = posix_uname();
+if ($uname['machine'] == "amd64")
+ ini_set('memory_limit', '256M');
+
+function pfb_update_check($header_url, $list_url, $url_format) {
+ global $pfb;
+ $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;
+ }
+
+ switch ($url_format) {
+ case "gz":
+ case "gz_2":
+ case "gz_lg":
+ case "et":
+ $type = '.gz';
+ break;
+ case "zip":
+ case "xlsx":
+ $type = '.zip';
+ break;
+ case "txt":
+ $type = '.orig';
+ break;
+ case "html":
+ case "block":
+ $type = '.raw';
+ break;
+ }
+
+ $log = "[ {$header_url} ]\n";
+ pfb_logger("{$log}","1");
+ $host = @parse_url($list_url);
+ $local_file = "{$pfb['origdir']}/{$header_url}{$type}";
+ if (file_exists($local_file)) {
+ // Determine if URL is Remote or Local
+ if ($host['host'] == "127.0.0.1" || $host['host'] == $pfb['iplocal'] || empty($host['host'])) {
+ $remote_tds = gmdate ("D, d M Y H:i:s T", filemtime($local_file));
+ } else {
+ $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers($list_url)));
+ $remote_tds = preg_replace("/^Last-Modified: /","", $remote_tds);
+ }
+
+ $log = " Remote timestamp: {$remote_tds}\n";
+ pfb_logger("{$log}","1");
+ $local_tds = gmdate ("D, d M Y H:i:s T", filemtime($local_file));
+ $log = " Local timestamp: {$local_tds}\n";
+ pfb_logger("{$log}","1");
+ if ("{$remote_tds}" != "{$local_tds}") {
+ $pfb['cron_update'] = TRUE;
+ } else {
+ $log = " Remote file unchanged. Download Terminated\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.
+ $pfb['update_cron'] = TRUE;
+
+ $log = " Updates Found\n";
+ pfb_logger("{$log}","1");
+ unlink_if_exists($pfbfolder . '/' . $header_url . '.txt');
+ }
+}
+
+
+if ($argv[1] == 'update') {
+ sync_package_pfblockerng("cron");
+}
+
+if ($argv[1] == 'dc') {
+ # (Options - 'bu' Binary Update for Reputation/Alerts Page, 'all' for Country update and 'bu' options.
+ if ($pfb['cc'] == "") {
+ exec("/bin/sh /usr/local/pkg/pfblockerng/geoipupdate.sh all >> {$pfb['geolog']} 2>&1");
+ } else {
+ exec("/bin/sh /usr/local/pkg/pfblockerng/geoipupdate.sh bu >> {$pfb['geolog']} 2>&1");
+ }
+ pfblockerng_uc_countries();
+ pfblockerng_get_countries();
+}
+
+if ($argv[1] == 'uc') {
+ pfblockerng_uc_countries();
+}
+
+if ($argv[1] == 'gc') {
+ pfblockerng_get_countries();
+}
+
+if ($argv[1] == 'cron') {
+ $hour = date('H');
+ $dow = date('N');
+ $pfb['update_cron'] = FALSE;
+
+ # Start hour of the 'Once a day' Schedule
+ $pfb['dailystart'] = $config['installedpackages']['pfblockerng']['config'][0]['pfb_dailystart'];
+ # Start hour of the Scheduler
+ if ($config['installedpackages']['pfblockerng']['config'][0]['pfb_hour'] != "") {
+ $pfb['hour'] = $config['installedpackages']['pfblockerng']['config'][0]['pfb_hour'];
+ } else {
+ $pfb['hour'] = "1";
+ }
+ $updates = 0;
+
+ # 2 Hour Schedule Converter
+ $shour = intval(substr($pfb['hour'], 0, 2));
+ $sch2 = strval($shour);
+ for ($i=0; $i<11; $i++) {
+ $shour += 2;
+ if ($shour > 24)
+ $shour -= 24;
+ $sch2 .= "," . strval($shour);
+ }
+
+ # 3 Hour Schedule Converter
+ $shour = intval(substr($pfb['hour'], 0, 2));
+ $sch3 = strval($shour);
+ for ($i=0; $i<7; $i++) {
+ $shour += 3;
+ if ($shour > 24)
+ $shour -= 24;
+ $sch3 .= "," . strval($shour);
+ }
+
+ # 4 Hour Schedule Converter
+ $shour = intval(substr($pfb['hour'], 0, 2));
+ $sch4 = strval($shour);
+ for ($i=0; $i<5; $i++) {
+ $shour += 4;
+ if ($shour > 24)
+ $shour -= 24;
+ $sch4 .= "," . strval($shour);
+ }
+
+ # 6 Hour Schedule Converter
+ $shour = intval(substr($pfb['hour'], 0, 2));
+ $sch6 = strval($shour);
+ for ($i=0; $i<3; $i++) {
+ $shour += 6;
+ if ($shour > 24)
+ $shour -= 24;
+ $sch6 .= "," . strval($shour);
+ }
+
+ # 8 Hour Schedule Converter
+ $shour = intval(substr($pfb['hour'], 0, 2));
+ $sch8 = strval($shour);
+ for ($i=0; $i<2; $i++) {
+ $shour += 8;
+ if ($shour > 24)
+ $shour -= 24;
+ $sch8 .= "," . strval($shour);
+ }
+
+ # 12 Hour Schedule Converter
+ $shour = intval(substr($pfb['hour'], 0, 2));
+ $sch12 = strval($shour) . ",";
+ $shour += 12;
+ if ($shour > 24)
+ $shour -= 24;
+ $sch12 .= strval($shour);
+
+ $e_sch2 = explode(",", $sch2);
+ $e_sch3 = explode(",", $sch3);
+ $e_sch4 = explode(",", $sch4);
+ $e_sch6 = explode(",", $sch6);
+ $e_sch8 = explode(",", $sch8);
+ $e_sch12 = explode(",", $sch12);
+
+ $log = " CRON PROCESS START [ NOW ]\n";
+ pfb_logger("{$log}","1");
+
+ $list_type = array ("pfblockernglistsv4" => "_v4", "pfblockernglistsv6" => "_v6");
+ foreach ($list_type as $ip_type => $vtype) {
+ if ($config['installedpackages'][$ip_type]['config'] != "") {
+ foreach ($config['installedpackages'][$ip_type]['config'] as $list) {
+ if (is_array($list['row']) && $list['action'] != "Disabled") {
+ foreach ($list['row'] as $row) {
+ if ($row['url'] != "" && $row['state'] != "Disabled") {
+
+ if ($vtype == "_v4") {
+ $header_url = "{$row['header']}";
+ } else {
+ $header_url = "{$row['header']}_v6";
+ }
+
+ # Determine Folder Location for Alias (return array $pfbarr)
+ pfb_determine_list_detail($list['action']);
+ $pfbfolder = $pfbarr['folder'];
+
+ $list_cron = $list['cron'];
+ $list_url = $row['url'];
+ $header_dow = $list['dow'];
+ $url_format = $row['format'];
+
+ // Bypass update if state is defined as "Hold" and list file exists
+ if (file_exists($pfbfolder . '/' . $header_url . '.txt') && $row['state'] == "Hold") {
+ continue;
+ }
+
+ # Check if List file exists, if not found run Update
+ if (!file_exists($pfbfolder . '/' . $header_url . '.txt')) {
+ $log = " Updates Found\n";
+ pfb_logger("{$log}","1");
+ $pfb['update_cron'] = TRUE;
+ continue;
+ }
+
+ switch ($list_cron) {
+ case "01hour":
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "02hours":
+ if (in_array($hour, $e_sch2))
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "03hours":
+ if (in_array($hour, $e_sch3))
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "04hours":
+ if (in_array($hour, $e_sch4))
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "06hours":
+ if (in_array($hour, $e_sch6))
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "08hours":
+ if (in_array($hour, $e_sch8))
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "12hours":
+ if (in_array($hour, $e_sch12))
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "EveryDay":
+ if ($hour == $pfb['dailystart'])
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ case "Weekly":
+ if ($hour == $pfb['dailystart'] && $dow == $header_dow)
+ pfb_update_check($header_url, $list_url, $url_format, $pfbfolder);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ($pfb['update_cron']) {
+ sync_package_pfblockerng("cron");
+ } else {
+ $log = "\n No Updates required. \n\n";
+ pfb_logger("{$log}","1");
+ }
+
+ $log = " CRON PROCESS ENDED [ NOW ]\n";
+ pfb_logger("{$log}","1");
+
+ # Call Log Mgmt Function
+ // If Update GUI 'Manual view' is selected. Last output will be missed. So sleep for 5 secs.
+ sleep(5);
+ pfb_log_mgmt();
+}
+
+
+// Function to process the downloaded Maxmind Database and format into Continent txt files.
+function pfblockerng_uc_countries() {
+ global $g,$pfb;
+ pfb_global();
+
+ $maxmind_cont = "{$pfb['dbdir']}/country_continent.csv";
+ $maxmind_cc4 = "{$pfb['dbdir']}/GeoIPCountryWhois.csv";
+ $maxmind_cc6 = "{$pfb['dbdir']}/GeoIPv6.csv";
+
+ # Create Folders if not Exist
+ $folder_array = array ("{$pfb['dbdir']}","{$pfb['logdir']}","{$pfb['ccdir']}");
+ foreach ($folder_array as $folder) {
+ safe_mkdir ("{$folder}",0755);
+ }
+
+ $now = date("m/d/y G:i:s", time());
+ $log = "Country Code Update Start - [ NOW ]\n\n";
+ print "Country Code Update Start - [ $now ]\n\n";
+ pfb_logger("{$log}","3");
+
+ if (!file_exists($maxmind_cont) || !file_exists($maxmind_cc4) || !file_exists($maxmind_cc6)) {
+ $log = " [ MAXMIND UPDATE FAIL, CSV Missing, using Previous Country Code Database \n";
+ print $log;
+ pfb_logger("{$log}","3");
+ return;
+ }
+
+ # Save Date/Time Stamp to MaxMind version file
+ $maxmind_ver = "MaxMind GeoLite Date/Time Stamps \n\n";
+ $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers("http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip")));
+ $maxmind_ver .= "MaxMind_v4 \t" . $remote_tds . "\n";
+ $local_tds = @gmdate ("D, d M Y H:i:s T", filemtime($maxmind_cc4));
+ $maxmind_ver .= "Local_v4 \tLast-Modified: " . $local_tds . "\n\n";
+ $remote_tds = @implode(preg_grep("/Last-Modified/", get_headers("http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz")));
+ $maxmind_ver .= "MaxMind_v6 \t" . $remote_tds . "\n";
+ $local_tds = @gmdate ("D, d M Y H:i:s T", filemtime($maxmind_cc6));
+ $maxmind_ver .= "Local_v6 \tLast-Modified: " . $local_tds . "\n";
+ $maxmind_ver .= "\nThese Timestamps should *match* \n";
+ @file_put_contents("{$pfb['logdir']}/maxmind_ver", $maxmind_ver);
+
+ // Collect ISO Codes for Each Continent
+ $log = "Processing Continent Data\n";
+ print $log;
+ pfb_logger("{$log}","3");
+
+ $cont_array = array ( array($AF),array($AS),array($EU),array($NA),array($OC),array($SA),array($AX));
+ if (($handle = fopen("{$maxmind_cont}",'r')) !== FALSE) {
+ while (($cc = fgetcsv($handle)) !== FALSE) {
+
+ $cc_key = $cc[0];
+ $cont_key = $cc[1];
+ switch ($cont_key) {
+ case "AF":
+ $cont_array[0]['continent'] = "Africa";
+ $cont_array[0]['iso'] .= "{$cc_key},";
+ $cont_array[0]['file4'] = "{$pfb['ccdir']}/Africa_v4.txt";
+ $cont_array[0]['file6'] = "{$pfb['ccdir']}/Africa_v6.txt";
+ break;
+ case "AS":
+ $cont_array[1]['continent'] = "Asia";
+ $cont_array[1]['iso'] .= "{$cc_key},";
+ $cont_array[1]['file4'] = "{$pfb['ccdir']}/Asia_v4.txt";
+ $cont_array[1]['file6'] = "{$pfb['ccdir']}/Asia_v6.txt";
+ break;
+ case "EU":
+ $cont_array[2]['continent'] = "Europe";
+ $cont_array[2]['iso'] .= "{$cc_key},";
+ $cont_array[2]['file4'] = "{$pfb['ccdir']}/Europe_v4.txt";
+ $cont_array[2]['file6'] = "{$pfb['ccdir']}/Europe_v6.txt";
+ break;
+ case "NA":
+ $cont_array[3]['continent'] = "North America";
+ $cont_array[3]['iso'] .= "{$cc_key},";
+ $cont_array[3]['file4'] = "{$pfb['ccdir']}/North_America_v4.txt";
+ $cont_array[3]['file6'] = "{$pfb['ccdir']}/North_America_v6.txt";
+ break;
+ case "OC":
+ $cont_array[4]['continent'] = "Oceania";
+ $cont_array[4]['iso'] .= "{$cc_key},";
+ $cont_array[4]['file4'] = "{$pfb['ccdir']}/Oceania_v4.txt";
+ $cont_array[4]['file6'] = "{$pfb['ccdir']}/Oceania_v6.txt";
+ break;
+ case "SA":
+ $cont_array[5]['continent'] = "South America";
+ $cont_array[5]['iso'] .= "{$cc_key},";
+ $cont_array[5]['file4'] = "{$pfb['ccdir']}/South_America_v4.txt";
+ $cont_array[5]['file6'] = "{$pfb['ccdir']}/South_America_v6.txt";
+ break;
+ }
+ }
+ }
+ unset($cc);
+ fclose($handle);
+
+ // 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]['file4'] = "{$pfb['ccdir']}/Proxy_Satellite_v4.txt";
+ $cont_array[6]['file6'] = "{$pfb['ccdir']}/Proxy_Satellite_v6.txt";
+
+ // 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");
+
+ if ($type == "4") {
+ $maxmind_cc = "{$pfb['dbdir']}/GeoIPCountryWhois.csv";
+ } else {
+ $maxmind_cc = "{$pfb['dbdir']}/GeoIPv6.csv";
+ }
+ $iptype = "ip{$type}";
+ $filetype = "file{$type}";
+
+ 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;
+ 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];
+ $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] = "";
+ }
+ }
+ $counter++;
+ @file_put_contents($pfb_file, $header, LOCK_EX);
+ }
+ }
+}
+
+
+// Function to process Continent txt files and create Country ISO files and to Generate GUI XML files.
+function pfblockerng_get_countries() {
+ global $g,$pfb;
+ pfb_global();
+
+ $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");
+
+ 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");
+
+ if ($type == "6")
+ $file = preg_replace("/v4/", "v6", $file);
+ $convert = explode("\n", file_get_contents($file));
+ $cont_name = preg_replace("/ /", "", $cont);
+ $cont_name_lower = strtolower($cont_name);
+ $active = array("$cont" => '<active/>');
+ $lastkey = count ($convert) - 1;
+ $pfb['complete'] = FALSE;
+ $keycount = 1;
+ $total = 0;
+
+ foreach ($convert as $line) {
+ if (preg_match("/#/",$line)) {
+ if ($pfb['complete']) {
+ ${'coptions' . $type}[] = $country . '-' . $isocode . ' ('. $total .') ' . ' </name><value>' . $isocode . '</value></option>';
+ ${'roptions' . $type}[] = $country . '-' . $isocode . ' ('. $total .') ' . ' </name><value>' . $isocode . '</value></option>';
+
+ // Save ISO data
+ @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];}
+ }
+ elseif (!preg_match("/#/",$line)) {
+ $total++;
+ 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>';
+ ${'roptions' . $type}[] = $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++;
+ }
+ unset ($ips, $convert);
+
+ // Sort IP Countries alphabetically and build XML <option> data for Continents tab
+ if (!empty (${'coptions' . $type})) {
+ sort(${'coptions' . $type}, SORT_STRING);
+ ${'ftotal' . $type} = count(${'coptions' . $type});
+ $count = 1;
+ ${'options' . $type} = "";
+
+ foreach (${'coptions' . $type} as $option) {
+ 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;
+ } else {
+ ${'options' . $type} .= "\t\t\t\t" . '<option><name>' . $option . "\n";
+ }
+ $count++;
+ }
+ }
+ 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"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* \$Id\$ */
+/* ========================================================================== */
+/*
+ pfblockerng_{$cont_name}.xml
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfblocker for pfSense
+ Copyright (C) 2011 Marcello Coutinho
+ All rights reserved.
+*/
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS`` AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+/* ========================================================================== */
+]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>pfblockerng{$cont_name_lower}</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: {$cont}</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <menu>
+ <name>pfBlockerNG: {$cont_name}</name>
+ <tooltiptext>Configure pfBlockerNG</tooltiptext>
+ <section>Firewall</section>
+ <url>pkg_edit.php?xml=pfblockerng_{$cont_name_lower}.xml&amp;id=0</url>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Update</text>
+ <url>/pfblockerng/pfblockerng_update.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pfblockerng/pfblockerng_alerts.php</url>
+ </tab>
+ <tab>
+ <text>Reputation</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>IPv4</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</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>
+ </tab>
+ <tab>
+ <text>Africa</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&amp;id=0</url>
+ {$active['Africa']}
+ </tab>
+ <tab>
+ <text>Asia</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&amp;id=0</url>
+ {$active['Asia']}
+ </tab>
+ <tab>
+ <text>Europe</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&amp;id=0</url>
+ {$active['Europe']}
+ </tab>
+ <tab>
+ <text>N.A.</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&amp;id=0</url>
+ {$active['North America']}
+ </tab>
+ <tab>
+ <text>Oceania</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&amp;id=0</url>
+ {$active['Oceania']}
+ </tab>
+ <tab>
+ <text>S.A.</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&amp;id=0</url>
+ {$active['South America']}
+ </tab>
+ <tab>
+ <text>P.S.</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&amp;id=0</url>
+ {$active['Proxy and Satellite']}
+ </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&amp;id=0</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <name><![CDATA[Continent {$cont}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Geolite Data by MaxMind Inc. - ISO 3166)]]></name>
+ <type>listtopic</type>
+ </field>
+ <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>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<br /><strong>IPv4</strong><br />Countries]]></fielddescr>
+ <fieldname>countries4</fieldname>
+ <description>
+ <![CDATA[Select IPv4 Countries you want to take an action on.<br />
+ <strong>Use CTRL + CLICK to unselect countries</strong>]]>
+ </description>
+ <type>select</type>
+ <options>
+ ${'options4'}
+ </options>
+ <size>${'ftotal4'}</size>
+ <multiple/>
+ </field>
+
+EOF;
+
+// Skip IPv6 when Null data found
+if (!empty (${'options6'})) {
+ $xml .= <<<EOF
+ <field>
+ <fielddescr><![CDATA[<br /><strong>IPv6</strong><br />Countries]]></fielddescr>
+ <fieldname>countries6</fieldname>
+ <description>
+ <![CDATA[Select IPv6 Countries you want to take an action on.<br />
+ <strong>Use CTRL + CLICK to unselect countries</strong>]]>
+ </description>
+ <type>select</type>
+ <options>
+ ${'options6'}
+ </options>
+ <size>${'ftotal6'}</size>
+ <multiple/>
+ </field>
+
+EOF;
+}
+
+$xml .= <<<EOF
+ <field>
+ <fielddescr>List Action</fielddescr>
+ <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br />
+ Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br />
+ <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br />
+
+ <strong><u>'Deny' Rules:</u></strong><br />
+ 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other
+ interfaces. Typical uses of 'Deny' rules are:<br />
+ <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li>
+ <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by
+ traffic sent in the other direction. Does not affect traffic in the other direction. </li>
+ <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while
+ still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul>
+ <strong><u>'Permit' Rules:</u></strong><br />
+ 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create
+ any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br />
+ <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They
+ override <u>almost all other</u> Firewall rules on the stated interfaces.</li>
+ <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a
+ few IPs that should be accessible.</li></ul>
+ <strong><u>'Match' Rules:</u></strong><br />
+ 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic.
+ <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li>
+ <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul>
+ <strong><u>'Alias' Rules:</u></strong><br />
+ <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else).
+ This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired.
+ <ul><li><strong>Options &nbsp;&nbsp; - 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)&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 />]]>
+ </description>
+ <fieldname>action</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>Disabled</name><value>Disabled</value></option>
+ <option><name>Deny Inbound</name><value>Deny_Inbound</value></option>
+ <option><name>Deny Outbound</name><value>Deny_Outbound</value></option>
+ <option><name>Deny Both</name><value>Deny_Both</value></option>
+ <option><name>Permit Inbound</name><value>Permit_Inbound</value></option>
+ <option><name>Permit Outbound</name><value>Permit_Outbound</value></option>
+ <option><name>Permit Both</name><value>Permit_Both</value></option>
+ <option><name>Match Inbound</name><value>Match_Inbound</value></option>
+ <option><name>Match Outbound</name><value>Match_Outbound</value></option>
+ <option><name>Match Both</name><value>Match_Both</value></option>
+ <option><name>Alias Deny</name><value>Alias_Deny</value></option>
+ <option><name>Alias Permit</name><value>Alias_Permit</value></option>
+ <option><name>Alias Match</name><value>Alias_Match</value></option>
+ <option><name>Alias Native</name><value>Alias_Native</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Enable Logging</fielddescr>
+ <fieldname>aliaslog</fieldname>
+ <description><![CDATA[Default:<strong>Enable</strong><br />
+ Select - Logging to Status: System Logs: FIREWALL ( Log )<br />
+ This can be overriden by the 'Global Logging' Option in the General Tab.]]></description>
+ <type>select</type>
+ <options>
+ <option><name>Enable</name><value>enabled</value></option>
+ <option><name>Disable</name><value>disabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Changes are Applied via CRON or
+ 'Force Update'</ul>]]>
+ </name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_install_command>
+ pfblockerng_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ pfblockerng_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ pfblockerng_validate_input(\$_POST, \$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ global \$pfb;
+ \$pfb['save'] = TRUE;
+ sync_package_pfblockerng();
+ </custom_php_resync_config_command>
+</packagegui>
+EOF;
+
+ // Update Each Continent XML file.
+ @file_put_contents('/usr/local/pkg/pfblockerng/pfblockerng_'.$cont_name.'.xml',$xml,LOCK_EX);
+
+ // Unset Arrays
+ unset (${'options4'}, ${'options6'}, $xml);
+
+ } // 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)
+
+ $type = "4";
+ sort(${'roptions' . $type}, SORT_STRING);
+ $eoa = count(${'roptions' . $type});
+ $count = 1;
+ $etoptions = "";
+
+ foreach (${'roptions' . $type} as $option4) {
+ if ($count == 1) { $et_options .= "\t" . '<option><name>' . $option4 . "\n"; $count++; continue; }
+ if ($eoa == $count) {
+ $et_options .= "\t\t\t\t" . '<option><name>' . $option4;
+ } else {
+ $et_options .= "\t\t\t\t" . '<option><name>' . $option4 . "\n";
+ }
+ $count++;
+ }
+
+// Update pfBlockerNG_Reputation.xml file with Country Code Changes
+
+$xmlrep = <<<EOF
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* \$Id\$ */
+/* ========================================================================== */
+/*
+ pfBlockerNG_Reputation.xml
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfblocker for pfSense
+ Copyright (C) 2011 Marcello Coutinho
+ All rights reserved.
+
+*/
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>pfblockerngreputation</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: IPv4 Reputation</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <menu>
+ <name>pfBlockerNG</name>
+ <tooltiptext>Configure pfblockerNG</tooltiptext>
+ <section>Firewall</section>
+ <url>pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Update</text>
+ <url>/pfblockerng/pfblockerng_update.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pfblockerng/pfblockerng_alerts.php</url>
+ </tab>
+ <tab>
+ <text>Reputation</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>IPv4</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</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>
+ </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>
+ </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&amp;id=0</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <name>IPv4 Reputation Preface</name>
+ <type>listtopic</type>
+ </field>
+ <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>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>Why Reputation Matters:</strong>]]></fielddescr>
+ <fieldname></fieldname>
+ <type>info</type>
+ <description><![CDATA[By Enabling '<strong>Reputation</strong>', each Blocklist will be analyzed for Repeat Offenders in each IP Range.
+ <ul>Example: &nbsp;&nbsp; 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 />
+ This will completely Block/Reject this particular range from your Firewall.<br /><br />
+ Selecting Blocklists from various Threat Sources will help to highlight Repeat Offending IP Ranges,<br />
+ Its Important to select a Broad Range of Blocklists that cover different types of Malicious Activity.<br /><br />
+ You *may* experience some False Positives. Add any False Positive IPs manually to the<br />
+ <strong>pfBlockerNGSuppress Alias</strong> or use the "+" suppression Icon in the Alerts TAB<br /><br />
+ To help mitigate False Positives 'Countries' can be '<strong>Excluded</strong>' from this Process. (Refer to Country Code Settings)
+ <br /><br />Enabling <strong>De-Duplication</strong> is highly recommended before utilizing 'Reputation' processes.]]>
+ </description>
+ </field>
+ <field>
+ <name>Reputation Settings:</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fieldname></fieldname>
+ <fielddescr><![CDATA[<br /><strong>Individual List Reputation</strong><br /><br />]]></fielddescr>
+ <type>info</type>
+ <description></description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[Enable Max]]></fielddescr>
+ <fieldname>enable_rep</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[Enables Search for Repeat Offenders in a /24 Range on <strong>Each Individual Blocklist</strong>]]></description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[&nbsp;&nbsp;&nbsp;[ <strong>Max</strong> ] Setting]]></fielddescr>
+ <fieldname>p24_max_var</fieldname>
+ <description><![CDATA[Default: <strong>5</strong><br />
+ Maximum number of Repeat Offenders allowed in a Single IP Range]]></description>
+ <type>select</type>
+ <options>
+ <option><name>5</name><value>5</value></option>
+ <option><name>10</name><value>10</value></option>
+ <option><name>15</name><value>15</value></option>
+ <option><name>20</name><value>20</value></option>
+ <option><name>25</name><value>25</value></option>
+ <option><name>50</name><value>50</value></option>
+ </options>
+ </field>
+ <field>
+ <fieldname></fieldname>
+ <fielddescr><![CDATA[<br /><strong>Collective List Reputation</strong><br /><br />]]></fielddescr>
+ <type>info</type>
+ <description></description>
+ </field>
+ <field>
+ <fieldname></fieldname>
+ <type>info</type>
+ <description><![CDATA[Once all Blocklists are Downloaded, these two 'additional' processes <strong>[ pMax ] and [ dMax ]</strong><br />
+ Can be used to Further analyze for Repeat Offenders.<br />
+ <ul>Analyzing All Blocklists as a Whole:</ul>
+ <ul><strong>[ pMax ]</strong> will analyze for Repeat Offenders in each IP Range but will not use the Country Exclusion.<br />
+ Default is 50 IPs in any Range. Having 50 Repeat Offenders IPs in any Range will Block the entire Range.<br /><br /></ul>
+ <ul><strong>[ dMax ]</strong> will analyze for Repeat Offenders in each IP Range. Country Exclusions will be applied.<br />
+ Default is 5 IPs in any Range.</ul>
+ Note: <strong>MAX</strong> performs on individual Blocklists, while <strong>pMAX / dMAX</strong>
+ perform on all Lists together.<br />]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr>Enable pMAX</fielddescr>
+ <fieldname>enable_pdup</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[Enables Search for Repeat Offenders in All BlockLists, <strong>Without</strong> Country Code Exclusion]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[&nbsp;&nbsp;&nbsp;[ <strong>pMax</strong> ] Setting]]></fielddescr>
+ <fieldname>p24_pmax_var</fieldname>
+ <description><![CDATA[Default: <strong>50</strong><br />Maximum number of Repeat Offenders]]></description>
+ <type>select</type>
+ <options>
+ <option><name>50</name><value>50</value></option>
+ <option><name>25</name><value>25</value></option>
+ <option><name>20</name><value>20</value></option>
+ <option><name>15</name><value>15</value></option>
+ <option><name>10</name><value>10</value></option>
+ <option><name>5</name><value>5</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Enable dMAX</fielddescr>
+ <fieldname>enable_dedup</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[Enables Search for Repeat Offenders in All BlockLists <strong>Using</strong> Country Code Exclusion]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[&nbsp;&nbsp;&nbsp;[ <strong>dMax</strong> ] Setting]]></fielddescr>
+ <fieldname>p24_dmax_var</fieldname>
+ <description><![CDATA[Default: <strong>5</strong><br />
+ Maximum number of Repeat Offenders]]></description>
+ <type>select</type>
+ <options>
+ <option><name>5</name><value>5</value></option>
+ <option><name>10</name><value>10</value></option>
+ <option><name>15</name><value>15</value></option>
+ <option><name>20</name><value>20</value></option>
+ <option><name>25</name><value>25</value></option>
+ <option><name>50</name><value>50</value></option>
+ </options>
+ </field>
+ <field>
+ <name>Country Code Settings</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fieldname>INFO</fieldname>
+ <type>info</type>
+ <description><![CDATA[When performing Queries for Repeat Offenders, you can choose to <strong>ignore</strong> Repeat Offenders in select
+ Countries. The Original Blocklisted IPs remain intact. All other Repeat Offending Country Ranges will be processed.<br /><br />
+ Define Repeat Offending Ranges [ <strong>Action</strong> ] Available settings are:<br />
+ <ul><strong>Ignore</strong>: Repeat Offenders that are in the 'ccwhite' category will be 'Ignored' (Default)</ul>
+ <ul><strong>Block:</strong> Repeat Offenders are set to Block the entire Repeat Offending Range(s)</ul>
+ <ul><strong>Match:</strong> Repeat Offenders are added to a 'Match' List which can be used in a Floating Match Rule<br />
+ Selecting 'Match' will consume more processing time, so only select this option if you enable Rules for it.</ul>
+ '<strong>ccwhite</strong>' are Countries that are Selected to be excluded from the Repeat Offenders Search.<br />
+ '<strong>ccblack</strong>' are all other Countries that are not selected.<br /><br />
+ To use '<strong>Match</strong>' Lists, Create a new 'Alias'
+ and select one of the <strong>Action 'Match'</strong> Formats and<br /> enter the 'Localfile' as:
+ <ul>/var/db/pfblockerng/match/matchdedup.txt</ul>]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr>ccwhite Action:</fielddescr>
+ <fieldname>ccwhite</fieldname>
+ <description><![CDATA[Default: <strong>Ignore</strong><br />
+ Select the 'Action' format for ccwhite]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Ignore</name><value>ignore</value></option>
+ <option><name>Match</name><value>match</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>ccblack Action:</fielddescr>
+ <fieldname>ccblack</fieldname>
+ <description><![CDATA[Default: <strong>Block</strong><br />
+ Select the 'Action' format for ccblack]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Block</name><value>block</value></option>
+ <option><name>Match</name><value>match</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<br /><strong>IPv4</strong><br />Country Exclusion<br />
+ <br />Geolite Data by:<br />MaxMind Inc.&nbsp;&nbsp;(ISO 3166)]]></fielddescr>
+ <fieldname>ccexclude</fieldname>
+ <description>
+ <![CDATA[Select Countries you want to <strong>Exclude</strong> from the Reputation Process.<br />
+ <strong>Use CTRL + CLICK to unselect countries</strong>]]>
+ </description>
+ <type>select</type>
+ <options>
+ {$et_options}
+ </options>
+ <size>20</size>
+ <multiple/>
+ </field>
+ <field>
+ <name>Emerging Threats IQRISK IPv4 Reputation</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Subscription Pro. Blocklist</fielddescr>
+ <fieldname>ETINFO</fieldname>
+ <type>info</type>
+ <description><![CDATA[<strong>Emerging Threats IQRisk</strong> is a Subscription Professional Reputation List.<br /><br />
+ ET IQRisk Blocklist must be entered in the Lists Tab using the following example:
+ <ul>https://rules.emergingthreatspro.com/XXXXXXXXXXXXXXXX/reputation/iprepdata.txt.gz</ul>
+ Select the <strong>ET IQRisk'</strong> format. The URL should use the .gz File Type.<br />
+ Enter your "ETPRO" code in URL. Further information can be found @
+ <a target=_new href='http://emergingthreats.net/solutions/iqrisk-suite/'>ET IQRisk IP Reputation</a><br /><br />
+ To use <strong>'Match'</strong> Lists, Create a new 'Alias' and select one of the <strong>
+ Action 'Match'</strong> Formats and <br />
+ enter the 'Localfile' as: <ul>/var/db/pfblockerng/match/ETMatch.txt</ul>
+ ET IQRisk Individual Match Lists can be found in the following folder:<br />
+ <ul>/var/db/pfblockerng/ET</ul> ]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr>ET IQRisk Header Name</fielddescr>
+ <fieldname>et_header</fieldname>
+ <type>input</type>
+ <description><![CDATA[Enter the 'Header Name' referenced in the IPv4 List TAB for ET IQRisk IPRep.<br />
+ This will be used to improve the Alerts TAB reporting for ET IPRep.]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr>ET IQRISK BLOCK LISTS</fielddescr>
+ <fieldname>etblock</fieldname>
+ <description>
+ <![CDATA[Select Lists you want to BLOCK.<br />
+ <strong>Use CTRL + CLICK to unselect Categories</strong>
+ <br /><br />Any Changes will take effect at the Next Scheduled CRON Task]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>ET CNC</name><value>ET_Cnc</value></option>
+ <option><name>ET BOT</name><value>ET_Bot</value></option>
+ <option><name>ET SPAM</name><value>ET_Spam</value></option>
+ <option><name>ET DROP</name><value>ET_Drop</value></option>
+ <option><name>ET Spyware CNC</name><value>ET_Spywarecnc</value></option>
+ <option><name>ET Online Gaming</name><value>ET_Onlinegaming</value></option>
+ <option><name>ET DrivebySRC</name><value>ET_Drivebysrc</value></option>
+ <option><name>ET Chat Server</name><value>ET_Chatserver</value></option>
+ <option><name>ET TOR Node</name><value>ET_Tornode</value></option>
+ <option><name>ET Compromised</name><value>ET_Compromised</value></option>
+ <option><name>ET P2P</name><value>ET_P2P</value></option>
+ <option><name>ET Proxy</name><value>ET_Proxy</value></option>
+ <option><name>ET IP Check</name><value>ET_Ipcheck</value></option>
+ <option><name>ET Utility</name><value>ET_Utility</value></option>
+ <option><name>ET DOS</name><value>ET_DDos</value></option>
+ <option><name>ET Scanner</name><value>ET_Scanner</value></option>
+ <option><name>ET Brute</name><value>ET_Brute</value></option>
+ <option><name>ET Fake AV</name><value>ET_Fakeav</value></option>
+ <option><name>ET DYN DNS</name><value>ET_Dyndns</value></option>
+ <option><name>ET Undersireable</name><value>ET_Undesireable</value></option>
+ <option><name>ET Abuse TLD</name><value>ET_Abusedtld</value></option>
+ <option><name>ET SelfSigned SSL</name><value>ET_Selfsignedssl</value></option>
+ <option><name>ET Blackhole</name><value>ET_Blackhole</value></option>
+ <option><name>ET RAS</name><value>ET_RAS</value></option>
+ <option><name>ET P2P CNC</name><value>ET_P2Pcnc</value></option>
+ <option><name>ET Shared Hosting</name><value>ET_Sharedhosting</value></option>
+ <option><name>ET Parking</name><value>ET_Parking</value></option>
+ <option><name>ET VPN</name><value>ET_VPN</value></option>
+ <option><name>ET EXE Source</name><value>ET_Exesource</value></option>
+ <option><name>ET Mobile CNC</name><value>ET_Mobilecnc</value></option>
+ <option><name>ET Mobile Spyware</name><value>ET_Mobilespyware</value></option>
+ <option><name>ET Skype Node</name><value>ET_Skypenode</value></option>
+ <option><name>ET Bitcoin</name><value>ET_Bitcoin</value></option>
+ <option><name>ET DOS Attack</name><value>ET_DDosattack</value></option>
+ <option><name>Unknown</name><value>ET_Unknown</value></option>
+ </options>
+ <size>35</size>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr>ET IQRISK Match LISTS</fielddescr>
+ <fieldname>etmatch</fieldname>
+ <description>
+ <![CDATA[Select Lists you want to MATCH.<br />
+ <strong>Use CTRL + CLICK to unselect Categories</strong>
+ <br /><br />Any Changes will take effect at the Next Scheduled CRON Task]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>ET CNC</name><value>ET_Cnc</value></option>
+ <option><name>ET BOT</name><value>ET_Bot</value></option>
+ <option><name>ET SPAM</name><value>ET_Spam</value></option>
+ <option><name>ET DROP</name><value>ET_Drop</value></option>
+ <option><name>ET Spyware CNC</name><value>ET_Spywarecnc</value></option>
+ <option><name>ET Online Gaming</name><value>ET_Onlinegaming</value></option>
+ <option><name>ET DrivebySRC</name><value>ET_Drivebysrc</value></option>
+ <option><name>ET Chat Server</name><value>ET_Chatserver</value></option>
+ <option><name>ET TOR Node</name><value>ET_Tornode</value></option>
+ <option><name>ET Compromised</name><value>ET_Compromised</value></option>
+ <option><name>ET P2P</name><value>ET_P2P</value></option>
+ <option><name>ET Proxy</name><value>ET_Proxy</value></option>
+ <option><name>ET IP Check</name><value>ET_Ipcheck</value></option>
+ <option><name>ET Utility</name><value>ET_Utility</value></option>
+ <option><name>ET DOS</name><value>ET_DDos</value></option>
+ <option><name>ET Scanner</name><value>ET_Scanner</value></option>
+ <option><name>ET Brute</name><value>ET_Brute</value></option>
+ <option><name>ET Fake AV</name><value>ET_Fakeav</value></option>
+ <option><name>ET DYN DNS</name><value>ET_Dyndns</value></option>
+ <option><name>ET Undersireable</name><value>ET_Undesireable</value></option>
+ <option><name>ET Abuse TLD</name><value>ET_Abusedtld</value></option>
+ <option><name>ET SelfSigned SSL</name><value>ET_Selfsignedssl</value></option>
+ <option><name>ET Blackhole</name><value>ET_Blackhole</value></option>
+ <option><name>ET RAS</name><value>ET_RAS</value></option>
+ <option><name>ET P2P CNC</name><value>ET_P2Pcnc</value></option>
+ <option><name>ET Shared Hosting</name><value>ET_Sharedhosting</value></option>
+ <option><name>ET Parking</name><value>ET_Parking</value></option>
+ <option><name>ET VPN</name><value>ET_VPN</value></option>
+ <option><name>ET EXE Source</name><value>ET_Exesource</value></option>
+ <option><name>ET Mobile CNC</name><value>ET_Mobilecnc</value></option>
+ <option><name>ET Mobile Spyware</name><value>ET_Mobilespyware</value></option>
+ <option><name>ET Skype Node</name><value>ET_Skypenode</value></option>
+ <option><name>ET Bitcoin</name><value>ET_Bitcoin</value></option>
+ <option><name>ET DOS Attack</name><value>ET_DDosattack</value></option>
+ <option><name>Unknown</name><value>ET_Unknown</value></option>
+ </options>
+ <size>35</size>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr>Update ET Categories</fielddescr>
+ <fieldname>et_update</fieldname>
+ <description><![CDATA[Default:<strong>Disable</strong><br />
+ Select - Enable ET Update if Category Changes are Made.<br />
+ You can perform a 'Force Update' to enable these changes.<br />
+ Cron will also resync this list at the next Scheduled Update.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Disable</name><value>disabled</value></option>
+ <option><name>Enable</name><value>enabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ 'Force Update'</ul>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_install_command>
+ pfblockerng_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ pfblockerng_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ pfblockerng_validate_input(\$_POST, \$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ global \$pfb;
+ \$pfb['save'] = TRUE;
+ sync_package_pfblockerng();
+ </custom_php_resync_config_command>
+</packagegui>
+EOF;
+ $log = "Saving pfBlockerNG Reputation TAB \n";
+ print $log;
+ pfb_logger("{$log}","3");
+
+ // Save pfBlockerng_reputation.xml file
+ @file_put_contents('/usr/local/pkg/pfblockerng/pfblockerng_reputation.xml', $xmlrep, LOCK_EX);
+
+ $log = "\n Country Code - XML File Update completed.\n";
+ print $log;
+ pfb_logger("{$log}","3");
+ $now = date("m/d/y G.i:s", time());
+ $log = "Country Code Update Ended - [ NOW ]\n";
+ print "Country Code Update Ended - [ $now ]\n";
+ pfb_logger("{$log}","3");
+
+ // Unset Arrays
+ unset ($et_options, $xmlrep);
+}
+?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.priv.inc b/config/pfblockerng/pfblockerng.priv.inc
new file mode 100644
index 00000000..970ab25f
--- /dev/null
+++ b/config/pfblockerng/pfblockerng.priv.inc
@@ -0,0 +1,30 @@
+<?php
+
+global $priv_list;
+
+$priv_list['page-firewall-pfblockerng'] = array();
+$priv_list['page-firewall-pfblockerng']['name'] = "WebCfg - Firewall: pfBlockerNG";
+$priv_list['page-firewall-pfblockerng']['descr'] = "Allow access to pfBlockerNG package gui";
+$priv_list['page-firewall-pfblockerng']['match'] = array();
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_reputation.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_v4lists.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_v6lists.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_top20.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Africa.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Asia.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Europe.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_NorthAmerica.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_Oceania.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_SouthAmerica.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_ProxyandSatellite.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pkg_edit.php?xml=pfblockerng/pfblockerng_sync.xml*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_update.php*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_alerts.php*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_log.php*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng_diag_dns.php*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "widgets/javascript/pfblockerng.js*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "widgets/include/widget-pfblockerng.inc*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "widgets/widgets/pfblockerng.widget.php*";
+$priv_list['page-firewall-pfblockerng']['match'][] = "pfblockerng/pfblockerng.inc*";
+?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.sh b/config/pfblockerng/pfblockerng.sh
new file mode 100644
index 00000000..cc11be6b
--- /dev/null
+++ b/config/pfblockerng/pfblockerng.sh
@@ -0,0 +1,927 @@
+#!/bin/sh
+# pfBlockerNG IP Reputation Script - By BBcan177@gmail.com - 04-12-14
+# Copyright (C) 2014 BBcan177@gmail.com
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License Version 2 as
+# published by the Free Software Foundation. You may not use, modify or
+# distribute this program under any other version of the GNU General
+# Public License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+now=$(/bin/date +%m/%d/%y' '%T)
+mtype=$(/usr/bin/uname -m);
+
+# Application Paths
+pathgrepcidr="/usr/pbi/pfblockerng-$mtype/bin/grepcidr"
+pathgeoip="/usr/pbi/pfblockerng-$mtype/bin/geoiplookup"
+
+pathtar=/usr/bin/tar
+pathgunzip=/usr/bin/gunzip
+pathpfctl=/sbin/pfctl
+
+# Script Arguments
+alias=$2
+max=$3
+dedup=$4
+cc=$(echo $5 | sed 's/,/, /g')
+ccwhite=$(echo $6 | tr '[A-Z]' '[a-z]')
+ccblack=$(echo $7 | tr '[A-Z]' '[a-z]')
+etblock=$(echo $8 | sed 's/,/, /g')
+etmatch=$(echo $9 | sed 's/,/, /g')
+
+# File Locations
+pathgeoipdat=/usr/pbi/pfblockerng-$mtype/share/GeoIP/GeoIP.dat
+pfbsuppression=/var/db/pfblockerng/pfbsuppression.txt
+masterfile=/var/db/pfblockerng/masterfile
+mastercat=/var/db/pfblockerng/mastercat
+geoiplog=/var/log/pfblockerng/geoip.log
+errorlog=/var/log/pfblockerng/error.log
+
+# Folder Locations
+etdir=/var/db/pfblockerng/ET
+tmpxlsx=/tmp/xlsx/
+
+pfbdeny=/var/db/pfblockerng/deny/
+pfborig=/var/db/pfblockerng/original/
+pfbmatch=/var/db/pfblockerng/match/
+pfbpermit=/var/db/pfblockerng/permit/
+pfbnative=/var/db/pfblockerng/native/
+pfsense_alias_dir=/var/db/aliastables/
+
+# Store "Match" d-dedups in matchdedup.txt file
+matchdedup=matchdedup.txt
+
+tempfile=/tmp/pfbtempfile
+tempfile2=/tmp/pfbtempfile2
+dupfile=/tmp//pfbduptemp
+dedupfile=/tmp/pfbdeduptemp
+addfile=/tmp/pfBaddfile
+syncfile=/tmp/pfbsyncfile
+matchfile=/tmp/pfbmatchfile
+tempmatchfile=/tmp/pfbtempmatchfile
+
+if [ ! -f $masterfile ]; then touch $masterfile; fi
+if [ ! -f $mastercat ]; then touch $mastercat; fi
+if [ ! -f $tempfile ]; then touch $tempfile; fi
+if [ ! -f $tempfile2 ]; then touch $tempfile2; fi
+if [ ! -f $dupfile ]; then touch $dupfile; fi
+if [ ! -f $dedupfile ]; then touch $dedupfile; fi
+if [ ! -f $addfile ]; then touch $addfile; fi
+if [ ! -f $syncfile ]; then touch $syncfile; fi
+if [ ! -f $matchfile ]; then touch $matchfile; fi
+if [ ! -f $tempmatchfile ]; then touch $tempmatchfile; fi
+if [ ! -d $pfbmatch ]; then mkdir $pfbmatch; fi
+if [ ! -d $etdir ]; then mkdir $etdir; fi
+if [ ! -d $tmpxlsx ]; then mkdir $tmpxlsx; fi
+
+##########
+# Process to condense an IP range if a "Max" amount of IP addresses are found in a /24 range per Alias Group.
+process24() {
+
+if [ ! -x $pathgeoip ]; then
+ echo "Process24 - Application [ GeoIP ] Not found. Can't proceed."
+ echo "Process24 - Application [ GeoIP ] Not found. Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+# Download MaxMind GeoIP.dat Binary on first Install.
+if [ ! -f $pathgeoipdat ]; then
+ echo "Downloading [ MaxMind GeoIP.dat ] [ $now ]" >> $geoiplog
+ /usr/local/pkg/pfblockerng/geoipupdate.sh bu
+fi
+# Exit if GeoIP.dat is not found.
+if [ ! -f $pathgeoipdat ]; then
+ echo "Process24 - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed."
+ echo "Process24 - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+count=$(grep -c ^ $pfbdeny$alias".txt")
+echo; echo "Original File Count [ $count ]"
+
+grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile
+> $dupfile; > $tempfile2; > $matchfile; > $tempmatchfile
+data="$(cut -d '.' -f 1-3 $tempfile | awk -v max="$max" '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}')"
+count=$(echo "$data" | grep -c ^); mcount=0; dcount=0; safe=0
+if [ "$data" == "" ]; then count=0; fi
+matchoutfile="match"$header".txt"
+# Classify Repeat Offenders by Country Code
+if [ -f $pathgeoipdat ]; then
+ for ip in $data; do
+ ccheck=$($pathgeoip -f $pathgeoipdat "$ip.1" | cut -c 24-25)
+ case "$cc" in
+ *$ccheck*)
+ safe=$(($safe + 1))
+ if [ "$ccwhite" == "match" -o "$ccblack" == "match" ]; then
+ echo "$ip." >> $matchfile
+ fi
+ ;;
+ *)
+ echo "$ip." >> $dupfile
+ ;;
+ esac
+ done
+else
+ echo; echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping p24 Process"; echo
+ echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping p24 Process [ $now ]" >> $errorlog
+fi
+# Collect Match File Details
+if [ -s "$matchfile" -a ! "$dedup" == "on" -a "$ccwhite" == "match" ]; then
+ mon=$(sed -e 's/^/^/' -e 's/\./\\\./g' $matchfile)
+ for ip in $mon; do
+ grep $ip $tempfile >> $tempfile2
+ done
+ mcount=$(grep -c ^ $tempfile2)
+ if [ "$ccwhite" == "match" ]; then
+ sed 's/$/0\/24/' $matchfile >> $tempmatchfile
+ sed 's/^/\!/' $tempfile2 >> $tempmatchfile
+ fi
+fi
+
+# If no Matches found remove previous Matchoutfile if exists.
+if [ ! -s "$tempmatchfile" -a -f $matchoutfile ]; then rm -r $matchoutfile; fi
+# Move Match File to the Match Folder by Individual Blocklist Name
+if [ -s "$tempmatchfile" ]; then mv -f $tempmatchfile $pfbmatch$matchoutfile; fi
+
+# Find Repeat Offenders in each individual Blocklist Outfile
+if [ -s "$dupfile" ]; then
+ > $tempfile2
+ dup=$(sed -e 's/^/^/' -e 's/\./\\\./g' $dupfile)
+ for ip in $dup; do
+ grep $ip $tempfile >> $tempfile2
+ done
+ dcount=$(grep -c ^ $tempfile2)
+ if [ "$ccblack" == "block" ]; then
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile2 $tempfile > $pfbdeny$alias".txt"
+ sed 's/$/0\/24/' $dupfile >> $pfbdeny$alias".txt"
+ elif [ "$ccblack" == "match" ]; then
+ sed 's/$/0\/24/' $dupfile >> $tempmatchfile
+ sed 's/^/\!/' $tempfile2 >> $tempmatchfile
+ else
+ :
+ fi
+fi
+if [ "$count" == "0" -a "$safe" == "0" ]; then echo; echo " Process /24 Stats [ $alias ] [ $now ] "; echo "------------------------------------------------"; fi
+if [ "$count" == "0" ]; then echo "Found [ 0 ] IP range(s) over the threshold of [ $max ] p24 - CC Blacklist"; fi
+if [ "$safe" == "0" ]; then echo "Found [ 0 ] IP range(s) over the threshold of [ $max ] p24 - CC Whitelist"; fi
+
+if [ -s "$dupfile" -o -s "$matchfile" ]; then
+echo
+echo " Process /24 Stats [ $alias ] [ $now ]"
+echo "--------------------------------------------------------"
+echo "Found [ $count ] IP range(s) over the threshold of [ $max ] on the CC Blacklist"
+echo "Found [ $safe ] IP range(s) over the threshold of [ $max ] on the CC Whitelist"
+echo
+echo "Found [ $dcount ] CC Blacklisted IP Address(es) are being set to [ $ccblack ]"
+# Skip Match Process if dedup=yes as it will create duplicates
+if [ "$dedup" == "on" ]; then mcount=Skipped; fi
+echo "Found [ $mcount ] CC Whitelisted IP Address(es) are being set to [ $ccwhite ]"
+if [ "$ccblack" == "block" ]; then
+ echo; echo "Removed the following IP Ranges"
+ cat $dupfile | tr '\n' '|'; echo
+else
+ echo "Skipped, CCBlack set to [ $ccblack ]"
+fi
+sort $pfbdeny$alias".txt" | uniq > $tempfile; mv -f $tempfile $pfbdeny$alias".txt"
+echo "-------------------------------------------------------"
+cocount=$(grep -cv "^1\.1\.1\.1" $pfbdeny$alias".txt")
+echo "Post /24 Count [ $cocount ]"; echo
+fi
+}
+
+
+##########
+process255() {
+# Remove IPs if exists over 255 IPs in a Range and replace with a single /24 Block
+cp $pfbdeny$alias".txt" $tempfile; > $dedupfile
+
+data255="$(cut -d '.' -f 1-3 $tempfile | awk '{a[$0]++}END{for(i in a){if(a[i] > 255){print i}}}')"
+if [ ! -z "$data255" ]; then
+ for ip in $data255; do
+ ii=$(echo "^$ip" | sed 's/\./\\\./g')
+ grep $ii $tempfile >> $dedupfile
+ done
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $dedupfile $tempfile > $pfbdeny$alias".txt"
+ for ip in $data255; do echo $ip"0/24" >> $pfbdeny$alias".txt"; done
+fi
+}
+
+
+##########
+continent() {
+
+dupcheck=yes
+# Check if Masterfile is Empty
+hcheck=$(grep -c ^ $masterfile); if [ "$hcheck" -eq "0" ]; then dupcheck=no; fi
+# Check if Alias exists in Masterfile
+lcheck=$(grep -m 1 "$alias " $masterfile ); if [ "$lcheck" == "" ]; then dupcheck=no; fi
+
+if [ "$dupcheck" == "yes" ]; then
+ # Grep Alias with a trailing Space character
+ grep "$alias[[:space:]]" $masterfile > $tempfile
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile
+ cut -d' ' -f2 $masterfile > $mastercat
+fi
+
+grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile
+
+if [ ! "$hcheck" -eq "0" ]; then
+ $pathgrepcidr -vf $mastercat $pfbdeny$alias".txt" > $tempfile; mv -f $tempfile $pfbdeny$alias".txt"
+fi
+
+sed -e 's/^/'$alias' /' $pfbdeny$alias".txt" >> $masterfile
+cut -d' ' -f2 $masterfile > $mastercat
+
+countg=$(grep -c ^ $pfborig$alias".orig")
+countm=$(grep -c "$alias " $masterfile); counto=$(grep -c ^ $pfbdeny$alias".txt")
+if [ "$countm" == "$counto" ]; then sanity="Passed"; else sanity=" ==> FAILED <== "; fi
+echo "----------------------------------------------------------"
+echo; echo " Post Duplication count [ $now ]"
+echo "----------------------------------------------------------"
+printf "%-10s %-10s %-10s %-30s\n" "Original" "Masterfile" "Outfile" "Sanity Check"
+echo "----------------------------------------------------------"
+printf "%-10s %-10s %-10s %-30s\n" "$countg" "$countm" "$counto" " [ $sanity ]"
+echo "----------------------------------------------------------"
+}
+
+
+##########
+# Process to remove Suppressed Entries and RFC 1918 and Misc IPs on each downloaded Blocklist
+suppress() {
+
+if [ ! -x $pathgrepcidr ]; then
+ echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]"
+ echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" >> errorlog
+ exit
+fi
+
+if [ -e "$pfbsuppression" ] && [ -s "$pfbsuppression" ]; then
+ # Find '/24' Blocked IPs that are single addresses in the Suppressed IP Address List.
+ # These '/24' Are converted to single Addresses excluding the Suppressed IPs.
+ data="$(cat $pfbsuppression)"
+ if [ ! -z "$data" -a ! -z "$cc" ]; then
+ # Loop thru each Updated List to remove Suppression and RFC1918 Addresses
+ if [ "$cc" == "suppressheader" ]; then
+ echo; echo "===[ Suppression Stats ]========================================"; echo
+ printf "%-20s %-10s %-10s %-10s %-10s\n" "List" "Pre" "RFC1918" "Suppress" "Masterfile"
+ echo "----------------------------------------------------------------"
+ exit
+ fi
+
+ for i in $cc; do
+ counter=0
+ > $dupfile
+ alias=$(echo "${i%|*}")
+ pfbfolder=$(echo "${i#*|}")
+
+ if [ ! "$alias" == "" ]; then
+ # Count (PRE)
+ countg=$(grep -c ^ $pfbfolder$alias".txt")
+
+ grep -Ev "^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|#|$)" $pfbfolder$alias".txt" |
+ sort | uniq > $tempfile
+ # Count (Post RFC1918)
+ countm=$(grep -c ^ $tempfile)
+
+ for ip in $data; do
+ found=""; ddcheck="";
+ iptrim=$(echo $ip | cut -d '.' -f 1-3)
+ mask=$(echo $ip | cut -d"/" -f2)
+ found=$(grep -m1 $iptrim".0/24" $tempfile)
+ # If a Suppression is '/32' and a Blocklist has a full '/24' Block execute the following.
+ if [ ! "$found" == "" -a "$mask" == "32" ]; then
+ echo " Suppression $alias: $iptrim.0/24"
+ octet4=$(echo $ip | cut -d '.' -f 4 | sed 's/\/.*//')
+ dcheck=$(grep $iptrim".0/24" $dupfile)
+ if [ "$dcheck" == "" ]; then
+ echo $iptrim".0" >> $tempfile
+ echo $iptrim".0/24" >> $dupfile
+ counter=$(($counter + 1))
+ # Add Individual IP addresses from Range excluding Suppressed IP
+ for i in $(/usr/bin/jot 255); do
+ if [ "$i" != "$octet4" ]; then
+ echo $iptrim"."$i >> $tempfile
+ counter=$(($counter + 1))
+ fi
+ done
+ fi
+ fi
+ done
+ if [ -s $dupfile ]; then
+ # Remove '/24' Suppressed Ranges
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $dupfile $tempfile > $tempfile2; mv -f $tempfile2 $tempfile
+ fi
+ # Remove All other Suppressions from Lists
+ $pathgrepcidr -vf $pfbsuppression $tempfile > $pfbfolder$alias".txt"
+ # Update Masterfiles. Don't execute if Duplication Process is Disabled
+ if [ "$dedup" == "x" ]; then
+ # Dont execute if Alias doesnt exist in Masterfile
+ lcheck=$(grep -m1 "$alias " $masterfile)
+ if [ ! "$lcheck" == "" ]; then
+ # Replace Masterfile with changes to List.
+ grep "$alias[[:space:]]" $masterfile > $tempfile
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile
+ sed -e 's/^/'$alias' /' $pfbfolder$alias".txt" >> $masterfile
+ cut -d' ' -f2 $masterfile > $mastercat
+ fi
+ fi
+ countk=$(grep -c ^ $masterfile)
+ countx=$(grep -c ^ $pfbfolder$alias".txt")
+ counto=$(($countx - $counter))
+ printf "%-20s %-10s %-10s %-10s %-10s\n" "$alias" "$countg" "$countm" "$counto" "$countk"
+ fi
+ done
+ fi
+else
+ if [ "$cc" == "suppressheader" ]; then
+ echo "===[ Suppression Stats ]========================================"; echo
+ printf "%-20s %-10s %-10s %-10s %-10s\n" "List" "Pre" "RFC1918" "Suppress" "Masterfile"
+ echo "----------------------------------------------------------------"
+ exit
+ fi
+ for i in $cc; do
+ alias=$(echo "${i%|*}")
+ pfbfolder=$(echo "${i#*|}")
+
+ if [ ! "$alias" == "" ]; then
+ countg=$(grep -c ^ $pfbfolder$alias".txt")
+ grep -Ev "^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.|#|$)" $pfbfolder$alias".txt" |
+ sort | uniq > $tempfile; mv -f $tempfile $pfbfolder$alias".txt"
+ countx=$(grep -c ^ $pfbfolder$alias".txt")
+ # Update Masterfiles. Don't execute if Duplication Process is Disabled or if No Suppression Changes Found
+ if [ "$dedup" == "x" -a "$countg" != "$countx" ]; then
+ # Dont execute if Alias doesnt exist in Masterfile
+ lcheck=$(grep -m1 "$alias " $masterfile)
+ if [ ! "$lcheck" == "" ]; then
+ # Replace Masterfile with changes to List.
+ grep "$alias[[:space:]]" $masterfile > $tempfile
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile
+ sed -e 's/^/'$alias' /' $pfbfolder$alias".txt" >> $masterfile
+ cut -d' ' -f2 $masterfile > $mastercat
+ fi
+ fi
+ countm=$(grep -c ^ $pfbfolder$alias".txt")
+ counto=" - "
+ countk=$(grep -c ^ $masterfile)
+ printf "%-20s %-10s %-10s %-10s %-10s\n" "$alias" "$countg" "$countm" "$counto" "$countk"
+ fi
+ done
+fi
+}
+
+
+##########
+# Process to remove Duplicate Entries on each downloaded Blocklist Individually
+duplicate() {
+
+if [ ! -x $pathgrepcidr ]; then
+ echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]"
+ echo "Application [ Grepcidr ] Not found. Can't proceed. [ $now ]" >> errorlog
+ exit
+fi
+
+dupcheck=yes
+# Check if Masterfile is Empty
+hcheck=$(grep -cv "^$" $masterfile); if [ "$hcheck" -eq "0" ]; then dupcheck=no; fi
+# Check if Alias exists in Masterfile
+lcheck=$(grep -m1 "$alias " $masterfile); if [ "$lcheck" == "" ]; then dupcheck=no; fi
+
+if [ "$dupcheck" == "yes" ]; then
+ # Grep Alias with a trailing Space character
+ grep "$alias[[:space:]]" $masterfile > $tempfile
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile
+ cut -d' ' -f2 $masterfile > $mastercat
+fi
+
+grep -Ev "^(#|$)" $pfbdeny$alias".txt" | sort | uniq > $tempfile; mv -f $tempfile $pfbdeny$alias".txt"
+
+if [ ! "$hcheck" -eq "0" ]; then
+ $pathgrepcidr -vf $mastercat $pfbdeny$alias".txt" > $tempfile; mv -f $tempfile $pfbdeny$alias".txt"
+fi
+
+sed -e 's/^/'$alias' /' $pfbdeny$alias".txt" >> $masterfile
+cut -d' ' -f2 $masterfile > $mastercat
+
+countg=$(grep -c ^ $pfborig$alias".orig")
+countm=$(grep -c "$alias " $masterfile); counto=$(grep -c ^ $pfbdeny$alias".txt")
+if [ "$countm" == "$counto" ]; then sanity="Passed"; else sanity=" ==> FAILED <== "; fi
+echo "----------------------------------------------------------"
+printf "%-10s %-10s %-10s %-30s\n" "Original" "Masterfile" "Outfile" " [ Post Duplication count ]"
+echo "----------------------------------------------------------"
+printf "%-10s %-10s %-10s %-30s\n" "$countg" "$countm" "$counto" " [ $sanity ]"
+echo "----------------------------------------------------------"
+}
+
+
+##########
+# De-Duplication utilizing MaxMind GeoIP Country Code Whitelisting ("dmax" variable)
+deduplication() {
+
+if [ ! -x $pathgeoip ]; then
+ echo "d-duplication - Application [ GeoIP ] Not found. Can't proceed."
+ echo "d-duplication - Application [ GeoIP ] Not found. Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+# Download MaxMind GeoIP.dat on first Install.
+if [ ! -f $pathgeoipdat ]; then
+ echo "Downloading [ MaxMind GeoIP.dat ] [ $now ]" >> $geoiplog
+ /usr/local/pkg/pfblockerng/geoipupdate.sh bu
+fi
+
+# Exit if GeoIP.dat is not found
+if [ ! -f $pathgeoipdat ]; then
+ echo "d-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed."
+ echo "d-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+> $tempfile; > $tempfile2; > $dupfile; > $addfile; > $dedupfile; > $matchfile; > $tempmatchfile; count=0; dcount=0; mcount=0; mmcount=0
+echo; echo "Querying for Repeat Offenders"
+data="$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | cut -d '.' -f 1-3 $pfbdeny*.txt |
+ awk -v max="$max" '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}' | grep -v "^1\.1\.1")"
+count=$(echo "$data" | grep -c ^)
+if [ "$data" == "" ]; then count=0; fi
+safe=0
+# Classify Repeat Offenders by Country Code
+if [ -f $pathgeoipdat ]; then
+ echo "Classifying Repeat Offenders by GeoIP"
+ for ip in $data; do
+ ccheck=$($pathgeoip -f $pathgeoipdat "$ip.1" | cut -c 24-25)
+ case "$cc" in
+ *$ccheck*)
+ safe=$(($safe + 1))
+ if [ "$ccwhite" == "match" -o "$ccblack" == "match" ]; then
+ echo "$ip." >> $matchfile
+ fi
+ ;;
+ *)
+ echo "$ip." >> $dupfile
+ ;;
+ esac
+ done
+else
+ echo; echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping d-dedup Process"; echo
+ echo "MaxMind Binary Database Missing [ $pathgeoipdat ], skipping d-dedup Process [ $now ]" >> $errorlog
+fi
+if [ -s "$matchfile" -a "$ccwhite" == "match" ]; then
+ echo "Processing [ Match ] IPs"
+ match=$(sed -e 's/^/^/' -e 's/\./\\\./g' $matchfile)
+ for mfile in $match; do
+ grep $mfile $pfbdeny*.txt >> $tempfile
+ done
+ sed 's/$/0\/24/' $matchfile >> $tempmatchfile
+ sed -e 's/.*://' -e 's/^/\!/' $tempfile >> $tempmatchfile
+ mv -f $tempmatchfile $pfbmatch$matchdedup
+ mcount=$(grep -c ^ $tempfile)
+ mmcount=$(($mcount + $mmcount))
+fi
+# Find Repeat Offenders in each individual Blocklist Outfile
+if [ -s "$dupfile" ]; then
+ echo "Processing [ Block ] IPs"
+ dup=$(cat $dupfile)
+ for ip in $dup; do
+ pcount=1; ii=$(echo "^$ip" | sed 's/\./\\\./g')
+ list=$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | xargs grep -al $ii)
+ for blfile in $list; do
+ header=$(echo "${blfile##*/}" | cut -d '.' -f1)
+ grep $ii $blfile > $tempfile
+ if [ "$ccblack" == "block" ]; then
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $blfile > $tempfile2; mv -f $tempfile2 $blfile
+ if [ "$pcount" -eq "1" ]; then
+ echo $ip"0/24" >> $blfile
+ echo $header" "$ip >> $dedupfile
+ echo $header" "$ip"0/24" >> $addfile
+ pcount=2
+ else
+ echo $header" "$ip >> $dedupfile
+ fi
+ else
+ if [ "$pcount" -eq "1" ]; then
+ matchoutfile="match"$header".txt"
+ echo $ip"0/24" >> $pfbmatch$matchoutfile
+ sed 's/^/\!/' $tempfile >> $pfbmatch$matchoutfile
+ mcount=$(grep -c ^ $pfbmatch$matchoutfile)
+ mmcount=$(($mcount + $mmcount))
+ pcount=2
+ fi
+ fi
+ done
+ done
+ # Remove Repeat Offenders in Masterfiles
+ if [ -s "$dedupfile" ]; then
+ echo "Removing [ Block ] IPs"
+ > $tempfile; > $tempfile2
+ sed 's/\./\\\./g' $dedupfile > $tempfile2
+ while IFS=' ' read -r ips; do grep "$ips" $masterfile >> $tempfile; done < $tempfile2
+ dcount=$(grep -c ^ $tempfile)
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile
+ cat $addfile >> $masterfile
+ cut -d' ' -f2 $masterfile > $mastercat
+ fi
+fi
+
+echo; echo "d-Duplication Process [ $now ]"; echo "------------------------------------------------"
+echo; echo "Found [ $count ] IP range(s) over the threshold of dmax= [ $max ]"
+echo "Found [ $safe ] IP range(s) classified as Whitelisted"
+echo; echo "Found [ $dcount ] CC Blacklisted IP Address(es) are being set to [ $ccblack ]"
+echo "Found [ $mmcount ] CC Whitelisted IP Address(es) are being set to [ $ccwhite ]"; echo
+if [ -s "$addfile" ]; then
+ echo; echo "Removed the following IP Ranges"
+ sed -e 's/^.* //' -e 's/0\/24//' $addfile | tr '\n' '|'; echo
+fi
+count=$(grep -c ^ $masterfile)
+echo " [ Post d-Deduplication count ] [ $count ]"; echo
+
+# Write "1.1.1.1" to empty Final Blocklist Files
+emptyfiles=$(find $pfbdeny -size 0)
+for i in $emptyfiles; do echo "1.1.1.1" > $i; done
+}
+
+
+##########
+# Process to perform a final De-Duplication on all of the BlockLists (Excluding Country Whitelist) ("pmax" variable).
+pdeduplication(){
+
+if [ ! -x $pathgeoip ]; then
+ echo "p-duplication - Application [ GeoIP ] Not found. Can't proceed."
+ echo "p-duplication - Application [ GeoIP ] Not found. Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+# Download MaxMind GeoIP.dat on first Install.
+if [ ! -f $pathgeoipdat ]; then
+ echo "Downloading [ MaxMind GeoIP.dat ] [ $now ]" >> $geoiplog
+ /usr/local/pkg/pfblockerng/geoipupdate.sh bu
+fi
+# Exit if GeoIP.dat is not found.
+if [ ! -f $pathgeoipdat ]; then
+ echo "p-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed."
+ echo "p-duplication - Database GeoIP [ GeoIP.Dat ] not found. Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+> $tempfile; > $tempfile2; > $dupfile; > $addfile; > $dedupfile; count=0; dcount=0
+echo; echo "====================================================================="
+echo; echo "Querying for Repeat Offenders"
+data="$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | cut -d '.' -f 1-3 $pfbdeny*.txt |
+ awk -v max="$max" '{a[$0]++}END{for(i in a){if(a[i] > max){print i}}}' | grep -v "^1\.1\.1")"
+count=$(echo "$data" | grep -c ^)
+if [ "$data" == "" ]; then count=0; fi
+# Find Repeat Offenders in each individual Blocklist Outfile
+echo "Processing [ Block ] IPs"
+for ip in $data; do
+ pcount=1; ii=$(echo "^$ip." | sed 's/\./\\\./g')
+ list=$(find $pfbdeny ! -name "pfB*.txt" ! -name "*_v6.txt" -type f | xargs grep -al $ii)
+ for blfile in $list; do
+ header=$(echo "${blfile##*/}" | cut -d '.' -f1)
+ grep $ii $blfile > $tempfile
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $blfile > $tempfile2; mv -f $tempfile2 $blfile
+ if [ "$pcount" -eq "1" ]; then
+ echo $ip".0/24" >> $blfile
+ echo $header" $ip." >> $dedupfile
+ echo $header" "$ip".0/24" >> $addfile
+ pcount=2
+ else
+ echo $header" $ip." >> $dedupfile
+ fi
+ done
+done
+# Remove Repeat Offenders in Masterfile
+if [ -s "$dedupfile" ]; then
+ echo "Removing [ Block ] IPs"
+ > $tempfile; > $tempfile2
+ sed 's/\./\\\./g' $dedupfile > $tempfile2
+ while IFS=' ' read -r ips; do grep "$ips" $masterfile >> $tempfile; done < $tempfile2
+ dcount=$(grep -c ^ $tempfile)
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile
+ cat $addfile >> $masterfile
+ cut -d' ' -f2 $masterfile > $mastercat
+fi
+
+echo; echo "p-Duplication Process [ $now ]"; echo "------------------------------------------------"
+echo "Found [ $dcount ] IP Address(es) are being set to [ block ]"
+if [ -s "$addfile" ]; then
+ echo; echo "Removed the following IP Ranges"
+ sed -e 's/^.* //' -e 's/0\/24//' $addfile | tr '\n' '|'; echo
+fi
+count=$(grep -c ^ $masterfile)
+echo; echo " [ Post p-Deduplication count ] [ $count ]"
+
+# Write "1.1.1.1" to empty Final Blocklist Files
+emptyfiles=$(find $pfbdeny -size 0)
+for i in $emptyfiles; do echo "1.1.1.1" > $i; done
+}
+
+
+##########
+# Process to Split ET Pro IPREP into Category Files and Compile selected Blocked categories into Outfile
+processet() {
+
+if [ ! -x $pathgunzip ]; then
+ echo "Application [ Gunzip ] Not found, Can't proceed."
+ echo "Application [ Gunzip ] Not found, Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+if [ -s $pfborig$alias".gz" ]; then
+ evar="ET_*"
+ # Remove Previous ET IPRep Files
+ [ -d $etdir ] && [ "$(ls -A $etdir)" ] && rm -r $etdir/$evar
+ > $tempfile; > $tempfile2
+
+ $pathgunzip -c $pfborig$alias".gz" > $pfborig$alias".raw"
+
+ # ET CSV Format (IP, Category, Score)
+ echo; echo "Processing [ $alias ]"
+ while IFS="," read a b c; do
+ # Some ET Categories are not in use (For Future Use)
+ case "$b" in
+ 1) echo $a >> $etdir/ET_Cnc;;
+ 2) echo $a >> $etdir/ET_Bot;;
+ 3) echo $a >> $etdir/ET_Spam;;
+ 4) echo $a >> $etdir/ET_Drop;;
+ 5) echo $a >> $etdir/ET_Spywarecnc;;
+ 6) echo $a >> $etdir/ET_Onlinegaming;;
+ 7) echo $a >> $etdir/ET_Drivebysrc;;
+ 8) echo $a >> $etdir/ET_Cat8;;
+ 9) echo $a >> $etdir/ET_Chatserver;;
+ 10) echo $a >> $etdir/ET_Tornode;;
+ 11) echo $a >> $etdir/ET_Cat11;;
+ 12) echo $a >> $etdir/ET_Cat12;;
+ 13) echo $a >> $etdir/ET_Compromised;;
+ 14) echo $a >> $etdir/ET_Cat14;;
+ 15) echo $a >> $etdir/ET_P2P;;
+ 16) echo $a >> $etdir/ET_Proxy;;
+ 17) echo $a >> $etdir/ET_Ipcheck;;
+ 18) echo $a >> $etdir/ET_Cat18;;
+ 19) echo $a >> $etdir/ET_Utility;;
+ 20) echo $a >> $etdir/ET_DDos;;
+ 21) echo $a >> $etdir/ET_Scanner;;
+ 22) echo $a >> $etdir/ET_Cat22;;
+ 23) echo $a >> $etdir/ET_Brute;;
+ 24) echo $a >> $etdir/ET_Fakeav;;
+ 25) echo $a >> $etdir/ET_Dyndns;;
+ 26) echo $a >> $etdir/ET_Undesireable;;
+ 27) echo $a >> $etdir/ET_Abusedtld;;
+ 28) echo $a >> $etdir/ET_Selfsignedssl;;
+ 29) echo $a >> $etdir/ET_Blackhole;;
+ 30) echo $a >> $etdir/ET_RAS;;
+ 31) echo $a >> $etdir/ET_P2Pcnc;;
+ 32) echo $a >> $etdir/ET_Sharedhosting;;
+ 33) echo $a >> $etdir/ET_Parking;;
+ 34) echo $a >> $etdir/ET_VPN;;
+ 35) echo $a >> $etdir/ET_Exesource;;
+ 36) echo $a >> $etdir/ET_Cat36;;
+ 37) echo $a >> $etdir/ET_Mobilecnc;;
+ 38) echo $a >> $etdir/ET_Mobilespyware;;
+ 39) echo $a >> $etdir/ET_Skypenode;;
+ 40) echo $a >> $etdir/ET_Bitcoin;;
+ 41) echo $a >> $etdir/ET_DDosattack;;
+ *) echo $a >> $etdir/ET_Unknown;;
+ esac
+ done <"$pfborig$alias.raw"
+ data=$(ls $etdir)
+ echo "Compiling ET IP IQRisk REP Lists based upon User Selected Categories"
+ printf "%-10s %-25s\n" " Action" "Category"
+ echo "-------------------------------------------"
+
+ for list in $data; do
+ case "$etblock" in
+ *$list*)
+ printf "%-10s %-25s\n" " Block: " "$list"
+ cat $etdir/$list >> $tempfile
+ ;;
+ esac
+ case "$etmatch" in
+ *$list*)
+ printf "%-10s %-25s\n" " Match: " "$list"
+ cat $etdir/$list >> $tempfile2
+ ;;
+ esac
+ done
+ echo "-------------------------------------------"
+
+ if [ -f $tempfile ]; then mv -f $tempfile $pfborig$alias".orig"; fi
+ if [ "$etmatch" != "x" ]; then mv -f $tempfile2 $pfbmatch/ETMatch.txt; fi
+ cicount=$(cat $etdir/$evar | grep -cv '^#\|^$'); cocount=$(grep -cv "^1\.1\.1\.1" $pfborig$alias".orig")
+ echo; echo "ET Folder count [ $cicount ] Outfile count [ $cocount ]"
+else
+ echo; echo "No ET .GZ File Found!"
+fi
+}
+
+# Process to extract IP addresses from XLSX Files
+processxlsx() {
+
+if [ ! -x $pathtar ]; then
+ echo "Application [ TAR ] Not found, Can't proceed."
+ echo "Application [ TAR ] Not found, Can't proceed. [ $now ]" >> $errorlog
+ exit
+fi
+
+if [ -s $pfborig$alias".zip" ]; then
+
+ $pathtar -xf $pfborig$alias".zip" -C $tmpxlsx
+ $pathtar -xOf $tmpxlsx*.[xX][lL][sS][xX] xl/sharedStrings.xml |
+ grep -aoEw "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" | sort | uniq > $pfborig$alias".orig"
+ rm -r $tmpxlsx*
+
+ cocount=$(grep -cv "^1\.1\.1\.1" $pfborig$alias".orig")
+ echo; echo "Download file count [ ZIP file ] Outfile count [ $cocount ]"
+else
+ echo "XLSX Download File Missing"
+ echo " [ $alias ] XLSX Download File Missing [ $now ]" >> $errorlog
+fi
+}
+
+closingprocess() {
+
+# Write "1.1.1.1" to empty Final Blocklist Files
+emptyfiles=$(find $pfbdeny -size 0)
+for i in $emptyfiles; do echo "1.1.1.1" > $i; done
+
+if [ -d "$pfborig" ] && [ "$(ls -A $pfborig)" ]; then
+ fcount=$(find $pfborig*.orig | xargs cat | grep -cv '^#\|^$')
+else
+ fcount=0
+fi
+
+if [ "$alias" == "on" ]; then
+ sort -o $masterfile $masterfile
+ sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n $mastercat > $tempfile; mv -f $tempfile $mastercat
+
+ echo; echo; echo "===[ FINAL Processing ]====================================="; echo
+ echo " [ Original count ] [ $fcount ]"
+ count=$(grep -c ^ $masterfile)
+ echo; echo " [ Processed Count ] [ $count ]"; echo
+
+ s1=$(grep -cv "1\.1\.1\.1" $masterfile)
+ s2=$(find $pfbdeny ! -name "*_v6.txt" -type f | xargs cat | grep -cv "^1\.1\.1\.1")
+ s3=$(sort $mastercat | uniq -d | tail -30)
+ s4=$(find $pfbdeny ! -name "*_v6.txt" -type f | xargs cat | sort | uniq -d | tail -30 | grep -v "^1\.1\.1\.1")
+
+ if [ -d "$pfbpermit" ] && [ "$(ls -A $pfbpermit)" ]; then
+ echo; echo "===[ Permit List IP Counts ]========================="; echo
+ wc -l $pfbpermit* | sort -n -r
+ fi
+ if [ -d "$pfbmatch" ] && [ "$(ls -A $pfbmatch)" ]; then
+ echo; echo "===[ Match List IP Counts ]=========================="; echo
+ wc -l $pfbmatch* | sort -n -r
+ fi
+ if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then
+ echo; echo "===[ Deny List IP Counts ]==========================="; echo
+ wc -l $pfbdeny* | sort -n -r
+ fi
+ if [ -d "$pfbnative" ] && [ "$(ls -A $pfbnative)" ]; then
+ echo; echo "===[ Native List IP Counts ] ==================================="; echo
+ wc -l $pfbnative* | sort -n -r
+ fi
+ if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then
+ emptylists=$(grep "1\.1\.1\.1" $pfbdeny* | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:1.1.1.1/ /')
+ if [ ! -z "$emptylists" ]; then
+ echo; echo "====================[ Empty Lists w/1.1.1.1 ]=================="; echo
+ for list in $emptylists; do
+ echo $list
+ done
+ fi
+ fi
+ if [ -d "$pfborig" ] && [ "$(ls -A $pfborig)" ]; then
+ echo; echo "====================[ Last Updated List Summary ]=============="; echo
+ ls -lahtr $pfborig* | sed -e 's/\/.*\// /' -e 's/.orig//' | awk -v OFS='\t' '{print $6" "$7,$8,$9}'
+ fi
+ echo "==============================================================="; echo
+ echo "Sanity Check (Not Including IPv6) ** These two Counts should Match! **"
+ echo "------------"
+ echo "Masterfile Count [ $s1 ]"
+ echo "Deny folder Count [ $s2 ]"; echo
+ echo "Duplication Sanity Check (Pass=No IPs reported)"
+ echo "------------------------"
+ echo "Masterfile/Deny Folder Uniq check"
+ if [ ! -z "$s3" ]; then echo $s3; fi
+ echo "Deny Folder/Masterfile Uniq check"
+ if [ ! -z "$s4" ]; then echo $s4; fi
+ echo; echo "Sync Check (Pass=No IPs reported)"
+ echo "----------"
+else
+ echo; echo "===[ FINAL Processing ]============================================="; echo
+ echo " [ Original count ] [ $fcount ]"
+ if [ -d "$pfbpermit" ] && [ "$(ls -A $pfbpermit)" ]; then
+ echo; echo "===[ Permit List IP Counts ]========================="; echo
+ wc -l $pfbpermit* | sort -n -r
+ fi
+ if [ -d "$pfbmatch" ] && [ "$(ls -A $pfbmatch)" ]; then
+ echo; echo "===[ Match List IP Counts ]=========================="; echo
+ wc -l $pfbmatch* | sort -n -r
+ fi
+ if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then
+ echo; echo "===[ Deny List IP Counts ]==========================="; echo
+ wc -l $pfbdeny* | sort -n -r
+ fi
+ if [ -d "$pfbnative" ] && [ "$(ls -A $pfbnative)" ]; then
+ echo; echo "===[ Native List IP Counts ] ==================================="; echo
+ wc -l $pfbnative* | sort -n -r
+ fi
+ if [ -d "$pfbdeny" ] && [ "$(ls -A $pfbdeny)" ]; then
+ emptylists=$(grep "1\.1\.1\.1" $pfbdeny* | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:1.1.1.1/ /')
+ if [ ! -z "$emptylists" ]; then
+ echo; echo "====================[ Empty Lists w/1.1.1.1 ]=================="; echo
+ for list in $emptylists; do
+ echo $list
+ done
+ fi
+ fi
+ if [ -d "$pfborig" ] && [ "$(ls -A $pfborig)" ]; then
+ echo; echo "====================[ Last Updated List Summary ]=============="; echo
+ ls -lahtr $pfborig* | sed -e 's/\/.*\// /' -e 's/.orig//' | awk -v OFS='\t' '{print $6" "$7,$8,$9}'
+ echo "==============================================================="
+ fi
+fi
+
+echo; echo "IPv4 Alias Table IP Total"; echo "-----------------------------"
+find $pfsense_alias_dir ! -name "*_v6.txt" -type f | xargs cat | grep -c ^
+
+echo; echo "IPv6 Alias Table IP Total"; echo "-----------------------------"
+find $pfsense_alias_dir -name "*_v6.txt" -type f | xargs cat | grep -c ^
+
+echo; echo "Alias Table IP Counts"; echo "-----------------------------"
+wc -l $pfsense_alias_dir*.txt | sort -n -r
+
+echo; echo "pfSense Table Stats"; echo "-------------------"
+$pathpfctl -s memory | grep "table-entries"
+pfctlcount=$($pathpfctl -vvsTables | awk '/Addresses/ {s+=$2}; END {print s}')
+echo "Table Usage Count " $pfctlcount
+}
+
+remove() {
+# Remove Lists from Masterfiles and Delete Associated Files
+echo
+for i in $cc; do
+ header=$(echo "${i%*,}")
+ if [ ! "$header" == "" ]; then
+ # Make sure that Alias Exists in Masterfile before removal.
+ masterchk=$(grep -m1 "$header[[:space:]]" $masterfile)
+ if [ ! -z "$masterchk" ]; then
+ # Grep Header with a Trailing Space character
+ grep "$header[[:space:]]" $masterfile > $tempfile
+ awk 'FNR==NR{a[$0];next}!($0 in a)' $tempfile $masterfile > $tempfile2; mv -f $tempfile2 $masterfile
+ cut -d' ' -f2 $masterfile > $mastercat
+ fi
+ rm -rf $pfborig$header*; rm -rf $pfbdeny$header*; rm -rf $pfbmatch$header*; rm -rf $pfbpermit$header*; rm -rf $pfbnative$header*
+ echo "The Following list has been REMOVED [ $header ]"
+ fi
+ echo
+done
+
+# Delete Masterfiles if they are empty
+emptychk=$(find $masterfile -size 0)
+if [ ! "$emptychk" == "" ]; then
+ rm -r $masterfile; rm -r $mastercat
+fi
+}
+
+
+##########
+# CALL APPROPRIATE PROCESSES using Script Argument $1
+case $1 in
+ continent)
+ continent
+ ;;
+ duplicate)
+ process255
+ duplicate
+ ;;
+ suppress)
+ suppress
+ ;;
+ p24)
+ process24
+ ;;
+ dedup)
+ deduplication
+ ;;
+ pdup)
+ pdeduplication
+ ;;
+ et)
+ processet
+ ;;
+ xlsx)
+ processxlsx
+ ;;
+ closing)
+ closingprocess
+ ;;
+ remove)
+ remove
+ ;;
+ *)
+ exit
+ ;;
+esac
+exit \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.widget.php b/config/pfblockerng/pfblockerng.widget.php
new file mode 100644
index 00000000..647017ff
--- /dev/null
+++ b/config/pfblockerng/pfblockerng.widget.php
@@ -0,0 +1,280 @@
+<?php
+/*
+ pfBlockerNG.widget.php
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based Upon pfblocker :
+ Copyright 2011 Thomas Schaefer - Tomschaefer.org
+ Copyright 2011 Marcello Coutinho
+ Part of pfSense widgets (www.pfsense.org)
+
+ Adapted From:
+ snort_alerts.widget.php
+ Copyright (C) 2009 Jim Pingle
+ mod 24-07-2012
+ mod 28-02-2014 by Bill Meeks
+
+ Javascript and Integration modifications by J. Nieuwenhuizen
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+@require_once("/usr/local/www/widgets/include/widget-pfblockerng.inc");
+@require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+@require_once("guiconfig.inc");
+@require_once("globals.inc");
+@require_once("pfsense-utils.inc");
+@require_once("functions.inc");
+
+pfb_global();
+
+// Ackwnowlege Failed Downloads
+if (isset($_POST['pfblockerngack'])) {
+ $clear = exec("/usr/bin/sed -i '' 's/FAIL/Fail/g' {$pfb['errlog']}");
+ header("Location: ../../index.php");
+}
+
+// This function will create the counts
+function pfBlockerNG_get_counts() {
+ global $config, $g, $pfb;
+
+ // Collect Alias Count and Update Date/Time
+ $pfb_table = array();
+ $out = "<img src ='/themes/{$g['theme']}/images/icons/icon_interface_down.gif' title=\"No Rules are Defined using this Alias\" alt=\"\" />";
+ $in = "<img src ='/themes/{$g['theme']}/images/icons/icon_interface_up.gif' title=\"Rules are Defined using this Alias\" alt=\"\" />";
+ if (is_array($config['aliases']['alias'])) {
+ foreach ($config['aliases']['alias'] as $cbalias) {
+ if (preg_match("/pfB_/", $cbalias['name'])) {
+ if (file_exists("{$pfb['aliasdir']}/{$cbalias['name']}.txt")) {
+ preg_match("/(\d+)/", exec("/usr/bin/grep -cv \"^1\.1\.1\.1\" {$pfb['aliasdir']}/{$cbalias['name']}.txt"), $matches);
+ $pfb_table[$cbalias['name']] = array("count" => $matches[1], "img" => $out);
+ $updates = exec("ls -ld {$pfb['aliasdir']}/{$cbalias['name']}.txt | awk '{ print $6,$7,$8 }'", $update);
+ $pfb_table[$cbalias['name']]['up'] = $updates;
+ }
+ }
+ }
+ }
+
+ // Collect if Rules are defined using pfBlockerNG Aliases.
+ if (is_array($config['filter']['rule'])) {
+ foreach ($config['filter']['rule'] as $rule) {
+ if (preg_match("/pfB_/",$rule['source']['address']) || preg_match("/pfb_/",$rule['source']['address'])) {
+ $pfb_table[$rule['source']['address']]['img'] = $in;
+ }
+ if (preg_match("/pfB_/",$rule['destination']['address']) || preg_match("/pfb_/",$rule['destination']['address'])) {
+ $pfb_table[$rule['destination']['address']]['img'] = $in;
+ }
+ }
+ return $pfb_table;
+ }
+}
+
+// Status Indicator if pfBlockerNG is Enabled/Disabled
+if ("{$pfb['enable']}" == "on") {
+ $pfb_status = "/themes/{$g['theme']}/images/icons/icon_pass.gif";
+ $pfb_msg = "pfBlockerNG is Active.";
+} else {
+ $pfb_status = "/themes/{$g['theme']}/images/icons/icon_block.gif";
+ $pfb_msg = "pfBlockerNG is Disabled.";
+}
+
+// Collect Total IP/Cidr Counts
+$dcount = exec("cat {$pfb['denydir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'");
+$pcount = exec("cat {$pfb['permitdir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'");
+$mcount = exec("cat {$pfb['matchdir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'");
+$ncount = exec("cat {$pfb['nativedir']}/*.txt | grep -cv '^#\|^$\|^1\.1\.1\.1'");
+
+// Collect Number of Suppressed Hosts
+if (file_exists("{$pfb['supptxt']}")) {
+ $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}");
+} else {
+ $pfbsupp_cnt = 0;
+}
+
+#check rule count
+#(label, evaluations,packets total, bytes total, packets in, bytes in,packets out, bytes out)
+$packets = exec("/sbin/pfctl -s labels", $debug);
+if (!empty($debug)) {
+ foreach ($debug as $line) {
+ // Auto-Rules start with 'pfB_', Alias Rules should start with 'pfb_' and exact spelling of Alias Name.
+ $line = str_replace("pfb_","pfB_",$line);
+ if ("{$pfb['pfsenseversion']}" >= '2.2') {
+ #USER_RULE: pfB_Top auto rule 8494 17 900 17 900 0 0 0
+ if (preg_match("/USER_RULE: (\w+).*\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+/", $line, $matches)) {
+ if (isset($matches)) {
+ ${$matches[1]}+=$matches[2];
+ } else {
+ ${$matches[1]} = 'Err';
+ }
+ }
+ } else {
+ #USER_RULE: pfB_Top auto rule 1656 0 0 0 0 0 0
+ if (preg_match("/USER_RULE: (\w+).*\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+/", $line, $matches)) {
+ if (isset($matches)) {
+ ${$matches[1]}+=$matches[2];
+ } else {
+ ${$matches[1]} = 'Err';
+ }
+ }
+ }
+ }
+}
+
+// Called by Ajax to update alerts table contents
+if (isset($_GET['getNewCounts'])) {
+ $response = "";
+ $pfb_table = pfBlockerNG_get_counts();
+ if (!empty($pfb_table)) {
+ foreach ($pfb_table as $alias => $values){
+ if (!isset(${$alias})) { ${$alias} = "-";}
+ $response .= $alias . "||" . $values['count'] . "||" . ${$alias} . "||" . $values['up'] . "||" . $values['img'] . "\n";
+ }
+ echo $response;
+ return;
+ }
+}
+
+// Report any Failed Downloads
+$results = array();
+$fails = exec("grep $(date +%m/%d/%y) {$pfb['errlog']} | grep 'FAIL'", $results);
+
+// Print widget Status Bar Items
+?>
+ <div class="marinarea">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <thead>
+ <tr>
+ <td valign="middle">&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">
+ <?php if (!empty($results)): ?> <!--Hide "Ack" Button when Failed Downloads are Empty-->
+ <form action="/widgets/widgets/pfblockerng.widget.php" method="post" name="widget_pfblockerng_ack">
+ <input type="hidden" value="clearack" name="pfblockerngack" />
+ <input class="vexpl" type="image" name="pfblockerng_ackbutton" src="/themes/<?=$g['theme']; ?>/images/icons/icon_x.gif" width="14" height="14" border="0" title="<?=gettext("Clear Failed Downloads") ?>"/>
+ </form>
+ <?php endif; ?>
+ </td>
+ </tr>
+ </thead>
+ </table>
+ </div>
+
+ <table id="pfb-tblfails" width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tbody id="pfb-fails">
+<?php
+
+if ("{$pfb['pfsenseversion']}" > '2.0') {
+ $alertRowEvenClass = "listMReven";
+ $alertRowOddClass = "listMRodd";
+ $alertColClass = "listMRr";
+} else {
+ $alertRowEvenClass = "listr";
+ $alertRowOddClass = "listr";
+ $alertColClass = "listr";
+}
+
+# Last errors first
+$results = array_reverse($results);
+
+$counter = 0;
+# Max errors to display
+$maxfailcount = 3;
+if (!empty($results)) {
+ foreach ($results as $result) {
+ $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass;
+ if (!isset(${$alias})) { ${$alias} = "-";}
+ echo(" <tr class='" . $alertRowClass . "'><td class='" . $alertColClass . "'>" . $result . "</td><tr>");
+ $counter++;
+ if ($counter > $maxfailcount) {
+ # To many errors stop displaying
+ echo(" <tr class='" . $alertRowClass . "'><td class='" . $alertColClass . "'>" . (count($results) - $maxfailcount) . " more error(s)...</td><tr>");
+ break;
+ }
+ }
+}
+
+// Print Main Table Header
+?>
+ </tbody>
+ </table>
+ <table id="pfb-tbl" width="100%" border="0" cellspacing="0" cellpadding="0">
+ <thead>
+ <tr>
+ <th class="widgetsubheader" align="center"><?=gettext("Alias");?></th>
+ <th title="The count can be a mixture of Single IPs or CIDR values" class="widgetsubheader" align="center"><?=gettext("Count");?></th>
+ <th title="Packet Counts can be cleared by the pfSense filter_configure() function. Make sure Rule Descriptions start with 'pfB_'" class="widgetsubheader" align="center"><?=gettext("Packets");?></th>
+ <th title="Last Update (Date/Time) of the Alias " class="widgetsubheader" align="center"><?=gettext("Updated");?></th>
+ <th class="widgetsubheader" align="center"><?php echo $out; ?><?php echo $in; ?></th>
+ </tr>
+ </thead>
+ <tbody id="pfbNG-entries">
+<?php
+// Print Main Table Body
+$pfb_table = pfBlockerNG_get_counts();
+$counter=0;
+if (is_array($pfb_table)) {
+ foreach ($pfb_table as $alias => $values) {
+ $evenRowClass = $counter % 2 ? " listMReven" : " listMRodd";
+ if (!isset(${$alias})) { ${$alias} = "-";}
+ echo(" <tr class='" . $evenRowClass . "'>
+ <td class='listMRr ellipsis'>{$alias}</td>
+ <td class='listMRr' align='center'>{$values['count']}</td>
+ <td class='listMRr' align='center'>{${$alias}}</td>
+ <td class='listMRr' align='center'>{$values['up']}</td>
+ <td class='listMRr' align='center'>{$values['img']}</td>
+ </tr>");
+ $counter++;
+ }
+}
+
+?>
+</tbody>
+</table>
+
+<script type="text/javascript">
+//<![CDATA[
+ var pfBlockerNGupdateDelay = 10000; // update every 10000 ms
+//]]>
+</script> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng.xml b/config/pfblockerng/pfblockerng.xml
new file mode 100644
index 00000000..e2f4b508
--- /dev/null
+++ b/config/pfblockerng/pfblockerng.xml
@@ -0,0 +1,495 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ======================================================================================= */
+/*
+ pfBlockerNG.xml
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfblocker for pfSense
+ Copyright (C) 2011 Marcello Coutinho
+ All rights reserved.
+/*
+/* ====================================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+/*
+/* ====================================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>pfblockerng</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: General Settings</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <menu>
+ <name>pfBlockerNG</name>
+ <configfile>pfblockerng.xml</configfile>
+ <tooltiptext>Configure pfBlockerNG</tooltiptext>
+ <section>Firewall</section>
+ <url>/pkg_edit.php?xml=pfblockerng.xml</url>
+ </menu>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.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.php</item>
+ <prefix>/usr/local/www/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_alerts.php</item>
+ <prefix>/usr/local/www/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_update.php</item>
+ <prefix>/usr/local/www/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_log.php</item>
+ <prefix>/usr/local/www/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_diag_dns.php</item>
+ <prefix>/usr/local/www/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.widget.php</item>
+ <prefix>/usr/local/www/widgets/widgets/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/widget-pfblockerng.inc</item>
+ <prefix>/usr/local/www/widgets/include/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.js</item>
+ <prefix>/usr/local/www/widgets/javascript/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_top20.xml</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_v4lists.xml</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_v6lists.xml</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng_sync.xml</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ <chmod>0644</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/countrycodes.tar.bz2</item>
+ <prefix>/var/db/pfblockerng/cc/</prefix>
+ <chmod>0444</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/pfblockerng.sh</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/pfblockerng/geoipupdate.sh</item>
+ <prefix>/usr/local/pkg/pfblockerng/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Update</text>
+ <url>/pfblockerng/pfblockerng_update.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pfblockerng/pfblockerng_alerts.php</url>
+ </tab>
+ <tab>
+ <text>Reputation</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>IPv4</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</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>
+ </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>
+ </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&amp;id=0</url>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <name>pfBlockerNG General Settings</name>
+ <type>listtopic</type>
+ </field>
+ <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>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>Enable pfBlockerNG</strong>]]></fielddescr>
+ <fieldname>enable_cb</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[Note - with "Keep settings" enabled, pfBlockerNG will maintain run state on Installation/Upgrade<br />
+ If "Keep Settings" is not "enabled" on pkg Install/De-Install, all Settings will be Wiped!]]></description>
+ </field>
+ <field>
+ <fielddescr>CRON MIN Start Time</fielddescr>
+ <fieldname>pfb_min</fieldname>
+ <description><![CDATA[Default: <strong> : 00</strong><br />
+ Select Cron Update Minute ]]></description>
+ <type>select</type>
+ <options>
+ <option><name> : 00</name><value>0</value></option>
+ <option><name> : 15</name><value>15</value></option>
+ <option><name> : 30</name><value>30</value></option>
+ <option><name> : 45</name><value>45</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>CRON Base Hour Start Time</fielddescr>
+ <fieldname>pfb_hour</fieldname>
+ <description><![CDATA[Default: <strong> 1 </strong><br />
+ Select Cron Base Start Hour ]]></description>
+ <type>select</type>
+ <options>
+ <option><name>1</name><value>0</value></option>
+ <option><name>0</name><value>1</value></option>
+ <option><name>2</name><value>2</value></option>
+ <option><name>3</name><value>3</value></option>
+ <option><name>4</name><value>4</value></option>
+ <option><name>5</name><value>5</value></option>
+ <option><name>6</name><value>6</value></option>
+ <option><name>7</name><value>7</value></option>
+ <option><name>8</name><value>8</value></option>
+ <option><name>9</name><value>9</value></option>
+ <option><name>10</name><value>10</value></option>
+ <option><name>11</name><value>11</value></option>
+ <option><name>12</name><value>12</value></option>
+ <option><name>13</name><value>13</value></option>
+ <option><name>14</name><value>14</value></option>
+ <option><name>15</name><value>15</value></option>
+ <option><name>16</name><value>16</value></option>
+ <option><name>17</name><value>17</value></option>
+ <option><name>18</name><value>18</value></option>
+ <option><name>19</name><value>19</value></option>
+ <option><name>20</name><value>20</value></option>
+ <option><name>21</name><value>21</value></option>
+ <option><name>22</name><value>22</value></option>
+ <option><name>23</name><value>23</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>'Daily/Weekly' Start Hour</fielddescr>
+ <fieldname>pfb_dailystart</fieldname>
+ <description><![CDATA[Default: <strong> 1 </strong><br />
+ Select 'Daily' Schedule Start Hour <br />
+ This is used for the 'Daily/Weekly' Scheduler Only.]]></description>
+ <type>select</type>
+ <options>
+ <option><name>1</name><value>0</value></option>
+ <option><name>0</name><value>1</value></option>
+ <option><name>2</name><value>2</value></option>
+ <option><name>3</name><value>3</value></option>
+ <option><name>4</name><value>4</value></option>
+ <option><name>5</name><value>5</value></option>
+ <option><name>6</name><value>6</value></option>
+ <option><name>7</name><value>7</value></option>
+ <option><name>8</name><value>8</value></option>
+ <option><name>9</name><value>9</value></option>
+ <option><name>10</name><value>10</value></option>
+ <option><name>11</name><value>11</value></option>
+ <option><name>12</name><value>12</value></option>
+ <option><name>13</name><value>13</value></option>
+ <option><name>14</name><value>14</value></option>
+ <option><name>15</name><value>15</value></option>
+ <option><name>16</name><value>16</value></option>
+ <option><name>17</name><value>17</value></option>
+ <option><name>18</name><value>18</value></option>
+ <option><name>19</name><value>19</value></option>
+ <option><name>20</name><value>20</value></option>
+ <option><name>21</name><value>21</value></option>
+ <option><name>22</name><value>22</value></option>
+ <option><name>23</name><value>23</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Enable De-Duplication</fielddescr>
+ <fieldname>enable_dup</fieldname>
+ <type>checkbox</type>
+ <description>Only for IPv4 Lists</description>
+ </field>
+ <field>
+ <fielddescr>Enable Suppression</fielddescr>
+ <fieldname>suppression</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[This will prevent Selected IPs from being Blocked. Only for IPv4 Lists (/32 and /24).<br />
+ Country Blocking Lists cannot be Suppressed.<br />
+ This will also remove any RFC1918 addresses from all Lists.<br /><br />
+ Alerts can be Suppressed using the '+' icon in the Alerts Tab and IPs added to the 'pfBlockerNGSuppress' Alias<br />
+ A Blocked IP in a CIDR other than /24 will need to be Suppressed by an 'Permit Outbound' Firewall Rule]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>Keep Settings</strong>/Lists After Disable/Re-Install/De-Install]]></fielddescr>
+ <fieldname>pfb_keep</fieldname>
+ <type>checkbox</type>
+ <description>Keep Settings and Lists intact when pfBlockerNG is Disabled or After pfBlockerNG Re-Install/De-Install</description>
+ </field>
+ <field>
+ <fielddescr>Global Enable Logging</fielddescr>
+ <fieldname>enable_log</fieldname>
+ <type>checkbox</type>
+ <description>Enable Global Logging to Status: System Logs: FIREWALL ( Log ). This overrides any Log Settings in the Alias Tabs.</description>
+ </field>
+ <field>
+ <fielddescr>Disable MaxMind Country Database CRON Updates</fielddescr>
+ <fieldname>database_cc</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[This will Disable the MaxMind Monthly Country Database Cron Update.<br />
+ This does not affect the MaxMind Binary Cron Task]]>
+ </description>
+ </field>
+ <field>
+ <fielddescr>Logfile Size</fielddescr>
+ <fieldname>log_maxlines</fieldname>
+ <description><![CDATA[Default:<strong>20000</strong><br />
+ Select number of Lines to Keep in Log File]]></description>
+ <type>select</type>
+ <options>
+ <option><name>20000</name><value>20000</value></option>
+ <option><name>40000</name><value>40000</value></option>
+ <option><name>60000</name><value>60000</value></option>
+ <option><name>80000</name><value>80000</value></option>
+ <option><name>100000</name><value>100000</value></option>
+ <option><name>No Limit</name><value>nolimit</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[Interface/Rules Configuration]]> </name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Inbound Interface(s)</fielddescr>
+ <fieldname>inbound_interface</fieldname>
+ <description>Select the Inbound interface(s) you want to Apply Auto Rules to</description>
+ <type>interfaces_selection</type>
+ <hideinterfaceregex>loopback</hideinterfaceregex>
+ <required/>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr> - Rule Action</fielddescr>
+ <fieldname>inbound_deny_action</fieldname>
+ <description><![CDATA[Default:<strong>Block</strong><br />
+ Select 'Rule Action' for Inbound Rules]]></description>
+ <type>select</type>
+ <options>
+ <option><name>Block</name><value>block</value></option>
+ <option><name>Reject</name><value>reject</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Outbound Interface(s)</fielddescr>
+ <fieldname>outbound_interface</fieldname>
+ <description>Select the Outbound interface(s) you want to Apply Auto Rules to</description>
+ <type>interfaces_selection</type>
+ <hideinterfaceregex>loopback</hideinterfaceregex>
+ <required/>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr> - Rule Action</fielddescr>
+ <fieldname>outbound_deny_action</fieldname>
+ <description><![CDATA[Default:<strong>Reject</strong><br />
+ Select 'Rule Action' for Outbound rules]]></description>
+ <type>select</type>
+ <options>
+ <option><name>Reject</name><value>reject</value></option>
+ <option><name>Block</name><value>block</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>OpenVPN Interface</strong>]]></fielddescr>
+ <fieldname>openvpn_action</fieldname>
+ <type>checkbox</type>
+ <description>Select to add Auto-Rules for OpenVPN. These will be added to 'Floating Rules' or OpenVPN Rules Tab.</description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>Floating Rules</strong>]]></fielddescr>
+ <fieldname>enable_float</fieldname>
+ <type>checkbox</type>
+ <description><![CDATA[<strong>Enabled:&nbsp;</strong> Auto-Rules will be generated in the 'Floating Rules' Tab<br /><br />
+ <strong>Disabled:</strong> Auto-Rules will be generated in the Selected Inbound/Outbound Interfaces<br /><br />
+ <strong>Rules will be ordered by the selection below.</strong>]]></description>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>Rule Order</strong>]]></fielddescr>
+ <fieldname>pass_order</fieldname>
+ <description><![CDATA[<br />Default Order: <strong> | pfB_Block/Reject | All other Rules | (original format)<br /></strong><br />
+ Select The '<strong>Order</strong>' of the Rules<br />
+ &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>]]></description>
+ <type>select</type>
+ <options>
+ <option><name>| pfB_Block/Reject | All other Rules | (original format)</name><value>order_0</value></option>
+ <option><name>| pfSense Pass/Match | pfB_Pass/Match | pfB_Block/Reject |</name><value>order_1</value></option>
+ <option><name>| pfB_Pass/Match | pfSense Pass/Match | pfB_Block/Reject |</name><value>order_2</value></option>
+ <option><name>| pfB_Pass/Match | pfB_Block/Reject | pfSense Pass/Match |</name><value>order_3</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>Auto Rule Suffix</strong>]]></fielddescr>
+ <fieldname>autorule_suffix</fieldname>
+ <description><![CDATA[Default:<strong>auto rule</strong><br />
+ Select 'Auto Rule' Description Suffix for Auto Defined rules. pfBlockerNG Must be Disabled to Modify Suffix]]></description>
+ <type>select</type>
+ <options>
+ <option><name>auto rule</name><value>autorule</value></option>
+ <option><name>Null (no suffix)</name><value>standard</value></option>
+ <option><name>AR</name><value>ar</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[Acknowledgements]]> </name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Credits</fielddescr>
+ <fieldname>credits</fieldname>
+ <type>info</type>
+ <description><![CDATA[<strong>
+ pfBlockerNG</strong> Created in 2014 by <a target=_new href='https://forum.pfsense.org/index.php?action=profile;u=238481'>BBcan177.</a>
+ <br /><br />Based upon pfBlocker by Marcello Coutinho and Tom Schaefer.<br />
+ Country Database GeoLite distributed under the Creative Commons Attribution-ShareAlike 3.0 Unported License by:
+ MaxMind Inc. @ <a target=_new href='http://www.maxmind.com'>MaxMind.com</a>.
+ The Database is Automatically Updated the First Tuesday of Each Month]]></description>
+ </field>
+ <field>
+ <fielddescr>pfBlocker Validation Check</fielddescr>
+ <fieldname>pfblocker_cb</fieldname>
+ <type>checkbox</type>
+ <description>Disable pfBlockerNG if the pfBlocker package is Enabled. Click to Disable this validation check.</description>
+ </field>
+ <field>
+ <fielddescr>Gold Membership</fielddescr>
+ <type>info</type>
+ <description><![CDATA[If you like this package, please Support pfSense by subscribing to a <a target=_new href='https://portal.pfsense.org/gold-subscription.php'>Gold Membership</a><br /> or support the developer @ BBCan177@gmail.com]]></description>
+ </field>
+ <field>
+ <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ 'Force Update'</ul>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_install_command>
+ pfblockerng_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ pfblockerng_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ pfblockerng_validate_input($_POST, $input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ global $pfb;
+ $pfb['save'] = TRUE;
+ sync_package_pfblockerng();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_alerts.php b/config/pfblockerng/pfblockerng_alerts.php
new file mode 100644
index 00000000..7b84bca8
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_alerts.php
@@ -0,0 +1,769 @@
+<?php
+/*
+ pfBlockerNG_Alerts.php
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Portions of this code are based on original work done for
+ pfSense from the following contributors:
+
+ Parts based on works from Snort_alerts.php
+ Copyright (C) 2014 Bill Meeks
+ All rights reserved.
+
+ Javascript Hostname Lookup modifications by J. Nieuwenhuizen
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("util.inc");
+require_once("guiconfig.inc");
+require_once("globals.inc");
+require_once("filter_log.inc");
+require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+
+pfb_global();
+
+// Application Paths
+$pathgeoip = "/usr/pbi/pfblockerng-" . php_uname("m") . "/bin/geoiplookup";
+$pathgeoip6 = "/usr/pbi/pfblockerng-" . php_uname("m") . "/bin/geoiplookup6";
+
+// Define File Locations
+$filter_logfile = "{$g['varlog_path']}/filter.log";
+$pathgeoipdat = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIP.dat";
+$pathgeoipdat6 = "/usr/pbi/pfblockerng-" . php_uname("m") . "/share/GeoIP/GeoIPv6.dat";
+
+// Emerging Threats IQRisk Header Name Reference
+$pfb['et_header'] = TRUE;
+$et_header = $config['installedpackages']['pfblockerngreputation']['config'][0]['et_header'];
+if (empty($et_header))
+ $pfb['et_header'] = FALSE;
+
+// Collect pfBlockerNGSuppress Alias and Create pfbsuppression.txt
+if ($pfb['supp'] == "on")
+ pfb_create_suppression_file();
+
+// Collect Number of Suppressed Hosts
+if (file_exists("{$pfb['supptxt']}")) {
+ $pfbsupp_cnt = exec ("/usr/bin/grep -c ^ {$pfb['supptxt']}");
+} else {
+ $pfbsupp_cnt = 0;
+}
+
+// Collect pfBlockerNG Rule Names and Number
+$rule_list = array();
+$results = array();
+$data = exec ("/sbin/pfctl -vv -sr | grep 'pfB_'", $results);
+
+if (empty($config['installedpackages']['pfblockerngglobal']['pfbdenycnt']))
+ $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = '25';
+if (empty($config['installedpackages']['pfblockerngglobal']['pfbpermitcnt']))
+ $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = '5';
+if (empty($config['installedpackages']['pfblockerngglobal']['pfbmatchcnt']))
+ $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'] = '5';
+if (empty($config['installedpackages']['pfblockerngglobal']['alertrefresh']))
+ $config['installedpackages']['pfblockerngglobal']['alertrefresh'] = 'off';
+if (empty($config['installedpackages']['pfblockerngglobal']['hostlookup']))
+ $config['installedpackages']['pfblockerngglobal']['hostlookup'] = 'off';
+
+if (isset($_POST['save'])) {
+ if (!is_array($config['installedpackages']['pfblockerngglobal']))
+ $config['installedpackages']['pfblockerngglobal'] = array();
+ $config['installedpackages']['pfblockerngglobal']['alertrefresh'] = $_POST['alertrefresh'] ? 'on' : 'off';
+ $config['installedpackages']['pfblockerngglobal']['hostlookup'] = $_POST['hostlookup'] ? 'on' : 'off';
+ if (is_numeric($_POST['pfbdenycnt']))
+ $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'] = $_POST['pfbdenycnt'];
+ if (is_numeric($_POST['pfbpermitcnt']))
+ $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'] = $_POST['pfbpermitcnt'];
+ if (is_numeric($_POST['pfbmatchcnt']))
+ $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'] = $_POST['pfbmatchcnt'];
+
+ write_config("pfBlockerNG pkg: updated ALERTS tab settings.");
+ header("Location: " . $_SERVER['PHP_SELF']);
+ exit;
+}
+
+if (is_array($config['installedpackages']['pfblockerngglobal'])) {
+ $alertrefresh = $config['installedpackages']['pfblockerngglobal']['alertrefresh'];
+ $hostlookup = $config['installedpackages']['pfblockerngglobal']['hostlookup'];
+ $pfbdenycnt = $config['installedpackages']['pfblockerngglobal']['pfbdenycnt'];
+ $pfbpermitcnt = $config['installedpackages']['pfblockerngglobal']['pfbpermitcnt'];
+ $pfbmatchcnt = $config['installedpackages']['pfblockerngglobal']['pfbmatchcnt'];
+}
+
+// Collect pfBlockerNG Firewall Rules
+if (!empty($results)) {
+ foreach ($results as $result) {
+
+ # Find Rule Descriptions
+ $descr = "";
+ if (preg_match("/USER_RULE: (\w+)/",$result,$desc))
+ $descr = $desc[1];
+
+ if ($pfb['pfsenseversion'] >= '2.2') {
+ preg_match ("/@(\d+)\(/",$result, $rule);
+ } else {
+ preg_match ("/@(\d+)\s/",$result, $rule);
+ }
+
+ $id = $rule[1];
+ # Create array of Rule Description and pfctl Rule Number
+ $rule_list['id'][] = $id;
+ $rule_list[$id]['name'] = $descr;
+ }
+}
+
+// Add IP to the Suppression Alias
+if (isset($_POST['addsuppress'])) {
+ $ip = "";
+ if (isset($_POST['ip'])) {
+ $ip = $_POST['ip'];
+ $table = $_POST['table'];
+ $descr = $_POST['descr'];
+ $cidr = $_POST['cidr'];
+
+ // If Description or CIDR field is empty, exit.
+ if (empty($descr) || empty($cidr)) {
+ header("Location: " . $_SERVER['PHP_SELF']);
+ exit;
+ }
+
+ if (is_ipaddr($ip)) {
+
+ $savemsg1 = "Host IP address {$ip}";
+ if (is_ipaddrv4($ip)) {
+ $iptrim1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.0/24', $ip);
+ $iptrim2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$1.$2.$3.', $ip);
+ $iptrim3 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$4', $ip);
+
+ if ($cidr == "32") {
+ $pfb_pfctl = exec ("/sbin/pfctl -t {$table} -T show | grep {$iptrim1} 2>&1");
+
+ if ($pfb_pfctl == "") {
+ $savemsg2 = " : Removed /32 entry";
+ exec ("/sbin/pfctl -t {$table} -T delete {$ip}");
+ } else {
+ $savemsg2 = " : Removed /24 entry, added 254 addr";
+ exec ("/sbin/pfctl -t {$table} -T delete {$iptrim1}");
+ for ($add_ip=0; $add_ip <= 255; $add_ip++){
+ if ($add_ip != $iptrim3) {
+ exec ("/sbin/pfctl -t {$table} -T add {$iptrim2}{$add_ip}");
+ }
+ }
+ }
+ } else {
+ $cidr = 24;
+ $savemsg2 = " : Removed /24 entry";
+ exec ("/sbin/pfctl -t {$table} -T delete {$iptrim1} 2>&1", $pfb_pfctl);
+ if (!preg_grep("/1\/1 addresses deleted/", $pfb_pfctl)) {
+ $savemsg2 = " : Removed all entries";
+ // Remove 0-255 IP Address from Alias Table
+ for ($del_ip=0; $del_ip <= 255; $del_ip++){
+ exec ("/sbin/pfctl -t {$table} -T delete {$iptrim2}{$del_ip}");
+ }
+ }
+ }
+ }
+
+ // Collect pfBlockerNGSuppress Alias Contents
+ $pfb_sup_list = array();
+ $pfb_sup_array = array();
+ $pfb['found'] = FALSE;
+ $pfb['update'] = FALSE;
+ if (is_array($config['aliases']['alias'])) {
+ foreach ($config['aliases']['alias'] as $alias) {
+ if ($alias['name'] == "pfBlockerNGSuppress") {
+ $data = $alias['address'];
+ $data2 = $alias['detail'];
+ $arr1 = explode(" ",$data);
+ $arr2 = explode("||",$data2);
+
+ if (!empty($data)) {
+ $row = 0;
+ foreach ($arr1 as $host) {
+ $pfb_sup_list[] = $host;
+ $pfb_sup_array[$row]['host'] = $host;
+ $row++;
+ }
+ $row = 0;
+ foreach ($arr2 as $detail) {
+ $pfb_sup_array[$row]['detail'] = $detail;
+ $row++;
+ }
+ }
+ $pfb['found'] = TRUE;
+ }
+ }
+ }
+
+ // Call Function to Create Suppression Alias if not found.
+ if (!$pfb['found'])
+ pfb_create_suppression_alias();
+
+ // Save New Suppress IP to pfBlockerNGSuppress Alias
+ if (in_array($ip . '/' . $cidr, $pfb_sup_list)) {
+ $savemsg = gettext("Host IP address {$ip} already exists in the pfBlockerNG Suppress Table.");
+ } else {
+ if (!$pfb['found'] && empty($pfb_sup_list)) {
+ $next_id = 0;
+ } else {
+ $next_id = count($pfb_sup_list);
+ }
+ $pfb_sup_array[$next_id]['host'] = $ip . '/' . $cidr;
+ $pfb_sup_array[$next_id]['detail'] = $descr;
+
+ $address = "";
+ $detail = "";
+ foreach ($pfb_sup_array as $pfb_sup) {
+ $address .= $pfb_sup['host'] . " ";
+ $detail .= $pfb_sup['detail'] . "||";
+ }
+
+ // Find pfBlockerNGSuppress Array ID Number
+ if (is_array($config['aliases']['alias'])) {
+ $pfb_id = 0;
+ foreach ($config['aliases']['alias'] as $alias) {
+ if ($alias['name'] == "pfBlockerNGSuppress") {
+ break;
+ }
+ $pfb_id++;
+ }
+ }
+
+ $config['aliases']['alias'][$pfb_id]['address'] = rtrim($address, " ");
+ $config['aliases']['alias'][$pfb_id]['detail'] = rtrim($detail, "||");
+ $savemsg = gettext($savemsg1) . gettext($savemsg2) . gettext(" and added Host to the pfBlockerNG Suppress Table.");
+ $pfb['update'] = TRUE;
+ }
+
+ if ($pfb['found'] || $pfb['update']) {
+ // Save all Changes to pfsense config file
+ write_config();
+ }
+ }
+ }
+}
+
+// Auto-Resolve Hostnames
+if (isset($_REQUEST['getpfhostname'])) {
+ $getpfhostname = htmlspecialchars($_REQUEST['getpfhostname']);
+ $hostname = htmlspecialchars(gethostbyaddr($getpfhostname), ENT_QUOTES);
+ if ($hostname == $getpfhostname) {
+ $hostname = 'unknown';
+ }
+ echo $hostname;
+ die;
+}
+
+
+// Host Resolve Function lookup
+function getpfbhostname($type = 'src', $hostip, $countme = 0) {
+ $hostnames['src'] = '';
+ $hostnames['dst'] = '';
+ $hostnames[$type] = '<div id="gethostname_' . $countme . '" name="' . $hostip . '"></div>';
+ return $hostnames;
+}
+
+
+// Determine if Alert Host 'Dest' is within the Local Lan IP Range.
+function check_lan_dest($lan_ip,$lan_mask,$dest_ip,$dest_mask="32") {
+ $result = check_subnets_overlap($lan_ip, $lan_mask, $dest_ip, $dest_mask);
+ return $result;
+}
+
+
+$pgtitle = gettext("pfBlockerNG: Alerts");
+include_once("head.inc");
+?>
+<body link="#000000" vlink="#0000CC" alink="#000000">
+<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
+<input type="hidden" name="ip" id="ip" value=""/>
+<input type="hidden" name="table" id="table" value=""/>
+<input type="hidden" name="descr" id="descr" value=""/>
+<input type="hidden" name="cidr" id="cidr" value=""/>
+<?php
+
+include_once("fbegin.inc");
+
+/* refresh every 60 secs */
+if ($alertrefresh == 'on')
+ echo "<meta http-equiv=\"refresh\" content=\"60;url={$_SERVER['PHP_SELF']}\" />\n";
+if ($savemsg) {
+ print_info_box($savemsg);
+}
+
+?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <?php
+ $tab_array = array();
+ $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml&amp;id=0");
+ $tab_array[] = array(gettext("Update"), false, "/pfblockerng/pfblockerng_update.php");
+ $tab_array[] = array(gettext("Alerts"), true, "/pfblockerng/pfblockerng_alerts.php");
+ $tab_array[] = array(gettext("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0");
+ $tab_array[] = array(gettext("IPv4"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml");
+ $tab_array[] = array(gettext("IPv6"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml");
+ $tab_array[] = array(gettext("Top 20"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0");
+ $tab_array[] = array(gettext("Africa"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0");
+ $tab_array[] = array(gettext("Asia"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0");
+ $tab_array[] = array(gettext("Europe"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0");
+ $tab_array[] = array(gettext("N.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0");
+ $tab_array[] = array(gettext("Oceania"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0");
+ $tab_array[] = array(gettext("S.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0");
+ $tab_array[] = array(gettext("P.S."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&id=0");
+ $tab_array[] = array(gettext("Logs"), false, "/pfblockerng/pfblockerng_log.php");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0");
+ display_top_tabs($tab_array, true);
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td><div id="mainarea">
+ <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="6">
+ <tr>
+ <td colspan="3" class="vncell" align="left"><?php echo gettext("LINKS :"); ?>&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;
+ <a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br /></td>
+ </tr>
+ <tr>
+ <td width="10%" class="vncell"><?php echo gettext('Alert Settings'); ?></td>
+ <td width="90%" class="vtable">
+ <input name="pfbdenycnt" type="text" class="formfld unknown" id="pdbdenycnt" size="1" title="Enter the number of 'Deny' Alerts to Show" value="<?=htmlspecialchars($pfbdenycnt);?>"/>
+ <?php printf(gettext('%sDeny%s.&nbsp;&nbsp;') , '<strong>', '</strong>'); ?>
+ <input name="pfbpermitcnt" type="text" class="formfld unknown" id="pdbpermitcnt" size="1" title="Enter the number of 'Permit' Alerts to Show" value="<?=htmlspecialchars($pfbpermitcnt);?>"/>
+ <?php printf(gettext('%sPermit%s.&nbsp;&nbsp;'), '<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" 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" 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;
+ <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("Currently Suppressing &nbsp; %s$pfbsupp_cnt%s &nbsp; Hosts."), '<strong>', '</strong>');?>
+ </td>
+ </tr>
+<!--Create Three Output Windows 'Deny', 'Permit' and 'Match'-->
+<?php foreach (array ("Deny" => $pfb['denydir'] . " " . $pfb['nativedir'], "Permit" => $pfb['permitdir'], "Match" => $pfb['matchdir']) as $type => $pfbfolder ):
+ switch($type) {
+ case "Deny":
+ $rtype = "block";
+ $pfbentries = "{$pfbdenycnt}";
+ break;
+ case "Permit":
+ $rtype = "pass";
+ $pfbentries = "{$pfbpermitcnt}";
+ break;
+ case "Match":
+ if ($pfb['pfsenseversion'] >= '2.2') {
+ $rtype = "unkn(%u)";
+ } else {
+ $rtype = "unkn(11)";
+ }
+ $pfbentries = "{$pfbmatchcnt}";
+ break;
+ }
+
+?>
+ <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="6">
+ <tr>
+ <!--Print Table Info-->
+ <td colspan="2" class="listtopic"><?php printf(gettext("&nbsp;{$type}&nbsp;&nbsp; - &nbsp; Last %s Alert Entries."), "{$pfbentries}"); ?>
+ <?php if ($pfb['pfsenseversion'] >= '2.2'): ?>
+ <?php if (!is_array($config['syslog']) || !array_key_exists("reverse", $config['syslog'])): ?>
+ &nbsp;&nbsp;<?php echo gettext("Firewall Logs must be in Reverse Order."); ?>
+ <?php endif; ?>
+ <?php else: ?>
+ &nbsp;&nbsp;<?php echo gettext("Firewall Rule changes can unsync these Alerts."); ?>
+ <?php if (!is_array($config['syslog']) || !array_key_exists("reverse", $config['syslog'])): ?>
+ &nbsp;&nbsp;<?php echo gettext("Firewall Logs must be in Reverse Order."); ?>
+ <?php endif; ?>
+ <?php endif; ?>
+ </td>
+ </tr>
+
+<td width="100%" colspan="2">
+<table id="pfbAlertsTable" style="table-layout: fixed;" width="100%" class="sortable" border="0" cellpadding="0" cellspacing="0">
+ <colgroup>
+ <col width="8%" align="center" axis="date">
+ <col width="6%" align="center" axis="string">
+ <col width="16%" align="center" axis="string">
+ <col width="6%" align="center" axis="string">
+ <col width="20%" align="center" axis="string">
+ <col width="20%" align="center" axis="string">
+ <col width="3%" align="center" axis="string">
+ <col width="13%" align="center" axis="string">
+ </colgroup>
+ <thead>
+ <tr class="sortableHeaderRowIdentifier">
+ <th class="listhdrr" axis="date"><?php echo gettext("Date"); ?></th>
+ <th class="listhdrr" axis="string"><?php echo gettext("IF"); ?></th>
+ <th class="listhdrr" axis="string"><?php echo gettext("Rule"); ?></th>
+ <th class="listhdrr" axis="string"><?php echo gettext("Proto"); ?></th>
+ <th class="listhdrr" axis="string"><?php echo gettext("Source"); ?></th>
+ <th class="listhdrr" axis="string"><?php echo gettext("Destination"); ?></th>
+ <th class="listhdrr" axis="string"><?php echo gettext("CC"); ?></th>
+ <th class="listhdrr" axis="string"><?php echo gettext("List"); ?></th>
+ </tr>
+ </thead>
+ <tbody>
+<?php
+
+$pfb['runonce'] = TRUE;
+if (isset($pfb['load']))
+ $pfb['runonce'] = FALSE;
+
+// Execute the following once per refresh
+if ($pfb['runonce']) {
+ $pfb['load'] = TRUE;
+ $fields_array = array();
+
+ // pfSense versions below 2.2 have the Logfiles in two lines.
+ if ($pfb['pfsenseversion'] >= '2.2') {
+ $pfblines = exec("/usr/bin/grep -c ^ {$filter_logfile}");
+ } else {
+ $pfblines = (exec("/usr/bin/grep -c ^ {$filter_logfile}") /2 );
+ }
+ $fields_array = conv_log_filter($filter_logfile, $pfblines, $pfblines);
+
+ $continents = array('pfB_Africa','pfB_Antartica','pfB_Asia','pfB_Europe','pfB_NAmerica','pfB_Oceania','pfB_SAmerica','pfB_Top');
+
+ $supp_ip_txt .= "Clicking this Suppression Icon, will immediately remove the Block.\n\nSuppressing a /32 CIDR is better than Suppressing the full /24";
+ $supp_ip_txt .= " CIDR.\nThe Host will be added to the pfBlockerNG Suppress Alias Table.\n\nOnly 32 or 24 CIDR IPs can be Suppressed with the '+' Icon.";
+ $supp_ip_txt .= "\nTo manually add Host(s), edit the 'pfBlockerNGSuppress' Alias in the Alias Tab.\nManual entries will not remove existing Blocked Hosts";
+
+ // Array of all Local IPs for Alert Analysis
+ $pfb_local = array();
+
+ // Collect Gateway IP Addresses for Inbound/Outbound List matching
+ $int_gateway = get_interfaces_with_gateway();
+ if (is_array($int_gateway)) {
+ foreach ($int_gateway as $gateway) {
+ $convert = get_interface_ip($gateway);
+ $pfb_local[] = $convert;
+ }
+ }
+
+ // Collect Virtual IP Aliases for Inbound/Outbound List Matching
+ if (is_array($config['virtualip']['vip'])) {
+ foreach ($config['virtualip']['vip'] as $list) {
+ $pfb_local[] = $list['subnet'];
+ }
+ }
+ // Collect NAT IP Addresses for Inbound/Outbound List Matching
+ if (is_array($config['nat']['rule'])) {
+ foreach ($config['nat']['rule'] as $natent) {
+ $pfb_local[] = $natent['target'];
+ }
+ }
+
+ // Collect 1:1 NAT IP Addresses for Inbound/Outbound List Matching
+ if(is_array($config['nat']['onetoone'])) {
+ foreach ($config['nat']['onetoone'] as $onetoone) {
+ $pfb_local[] = $onetoone['source']['address'];
+ }
+ }
+
+ // Convert any 'Firewall Aliases' to IP Address Format
+ if (is_array($config['aliases']['alias'])) {
+ for ($cnt = 0; $cnt <= count($pfb_local); $cnt++) {
+ foreach ($config['aliases']['alias'] as $i=> $alias) {
+ if (isset($alias['name']) && isset($pfb_local[$cnt])) {
+ if ($alias['name'] == $pfb_local[$cnt]) {
+ $pfb_local[$cnt] = $alias['address'];
+ }
+ }
+ }
+ }
+ }
+ // Remove any Duplicate IPs
+ $pfb_local = array_unique($pfb_local);
+
+ // Determine Lan IP Address and Mask
+ if (is_array($config['interfaces']['lan'])) {
+ $lan_ip = $config['interfaces']['lan']['ipaddr'];
+ $lan_mask = $config['interfaces']['lan']['subnet'];
+ }
+}
+
+$counter = 0;
+// Process Fields_array and generate Output
+if (!empty($fields_array)) {
+ foreach ($fields_array as $fields) {
+ $rulenum = "";
+ $alert_ip = "";
+ $supp_ip = "";
+ $pfb_query = "";
+
+ $rulenum = $fields['rulenum'];
+ if ($fields['act'] == $rtype && !empty($rule_list) && in_array($rulenum, $rule_list['id']) && $counter < $pfbentries) {
+
+ // Skip Repeated Events
+ if (($fields['dstip'] . $fields['dstport']) == $previous_dstip || ($fields['srcip'] . $fields['srcport']) == $previous_srcip) {
+ continue;
+ }
+
+ $proto = str_replace("TCP", "TCP-", $fields['proto']) . $fields['tcpflags'];
+
+ // Cleanup Port Output
+ if ($fields['proto'] == "ICMP") {
+ $srcport = $fields['srcport'];
+ $dstport = $fields['dstport'];
+ } else {
+ $srcport = " :" . $fields['srcport'];
+ $dstport = " :" . $fields['dstport'];
+ }
+
+ // Don't add Suppress Icon to Country Block Lines
+ if (in_array(substr($rule_list[$rulenum]['name'], 0, -3), $continents)) {
+ $pfb_query = "Country";
+ }
+
+ // Add DNS Resolve and Suppression Icons to External IPs only. GeoIP Code to External IPs only.
+ if (in_array($fields['dstip'], $pfb_local) || check_lan_dest($lan_ip,$lan_mask,$fields['dstip'],"32")) {
+ // Destination is Gateway/NAT/VIP
+ $rule = $rule_list[$rulenum]['name'] . "<br />(" . $rulenum .")";
+ $host = $fields['srcip'];
+
+ if (is_ipaddrv4($host)) {
+ $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2);
+ } else {
+ $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2);
+ }
+
+ $alert_ip .= "<a href='/pfblockerng/pfblockerng_diag_dns.php?host={$host}' title=\" " . gettext("Resolve host via Rev. DNS lookup");
+ $alert_ip .= "\"> <img src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" width=\"11\" height=\"11\" border=\"0\" ";
+ $alert_ip .= "alt=\"Icon Reverse Resolve with DNS\" style=\"cursor: pointer;\"/></a>";
+
+ if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") {
+ $supp_ip .= "<input type='image' name='addsuppress[]' onclick=\"hostruleid('{$host}','{$rule_list[$rulenum]['name']}');\" ";
+ $supp_ip .= "src=\"../themes/{$g['theme']}/images/icons/icon_plus.gif\" title=\"";
+ $supp_ip .= gettext($supp_ip_txt) . "\" border=\"0\" width='11' height='11'/>";
+ }
+
+ if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") {
+ $hostname = getpfbhostname('src', $fields['srcip'], $counter);
+ } else {
+ $hostname = "";
+ }
+
+ $src_icons = $alert_ip . "&nbsp;" . $supp_ip . "&nbsp;";
+ $dst_icons = "";
+ $scc = $country;
+ $dcc = "";
+ } else {
+ // Outbound
+ $rule = $rule_list[$rulenum]['name'] . "<br />(" . $rulenum .")";
+ $host = $fields['dstip'];
+
+ if (is_ipaddrv4($host)) {
+ $country = substr(exec("$pathgeoip -f $pathgeoipdat $host"),23,2);
+ } else {
+ $country = substr(exec("$pathgeoip6 -f $pathgeoipdat6 $host"),26,2);
+ }
+
+ $alert_ip .= "<a href='/pfblockerng/pfblockerng_diag_dns.php?host={$host}' title=\"" . gettext("Resolve host via Rev. DNS lookup");
+ $alert_ip .= "\"> <img src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" width=\"11\" height=\"11\" border=\"0\" ";
+ $alert_ip .= "alt=\"Icon Reverse Resolve with DNS\" style=\"cursor: pointer;\"/></a>";
+
+ if ($pfb_query != "Country" && $rtype == "block" && $pfb['supp'] == "on") {
+ $supp_ip .= "<input type='image' name='addsuppress[]' onclick=\"hostruleid('{$host}','{$rule_list[$rulenum]['name']}');\" ";
+ $supp_ip .= "src=\"../themes/{$g['theme']}/images/icons/icon_plus.gif\" title=\"";
+ $supp_ip .= gettext($supp_ip_txt) . "\" border=\"0\" width='11' height='11'/>";
+ }
+
+ if ($pfb_query != "Country" && $rtype == "block" && $hostlookup == "on") {
+ $hostname = getpfbhostname('dst', $fields['dstip'], $counter);
+ } else {
+ $hostname = "";
+ }
+
+ $src_icons = "";
+ $dst_icons = $alert_ip . "&nbsp;" . $supp_ip . "&nbsp;";
+ $scc = "";
+ $dcc = $country;
+ }
+
+ # IP Query Grep Exclusion
+ $pfb_ex1 = "grep -v 'pfB\_\|\_v6\.txt'";
+ $pfb_ex2 = "grep -v 'pfB\_\|/32\|/24\|\_v6\.txt' | grep -m1 '/'";
+
+ // Find List which contains Blocked IP Host
+ if ($pfb_query == "Country") {
+ # Skip
+ } else {
+ // Search for exact IP Match
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host);
+ $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' | {$pfb_ex1}");
+ // Search for IP in /24 CIDR
+ if (empty($pfb_query)) {
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.0/24\'', $host);
+ $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}");
+ }
+ // Search for First Two IP Octets in CIDR Matches Only. Skip any pfB (Country Lists) or /32,/24 Addresses.
+ if (empty($pfb_query)) {
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host);
+ $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
+ }
+ // Search for First Two IP Octets in CIDR Matches Only (Subtract 1 from second Octet on each loop).
+ // Skip (Country Lists) or /32,/24 Addresses.
+ if (empty($pfb_query)) {
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.', $host);
+ $host2 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '$2', $host);
+ for ($cnt = 1; $cnt <= 5; $cnt++) {
+ $host3 = $host2 - $cnt . '\'';
+ $pfb_query = exec("grep -rH {$host1}{$host3} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
+ // Break out of loop if found.
+ if (!empty($pfb_query))
+ $cnt = 6;
+ }
+ }
+ // Search for First Three Octets
+ if (empty($pfb_query)) {
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.$3\.\'', $host);
+ $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
+ }
+ // Search for First Two Octets
+ if (empty($pfb_query)) {
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'^$1\.$2\.\'', $host);
+ $pfb_query = exec("grep -rH {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex2}");
+ }
+ // Report Specific ET IQRisk Details
+ if ($pfb['et_header'] && preg_match("/{$et_header}/", $pfb_query)) {
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1\.$2\.$3\.$4\'', $host);
+ $pfb_query = exec("grep -Hm1 {$host1} {$pfb['etdir']}/* | sed -e 's/^.*[a-zA-Z]\///' -e 's/:.*//' -e 's/\..*/ /' -e 's/ET_/ET IPrep /' ");
+ if (empty($pfb_query)) {
+ $host1 = preg_replace("/(\d{1,3})\.(\d{1,3}).(\d{1,3}).(\d{1,3})/", '\'$1.$2.$3.0/24\'', $host);
+ $pfb_query = exec("grep -rHm1 {$host1} {$pfbfolder} | sed -e 's/^.*[a-zA-Z]\///' -e 's/\.txt:/ /' | {$pfb_ex1}");
+ }
+ }
+ // Default to "No Match" if not found.
+ if (empty($pfb_query))
+ $pfb_query = "No Match";
+ }
+
+ # Split List Column into Two lines.
+ unset ($pfb_match);
+ if ($pfb_query == "No Match") {
+ $pfb_match[1] = "{$pfb_query}";
+ $pfb_match[2] = "";
+ } else {
+ preg_match ("/(.*)\s(.*)/", $pfb_query, $pfb_match);
+ if ($pfb_match[1] == "") {
+ $pfb_match[1] = "{$pfb_query}";
+ $pfb_match[2] = "";
+ }
+ }
+
+ // Print Alternating Line Shading
+ if ($pfb['pfsenseversion'] > '2.0') {
+ $alertRowEvenClass = "listMReven";
+ $alertRowOddClass = "listMRodd";
+ } else {
+ $alertRowEvenClass = "listr";
+ $alertRowOddClass = "listr";
+ }
+
+ // Collect Details for Repeated Alert Comparison
+ $previous_srcip = $fields['srcip'] . $fields['srcport'];
+ $previous_dstip = $fields['dstip'] . $fields['dstport'];
+ $countrycode = trim($scc . $dcc);
+
+ $alertRowClass = $counter % 2 ? $alertRowEvenClass : $alertRowOddClass;
+ echo "<tr class='{$alertRowClass}'>
+ <td class='listMRr' align='center'>{$fields['time']}</td>
+ <td class='listMRr' align='center'>{$fields['interface']}</td>
+ <td class='listMRr' align='center' title='The pfBlockerNG Rule that Blocked this Host.'>{$rule}</td>
+ <td class='listMRr' align='center'>{$proto}</td>
+ <td nowrap='nowrap' class='listMRr' align='center' style='sorttable_customkey:{$fields['srcip']};' sorttable_customkey='{$fields['srcip']}'>{$src_icons}{$fields['srcip']}{$srcport}<br /><small>{$hostname['src']}</small></td>
+ <td nowrap='nowrap' class='listMRr' align='center' style='sorttable_customkey:{$fields['dstip']};' sorttable_customkey='{$fields['dstip']}'>{$dst_icons}{$fields['dstip']}{$dstport}<br /><small>{$hostname['dst']}</small></td>
+ <td class='listMRr' align='center'>{$countrycode}</td>
+ <td class='listbg' align='center' title='Country Block Rules cannot be suppressed.\n\nTo allow a particular Country IP, either remove the particular Country or add the Host\nto a Permit Alias in the Firewall Tab.\n\nIf the IP is not listed beside the List, this means that the Block is a /32 entry.\nOnly /32 or /24 CIDR Hosts can be suppressed.\n\nIf (Duplication) Checking is not enabled. You may see /24 and /32 CIDR Blocks for a given blocked Host' style=\"font-size: 10px word-wrap:break-word;\">{$pfb_match[1]}<br />{$pfb_match[2]}</td></tr>";
+ $counter++;
+ if ($counter > 0 && $rtype == "block") {
+ $mycounter = $counter;
+ }
+ }
+ }
+}
+?>
+ </tbody>
+ </table>
+ </table>
+<?php endforeach; ?> <!--End - Create Three Output Windows 'Deny', 'Permit' and 'Match'-->
+</td></tr>
+</table>
+
+</div>
+</td>
+
+<script type="text/javascript">
+//<![CDATA[
+
+// This function stuffs the passed HOST, Table values into hidden Form Fields for postback.
+function hostruleid(host,table) {
+ document.getElementById("ip").value = host;
+ document.getElementById("table").value = table;
+
+ var description = prompt("Please enter Suppression Description");
+ document.getElementById("descr").value = description;
+
+ if (description.value != "") {
+ var cidr = prompt("Please enter CIDR [ 32 or 24 CIDR only supported ]","32");
+ document.getElementById("cidr").value = cidr;
+ }
+}
+
+// Auto-Resolve of Alerted Hostnames
+function findhostnames(counter) {
+ getip = jQuery('#gethostname_' + counter).attr('name');
+ geturl = "<?php echo $_SERVER['PHP_SELF']; ?>";
+ jQuery.get( geturl, { "getpfhostname": getip } )
+ .done(function( data ) {
+ jQuery('#gethostname_' + counter).prop('title' , data );
+ var str = data;
+ if(str.length > 32) str = str.substring(0,29)+"...";
+ jQuery('#gethostname_' + counter).html( str );
+ }
+ )
+}
+
+ var lines = <?php echo $mycounter; ?>;
+ for (i = 0; i < lines; i++) {
+ findhostnames(i);
+ }
+
+//]]>
+</script>
+<?php include("fend.inc"); ?>
+</form>
+</body>
+</html> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_diag_dns.php b/config/pfblockerng/pfblockerng_diag_dns.php
new file mode 100644
index 00000000..b2f07464
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_diag_dns.php
@@ -0,0 +1,318 @@
+<?php
+/*
+ pfBlockerNG_diag_dns.php
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Original Code by:
+ Copyright (C) 2009 Jim Pingle (jpingle@gmail.com)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$pgtitle = array(gettext("pfBlockerNG"),gettext("DNS/Threat Source Lookup"));
+require("guiconfig.inc");
+
+$host = trim($_REQUEST['host'], " \t\n\r\0\x0B[];\"'");
+$host_esc = escapeshellarg($host);
+
+if (is_array($config['aliases']['alias'])) {
+ $a_aliases = &$config['aliases']['alias'];
+} else {
+ $a_aliases = array();
+}
+$aliasname = str_replace(array(".","-"), "_", $host);
+$alias_exists = false;
+$counter=0;
+foreach($a_aliases as $a) {
+ if($a['name'] == $aliasname) {
+ $alias_exists = true;
+ $id=$counter;
+ }
+ $counter++;
+}
+
+# Collect pfSense Version
+$pfs_version = substr(trim(file_get_contents("/etc/version")), 0, 3);
+
+if ($pfs_version > '2.2') {
+ $cmd = '/usr/bin/drill';
+} else {
+ $cmd = '/usr/bin/dig';
+}
+
+
+if(isset($_POST['create_alias']) && (is_hostname($host) || is_ipaddr($host))) {
+ if($_POST['override'])
+ $override = true;
+ $resolved = gethostbyname($host);
+ $type = "hostname";
+ if($resolved) {
+ $resolved = array();
+ exec("{$cmd} {$host_esc} A | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved);
+ $isfirst = true;
+ foreach($resolved as $re) {
+ if($re <> "") {
+ if(!$isfirst)
+ $addresses .= " ";
+ $addresses .= rtrim($re) . "/32";
+ $isfirst = false;
+ }
+ }
+ $newalias = array();
+ if($override)
+ $alias_exists = false;
+ if($alias_exists == false) {
+ $newalias['name'] = $aliasname;
+ $newalias['type'] = "network";
+ $newalias['address'] = $addresses;
+ $newalias['descr'] = "Created from Diagnostics-> DNS Lookup";
+ if($override)
+ $a_aliases[$id] = $newalias;
+ else
+ $a_aliases[] = $newalias;
+ write_config();
+ $createdalias = true;
+ }
+ }
+}
+
+if ($_POST) {
+ unset($input_errors);
+
+ $reqdfields = explode(" ", "host");
+ $reqdfieldsn = explode(",", "Host");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
+
+ if (!is_hostname($host) && !is_ipaddr($host)) {
+ $input_errors[] = gettext("Host must be a valid hostname or IP address.");
+ } else {
+ // Test resolution speed of each DNS server.
+ $dns_speeds = array();
+ $dns_servers = array();
+ exec("/usr/bin/grep nameserver /etc/resolv.conf | /usr/bin/cut -f2 -d' '", $dns_servers);
+ foreach ($dns_servers as $dns_server) {
+ $query_time = exec("{$cmd} {$host_esc} " . escapeshellarg("@" . trim($dns_server)) . " | /usr/bin/grep Query | /usr/bin/cut -d':' -f2");
+ if($query_time == "")
+ $query_time = gettext("No response");
+ $new_qt = array();
+ $new_qt['dns_server'] = $dns_server;
+ $new_qt['query_time'] = $query_time;
+ $dns_speeds[] = $new_qt;
+ unset($new_qt);
+ }
+ }
+
+ $type = "unknown";
+ $resolved = "";
+ $ipaddr = "";
+ $hostname = "";
+ if (!$input_errors) {
+ if (is_ipaddr($host)) {
+ $type = "ip";
+ $resolved = gethostbyaddr($host);
+ $ipaddr = $host;
+ if ($host != $resolved)
+ $hostname = $resolved;
+ } elseif (is_hostname($host)) {
+ $type = "hostname";
+ $resolved = gethostbyname($host);
+ if($resolved) {
+ $resolved = array();
+ exec("{$cmd} {$host_esc} A | /usr/bin/grep {$host_esc} | /usr/bin/grep -v ';' | /usr/bin/awk '{ print $5 }'", $resolved);
+ }
+ $hostname = $host;
+ if ($host != $resolved)
+ $ipaddr = $resolved[0];
+ }
+
+ if ($host == $resolved) {
+ $resolved = gettext("No record found");
+ }
+ }
+}
+
+function display_host_results ($address,$hostname,$dns_speeds) {
+ $map_lengths = function($element) { return strlen($element[0]); };
+
+ echo gettext("IP Address") . ": {$address} \n";
+ echo gettext("Host Name") . ": {$hostname} \n";
+ echo "\n";
+ $text_table = array();
+ $text_table[] = array(gettext("Server"), gettext("Query Time"));
+ if (is_array($dns_speeds)) {
+ foreach ($dns_speeds as $qt) {
+ $text_table[] = array(trim($qt['dns_server']), trim($qt['query_time']));
+ }
+ }
+ $col0_padlength = max(array_map($map_lengths, $text_table)) + 4;
+ foreach ($text_table as $text_row) {
+ echo str_pad($text_row[0], $col0_padlength) . $text_row[1] . "\n";
+ }
+}
+
+include("head.inc"); ?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="/pfblockerng/pfblockerng_diag_dns.php" method="post" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"> <?=gettext("Resolve DNS hostname or IP");?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq"><?=gettext("Hostname or IP");?></td>
+ <td width="78%" class="vtable">
+ <?=$mandfldhtml;?>
+ <table>
+ <tr><td valign="top">
+ <input name="host" type="text" class="formfld" id="host" size="20" value="<?=htmlspecialchars($host);?>">
+ </td>
+ <td>
+ <?php if ($resolved && $type) { ?>
+ = <font size="+1">
+<?php
+ $found = 0;
+ if(is_array($resolved)) {
+ foreach($resolved as $hostitem) {
+ if($hostitem <> "") {
+ echo $hostitem . "<br/>";
+ $found++;
+ }
+ }
+ } else {
+ echo $resolved;
+ }
+ if($found > 0) { ?>
+ <br/><font size='-2'>
+ <?PHP if($alias_exists) { ?>
+ An alias already exists for the hostname <?= htmlspecialchars($host) ?>. <br />
+ <input type="hidden" name="override" value="true"/>
+ <input type="submit" name="create_alias" value="Overwrite Alias"/>
+ <?PHP } else {
+ if(!$createdalias) { ?>
+ <input type="submit" name="create_alias" value="Create Alias from These Entries"/>
+ <?PHP } else { ?>
+ Alias created with name <?= htmlspecialchars($newalias['name']) ?>
+ <?PHP }
+ }
+ }
+?>
+ <font size="-1">
+
+ <? } ?>
+ </td></tr></table>
+ </td>
+ </tr>
+<?php if($_POST): ?>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?=gettext("Resolution time per server");?></td>
+ <td width="78%" class="vtable">
+ <table width="170" border="1" cellpadding="2" style="border-width: 1px 1px 1px 1px; border-collapse: collapse;">
+ <tr>
+ <td>
+ <b><?=gettext("Server");?></b>
+ </td>
+ <td>
+ <b><?=gettext("Query time");?></b>
+ </td>
+ </tr>
+<?php
+ if(is_array($dns_speeds))
+ foreach($dns_speeds as $qt):
+?>
+ <tr>
+ <td>
+ <?=$qt['dns_server']?>
+ </td>
+ <td>
+ <?=$qt['query_time']?>
+ </td>
+ </tr>
+<?php
+ endforeach;
+?>
+ </table>
+ </td>
+ </tr>
+ <?php endif; ?>
+ <?php if (!$input_errors && $ipaddr) { ?>
+ <tr>
+
+ <td width="22%" valign="top" class="vncell"><?=gettext("More Information:");?></td>
+ <td width="78%" class="vtable">
+ <a target="_new" href ="/diag_ping.php?host=<?=htmlspecialchars($host)?>&interface=wan&count=3"><?=gettext("Ping");?></a> <br/>
+ <a target="_new" href ="/diag_traceroute.php?host=<?=htmlspecialchars($host)?>&ttl=18"><?=gettext("Traceroute");?></a>
+ <p/>
+ <?=gettext("NOTE: The following links are to external services, so their reliability cannot be guaranteed.");?><br/><br/>
+ <a target="_new" href="http://private.dnsstuff.com/tools/whois.ch?ip=<?php echo $ipaddr; ?>"><?=gettext("IP WHOIS @ DNS Stuff");?></a><br />
+ <a target="_new" href="http://private.dnsstuff.com/tools/ipall.ch?ip=<?php echo $ipaddr; ?>"><?=gettext("IP Info @ DNS Stuff");?></a>
+
+ <?=gettext("NOTE: The following links are to external services, so their reliability cannot be guaranteed.");?><br/><br/>
+ <a target="_new" href="http://kb.bothunter.net/ipInfo/nowait.php?IP=<?php echo $ipaddr; ?>"><?=gettext("BOTHunter");?></a><br/>
+ <a target="_new" href="http://www.ipvoid.com/scan/<?php echo $ipaddr; ?>/"><?=gettext("IPVOID");?></a><br/>
+ <a target="_new" href="http://www.tcpiputils.com/browse/ip-address/<?php echo $ipaddr; ?>/"><?=gettext("TCPUtils");?></a><br/>
+ <a target="_new" href="https://www.herdprotect.com/ip-address-<?php echo $ipaddr; ?>.aspx"><?=gettext("Herd Protect");?></a><br/>
+ <a target="_new" href="https://www.senderbase.org/lookup/ip/?search_string=<?php echo $ipaddr; ?>"><?=gettext("SenderBase");?></a><br/>
+ <a target="_new" href="http://www.ip-tracker.org/locator/ip-lookup.php?ip=<?php echo $ipaddr; ?>"><?=gettext("IP Tracker");?></a><br/>
+
+ <a target="_new" href="https://www.fortiguard.com/ip_rep/index.php?data=/<?php echo $ipaddr; ?>?"><?=gettext("FortiGuard");?></a><br/>
+ <a target="_new" href="https://www.projecthoneypot.org/ip_<?php echo $ipaddr; ?>"><?=gettext("Project HoneyPot");?></a><br/>
+ <a target="_new" href="https://www.virustotal.com/en/ip-address/<?php echo $ipaddr; ?>/information"><?=gettext("VirusTotal Info");?></a><br/>
+ <a target="_new" href="https://www.mcafee.com/threat-intelligence/ip/default.aspx?ip=<?php echo $ipaddr; ?>"><?=gettext("McAfee Threat Center");?></a><br/>
+ <a target="_new" href="http://sitecheck2.sucuri.net/results/<?php echo $ipaddr; ?>"><?=gettext("Securi SiteCheck");?></a><br/>
+ <a target="_new" href="https://www.dshield.org/ipinfo.html?IP=<?php echo $ipaddr; ?>"><?=gettext("DShield Threat Lookup");?></a><br/>
+ <a target="_new" href="https://isc.sans.edu/ipinfo.html?ip=<?php echo $ipaddr; ?>"><?=gettext("Internet Storm Center");?></a><br/>
+ <a target="_new" href="https://www.mywot.com/en/scorecard/<?php echo $ipaddr; ?>"><?=gettext("Web of Trust (WOT) Scorecard");?></a><br/>
+ <a target="_new" href="https://quttera.com/sitescan/<?php echo $ipaddr; ?>"><?=gettext("Quattera");?></a><br/>
+ <a target="_new" href="https://www.iblocklist.com/search.php?string=<?php echo $ipaddr; ?>"><?=gettext("I-Block List");?></a><br/>
+ <p/>
+ <?=gettext("NOTE: Mail Server DNSRBL Lookups");?><br/><br/>
+ <a target="_new" href="https://senderscore.org/lookup.php?lookup=<?php echo $ipaddr; ?>&ipLookup=Go"><?=gettext("SenderScore");?></a><br/>
+ <a target="_new" href="http://www.spamhaus.org/query/bl?ip=<?php echo $ipaddr; ?>"><?=gettext("Spamhaus Blocklist");?></a><br/>
+ <a target="_new" href="http://www.spamcop.net/w3m?action=checkblock&ip=<?php echo $ipaddr; ?>"><?=gettext("SPAMcop Blocklist");?></a><br/>
+ <a target="_new" href="http://multirbl.valli.org/lookup/<?php echo $ipaddr; ?>.html"><?=gettext("multirbl RBL Lookup");?></a><br/>
+ <a target="_new" href="http://mxtoolbox.com/SuperTool.aspx?action=blacklist%3a<?php echo $ipaddr; ?>&run=toolpage"><?=gettext("MXToolbox");?></a><br/>
+
+ </td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <br/>&nbsp;
+ <input name="Submit" type="submit" class="formbtn" value="<?=gettext("DNS Lookup");?>">
+ </td>
+ </tr>
+ </table>
+</td></tr></table>
+</form>
+<?php include("fend.inc"); ?> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_log.php b/config/pfblockerng/pfblockerng_log.php
new file mode 100644
index 00000000..74f513a2
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_log.php
@@ -0,0 +1,428 @@
+<?php
+/*
+ pfBlockerNG_Log.php
+
+ pfBlockerNG
+ Copyright (c) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Portions of this code are based on original work done for the
+ Snort package for pfSense from the following contributors:
+
+ Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>.
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ Copyright (C) 2006 Scott Ullrich
+ Copyright (C) 2009 Robert Zelaya Sr. Developer
+ Copyright (C) 2012 Ermal Luci
+ All rights reserved.
+
+ Adapted for Suricata by:
+ Copyright (C) 2014 Bill Meeks
+ All rights reserved.
+
+ Javascript and Integration modifications by J. Nieuwenhuizen
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("guiconfig.inc");
+require_once("globals.inc");
+require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+
+pfb_global();
+
+# Get log files from directory
+function getlogs($logdir, $log_extentions = array('log')) {
+ if (!is_array($log_extentions)) {
+ $log_extentions = array($log_extentions);
+ }
+
+ # Get logfiles
+ $log_filenames = array();
+ foreach ($log_extentions as $extention) {
+ if ($extention <> '*') {
+ $log_filenames = array_merge($log_filenames, glob($logdir . "*." . $extention));
+ } else {
+ $log_filenames = array_merge($log_filenames, glob($logdir . "*"));
+ }
+ }
+
+ # Convert to filenames only
+ if (count($log_filenames) > 0) {
+ $log_totalfiles = count($log_filenames);
+ for ($cnt = 0; $cnt < $log_totalfiles; $cnt++) {
+ $log_filenames[$cnt] = basename($log_filenames[$cnt]);
+ }
+ }
+
+ # Sort the filename
+ asort($log_filenames);
+
+ # Done
+ return $log_filenames;
+}
+
+# Define logtypes
+# name => Displayname of the type
+# ext => Log extentions (array for multiple extentions)
+# logdir=> Log directory
+# clear => Add clear button (TRUE/FALSE)
+$pfb_logtypes = array( 'defaultlogs' => array('name' => 'Log Files',
+ 'logdir' => "{$pfb['logdir']}/",
+ 'logs' => array("pfblockerng.log", "error.log", "geoip.log", "maxmind_ver"),
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
+ 'masterfiles' => array('name' => 'Masterfiles',
+ 'logdir' => "{$pfb['dbdir']}/",
+ 'logs' => array("masterfile", "mastercat"),
+ 'download' => TRUE,
+ 'clear' => FALSE
+ ),
+ 'originallogs' => array('name' => 'Original Files',
+ 'ext' => array('orig', 'raw'),
+ 'logdir' => "{$pfb['origdir']}/",
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
+ 'denylogs' => array('name' => 'Deny Files',
+ 'ext' => 'txt',
+ 'txt' => 'deny',
+ 'logdir' => "{$pfb['denydir']}/",
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
+ 'permitlogs' => array('name' => 'Permit Files',
+ 'ext' => 'txt',
+ 'txt' => 'permit',
+ 'logdir' => "{$pfb['permitdir']}/",
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
+ 'matchlogs' => array('name' => 'Match Files',
+ 'ext' => 'txt',
+ 'txt' => 'match',
+ 'logdir' => "{$pfb['matchdir']}/",
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
+ 'nativelogs' => array('name' => 'Native Files',
+ 'ext' => 'txt',
+ 'logdir' => "{$pfb['nativedir']}/",
+ 'download' => TRUE,
+ 'clear' => TRUE
+ ),
+ 'aliaslogs' => array('name' => 'Alias Files',
+ 'ext' => 'txt',
+ 'logdir' => "{$pfb['aliasdir']}/",
+ 'download' => TRUE,
+ 'clear' => FALSE
+ ),
+ 'etiprep' => array('name' => 'ET IPRep Files',
+ 'ext' => '*',
+ 'logdir' => "{$pfb['etdir']}/",
+ 'download' => TRUE,
+ 'clear' => FALSE
+ ),
+ 'country' => array('name' => 'Country Files',
+ 'ext' => 'txt',
+ 'logdir' => "{$pfb['ccdir']}/",
+ 'download' => TRUE,
+ 'clear' => FALSE
+ )
+ );
+
+# Check logtypes
+$logtypeid = 'defaultlogs';
+if (isset($_POST['logtype'])) {
+ $logtypeid = $_POST['logtype'];
+} elseif (isset($_GET['logtype'])) {
+ $logtypeid = htmlspecialchars($_GET['logtype']);
+}
+
+# Check if POST has been set
+if (isset($_POST['file'])) {
+ clearstatcache();
+ $pfb_logfilename = $_POST['file'];
+ $pfb_ext = pathinfo($pfb_logfilename, PATHINFO_EXTENSION);
+
+ # Load log
+ if ($_POST['action'] == 'load') {
+ if (!is_file($pfb_logfilename)) {
+ echo "|3|" . gettext("Log file is empty or does not exist") . ".|";
+ } else {
+ $data = file_get_contents($pfb_logfilename);
+ if ($data === false) {
+ echo "|1|" . gettext("Failed to read log file") . ".|";
+ } else {
+ $data = base64_encode($data);
+ echo "|0|" . $pfb_logfilename . "|" . $data . "|";
+ }
+ }
+ exit;
+ }
+}
+
+if (isset($_POST['logFile'])) {
+ $s_logfile = $_POST['logFile'];
+
+ # Clear selected file
+ if (isset($_POST['clear'])) {
+ unlink_if_exists($s_logfile);
+ }
+
+ # Download log
+ if (isset($_POST['download'])) {
+ if (file_exists($s_logfile)) {
+ ob_start(); //important or other posts will fail
+ if (isset($_SERVER['HTTPS'])) {
+ header('Pragma: ');
+ header('Cache-Control: ');
+ } else {
+ header("Pragma: private");
+ header("Cache-Control: private, must-revalidate");
+ }
+ header("Content-Type: application/octet-stream");
+ header("Content-length: " . filesize($s_logfile));
+ header("Content-disposition: attachment; filename = " . basename($s_logfile));
+ ob_end_clean(); //important or other post will fail
+ readfile($s_logfile);
+ }
+ }
+} else {
+ $s_logfile = "";
+}
+
+$pgtitle = gettext("pfBlockerNG: Log Browser");
+include_once("head.inc");
+?>
+
+<body link="#000000" vlink="#0000CC" alink="#000000">
+
+<?php
+include_once("fbegin.inc");
+if ($input_errors) {
+ print_input_errors($input_errors);
+}
+?>
+<script type="text/javascript" src="/javascript/base64.js"></script>
+<script type="text/javascript">
+//<![CDATA[
+
+ function loadFile() {
+ jQuery("#fileStatus").html("<?=gettext("Loading file"); ?> ...");
+ jQuery("#fileStatusBox").show(250);
+ jQuery("#filePathBox").show(250);
+ jQuery("#fbTarget").html("");
+
+ jQuery.ajax(
+ "<?=$_SERVER['SCRIPT_NAME'];?>", {
+ type: 'POST',
+ data: "instance=" + jQuery("#instance").val() + "&action=load&file=" + jQuery("#logFile").val(),
+ complete: loadComplete
+ }
+ )
+ }
+
+ function loadComplete(req) {
+ jQuery("#fileContent").show(250);
+ var values = req.responseText.split("|");
+ values.shift(); values.pop();
+
+ if(values.shift() == "0") {
+ var file = values.shift();
+ var fileContent = Base64.decode(values.join("|"));
+ jQuery("#fileStatus").html("<?=gettext("File successfully loaded"); ?>.");
+ jQuery("#fbTarget").html(file);
+ jQuery("#fileRefreshBtn").show();
+ jQuery("#fileContent").prop("disabled", false);
+ jQuery("#fileContent").val(fileContent);
+ } else {
+ jQuery("#fileStatus").html(values[0]);
+ jQuery("#fbTarget").html("");
+ jQuery("#fileRefreshBtn").hide();
+ jQuery("#fileContent").val("");
+ jQuery("#fileContent").prop("disabled", true);
+ }
+ }
+//]]>
+</script>
+
+<?php
+echo("<form action='" . $_SERVER['PHP_SELF'] . "' method='post' id='formbrowse'>");
+if ($savemsg) {
+ print_info_box($savemsg);
+}
+?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <?php
+ $tab_array = array();
+ $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml&amp;id=0");
+ $tab_array[] = array(gettext("Update"), false, "/pfblockerng/pfblockerng_update.php");
+ $tab_array[] = array(gettext("Alerts"), false, "/pfblockerng/pfblockerng_alerts.php");
+ $tab_array[] = array(gettext("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0");
+ $tab_array[] = array(gettext("IPv4"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml");
+ $tab_array[] = array(gettext("IPv6"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml");
+ $tab_array[] = array(gettext("Top 20"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0");
+ $tab_array[] = array(gettext("Africa"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0");
+ $tab_array[] = array(gettext("Asia"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0");
+ $tab_array[] = array(gettext("Europe"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0");
+ $tab_array[] = array(gettext("N.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0");
+ $tab_array[] = array(gettext("Oceania"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0");
+ $tab_array[] = array(gettext("S.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0");
+ $tab_array[] = array(gettext("P.S."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&id=0");
+ $tab_array[] = array(gettext("Logs"), true, "/pfblockerng/pfblockerng_log.php");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0");
+ display_top_tabs($tab_array, true);
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <div id="mainarea">
+ <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="6">
+ <tbody>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Log/File Browser Selections"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="3" class="vncell" align="left"><?php echo gettext("LINKS :"); ?> &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;
+ <a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br /></td>
+ </tr>
+ <tr>
+ <td width="22%" class="vncell"><?php echo gettext('Log/File type:'); ?></td>
+ <td width="78%" class="vtable">
+ <select name="logtype" id="logtype" class="formselect" onChange="document.getElementById('formbrowse').method='post';document.getElementById('formbrowse').submit()">
+ <?php
+ $clearable = FALSE;
+ $downloadable = FALSE;
+ foreach ($pfb_logtypes as $id => $logtype) {
+ $selected = "";
+ if ($id == $logtypeid) {
+ $selected = " selected";
+ $clearable = $logtype['clear'];
+ $downloadable = $logtype['download'];
+ }
+ echo("<option value='" . $id . "'" . $selected . ">" . $logtype['name'] . "</option>\n");
+ }
+ ?>
+ </select>&nbsp;&nbsp;<?php echo gettext('Choose which type of log/file you want to view.'); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" class="vncell"><?php echo gettext('Log/File selection:'); ?></td>
+ <td width="78%" class="vtable">
+ <select name="logFile" id="logFile" class="formselect" onChange="loadFile();">
+ <?php
+ if (isset($pfb_logtypes[$logtypeid]['logs'])) {
+ $logs = $pfb_logtypes[$logtypeid]['logs'];
+ } else {
+ $logs = getlogs($pfb_logtypes[$logtypeid]['logdir'], $pfb_logtypes[$logtypeid]['ext']);
+ }
+ foreach ($logs as $log) {
+ $selected = "";
+ if ($log == $pfb_logfilename) {
+ $selected = " selected";
+ }
+ echo("<option value='" . $pfb_logtypes[$logtypeid]['logdir'] . $log . "'" . $selected . ">" . $log . "</option>\n");
+ }
+ ?>
+ </select>&nbsp;&nbsp;<?php echo gettext('Choose which log/file you want to view.'); ?>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Log/File Contents"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <table width="100%">
+ <tbody>
+ <tr>
+ <td width="75%">
+ <div style="display:none; " id="fileStatusBox">
+ <div class="list" style="padding-left:15px;">
+ <strong id="fileStatus"></strong>
+ </div>
+ </div>
+ <div style="padding-left:15px; display:none;" id="filePathBox">
+ <strong><?=gettext("Log/File Path"); ?>:</strong>
+ <div class="list" style="display:inline;" id="fbTarget"></div>
+ </div>
+ </td>
+ <td align="right">
+ <div style="padding-right:15px; display:none;" id="fileRefreshBtn">
+ <?php
+ echo("<img src='../tree/page-file.png' onclick='loadFile()' title='" . gettext("Refresh current display") . "' alt='refresh' width='17' height='17' border='0' /> &nbsp;");
+ if ($downloadable) {
+ echo("<input type='image' src='../tree/page-file_play.gif' name='download[]' id='download' value='Download' title='" . gettext("Download current logfile") . "' alt='download' width='17' height='17' border='0' /> &nbsp;");
+ }
+ if ($clearable) {
+ echo("<input type='image' src='../tree/page-file_x.gif' name='clear[]' id='clear' value='Clear' title='" . gettext("Clear current logfile") . "' alt='clear' width='17' height='17' border='0' />");
+ }
+ ?>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <table width="100%">
+ <tbody>
+ <tr>
+ <td valign="top" class="label">
+ <div style="background:#eeeeee;" id="fileOutput">
+ <textarea id="fileContent" name="fileContent" style="width:100%;" rows="30" wrap="off" disabled></textarea>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+
+<?php if (!isset($_POST['file'])): ?>
+<script type="text/javascript">
+//<![CDATA[
+ document.getElementById("logFile").selectedIndex=-1;
+//]]>
+</script>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_sync.xml b/config/pfblockerng/pfblockerng_sync.xml
new file mode 100644
index 00000000..00186af8
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_sync.xml
@@ -0,0 +1,246 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ pfBlockerNG_sync.xml
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfblocker for pfSense
+ Copyright (C) 2011 Marcello Coutinho
+ All rights reserved.
+*/
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>pfblockerngsync</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: XMLRPC Sync</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <menu>
+ <name>pfBlockerNG</name>
+ <tooltiptext>Configure pfBlockerNG</tooltiptext>
+ <section>Services</section>
+ <url>pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Update</text>
+ <url>/pfblockerng/pfblockerng_update.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pfblockerng/pfblockerng_alerts.php</url>
+ </tab>
+ <tab>
+ <text>Reputation</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>IPv4</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</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>
+ </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>
+ </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&amp;id=0</url>
+ <active/>
+ </tab>
+ </tabs>
+ <fields>
+ <field>
+ <name>pfBlockerNG XMLRPC Sync Settings</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>LINKS</fielddescr>
+ <fieldname>none</fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp; <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ </description>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr>Enable Sync</fielddescr>
+ <fieldname>varsynconchanges</fieldname>
+ <description><![CDATA[When enabled, this will sync all configuration settings to the Replication Targets.<br /><br />
+ <b>Important:</b> While using "Sync to hosts defined below", only sync from host A to B, A to C
+ <br /> but <b>do not</b> enable XMLRPC sync <b>to</b> A. This will result in a loop!]]>
+ </description>
+ <type>select</type>
+ <required/>
+ <default_value>disabled</default_value>
+ <options>
+ <option><name>Do not sync this package configuration</name><value>disabled</value></option>
+ <option><name>Sync to configured system backup server</name><value>auto</value></option>
+ <option><name>Sync to host(s) defined below</name><value>manual</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>XMLRPC Timeout</fielddescr>
+ <fieldname>varsynctimeout</fieldname>
+ <description><![CDATA[Timeout in seconds for the XMLRPC timeout. Default: 150]]></description>
+ <type>input</type>
+ <default_value>150</default_value>
+ <size>5</size>
+ </field>
+ <field>
+ <fielddescr><![CDATA[Disable 'General Tab' sync]]></fielddescr>
+ <fieldname>syncinterfaces</fieldname>
+ <description>When selected, the 'General' Tab Customizations will not be sync'd</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <name>pfBlockerNG XMLRPC Replication Targets</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Replication Targets</fielddescr>
+ <fieldname>none</fieldname>
+ <type>rowhelper</type>
+ <rowhelper>
+ <rowhelperfield>
+ <fielddescr>Enable</fielddescr>
+ <fieldname>varsyncdestinenable</fieldname>
+ <description><![CDATA[Enable this host as a replication target]]></description>
+ <type>checkbox</type>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Protocol</fielddescr>
+ <fieldname>varsyncprotocol</fieldname>
+ <description><![CDATA[Choose the protocol of the destination host. Probably <b>http</b> or <b>https</b>]]></description>
+ <type>select</type>
+ <default_value>HTTP</default_value>
+ <options>
+ <option><name>HTTP</name><value>http</value></option>
+ <option><name>HTTPS</name><value>https</value></option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Target IP Address</fielddescr>
+ <fieldname>varsyncipaddress</fieldname>
+ <description><![CDATA[IP Address of the destination host.]]></description>
+ <type>input</type>
+ <size>15</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Target Port</fielddescr>
+ <fieldname>varsyncport</fieldname>
+ <description><![CDATA[Choose the sync port of the destination host.]]></description>
+ <type>input</type>
+ <size>3</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Target Username (admin)</fielddescr>
+ <fieldname>varsyncusername</fieldname>
+ <description><![CDATA[Enter the Username Account for Authentication]]></description>
+ <type>input</type>
+ <size>15</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Target Password</fielddescr>
+ <fieldname>varsyncpassword</fieldname>
+ <description><![CDATA[Password of the user "admin" on the destination host.]]></description>
+ <type>password</type>
+ <size>20</size>
+ </rowhelperfield>
+ </rowhelper>
+ </field>
+ <field>
+ <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ 'Force Update'</ul>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_install_command>
+ pfblockerng_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ pfblockerng_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ pfblockerng_validate_input($_POST, $input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+ write_config("[pfBlockerNG] XMLRPC sync configurations saved.");
+ pfblockerng_sync_on_changes();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_top20.xml b/config/pfblockerng/pfblockerng_top20.xml
new file mode 100644
index 00000000..ccaf68a0
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_top20.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* $Id$ */
+/* ========================================================================== */
+/*
+ pfBlockerNG_Top20.xml
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfblocker for pfSense
+ Copyright (C) 2011 Marcello Coutinho
+ All rights reserved.
+*/
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>pfblockerngtopspammers</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: Top 20 Spammer Countries</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <menu>
+ <name>pfBlockerNG</name>
+ <tooltiptext>Configure pfblockerNG</tooltiptext>
+ <section>Firewall</section>
+ <url>pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>Update</text>
+ <url>/pfblockerng/pfblockerng_update.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pfblockerng/pfblockerng_alerts.php</url>
+ </tab>
+ <tab>
+ <text>Reputation</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>IPv4</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</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>
+ <active/>
+ </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>
+ </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&amp;id=0</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>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>LINKS</fielddescr>
+ <fieldname>none</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>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<br /><strong>Top 20 IPv4</strong><br />Spammer Countries]]></fielddescr>
+ <fieldname>countries4</fieldname>
+ <description>
+ <![CDATA[Select Top IPv4 Spammer Countries you want to take an action on.<br />
+ <strong>Use CTRL + CLICK to unselect countries</strong>]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>China-CN</name><value>CN</value></option>
+ <option><name>Russia-RU</name><value>RU</value></option>
+ <option><name>Japan-JP</name><value>JP</value></option>
+ <option><name>Ukraine-UA</name><value>UA</value></option>
+ <option><name>United Kingdom-GB</name><value>GB</value></option>
+ <option><name>Germany-DE</name><value>DE</value></option>
+ <option><name>Brazil-BR</name><value>BR</value></option>
+ <option><name>France-FR</name><value>FR</value></option>
+ <option><name>India-IN</name><value>IN</value></option>
+ <option><name>Turkey-TR</name><value>TR</value></option>
+ <option><name>Italy-IT</name><value>IT</value></option>
+ <option><name>South Korea-KR</name><value>KR</value></option>
+ <option><name>Poland-PL</name><value>PL</value></option>
+ <option><name>Spain-ES</name><value>ES</value></option>
+ <option><name>Vietnam-VN</name><value>VN</value></option>
+ <option><name>Argentina-AR</name><value>AR</value></option>
+ <option><name>Columbia-CO</name><value>CO</value></option>
+ <option><name>Taiwan-TW</name><value>TW</value></option>
+ <option><name>Mexico-MX</name><value>MX</value></option>
+ <option><name>Chilie-CL</name><value>CL</value></option>
+ </options>
+ <size>20</size>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<br /><strong>Top 20 IPv6</strong><br />Spammer Countries]]></fielddescr>
+ <fieldname>countries6</fieldname>
+ <description>
+ <![CDATA[Select Top IPv6 Spammer Countries you want to take an action on.<br />
+ <strong>Use CTRL + CLICK to unselect countries</strong>]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>China-CN</name><value>CN</value></option>
+ <option><name>Russia-RU</name><value>RU</value></option>
+ <option><name>Japan-JP</name><value>JP</value></option>
+ <option><name>Ukraine-UA</name><value>UA</value></option>
+ <option><name>United Kingdom-GB</name><value>GB</value></option>
+ <option><name>Germany-DE</name><value>DE</value></option>
+ <option><name>Brazil-BR</name><value>BR</value></option>
+ <option><name>France-FR</name><value>FR</value></option>
+ <option><name>India-IN</name><value>IN</value></option>
+ <option><name>Turkey-TR</name><value>TR</value></option>
+ <option><name>Italy-IT</name><value>IT</value></option>
+ <option><name>South Korea-KR</name><value>KR</value></option>
+ <option><name>Poland-PL</name><value>PL</value></option>
+ <option><name>Spain-ES</name><value>ES</value></option>
+ <option><name>Vietnam-VN</name><value>VN</value></option>
+ <option><name>Argentina-AR</name><value>AR</value></option>
+ <option><name>Columbia-CO</name><value>CO</value></option>
+ <option><name>Taiwan-TW</name><value>TW</value></option>
+ <option><name>Mexico-MX</name><value>MX</value></option>
+ <option><name>Chilie-CL</name><value>CL</value></option>
+ </options>
+ <size>20</size>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr>List Action</fielddescr>
+ <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br />
+ Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br />
+ <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br />
+
+ <strong><u>'Deny' Rules:</u></strong><br />
+ 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other
+ interfaces. Typical uses of 'Deny' rules are:<br />
+ <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li>
+ <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by
+ traffic sent in the other direction. Does not affect traffic in the other direction. </li>
+ <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while
+ still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul>
+ <strong><u>'Permit' Rules:</u></strong><br />
+ 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create
+ any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br />
+ <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They
+ override <u>almost all other</u> Firewall rules on the stated interfaces.</li>
+ <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a
+ few IPs that should be accessible.</li></ul>
+ <strong><u>'Match' Rules:</u></strong><br />
+ 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic.
+ <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li>
+ <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul>
+ <strong><u>'Alias' Rules:</u></strong><br />
+ <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else).
+ This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired.
+ <ul><li><strong>Options &nbsp;&nbsp; - 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)&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 />]]>
+ </description>
+ <fieldname>action</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>Disabled</name><value>Disabled</value></option>
+ <option><name>Deny Inbound</name><value>Deny_Inbound</value></option>
+ <option><name>Deny Outbound</name><value>Deny_Outbound</value></option>
+ <option><name>Deny Both</name><value>Deny_Both</value></option>
+ <option><name>Permit Inbound</name><value>Permit_Inbound</value></option>
+ <option><name>Permit Outbound</name><value>Permit_Outbound</value></option>
+ <option><name>Permit Both</name><value>Permit_Both</value></option>
+ <option><name>Match Inbound</name><value>Match_Inbound</value></option>
+ <option><name>Match Outbound</name><value>Match_Outbound</value></option>
+ <option><name>Match Both</name><value>Match_Both</value></option>
+ <option><name>Alias Deny</name><value>Alias_Deny</value></option>
+ <option><name>Alias Permit</name><value>Alias_Permit</value></option>
+ <option><name>Alias Match</name><value>Alias_Match</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Enable Logging</fielddescr>
+ <fieldname>aliaslog</fieldname>
+ <description><![CDATA[Default:<strong>Enable</strong><br />
+ Select - Logging to Status: System Logs: FIREWALL ( Log )]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Enable</name><value>enabled</value></option>
+ <option><name>Disable</name><value>disabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ 'Force Update'</ul>]]> </name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_install_command>
+ pfblockerng_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ pfblockerng_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ pfblockerng_validate_input($_POST, $input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ global $pfb;
+ $pfb['save'] = TRUE;
+ sync_package_pfblockerng();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_update.php b/config/pfblockerng/pfblockerng_update.php
new file mode 100644
index 00000000..99480900
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_update.php
@@ -0,0 +1,426 @@
+<?php
+
+/* pfBlockerNG_Update.php
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Portions of this code are based on original work done for
+ pfSense from the following contributors:
+
+ pkg_mgr_install.php
+ Part of pfSense (https://www.pfsense.org)
+ Copyright (C) 2004-2010 Scott Ullrich <sullrich@gmail.com>
+ Copyright (C) 2005 Colin Smith
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("guiconfig.inc");
+require_once("globals.inc");
+require_once("pfsense-utils.inc");
+require_once("functions.inc");
+require_once("util.inc");
+require_once("/usr/local/pkg/pfblockerng/pfblockerng.inc");
+
+pfb_global();
+
+// Collect pfBlockerNG log file and post Live output to Terminal window.
+function pfbupdate_output($text) {
+ $text = preg_replace("/\n/", "\\n", $text);
+ echo "\n<script type=\"text/javascript\">";
+ echo "\n//<![CDATA[";
+ echo "\nthis.document.forms[0].pfb_output.value = \"" . $text . "\";";
+ echo "\nthis.document.forms[0].pfb_output.scrollTop = this.document.forms[0].pfb_output.scrollHeight;";
+ echo "\n//]]>";
+ echo "\n</script>";
+ /* ensure that contents are written out */
+ ob_flush();
+}
+
+// Post Status Message to Terminal window.
+function pfbupdate_status($status) {
+ $status = preg_replace("/\n/", "\\n", $status);
+ echo "\n<script type=\"text/javascript\">";
+ echo "\n//<![CDATA[";
+ echo "\nthis.document.forms[0].pfb_status.value=\"" . $status . "\";";
+ echo "\n//]]>";
+ echo "\n</script>";
+ /* ensure that contents are written out */
+ ob_flush();
+}
+
+
+// Function to perform a Force Update, Cron or Reload
+function pfb_cron_update($type) {
+
+ global $pfb;
+
+ // Query for any Active pfBlockerNG CRON Jobs
+ $result_cron = array();
+ $cron_event = exec ("/bin/ps -wx", $result_cron);
+ if (preg_grep("/pfblockerng[.]php\s+cron/", $result_cron) || preg_grep("/pfblockerng[.]php\s+update/", $result_cron)) {
+ pfbupdate_status(gettext("Force {$type} Terminated - Failed due to Active Running Task"));
+ exit;
+ }
+
+ if (!file_exists("{$pfb['log']}"))
+ touch("{$pfb['log']}");
+
+ // Update Status Window with correct Task
+ if ($type == "update") {
+ pfbupdate_status(gettext("Running Force Update Task"));
+ } elseif ($type == "reload") {
+ pfbupdate_status(gettext("Running Force Reload Task"));
+ $type = "update";
+ } else {
+ pfbupdate_status(gettext("Running Force CRON Task"));
+ }
+
+ // Remove any existing pfBlockerNG CRON Jobs
+ install_cron_job("pfblockerng.php cron", false);
+ write_config();
+
+ // Execute PHP Process in the Background
+ mwexec_bg("/usr/local/bin/php /usr/local/www/pfblockerng/pfblockerng.php {$type} >> {$pfb['log']} 2>&1");
+
+ // Start at EOF
+ $lastpos_old = "";
+ $len = filesize("{$pfb['log']}");
+ $lastpos = $len;
+
+ while (true) {
+ usleep(300000); //0.3s
+ clearstatcache(false,$pfb['log']);
+ $len = filesize("{$pfb['log']}");
+ if ($len < $lastpos) {
+ //file deleted or reset
+ $lastpos = $len;
+ } else {
+ $f = fopen($pfb['log'], "rb");
+ if ($f === false)
+ die();
+ fseek($f, $lastpos);
+
+ while (!feof($f)) {
+
+ $pfb_buffer = fread($f, 2048);
+ $pfb_output .= str_replace( 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();
+ }
+ }
+}
+
+
+$pgtitle = gettext("pfBlockerNG: Update");
+include_once("head.inc");
+?>
+<body link="#000000" vlink="#0000CC" alink="#000000">
+<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
+<?php include_once("fbegin.inc"); ?>
+
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td>
+ <?php
+ $tab_array = array();
+ $tab_array[] = array(gettext("General"), false, "/pkg_edit.php?xml=pfblockerng.xml&amp;id=0");
+ $tab_array[] = array(gettext("Update"), true, "/pfblockerng/pfblockerng_update.php");
+ $tab_array[] = array(gettext("Alerts"), false, "/pfblockerng/pfblockerng_alerts.php");
+ $tab_array[] = array(gettext("Reputation"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&id=0");
+ $tab_array[] = array(gettext("IPv4"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml");
+ $tab_array[] = array(gettext("IPv6"), false, "/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml");
+ $tab_array[] = array(gettext("Top 20"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_top20.xml&id=0");
+ $tab_array[] = array(gettext("Africa"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Africa.xml&id=0");
+ $tab_array[] = array(gettext("Asia"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Asia.xml&id=0");
+ $tab_array[] = array(gettext("Europe"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Europe.xml&id=0");
+ $tab_array[] = array(gettext("N.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_NorthAmerica.xml&id=0");
+ $tab_array[] = array(gettext("Oceania"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_Oceania.xml&id=0");
+ $tab_array[] = array(gettext("S.A."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_SouthAmerica.xml&id=0");
+ $tab_array[] = array(gettext("P.S."), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_ProxyandSatellite.xml&id=0");
+ $tab_array[] = array(gettext("Logs"), false, "/pfblockerng/pfblockerng_log.php");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=/pfblockerng/pfblockerng_sync.xml&id=0");
+ display_top_tabs($tab_array, true);
+ ?>
+ </td>
+ </tr>
+ </table>
+ <div id="mainareapkg">
+ <table id="maintable" class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="2">
+ <tr>
+ <td colspan="2" class="vncell" align="left"><?php echo gettext("LINKS :"); ?>&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;
+ <a href='/diag_logs_filter.php' target="_blank"><?php echo gettext("Firewall Logs"); ?></a><br />
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("CRON Status"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listr">
+ <?php
+ // Collect Existing CRON settings
+ if (is_array($config['cron']['item'])) {
+ foreach ($config['cron']['item'] as $cron) {
+ if (preg_match("/usr.local.www.pfblockerng.pfblockerng.php cron/",$cron["command"])) {
+ $pfb_min = "{$cron['minute']}";
+ break;
+ }
+ }
+ }
+ // Calculate Minutes Remaining till next CRON Event.
+ $currentmin = date('i');
+ switch ($pfb_min) {
+ case "0":
+ $min_remain = (60 - $currentmin);
+ break;
+ case "15":
+ if ($currentmin < 15) {
+ $min_remain = (15 - $currentmin);
+ } else {
+ $min_remain = (75 - $currentmin);
+ }
+ break;
+ case "30":
+ if ($currentmin < 30) {
+ $min_remain = (30 - $currentmin);
+ } else {
+ $min_remain = (90 - $currentmin);
+ }
+ break;
+ case "45":
+ if ($currentmin < 45) {
+ $min_remain = (45 - $currentmin);
+ } else {
+ $min_remain = (105 - $currentmin);
+ }
+ break;
+ }
+
+ // Default to "< 1 minute" if empty
+ if (empty($min_remain))
+ $min_remain = "< 1";
+
+ // Next Scheduled Cron Time
+ if ($pfb_min == "0")
+ $pfb_min = "00";
+ $nextcron = (date('H') +1) . ":{$pfb_min}";
+
+ // If pfBlockerNG is Disabled or Cron Task is Missing
+ if (empty($pfb['enable']) || empty($pfb_min)) {
+ $min_remain = " -- ";
+ $nextcron = " [ Disabled ] ";
+ }
+
+ echo "NEXT Scheduled CRON Event will run at <font size=\"3\">&nbsp;{$nextcron}</font>&nbsp; in<font size=\"3\">
+ <span class=\"red\">&nbsp;{$min_remain}&nbsp;</span></font> Minutes.";
+
+ // Query for any Active pfBlockerNG CRON Jobs
+ $result_cron = array();
+ $cron_event = exec ("/bin/ps -wax", $result_cron);
+ if (preg_grep("/pfblockerng[.]php\s+cron/", $result_cron)) {
+ echo "<font size=\"2\"><span class=\"red\">&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'
+ border='0' title='pfBockerNG Cron Task is Running.'/>";
+ }
+ echo "<br /><font size=\"3\"><span class=\"red\">Refresh</span></font> to update current Status and Minute(s) remaining";
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vncell"><?php echo gettext("<br />"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Update Options"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listr">
+ <!-- Update Option Text -->
+ <?php echo "<span class='red'><strong>" . gettext("** AVOID ** ") . "&nbsp;" . "</strong></span>" .
+ gettext("Running these Options - when CRON is expected to RUN!") . gettext("<br /><br />") .
+ "<strong>" . gettext("Force Update") . "</strong>" . gettext(" will download any new Alias/Lists.") .
+ gettext("<br />") . "<strong>" . gettext("Force Cron") . "</strong>" .
+ gettext(" will download any Alias/Lists that are within the Frequency Setting (due for Update).") . gettext("<br />") .
+ "<strong>" . gettext("Force Reload") . "</strong>" .
+ gettext(" will reload all Lists using the existing Downloaded files.") .
+ gettext(" This is useful when Lists are out of 'sync' or Reputation changes were made.") ;?><br />
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vncell">
+ <!-- Update Option Buttons -->
+ <input type="submit" class="formbtns" name="pfbupdate" id="pfbupdate" value="Force Update"
+ title="<?=gettext("Run Force Update");?>" />
+ <input type="submit" class="formbtns" name="pfbcron" id="pfbcron" value="Force Cron"
+ title="<?=gettext("Run Force Cron Update");?>" />
+ <input type="submit" class="formbtns" name="pfbreload" id="pfbreload" value="Force Reload"
+ title="<?=gettext("Run Force Reload");?>" />
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vncell"><?php echo gettext("<br />"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Live Log Viewer only"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listr"><?php echo gettext("Selecting 'Live Log Viewer' will allow viewing a running Cron Update"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vncell">
+ <!-- Log Viewer Buttons -->
+ <input type="submit" class="formbtns" name="pfbview" id="pfbview" value="VIEW"
+ title="<?=gettext("VIEW pfBlockerNG LOG");?>"/>
+ <input type="submit" class="formbtns" name="pfbviewcancel" id="pfbviewcancel" value="End View"
+ title="<?=gettext("END VIEW of pfBlockerNG LOG");?>"/>
+ <?php echo "&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 />
+ </td>
+ </tr>
+ <tr>
+ <td class="tabcont" align="left">
+ <!-- status box -->
+ <textarea cols="90" rows="1" name="pfb_status" id="pfb_status"
+ wrap="hard"><?=gettext("Log Viewer Standby");?></textarea>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <!-- command output box -->
+ <textarea cols="90" rows="35" name="pfb_output" id="pfb_output" wrap="hard"></textarea>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+<?php
+include("fend.inc");
+
+// Execute the Viewer output Window
+if (isset($_POST['pfbview'])) {
+
+ if (!file_exists("{$pfb['log']}"))
+ touch("{$pfb['log']}");
+
+ // Reference: http://stackoverflow.com/questions/3218895/php-how-to-read-a-file-live-that-is-constantly-being-written-to
+ pfbupdate_status(gettext("Log Viewing in progress. ** Press 'END VIEW' to Exit ** "));
+ $lastpos_old = "";
+ $len = filesize("{$pfb['log']}");
+
+ // Start at EOF ( - 15000)
+ if ($len > 15000) {
+ $lastpos = ($len - 15000);
+ } else {
+ $lastpos = 0;
+ }
+
+ while (true) {
+ usleep(300000); //0.3s
+ clearstatcache(false,$pfb['log']);
+ $len = filesize("{$pfb['log']}");
+ if ($len < $lastpos) {
+ //file deleted or reset
+ $lastpos = $len;
+ } else {
+ $f = fopen($pfb['log'], "rb");
+ if ($f === false)
+ die();
+ fseek($f, $lastpos);
+
+ while (!feof($f)) {
+
+ $pfb_buffer = fread($f, 4096);
+ $pfb_output .= str_replace( 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);
+ }
+ }
+}
+
+// End the Viewer output Window
+if (isset($_POST['pfbviewcancel'])) {
+ clearstatcache(false,$pfb['log']);
+ ob_flush();
+ flush();
+ fclose("{$pfb['log']}");
+}
+
+// Execute a Force Update
+if (isset($_POST['pfbupdate']) && $pfb['enable'] == "on") {
+ pfb_cron_update(update);
+}
+
+// Execute a CRON Command to update any Lists within the Frequency Settings
+if (isset($_POST['pfbcron']) && $pfb['enable'] == "on") {
+ pfb_cron_update(cron);
+}
+
+// Execute a Reload of all Aliases and Lists
+if (isset($_POST['pfbreload']) && $pfb['enable'] == "on") {
+ $config['installedpackages']['pfblockerng']['config'][0]['pfb_reuse'] = "on";
+ write_config();
+ pfb_cron_update(reload);
+}
+
+?>
+</form>
+</body>
+</html> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_v4lists.xml b/config/pfblockerng/pfblockerng_v4lists.xml
new file mode 100644
index 00000000..6df839ed
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_v4lists.xml
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* ========================================================================== */
+/*
+ pfBlockerNG_v4lists.xml
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfblocker for pfSense
+ Copyright (C) 2011 Marcello Coutinho
+
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com>
+ All rights reserved.
+*/
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>pfblockernglistsv4</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: IPv4 Alias/List Configuration</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <menu>
+ <name>pfBlockerNG</name>
+ <tooltiptext></tooltiptext>
+ <section>Firewall</section>
+ <configfile>pfblockerng_v4lists.xml</configfile>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <tooltiptext></tooltiptext>
+ </tab>
+ <tab>
+ <text>Update</text>
+ <url>/pfblockerng/pfblockerng_update.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pfblockerng/pfblockerng_alerts.php</url>
+ </tab>
+ <tab>
+ <text>Reputation</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>IPv4</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ <active/>
+ </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>
+ </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>
+ </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&amp;id=0</url>
+ </tab>
+ </tabs>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>Alias Name</fielddescr>
+ <fieldname>aliasname</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Alias Description</fielddescr>
+ <fieldname>description</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Action</fielddescr>
+ <fieldname>action</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Frequency</fielddescr>
+ <fieldname>cron</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Logging</fielddescr>
+ <fieldname>aliaslog</fieldname>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <name><![CDATA[IPv4 Network ranges / CIDR lists &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ (When Removing or Re-configuring Lists a 'Reload' is recommended.)]]></name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>LINKS</fielddescr>
+ <fieldname>none</fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp; <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ </description>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr>Alias Name</fielddescr>
+ <fieldname>aliasname</fieldname>
+ <description><![CDATA[Enter lists Alias Names.<br />
+ Example: Badguys<br />
+ Do not include <strong>'pfBlocker' or 'pfB_'</strong> in the Alias Name, it's done by package.<br />
+ <strong>International, special or space characters will be ignored in firewall alias names.
+ </strong><br />]]>
+ </description>
+ <type>input</type>
+ <size>20</size>
+ </field>
+ <field>
+ <fielddescr>List Description</fielddescr>
+ <fieldname>description</fieldname>
+ <type>input</type>
+ <size>90</size>
+ </field>
+ <field>
+ <fieldname>InfoLists</fieldname>
+ <type>info</type>
+ <description><![CDATA[<strong><u>'Format'</u></strong> : Select the Format Type<br /><br />
+ <strong><u>'URL'</u></strong> : Add direct link to list:
+ Example: <a target=_new href='http://list.iblocklist.com/?list=bt_ads&fileformat=p2p&archiveformat=gz'>Ads</a>,
+ <a target=_new href='http://list.iblocklist.com/?list=bt_spyware&fileformat=p2p&archiveformat=gz'>Spyware</a>,
+ <a target=_new href='http://list.iblocklist.com/?list=bt_proxy&fileformat=p2p&archiveformat=gz'>Proxies</a> )<br /><br />
+ <strong><u>'pfSense Local File'</u></strong> Format :<br /><br />
+ &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>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>IPv4</strong> Lists]]></fielddescr>
+ <fieldname>none</fieldname>
+ <description><![CDATA[<br /><strong>'Format'</strong> - Select the file format that URL will retrieve.<br />
+
+ <ul><li><strong>'txt'</strong> Plain txt Lists</li><br />
+ <li><strong>'gz'</strong> - IBlock GZ Lists in Range Format only.</li><br />
+ <li><strong>'gz_2'</strong> - Other GZ Lists in IP or CIDR only.</li><br />
+ <li><strong>'gz_lg'</strong> - Large IBlock GZ Lists in Range Format only.</li><br />
+ <li><strong>'zip'</strong> - ZIP'd Lists</li><br />
+ <li><strong>'block'</strong>- IP x.x.x.0 Block type</li><br />
+ <li><strong>'html'</strong> - Web Links</li><br />
+ <li><strong>'xlsx'</strong> - Excel Lists</li><br />
+ <li><strong>'rsync'</strong> - RSync Lists</li><br />
+ <li><strong>'ET' IQRisk</strong> - Only</li></ul>
+ <strong>'State'</strong> - Select the Run State for each list.<br />
+ <ul><li><strong>'ON/OFF'</strong> - Enabled / Disabled</li><br />
+ <li><strong>'HOLD'</strong> - Once a List has been Downloaded, list will remain Static.</li></ul>
+ <strong>'Note' -</strong> Downloaded or pfsense local file must have only one network per line and follows the syntax below:
+ <ul>Network ranges: <strong>172.16.1.0-172.16.1.255</strong><br />
+ IP Address: <strong>172.16.1.10</strong><br />
+ CIDR: <strong>172.16.1.0/24</strong></ul>]]>
+ </description>
+ <type>rowhelper</type>
+ <rowhelper>
+ <rowhelperfield>
+ <fielddescr>Format</fielddescr>
+ <fieldname>format</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>txt</name><value>txt</value></option>
+ <option><name>gz</name><value>gz</value></option>
+ <option><name>gz_2</name><value>gz_2</value></option>
+ <option><name>gz_lg</name><value>gz_lg</value></option>
+ <option><name>zip</name><value>zip</value></option>
+ <option><name>block</name><value>block</value></option>
+ <option><name>html</name><value>html</value></option>
+ <option><name>xlsx</name><value>xlsx</value></option>
+ <option><name>RSync</name><value>rsync</value></option>
+ <option><name>ET</name><value>et</value></option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>State</fielddescr>
+ <fieldname>state</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>ON</name><value>Enabled</value></option>
+ <option><name>OFF</name><value>Disabled</value></option>
+ <option><name>HOLD</name><value>Hold</value></option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>URL or pfSense local file</fielddescr>
+ <fieldname>url</fieldname>
+ <type>input</type>
+ <size>50</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Header</fielddescr>
+ <fieldname>header</fieldname>
+ <type>input</type>
+ <size>15</size>
+ </rowhelperfield>
+ </rowhelper>
+ </field>
+ <field>
+ <fielddescr>List Action</fielddescr>
+ <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br />
+ Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br />
+ <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br />
+
+ <strong><u>'Deny' Rules:</u></strong><br />
+ 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other
+ interfaces. Typical uses of 'Deny' rules are:<br />
+ <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li>
+ <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by
+ traffic sent in the other direction. Does not affect traffic in the other direction.</li>
+ <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while
+ still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul>
+ <strong><u>'Permit' Rules:</u></strong><br />
+ 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create
+ any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br />
+ <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They
+ override <u>almost all other</u> Firewall rules on the stated interfaces.</li>
+ <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a
+ few IPs that should be accessible.</li></ul>
+ <strong><u>'Match' Rules:</u></strong><br />
+ 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic.
+ <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li>
+ <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul>
+ <strong><u>'Alias' Rules:</u></strong><br />
+ <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else).
+ This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired.
+ <ul><li><strong>Options &nbsp;&nbsp; - 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)&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 />]]>
+ </description>
+ <fieldname>action</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>Disabled</name><value>Disabled</value></option>
+ <option><name>Deny Inbound</name><value>Deny_Inbound</value></option>
+ <option><name>Deny Outbound</name><value>Deny_Outbound</value></option>
+ <option><name>Deny Both</name><value>Deny_Both</value></option>
+ <option><name>Permit Inbound</name><value>Permit_Inbound</value></option>
+ <option><name>Permit Outbound</name><value>Permit_Outbound</value></option>
+ <option><name>Permit Both</name><value>Permit_Both</value></option>
+ <option><name>Match Inbound</name><value>Match_Inbound</value></option>
+ <option><name>Match Outbound</name><value>Match_Outbound</value></option>
+ <option><name>Match Both</name><value>Match_Both</value></option>
+ <option><name>Alias Deny</name><value>Alias_Deny</value></option>
+ <option><name>Alias Permit</name><value>Alias_Permit</value></option>
+ <option><name>Alias Match</name><value>Alias_Match</value></option>
+ <option><name>Alias Native</name><value>Alias_Native</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Update Frequency</fielddescr>
+ <fieldname>cron</fieldname>
+ <description><![CDATA[Default:<strong>Never</strong><br />
+ Select how often List files will be downloaded]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Never</name><value>Never</value></option>
+ <option><name>Every Hour</name><value>01hour</value></option>
+ <option><name>Every 2 Hours</name><value>02hours</value></option>
+ <option><name>Every 3 Hours</name><value>03hours</value></option>
+ <option><name>Every 4 Hours</name><value>04hours</value></option>
+ <option><name>Every 6 Hours</name><value>06hours</value></option>
+ <option><name>Every 8 Hours</name><value>08hours</value></option>
+ <option><name>Every 12 Hours</name><value>12hours</value></option>
+ <option><name>Once a day</name><value>EveryDay</value></option>
+ <option><name>Weekly</name><value>Weekly</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Weekly (Day of Week)</fielddescr>
+ <fieldname>dow</fieldname>
+ <description><![CDATA[Default:<strong>1</strong><br />
+ Select the 'Weekly' ( Day of the Week ) to Update <br />
+ This is only required for the 'Weekly' Frequency Selection. The 24 Hour Download 'Time' will be used.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Monday</name><value>1</value></option>
+ <option><name>Tuesday</name><value>2</value></option>
+ <option><name>Wednesday</name><value>3</value></option>
+ <option><name>Thursday</name><value>4</value></option>
+ <option><name>Friday</name><value>5</value></option>
+ <option><name>Saturday</name><value>6</value></option>
+ <option><name>Sunday</name><value>7</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Enable Logging</fielddescr>
+ <fieldname>aliaslog</fieldname>
+ <description><![CDATA[Default:<strong>Enable</strong><br />
+ Select - Logging to Status: System Logs: FIREWALL ( Log )<br />
+ This can be overriden by the 'Global Logging' Option in the General Tab.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Enable</name><value>enabled</value></option>
+ <option><name>Disable</name><value>disabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name>IPv4 Custom list</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>IPv4 Custom Address(es)</fielddescr>
+ <fieldname>custom</fieldname>
+ <description><![CDATA[Please limit the size of the Custom List as this is stored as 'Base64' format in the config.xml file.<br />
+ Follow the syntax below:<br /><br />
+ Network ranges: <strong>172.16.1.0-172.16.1.255</strong><br />
+ IP Address: <strong>172.16.1.10</strong><br />
+ CIDR: <strong>172.16.1.0/24</strong><br /><br />
+ You may use "<strong>#</strong>" after any IP/CIDR/Range to add comments. ie: x.x.x.x # Safe IP Address]]>
+ </description>
+ <type>textarea</type>
+ <cols>50</cols>
+ <rows>10</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <fielddescr>Update Custom List</fielddescr>
+ <fieldname>custom_update</fieldname>
+ <description><![CDATA[Default:<strong>Disable</strong><br />
+ select - Enable Update if changes are made to this List. Cron will also resync this list at the next Scheduled Update.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Disable</name><value>disabled</value></option>
+ <option><name>Enable</name><value>enabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ 'Force Update'</ul>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_install_command>
+ pfblockerng_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ pfblockerng_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ pfblockerng_validate_input($_POST, $input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ global $pfb;
+ $pfb['save'] = TRUE;
+ sync_package_pfblockerng();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/pfblockerng/pfblockerng_v6lists.xml b/config/pfblockerng/pfblockerng_v6lists.xml
new file mode 100644
index 00000000..15d788cf
--- /dev/null
+++ b/config/pfblockerng/pfblockerng_v6lists.xml
@@ -0,0 +1,421 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "./schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="./xsl/package.xsl"?>
+<packagegui>
+ <copyright>
+ <![CDATA[
+/* ========================================================================== */
+/*
+ pfBlockerNG_v6lists.xml
+
+ pfBlockerNG
+ Copyright (C) 2014 BBcan177@gmail.com
+ All rights reserved.
+
+ Based upon pfblocker for pfSense
+ Copyright (C) 2011 Marcello Coutinho
+
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2010 Scott Ullrich <sullrich@gmail.com>
+ All rights reserved.
+*/
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+/* ========================================================================== */
+ ]]>
+ </copyright>
+ <description>Describe your package here</description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>pfblockernglistsv6</name>
+ <version>1.0</version>
+ <title>pfBlockerNG: IPv6 Alias/List Configuration</title>
+ <include_file>/usr/local/pkg/pfblockerng/pfblockerng.inc</include_file>
+ <menu>
+ <name>pfBlockerNG</name>
+ <tooltiptext></tooltiptext>
+ <section>Firewall</section>
+ <configfile>pfblockerng_v6lists.xml</configfile>
+ </menu>
+ <tabs>
+ <tab>
+ <text>General</text>
+ <url>/pkg_edit.php?xml=pfblockerng.xml&amp;id=0</url>
+ <tooltiptext></tooltiptext>
+ </tab>
+ <tab>
+ <text>Update</text>
+ <url>/pfblockerng/pfblockerng_update.php</url>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/pfblockerng/pfblockerng_alerts.php</url>
+ </tab>
+ <tab>
+ <text>Reputation</text>
+ <url>/pkg_edit.php?xml=/pfblockerng/pfblockerng_reputation.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>IPv4</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v4lists.xml&amp;id=0</url>
+ </tab>
+ <tab>
+ <text>IPv6</text>
+ <url>/pkg.php?xml=/pfblockerng/pfblockerng_v6lists.xml&amp;id=0</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Top 20</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>
+ </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>
+ </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&amp;id=0</url>
+ </tab>
+ </tabs>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fielddescr>Alias Name</fielddescr>
+ <fieldname>aliasname</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Alias Description</fielddescr>
+ <fieldname>description</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Action</fielddescr>
+ <fieldname>action</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Frequency</fielddescr>
+ <fieldname>cron</fieldname>
+ </columnitem>
+ <columnitem>
+ <fielddescr>Logging</fielddescr>
+ <fieldname>aliaslog</fieldname>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <name>IPv6 Network ranges / CIDR lists</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>LINKS</fielddescr>
+ <fieldname>none</fieldname>
+ <description><![CDATA[<a href="/firewall_aliases.php">Firewall Alias</a> &nbsp;&nbsp;&nbsp; <a href="/firewall_rules.php">Firewall Rules</a> &nbsp;&nbsp;&nbsp; <a href="diag_logs_filter.php">Firewall Logs</a>]]>
+ </description>
+ <type>info</type>
+ </field>
+ <field>
+ <fielddescr>Alias Name</fielddescr>
+ <fieldname>aliasname</fieldname>
+ <description><![CDATA[Enter lists Alias Names.<br />
+ Example: Badguys<br />
+ Do not include <strong>'pfBlocker' or 'pfB_'</strong> in the Alias Name, it's done by package.<br />
+ <strong>International, special or space characters will be ignored in firewall alias names.
+ </strong><br />]]>
+ </description>
+ <type>input</type>
+ <size>20</size>
+ </field>
+ <field>
+ <fielddescr>List Description</fielddescr>
+ <fieldname>description</fieldname>
+ <type>input</type>
+ <size>90</size>
+ </field>
+ <field>
+ <fieldname>InfoLists</fieldname>
+ <type>info</type>
+ <description><![CDATA[<strong><u>'Format'</u></strong> : Select the Format Type<br /><br />
+ <strong><u>'URL'</u></strong> : Add direct link to list:
+ Example: <a target=_new href='http://list.iblocklist.com/?list=bt_ads&fileformat=p2p&archiveformat=gz'>Ads</a>,
+ <a target=_new href='http://list.iblocklist.com/?list=bt_spyware&fileformat=p2p&archiveformat=gz'>Spyware</a>,
+ <a target=_new href='http://list.iblocklist.com/?list=bt_proxy&fileformat=p2p&archiveformat=gz'>Proxies</a><br /><br />
+ <strong><u>'pfSense Local File'</u></strong> Format :<br /><br />
+ &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>
+ </field>
+ <field>
+ <fielddescr><![CDATA[<strong>IPv6</strong> Lists]]></fielddescr>
+ <fieldname>none</fieldname>
+ <description><![CDATA[<br /><strong>'Format'</strong> - Choose the file format that URL will retrieve.<br />
+
+ <ul><li><strong>'txt'</strong> Plain txt Lists</li><br />
+ <li><strong>'gz'</strong> - IBlock GZ Lists in Range Format only.</li><br />
+ <li><strong>'gz_2'</strong> - Other GZ Lists in IP or CIDR only.</li><br />
+ <li><strong>'zip'</strong> - ZIP'd Lists</li><br />
+ <li><strong>'block'</strong>- IP x.x.x.0 Block type</li><br />
+ <li><strong>'html'</strong> - Web Links</li><br />
+ <li><strong>'xlsx'</strong> - Excel Lists</li><br />
+ <li><strong>'rsync'</strong> - RSync Lists</li><br />
+ <strong>'State'</strong> - Select the Run State for each list.<br />
+ <ul><li><strong>'ON/OFF'</strong> - Enabled / Disabled</li><br />
+ <li><strong>'HOLD'</strong> - Once a List has been Downloaded, list will remain Static.</li></ul>
+ <strong>'Note' -</strong> Downloaded or pfsense local file must have only one network per line and follows the syntax below:
+ <ul>Network ranges: <strong> TBC </strong><br />
+ IP Address: <strong> TBC </strong><br />
+ CIDR: <strong> TBC </strong></ul>]]>
+ </description>
+ <type>rowhelper</type>
+ <rowhelper>
+ <rowhelperfield>
+ <fielddescr>Format</fielddescr>
+ <fieldname>format</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>txt</name><value>txt</value></option>
+ <option><name>gz</name><value>gz</value></option>
+ <option><name>gz_2</name><value>gz_2</value></option>
+ <option><name>zip</name><value>zip</value></option>
+ <option><name>block</name><value>block</value></option>
+ <option><name>html</name><value>html</value></option>
+ <option><name>xlsx</name><value>xlsx</value></option>
+ <option><name>RSync</name><value>rsync</value></option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>State</fielddescr>
+ <fieldname>state</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>ON</name><value>Enabled</value></option>
+ <option><name>OFF</name><value>Disabled</value></option>
+ <option><name>HOLD</name><value>Hold</value></option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>URL or pfSense local file</fielddescr>
+ <fieldname>url</fieldname>
+ <type>input</type>
+ <size>50</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Header</fielddescr>
+ <fieldname>header</fieldname>
+ <type>input</type>
+ <size>15</size>
+ </rowhelperfield>
+ </rowhelper>
+ </field>
+ <field>
+ <fielddescr>List Action</fielddescr>
+ <description><![CDATA[<br />Default : <strong>Disabled</strong><br /><br />
+ Select the <strong>Action</strong> for Firewall Rules on lists you have selected.<br /><br />
+ <strong><u>'Disabled' Rules:</u></strong> Disables selection and does nothing to selected Alias.<br /><br />
+
+ <strong><u>'Deny' Rules:</u></strong><br />
+ 'Deny' rules create high priority 'block' or 'reject' rules on the stated interfaces. They don't change the 'pass' rules on other
+ interfaces. Typical uses of 'Deny' rules are:<br />
+ <ul><li><strong>Deny Both</strong> - blocks all traffic in both directions, if the source or destination IP is in the block list</li>
+ <li><strong>Deny Inbound/Deny Outbound</strong> - blocks all traffic in one direction <u>unless</u> it is part of a session started by
+ traffic sent in the other direction. Does not affect traffic in the other direction.</li>
+ <li>One way 'Deny' rules can be used to selectively block <u>unsolicited</u> incoming (new session) packets in one direction, while
+ still allowing <u>deliberate</u> outgoing sessions to be created in the other direction.</li></ul>
+ <strong><u>'Permit' Rules:</u></strong><br />
+ 'Permit' rules create high priority 'pass' rules on the stated interfaces. They are the opposite of Deny rules, and don't create
+ any 'blocking' effect anywhere. They have priority over all Deny rules. Typical uses of 'Permit' rules are:<br />
+ <ul><li><strong>To ensure</strong> that traffic to/from the listed IPs will <u>always</u> be allowed in the stated directions. They
+ override <u>almost all other</u> Firewall rules on the stated interfaces.</li>
+ <li><strong>To act as a whitelist</strong> for Deny rule exceptions, for example if a large IP range or pre-created blocklist blocks a
+ few IPs that should be accessible.</li></ul>
+ <strong><u>'Match' Rules:</u></strong><br />
+ 'Match' or 'Log' only the traffic on the stated interfaces. This does not Block or Reject. It just Logs the traffic.
+ <ul><li><strong>Match Both</strong> - Matches all traffic in both directions, if the source or destination IP is in the list.</li>
+ <li><strong>Match Inbound/Match Outbound</strong> - Matches all traffic in one direction only.</li></ul>
+ <strong><u>'Alias' Rules:</u></strong><br />
+ <strong>'Alias'</strong> rules create an <a href="/firewall_aliases.php">alias</a> for the list (and do nothing else).
+ This enables a pfBlockerNG list to be used by name, in any firewall rule or pfSense function, as desired.
+ <ul><li><strong>Options &nbsp;&nbsp; - 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)&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 />]]>
+ </description>
+ <fieldname>action</fieldname>
+ <type>select</type>
+ <options>
+ <option><name>Disabled</name><value>Disabled</value></option>
+ <option><name>Deny Inbound</name><value>Deny_Inbound</value></option>
+ <option><name>Deny Outbound</name><value>Deny_Outbound</value></option>
+ <option><name>Deny Both</name><value>Deny_Both</value></option>
+ <option><name>Permit Inbound</name><value>Permit_Inbound</value></option>
+ <option><name>Permit Outbound</name><value>Permit_Outbound</value></option>
+ <option><name>Permit Both</name><value>Permit_Both</value></option>
+ <option><name>Match Inbound</name><value>Match_Inbound</value></option>
+ <option><name>Match Outbound</name><value>Match_Outbound</value></option>
+ <option><name>Match Both</name><value>Match_Both</value></option>
+ <option><name>Alias Deny</name><value>Alias_Deny</value></option>
+ <option><name>Alias Permit</name><value>Alias_Permit</value></option>
+ <option><name>Alias Match</name><value>Alias_Match</value></option>
+ <option><name>Alias Native</name><value>Alias_Native</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Update Frequency</fielddescr>
+ <fieldname>cron</fieldname>
+ <description><![CDATA[Default:<strong>Never</strong><br />
+ Select how often List files will be downloaded]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Never</name><value>Never</value></option>
+ <option><name>Every Hour</name><value>01hour</value></option>
+ <option><name>Every 2 Hours</name><value>02hours</value></option>
+ <option><name>Every 3 Hours</name><value>03hours</value></option>
+ <option><name>Every 4 Hours</name><value>04hours</value></option>
+ <option><name>Every 6 Hours</name><value>06hours</value></option>
+ <option><name>Every 8 Hours</name><value>08hours</value></option>
+ <option><name>Every 12 Hours</name><value>12hours</value></option>
+ <option><name>Once a day</name><value>EveryDay</value></option>
+ <option><name>Weekly</name><value>Weekly</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Weekly (Day of Week)</fielddescr>
+ <fieldname>dow</fieldname>
+ <description><![CDATA[Default:<strong>1</strong><br />
+ Select the 'Weekly' ( Day of the Week ) to Update <br />
+ This is only required for the 'Weekly' Frequency Selection. The 24 Hour Download 'Time' will be used.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Monday</name><value>1</value></option>
+ <option><name>Tuesday</name><value>2</value></option>
+ <option><name>Wednesday</name><value>3</value></option>
+ <option><name>Thursday</name><value>4</value></option>
+ <option><name>Friday</name><value>5</value></option>
+ <option><name>Saturday</name><value>6</value></option>
+ <option><name>Sunday</name><value>7</value></option>
+ </options>
+ </field>
+ <field>
+ <fielddescr>Enable Logging</fielddescr>
+ <fieldname>aliaslog</fieldname>
+ <description><![CDATA[Default:<strong>Enable</strong><br />
+ Select - Logging to Status: System Logs: FIREWALL ( Log )<br />
+ This can be overriden by the 'Global Logging' Option in the General Tab.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Enable</name><value>enabled</value></option>
+ <option><name>Disable</name><value>disabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name>IPv6 Custom list</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>IPv6 Custom Address(es)</fielddescr>
+ <fieldname>custom</fieldname>
+ <description><![CDATA[Please limit the size of the Custom List as this is stored as 'Base64' format in the config.xml file.<br />
+ Follow the syntax below:<br /><br />
+ Network ranges: <strong> TBC </strong><br />
+ IP Address: <strong> TBC </strong><br />
+ CIDR: <strong> TBC </strong><br /><br />
+ You may use "<strong>#</strong>" after any IP/CIDR/Range to add comments. # Safe IP Address]]>
+ </description>
+ <type>textarea</type>
+ <cols>50</cols>
+ <rows>10</rows>
+ <encoding>base64</encoding>
+ </field>
+ <field>
+ <fielddescr>Update Custom List</fielddescr>
+ <fieldname>custom_update</fieldname>
+ <description><![CDATA[Default:<strong>Disable</strong><br />
+ Select - Enable Update if changes are made to this List. Cron will also resync this list at the next Scheduled Update.]]>
+ </description>
+ <type>select</type>
+ <options>
+ <option><name>Disable</name><value>disabled</value></option>
+ <option><name>Enable</name><value>enabled</value></option>
+ </options>
+ </field>
+ <field>
+ <name><![CDATA[<ul>Click to SAVE Settings and/or Rule Edits. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Changes are Applied via CRON or
+ 'Force Update'</ul>]]></name>
+ <type>listtopic</type>
+ </field>
+ </fields>
+ <custom_php_install_command>
+ pfblockerng_php_install_command();
+ </custom_php_install_command>
+ <custom_php_deinstall_command>
+ pfblockerng_php_deinstall_command();
+ </custom_php_deinstall_command>
+ <custom_php_validation_command>
+ pfblockerng_validate_input($_POST, $input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ global $pfb;
+ $pfb['save'] = TRUE;
+ sync_package_pfblockerng();
+ </custom_php_resync_config_command>
+</packagegui> \ No newline at end of file
diff --git a/config/pfblockerng/widget-pfblockerng.inc b/config/pfblockerng/widget-pfblockerng.inc
new file mode 100644
index 00000000..1b3c7c2b
--- /dev/null
+++ b/config/pfblockerng/widget-pfblockerng.inc
@@ -0,0 +1,7 @@
+<?php
+
+//set variables for custom title and link
+$pfblockerng_title = "pfBlockerNG";
+$pfblockerng_title_link = "pfblockerng/pfblockerng_alerts.php";
+
+?> \ No newline at end of file
diff --git a/config/postfix/postfix_queue.php b/config/postfix/postfix_queue.php
index 1db2b8e2..a737340e 100755
--- a/config/postfix/postfix_queue.php
+++ b/config/postfix/postfix_queue.php
@@ -227,7 +227,7 @@ else{
//prevent multiple instances
if ($('run').value=="show queue" || loop== 'running'){
$('run').value="running...";
- $('search_help').innerHTML ="<br><strong>You can change options while running.<br>To Stop seach, change update frequency to Never.</strong>";
+ $('search_help').innerHTML ="<br><strong>You can change options while running.<br>To Stop search, change update frequency to Never.</strong>";
var q_args=loopSelected('qshape');
var pars = 'cmd='+$('cmd').options[$('cmd').selectedIndex].value;
var pars = pars + '&qshape='+q_args;
diff --git a/config/sarg/sarg_realtime.php b/config/sarg/sarg_realtime.php
index 81ea0a79..c5d926e5 100755
--- a/config/sarg/sarg_realtime.php
+++ b/config/sarg/sarg_realtime.php
@@ -220,7 +220,7 @@ else{
//prevent multiple instances
if ($('run').value=="show log" || loop== 'running'){
$('run').value="running...";
- $('search_help').innerHTML ="<br><strong>You can change options while running.<br>To Stop seach, change update frequency to Never.</strong>";
+ $('search_help').innerHTML ="<br><strong>You can change options while running.<br>To Stop search, change update frequency to Never.</strong>";
var axel = Math.random() + "";
var num = axel * 1000000000000000000;
var q_args=loopSelected('qshape');
diff --git a/config/sarg/sarg_schedule.xml b/config/sarg/sarg_schedule.xml
index 6080e530..5123d786 100644
--- a/config/sarg/sarg_schedule.xml
+++ b/config/sarg/sarg_schedule.xml
@@ -144,7 +144,7 @@
To force sarg to create a report only for specific days, use:<br>
<b>TODAY:</b>&nbsp;&nbsp;-d `date +%d/%m/%Y`<br>
<b>YESTERDAY:</b>&nbsp;&nbsp;-d `date -v-1d +%d/%m/%Y`<br>
- <b>WEEKAGO:</b>&nbsp;&nbsp;-d `date -v-1w +%d/%m/%Y`- `date -v-1d +%d/%m/%Y`<br>
+ <b>WEEKAGO:</b>&nbsp;&nbsp;-d `date -v-1w +%d/%m/%Y`-`date -v-1d +%d/%m/%Y`<br>
<b>MONTHAGO:</b>&nbsp;&nbsp;-d `date -v-1m +01/%m/%Y`-`date -v-1m +31/%m/%Y`]]></description>
<type>input</type>
<size>50</size>
diff --git a/config/siproxd.inc b/config/siproxd.inc
index 7e72c868..d76f79d3 100644
--- a/config/siproxd.inc
+++ b/config/siproxd.inc
@@ -29,6 +29,7 @@
if(!function_exists("filter_configure"))
require_once("filter.inc");
+require_once("service-utils.inc");
// Check to find out on which system the package is running
if (substr(trim(file_get_contents("/etc/version")),0,3) == "2.0") {
diff --git a/config/siproxd.xml b/config/siproxd.xml
index 27d00f32..dd833629 100644
--- a/config/siproxd.xml
+++ b/config/siproxd.xml
@@ -37,7 +37,7 @@
<requirements>Describe your package requirements here</requirements>
<faq>Currently there are no FAQ items provided.</faq>
<name>siproxdsettings</name>
- <version>0.8.0_2 pkg v1.0.1</version>
+ <version>0.8.0_2 pkg v1.0.2</version>
<title>siproxd: Settings</title>
<include_file>/usr/local/pkg/siproxd.inc</include_file>
<aftersaveredirect>/pkg_edit.php?xml=siproxd.xml&amp;id=0</aftersaveredirect>
diff --git a/config/snort/snort.inc b/config/snort/snort.inc
index 5c113d27..bec163d7 100755
--- a/config/snort/snort.inc
+++ b/config/snort/snort.inc
@@ -36,9 +36,8 @@ require_once("config.inc");
require_once("functions.inc");
require_once("service-utils.inc");
require_once("pkg-utils.inc");
-
-// Needed on 2.0 because of filter_get_vpns_list()
require_once("filter.inc");
+require("/usr/local/pkg/snort/snort_defs.inc");
// Snort GUI needs some extra PHP memory space to manipulate large rules arrays
ini_set("memory_limit", "256M");
@@ -48,47 +47,12 @@ global $g, $config, $rebuild_rules, $pfSense_snort_version;
// Grab the Snort binary version programmatically, but if that fails use a safe default
$snortver = array();
-exec("/usr/local/bin/snort -V 2>&1 |/usr/bin/grep Version | /usr/bin/cut -c20-26", $snortver);
-
-/* Used to indicate latest version of this include file has been loaded */
-$pfSense_snort_version = "3.1.5";
+$snortbindir = SNORT_PBI_BINDIR;
+exec("{$snortbindir}snort -V 2>&1 |/usr/bin/grep Version | /usr/bin/cut -c20-26", $snortver);
/* get installed package version for display */
$snort_package_version = "Snort {$config['installedpackages']['package'][get_pkg_id("snort")]['version']}";
-// Define SNORTDIR and SNORTLIBDIR constants according to pfSense version
-$pfs_version=substr(trim(file_get_contents("/etc/version")),0,3);
-if ($pfs_version >= 2.2) {
- define("SNORTDIR", "/usr/pbi/snort-" . php_uname("m") . "/local/etc/snort");
- define("SNORTLIBDIR", "/usr/pbi/snort-" . php_uname("m") . "/local/lib/snort");
-}
-else {
- define("SNORTDIR", "/usr/pbi/snort-" . php_uname("m") . "/etc/snort");
- define("SNORTLIBDIR", "/usr/pbi/snort-" . php_uname("m") . "/lib/snort");
-}
-
-/* Define some useful constants for Snort */
-/* Be sure to include trailing slash on the URL defines */
-define("SNORTLOGDIR", "{$g['varlog_path']}/snort");
-define("SNORT_BIN_VERSION", "2.9.6.2");
-define("SNORT_ET_DNLD_FILENAME", "emerging.rules.tar.gz");
-define("SNORT_ETPRO_DNLD_FILENAME", "etpro.rules.tar.gz");
-define("SNORT_GPLV2_DNLD_FILENAME", "community-rules.tar.gz");
-define("SNORT_ENFORCING_RULES_FILENAME", "snort.rules");
-define("SNORT_RULES_UPD_LOGFILE", SNORTLOGDIR . "/snort_rules_update.log");
-define("SNORT_IPREP_PATH", "{$g['vardb_path']}/snort/iprep/");
-define('SNORT_SID_MODS_PATH', "{$g['vardb_path']}/snort/sidmods/");
-if (!defined("FLOWBITS_FILENAME"))
- define("FLOWBITS_FILENAME", "flowbit-required.rules");
-if (!defined("VRT_FILE_PREFIX"))
- define("VRT_FILE_PREFIX", "snort_");
-if (!defined("GPL_FILE_PREFIX"))
- define("GPL_FILE_PREFIX", "GPLv2_");
-if (!defined("ET_OPEN_FILE_PREFIX"))
- define("ET_OPEN_FILE_PREFIX", "emerging-");
-if (!defined("ET_PRO_FILE_PREFIX"))
- define("ET_PRO_FILE_PREFIX", "etpro-");
-
/* Rebuild Rules Flag -- if "true", rebuild enforcing rules and flowbit-rules files */
$rebuild_rules = false;
@@ -599,13 +563,14 @@ function snort_barnyard_start($snortcfg, $if_real, $background=FALSE) {
$snortdir = SNORTDIR;
$snortlogdir = SNORTLOGDIR;
$snort_uuid = $snortcfg['uuid'];
+ $snortbindir = SNORT_PBI_BINDIR;
if ($snortcfg['barnyard_enable'] == 'on' && !isvalidpid("{$g['varrun_path']}/barnyard2_{$if_real}{$snort_uuid}.pid")) {
log_error("[Snort] Barnyard2 START for " . convert_real_interface_to_friendly_descr($if_real) . "({$if_real})...");
if ($background)
- mwexec_bg("/usr/local/bin/barnyard2 -r {$snort_uuid} -f \"snort_{$snort_uuid}_{$if_real}.u2\" --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d {$snortlogdir}/snort_{$if_real}{$snort_uuid} -D -q");
+ mwexec_bg("{$snortbindir}barnyard2 -r {$snort_uuid} -f \"snort_{$snort_uuid}_{$if_real}.u2\" --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d {$snortlogdir}/snort_{$if_real}{$snort_uuid} -D -q");
else
- mwexec("/usr/local/bin/barnyard2 -r {$snort_uuid} -f \"snort_{$snort_uuid}_{$if_real}.u2\" --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d {$snortlogdir}/snort_{$if_real}{$snort_uuid} -D -q");
+ mwexec("{$snortbindir}barnyard2 -r {$snort_uuid} -f \"snort_{$snort_uuid}_{$if_real}.u2\" --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d {$snortlogdir}/snort_{$if_real}{$snort_uuid} -D -q");
}
}
@@ -615,13 +580,19 @@ function snort_start($snortcfg, $if_real, $background=FALSE) {
$snortdir = SNORTDIR;
$snortlogdir = SNORTLOGDIR;
$snort_uuid = $snortcfg['uuid'];
+ $snortbindir = SNORT_PBI_BINDIR;
+
+ if ($config['installedpackages']['snortglobal']['verbose_logging'] == "on")
+ $quiet = "";
+ else
+ $quiet = "-q --suppress-config-log";
if ($snortcfg['enable'] == 'on' && !isvalidpid("{$g['varrun_path']}/snort_{$if_real}{$snort_uuid}.pid")) {
log_error("[Snort] Snort START for " . convert_real_interface_to_friendly_descr($if_real) . "({$if_real})...");
if ($background)
- mwexec_bg("/usr/local/bin/snort -R {$snort_uuid} -D -q -l {$snortlogdir}/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}");
+ mwexec_bg("{$snortbindir}snort -R {$snort_uuid} -D {$quiet} -l {$snortlogdir}/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}");
else
- mwexec("/usr/local/bin/snort -R {$snort_uuid} -D -q -l {$snortlogdir}/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}");
+ mwexec("{$snortbindir}snort -R {$snort_uuid} -D {$quiet} -l {$snortlogdir}/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real}");
snort_barnyard_start($snortcfg, $if_real, $background);
}
}
@@ -2735,11 +2706,12 @@ function snort_load_sid_mods($sids) {
if (preg_match('/(\d+)\s*:\s*(\d+)/', $v, $match)) {
if (!is_array($result[$match[1]]))
$result[$match[1]] = array();
+ if (!is_array($result[$match[1]][$match[2]]))
+ $result[$match[1]][$match[2]] = array();
$result[$match[1]][$match[2]] = "{$match[1]}:{$match[2]}";
}
}
unset($tmp);
-
return $result;
}
@@ -2804,6 +2776,7 @@ function snort_create_rc() {
$snortdir = SNORTDIR;
$snortlogdir = SNORTLOGDIR;
+ $snortbindir = SNORT_PBI_BINDIR;
$rcdir = RCFILEPREFIX;
$snortconf = $config['installedpackages']['snortglobal']['rule'];
@@ -2814,6 +2787,12 @@ function snort_create_rc() {
return;
}
+ // See whether or not to enable detailed startup logging
+ if ($config['installedpackages']['snortglobal']['verbose_logging'] == "on")
+ $quiet = "";
+ else
+ $quiet = "-q --suppress-config-log";
+
// At least one interface is configured, so OK
$start_snort_iface_start = array();
$start_snort_iface_stop = array();
@@ -2837,7 +2816,7 @@ function snort_create_rc() {
fi
if [ -z \$pid ]; then
/usr/bin/logger -p daemon.info -i -t SnortStartup "Barnyard2 START for {$value['descr']}({$snort_uuid}_{$if_real})..."
- /usr/local/bin/barnyard2 -r {$snort_uuid} -f snort_{$snort_uuid}_{$if_real}.u2 --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d {$snortlogdir}/snort_{$if_real}{$snort_uuid} -D -q > /dev/null 2>&1
+ {$snortbindir}barnyard2 -r {$snort_uuid} -f snort_{$snort_uuid}_{$if_real}.u2 --pid-path {$g['varrun_path']} --nolock-pidfile -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/barnyard2.conf -d {$snortlogdir}/snort_{$if_real}{$snort_uuid} -D -q > /dev/null 2>&1
fi
EOE;
$stop_barnyard2 = <<<EOE
@@ -2888,7 +2867,7 @@ EOE;
if [ -z \$pid ]; then
/usr/bin/logger -p daemon.info -i -t SnortStartup "Snort START for {$value['descr']}({$snort_uuid}_{$if_real})..."
- /usr/local/bin/snort -R {$snort_uuid} -D -q -l {$snortlogdir}/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real} > /dev/null 2>&1
+ {$snortbindir}snort -R {$snort_uuid} -D {$quiet} -l {$snortlogdir}/snort_{$if_real}{$snort_uuid} --pid-path {$g['varrun_path']} --nolock-pidfile -G {$snort_uuid} -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf -i {$if_real} > /dev/null 2>&1
fi
{$start_barnyard2}
@@ -3106,7 +3085,7 @@ function snort_deinstall() {
global $config, $g;
$snortdir = SNORTDIR;
- $snortlibdir = SNORTLIBDIR;
+ $snortlibdir = "/usr/pbi/snort-" . php_uname("m") . "/lib";
$snortlogdir = SNORTLOGDIR;
$rcdir = RCFILEPREFIX;
$snort_rules_upd_log = SNORT_RULES_UPD_LOGFILE;
@@ -3115,7 +3094,7 @@ function snort_deinstall() {
log_error(gettext("[Snort] Snort package uninstall in progress..."));
/* Remove our rc.d startup shell script */
- unlink_if_exists("{$rcdir}snort_pkg.sh");
+ unlink_if_exists("{$rcdir}snort.sh");
/* Make sure all active Snort processes are terminated */
/* Log a message only if a running process is detected */
@@ -3205,6 +3184,8 @@ function snort_deinstall() {
rmdir_recursive("/usr/local/www/snort");
rmdir_recursive("/usr/local/etc/snort");
rmdir_recursive("/usr/local/lib/snort");
+ rmdir_recursive("/usr/local/lib/snort_dynamicengine");
+ rmdir_recursive("/usr/local/lib/snort_dynamicpreprocessor");
}
/* Keep this as a last step */
@@ -3518,10 +3499,9 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules, $persist_log = fa
* Format of array is: *
* "rule_option" => "dependent_preprocessor" *
* *
- * Last Update: 04/05/2013 *
+ * Last Update: 10/30/2014 *
* *
- * Added: http_inspect content modifiers and *
- * various "service" metadata values. *
+ * Added: appid: detection option *
* *
***************************************************/
$rule_opts_preprocs = array("ssl_version:" => "ssl_preproc","ssl_state:" => "ssl_preproc",
@@ -3544,7 +3524,8 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules, $persist_log = fa
"uricontent:" => "http_inspect", "urilen:" => "http_inspect",
"http_encode;" => "http_inspect", "service http" => "http_inspect",
"service imap" => "imap_preproc", "service pop2" => "pop_preproc",
- "service pop3" => "pop_preproc", "service smtp" => "smtp_preprocessor");
+ "service pop3" => "pop_preproc", "service smtp" => "smtp_preprocessor",
+ "appid:" => "appid_preproc" );
/***************************************************
* Iterate the enabled rules, and check for rule *
@@ -3650,7 +3631,7 @@ function snort_generate_conf($snortcfg) {
return;
$snortdir = SNORTDIR;
- $snortlibdir = SNORTLIBDIR;
+ $snortlibdir = SNORT_PBI_BASEDIR . "lib";
$snortlogdir = SNORTLOGDIR;
$flowbit_rules_file = FLOWBITS_FILENAME;
$snort_enforcing_rules_file = SNORT_ENFORCING_RULES_FILENAME;
diff --git a/config/snort/snort.priv.inc b/config/snort/snort.priv.inc
index 1af0e783..928ecb52 100644
--- a/config/snort/snort.priv.inc
+++ b/config/snort/snort.priv.inc
@@ -11,6 +11,7 @@ $priv_list['page-services-snort']['match'][] = "snort/snort_barnyard.php*";
$priv_list['page-services-snort']['match'][] = "snort/snort_blocked.php*";
$priv_list['page-services-snort']['match'][] = "snort/snort_check_for_rule_updates.php*";
$priv_list['page-services-snort']['match'][] = "snort/snort_define_servers.php*";
+$priv_list['page-services-snort']['match'][] = "snort/snort_defs.inc*";
$priv_list['page-services-snort']['match'][] = "snort/snort_download_rules.php*";
$priv_list['page-services-snort']['match'][] = "snort/snort_download_updates.php*";
$priv_list['page-services-snort']['match'][] = "snort/snort_edit_hat_data.php*";
diff --git a/config/snort/snort.xml b/config/snort/snort.xml
index 91d42532..fb23997c 100755
--- a/config/snort/snort.xml
+++ b/config/snort/snort.xml
@@ -46,8 +46,8 @@
<requirements>None</requirements>
<faq>Currently there are no FAQ items provided.</faq>
<name>Snort</name>
- <version>2.9.6.2</version>
- <title>Services:2.9.6.2 pkg v3.1.5</title>
+ <version>2.9.7.0</version>
+ <title>Services:2.9.7.0 pkg v3.2.2</title>
<include_file>/usr/local/pkg/snort/snort.inc</include_file>
<menu>
<name>Snort</name>
@@ -129,6 +129,11 @@
<item>https://packages.pfsense.org/packages/config/snort/snort_check_for_rule_updates.php</item>
</additional_files_needed>
<additional_files_needed>
+ <prefix>/usr/local/pkg/snort/</prefix>
+ <chmod>077</chmod>
+ <item>https://packages.pfsense.org/packages/config/snort/snort_defs.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
<prefix>/usr/local/www/snort/</prefix>
<chmod>077</chmod>
<item>https://packages.pfsense.org/packages/config/snort/snort_interfaces.php</item>
diff --git a/config/snort/snort_check_cron_misc.inc b/config/snort/snort_check_cron_misc.inc
index b39d8d1c..a2688b58 100644
--- a/config/snort/snort_check_cron_misc.inc
+++ b/config/snort/snort_check_cron_misc.inc
@@ -75,16 +75,21 @@ function snort_check_dir_size_limit($snortloglimitsize) {
@file_put_contents("{$snort_log_dir}/alert", "");
}
- // Cleanup any rotated perfmon stats logs
+ // Cleanup any perfmon stats logs
$files = array();
$list = glob("{$snort_log_dir}/*");
foreach ($list as $file) {
- if (preg_match('/(^\d{4}-\d{2}-\d{2}[\.]?[\d+]?)/', basename($file), $matches))
+ if (preg_match('/(^\d{4}-\d{2}-\d{2}[\.\d+]*)/', basename($file), $matches))
$files[] = $snort_log_dir . "/" . $matches[1];
}
foreach ($files as $file)
unlink_if_exists($file);
+ // Cleanup any AppID stats logs
+ $files = glob("{$snort_log_dir}/appid-stats.log.*");
+ foreach ($files as $file)
+ unlink_if_exists($file);
+
// This is needed if snort is run as snort user
mwexec('/bin/chmod 660 {$snort_log_dir}/*', true);
@@ -214,7 +219,7 @@ if ($config['installedpackages']['snortglobal']['enable_log_mgmt'] == 'on') {
$files = array();
$list = glob("{$snort_log_dir}/*");
foreach ($list as $file) {
- if (preg_match('/(^\d{4}-\d{2}-\d{2}[\.]?[\d+]?)/', basename($file), $matches))
+ if (preg_match('/(^\d{4}-\d{2}-\d{2}[\.\d+]*)/', basename($file), $matches))
$files[] = $snort_log_dir . "/" . $matches[1];
}
$prune_count = 0;
@@ -228,6 +233,22 @@ if ($config['installedpackages']['snortglobal']['enable_log_mgmt'] == 'on') {
if ($prune_count > 0)
log_error(gettext("[Snort] perfmon stats logs cleanup job removed {$prune_count} file(s) from {$snort_log_dir}/..."));
}
+
+ // Prune any aged-out AppID stats logs if any exist
+ if ($value['appid_stats_log_retention'] > 0) {
+ $now = time();
+ $files = glob("{$snort_log_dir}/app-stats.log.*");
+ $prune_count = 0;
+ foreach ($files as $f) {
+ if (($now - filemtime($f)) > ($value['appid_stats_log_retention'] * 3600)) {
+ $prune_count++;
+ unlink_if_exists($f);
+ }
+ }
+ unset($files);
+ if ($prune_count > 0)
+ log_error(gettext("[Snort] AppID stats logs cleanup job removed {$prune_count} file(s) from {$snort_log_dir}/..."));
+ }
}
}
diff --git a/config/snort/snort_check_for_rule_updates.php b/config/snort/snort_check_for_rule_updates.php
index edf99dc8..3106cb7b 100755
--- a/config/snort/snort_check_for_rule_updates.php
+++ b/config/snort/snort_check_for_rule_updates.php
@@ -32,46 +32,16 @@
require_once("functions.inc");
require_once("service-utils.inc");
-require_once "/usr/local/pkg/snort/snort.inc";
+require_once("/usr/local/pkg/snort/snort.inc");
+require("/usr/local/pkg/snort/snort_defs.inc");
global $g, $config, $pkg_interface, $snort_gui_include, $rebuild_rules;
-if (!defined("VRT_DNLD_URL"))
- define("VRT_DNLD_URL", "https://www.snort.org/rules/");
-if (!defined("SNORT_BIN_VERSION"))
- define("SNORT_BIN_VERSION", "2.9.6.2");
-if (!defined("ET_VERSION"))
- define("ET_VERSION", "2.9.0");
-if (!defined("ET_BASE_DNLD_URL"))
- define("ET_BASE_DNLD_URL", "http://rules.emergingthreats.net/");
-if (!defined("ETPRO_BASE_DNLD_URL"))
- define("ETPRO_BASE_DNLD_URL", "https://rules.emergingthreatspro.com/");
-if (!defined("SNORT_ET_DNLD_FILENAME"))
- define("SNORT_ET_DNLD_FILENAME", "emerging.rules.tar.gz");
-if (!defined("SNORT_ETPRO_DNLD_FILENAME"))
- define("SNORT_ETPRO_DNLD_FILENAME", "etpro.rules.tar.gz");
-if (!defined("SNORT_GPLV2_DNLD_FILENAME"))
- define("SNORT_GPLV2_DNLD_FILENAME", "community-rules.tar.gz");
-if (!defined("GPLV2_DNLD_URL"))
- define("GPLV2_DNLD_URL", "https://s3.amazonaws.com/snort-org/www/rules/community/");
-if (!defined("SNORT_RULES_UPD_LOGFILE"))
- define("SNORT_RULES_UPD_LOGFILE", SNORTLOGDIR . "/snort_rules_update.log");
-if (!defined("VRT_FILE_PREFIX"))
- define("VRT_FILE_PREFIX", "snort_");
-if (!defined("GPL_FILE_PREFIX"))
- define("GPL_FILE_PREFIX", "GPLv2_");
-if (!defined("ET_OPEN_FILE_PREFIX"))
- define("ET_OPEN_FILE_PREFIX", "emerging-");
-if (!defined("ET_PRO_FILE_PREFIX"))
- define("ET_PRO_FILE_PREFIX", "etpro-");
-if (!defined("SNORT_IPREP_PATH"))
- define("SNORT_IPREP_PATH", "{$g['vardb_path']}/snort/iprep/");
-
$snortdir = SNORTDIR;
-$snortlibdir = SNORTLIBDIR;
+$snortlibdir = "/usr/pbi/snort-" . php_uname("m") . "/lib";
$snortlogdir = SNORTLOGDIR;
$snortiprepdir = SNORT_IPREP_PATH;
-$snort_rules_upd_log = SNORT_RULES_UPD_LOGFILE;
+$snortbindir = SNORT_PBI_BINDIR;
$mounted_rw = FALSE;
/* Save the state of $pkg_interface so we can restore it */
@@ -89,6 +59,7 @@ $emergingthreats = $config['installedpackages']['snortglobal']['emergingthreats'
$etpro = $config['installedpackages']['snortglobal']['emergingthreats_pro'] == 'on' ? 'on' : 'off';
$snortcommunityrules = $config['installedpackages']['snortglobal']['snortcommunityrules'] == 'on' ? 'on' : 'off';
$vrt_enabled = $config['installedpackages']['snortglobal']['snortdownload'] == 'on' ? 'on' : 'off';
+$openappid_detectors = $config['installedpackages']['snortglobal']['openappid_detectors'] == 'on' ? 'on' : 'off';
/* Working directory for downloaded rules tarballs and extraction */
$tmpfname = "{$g['tmp_path']}/snort_rules_up";
@@ -97,7 +68,7 @@ $tmpfname = "{$g['tmp_path']}/snort_rules_up";
/* the proper Snort VRT rules tarball and md5 filenames. Fallback to a */
/* default in the event we fail. */
$snortver = array();
-exec("/usr/local/bin/snort -V 2>&1 |/usr/bin/grep Version | /usr/bin/cut -c20-26", $snortver);
+exec("{$snortbindir}snort -V 2>&1 |/usr/bin/grep Version | /usr/bin/cut -c20-26", $snortver);
// Save the version with decimal delimiters for use in extracting the rules
$snort_version = $snortver[0];
if (empty($snort_version))
@@ -143,6 +114,11 @@ $snort_community_rules_filename = SNORT_GPLV2_DNLD_FILENAME;
$snort_community_rules_filename_md5 = SNORT_GPLV2_DNLD_FILENAME . ".md5";
$snort_community_rules_url = GPLV2_DNLD_URL;
+/* Snort OpenAppID detectors filename and URL */
+$snort_openappid_filename = SNORT_OPENAPPID_DNLD_FILENAME;
+$snort_openappid_filename_md5 = SNORT_OPENAPPID_DNLD_FILENAME . ".md5";
+$snort_openappid_url = SNORT_OPENAPPID_DNLD_URL;
+
function snort_download_file_url($url, $file_out) {
/************************************************/
@@ -293,21 +269,21 @@ function snort_check_rule_md5($file_url, $file_dst, $desc = "") {
/* error occurred. */
/**********************************************************/
- global $pkg_interface, $snort_rules_upd_log, $last_curl_error, $update_errors;
+ global $pkg_interface, $last_curl_error, $update_errors;
$snortdir = SNORTDIR;
$filename_md5 = basename($file_dst);
if ($pkg_interface <> "console")
update_status(gettext("Downloading {$desc} md5 file..."));
- error_log(gettext("\tDownloading {$desc} md5 file {$filename_md5}...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tDownloading {$desc} md5 file {$filename_md5}...\n"), 3, SNORT_RULES_UPD_LOGFILE);
$rc = snort_download_file_url($file_url, $file_dst);
// See if download from URL was successful
if ($rc === true) {
if ($pkg_interface <> "console")
update_status(gettext("Done downloading {$filename_md5}."));
- error_log("\tChecking {$desc} md5 file...\n", 3, $snort_rules_upd_log);
+ error_log("\tChecking {$desc} md5 file...\n", 3, SNORT_RULES_UPD_LOGFILE);
// check md5 hash in new file against current file to see if new download is posted
if (file_exists("{$snortdir}/{$filename_md5}")) {
@@ -317,7 +293,7 @@ function snort_check_rule_md5($file_url, $file_dst, $desc = "") {
if ($pkg_interface <> "console")
update_status(gettext("{$desc} are up to date..."));
log_error(gettext("[Snort] {$desc} are up to date..."));
- error_log(gettext("\t{$desc} are up to date.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\t{$desc} are up to date.\n"), 3, SNORT_RULES_UPD_LOGFILE);
return false;
}
else
@@ -326,7 +302,7 @@ function snort_check_rule_md5($file_url, $file_dst, $desc = "") {
return true;
}
else {
- error_log(gettext("\t{$desc} md5 download failed.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\t{$desc} md5 download failed.\n"), 3, SNORT_RULES_UPD_LOGFILE);
$snort_err_msg = gettext("Server returned error code {$rc}.");
if ($pkg_interface <> "console") {
update_status(gettext("{$desc} md5 error ... Server returned error code {$rc} ..."));
@@ -334,9 +310,9 @@ function snort_check_rule_md5($file_url, $file_dst, $desc = "") {
}
log_error(gettext("[Snort] {$desc} md5 download failed..."));
log_error(gettext("[Snort] Server returned error code {$rc}..."));
- error_log(gettext("\t{$snort_err_msg}\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\tServer error message was: {$last_curl_error}\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\t{$desc} will not be updated.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\t{$snort_err_msg}\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\tServer error message was: {$last_curl_error}\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\t{$desc} will not be updated.\n"), 3, SNORT_RULES_UPD_LOGFILE);
$update_errors = true;
return false;
}
@@ -361,7 +337,7 @@ function snort_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
/* FALSE if download was not successful. */
/**********************************************************/
- global $pkg_interface, $snort_rules_upd_log, $last_curl_error, $update_errors;
+ global $pkg_interface, $last_curl_error, $update_errors;
$snortdir = SNORTDIR;
$filename = basename($file_dst);
@@ -369,8 +345,8 @@ function snort_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
if ($pkg_interface <> "console")
update_status(gettext("There is a new set of {$desc} posted. Downloading..."));
log_error(gettext("[Snort] There is a new set of {$desc} posted. Downloading {$filename}..."));
- error_log(gettext("\tThere is a new set of {$desc} posted.\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\tDownloading file '{$filename}'...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tThere is a new set of {$desc} posted.\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\tDownloading file '{$filename}'...\n"), 3, SNORT_RULES_UPD_LOGFILE);
$rc = snort_download_file_url($file_url, $file_dst);
// See if the download from the URL was successful
@@ -378,7 +354,7 @@ function snort_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
if ($pkg_interface <> "console")
update_status(gettext("Done downloading {$desc} file."));
log_error("[Snort] {$desc} file update downloaded successfully");
- error_log(gettext("\tDone downloading rules file.\n"),3, $snort_rules_upd_log);
+ error_log(gettext("\tDone downloading rules file.\n"),3, SNORT_RULES_UPD_LOGFILE);
// Test integrity of the rules file. Turn off update if file has wrong md5 hash
if ($file_md5 != trim(md5_file($file_dst))){
@@ -387,10 +363,10 @@ function snort_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
log_error(gettext("[Snort] {$desc} file download failed. Bad MD5 checksum..."));
log_error(gettext("[Snort] Downloaded File MD5: " . md5_file($file_dst)));
log_error(gettext("[Snort] Expected File MD5: {$file_md5}"));
- error_log(gettext("\t{$desc} file download failed. Bad MD5 checksum.\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\tDownloaded {$desc} file MD5: " . md5_file($file_dst) . "\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\tExpected {$desc} file MD5: {$file_md5}\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\t{$desc} file download failed. {$desc} will not be updated.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\t{$desc} file download failed. Bad MD5 checksum.\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\tDownloaded {$desc} file MD5: " . md5_file($file_dst) . "\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\tExpected {$desc} file MD5: {$file_md5}\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\t{$desc} file download failed. {$desc} will not be updated.\n"), 3, SNORT_RULES_UPD_LOGFILE);
$update_errors = true;
return false;
}
@@ -400,9 +376,9 @@ function snort_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
if ($pkg_interface <> "console")
update_output_window(gettext("{$desc} file download failed..."));
log_error(gettext("[Snort] {$desc} file download failed... server returned error '{$rc}'..."));
- error_log(gettext("\t{$desc} file download failed. Server returned error {$rc}.\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\tThe error text was: {$last_curl_error}\n"), 3, $snort_rules_upd_log);
- error_log(gettext("\t{$desc} will not be updated.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\t{$desc} file download failed. Server returned error {$rc}.\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\tThe error text was: {$last_curl_error}\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ error_log(gettext("\t{$desc} will not be updated.\n"), 3, SNORT_RULES_UPD_LOGFILE);
$update_errors = true;
return false;
}
@@ -422,18 +398,18 @@ safe_mkdir("{$snortdir}/rules");
safe_mkdir("{$snortdir}/signatures");
safe_mkdir("{$snortdir}/preproc_rules");
safe_mkdir("{$tmpfname}");
-safe_mkdir("{$snortlibdir}/dynamicrules");
+safe_mkdir("{$snortlibdir}/snort_dynamicrules");
safe_mkdir("{$snortlogdir}");
safe_mkdir("{$snortiprepdir}");
/* See if we need to automatically clear the Update Log based on 1024K size limit */
-if (file_exists($snort_rules_upd_log)) {
- if (1048576 < filesize($snort_rules_upd_log))
- unlink_if_exists("{$snort_rules_upd_log}");
+if (file_exists(SNORT_RULES_UPD_LOGFILE)) {
+ if (1048576 < filesize(SNORT_RULES_UPD_LOGFILE))
+ unlink_if_exists("{SNORT_RULES_UPD_LOGFILE}");
}
/* Log start time for this rules update */
-error_log(gettext("Starting rules update... Time: " . date("Y-m-d H:i:s") . "\n"), 3, $snort_rules_upd_log);
+error_log(gettext("Starting rules update... Time: " . date("Y-m-d H:i:s") . "\n"), 3, SNORT_RULES_UPD_LOGFILE);
$last_curl_error = "";
$update_errors = false;
@@ -449,9 +425,22 @@ if ($snortdownload == 'on') {
$snortdownload = 'off';
}
+/* Check for and download any new Snort OpenAppID detectors */
+if ($openappid_detectors == 'on') {
+ if (snort_check_rule_md5("{$snort_openappid_url}{$snort_openappid_filename}/md5", "{$tmpfname}/{$snort_openappid_filename_md5}", "Snort OpenAppID detectors")) {
+ $file_md5 = trim(file_get_contents("{$tmpfname}/{$snort_openappid_filename_md5}"));
+ file_put_contents("{$tmpfname}/{$snort_openappid_filename_md5}", $file_md5);
+ /* download snort-openappid file */
+ if (!snort_fetch_new_rules("{$snort_openappid_url}{$snort_openappid_filename}", "{$tmpfname}/{$snort_openappid_filename}", $file_md5, "Snort OpenAppID detectors"))
+ $openappid_detectors = 'off';
+ }
+ else
+ $openappid_detectors = 'off';
+}
+
/* Check for and download any new Snort GPLv2 Community Rules sigs */
if ($snortcommunityrules == 'on') {
- if (snort_check_rule_md5("{$snort_community_rules_url}{$snort_community_rules_filename_md5}", "{$tmpfname}/{$snort_community_rules_filename_md5}", "Snort GPLv2 Community Rules")) {
+ if (snort_check_rule_md5("{$snort_community_rules_url}{$snort_community_rules_filename}/md5", "{$tmpfname}/{$snort_community_rules_filename_md5}", "Snort GPLv2 Community Rules")) {
/* download Snort GPLv2 Community Rules file */
$file_md5 = trim(file_get_contents("{$tmpfname}/{$snort_community_rules_filename_md5}"));
if (!snort_fetch_new_rules("{$snort_community_rules_url}{$snort_community_rules_filename}", "{$tmpfname}/{$snort_community_rules_filename}", $file_md5, "Snort GPLv2 Community Rules"))
@@ -492,7 +481,7 @@ if ($snortdownload == 'on') {
update_status(gettext("Extracting Snort VRT rules..."));
update_output_window(gettext("Installing Sourcefire VRT rules..."));
}
- error_log(gettext("\tExtracting and installing Snort VRT rules...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tExtracting and installing Snort VRT rules...\n"), 3, SNORT_RULES_UPD_LOGFILE);
/* extract snort.org rules and add VRT_FILE_PREFIX prefix to all snort.org files */
safe_mkdir("{$tmpfname}/snortrules");
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$tmpfname}/snortrules rules/");
@@ -507,7 +496,7 @@ if ($snortdownload == 'on') {
$newfile = basename($file);
@copy($file, "{$snortdir}/rules/{$newfile}");
}
- exec("rm -r {$tmpfname}/snortrules");
+ rmdir_recursive("{$tmpfname}/snortrules");
/* Extract the Snort preprocessor rules */
if ($pkg_interface <> "console")
update_output_window(gettext("Extracting preprocessor rules files..."));
@@ -517,22 +506,21 @@ if ($snortdownload == 'on') {
$newfile = basename($file);
@copy($file, "{$snortdir}/preproc_rules/{$newfile}");
}
- exec("rm -r {$tmpfname}/preproc_rules");
+ rmdir_recursive("{$tmpfname}/preproc_rules");
/* extract so rules */
if ($pkg_interface <> "console") {
update_status(gettext("Extracting Snort VRT Shared Objects rules..."));
update_output_window(gettext("Installing precompiled Shared Objects rules for {$freebsd_version_so}..."));
}
- exec("/bin/mkdir -p {$snortlibdir}/dynamicrules/");
- error_log(gettext("\tUsing Snort VRT precompiled SO rules for {$freebsd_version_so} ...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tUsing Snort VRT precompiled SO rules for {$freebsd_version_so} ...\n"), 3, SNORT_RULES_UPD_LOGFILE);
$snort_arch = php_uname("m");
$nosorules = false;
if ($snort_arch == 'i386'){
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$tmpfname} so_rules/precompiled/{$freebsd_version_so}/i386/{$snort_version}/");
- exec("/bin/cp {$tmpfname}/so_rules/precompiled/{$freebsd_version_so}/i386/{$snort_version}/*.so {$snortlibdir}/dynamicrules/");
+ exec("/bin/cp {$tmpfname}/so_rules/precompiled/{$freebsd_version_so}/i386/{$snort_version}/*.so {$snortlibdir}/snort_dynamicrules/");
} elseif ($snort_arch == 'amd64') {
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$tmpfname} so_rules/precompiled/{$freebsd_version_so}/x86-64/{$snort_version}/");
- exec("/bin/cp {$tmpfname}/so_rules/precompiled/{$freebsd_version_so}/x86-64/{$snort_version}/*.so {$snortlibdir}/dynamicrules/");
+ exec("/bin/cp {$tmpfname}/so_rules/precompiled/{$freebsd_version_so}/x86-64/{$snort_version}/*.so {$snortlibdir}/snort_dynamicrules/");
} else
$nosorules = true;
rmdir_recursive("{$tmpfname}/so_rules/");
@@ -558,7 +546,7 @@ if ($snortdownload == 'on') {
if (file_exists("{$tmpfname}/etc/{$file}"))
@copy("{$tmpfname}/etc/{$file}", "{$tmpfname}/VRT_{$file}");
}
- exec("rm -r {$tmpfname}/etc");
+ rmdir_recursive("{$tmpfname}/etc");
if (file_exists("{$tmpfname}/{$snort_filename_md5}")) {
if ($pkg_interface <> "console")
update_status(gettext("Copying md5 signature to snort directory..."));
@@ -568,7 +556,30 @@ if ($snortdownload == 'on') {
update_status(gettext("Extraction of Snort VRT rules completed..."));
update_output_window(gettext("Installation of Sourcefire VRT rules completed..."));
}
- error_log(gettext("\tInstallation of Snort VRT rules completed.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tInstallation of Snort VRT rules completed.\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ }
+}
+
+/* Untar Snort OpenAppID detectors file to SNORT_APPID_ODP_PATH */
+if ($openappid_detectors == 'on') {
+ // If we have a valid downloaded file, then first cleanup the old directory
+ if (file_exists("{$tmpfname}/{$snort_openappid_filename}")) {
+ $snort_openappid_path = SNORT_APPID_ODP_PATH;
+ rmdir_recursive("{$snort_openappid_path}odp");
+ error_log(gettext("\tExtracting and installing Snort OpenAppID detectors...\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ safe_mkdir(SNORT_APPID_ODP_PATH);
+ exec("/usr/bin/tar oxzf {$tmpfname}/{$snort_openappid_filename} -C {$snort_openappid_path}");
+ if (file_exists("{$tmpfname}/{$snort_openappid_filename_md5}")) {
+ if ($pkg_interface <> "console")
+ update_status(gettext("Copying md5 signature to snort directory..."));
+ @copy("{$tmpfname}/{$snort_openappid_filename_md5}", "{$snortdir}/{$snort_openappid_filename_md5}");
+ }
+ if ($pkg_interface <> "console") {
+ update_status(gettext("Extraction of Snort OpenAppID detectors completed..."));
+ update_output_window(gettext("Installation of Snort OpenAppID detectors completed..."));
+ }
+ unlink_if_exists("{$tmpfname}/{$snort_openappid_filename}");
+ error_log(gettext("\tInstallation of Snort OpenAppID detectors completed.\n"), 3, SNORT_RULES_UPD_LOGFILE);
}
}
@@ -580,7 +591,7 @@ if ($snortcommunityrules == 'on') {
update_status(gettext("Extracting Snort GPLv2 Community Rules..."));
update_output_window(gettext("Installing Snort GPLv2 Community Rules..."));
}
- error_log(gettext("\tExtracting and installing Snort GPLv2 Community Rules...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tExtracting and installing Snort GPLv2 Community Rules...\n"), 3, SNORT_RULES_UPD_LOGFILE);
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_community_rules_filename} -C {$tmpfname}/community/");
$files = glob("{$tmpfname}/community/community-rules/*.rules");
@@ -603,7 +614,7 @@ if ($snortcommunityrules == 'on') {
update_status(gettext("Extraction of Snort GPLv2 Community Rules completed..."));
update_output_window(gettext("Installation of Snort GPLv2 Community Rules file completed..."));
}
- error_log(gettext("\tInstallation of Snort GPLv2 Community Rules completed.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tInstallation of Snort GPLv2 Community Rules completed.\n"), 3, SNORT_RULES_UPD_LOGFILE);
rmdir_recursive("{$tmpfname}/community/");
}
}
@@ -616,7 +627,7 @@ if ($emergingthreats == 'on') {
update_status(gettext("Extracting {$et_name} rules..."));
update_output_window(gettext("Installing {$et_name} rules..."));
}
- error_log(gettext("\tExtracting and installing {$et_name} rules...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tExtracting and installing {$et_name} rules...\n"), 3, SNORT_RULES_UPD_LOGFILE);
exec("/usr/bin/tar xzf {$tmpfname}/{$emergingthreats_filename} -C {$tmpfname}/emerging rules/");
/* Remove the old Emerging Threats rules files */
@@ -664,7 +675,7 @@ if ($emergingthreats == 'on') {
update_status(gettext("Extraction of {$et_name} rules completed..."));
update_output_window(gettext("Installation of {$et_name} rules completed..."));
}
- error_log(gettext("\tInstallation of {$et_name} rules completed.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tInstallation of {$et_name} rules completed.\n"), 3, SNORT_RULES_UPD_LOGFILE);
rmdir_recursive("{$tmpfname}/emerging/");
}
}
@@ -698,7 +709,7 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
if ($pkg_interface <> "console")
update_status(gettext('Copying new config and map files...'));
- error_log(gettext("\tCopying new config and map files...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tCopying new config and map files...\n"), 3, SNORT_RULES_UPD_LOGFILE);
/******************************************************************/
/* Build the classification.config and reference.config files */
@@ -757,8 +768,8 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
safe_mkdir("{$snortdir}/snort_{$value['uuid']}_{$if_real}/rules");
if (!is_dir("{$snortdir}/snort_{$value['uuid']}_{$if_real}/preproc_rules"))
safe_mkdir("{$snortdir}/snort_{$value['uuid']}_{$if_real}/preproc_rules");
- if (!is_dir("{$snortdir}/snort_{$value['uuid']}_{$if_real}/dynamicpreprocessor"))
- safe_mkdir("{$snortdir}/snort_{$value['uuid']}_{$if_real}/dynamicpreprocessor");
+ if (!is_dir("{$snortdir}/snort_{$value['uuid']}_{$if_real}/snort_dynamicpreprocessor"))
+ safe_mkdir("{$snortdir}/snort_{$value['uuid']}_{$if_real}/snort_dynamicpreprocessor");
snort_apply_customizations($value, $if_real);
@@ -768,7 +779,7 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
$tmp .= gettext("\tPreprocessor text rules flagged as protected and not updated for ");
$tmp .= convert_friendly_interface_to_friendly_descr($value['interface']) . "...\n";
}
- error_log($tmp, 3, $snort_rules_upd_log);
+ error_log($tmp, 3, SNORT_RULES_UPD_LOGFILE);
}
}
else {
@@ -776,7 +787,7 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
update_output_window(gettext("Warning: No interfaces configured for Snort were found..."));
update_output_window(gettext("No interfaces currently have Snort configured and enabled on them..."));
}
- error_log(gettext("\tWarning: No interfaces configured for Snort were found...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tWarning: No interfaces configured for Snort were found...\n"), 3, SNORT_RULES_UPD_LOGFILE);
}
/* Clear the rebuild rules flag. */
@@ -788,7 +799,7 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
update_status(gettext('Restarting Snort to activate the new set of rules...'));
update_output_window(gettext("Please wait ... restarting Snort will take some time..."));
}
- error_log(gettext("\tRestarting Snort to activate the new set of rules...\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tRestarting Snort to activate the new set of rules...\n"), 3, SNORT_RULES_UPD_LOGFILE);
touch("{$g['varrun_path']}/snort_pkg_starting.lck");
snort_restart_all_interfaces(TRUE);
sleep(3);
@@ -796,7 +807,32 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
if ($pkg_interface <> "console")
update_output_window(gettext("Snort has restarted with your new set of rules..."));
log_error(gettext("[Snort] Snort has restarted with your new set of rules..."));
- error_log(gettext("\tSnort has restarted with your new set of rules.\n"), 3, $snort_rules_upd_log);
+ error_log(gettext("\tSnort has restarted with your new set of rules.\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ }
+ else {
+ if ($pkg_interface <> "console")
+ update_output_window(gettext("The rules update task is complete..."));
+ }
+}
+elseif ($openappid_detectors == 'on') {
+ /**************************************************************************************/
+ /* Only updated OpenAppID detectors, so do not need to rebuild all interface rules. */
+ /* Restart snort if running, and not in post-install, so as to pick up the detectors. */
+ /**************************************************************************************/
+ if (!$g['snort_postinstall'] && is_service_running("snort") && count($config['installedpackages']['snortglobal']['rule']) > 0) {
+ if ($pkg_interface <> "console") {
+ update_status(gettext('Restarting Snort to activate the new OpenAppID detectors...'));
+ update_output_window(gettext("Please wait ... restarting Snort will take some time..."));
+ }
+ error_log(gettext("\tRestarting Snort to activate the new OpenAppID detectors...\n"), 3, SNORT_RULES_UPD_LOGFILE);
+ touch("{$g['varrun_path']}/snort_pkg_starting.lck");
+ snort_restart_all_interfaces(TRUE);
+ sleep(2);
+ unlink_if_exists("{$g['varrun_path']}/snort_pkg_starting.lck");
+ if ($pkg_interface <> "console")
+ update_output_window(gettext("Snort has restarted with your new set of OpenAppID detectors..."));
+ log_error(gettext("[Snort] Snort has restarted with your new set of OpenAppID detectors..."));
+ error_log(gettext("\tSnort has restarted with your new set of OpenAppID detectors.\n"), 3, SNORT_RULES_UPD_LOGFILE);
}
else {
if ($pkg_interface <> "console")
@@ -812,7 +848,7 @@ if (is_dir("{$tmpfname}")) {
if ($pkg_interface <> "console")
update_status(gettext("The Rules update has finished..."));
log_error(gettext("[Snort] The Rules update has finished."));
-error_log(gettext("The Rules update has finished. Time: " . date("Y-m-d H:i:s"). "\n\n"), 3, $snort_rules_upd_log);
+error_log(gettext("The Rules update has finished. Time: " . date("Y-m-d H:i:s"). "\n\n"), 3, SNORT_RULES_UPD_LOGFILE);
/* Remount filesystem read-only if we changed it in this module */
if ($mounted_rw == TRUE)
diff --git a/config/snort/snort_conf_template.inc b/config/snort/snort_conf_template.inc
index e1b11acc..6b362ce5 100644
--- a/config/snort/snort_conf_template.inc
+++ b/config/snort/snort_conf_template.inc
@@ -24,9 +24,6 @@ var RULE_PATH {$snortcfgdir}/rules
# Define Server Ports #
{$portvardef}
-# Configure quiet startup mode #
-config quiet
-
# Configure the snort decoder #
config checksum_mode: {$cksumcheck}
config disable_decode_alerts
diff --git a/config/snort/snort_defs.inc b/config/snort/snort_defs.inc
new file mode 100644
index 00000000..43ecada6
--- /dev/null
+++ b/config/snort/snort_defs.inc
@@ -0,0 +1,101 @@
+<?php
+/*
+ * snort_defs.inc
+ *
+ * Copyright (C) 2006 Scott Ullrich
+ * Copyright (C) 2009-2010 Robert Zelaya
+ * Copyright (C) 2011-2012 Ermal Luci
+ * Copyright (C) 2013,2014 Bill Meeks
+ * part of pfSense
+ * 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.
+ */
+
+global $g, $config;
+
+/* Define some useful constants for Snort */
+if (!defined("SNORT_PBI_BASEDIR"))
+ define("SNORT_PBI_BASEDIR", "/usr/pbi/snort-" . php_uname("m") . "/");
+if (!defined("SNORT_PBI_BINDIR"))
+ define("SNORT_PBI_BINDIR", SNORT_PBI_BASEDIR . "bin/");
+if (!defined("SNORTDIR"))
+ define("SNORTDIR", SNORT_PBI_BASEDIR . "etc/snort");
+if (!defined("SNORTLOGDIR"))
+ define("SNORTLOGDIR", "{$g['varlog_path']}/snort");
+if (!defined("SNORT_BIN_VERSION")) {
+ // Grab the Snort binary version programmatically
+ $snortver = array();
+ $snortbindir = SNORT_PBI_BINDIR;
+ mwexec("{$snortbindir}/snort -V 2>&1 |/usr/bin/grep Version | /usr/bin/cut -c20-26", $snortver);
+ if (!empty($snortver[0]))
+ define("SNORT_BIN_VERSION", $snortver[0]);
+ else
+ define("SNORT_BIN_VERSION", "2.9.7.0");
+}
+if (!defined("SNORT_SID_MODS_PATH"))
+ define('SNORT_SID_MODS_PATH', "{$g['vardb_path']}/snort/sidmods/");
+if (!defined("SNORT_IPREP_PATH"))
+ define("SNORT_IPREP_PATH", "{$g['vardb_path']}/snort/iprep/");
+if (!defined('SNORT_APPID_ODP_PATH'))
+ define('SNORT_APPID_ODP_PATH', SNORTDIR . "/appid/");
+
+// Rules filenames, download URLs and prefixes.
+// Be sure to include the trailing backslash on URLs.
+if (!defined("SNORT_ENFORCING_RULES_FILENAME"))
+ define("SNORT_ENFORCING_RULES_FILENAME", "snort.rules");
+if (!defined("FLOWBITS_FILENAME"))
+ define("FLOWBITS_FILENAME", "flowbit-required.rules");
+if (!defined("SNORT_RULES_UPD_LOGFILE"))
+ define("SNORT_RULES_UPD_LOGFILE", SNORTLOGDIR . "/snort_rules_update.log");
+if (!defined("VRT_DNLD_URL"))
+ define("VRT_DNLD_URL", "https://www.snort.org/rules/");
+if (!defined("ET_VERSION"))
+ define("ET_VERSION", "2.9.0");
+if (!defined("ET_BASE_DNLD_URL"))
+ define("ET_BASE_DNLD_URL", "http://rules.emergingthreats.net/");
+if (!defined("ETPRO_BASE_DNLD_URL"))
+ define("ETPRO_BASE_DNLD_URL", "https://rules.emergingthreatspro.com/");
+if (!defined("SNORT_ET_DNLD_FILENAME"))
+ define("SNORT_ET_DNLD_FILENAME", "emerging.rules.tar.gz");
+if (!defined("SNORT_ETPRO_DNLD_FILENAME"))
+ define("SNORT_ETPRO_DNLD_FILENAME", "etpro.rules.tar.gz");
+if (!defined("SNORT_GPLV2_DNLD_FILENAME"))
+ define("SNORT_GPLV2_DNLD_FILENAME", "community-rules.tar.gz");
+if (!defined("GPLV2_DNLD_URL"))
+ define("GPLV2_DNLD_URL", "https://www.snort.org/downloads/community/");
+if (!defined("SNORT_OPENAPPID_DNLD_URL"))
+ define("SNORT_OPENAPPID_DNLD_URL", "https://www.snort.org/downloads/openappid/");
+if (!defined("SNORT_OPENAPPID_DNLD_FILENAME"))
+ define("SNORT_OPENAPPID_DNLD_FILENAME", "snort-openappid.tar.gz");
+if (!defined("SNORT_RULES_UPD_LOGFILE"))
+ define("SNORT_RULES_UPD_LOGFILE", SNORTLOGDIR . "/snort_rules_update.log");
+if (!defined("VRT_FILE_PREFIX"))
+ define("VRT_FILE_PREFIX", "snort_");
+if (!defined("GPL_FILE_PREFIX"))
+ define("GPL_FILE_PREFIX", "GPLv2_");
+if (!defined("ET_OPEN_FILE_PREFIX"))
+ define("ET_OPEN_FILE_PREFIX", "emerging-");
+if (!defined("ET_PRO_FILE_PREFIX"))
+ define("ET_PRO_FILE_PREFIX", "etpro-");
+
+?>
diff --git a/config/snort/snort_download_updates.php b/config/snort/snort_download_updates.php
index e74a9ce6..3f34cb7e 100755
--- a/config/snort/snort_download_updates.php
+++ b/config/snort/snort_download_updates.php
@@ -39,24 +39,18 @@ require_once("/usr/local/pkg/snort/snort.inc");
/* Define some locally required variables from Snort constants */
$snortdir = SNORTDIR;
$snort_rules_upd_log = SNORT_RULES_UPD_LOGFILE;
+$snortbinver = SNORT_BIN_VERSION;
+$snortbinver = str_replace(".", "", $snortbinver);
-/* Grab the Snort binary version programmatically and */
-/* use it to construct the proper Snort VRT rules */
-/* tarball filename. Fallback to a safe default if */
-/* we fail. */
-$snortver = array();
-exec("/usr/local/bin/snort -V 2>&1 |/usr/bin/grep Version | /usr/bin/cut -c20-26", $snortver);
-if (empty($snortver[0]))
- $snortver[0] = SNORT_BIN_VERSION;
-$snortver[0] = str_replace(".", "", $snortver[0]);
-
-$snort_rules_file = "snortrules-snapshot-{$snortver[0]}.tar.gz";
+$snort_rules_file = "snortrules-snapshot-{$snortbinver}.tar.gz";
$snort_community_rules_filename = SNORT_GPLV2_DNLD_FILENAME;
+$snort_openappid_filename = SNORT_OPENAPPID_DNLD_FILENAME;
$snortdownload = $config['installedpackages']['snortglobal']['snortdownload'];
$emergingthreats = $config['installedpackages']['snortglobal']['emergingthreats'];
$etpro = $config['installedpackages']['snortglobal']['emergingthreats_pro'];
$snortcommunityrules = $config['installedpackages']['snortglobal']['snortcommunityrules'];
+$openappid_detectors = $config['installedpackages']['snortglobal']['openappid_detectors'];
/* Get last update information if available */
if (!empty($config['installedpackages']['snortglobal']['last_rule_upd_time']))
@@ -70,21 +64,21 @@ else
if ($etpro == "on") {
$emergingthreats_filename = SNORT_ETPRO_DNLD_FILENAME;
- $et_name = "Emerging Threats Pro Rules";
+ $et_name = gettext("Emerging Threats Pro Rules");
}
else {
$emergingthreats_filename = SNORT_ET_DNLD_FILENAME;
- $et_name = "Emerging Threats Open Rules";
+ $et_name = gettext("Emerging Threats Open Rules");
}
/* quick md5 chk of downloaded rules */
if ($snortdownload == 'on') {
- $snort_org_sig_chk_local = 'Not Downloaded';
- $snort_org_sig_date = 'Not Downloaded';
+ $snort_org_sig_chk_local = gettext("Not Downloaded");
+ $snort_org_sig_date = gettext("Not Downloaded");
}
else {
- $snort_org_sig_chk_local = 'Not Enabled';
- $snort_org_sig_date = 'Not Enabled';
+ $snort_org_sig_chk_local = gettext("Not Enabled");
+ $snort_org_sig_date = gettext("Not Enabled");
}
if (file_exists("{$snortdir}/{$snort_rules_file}.md5") && $snortdownload == 'on') {
$snort_org_sig_chk_local = file_get_contents("{$snortdir}/{$snort_rules_file}.md5");
@@ -92,12 +86,12 @@ if (file_exists("{$snortdir}/{$snort_rules_file}.md5") && $snortdownload == 'on'
}
if ($etpro == "on" || $emergingthreats == "on") {
- $emergingt_net_sig_chk_local = 'Not Downloaded';
- $emergingt_net_sig_date = 'Not Downloaded';
+ $emergingt_net_sig_chk_local = gettext("Not Downloaded");
+ $emergingt_net_sig_date = gettext("Not Downloaded");
}
else {
- $emergingt_net_sig_chk_local = 'Not Enabled';
- $emergingt_net_sig_date = 'Not Enabled';
+ $emergingt_net_sig_chk_local = gettext("Not Enabled");
+ $emergingt_net_sig_date = gettext("Not Enabled");
}
if (file_exists("{$snortdir}/{$emergingthreats_filename}.md5") && ($etpro == "on" || $emergingthreats == "on")) {
$emergingt_net_sig_chk_local = file_get_contents("{$snortdir}/{$emergingthreats_filename}.md5");
@@ -105,16 +99,29 @@ if (file_exists("{$snortdir}/{$emergingthreats_filename}.md5") && ($etpro == "on
}
if ($snortcommunityrules == 'on') {
- $snort_community_sig_chk_local = 'Not Downloaded';
- $snort_community_sig_sig_date = 'Not Downloaded';
+ $snort_community_sig_chk_local = gettext("Not Downloaded");
+ $snort_community_sig_date = gettext("Not Downloaded");
}
else {
- $snort_community_sig_chk_local = 'Not Enabled';
- $snort_community_sig_sig_date = 'Not Enabled';
+ $snort_community_sig_chk_local = gettext("Not Enabled");
+ $snort_community_sig_date = gettext("Not Enabled");
}
if (file_exists("{$snortdir}/{$snort_community_rules_filename}.md5") && $snortcommunityrules == 'on') {
$snort_community_sig_chk_local = file_get_contents("{$snortdir}/{$snort_community_rules_filename}.md5");
- $snort_community_sig_sig_date = date(DATE_RFC850, filemtime("{$snortdir}/{$snort_community_rules_filename}.md5"));
+ $snort_community_sig_date = date(DATE_RFC850, filemtime("{$snortdir}/{$snort_community_rules_filename}.md5"));
+}
+
+if ($openappid_detectors == 'on') {
+ $openappid_detectors_sig_chk_local = gettext("Not Downloaded");
+ $openappid_detectors_sig_date = gettext("Not Downloaded");
+}
+else {
+ $openappid_detectors_sig_chk_local = gettext("Not Enabled");
+ $openappid_detectors_sig_date = gettext("Not Enabled");
+}
+if (file_exists("{$snortdir}/{$snort_openappid_filename}.md5") && $openappid_detectors == 'on') {
+ $openappid_detectors_sig_chk_local = file_get_contents("{$snortdir}/{$snort_openappid_filename}.md5");
+ $openappid_detectors_sig_date = date(DATE_RFC850, filemtime("{$snortdir}/{$snort_openappid_filename}.md5"));
}
/* Check for postback to see if we should clear the update log file. */
@@ -122,7 +129,7 @@ if (isset($_POST['clear'])) {
unlink_if_exists($snort_rules_upd_log);
}
-if (isset($_POST['check'])) {
+if (isset($_POST['update'])) {
header("Location: /snort/snort_download_rules.php");
exit;
}
@@ -135,6 +142,7 @@ if ($_POST['force']) {
unlink_if_exists("{$snortdir}/{$emergingthreats_filename}.md5");
unlink_if_exists("{$snortdir}/{$snort_community_rules_filename}.md5");
unlink_if_exists("{$snortdir}/{$snort_rules_file}.md5");
+ unlink_if_exists("{$snortdir}/{$snort_openappid_filename}.md5");
// Revert file system to R/O.
conf_mount_ro();
@@ -204,20 +212,25 @@ include_once("head.inc");
</tr>
</thead>
<tr>
- <td align="center" class="vncell vexpl"><b>Snort VRT Rules</b></td>
+ <td align="center" class="vncell vexpl"><b><?=gettext("Snort VRT Rules");?></b></td>
<td align="center" class="vncell vexpl"><? echo trim($snort_org_sig_chk_local);?></td>
<td align="center" class="vncell vexpl"><?php echo gettext($snort_org_sig_date);?></td>
</tr>
<tr>
- <td align="center" class="vncell vexpl"><b>Snort GPLv2 Community Rules</b></td>
+ <td align="center" class="vncell vexpl"><b><?=gettext("Snort GPLv2 Community Rules");?></b></td>
<td align="center" class="vncell vexpl"><? echo trim($snort_community_sig_chk_local);?></td>
- <td align="center" class="vncell vexpl"><?php echo gettext($snort_community_sig_sig_date);?></td>
+ <td align="center" class="vncell vexpl"><?php echo gettext($snort_community_sig_date);?></td>
</tr>
<tr>
<td align="center" class="vncell vexpl"><b><?=$et_name;?></b></td>
<td align="center" class="vncell vexpl"><? echo trim($emergingt_net_sig_chk_local);?></td>
<td align="center" class="vncell vexpl"><?php echo gettext($emergingt_net_sig_date);?></td>
</tr>
+ <tr>
+ <td align="center" class="vncell vexpl"><b><?=gettext("Snort OpenAppID Detectors");?></b></td>
+ <td align="center" class="vncell vexpl"><? echo trim($openappid_detectors_sig_chk_local);?></td>
+ <td align="center" class="vncell vexpl"><?php echo gettext($openappid_detectors_sig_date);?></td>
+ </tr>
</table><br/>
</td>
</tr>
@@ -253,8 +266,8 @@ include_once("head.inc");
<br/></p>
<?php else: ?>
<br/>
- <input type="submit" value="<?=gettext("Check");?>" name="check" id="check" class="formbtn"
- title="<?php echo gettext("Check for new updates to enabled rule sets"); ?>"/>&nbsp;&nbsp;&nbsp;&nbsp;
+ <input type="submit" value="<?=gettext("Update");?>" name="update" id="update" class="formbtn"
+ title="<?php echo gettext("Check for and apply new update to enabled rule sets"); ?>"/>&nbsp;&nbsp;&nbsp;&nbsp;
<input type="submit" value="<?=gettext("Force");?>" name="force" id="force" class="formbtn"
title="<?=gettext("Force an update of all enabled rule sets");?>"
onclick="return confirm('<?=gettext("This will zero-out the MD5 hashes to force a fresh download of enabled rule sets. Click OK to continue or CANCEL to quit");?>');"/>
diff --git a/config/snort/snort_generate_conf.php b/config/snort/snort_generate_conf.php
index fb5c750f..1d56fc13 100644
--- a/config/snort/snort_generate_conf.php
+++ b/config/snort/snort_generate_conf.php
@@ -64,9 +64,9 @@ $snort_dirs = array( $snortdir, $snortcfgdir, "{$snortcfgdir}/rules",
"{$snortlogdir}/snort_{$if_real}{$snort_uuid}",
"{$snortlogdir}/snort_{$if_real}{$snort_uuid}/barnyard2",
"{$snortcfgdir}/preproc_rules",
- "dynamicrules" => "{$snortlibdir}/dynamicrules",
- "dynamicengine" => "{$snortlibdir}/dynamicengine",
- "dynamicpreprocessor" => "{$snortcfgdir}/dynamicpreprocessor"
+ "dynamicrules" => "{$snortlibdir}/snort_dynamicrules",
+ "dynamicengine" => "{$snortlibdir}/snort_dynamicengine",
+ "dynamicpreprocessor" => "{$snortcfgdir}/snort_dynamicpreprocessor"
);
foreach ($snort_dirs as $dir) {
if (!is_dir($dir))
@@ -82,7 +82,7 @@ foreach ($snort_dirs as $dir) {
/* put in place by the rules update process. */
/********************************************************************/
$snort_files = array("gen-msg.map", "classification.config", "reference.config", "attribute_table.dtd",
- "sid-msg.map", "unicode.map", "threshold.conf", "preproc_rules/preprocessor.rules",
+ "sid-msg.map", "unicode.map", "file_magic.conf", "threshold.conf", "preproc_rules/preprocessor.rules",
"preproc_rules/decoder.rules", "preproc_rules/sensitive-data.rules"
);
foreach ($snort_files as $file) {
@@ -126,6 +126,10 @@ if ($snortcfg['barnyard_enable'] == "on") {
$snortunifiedlog_type .= ", vlan_event_types";
if ($snortcfg['barnyard_log_mpls_events'] == 'on')
$snortunifiedlog_type .= ", mpls_event_types";
+
+ // If AppID detector is enabled, add it to unified2 logging
+ if ($snortcfg['appid_preproc'] == 'on' )
+ $snortunifiedlog_type .= ", appid_event_types";
}
/* define spoink */
@@ -889,6 +893,23 @@ preprocessor reputation: \
EOD;
+/* def AppID preprocessor */
+$appid_memcap = $snortcfg['sf_appid_mem_cap'] * 1024 * 1024;
+$appid_params = "app_detector_dir " . SNORT_APPID_ODP_PATH . ", \\\n\tmemcap {$appid_memcap}";
+if ($snortcfg['sf_appid_statslog'] == "on") {
+ $appid_params .= ", \\\n\tapp_stats_filename app-stats.log";
+ $appid_params .= ", \\\n\tapp_stats_period {$snortcfg['sf_appid_stats_period']}";
+ $appid_params .= ", \\\n\tapp_stats_rollover_size " . strval($config['installedpackages']['snortglobal']['appid_stats_log_limit_size'] * 1024);
+ $appid_params .= ", \\\n\tapp_stats_rollover_time 86400";
+}
+
+$appid_preproc = <<<EOD
+# AppID preprocessor #
+preprocessor appid: \
+ {$appid_params}
+
+EOD;
+
/***************************************/
/* end of preprocessor string var code */
/***************************************/
@@ -920,14 +941,14 @@ $snort_preproc_libs = array(
"dce_rpc_2" => "dce2_preproc", "dns_preprocessor" => "dns_preproc", "ftp_preprocessor" => "ftptelnet_preproc", "imap_preproc" => "imap_preproc",
"pop_preproc" => "pop_preproc", "reputation_preproc" => "reputation_preproc", "sensitive_data" => "sdf_preproc",
"sip_preproc" => "sip_preproc", "gtp_preproc" => "gtp_preproc", "smtp_preprocessor" => "smtp_preproc", "ssh_preproc" => "ssh_preproc",
- "ssl_preproc" => "ssl_preproc", "dnp3_preproc" => "dnp3_preproc", "modbus_preproc" => "modbus_preproc"
+ "ssl_preproc" => "ssl_preproc", "dnp3_preproc" => "dnp3_preproc", "modbus_preproc" => "modbus_preproc", "appid_preproc" => "appid_preproc"
);
$snort_preproc = array (
"perform_stat", "other_preprocs", "ftp_preprocessor", "smtp_preprocessor", "ssl_preproc", "sip_preproc", "gtp_preproc", "ssh_preproc", "sf_portscan",
- "dce_rpc_2", "dns_preprocessor", "sensitive_data", "pop_preproc", "imap_preproc", "dnp3_preproc", "modbus_preproc", "reputation_preproc"
+ "dce_rpc_2", "dns_preprocessor", "sensitive_data", "pop_preproc", "imap_preproc", "dnp3_preproc", "modbus_preproc", "reputation_preproc", "appid_preproc"
);
$default_disabled_preprocs = array(
- "sf_portscan", "gtp_preproc", "sensitive_data", "dnp3_preproc", "modbus_preproc", "reputation_preproc", "perform_stat"
+ "sf_portscan", "gtp_preproc", "sensitive_data", "dnp3_preproc", "modbus_preproc", "reputation_preproc", "perform_stat", "appid_preproc"
);
$snort_preprocessors = "";
foreach ($snort_preproc as $preproc) {
@@ -941,8 +962,8 @@ foreach ($snort_preproc as $preproc) {
if (!empty($snort_preproc_libs[$preproc])) {
$preproclib = "libsf_" . $snort_preproc_libs[$preproc];
if (!file_exists($snort_dirs['dynamicpreprocessor'] . "{$preproclib}.so")) {
- if (file_exists("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so")) {
- @copy("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so", "{$snort_dirs['dynamicpreprocessor']}/{$preproclib}.so");
+ if (file_exists("{$snortlibdir}/snort_dynamicpreprocessor/{$preproclib}.so")) {
+ @copy("{$snortlibdir}/snort_dynamicpreprocessor/{$preproclib}.so", "{$snort_dirs['dynamicpreprocessor']}/{$preproclib}.so");
$snort_preprocessors .= $$preproc;
$snort_preprocessors .= "\n";
} else
diff --git a/config/snort/snort_interface_logs.php b/config/snort/snort_interface_logs.php
index ba8215ca..c8c4c24c 100644
--- a/config/snort/snort_interface_logs.php
+++ b/config/snort/snort_interface_logs.php
@@ -54,15 +54,29 @@ $if_real = get_real_interface($a_instance[$id]['interface']);
// Construct a pointer to the instance's logging subdirectory
$snortlogdir = SNORTLOGDIR . "/snort_{$if_real}{$snort_uuid}/";
+// Construct a pointer to the PBI_BIN directory
+$snortbindir = SNORT_PBI_BINDIR;
+
// Limit all file access to just the currently selected interface's logging subdirectory
$logfile = htmlspecialchars($snortlogdir . basename($_POST['file']));
if ($_POST['action'] == 'load') {
+ // If viewing the app-stats log, then grab only the most recent one
+ if (strpos(basename($logfile), "app-stats.log") !== FALSE) {
+ $appid_statlogs = glob("{$snortlogdir}app-stats.log.*");
+ $logfile = array_pop($appid_statlogs);
+ }
+
if(!is_file($logfile)) {
echo "|3|" . gettext("Log file does not exist or that logging feature is not enabled") . ".|";
}
else {
- $data = file_get_contents($logfile);
+ // Test for special unified2 format app-stats file because
+ // we have to use a Snort binary tool to display its contents.
+ if (strpos(basename($_POST['file']), "app-stats.log") !== FALSE)
+ $data = shell_exec("{$snortbindir}u2openappid {$logfile} 2>&1");
+ else
+ $data = file_get_contents($logfile);
if($data === false) {
echo "|1|" . gettext("Failed to read log file") . ".|";
} else {
@@ -178,7 +192,7 @@ if ($input_errors) {
<td width="78%" class="vtable">
<select name="logFile" id="logFile" class="formselect" onChange="loadFile();">
<?php
- $logs = array( "alert", "{$if_real}.stats" , "sid_changes.log" );
+ $logs = array( "alert", "app-stats.log", "{$if_real}.stats" , "sid_changes.log" );
foreach ($logs as $log) {
$selected = "";
if ($log == basename($logfile))
diff --git a/config/snort/snort_interfaces_edit.php b/config/snort/snort_interfaces_edit.php
index 14b54b34..0d41c7db 100755
--- a/config/snort/snort_interfaces_edit.php
+++ b/config/snort/snort_interfaces_edit.php
@@ -365,9 +365,15 @@ if ($_POST["save"] && !$input_errors) {
if (!is_array($natent['stream5_tcp_engine']['item']))
$natent['stream5_tcp_engine']['item'] = array();
$natent['stream5_tcp_engine']['item'][] = $stream5_eng;
+
$natent['alertsystemlog_facility'] = "log_auth";
$natent['alertsystemlog_priority'] = "log_alert";
+ $natent['appid_preproc'] = "off";
+ $natent['sf_appid_mem_cap'] = "256";
+ $natent['sf_appid_statslog'] = "on";
+ $natent['sf_appid_stats_period'] = "300";
+
$a_rule[] = $natent;
}
diff --git a/config/snort/snort_interfaces_global.php b/config/snort/snort_interfaces_global.php
index fb36d192..6c1d56ac 100644
--- a/config/snort/snort_interfaces_global.php
+++ b/config/snort/snort_interfaces_global.php
@@ -41,19 +41,26 @@ require_once("/usr/local/pkg/snort/snort.inc");
global $g;
$snortdir = SNORTDIR;
-
-/* make things short */
-$pconfig['snortdownload'] = $config['installedpackages']['snortglobal']['snortdownload'] == "on" ? 'on' : 'off';
-$pconfig['oinkmastercode'] = $config['installedpackages']['snortglobal']['oinkmastercode'];
-$pconfig['etpro_code'] = $config['installedpackages']['snortglobal']['etpro_code'];
-$pconfig['emergingthreats'] = $config['installedpackages']['snortglobal']['emergingthreats'] == "on" ? 'on' : 'off';
-$pconfig['emergingthreats_pro'] = $config['installedpackages']['snortglobal']['emergingthreats_pro'] == "on" ? 'on' : 'off';
-$pconfig['rm_blocked'] = $config['installedpackages']['snortglobal']['rm_blocked'];
-$pconfig['autorulesupdate7'] = $config['installedpackages']['snortglobal']['autorulesupdate7'];
-$pconfig['rule_update_starttime'] = $config['installedpackages']['snortglobal']['rule_update_starttime'];
-$pconfig['forcekeepsettings'] = $config['installedpackages']['snortglobal']['forcekeepsettings'] == "on" ? 'on' : 'off';
-$pconfig['snortcommunityrules'] = $config['installedpackages']['snortglobal']['snortcommunityrules'] == "on" ? 'on' : 'off';
-$pconfig['clearblocks'] = $config['installedpackages']['snortglobal']['clearblocks'] == "on" ? 'on' : 'off';
+$snort_openappdir = SNORT_APPID_ODP_PATH;
+
+// Grab any previous input values if doing a SAVE operation
+if ($_POST['save'])
+ $pconfig = $_POST;
+else {
+ $pconfig['snortdownload'] = $config['installedpackages']['snortglobal']['snortdownload'] == "on" ? 'on' : 'off';
+ $pconfig['oinkmastercode'] = $config['installedpackages']['snortglobal']['oinkmastercode'];
+ $pconfig['etpro_code'] = $config['installedpackages']['snortglobal']['etpro_code'];
+ $pconfig['emergingthreats'] = $config['installedpackages']['snortglobal']['emergingthreats'] == "on" ? 'on' : 'off';
+ $pconfig['emergingthreats_pro'] = $config['installedpackages']['snortglobal']['emergingthreats_pro'] == "on" ? 'on' : 'off';
+ $pconfig['rm_blocked'] = $config['installedpackages']['snortglobal']['rm_blocked'];
+ $pconfig['autorulesupdate7'] = $config['installedpackages']['snortglobal']['autorulesupdate7'];
+ $pconfig['rule_update_starttime'] = $config['installedpackages']['snortglobal']['rule_update_starttime'];
+ $pconfig['forcekeepsettings'] = $config['installedpackages']['snortglobal']['forcekeepsettings'] == "on" ? 'on' : 'off';
+ $pconfig['snortcommunityrules'] = $config['installedpackages']['snortglobal']['snortcommunityrules'] == "on" ? 'on' : 'off';
+ $pconfig['clearblocks'] = $config['installedpackages']['snortglobal']['clearblocks'] == "on" ? 'on' : 'off';
+ $pconfig['verbose_logging'] = $config['installedpackages']['snortglobal']['verbose_logging'] == "on" ? 'on' : 'off';
+ $pconfig['openappid_detectors'] = $config['installedpackages']['snortglobal']['openappid_detectors'] == "on" ? 'on' : 'off';
+}
/* Set sensible values for any empty default params */
if (!isset($pconfig['rule_update_starttime']))
@@ -61,6 +68,16 @@ if (!isset($pconfig['rule_update_starttime']))
if (!isset($config['installedpackages']['snortglobal']['forcekeepsettings']))
$pconfig['forcekeepsettings'] = 'on';
+/* Grab OpenAppID version info if enabled and downloaded */
+if ($pconfig['openappid_detectors'] == "on") {
+ if (file_exists("{$snort_openappdir}odp/version.conf")) {
+ $openappid_ver = gettext("Installed Detection Package ");
+ $openappid_ver .= gettext(ucfirst(strtolower(file_get_contents("{$snort_openappdir}odp/version.conf"))));
+ }
+ else
+ $openappid_ver = gettext("N/A (Not Downloaded)");
+}
+
if ($_POST['rule_update_starttime']) {
if (!preg_match('/^([01]?[0-9]|2[0-3]):?([0-5][0-9])$/', $_POST['rule_update_starttime']))
$input_errors[] = "Invalid Rule Update Start Time! Please supply a value in 24-hour format as 'HH:MM'.";
@@ -81,6 +98,8 @@ if (!$input_errors) {
$config['installedpackages']['snortglobal']['emergingthreats'] = $_POST['emergingthreats'] ? 'on' : 'off';
$config['installedpackages']['snortglobal']['emergingthreats_pro'] = $_POST['emergingthreats_pro'] ? 'on' : 'off';
$config['installedpackages']['snortglobal']['clearblocks'] = $_POST['clearblocks'] ? 'on' : 'off';
+ $config['installedpackages']['snortglobal']['verbose_logging'] = $_POST['verbose_logging'] ? 'on' : 'off';
+ $config['installedpackages']['snortglobal']['openappid_detectors'] = $_POST['openappid_detectors'] ? 'on' : 'off';
// If any rule sets are being turned off, then remove them
// from the active rules section of each interface. Start
@@ -137,13 +156,13 @@ if (!$input_errors) {
$retval = 0;
+ write_config("Snort pkg: modified global settings.");
+
/* create whitelist and homenet file, then sync files */
conf_mount_rw();
sync_snort_package_config();
conf_mount_ro();
- write_config("Snort pkg: modified global settings.");
-
/* forces page to reload new settings */
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
@@ -206,7 +225,7 @@ if ($input_errors)
<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tr>
<td><input name="snortdownload" type="checkbox" id="snortdownload" value="on" onclick="enable_snort_vrt();"
- <?php if($pconfig['snortdownload']=='on') echo 'checked'; ?>></td>
+ <?php if($pconfig['snortdownload']=='on') echo 'checked'; ?> /></td>
<td><span class="vexpl"><?php echo gettext("Snort VRT free Registered User or paid Subscriber rules"); ?></span></td>
<tr>
<td>&nbsp;</td>
@@ -224,9 +243,9 @@ if ($input_errors)
</tr>
<tr>
<td valign="top"><span class="vexpl"><strong><?php echo gettext("Code:"); ?></strong></span></td>
- <td><input name="oinkmastercode" type="text"
- class="formfld unknown" id="oinkmastercode" size="52"
- value="<?=htmlspecialchars($pconfig['oinkmastercode']);?>"><br/>
+ <td><input name="oinkmastercode" type="text"
+ class="formfld unknown" id="oinkmastercode" size="52"
+ value="<?=htmlspecialchars($pconfig['oinkmastercode']);?>" /><br/>
<?php echo gettext("Obtain a snort.org Oinkmaster code and paste it here."); ?></td>
</tr>
</table>
@@ -236,8 +255,8 @@ if ($input_errors)
<td width="78%" class="vtable">
<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tr>
- <td valign="top" width="8%"><input name="snortcommunityrules" type="checkbox" value="on"
- <?php if ($config['installedpackages']['snortglobal']['snortcommunityrules']=="on") echo "checked";?> ></td>
+ <td valign="top" width="8%"><input name="snortcommunityrules" type="checkbox" value="on"
+ <?php if ($pconfig['snortcommunityrules']=="on") echo "checked";?> /></td>
<td class="vexpl"><?php echo gettext("The Snort Community Ruleset is a GPLv2 VRT certified ruleset that is distributed free of charge " .
"without any VRT License restrictions. This ruleset is updated daily and is a subset of the subscriber ruleset.");?>
<br/><br/><?php echo "<span class=\"red\"><strong>" . gettext("Note: ") . "</strong></span>" .
@@ -252,13 +271,13 @@ if ($input_errors)
<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tr>
<td valign="top" width="8%"><input name="emergingthreats" type="checkbox" value="on" onclick="enable_et_rules();"
- <?php if ($config['installedpackages']['snortglobal']['emergingthreats']=="on") echo "checked"; ?>></td>
+ <?php if ($pconfig['emergingthreats']=="on") echo "checked"; ?> /></td>
<td><span class="vexpl"><?php echo gettext("ETOpen is an open source set of Snort rules whose coverage " .
"is more limited than ETPro."); ?></span></td>
</tr>
<tr>
<td valign="top" width="8%"><input name="emergingthreats_pro" type="checkbox" value="on" onclick="enable_etpro_rules();"
- <?php if ($config['installedpackages']['snortglobal']['emergingthreats_pro']=="on") echo "checked"; ?>></td>
+ <?php if ($pconfig['emergingthreats_pro']=="on") echo "checked"; ?>/></td>
<td><span class="vexpl"><?php echo gettext("ETPro for Snort offers daily updates and extensive coverage of current malware threats."); ?></span></td>
</tr>
<tr>
@@ -282,13 +301,38 @@ if ($input_errors)
<td valign="top"><span class="vexpl"><strong><?php echo gettext("Code:"); ?></strong></span></td>
<td><input name="etpro_code" type="text"
class="formfld unknown" id="etpro_code" size="52"
- value="<?=htmlspecialchars($pconfig['etpro_code']);?>"><br/>
+ value="<?=htmlspecialchars($pconfig['etpro_code']);?>"/><br/>
<?php echo gettext("Obtain an ETPro subscription code and paste it here."); ?></td>
</tr>
</table>
</td>
</tr>
-
+<tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Install ") . "<strong>" . gettext("OpenAppID") . "</strong>" . gettext(" detectors");?></td>
+ <td width="78%" class="vtable">
+ <table width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tr>
+ <td valign="top" width="8%"><input name="openappid_detectors" type="checkbox" value="on" onclick="enable_openappid_dnload();"
+ <?php if ($pconfig['openappid_detectors']=="on") echo "checked";?> /></td>
+ <td class="vexpl"><?php echo gettext("The OpenAppID package contains the application signatures required by " .
+ "the AppID preprocessor.");?>
+ <br/><br/><?php echo "<span class=\"red\"><strong>" . gettext("Note: ") . "</strong></span>" .
+ gettext("You must enable download of the OpenAppID detectors package in order to utilize the Application ID ") .
+ gettext("preprocessor and any user-provided application detection rules. Once enabled, go to the ") .
+ "<a href='/snort/snort_download_updates.php'>" . gettext("UPDATES") . "</a>" . gettext(" tab and click to download updates.");?></td>
+ </tr>
+ <tbody id="openappid_rows">
+ <tr>
+ <td class="vexpl" colspan="2"><br/><strong><?=gettext("OpenAppID Detection Package");?></strong></td>
+ </tr>
+ <tr>
+ <td class="vexpl" valign="top"><strong><?=gettext("VER:");?></strong></td>
+ <td class="vexpl"><?=htmlspecialchars($openappid_ver);?></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+</tr>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Rules Update Settings"); ?></td>
</tr>
@@ -300,7 +344,7 @@ if ($input_errors)
$interfaces3 = array('never_up' => gettext('NEVER'), '6h_up' => gettext('6 HOURS'), '12h_up' => gettext('12 HOURS'), '1d_up' => gettext('1 DAY'), '4d_up' => gettext('4 DAYS'), '7d_up' => gettext('7 DAYS'), '28d_up' => gettext('28 DAYS'));
foreach ($interfaces3 as $iface3 => $ifacename3): ?>
<option value="<?=$iface3;?>"
- <?php if ($iface3 == $pconfig['autorulesupdate7']) echo "selected"; ?>>
+ <?php if ($iface3 == $pconfig['autorulesupdate7']) echo "selected"; ?> />
<?=htmlspecialchars($ifacename3);?></option>
<?php endforeach; ?>
</select><span class="vexpl">&nbsp;&nbsp;<?php echo gettext("Please select the interval for rule updates. Choosing ") .
@@ -310,7 +354,7 @@ if ($input_errors)
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Update Start Time"); ?></td>
<td width="78%" class="vtable"><input type="text" class="formfld time" name="rule_update_starttime" id="rule_update_starttime" size="4"
- maxlength="5" value="<?=htmlspecialchars($pconfig['rule_update_starttime']);?>" <?php if ($pconfig['autorulesupdate7'] == "never_up") {echo "disabled";} ?>><span class="vexpl">&nbsp;&nbsp;
+ maxlength="5" value="<?=htmlspecialchars($pconfig['rule_update_starttime']);?>" <?php if ($pconfig['autorulesupdate7'] == "never_up") {echo "disabled";} ?> /><span class="vexpl">&nbsp;&nbsp;
<?php echo gettext("Enter the rule update start time in 24-hour format (HH:MM). ") . "<strong>" .
gettext("Default") . "&nbsp;</strong>" . gettext("is ") . "<strong>" . gettext("00:05") . "</strong></span>"; ?>.<br/><br/>
<?php echo gettext("Rules will update at the interval chosen above starting at the time specified here. For example, using the default " .
@@ -327,7 +371,7 @@ if ($input_errors)
$interfaces3 = array('never_b' => gettext('NEVER'), '15m_b' => gettext('15 MINS'), '30m_b' => gettext('30 MINS'), '1h_b' => gettext('1 HOUR'), '3h_b' => gettext('3 HOURS'), '6h_b' => gettext('6 HOURS'), '12h_b' => gettext('12 HOURS'), '1d_b' => gettext('1 DAY'), '4d_b' => gettext('4 DAYS'), '7d_b' => gettext('7 DAYS'), '28d_b' => gettext('28 DAYS'));
foreach ($interfaces3 as $iface3 => $ifacename3): ?>
<option value="<?=$iface3;?>"
- <?php if ($iface3 == $pconfig['rm_blocked']) echo "selected"; ?>>
+ <?php if ($iface3 == $pconfig['rm_blocked']) echo "selected"; ?> />
<?=htmlspecialchars($ifacename3);?></option>
<?php endforeach; ?>
</select>&nbsp;
@@ -336,21 +380,29 @@ if ($input_errors)
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Remove Blocked Hosts After Deinstall"); ?></td>
- <td width="78%" class="vtable"><input name="clearblocks" id="clearblocks" type="checkbox" value="yes"
- <?php if ($config['installedpackages']['snortglobal']['clearblocks']=="on") echo " checked"; ?>/>&nbsp;
+ <td width="78%" class="vtable"><input name="clearblocks" id="clearblocks" type="checkbox" value="yes"
+ <?php if ($pconfig['clearblocks']=="on") echo " checked"; ?> />&nbsp;
<?php echo gettext("All blocked hosts added by Snort will be removed during package deinstallation."); ?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Keep Snort Settings After Deinstall"); ?></td>
<td width="78%" class="vtable"><input name="forcekeepsettings"
- id="forcekeepsettings" type="checkbox" value="yes"
- <?php if ($pconfig['forcekeepsettings']=="on") echo "checked"; ?>
- >&nbsp;&nbsp;<?php echo gettext("Settings will not be removed during package deinstallation."); ?></td>
+ id="forcekeepsettings" type="checkbox" value="yes"
+ <?php if ($pconfig['forcekeepsettings']=="on") echo "checked"; ?> />
+ &nbsp;&nbsp;<?php echo gettext("Settings will not be removed during package deinstallation."); ?></td>
+</tr>
+<tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Startup/Shutdown Logging"); ?></td>
+ <td width="78%" class="vtable"><input name="verbose_logging"
+ id="verbose_logging" type="checkbox" value="yes"
+ <?php if ($pconfig['verbose_logging']=="on") echo "checked"; ?> />
+ &nbsp;&nbsp;<?php echo gettext("Output detailed messages to the system log when Snort is starting and stopping. Default is ") .
+ "<strong>" . gettext("Not Checked") . "</strong>" . gettext("."); ?></td>
</tr>
<tr>
<td width="22%" valign="top">
<td width="78%">
- <input name="save" type="submit" class="formbtn" value="Save" >
+ <input name="save" type="submit" class="formbtn" value="Save" />
</td>
</tr>
<tr>
@@ -403,11 +455,20 @@ function enable_change_rules_upd() {
document.iform.rule_update_starttime.disabled="";
}
+function enable_openappid_dnload() {
+ var endis = document.iform.openappid_detectors.checked;
+ if (endis)
+ document.getElementById("openappid_rows").style.display = "";
+ else
+ document.getElementById("openappid_rows").style.display = "none";
+}
+
// Initialize the form controls state based on saved settings
enable_snort_vrt();
enable_et_rules();
enable_etpro_rules();
enable_change_rules_upd();
+enable_openappid_dnload();
//-->
</script>
diff --git a/config/snort/snort_ip_list_mgmt.php b/config/snort/snort_ip_list_mgmt.php
index 8311ea1c..20d486c6 100644
--- a/config/snort/snort_ip_list_mgmt.php
+++ b/config/snort/snort_ip_list_mgmt.php
@@ -152,6 +152,7 @@ if ($savemsg)
<input type="hidden" name="MAX_FILE_SIZE" value="100000000" />
<input type="hidden" name="iplist_fname" id="iplist_fname" value=""/>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
@@ -170,21 +171,19 @@ if ($savemsg)
?>
</td>
</tr>
-<tbody id="uploader" style="display: none;" class="tabcont">
- <tr>
- <td colspan="4" class="list"><br/><?php echo gettext("Click BROWSE to select a file to import, and then click UPLOAD. Click CLOSE to quit."); ?></td>
- </tr>
- <tr>
- <td colspan="4" class="list"><input type="file" name="iprep_fileup" id="iprep_fileup" class="formfld file" size="50" />
- &nbsp;&nbsp;<input type="submit" name="upload" id="upload" value="<?=gettext("Upload");?>"
- title="<?=gettext("Upload selected IP list to firewall");?>"/>&nbsp;&nbsp;<input type="button"
- value="<?=gettext("Close");?>" onClick="document.getElementById('uploader').style.display='none';" /><br/></td>
- <td class="list"></td>
- </tr>
-</tbody>
<tr>
<td>
<div id="mainarea">
+
+ <?php if ($g['platform'] == "nanobsd") : ?>
+ <table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("IP Reputation is not supported on NanoBSD installs"); ?></td>
+ </tr>
+ </tbody>
+ </table>
+ <?php else: ?>
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
<colgroup>
<col style="width: 50%;">
@@ -223,6 +222,18 @@ if ($savemsg)
height="17" border="0" title="<?php echo gettext('Delete this IP List');?>"/></td>
</tr>
<?php endforeach; ?>
+ <tbody id="uploader" style="display: none;">
+ <tr>
+ <td colspan="4" class="list"><br/><?php echo gettext("Click BROWSE to select a file to import, and then click UPLOAD. Click CLOSE to quit."); ?></td>
+ </tr>
+ <tr>
+ <td colspan="4" class="list"><input type="file" name="iprep_fileup" id="iprep_fileup" class="formfld file" size="50" />
+ &nbsp;&nbsp;<input type="submit" name="upload" id="upload" value="<?=gettext("Upload");?>"
+ title="<?=gettext("Upload selected IP list to firewall");?>"/>&nbsp;&nbsp;<input type="button"
+ value="<?=gettext("Close");?>" onClick="document.getElementById('uploader').style.display='none';" /><br/></td>
+ <td colspan="4" class="list"></td>
+ </tr>
+ </tbody>
<tbody id="iplist_editor" style="<?=$iplist_edit_style;?>">
<tr>
<td colspan="4">&nbsp;</td>
@@ -267,9 +278,11 @@ if ($savemsg)
<td class="list"></td>
</tr>
</table>
+ <?php endif; ?>
</div>
</td>
</tr>
+</tbody>
</table>
</form>
<?php include("fend.inc"); ?>
diff --git a/config/snort/snort_ip_reputation.php b/config/snort/snort_ip_reputation.php
index 891f3773..4c3065a0 100644
--- a/config/snort/snort_ip_reputation.php
+++ b/config/snort/snort_ip_reputation.php
@@ -204,6 +204,7 @@ if ($savemsg)
<?php endif; ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
<tr>
<td>
<?php
@@ -239,6 +240,12 @@ if ($savemsg)
<tr>
<td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
+ <?php if ($g['platform'] == "nanobsd") : ?>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("IP Reputation is not supported on NanoBSD installs"); ?></td>
+ </tr>
+ <?php else: ?>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("IP Reputation Preprocessor Configuration"); ?></td>
</tr>
@@ -368,9 +375,9 @@ if ($savemsg)
<td width="22%" valign='top' class='vncell'><?php echo gettext("Whitelist Files"); ?>
</td>
<td width="78%" class="vtable">
- <table width="95%" border="0" cellpadding="2" cellspacing="0">
<!-- wlist_chooser -->
<div id="wlistChooser" name="wlistChooser" style="display:none; border:1px dashed gray; width:98%;"></div>
+ <table width="95%" border="0" cellpadding="2" cellspacing="0">
<colgroup>
<col style="text-align:left;">
<col style="width: 30%; text-align:left;">
@@ -411,12 +418,16 @@ if ($savemsg)
</table>
</td>
</tr>
+ <?php endif; ?>
+ </tbody>
</table>
</div>
</td>
</tr>
+ </tbody>
</table>
+<?php if ($g['platform'] != "nanobsd") : ?>
<script type="text/javascript">
Event.observe(
window, "load",
@@ -504,6 +515,7 @@ function wlistComplete(req) {
}
</script>
+<?php endif; ?>
</form>
<?php include("fend.inc"); ?>
diff --git a/config/snort/snort_log_mgmt.php b/config/snort/snort_log_mgmt.php
index 0e38afc2..33d94a04 100644
--- a/config/snort/snort_log_mgmt.php
+++ b/config/snort/snort_log_mgmt.php
@@ -57,6 +57,8 @@ $pconfig['sid_changes_log_limit_size'] = $config['installedpackages']['snortglob
$pconfig['sid_changes_log_retention'] = $config['installedpackages']['snortglobal']['sid_changes_log_retention'];
$pconfig['event_pkts_log_limit_size'] = '0';
$pconfig['event_pkts_log_retention'] = $config['installedpackages']['snortglobal']['event_pkts_log_retention'];
+$pconfig['appid_stats_log_limit_size'] = $config['installedpackages']['snortglobal']['appid_stats_log_limit_size'];
+$pconfig['appid_stats_log_retention'] = $config['installedpackages']['snortglobal']['appid_stats_log_retention'];
// Load up some arrays with selection values (we use these later).
// The keys in the $retentions array are the retention period
@@ -86,6 +88,8 @@ if (!isset($pconfig['sid_changes_log_retention']))
$pconfig['sid_changes_log_retention'] = "336";
if (!isset($pconfig['event_pkts_log_retention']))
$pconfig['event_pkts_log_retention'] = "336";
+if (!isset($pconfig['appid_stats_log_retention']))
+ $pconfig['appid_stats_log_retention'] = "168";
// Set default log file size limits
if (!isset($pconfig['alert_log_limit_size']))
@@ -94,6 +98,8 @@ if (!isset($pconfig['stats_log_limit_size']))
$pconfig['stats_log_limit_size'] = "500";
if (!isset($pconfig['sid_changes_log_limit_size']))
$pconfig['sid_changes_log_limit_size'] = "250";
+if (!isset($pconfig['appid_stats_log_limit_size']))
+ $pconfig['appid_stats_log_limit_size'] = "1000";
if ($_POST['ResetAll']) {
@@ -102,11 +108,13 @@ if ($_POST['ResetAll']) {
$pconfig['stats_log_retention'] = "168";
$pconfig['sid_changes_log_retention'] = "336";
$pconfig['event_pkts_log_retention'] = "336";
+ $pconfig['appid_stats_log_retention'] = "168";
$pconfig['alert_log_limit_size'] = "500";
$pconfig['stats_log_limit_size'] = "500";
$pconfig['sid_changes_log_limit_size'] = "250";
$pconfig['event_pkts_log_limit_size'] = "0";
+ $pconfig['appid_stats_log_limit_size'] = "1000";
/* Log a message at the top of the page to inform the user */
$savemsg = gettext("All log management settings on this page have been reset to their defaults. Click APPLY if you wish to keep these new settings.");
@@ -148,6 +156,8 @@ if ($_POST["save"] || $_POST['apply']) {
$config['installedpackages']['snortglobal']['sid_changes_log_retention'] = $_POST['sid_changes_log_retention'];
$config['installedpackages']['snortglobal']['event_pkts_log_limit_size'] = $_POST['event_pkts_log_limit_size'];
$config['installedpackages']['snortglobal']['event_pkts_log_retention'] = $_POST['event_pkts_log_retention'];
+ $config['installedpackages']['snortglobal']['appid_stats_log_limit_size'] = $_POST['appid_stats_log_limit_size'];
+ $config['installedpackages']['snortglobal']['appid_stats_log_retention'] = $_POST['appid_stats_log_retention'];
write_config("Snort pkg: saved updated configuration for LOGS MGMT.");
conf_mount_rw();
@@ -307,7 +317,26 @@ if ($savemsg) {
</td>
<td class="listbg"><?=gettext("Snort alerts and event details");?></td>
</tr>
-
+ <tr>
+ <td class="listbg">appid-stats</td>
+ <td class="listr" align="center"><select name="appid_stats_log_limit_size" class="formselect" id="appid_stats_log_limit_size">
+ <?php foreach ($log_sizes as $k => $l): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['appid_stats_log_limit_size']) echo " selected"; ?>>
+ <?=htmlspecialchars($l);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listr" align="center"><select name="appid_stats_log_retention" class="formselect" id="appid_stats_log_retention">
+ <?php foreach ($retentions as $k => $p): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['appid_stats_log_retention']) echo " selected"; ?>>
+ <?=htmlspecialchars($p);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listbg"><?=gettext("Application ID statistics");?></td>
+ </tr>
<tr>
<td class="listbg">event pcaps</td>
<td class="listr" align="center"><select name="event_pkts_log_limit_size" class="formselect" id="event_pkts_log_limit_size">
@@ -324,7 +353,6 @@ if ($savemsg) {
</td>
<td class="listbg"><?=gettext("Snort alert related packet captures");?></td>
</tr>
-
<tr>
<td class="listbg">sid_changes</td>
<td class="listr" align="center"><select name="sid_changes_log_limit_size" class="formselect" id="sid_changes_log_limit_size">
diff --git a/config/snort/snort_migrate_config.php b/config/snort/snort_migrate_config.php
index a722d52b..12ae5d19 100644
--- a/config/snort/snort_migrate_config.php
+++ b/config/snort/snort_migrate_config.php
@@ -73,27 +73,52 @@ if (empty($config['installedpackages']['snortglobal']['snort_config_ver']) &&
/**********************************************************/
/* Create new Auto SID Mgmt settings if not set */
/**********************************************************/
- if (empty($config['installedpackages']['snortglobal']['auto_manage_sids'])) {
- $config['installedpackages']['snortglobal']['auto_manage_sids'] = "off";
- $updated_cfg = true;
- }
+if (empty($config['installedpackages']['snortglobal']['auto_manage_sids'])) {
+ $config['installedpackages']['snortglobal']['auto_manage_sids'] = "off";
+ $updated_cfg = true;
+}
/**********************************************************/
/* Create new LOG MGMT settings if not set */
/**********************************************************/
- if (empty($config['installedpackages']['snortglobal']['enable_log_mgmt'])) {
- $config['installedpackages']['snortglobal']['enable_log_mgmt'] = "on";
- $config['installedpackages']['snortglobal']['alert_log_limit_size'] = "500";
- $config['installedpackages']['snortglobal']['alert_log_retention'] = "336";
- $config['installedpackages']['snortglobal']['event_pkts_log_limit_size'] = "0";
- $config['installedpackages']['snortglobal']['event_pkts_log_retention'] = "336";
- $config['installedpackages']['snortglobal']['sid_changes_log_limit_size'] = "250";
- $config['installedpackages']['snortglobal']['sid_changes_log_retention'] = "336";
- $config['installedpackages']['snortglobal']['stats_log_limit_size'] = "500";
- $config['installedpackages']['snortglobal']['stats_log_retention'] = "168";
- $updated_cfg = true;
+if (empty($config['installedpackages']['snortglobal']['enable_log_mgmt'])) {
+ $config['installedpackages']['snortglobal']['enable_log_mgmt'] = "on";
+ $config['installedpackages']['snortglobal']['alert_log_limit_size'] = "500";
+ $config['installedpackages']['snortglobal']['alert_log_retention'] = "336";
+ $config['installedpackages']['snortglobal']['appid_stats_log_limit_size'] = "1000";
+ $config['installedpackages']['snortglobal']['appid_stats_log_retention'] = "168";
+ $config['installedpackages']['snortglobal']['event_pkts_log_limit_size'] = "0";
+ $config['installedpackages']['snortglobal']['event_pkts_log_retention'] = "336";
+ $config['installedpackages']['snortglobal']['sid_changes_log_limit_size'] = "250";
+ $config['installedpackages']['snortglobal']['sid_changes_log_retention'] = "336";
+ $config['installedpackages']['snortglobal']['stats_log_limit_size'] = "500";
+ $config['installedpackages']['snortglobal']['stats_log_retention'] = "168";
+ $updated_cfg = true;
+}
+if (empty($config['installedpackages']['snortglobal']['appid_stats_log_limit_size']))
+ $config['installedpackages']['snortglobal']['appid_stats_log_limit_size'] = "1000";
+if (empty($config['installedpackages']['snortglobal']['appid_stats_log_retention']))
+ $config['installedpackages']['snortglobal']['appid_stats_log_retention'] = "168";
+
+/**********************************************************/
+/* Create new VERBOSE_LOGGING setting if not set */
+/**********************************************************/
+if (empty($config['installedpackages']['snortglobal']['verbose_logging'])) {
+ $config['installedpackages']['snortglobal']['verbose_logging'] = "off";
+ $updated_cfg = true;
}
+/**********************************************************/
+/* Create new OpenAppID settings if not set */
+/**********************************************************/
+if (empty($config['installedpackages']['snortglobal']['openappid_detectors'])) {
+ $config['installedpackages']['snortglobal']['openappid_detectors'] = "off";
+ $updated_cfg = true;
+}
+
+/**********************************************************/
+/* Migrate per interface settings if required. */
+/**********************************************************/
foreach ($rule as &$r) {
// Initialize arrays for supported preprocessors if necessary
if (!is_array($r['frag3_engine']['item']))
@@ -482,6 +507,24 @@ foreach ($rule as &$r) {
$updated_cfg = true;
}
+ // Default any unconfigured AppID preprocessor settings
+ if (empty($pconfig['appid_preproc'])) {
+ $pconfig['appid_preproc'] = 'off';
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['sf_appid_mem_cap'])) {
+ $pconfig['sf_appid_mem_cap'] = '256';
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['sf_appid_statslog'])) {
+ $pconfig['sf_appid_statslog'] = 'on';
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['sf_appid_stats_period'])) {
+ $pconfig['sf_appid_stats_period'] = '300';
+ $updated_cfg = true;
+ }
+
// Save the new configuration data into the $config array pointer
$r = $pconfig;
}
@@ -490,8 +533,7 @@ unset($r);
// Log a message if we changed anything
if ($updated_cfg) {
- $config['installedpackages']['snortglobal']['snort_config_ver'] = "3.1.5";
- log_error("[Snort] Saving configuration settings in new format...");
+ $config['installedpackages']['snortglobal']['snort_config_ver'] = "3.2";
log_error("[Snort] Settings successfully migrated to new configuration format...");
}
else
diff --git a/config/snort/snort_post_install.php b/config/snort/snort_post_install.php
index 5009a8b3..57e92ce5 100644
--- a/config/snort/snort_post_install.php
+++ b/config/snort/snort_post_install.php
@@ -41,35 +41,12 @@
require_once("config.inc");
require_once("functions.inc");
require_once("/usr/local/pkg/snort/snort.inc");
+require("/usr/local/pkg/snort/snort_defs.inc");
global $config, $g, $rebuild_rules, $pkg_interface, $snort_gui_include;
-/****************************************
- * Define any new constants here that *
- * may not be yet defined in the old *
- * "snort.inc" include file that might *
- * be cached and used by the package *
- * manager installation code. *
- * *
- * This is a hack to work around the *
- * fact the old version of suricata.inc *
- * is cached and used instead of the *
- * updated version icluded with the *
- * updated GUI package. *
- ****************************************/
-if (!defined('SNORT_SID_MODS_PATH'))
- define('SNORT_SID_MODS_PATH', "{$g['vardb_path']}/snort/sidmods/");
-
-if (!defined('SNORT_ENFORCING_RULES_FILENAME'))
- define("SNORT_ENFORCING_RULES_FILENAME", "snort.rules");
-
-/****************************************
- * End of PHP caching workaround *
- ****************************************/
-
$snortdir = SNORTDIR;
$snortlogdir = SNORTLOGDIR;
-$snortlibdir = SNORTLIBDIR;
$rcdir = RCFILEPREFIX;
$flowbit_rules_file = FLOWBITS_FILENAME;
$snort_enforcing_rules_file = SNORT_ENFORCING_RULES_FILENAME;
@@ -101,6 +78,7 @@ conf_mount_rw();
@rename("{$snortdir}/threshold.conf-sample", "{$snortdir}/threshold.conf");
@rename("{$snortdir}/sid-msg.map-sample", "{$snortdir}/sid-msg.map");
@rename("{$snortdir}/unicode.map-sample", "{$snortdir}/unicode.map");
+@rename("{$snortdir}/file_magic.conf-sample", "{$snortdir}/file_magic.conf");
@rename("{$snortdir}/classification.config-sample", "{$snortdir}/classification.config");
@rename("{$snortdir}/generators-sample", "{$snortdir}/generators");
@rename("{$snortdir}/reference.config-sample", "{$snortdir}/reference.config");
@@ -123,6 +101,7 @@ unlink_if_exists("{$rcdir}barnyard2");
safe_mkdir(SNORTLOGDIR);
safe_mkdir(SNORT_IPREP_PATH);
safe_mkdir(SNORT_SID_MODS_PATH);
+safe_mkdir(SNORT_APPID_ODP_PATH);
/* If installed, absorb the Snort Dashboard Widget into this package */
/* by removing it as a separately installed package. */
@@ -263,8 +242,8 @@ if (stristr($config['widgets']['sequence'], "snort_alerts-container") === FALSE)
$config['widgets']['sequence'] .= ",{$snort_widget_container}";
/* Update Snort package version in configuration */
-$config['installedpackages']['snortglobal']['snort_config_ver'] = "3.1.5";
-write_config("Snort pkg v3.1.5: post-install configuration saved.");
+$config['installedpackages']['snortglobal']['snort_config_ver'] = "3.2";
+write_config("Snort pkg v3.2: post-install configuration saved.");
/* Done with post-install, so clear flag */
unset($g['snort_postinstall']);
diff --git a/config/snort/snort_preprocessors.php b/config/snort/snort_preprocessors.php
index 75e4902d..9f6879ef 100755
--- a/config/snort/snort_preprocessors.php
+++ b/config/snort/snort_preprocessors.php
@@ -341,6 +341,10 @@ if ($_POST['ResetAll']) {
$pconfig['smtp_log_rcpt_to'] = 'on';
$pconfig['smtp_log_filename'] = 'on';
$pconfig['smtp_log_email_hdrs'] = 'on';
+ $pconfig['appid_preproc'] = "off";
+ $pconfig['sf_appid_mem_cap'] = "256";
+ $pconfig['sf_appid_statslog'] = "on";
+ $pconfig['sf_appid_stats_period'] = "300";
$pconfig['sf_portscan'] = "off";
$pconfig['pscan_protocol'] = "all";
$pconfig['pscan_type'] = "all";
@@ -439,6 +443,14 @@ if ($_POST['save']) {
$input_errors[] = gettext("The value for SMTP Decoder E-Mail Headers Log Depth must be between 0 and 20,480.");
}
+ // Validate AppID parameter values if AppID Detector is enabled
+ if ($_POST['appid_preproc'] == 'on') {
+ if ($_POST['sf_appid_mem_cap'] < 32 || $_POST['sf_appid_mem_cap'] > 3000)
+ $input_errors[] = gettext("The value for Application ID Memory Cap must be between 32 and 3000.");
+ if ($_POST['sf_appid_stats_period'] < 60 || $_POST['sf_appid_stats_period'] > 3600)
+ $input_errors[] = gettext("The value for Application ID Stats Period must be between 60 and 3600.");
+ }
+
/* if no errors write to conf */
if (!$input_errors) {
/* post new options */
@@ -481,6 +493,8 @@ if ($_POST['save']) {
if ($_POST['smtp_bitenc_decode_depth'] != "") { $natent['smtp_bitenc_decode_depth'] = $_POST['smtp_bitenc_decode_depth']; }else{ $natent['smtp_bitenc_decode_depth'] = "0"; }
if ($_POST['smtp_uu_decode_depth'] != "") { $natent['smtp_uu_decode_depth'] = $_POST['smtp_uu_decode_depth']; }else{ $natent['smtp_uu_decode_depth'] = "0"; }
if ($_POST['smtp_email_hdrs_log_depth'] != "") { $natent['smtp_email_hdrs_log_depth'] = $_POST['smtp_email_hdrs_log_depth']; }else{ $natent['smtp_email_hdrs_log_depth'] = "1464"; }
+ if ($_POST['sf_appid_mem_cap'] != "") { $natent['sf_appid_mem_cap'] = $_POST['sf_appid_mem_cap']; }else{ $natent['sf_appid_mem_cap'] = "256"; }
+ if ($_POST['sf_appid_stats_period'] != "") { $natent['sf_appid_stats_period'] = $_POST['sf_appid_stats_period']; }else{ $natent['sf_appid_stats_period'] = "300"; }
// Set SDF inspection types
$natent['sdf_alert_data_type'] = implode(",",$_POST['sdf_alert_data_type']);
@@ -525,6 +539,8 @@ if ($_POST['save']) {
$natent['stream5_track_tcp'] = $_POST['stream5_track_tcp'] ? 'on' : 'off';
$natent['stream5_track_udp'] = $_POST['stream5_track_udp'] ? 'on' : 'off';
$natent['stream5_track_icmp'] = $_POST['stream5_track_icmp'] ? 'on' : 'off';
+ $natent['appid_preproc'] = $_POST['appid_preproc'] ? 'on' : 'off';
+ $natent['sf_appid_statslog'] = $_POST['sf_appid_statslog'] ? 'on' : 'off';
if (isset($id) && isset($a_nat[$id])) {
$a_nat[$id] = $natent;
@@ -685,14 +701,14 @@ if ($savemsg) {
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable Performance Stats"); ?></td>
<td width="78%" class="vtable"><input name="perform_stat" type="checkbox" value="on"
- <?php if ($pconfig['perform_stat']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['perform_stat']=="on") echo "checked"; ?>/>
<?php echo gettext("Collect Performance Statistics for this interface."); ?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Protect Customized Preprocessor Rules"); ?></td>
<td width="78%" class="vtable"><input name="protect_preproc_rules" type="checkbox" value="on"
<?php if ($pconfig['protect_preproc_rules']=="on") echo "checked ";
- if ($vrt_enabled <> 'on') echo "disabled"; ?>>
+ if ($vrt_enabled <> 'on') echo "disabled"; ?>/>
<?php echo gettext("Check this box if you maintain customized preprocessor text rules files for this interface."); ?>
<table width="100%" border="0" cellpadding="2" cellpadding="2">
<tr>
@@ -709,7 +725,7 @@ if ($savemsg) {
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Auto Rule Disable"); ?></td>
<td width="78%" class="vtable"><input name="preproc_auto_rule_disable" type="checkbox" value="on"
- <?php if ($pconfig['preproc_auto_rule_disable']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['preproc_auto_rule_disable']=="on") echo "checked"; ?>/>
<?php echo gettext("Auto-disable text rules dependent on disabled preprocessors for this interface. ");
echo gettext("Default is ") . '<strong>' . gettext("Not Checked"); ?></strong>.<br/>
<table width="100%" border="0" cellpadding="2" cellpadding="2">
@@ -739,7 +755,7 @@ if ($savemsg) {
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td>
<td width="78%" class="vtable"><input name="host_attribute_table"
type="checkbox" value="on" id="host_attribute_table" onclick="host_attribute_table_enable_change();"
- <?php if ($pconfig['host_attribute_table']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['host_attribute_table']=="on") echo "checked"; ?>/>
<?php echo gettext("Use a Host Attribute Table file to auto-configure applicable preprocessors. " .
"Default is "); ?><strong><?php echo gettext("Not Checked"); ?></strong>.</td>
</tr>
@@ -823,7 +839,7 @@ if ($savemsg) {
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td>
<td width="78%" class="vtable"><input name="http_inspect"
type="checkbox" value="on" id="http_inspect" onclick="http_inspect_enable_change();"
- <?php if ($pconfig['http_inspect']=="on" || empty($pconfig['http_inspect'])) echo "checked";?>>
+ <?php if ($pconfig['http_inspect']=="on" || empty($pconfig['http_inspect'])) echo "checked";?>/>
<?php echo gettext("Use HTTP Inspect to Normalize/Decode and detect HTTP traffic and protocol anomalies. Default is ");?>
<strong><?php echo gettext("Checked"); ?></strong>.</td>
</tr>
@@ -831,7 +847,7 @@ if ($savemsg) {
<td width="22%" valign="top" class="vncell"><?php echo gettext("Proxy Alert"); ?></td>
<td width="78%" class="vtable"><input name="http_inspect_proxy_alert"
type="checkbox" value="on" id="http_inspect_proxy_alert"
- <?php if ($pconfig['http_inspect_proxy_alert']=="on") echo "checked";?>>
+ <?php if ($pconfig['http_inspect_proxy_alert']=="on") echo "checked";?>/>
<?php echo gettext("Enable global alerting on HTTP server proxy usage. Default is ");?>
<strong><?php echo gettext("Not Checked"); ?></strong>.<br/><br/><span class="red"><strong>
<?php echo gettext("Note: ") . "</strong></span>" . gettext("By adding Server Configurations below and enabling " .
@@ -916,7 +932,7 @@ if ($savemsg) {
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable");?></td>
<td width="78%" class="vtable"><input name="frag3_detection" type="checkbox" value="on" onclick="frag3_enable_change();"
- <?php if ($pconfig['frag3_detection']=="on") echo "checked";?>>
+ <?php if ($pconfig['frag3_detection']=="on") echo "checked";?>/>
<?php echo gettext("Use Frag3 Engine to detect IDS evasion attempts via target-based IP packet fragmentation. Default is ") .
"<strong>" . gettext("Checked") . "</strong>.";?></td>
</tr>
@@ -984,14 +1000,14 @@ if ($savemsg) {
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td>
<td width="78%" class="vtable"><input name="stream5_reassembly" type="checkbox" value="on" onclick="stream5_enable_change();"
- <?php if ($pconfig['stream5_reassembly']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['stream5_reassembly']=="on") echo "checked"; ?>/>
<?php echo gettext("Use Stream5 session reassembly for TCP, UDP and/or ICMP traffic. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
<tr id="stream5_flushonalert_row">
<td width="22%" valign="top" class="vncell"><?php echo gettext("Flush On Alert"); ?></td>
<td width="78%" class="vtable"><input name="stream5_flush_on_alert" type="checkbox" value="on"
- <?php if ($pconfig['stream5_flush_on_alert']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['stream5_flush_on_alert']=="on") echo "checked"; ?>/>
<?php echo gettext("Flush a TCP stream when an alert is generated on that stream. Default is ") .
"<strong>" . gettext("Not Checked") . "</strong><br/><span class=\"red\"><strong>" .
gettext("Note: ") . "</strong></span>" . gettext("This parameter is for backwards compatibility.");?></td>
@@ -1135,6 +1151,53 @@ if ($savemsg) {
</table>
</td>
</tr>
+
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Application ID Detection"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td>
+ <td width="78%" class="vtable"><input name="appid_preproc" onclick="appid_preproc_enable_change();"
+ type="checkbox" value="on" id="appid_preproc"
+ <?php if ($pconfig['appid_preproc']=="on") echo "checked"; ?>/>
+ <?php echo gettext("Use OpenAppID to detect various applications. Default is ") .
+ "<strong>" . gettext("Not Checked") . "</strong>"; ?>.</td>
+ </tr>
+ <tbody id="appid_rows">
+ <tr>
+ <td valign="top" class="vncell"><?php echo gettext("Memory Cap"); ?></td>
+ <td class="vtable">
+ <input name="sf_appid_mem_cap" type="text" class="formfld unknown" id="sf_appid_mem_cap" size="9"
+ value="<?=htmlspecialchars($pconfig['sf_appid_mem_cap']);?>">
+ <?php echo gettext("Memory for App ID structures. Min is ") . "<strong>" . gettext("32") . "</strong>" .
+ gettext(" (32 MB) and Max is ") . "<strong>" . gettext("3000") . "</strong>" .
+ gettext(" (3 GB) bytes.");?><br/>
+ <?php echo gettext("The memory cap in megabytes used by AppID internal structures " .
+ "in RAM. Default value is ") . "<strong>" . gettext("256") . "</strong>" . gettext(" (256 MB)."); ?><br/>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("AppID Stats Logging"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="sf_appid_statslog" type="checkbox" value="on" id="sf_appid_statslog"
+ <?php if ($pconfig['sf_appid_statslog']=="on") echo "checked"; ?>/>
+ <?php echo gettext("Enable OpenAppID statistics logging. Default is ") .
+ "<strong>" . gettext("Checked") . "</strong>" . gettext("."); ?><br/><br/>
+ <span class="red"><strong><?php echo gettext("Note: ") . "</strong></span>" . gettext("log size and retention limits for AppID Stats Logging") .
+ gettext(" can be set on the ") . "<a href='/snort/snort_log_mgmt.php'>" . gettext("LOG MGMT") . "</a>" . gettext(" tab.");?> </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell"><?php echo gettext("AppID Stats Period"); ?></td>
+ <td class="vtable">
+ <input name="sf_appid_stats_period" type="text" class="formfld unknown" id="sf_appid_stats_period" size="9"
+ value="<?=htmlspecialchars($pconfig['sf_appid_stats_period']);?>">
+ <?php echo gettext("Bucket size in seconds for AppID stats. Min is ") . "<strong>" . gettext("60") . "</strong>" .
+ gettext(" (1 minute) and Max is ") . "<strong>" . gettext("3600") . "</strong>" . gettext(" (1 hour).");?><br/>
+ <?php echo gettext("The bucket size in seconds used to collecxt AppID statistics. " .
+ "Default value is ") . "<strong>" . gettext("300") . "</strong>" . gettext(" (5 minutes)."); ?><br/>
+ </td>
+ </tr>
+ </tbody>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Portscan Detection"); ?></td>
</tr>
@@ -1142,7 +1205,7 @@ if ($savemsg) {
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable"); ?></td>
<td width="78%" class="vtable"><input name="sf_portscan" onclick="sf_portscan_enable_change();"
type="checkbox" value="on" id="sf_portscan"
- <?php if ($pconfig['sf_portscan']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['sf_portscan']=="on") echo "checked"; ?>/>
<?php echo gettext("Use Portscan Detection to detect various types of port scans and sweeps. Default is ") .
"<strong>" . gettext("Not Checked") . "</strong>"; ?>.</td>
</tr>
@@ -1287,14 +1350,14 @@ if ($savemsg) {
<tr id="ftp_telnet_row_encrypted_check">
<td width="22%" valign="top" class="vncell"><?php echo gettext("Check Encrypted Traffic"); ?></td>
<td width="78%" class="vtable"><input name="ftp_telnet_check_encrypted" type="checkbox" value="on"
- <?php if ($pconfig['ftp_telnet_check_encrypted']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['ftp_telnet_check_encrypted']=="on") echo "checked"; ?>/>
<?php echo gettext("Continue to check an encrypted session for subsequent command to cease encryption. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
<tr id="ftp_telnet_row_encrypted_alert">
<td width="22%" valign="top" class="vncell"><?php echo gettext("Alert on Encrypted Commands"); ?></td>
<td width="78%" class="vtable"><input name="ftp_telnet_alert_encrypted" type="checkbox" value="on"
- <?php if ($pconfig['ftp_telnet_alert_encrypted']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['ftp_telnet_alert_encrypted']=="on") echo "checked"; ?>/>
<?php echo gettext("Alert on encrypted FTP and Telnet command channels. Default is ") .
"<strong>" . gettext("Not Checked") . "</strong>"; ?>.</td>
</tr>
@@ -1304,14 +1367,14 @@ if ($savemsg) {
<tr id="ftp_telnet_row_normalize">
<td width="22%" valign="top" class="vncell"><?php echo gettext("Normalization"); ?></td>
<td width="78%" class="vtable"><input name="ftp_telnet_normalize" type="checkbox" value="on"
- <?php if ($pconfig['ftp_telnet_normalize']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['ftp_telnet_normalize']=="on") echo "checked"; ?>/>
<?php echo gettext("Normalize Telnet traffic by eliminating Telnet escape sequences. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
<tr id="ftp_telnet_row_detect_anomalies">
<td width="22%" valign="top" class="vncell"><?php echo gettext("Detect Anomalies"); ?></td>
<td width="78%" class="vtable"><input name="ftp_telnet_detect_anomalies" type="checkbox" value="on"
- <?php if ($pconfig['ftp_telnet_detect_anomalies']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['ftp_telnet_detect_anomalies']=="on") echo "checked"; ?>/>
<?php echo gettext("Alert on Telnet subnegotiation begin without corresponding subnegotiation end. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
@@ -1423,7 +1486,7 @@ if ($savemsg) {
echo "checked";
elseif ($vrt_enabled == "off")
echo "disabled";
- ?>>
+ ?>/>
<?php echo gettext("Sensitive data searches for credit card numbers, Social Security numbers and e-mail addresses in data."); ?>
<br/>
<span class="red"><strong><?php echo gettext("Note: "); ?></strong></span><?php echo gettext("To enable this preprocessor, you must select the Snort VRT rules on the ") .
@@ -1458,7 +1521,7 @@ if ($savemsg) {
<input name="sdf_mask_output" type="checkbox" value="on"
<?php if ($pconfig['sdf_mask_output'] == "on")
echo "checked";
- ?>>
+ ?>/>
<?php echo gettext("Replace all but last 4 digits of PII with \"X\"s on credit card and Social Security Numbers. ") .
gettext("Default is ") . "<strong>" . gettext("Not Checked") . "</strong>."; ?>
</td>
@@ -1756,40 +1819,40 @@ if ($savemsg) {
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable RPC Decode and Back Orifice detector"); ?></td>
<td width="78%" class="vtable"><input name="other_preprocs" type="checkbox" value="on"
- <?php if ($pconfig['other_preprocs']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['other_preprocs']=="on") echo "checked"; ?>/>
<?php echo gettext("Normalize/Decode RPC traffic and detects Back Orifice traffic on the network. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable DCE/RPC2 Detection"); ?></td>
<td width="78%" class="vtable"><input name="dce_rpc_2" type="checkbox" value="on"
- <?php if ($pconfig['dce_rpc_2']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['dce_rpc_2']=="on") echo "checked"; ?>/>
<?php echo gettext("The DCE/RPC preprocessor detects and decodes SMB and DCE/RPC traffic. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable SIP Detection"); ?></td>
<td width="78%" class="vtable"><input name="sip_preproc" type="checkbox" value="on"
- <?php if ($pconfig['sip_preproc']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['sip_preproc']=="on") echo "checked"; ?>/>
<?php echo gettext("The SIP preprocessor decodes SIP traffic and detects vulnerabilities. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable GTP Detection"); ?></td>
<td width="78%" class="vtable"><input name="gtp_preproc" type="checkbox" value="on"
- <?php if ($pconfig['gtp_preproc']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['gtp_preproc']=="on") echo "checked"; ?>/>
<?php echo gettext("The GTP preprocessor decodes GPRS Tunneling Protocol traffic and detects intrusion attempts."); ?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable SSH Detection"); ?></td>
<td width="78%" class="vtable"><input name="ssh_preproc" type="checkbox" value="on"
- <?php if ($pconfig['ssh_preproc']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['ssh_preproc']=="on") echo "checked"; ?>/>
<?php echo gettext("The SSH preprocessor detects various Secure Shell exploit attempts."); ?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable DNS Detection"); ?></td>
<td width="78%" class="vtable"><input name="dns_preprocessor" type="checkbox" value="on"
- <?php if ($pconfig['dns_preprocessor']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['dns_preprocessor']=="on") echo "checked"; ?>/>
<?php echo gettext("The DNS preprocessor decodes DNS response traffic and detects vulnerabilities. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
@@ -1797,7 +1860,7 @@ if ($savemsg) {
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable SSL Data"); ?></td>
<td width="78%" class="vtable">
<input name="ssl_preproc" type="checkbox" value="on"
- <?php if ($pconfig['ssl_preproc']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['ssl_preproc']=="on") echo "checked"; ?>/>
<?php echo gettext("SSL data searches for irregularities during SSL protocol exchange. Default is ") .
"<strong>" . gettext("Checked") . "</strong>"; ?>.</td>
</tr>
@@ -1808,7 +1871,7 @@ if ($savemsg) {
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable Modbus Detection"); ?></td>
<td width="78%" class="vtable">
<input name="modbus_preproc" type="checkbox" value="on"
- <?php if ($pconfig['modbus_preproc']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['modbus_preproc']=="on") echo "checked"; ?>/>
<?php echo gettext("Modbus is a protocol used in SCADA networks. The default port is TCP 502.") . "<br/>" .
"<span class=\"red\"><strong>" . gettext("Note: ") . "</strong></span>" .
gettext("If your network does not contain Modbus-enabled devices, you can leave this preprocessor disabled."); ?>
@@ -1818,7 +1881,7 @@ if ($savemsg) {
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable DNP3 Detection"); ?></td>
<td width="78%" class="vtable">
<input name="dnp3_preproc" type="checkbox" value="on"
- <?php if ($pconfig['dnp3_preproc']=="on") echo "checked"; ?>>
+ <?php if ($pconfig['dnp3_preproc']=="on") echo "checked"; ?>/>
<?php echo gettext("DNP3 is a protocol used in SCADA networks. The default port is TCP 20000.") . "<br/>" .
"<span class=\"red\"><strong>" . gettext("Note: ") . "</strong></span>" .
gettext("If your network does not contain DNP3-enabled devices, you can leave this preprocessor disabled."); ?>
@@ -1833,7 +1896,7 @@ if ($savemsg) {
<input name="ResetAll" type="submit" class="formbtn" value="Reset" title="<?php echo
gettext("Reset all settings to defaults") . "\" onclick=\"return confirm('" .
gettext("WARNING: This will reset ALL preprocessor settings to their defaults. Click OK to continue or CANCEL to quit.") .
- "');\""; ?>></td>
+ "');\""; ?>/></td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
@@ -1978,12 +2041,20 @@ function http_inspect_enable_change() {
var endis = !(document.iform.http_inspect.checked);
document.iform.http_inspect_memcap.disabled=endis;
- // Hide the "icmp session timeout " row if stream5_track_icmp disabled
- if (endis) {
- document.getElementById("httpinspect_memcap_row").style.display="none";
- document.getElementById("httpinspect_maxgzipmem_row").style.display="none";
- document.getElementById("httpinspect_proxyalert_row").style.display="none";
- document.getElementById("httpinspect_engconf_row").style.display="none";
+ if (!document.iform.http_inspect.checked) {
+ var msg = "WARNING: Disabling the http_inspect preprocessor is not recommended!\n\n";
+ msg = msg + "Snort may fail to start because of other dependent preprocessors or ";
+ msg = msg + "rule options. Are you sure you want to disable it?\n\n";
+ msg = msg + "Click OK to disable http_inspect, or CANCEL to quit.";
+ if (!confirm(msg)) {
+ document.iform.http_inspect.checked=true;
+ }
+ else {
+ document.getElementById("httpinspect_memcap_row").style.display="none";
+ document.getElementById("httpinspect_maxgzipmem_row").style.display="none";
+ document.getElementById("httpinspect_proxyalert_row").style.display="none";
+ document.getElementById("httpinspect_engconf_row").style.display="none";
+ }
}
else {
document.getElementById("httpinspect_memcap_row").style.display="table-row";
@@ -2013,6 +2084,16 @@ function sf_portscan_enable_change() {
}
}
+function appid_preproc_enable_change() {
+ var endis = !(document.iform.appid_preproc.checked);
+
+ // Hide the AppID configuration rows if appid_preproc disabled
+ if (endis)
+ document.getElementById("appid_rows").style.display="none";
+ else
+ document.getElementById("appid_rows").style.display="";
+}
+
function stream5_enable_change() {
if (!document.iform.stream5_reassembly.checked) {
var msg = "WARNING: Stream5 is a critical preprocessor, and disabling it is not recommended! ";
@@ -2020,7 +2101,8 @@ function stream5_enable_change() {
msg = msg + " SMTP\t\tPOP\t\tSIP\n";
msg = msg + " SENSITIVE_DATA\tSF_PORTSCAN\tDCE/RPC 2\n";
msg = msg + " IMAP\t\tDNS\t\tSSL\n";
- msg = msg + " GTP\t\tDNP3\t\tMODBUS\n\n";
+ msg = msg + " GTP\t\tDNP3\t\tMODBUS\n";
+ msg = msg + " APP_ID\n\n";
msg = msg + "Snort may fail to start because of other preprocessors or rule options dependent on Stream5. ";
msg = msg + "Are you sure you want to disable it?\n\n";
msg = msg + "Click OK to disable Stream5, or CANCEL to quit.";
@@ -2039,6 +2121,7 @@ function stream5_enable_change() {
document.iform.dns_preprocessor.checked=false;
document.iform.modbus_preproc.checked=false;
document.iform.dnp3_preproc.checked=false;
+ document.iform.appid_preproc.checked=false;
document.iform.sf_portscan.checked=false;
sf_portscan_enable_change();
}
@@ -2147,6 +2230,7 @@ function smtp_enable_change() {
function enable_change_all() {
http_inspect_enable_change();
sf_portscan_enable_change();
+ appid_preproc_enable_change();
// -- Enable/Disable Host Attribute Table settings --
host_attribute_table_enable_change();
diff --git a/config/snort/snort_rules.php b/config/snort/snort_rules.php
index 681c691f..b9050b35 100755
--- a/config/snort/snort_rules.php
+++ b/config/snort/snort_rules.php
@@ -36,6 +36,7 @@ require_once("/usr/local/pkg/snort/snort.inc");
global $g, $rebuild_rules;
$snortdir = SNORTDIR;
+$snortbindir = SNORT_PBI_BINDIR;
$rules_map = array();
$categories = array();
$pconfig = array();
@@ -400,7 +401,7 @@ elseif ($_POST['save']) {
$rebuild_rules = false;
$output = "";
$retcode = "";
- exec("/usr/local/bin/snort -T -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf 2>&1", $output, $retcode);
+ exec("{$snortbindir}snort -T -c {$snortdir}/snort_{$snort_uuid}_{$if_real}/snort.conf 2>&1", $output, $retcode);
if (intval($retcode) != 0) {
$error = "";
$start = count($output);
@@ -412,8 +413,7 @@ elseif ($_POST['save']) {
else {
/* Soft-restart Snort to live-load new rules */
snort_reload_config($a_rule[$id]);
- $savemsg = gettext("Custom rules validated successfully and have been saved to the Snort configuration files. ");
- $savemsg .= gettext("Any active Snort process on this interface has been signalled to live-load the new rules.");
+ $savemsg = gettext("Custom rules validated successfully and any active Snort process on this interface has been signalled to live-load the new rules.");
}
clear_subsystem_dirty('snort_rules');
@@ -443,6 +443,9 @@ else if ($_POST['apply']) {
// Sync to configured CARP slaves if any are enabled
snort_sync_on_changes();
+
+ if (snort_is_running($snort_uuid, $if_real))
+ $savemsg = gettext("Snort is 'live-reloading' the new rule set.");
}
include_once("head.inc");
diff --git a/config/snort/snort_sid_mgmt.php b/config/snort/snort_sid_mgmt.php
index ea1a5b99..016cc96d 100644
--- a/config/snort/snort_sid_mgmt.php
+++ b/config/snort/snort_sid_mgmt.php
@@ -294,6 +294,11 @@ if ($savemsg) {
<div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
<tbody>
+ <?php if ($g['platform'] == "nanobsd") : ?>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("SID auto-management is not supported on NanoBSD installs"); ?></td>
+ </tr>
+ <?php else: ?>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Settings"); ?></td>
</tr>
@@ -568,6 +573,7 @@ if ($savemsg) {
&nbsp;&nbsp;<?=gettext("Remember to save changes before exiting this page"); ?>
</td>
</tr>
+ <?php endif; ?>
</tbody>
</table>
</div>
@@ -576,8 +582,9 @@ if ($savemsg) {
</table>
</form>
-
<?php include("fend.inc"); ?>
+
+<?php if ($g['platform'] != "nanobsd") : ?>
<script type="text/javascript">
function enable_sid_conf() {
@@ -593,5 +600,7 @@ function enable_sid_conf() {
enable_sid_conf();
</script>
+<?php endif; ?>
+
</body>
</html>
diff --git a/config/squid3/34/check_ip.php b/config/squid3/34/check_ip.php
index a3f07204..5865037b 100644
--- a/config/squid3/34/check_ip.php
+++ b/config/squid3/34/check_ip.php
@@ -3,7 +3,7 @@
/* $Id$ */
/*
check_ip.php
- Copyright (C) 2013-2014 Marcello Coutinho
+ Copyright (C) 2013-2015 Marcello Coutinho
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -27,6 +27,7 @@
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
+require_once("config.inc");
error_reporting(0);
// stdin loop
if (! defined(STDIN)) {
@@ -39,40 +40,24 @@ while( !feof(STDIN)){
$line = trim(fgets(STDIN));
// %SRC
-$pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
unset($cp_db);
-if ($pf_version > 2.0){
- $dir="/var/db";
- $files=scandir($dir);
- foreach ($files as $file){
- if (preg_match("/captive.*db/",$file)){
- $dbhandle = sqlite_open("$dir/$file", 0666, $error);
- if ($dbhandle){
- $query = "select * from captiveportal";
- $result = sqlite_array_query($dbhandle, $query, SQLITE_ASSOC);
- if ($result){
- foreach ($result as $rownum => $row){
- $cp_db[$rownum]=implode(",",$row);
- }
- sqlite_close($dbhandle);
- }
- }
+$files=scandir($g['vardb_path']);
+foreach ($files as $file){
+ if (preg_match("/captive.*db/",$file)){
+ $result=squid_cp_read_db("{$g['vardb_path']}/{$file}");
+ foreach ($result as $rownum => $row){
+ $cp_db[$rownum]=implode(",",$row);
}
- }
+ }
}
-else{
- $filename="/var/db/captiveportal.db";
- if (file_exists($filename))
- $cp_db=file($filename);
-}
$usuario="";
- // 1376630450,2,172.16.3.65,00:50:56:9c:00:c7,admin,e1779ea20d0a11c7,,,,
+ //1419045939,1419045939,2000,2000,192.168.10.11,192.168.10.11,08:00:27:5c:e1:ee,08:00:27:5c:e1:ee,marcello,marcello,605a1f46e2d64556,605a1f46e2d64556,,,,,,,,,,,first,first
if (is_array($cp_db)){
foreach ($cp_db as $cpl){
$fields=explode(",",$cpl);
- if ($fields[2] != "" && $fields[2]==$line)
- $usuario=$fields[4];
+ if ($fields[4] != "" && $fields[4]==$line)
+ $usuario=$fields[8];
}
}
if ($usuario !="")
@@ -82,5 +67,22 @@ else{
fwrite (STDOUT, "{$resposta}\n");
unset($cp_db);
}
+
+/* read captive portal DB into array */
+function squid_cp_read_db($file) {
+ $cpdb = array();
+ $DB = new SQLite3($file);
+ if ($DB) {
+ $response = $DB->query("SELECT * FROM captiveportal");
+ if ($response != FALSE) {
+ while ($row = $response->fetchArray())
+ $cpdb[] = $row;
+ }
+ $DB->close();
+ }
+
+ return $cpdb;
+}
+
?>
diff --git a/config/squid3/34/squid.inc b/config/squid3/34/squid.inc
index 87232c2b..69a50125 100755
--- a/config/squid3/34/squid.inc
+++ b/config/squid3/34/squid.inc
@@ -42,15 +42,8 @@ if(!function_exists("filter_configure"))
require_once("filter.inc");
$shortcut_section = "squid";
-$pfs_version = substr(trim(file_get_contents("/etc/version")),0,3);
-if (is_dir('/usr/pbi/squid-' . php_uname("m"))) {
- if ($pfs_version == 2.2)
- define('SQUID_LOCALBASE', '/usr/pbi/squid-' . php_uname("m")."/local");
- else
- define('SQUID_LOCALBASE', '/usr/pbi/squid-' . php_uname("m"));
-} else {
- define('SQUID_LOCALBASE','/usr/local');
-}
+define('SQUID_BASE', '/usr/pbi/squid-' . php_uname("m"));
+define('SQUID_LOCALBASE', SQUID_BASE . "/local");
define('SQUID_CONFBASE', SQUID_LOCALBASE .'/etc/squid');
define('SQUID_CONFFILE', SQUID_CONFBASE . '/squid.conf');
@@ -138,12 +131,12 @@ function squid_dash_z($cache_action='none') {
if(!is_dir($cachedir.'/00/')) {
log_error("Creating squid cache subdirs in $cachedir");
- mwexec(SQUID_LOCALBASE. "/sbin/squid -k shutdown -f " . SQUID_CONFFILE);
+ mwexec(SQUID_BASE. "/sbin/squid -k shutdown -f " . SQUID_CONFFILE);
sleep(5);
- mwexec(SQUID_LOCALBASE. "/sbin/squid -k kill -f " . SQUID_CONFFILE);
+ mwexec(SQUID_BASE. "/sbin/squid -k kill -f " . SQUID_CONFFILE);
// Double check permissions here, should be safe to recurse cache dir if it's small here.
mwexec("/usr/sbin/chown -R proxy:proxy $cachedir");
- mwexec(SQUID_LOCALBASE. "/sbin/squid -z -f " . SQUID_CONFFILE);
+ mwexec(SQUID_BASE. "/sbin/squid -z -f " . SQUID_CONFFILE);
}
if(file_exists("/var/squid/cache/swap.state")) {
@@ -176,7 +169,7 @@ function squid_install_command() {
$settingsgen = $config['installedpackages']['squid']['config'][0];
if (file_exists("/usr/local/pkg/check_ip.php"))
- rename("/usr/local/pkg/check_ip.php",SQUID_LOCALBASE . "/libexec/squid/check_ip.php");
+ rename("/usr/local/pkg/check_ip.php",SQUID_BASE . "/bin/check_ip.php");
/* Set storage system */
if ($g['platform'] == "nanobsd") {
$config['installedpackages']['squidcache']['config'][0]['harddisk_cache_system'] = 'null';
@@ -347,11 +340,11 @@ function squid_install_command() {
if (!is_service_running('squid')) {
update_status("Starting... One moment please...");
log_error("Starting Squid");
- mwexec_bg(SQUID_LOCALBASE. "/sbin/squid -f " . SQUID_CONFFILE);
+ mwexec_bg(SQUID_BASE. "/sbin/squid -f " . SQUID_CONFFILE);
} else {
update_status("Reloading Squid for configuration sync... One moment please...");
log_error("Reloading Squid for configuration sync");
- mwexec_bg(SQUID_LOCALBASE. "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
+ mwexec_bg(SQUID_BASE. "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
}
/* restart proxy alarm scripts */
@@ -409,6 +402,24 @@ function squid_before_form_general(&$pkg) {
for ($i = 0; $i < count($values) - 1; $i++)
$field['options']['option'][] = array('name' => $names[$i], 'value' => $values[$i]);
}
+function squid_validate_antivirus($post, &$input_errors) {
+ global $config;
+ if ($post['enable']=="on"){
+ if($post['squidclamav'] && preg_match("/(\S+proxy.domain\S+)/",$post['squidclamav'],$a_match)){
+ $input_errors[] ="Squidclamav warns redirect points to sample config domain ({$a_match[1]})";
+ $input_errors[] ="Change redirect info on 'squidclamav.conf' field to pfsense gui or an external host. ";
+ }
+ if($post['c-icap_conf']) {
+ if( !preg_match("/squid_clamav/",$post['c-icap_conf'])){
+ $input_errors[] ="c-icap Squidclamav service definition is no present.";
+ $input_errors[] ="Add 'Service squid_clamav squidclamav.so'(without quotes) to 'c-icap.conf' field in order to get it working.";
+ }
+ if (preg_match("/(Manager:Apassword\S+)/",$post['c-icap_conf'],$c_match)){
+ $input_errors[] ="Remove ldap configuration'{$c_match[1]}' from 'c-icap.conf' field.";
+ }
+ }
+ }
+}
function squid_validate_general($post, &$input_errors) {
global $config;
@@ -615,7 +626,7 @@ function squid_validate_traffic($post, &$input_errors) {
}
function squid_validate_reverse($post, &$input_errors) {
-
+ global $config;
if(!empty($post['reverse_ip'])) {
$reverse_ip = explode(";", ($post['reverse_ip']));
foreach ($reverse_ip as $reip) {
@@ -628,13 +639,20 @@ function squid_validate_reverse($post, &$input_errors) {
$input_errors[] = 'The field \'external FQDN\' must contain a valid domain name';
$port = trim($post['reverse_http_port']);
+ preg_match("/(\d+)/",`sysctl net.inet.ip.portrange.first`,$portrange);
if (!empty($port) && !is_port($port))
$input_errors[] = 'The field \'reverse HTTP port\' must contain a valid port number';
-
+ if (!empty($port) && is_port($port) && $port < $portrange[1]){
+ $input_errors[] = "The field 'reverse HTTP port' must contain a port number higher than net.inet.ip.portrange.first sysctl value({$portrange[1]}).";
+ $input_errors[] = "To listen on low ports, change portrange.first sysctl value to 0 on system tunable options and restart squid daemon.";
+ }
$port = trim($post['reverse_https_port']);
if (!empty($port) && !is_port($port))
$input_errors[] = 'The field \'reverse HTTPS port\' must contain a valid port number';
-
+ if (!empty($port) && is_port($port) && $port < $portrange[1]){
+ $input_errors[] = "The field 'reverse HTTPS port' must contain a port number higher than net.inet.ip.portrange.first sysctl value({$portrange[1]}).";
+ $input_errors[] = "To listen on low ports, change portrange.first sysctl value to 0 on system tunable options and restart squid daemon.";
+ }
if ($post['reverse_ssl_cert'] == 'none')
$input_errors[] = 'A valid certificate for the external interface must be selected';
@@ -736,7 +754,7 @@ function squid_install_cron($should_install) {
$rotate_job_id=-1;
$swapstate_job_id=-1;
$cron_cmd=($settings['clear_cache']=='on' ? "/usr/local/pkg/swapstate_check.php clean; " : "");
- $cron_cmd .= SQUID_LOCALBASE."/sbin/squid -k rotate -f " . SQUID_CONFFILE;
+ $cron_cmd .= SQUID_BASE."/sbin/squid -k rotate -f " . SQUID_CONFFILE;
$need_write = false;
foreach($config['cron']['item'] as $item) {
if(strstr($item['task_name'], "squid_rotate_logs")) {
@@ -942,7 +960,12 @@ function squid_resync_general() {
}
$icp_port = ($settings['icp_port'] ? $settings['icp_port'] : 0);
$dns_v4_first= ($settings['dns_v4_first'] == "on" ? "on" : "off" );
- $pidfile = "{$g['varrun_path']}/squid.pid";
+ $piddir="{$g['varrun_path']}/squid";
+ $pidfile = "{$piddir}/squid.pid";
+ if (!is_dir($piddir)){
+ make_dirs($piddir);
+ squid_chown_recursive($piddir, 'proxy', 'wheel');
+ }
$language = ($settings['error_language'] ? $settings['error_language'] : 'en');
$icondir = SQUID_CONFBASE . '/icons';
$hostname = ($settings['visible_hostname'] ? $settings['visible_hostname'] : 'localhost');
@@ -1002,7 +1025,8 @@ EOD;
$conf .= "acl localnet src $src\n";
$valid_acls[] = 'localnet';
}
- if ($settings['disable_xforward']) $conf .= "forwarded_for off\n";
+ if ($settings['xforward_mode']) $conf .= "forwarded_for {$settings['xforward_mode']}\n";
+ else $conf .= "forwarded_for on\n"; //only used for first run
if ($settings['disable_via']) $conf .= "via off\n";
if ($settings['disable_squidversion']) $conf .= "httpd_suppress_version_string on\n";
if (!empty($settings['uri_whitespace'])) $conf .= "uri_whitespace {$settings['uri_whitespace']}\n";
@@ -1327,35 +1351,6 @@ function squid_resync_antivirus(){
}
if (is_array($config['installedpackages']['squid']))
$squid_config=$config['installedpackages']['squid']['config'][0];
- $clwarn="clwarn.cgi.en_EN";
- if (preg_match("/de/i",$squid_config['error_language']))
- $clwarn="clwarn.cgi.de_DE";
- if (preg_match("/ru/i",$squid_config['error_language']))
- $clwarn="clwarn.cgi.ru_RU";
- if (preg_match("/fr/i",$squid_config['error_language']))
- $clwarn="clwarn.cgi.fr_FR";
- if (preg_match("/pt_br/i",$squid_config['error_language']))
- $clwarn="clwarn.cgi.pt_BR";
- $clwarn_file="/usr/local/www/clwarn.cgi";
- copy(SQUID_LOCALBASE."/libexec/squidclamav/{$clwarn}",$clwarn_file);
-
- #fix perl path on clwarn.cgi
- $clwarn_file_new=file_get_contents($clwarn_file);
- $c_pattern[]="@/usr/\S+/perl@";
- $c_replacement[]=SQUID_LOCALBASE."/bin/perl";
- /*$c_pattern[]="@redirect \S+/clwarn.cgi@";
- $gui_proto=$config['system']['webgui']['protocol'];
- $gui_port=$config['system']['webgui']['port'];
- if($gui_port == "") {
- $gui_port($gui_proto == "http"?"80":"443");
- }
- $c_replacement[]=SQUID_LOCALBASE."redirect {$gui_proto}://127.0.0.1:{$gui_port}/clwarn.cgi";
- */
- $clwarn_file_new=preg_replace($c_pattern, $c_replacement,$clwarn_file_new);
- file_put_contents($clwarn_file, $clwarn_file_new,LOCK_EX);
-
- #fix clwarn.cgi file permission
- chmod($clwarn_file,0755);
$conf = <<< EOF
icap_enable on
@@ -1366,11 +1361,10 @@ icap_client_username_header X-Authenticated-User
icap_preview_enable on
icap_preview_size 1024
-icap_service service_req reqmod_precache bypass=0 icap://127.0.0.1:1344/squidclamav
-icap_service service_resp respmod_precache bypass=0 icap://127.0.0.1:1344/squidclamav
-
-adaptation_access service_req allow all
-adaptation_access service_resp allow all
+icap_service service_avi_req reqmod_precache icap://[::1]:1344/squid_clamav bypass=off
+adaptation_access service_avi_req allow all
+icap_service service_avi_resp respmod_precache icap://[::1]:1344/squid_clamav bypass=on
+adaptation_access service_avi_resp allow all
EOF;
#check if icap is enabled on rc.conf.local
@@ -1397,29 +1391,41 @@ EOF;
if (file_exists(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.default")){
$sample_file=file_get_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.default");
$clamav_m[0]="@/var/run/clamav/clamd.ctl@";
+ $clamav_m[1]="@cgi-bin/clwarn.cgi@";
$clamav_r[0]="/var/run/clamav/clamd.sock";
+ $clamav_r[1]="squid_clwarn.php";
file_put_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample",preg_replace($clamav_m,$clamav_r,$sample_file),LOCK_EX);
}
#c-icap.conf
if (!file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample"))
if (file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.default")){
$sample_file=file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.default");
- if (! preg_match ("/squidclamav/"))
- $sample_file.="\nService squidclamav squidclamav.so\n";
-
- file_put_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample",$sample_file,LOCK_EX);
+ if (! preg_match("/squid_clamav/",$sample_file))
+ $sample_file.="\nService squid_clamav squidclamav.so\n";
+ $cicap_m[0]="@Manager:Apassword\S+@";
+ $cicap_r[0]="";
+ file_put_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample",preg_replace($cicap_m,$cicap_r,$sample_file),LOCK_EX);
}
+ //check squidclamav files until pbis are gone(https://redmine.pfsense.org/issues/4197)
+ $ln_icap= array('bin/c-icap','bin/c-icap-client','c-icap-config','c-icap-libicapapi-config','c-icap-stretch','lib/c_icap','share/c_icap','etc/c-icap');
+ foreach ($ln_icap as $ln){
+ if (!file_exists("/usr/local/{$ln}") && file_exists(SQUID_LOCALBASE."/{$ln}"))
+ symlink(SQUID_LOCALBASE."/{$ln}","/usr/local/{$ln}");
+ }
+ if (!file_exists("/usr/local/lib/libicapapi.so.3") && file_exists(SQUID_LOCALBASE."/lib/libicapapi.so.3.0.5"))
+ symlink(SQUID_LOCALBASE."/lib/libicapapi.so.3.0.5","/usr/local/lib/libicapapi.so.3");
+
$loadsample=0;
if ($antivirus_config['squidclamav'] =="" && file_exists(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample")){
- $config['installedpackages']['squidantivirus']['config'][0]['squidclamav']=base64_encode(file_get_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample"));
+ $config['installedpackages']['squidantivirus']['config'][0]['squidclamav']=base64_encode(str_replace( "\r", "",file_get_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf.sample")));
$loadsample++;
}
if ($antivirus_config['c-icap_conf'] =="" && file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample")){
- $config['installedpackages']['squidantivirus']['config'][0]['c-icap_conf']=base64_encode(file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample"));
+ $config['installedpackages']['squidantivirus']['config'][0]['c-icap_conf']=base64_encode(str_replace( "\r", "",file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.conf.sample")));
$loadsample++;
}
- if ($antivirus_config['squidclamav'] =="" && file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.magic.default")){
- $config['installedpackages']['squidantivirus']['config'][0]['c-icap_magic']=base64_encode(file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.magic.default"));
+ if ($antivirus_config['c-icap_magic'] =="" && file_exists(SQUID_LOCALBASE."/etc/c-icap/c-icap.magic.sample")){
+ $config['installedpackages']['squidantivirus']['config'][0]['c-icap_magic']=base64_encode(str_replace( "\r", "",file_get_contents(SQUID_LOCALBASE."/etc/c-icap/c-icap.magic.sample")));
$loadsample++;
}
if($loadsample > 0){
@@ -1440,15 +1446,12 @@ EOF;
#Check clamav database
if (count(glob("/var/db/clamav/*d"))==0){
log_error("Squid - Missing /var/db/clamav/*.cvd or *.cld files. Running freshclam on background.");
- mwexec_bg(SQUID_LOCALBASE."/bin/freshclam");
- }
- #check startup scripts on pfsense > 2.1
- if (preg_match("/usr.pbi/",SQUID_LOCALBASE)){
- $rcd_files = scandir(SQUID_LOCALBASE."/etc/rc.d");
- foreach($rcd_files as $rcd_file)
- if (!file_exists("/usr/local/etc/rc.d/{$rcd_file}"))
- symlink (SQUID_LOCALBASE."/etc/rc.d/{$rcd_file}","/usr/local/etc/rc.d/{$rcd_file}");
+ mwexec_bg(SQUID_BASE."/bin/freshclam");
}
+ $rcd_files = scandir(SQUID_LOCALBASE."/etc/rc.d");
+ foreach($rcd_files as $rcd_file)
+ if (!file_exists("/usr/local/etc/rc.d/{$rcd_file}"))
+ symlink (SQUID_LOCALBASE."/etc/rc.d/{$rcd_file}","/usr/local/etc/rc.d/{$rcd_file}");
#write advanced icap config files
file_put_contents(SQUID_LOCALBASE."/etc/c-icap/squidclamav.conf",base64_decode($antivirus_config['squidclamav']),LOCK_EX);
@@ -1467,11 +1470,29 @@ EOF;
$sample_file=file_get_contents($c_icap_rcfile);
$cicapm[0]="@c_icap_user=.*}@";
$cicapr[0]='c_icap_user="clamav"}';
+ $cicapm[1]="@/usr/local@";
+ $cicapr[1]=SQUID_LOCALBASE;
file_put_contents($c_icap_rcfile,preg_replace($cicapm,$cicapr,$sample_file),LOCK_EX);
}
mwexec_bg("/usr/local/etc/rc.d/c-icap start");
}
- #check clamav
+ #check clamav/freshclam
+ $rc_files=array("clamav-freshclam","clamav-clamd");
+ $clamm[0]="@/usr/local/(bin|sbin)@";
+ $clamm[1]="@/local/(bin|sbin)@";
+ $clamm[2]="@/usr/local/etc@";
+ $clamm[3]="@enable:=NO@";
+ $clamr[0]=SQUID_BASE."/bin";
+ $clamr[1]="/bin";
+ $clamr[2]=SQUID_LOCALBASE."/etc";
+ $clamr[3]="enable:=YES";
+ foreach ($rc_files as $rc_file){
+ $clamav_rcfile="/usr/local/etc/rc.d/{$rc_file}";
+ if (file_exists($clamav_rcfile)){
+ $sample_file=file_get_contents($clamav_rcfile);
+ file_put_contents($clamav_rcfile,preg_replace($clamm,$clamr,$sample_file),LOCK_EX);
+ }
+ }
if (is_process_running("clamd"))
mwexec_bg("/usr/local/etc/rc.d/clamav-clamd reload");
else
@@ -1703,6 +1724,11 @@ function squid_resync_auth() {
$conf .="http_access deny sglog\n";
}
if ($auth_method == 'none' ) {
+ // SSL interception acl options part 2 without authentication
+ if ($settingsconfig['ssl_proxy'] == "on"){
+ $conf .= "always_direct allow all\n";
+ $conf .= "ssl_bump server-first all\n";
+ }
$conf .="# Setup allowed acls\n";
$allowed = array('allowed_subnets');
if ($settingsconfig['allow_interface'] == 'on') {
@@ -1738,7 +1764,7 @@ function squid_resync_auth() {
$conf .= "auth_param basic program ". SQUID_LOCALBASE . "/libexec/squid/basic_radius_auth -w {$settings['radius_secret']} -h {$settings['auth_server']} $port\n";
break;
case 'cp':
- $conf .= "external_acl_type check_cp children-startup={$processes} ttl={$auth_ttl} %SRC ". SQUID_LOCALBASE . "/libexec/squid/check_ip.php\n";
+ $conf .= "external_acl_type check_cp children-startup={$processes} ttl={$auth_ttl} %SRC ". SQUID_BASE . "/bin/check_ip.php\n";
$conf .= "acl password external check_cp\n";
break;
case 'msnt':
@@ -1898,12 +1924,12 @@ function squid_resync($via_rpc="no") {
if (!is_service_running('squid')) {
log_error("Starting Squid");
- mwexec(SQUID_LOCALBASE . "/sbin/squid -f " . SQUID_CONFFILE);
+ mwexec(SQUID_BASE . "/sbin/squid -f " . SQUID_CONFFILE);
}
else {
if (!isset($boot_process)){
log_error("Reloading Squid for configuration sync");
- mwexec(SQUID_LOCALBASE . "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
+ mwexec(SQUID_BASE . "/sbin/squid -k reconfigure -f " . SQUID_CONFFILE);
}
}
@@ -2268,18 +2294,19 @@ function squid_write_rcfile() {
/* Declare a variable for the SQUID_CONFFILE constant. */
/* Then the variable can be referenced easily in the Heredoc text that generates the rc file. */
$squid_conffile_var = SQUID_CONFFILE;
- $squid_local_base = SQUID_LOCALBASE;
+ $squid_base = SQUID_BASE;
$rc = array();
$rc['file'] = 'squid.sh';
$rc['start'] = <<<EOD
+#sysctl net.inet.ip.portrange.reservedhigh=0
if [ -z "`ps auxw | grep "[s]quid "|awk '{print $2}'`" ];then
- {$squid_local_base}/sbin/squid -f {$squid_conffile_var}
+ {$squid_base}/sbin/squid -f {$squid_conffile_var}
fi
EOD;
$rc['stop'] = <<<EOD
-{$squid_local_base}/sbin/squid -k shutdown -f {$squid_conffile_var}
+{$squid_base}/sbin/squid -k shutdown -f {$squid_conffile_var}
# Just to be sure...
sleep 5
@@ -2294,9 +2321,9 @@ killall pinger 2>/dev/null
EOD;
$rc['restart'] = <<<EOD
if [ -z "`ps auxw | grep "[s]quid "|awk '{print $2}'`" ];then
- {$squid_local_base}/sbin/squid -f {$squid_conffile_var}
+ {$squid_base}/sbin/squid -f {$squid_conffile_var}
else
- {$squid_local_base}/sbin/squid -k reconfigure -f {$squid_conffile_var}
+ {$squid_base}/sbin/squid -k reconfigure -f {$squid_conffile_var}
fi
EOD;
diff --git a/config/squid3/34/squid.xml b/config/squid3/34/squid.xml
index 970f093e..57dfc938 100644
--- a/config/squid3/34/squid.xml
+++ b/config/squid3/34/squid.xml
@@ -46,7 +46,7 @@
<requirements>Describe your package requirements here</requirements>
<faq>Currently there are no FAQ items provided.</faq>
<name>squid</name>
- <version>3.4.9</version>
+ <version>3.4.10_2 pkg 0.2.6</version>
<title>Proxy server: General settings</title>
<include_file>/usr/local/pkg/squid.inc</include_file>
<menu>
@@ -239,6 +239,11 @@
<item>https://packages.pfsense.org/packages/config/squid3/34/squid_log_parser.php</item>
</additional_files_needed>
<additional_files_needed>
+ <prefix>/usr/local/www/</prefix>
+ <chmod>0755</chmod>
+ <item>https://packages.pfsense.org/packages/config/squid3/34/squid_clwarn.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
<prefix>/usr/local/www/shortcuts/</prefix>
<chmod>0755</chmod>
<item>https://packages.pfsense.org/packages/config/squid3/34/pkg_squid.inc</item>
@@ -480,10 +485,18 @@
<default_value>en</default_value>
</field>
<field>
- <fielddescr>Disable X-Forward</fielddescr>
- <fieldname>disable_xforward</fieldname>
- <description>If not set, Squid will include your system's IP address or name in the HTTP requests it forwards.</description>
- <type>checkbox</type>
+ <fielddescr>X-Forward Mode</fielddescr>
+ <fieldname>xforward_mode</fieldname>
+ <description>&lt;p&gt;&lt;b&gt; on:&lt;/b&gt; Squid will append your client's IP address in the HTTP requests it forwards. (Default)&lt;p&gt; By default it looks like: X-Forwarded-For: 192.1.2.3 &lt;p&gt; &lt;b&gt; off:&lt;/b&gt; It will appear as: X-Forwarded-For: unknown&lt;p&gt; &lt;b&gt; transparent:&lt;/b&gt; Squid will not alter the X-Forwarded-For header in any way.&lt;p&gt; &lt;b&gt; delete:&lt;/b&gt; Squid will delete the entire X-Forwarded-For header.&lt;p&gt; &lt;b&gt; truncate:&lt;/b&gt; Squid will remove all existing X-Forwarded-For entries, and place the client IP as the sole entry.</description>
+ <type>select</type>
+ <default_value>on</default_value>
+ <options>
+ <option><name>(on)</name><value>on</value></option>
+ <option><name>off</name><value>off</value></option>
+ <option><name>transparent</name><value>transparent</value></option>
+ <option><name>delete</name><value>delete</value></option>
+ <option><name>truncate</name><value>truncate</value></option>
+ </options>
</field>
<field>
<fielddescr>Disable VIA</fielddescr>
diff --git a/config/squid3/34/squid_antivirus.xml b/config/squid3/34/squid_antivirus.xml
index 2afb1ff1..c722598d 100755
--- a/config/squid3/34/squid_antivirus.xml
+++ b/config/squid3/34/squid_antivirus.xml
@@ -151,6 +151,7 @@
</field>
</fields>
<custom_php_validation_command>
+ squid_validate_antivirus($_POST, $input_errors);
</custom_php_validation_command>
<custom_php_resync_config_command>
squid_resync();
diff --git a/config/squid3/34/squid_clwarn.php b/config/squid3/34/squid_clwarn.php
new file mode 100644
index 00000000..0bd97d58
--- /dev/null
+++ b/config/squid3/34/squid_clwarn.php
@@ -0,0 +1,95 @@
+<?php
+/* ========================================================================== */
+/*
+ squid_clwarn.php
+ part of pfSense (http://www.pfSense.com)
+ Copyright (C) 2015 Marcello Coutinho
+ All rights reserved.
+ */
+/* ========================================================================== */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+ */
+/* ========================================================================== */
+$VERSION = '6.10';
+ $url = $_REQUEST['url'];
+$virus=($_REQUEST['virus']?$_REQUEST['virus']:$_REQUEST['malware']);
+$source = preg_replace("@/-@","",$_REQUEST['source']);
+$user = $_REQUEST['user'];
+
+
+$TITLE_VIRUS = "SquidClamAv $VERSION: Virus detected!";
+$subtitle = 'Virus name';
+$errorreturn = 'This file cannot be downloaded.';
+$urlerror = 'contains a virus';
+if (preg_match("/Safebrowsing/",$virus)) {
+ $TITLE_VIRUS = "SquidClamAv $VERSION: Unsafe Browsing detected";
+ $subtitle = 'Malware / pishing type';
+ $urlerror = 'is listed as suspicious';
+ $errorreturn = 'This page can not be displayed';
+}
+
+# Remove clamd infos
+$vp[0]="/stream: /";
+$vp[1]="/ FOUND/";
+$vr[0]="";
+$vr[1]="";
+
+$virus = preg_replace($vp,$vr,$virus);
+
+
+?>
+<style type="text/css">
+ .visu {
+ border:1px solid #C0C0C0;
+ color:#FFFFFF;
+ position: relative;
+ min-width: 13em;
+ max-width: 52em;
+ margin: 4em auto;
+ border: 1px solid ThreeDShadow;
+ border-radius: 10px;
+ padding: 3em;
+ -moz-padding-start: 30px;
+ background-color: #8b0000;
+}
+.visu h2, .visu h3, .visu h4 {
+ font-size:130%;
+ font-family:"times new roman", times, serif;
+ font-style:normal;
+ font-weight:bolder;
+}
+</style>
+ <div class="visu">
+ <h2><?=$TITLE_VIRUS?></h2>
+ <hr>
+ <p>
+ The requested URL <?=$url?> <?=$urlerror?><br>
+ <?=$subtitle?>: <?=$virus?>
+ <p>
+ <?=$errorreturn?>
+ <p>
+ Origin: <?=$source?> / <?=$user?>
+ <p>
+ <hr>
+ <font color="blue"> Powered by <a href="http://squidclamav.darold.net/">SquidClamAv <?=$VERSION?></a>.</font>
+ </div>
diff --git a/config/squid3/34/swapstate_check.php b/config/squid3/34/swapstate_check.php
index b9f51ec1..7a7ccd27 100644
--- a/config/squid3/34/swapstate_check.php
+++ b/config/squid3/34/swapstate_check.php
@@ -30,17 +30,6 @@ require_once('config.inc');
require_once('util.inc');
require_once('squid.inc');
-$pfs_version = substr(trim(file_get_contents("/etc/version")),0,3);
-if (is_dir('/usr/pbi/squid-' . php_uname("m"))) {
- if ($pfs_version == 2.2)
- define('SQUID_LOCALBASE', '/usr/pbi/squid-' . php_uname("m")."/local");
- else
- define('SQUID_LOCALBASE', '/usr/pbi/squid-' . php_uname("m"));
-} else {
- define('SQUID_LOCALBASE','/usr/local');
-}
-
-
$settings = $config['installedpackages']['squidcache']['config'][0];
// Only check the cache if Squid is actually caching.
// If there is no cache then quietly do nothing.
diff --git a/config/squidGuard-devel/squidguard_configurator.inc b/config/squidGuard-devel/squidguard_configurator.inc
index a48426bb..ff2b9f2c 100644
--- a/config/squidGuard-devel/squidguard_configurator.inc
+++ b/config/squidGuard-devel/squidguard_configurator.inc
@@ -93,10 +93,10 @@ define('CONFIG_SG_HEADER', "
# squid config options
# ------------------------------------------------------------------------------
define('REDIRECTOR_OPTIONS_REM', '# squidGuard options');
-define('REDIRECTOR_PROGRAM_OPT', 'redirect_program');
-define('REDIRECT_BYPASS_OPT', 'redirector_bypass');
+define('REDIRECTOR_PROGRAM_OPT', 'url_rewrite_program');
+define('REDIRECT_BYPASS_OPT', 'url_rewrite_bypass');
define('REDIRECT_CHILDREN_OPT', 'url_rewrite_children');
-define('REDIRECTOR_PROCESS_COUNT', '5'); # redirector processes count will started
+define('REDIRECTOR_PROCESS_COUNT', '16 startup=8 idle=4 concurrency=0'); # redirector processes count will started
# ------------------------------------------------------------------------------
# squidguard config options
diff --git a/config/squidGuard/squidguard.xml b/config/squidGuard/squidguard.xml
index 62882539..3a77edf3 100644
--- a/config/squidGuard/squidguard.xml
+++ b/config/squidGuard/squidguard.xml
@@ -6,7 +6,7 @@
<requirements>Describe your package requirements here</requirements>
<faq>Currently there are no FAQ items provided.</faq>
<name>squidguardgeneral</name>
- <version>1.4_4 pkg v.1.9.6</version>
+ <version>1.4_4 pkg v.1.9.8</version>
<title>Proxy filter SquidGuard: General settings</title>
<include_file>/usr/local/pkg/squidguard.inc</include_file>
<!-- Installation -->
diff --git a/config/squidGuard/squidguard_configurator.inc b/config/squidGuard/squidguard_configurator.inc
index 006cf083..d3448c5d 100644
--- a/config/squidGuard/squidguard_configurator.inc
+++ b/config/squidGuard/squidguard_configurator.inc
@@ -2081,8 +2081,8 @@ function squidguard_blacklist_update_start($url_filename)
function squidguard_blacklist_update_cancel()
{
# kill script and SG update process
- mwexec("kill `ps auxwwww | grep '" . SCR_NAME_BLKUPDATE . "' | grep -v 'grep' | awk '{print $2}'`");
- mwexec("kill `ps auxwwww | grep 'squidGuard -c .* -C all' | grep -v 'grep' | awk '{print $2}'`");
+ mwexec("/bin/kill `ps auxwwww | /usr/bin/grep '" . SCR_NAME_BLKUPDATE . "' | /usr/bin/grep -v 'grep' | /usr/bin/awk '{print $2}'`");
+ mwexec("/bin/kill `ps auxwwww | /usr/bin/grep 'squidGuard -c .* -C all' | /usr/bin/grep -v 'grep' | /usr/bin/awk '{print $2}'`");
squidguard_ramdisk(false);
squidguard_update_log("Blacklist update terminated by user.", "");
@@ -2102,7 +2102,7 @@ function squidguard_blacklist_update_clearlog()
# -----------------------------------------------------------------------------
function squidguard_blacklist_update_IsStarted()
{
- return exec("ps auxwwww | grep '" . SCR_NAME_BLKUPDATE . "' | grep -v 'grep' | awk '{print $2}' | wc -l | awk '{ print $1 }'");
+ return exec("/bin/ps auxwwww | /usr/bin/grep '" . SCR_NAME_BLKUPDATE . "' | /usr/bin/grep -v 'grep' | /usr/bin/awk '{print $2}' | /usr/bin/wc -l | /usr/bin/awk '{ print $1 }'");
}
# -----------------------------------------------------------------------------
@@ -2126,27 +2126,27 @@ function sg_reconfigure_blacklist($source_filename, $opt = '')
# 2. download
if ($sf[0] === "/") { # local file - example '/tmp/blacklists.tar'
- sg_addlog("sg_reconfigure_blacklist", "Update from file '$sf'.", SQUIDGUARD_INFO);
- squidguard_update_log("Copy archive from file '$sf'");
+ sg_addlog("sg_reconfigure_blacklist", "Update from file '{$sf}'.", SQUIDGUARD_INFO);
+ squidguard_update_log("Copy archive from file '{$sf}'");
if (file_exists($sf)) {
$sf_contents = file_get_contents($sf);
} else {
- sg_addlog("sg_reconfigure_blacklist", "File '$sf' not found.", SQUIDGUARD_ERROR);
- squidguard_update_log("File '$sf' not found.");
+ sg_addlog("sg_reconfigure_blacklist", "File '{$sf}' not found.", SQUIDGUARD_ERROR);
+ squidguard_update_log("File '{$sf}' not found.");
return;
}
}
# from url
else {
- sg_addlog("sg_reconfigure_blacklist", "Download from url '$sf'.", SQUIDGUARD_INFO);
+ sg_addlog("sg_reconfigure_blacklist", "Download from url '{$sf}'.", SQUIDGUARD_INFO);
squidguard_update_log("Start download.");
$sf_contents = sg_uploadfile_from_url($sf, $opt);
}
# 3. update
if (empty($sf_contents)) {
- sg_addlog("sg_reconfigure_blacklist", "Bad content from '$sf'. Terminate.", SQUIDGUARD_ERROR);
- squidguard_update_log("Bad content from '$sf'. Terminate.");
+ sg_addlog("sg_reconfigure_blacklist", "Bad content from '{$sf}'. Terminate.", SQUIDGUARD_ERROR);
+ squidguard_update_log("Bad content from '{$sf}'. Terminate.");
return;
}
@@ -2177,7 +2177,7 @@ function sg_update_blacklist($from_file)
$conf_path = SQUIDGUARD_VAR . DB_REBUILD_BLK_CONF;
$blklist_file = SQUIDGUARD_BLK_FILELISTPATH;
- sg_addlog("sg_update_blacklist", "Begin with '$from_file'.", SQUIDGUARD_INFO);
+ sg_addlog("sg_update_blacklist", "Begin with '{$from_file}'.", SQUIDGUARD_INFO);
if (file_exists($from_file)) {
# check work and DB dir's
@@ -2185,20 +2185,20 @@ function sg_update_blacklist($from_file)
if (file_exists($squidguard_config[F_WORKDIR])) $workdir = $squidguard_config[F_WORKDIR];
# delete old tmp dir's
- if (file_exists($tmp_unpack_dir)) mwexec("rm -R $tmp_unpack_dir");
- if (file_exists($arc_db_dir)) mwexec("rm -R $arc_db_dir");
+ if (file_exists($tmp_unpack_dir)) mwexec("/bin/rm -R {$tmp_unpack_dir}");
+ if (file_exists($arc_db_dir)) mwexec("/bin/rm -R {$arc_db_dir}");
squidguard_ramdisk(false);
# create new tmp/arc dir's, use ramdisk for quick operations
squidguard_ramdisk(true);
- mwexec("mkdir -p -m 0755 $tmp_unpack_dir");
- mwexec("mkdir -p -m 0755 $arc_db_dir");
+ mwexec("/bin/mkdir -p -m 0755 {$tmp_unpack_dir}");
+ mwexec("/bin/mkdir -p -m 0755 {$arc_db_dir}");
# 1. unpack archive
squidguard_update_log("Unpack archive");
- mwexec("tar zxvf $from_file -C $tmp_unpack_dir");
+ mwexec("/usr/bin/tar zxvf $from_file -C {$tmp_unpack_dir}");
set_file_access($tmp_unpack_dir, OWNER_NAME, 0755);
- sg_addlog("sg_update_blacklist", "Unpack uploaded file '$from_file' -> '$tmp_unpack_dir'.", SQUIDGUARD_INFO);
+ sg_addlog("sg_update_blacklist", "Unpack uploaded file '{$from_file}' -> '{$tmp_unpack_dir}'.", SQUIDGUARD_INFO);
# 2. copy blacklist to TempDB base & create entries list
squidguard_update_log("Scan blacklist categories.");
@@ -2211,7 +2211,7 @@ function sg_update_blacklist($from_file)
# move blacklist catalog structure to 'one level' (from tmp_DB to arch_DB)
foreach ($blk_items as $key => $val) {
- $current_dbpath = "$arc_db_dir/$key";
+ $current_dbpath = "{$arc_db_dir}/{$key}";
if (count($val)) {
# make blk_list for config file
$blk_list[$key] = $key;
@@ -2220,9 +2220,9 @@ function sg_update_blacklist($from_file)
# need moving $val['path'] to $current_dbpath
# if $current_dbpath exists, then $val['path'] will created as subdir - !it's worng!
if (file_exists($current_dbpath))
- mwexec("rm -R $current_dbpath");
- mwexec("mv -f {$val['path']}/ $current_dbpath");
- sg_addlog("sg_update_blacklist", "Move {$val['path']}/ -> $current_dbpath.", SQUIDGUARD_INFO);
+ mwexec("/bin/rm -R {$current_dbpath}");
+ mwexec("/bin/mv -f {$val['path']}/ {$current_dbpath}");
+ sg_addlog("sg_update_blacklist", "Move {$val['path']}/ -> {$current_dbpath}.", SQUIDGUARD_INFO);
}
}
set_file_access($arc_db_dir, OWNER_NAME, 0755);
@@ -2242,7 +2242,7 @@ function sg_update_blacklist($from_file)
file_put_contents($blklist_file, $cont);
set_file_access ($blklist_file, OWNER_NAME, 0755);
- sg_addlog("sg_update_blacklist", "Create DB entries list '$blklist_file'.", SQUIDGUARD_INFO);
+ sg_addlog("sg_update_blacklist", "Create DB entries list '{$blklist_file}'.", SQUIDGUARD_INFO);
squidguard_update_log("Found " . count($blk_items) . " items.");
}
@@ -2252,8 +2252,8 @@ function sg_update_blacklist($from_file)
squidguard_update_log("Copy DB to workdir.");
$blklist_file = $arc_db_dir . SQUIDGUARD_BLK_FILELIST;
- mwexec("cp -R -p $arc_db_dir/ $dbhome");
- mwexec("cp -f -p $blklist_file " . SQUIDGUARD_WORKDIR);
+ mwexec("/bin/cp -R -p {$arc_db_dir}/ {$dbhome}");
+ mwexec("/bin/cp -f -p {$blklist_file} " . SQUIDGUARD_WORKDIR);
set_file_access($dbhome, OWNER_NAME, 0755);
squidguard_update_log("Reconfigure Squid proxy.");
@@ -2266,7 +2266,7 @@ function sg_update_blacklist($from_file)
# free ramdisk
squidguard_ramdisk(false);
}
- else sg_addlog("sg_update_blacklist", "File $from_file not found.", SQUIDGUARD_ERROR);
+ else sg_addlog("sg_update_blacklist", "File {$from_file} not found.", SQUIDGUARD_ERROR);
}
# -----------------------------------------------------------------------------
@@ -2382,13 +2382,13 @@ function squidguard_blacklist_restore_arcdb()
if (file_exists($arc_db_dir)) {
conf_mount_rw();
# copy arc blacklist to work DB with permissions
- mwexec("cp -R -p $arc_db_dir/ $dbhome");
+ mwexec("/bin/cp -R -p {$arc_db_dir}/ {$dbhome}");
set_file_access($dbhome, OWNER_NAME, 0755);
- sg_addlog("squidguard_blacklist_restore_arcdb", "Restore blacklist archive from '$arc_db_dir'.", SQUIDGUARD_INFO);
+ sg_addlog("squidguard_blacklist_restore_arcdb", "Restore blacklist archive from '{$arc_db_dir}'.", SQUIDGUARD_INFO);
# generate blacklist files list
$blklist = "";
- $files = scan_dir("$arc_db_dir/");
+ $files = scan_dir("{$arc_db_dir}/");
if ($files) $blklist = implode("\n", $files);
file_put_contents($blklist_file, $blklist);
set_file_access($blklist_file, OWNER_NAME, 0755);
@@ -2401,8 +2401,8 @@ function squidguard_blacklist_restore_arcdb()
conf_mount_ro();
squidguard_update_log("Restore success.");
} else {
- sg_addlog("squidguard_blacklist_restore_arcdb", "File '$arc_db_dir' or '$blklist_file' not found.", SQUIDGUARD_ERROR);
- squidguard_update_log("Restore error: File '$arc_db_dir' or '$blklist_file' not found.");
+ sg_addlog("squidguard_blacklist_restore_arcdb", "File '{$arc_db_dir}' or '{$blklist_file}' not found.", SQUIDGUARD_ERROR);
+ squidguard_update_log("Restore error: File '{$arc_db_dir}' or '{$blklist_file}' not found.");
}
}
diff --git a/config/suricata/suricata.inc b/config/suricata/suricata.inc
index af0b0da2..66c1e799 100644
--- a/config/suricata/suricata.inc
+++ b/config/suricata/suricata.inc
@@ -44,47 +44,13 @@ require_once("services.inc");
require_once("service-utils.inc");
require_once("pkg-utils.inc");
require_once("filter.inc");
+require("/usr/local/pkg/suricata/suricata_defs.inc");
global $g, $config;
// Suricata GUI needs some extra PHP memory space to manipulate large rules arrays
ini_set("memory_limit", "256M");
-if (!is_array($config['installedpackages']['suricata']))
- $config['installedpackages']['suricata'] = array();
-
-/* Get installed package version for display */
-$suricata_package_version = "Suricata {$config['installedpackages']['package'][get_pkg_id("suricata")]['version']}";
-
-// Define the installed package version
-define('SURICATA_PKG_VER', $suricata_package_version);
-
-// Define the name of the pf table used for IP blocks
-define('SURICATA_PF_TABLE', 'snort2c');
-
-// Create some other useful defines
-$pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
-if ($pf_version >= 2.2)
- define('SURICATADIR', '/usr/pbi/suricata-' . php_uname("m") . '/local/etc/suricata/');
-else
- define('SURICATADIR', '/usr/pbi/suricata-' . php_uname("m") . '/etc/suricata/');
-
-define('SURICATALOGDIR', '/var/log/suricata/');
-define('RULES_UPD_LOGFILE', SURICATALOGDIR . 'suricata_rules_update.log');
-define('ENFORCING_RULES_FILENAME', 'suricata.rules');
-define('FLOWBITS_FILENAME', 'flowbit-required.rules');
-define('SID_MODS_PATH', '/var/db/suricata/sidmods/');
-define('IPREP_PATH', '/var/db/suricata/iprep/');
-
-// Rule set download filenames and prefixes
-define('ET_DNLD_FILENAME', 'emerging.rules.tar.gz');
-define('ETPRO_DNLD_FILENAME', 'etpro.rules.tar.gz');
-define('GPLV2_DNLD_FILENAME', 'community-rules.tar.gz');
-define('VRT_FILE_PREFIX', 'snort_');
-define('GPL_FILE_PREFIX', 'GPLv2_');
-define('ET_OPEN_FILE_PREFIX', 'emerging-');
-define('ET_PRO_FILE_PREFIX', 'etpro-');
-
function suricata_generate_id() {
global $config;
@@ -139,10 +105,11 @@ function suricata_barnyard_start($suricatacfg, $if_real) {
$suricata_uuid = $suricatacfg['uuid'];
$suricatadir = SURICATADIR . "suricata_{$suricata_uuid}_{$if_real}";
$suricatalogdir = SURICATALOGDIR . "suricata_{$if_real}{$suricata_uuid}";
+ $suricatabindir = SURICATA_PBI_BINDIR;
if ($suricatacfg['barnyard_enable'] == 'on') {
log_error("[Suricata] Barnyard2 START for {$suricatacfg['descr']}({$if_real})...");
- mwexec_bg("/usr/local/bin/barnyard2 -r {$suricata_uuid} -f unified2.alert --pid-path {$g['varrun_path']} --nolock-pidfile -c {$suricatadir}/barnyard2.conf -d {$suricatalogdir} -D -q");
+ mwexec_bg("{$suricatabindir}barnyard2 -r {$suricata_uuid} -f unified2.alert --pid-path {$g['varrun_path']} --nolock-pidfile -c {$suricatadir}/barnyard2.conf -d {$suricatalogdir} -D -q");
}
}
@@ -151,10 +118,11 @@ function suricata_start($suricatacfg, $if_real) {
$suricatadir = SURICATADIR;
$suricata_uuid = $suricatacfg['uuid'];
+ $suricatabindir = SURICATA_PBI_BINDIR;
if ($suricatacfg['enable'] == 'on') {
log_error("[Suricata] Suricata START for {$suricatacfg['descr']}({$if_real})...");
- mwexec_bg("/usr/local/bin/suricata -i {$if_real} -D -c {$suricatadir}suricata_{$suricata_uuid}_{$if_real}/suricata.yaml --pidfile {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid");
+ mwexec_bg("{$suricatabindir}suricata -i {$if_real} -D -c {$suricatadir}suricata_{$suricata_uuid}_{$if_real}/suricata.yaml --pidfile {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid");
}
else
return;
@@ -163,6 +131,61 @@ function suricata_start($suricatacfg, $if_real) {
suricata_barnyard_start($suricatacfg, $if_real);
}
+function suricata_start_all_interfaces($background=FALSE) {
+
+ /*************************************************************/
+ /* This function starts all configured and enabled Suricata */
+ /* interfaces. */
+ /*************************************************************/
+
+ global $g, $config;
+
+ /* do nothing if no Suricata interfaces active */
+ if (!is_array($config['installedpackages']['suricata']['rule']))
+ return;
+
+ foreach ($config['installedpackages']['suricata']['rule'] as $suricatacfg) {
+ if ($suricatacfg['enable'] != 'on')
+ continue;
+ suricata_start($suricatacfg, get_real_interface($suricatacfg['interface']));
+ }
+}
+
+function suricata_stop_all_interfaces() {
+
+ /*************************************************************/
+ /* This function stops all configured Suricata interfaces. */
+ /*************************************************************/
+
+ global $g, $config;
+
+ /* do nothing if no Suricata interfaces active */
+ if (!is_array($config['installedpackages']['suricata']['rule']))
+ return;
+
+ foreach ($config['installedpackages']['suricata']['rule'] as $suricatacfg) {
+ suricata_stop($suricatacfg, get_real_interface($suricatacfg['interface']));
+ }
+}
+
+function suricata_restart_all_interfaces() {
+
+ /*************************************************************/
+ /* This function stops all configured Suricata interfaces */
+ /* and restarts enabled Suricata interfaces. */
+ /*************************************************************/
+
+ global $g, $config;
+
+ /* do nothing if no Suricata interfaces active */
+ if (!is_array($config['installedpackages']['suricata']['rule']))
+ return;
+
+ suricata_stop_all_interfaces();
+ sleep(2);
+ suricata_start_all_interfaces(TRUE);
+}
+
function suricata_reload_config($suricatacfg, $signal="USR2") {
/**************************************************************/
@@ -492,17 +515,61 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false, $e
return $valresult;
}
-function suricata_rules_up_install_cron($should_install=true) {
+function suricata_cron_job_exists($crontask, $match_time=FALSE, $minute="0", $hour="*", $monthday="*", $month="*", $weekday="*", $who="root") {
+
+ /************************************************************
+ * This function iterates the cron[] array in the config *
+ * to determine if the passed $crontask entry exists. It *
+ * returns TRUE if the $crontask already exists, or FALSE *
+ * if there is no match. *
+ * *
+ * The $match_time flag, when set, causes a test of the *
+ * configured task execution times along with the task *
+ * when checking for a match. *
+ * *
+ * We use this to prevent unneccessary config writes if *
+ * the $crontask already exists. *
+ ************************************************************/
+
global $config, $g;
- // Remove any existing job first
- install_cron_job("suricata_check_for_rule_updates.php", false);
+ if (!is_array($config['cron']))
+ $config['cron'] = array();
+ if (!is_array($config['cron']['item']))
+ $config['cron']['item'] = array();
+
+ foreach($config['cron']['item'] as $item) {
+ if(strpos($item['command'], $crontask) !== FALSE) {
+ if ($match_time) {
+ if ($item['minute'] != $minute)
+ return FALSE;
+ if ($item['hour'] != $hour)
+ return FALSE;
+ if ($item['mday'] != $monthday)
+ return FALSE;
+ if ($item['month'] != $month)
+ return FALSE;
+ if ($item['wday'] != $weekday)
+ return FALSE;
+ if ($item['who'] != $who)
+ return FALSE;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
- // If called with FALSE as argument, then we're done
- if ($should_install == FALSE)
- return;
+function suricata_rules_up_install_cron($should_install=true) {
+ global $config, $g;
- $command = "/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_check_for_rule_updates.php";
+ // If called with FALSE as argument, then we're removing
+ // the existing job.
+ if ($should_install == FALSE) {
+ if (suricata_cron_job_exists("suricata_check_for_rule_updates.php", FALSE))
+ install_cron_job("suricata_check_for_rule_updates.php", false);
+ return;
+ }
// Get auto-rule update parameter from configuration
$suricata_rules_up_info_ck = $config['installedpackages']['suricata']['config'][0]['autoruleupdate'];
@@ -568,12 +635,32 @@ function suricata_rules_up_install_cron($should_install=true) {
$suricata_rules_up_wday = "*";
}
- // System call to manage the cron job.
- install_cron_job($command, $should_install, $suricata_rules_up_min, $suricata_rules_up_hr, $suricata_rules_up_mday, $suricata_rules_up_month, $suricata_rules_up_wday, "root");
+ // Construct the basic cron command task
+ $command = "/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_check_for_rule_updates.php";
+
+ // If there are no changes in the cron job command string from the existing job, then exit
+ if (suricata_cron_job_exists($command, TRUE, $suricata_rules_up_min, $suricata_rules_up_hr, $suricata_rules_up_mday, $suricata_rules_up_month, $suricata_rules_up_wday, "root"))
+ return;
+
+ // Else install the new or updated cron job
+ if ($should_install)
+ install_cron_job($command, $should_install, $suricata_rules_up_min, $suricata_rules_up_hr, $suricata_rules_up_mday, $suricata_rules_up_month, $suricata_rules_up_wday, "root");
}
function suricata_loglimit_install_cron($should_install=true) {
+ // See if simply removing existing "loglimit" job for Suricata
+ if ($should_install == FALSE) {
+ if (suricata_cron_job_exists("suricata/suricata_check_cron_misc.inc", FALSE))
+ install_cron_job("suricata_check_cron_misc.inc", false);
+ return;
+ }
+
+ // If there are no changes in the cron job command string from the existing job, then exit.
+ if ($should_install && suricata_cron_job_exists("/usr/local/pkg/suricata/suricata_check_cron_misc.inc", TRUE, "*/5"))
+ return;
+
+ // Else install the new or updated cron job
install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_check_cron_misc.inc", $should_install, "*/5");
}
@@ -581,6 +668,13 @@ function suricata_rm_blocked_install_cron($should_install) {
global $config, $g;
$suri_pf_table = SURICATA_PF_TABLE;
+ // See if simply removing existing "expiretable" job for Suricata
+ if ($should_install == FALSE) {
+ if (suricata_cron_job_exists("{$suri_pf_table}", FALSE))
+ install_cron_job("{$suri_pf_table}", false);
+ return;
+ }
+
$suricata_rm_blocked_info_ck = $config['installedpackages']['suricata']['config'][0]['rm_blocked'];
if ($suricata_rm_blocked_info_ck == "15m_b") {
@@ -664,13 +758,15 @@ function suricata_rm_blocked_install_cron($should_install) {
$suricata_rm_blocked_expire = "2419200";
}
- // First, remove any existing cron task for "rm_blocked" hosts
- install_cron_job("{$suri_pf_table}", false);
+ // Construct the basic cron command task
+ $command = "/usr/bin/nice -n20 /sbin/pfctl -q -t {$suri_pf_table} -T expire {$suricata_rm_blocked_expire}";
- // Now add or update the cron task for "rm_blocked" hosts
- // if enabled.
+ // If there are no changes in the cron job command string from the existing job, then exit.
+ if (suricata_cron_job_exists($command, TRUE, $suricata_rm_blocked_min, $suricata_rm_blocked_hr, $suricata_rm_blocked_mday, $suricata_rm_blocked_month, $suricata_rm_blocked_wday, "root"))
+ return;
+
+ // Else install the new or updated cron job
if ($should_install) {
- $command = "/usr/bin/nice -n20 /sbin/pfctl -q -t {$suri_pf_table} -T expire {$suricata_rm_blocked_expire}";
install_cron_job($command, $should_install, $suricata_rm_blocked_min, $suricata_rm_blocked_hr, $suricata_rm_blocked_mday, $suricata_rm_blocked_month, $suricata_rm_blocked_wday, "root");
}
}
@@ -681,25 +777,22 @@ function sync_suricata_package_config() {
$suricatadir = SURICATADIR;
$rcdir = RCFILEPREFIX;
- conf_mount_rw();
-
// Do not start config build if there are no Suricata-configured interfaces
- if (!is_array($config['installedpackages']['suricata']) || !is_array($config['installedpackages']['suricata']['rule'])) {
- @unlink("{$rcdir}suricata.sh");
- conf_mount_ro();
+ if (!is_array($config['installedpackages']['suricata']['rule']) || count($config['installedpackages']['suricata']['rule']) < 1)
return;
- }
$suricataconf = $config['installedpackages']['suricata']['rule'];
foreach ($suricataconf as $value) {
- $if_real = get_real_interface($value['interface']);
+ /* Skip configuration of any disabled interface */
+ if ($value['enable'] != 'on')
+ continue;
// create a suricata.yaml file for interface
suricata_generate_yaml($value);
// create barnyard2.conf file for interface
if ($value['barnyard_enable'] == 'on')
- suricata_generate_barnyard2_conf($value, $if_real);
+ suricata_generate_barnyard2_conf($value, get_real_interface($value['interface']));
}
// create suricata bootup file suricata.sh
@@ -707,18 +800,16 @@ function sync_suricata_package_config() {
// setup the log directory size check job if enabled
suricata_loglimit_install_cron(true);
+
// setup the suricata rules update job if enabled
suricata_rules_up_install_cron($config['installedpackages']['suricata']['config'][0]['autoruleupdate'] != "never_up" ? true : false);
+
// set the suricata blocked hosts time
suricata_rm_blocked_install_cron($config['installedpackages']['suricata']['config'][0]['rm_blocked'] != "never_b" ? true : false);
- configure_cron();
-
// Do not attempt package sync if reinstalling package or booting
if (!isset($g['suricata_postinstall']) && !$g['booting'])
suricata_sync_on_changes();
-
- conf_mount_ro();
}
function suricata_load_suppress_sigs($suricatacfg, $track_by=false) {
@@ -853,19 +944,19 @@ function suricata_post_delete_logs($suricata_uuid = 0) {
// Keep most recent file
unset($filelist[count($filelist) - 1]);
foreach ($filelist as $file)
- @unlink($file);
+ unlink_if_exists($file);
/* Clean-up Barnyard2 archived files if any exist */
$filelist = glob("{$suricata_log_dir}/barnyard2/archive/unified2.alert.*");
foreach ($filelist as $file)
- @unlink($file);
+ unlink_if_exists($file);
/* Clean-up packet capture files if any exist */
$filelist = glob("{$suricata_log_dir}/log.pcap.*");
// Keep most recent file
unset($filelist[count($filelist) - 1]);
foreach ($filelist as $file)
- @unlink($file);
+ unlink_if_exists($file);
unset($filelist);
}
}
@@ -1693,7 +1784,7 @@ function suricata_sid_mgmt_auto_categories($suricatacfg, $log_results = FALSE) {
/****************************************************/
global $config;
- $suricata_sidmods_dir = SID_MODS_PATH;
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
$sid_mods = array();
$enables = array();
$disables = array();
@@ -2232,7 +2323,7 @@ function suricata_process_enablesid(&$rule_map, $suricatacfg, $log_results = FAL
/* $rule_map array */
/**********************************************/
- $suricata_sidmods_dir = SID_MODS_PATH;
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
$suricatalogdir = SURICATALOGDIR;
$sid_mods = array();
@@ -2279,7 +2370,7 @@ function suricata_process_disablesid(&$rule_map, $suricatacfg, $log_results = FA
/* $rule_map array */
/**********************************************/
- $suricata_sidmods_dir = SID_MODS_PATH;
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
$suricatalogdir = SURICATALOGDIR;
$sid_mods = array();
@@ -2326,7 +2417,7 @@ function suricata_process_modifysid(&$rule_map, $suricatacfg, $log_results = FAL
/* $rule_map array */
/**********************************************/
- $suricata_sidmods_dir = SID_MODS_PATH;
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
$suricatalogdir = SURICATALOGDIR;
$sid_mods = array();
@@ -2550,7 +2641,7 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
$suricatadir = SURICATADIR;
$flowbit_rules_file = FLOWBITS_FILENAME;
- $suricata_enforcing_rules_file = ENFORCING_RULES_FILENAME;
+ $suricata_enforcing_rules_file = SURICATA_ENFORCING_RULES_FILENAME;
$enabled_rules = array();
$enabled_files = array();
$all_rules = array();
@@ -2749,7 +2840,7 @@ function suricata_write_enforcing_rules_file($rule_map, $rule_path) {
/* rules file will be written. */
/************************************************/
- $rule_file = "/" . ENFORCING_RULES_FILENAME;
+ $rule_file = "/" . SURICATA_ENFORCING_RULES_FILENAME;
// See if we were passed a directory or full
// filename to write the rules to, and adjust
@@ -2798,6 +2889,7 @@ function suricata_create_rc() {
$suricatadir = SURICATADIR;
$suricatalogdir = SURICATALOGDIR;
+ $suricatabindir = SURICATA_PBI_BINDIR;
$rcdir = RCFILEPREFIX;
// If no interfaces are configured for Suricata, exit
@@ -2815,7 +2907,7 @@ function suricata_create_rc() {
// the shell script.
foreach ($suricataconf as $value) {
// Skip disabled Suricata interfaces
- if ($value['enable'] <> 'on')
+ if ($value['enable'] != 'on')
continue;
$suricata_uuid = $value['uuid'];
$if_real = get_real_interface($value['interface']);
@@ -2828,14 +2920,10 @@ function suricata_create_rc() {
pid=`/bin/pgrep -F {$g['varrun_path']}/barnyard2_{$if_real}{$suricata_uuid}.pid`
fi
- if [ ! -z \$pid ]; then
- /usr/bin/logger -p daemon.info -i -t SuricataStartup "Barnyard2 SOFT RESTART for {$value['descr']}({$suricata_uuid}_{$if_real})..."
- /bin/pkill -HUP \$pid
- else
+ if [ -z \$pid ]; then
/usr/bin/logger -p daemon.info -i -t SuricataStartup "Barnyard2 START for {$value['descr']}({$suricata_uuid}_{$if_real})..."
- /usr/local/bin/barnyard2 -r {$suricata_uuid} -f unified2.alert --pid-path {$g['varrun_path']} --nolock-pidfile -c {$suricatadir}suricata_{$suricata_uuid}_{$if_real}/barnyard2.conf -d {$suricatalogdir}suricata_{$if_real}{$suricata_uuid} -D -q
+ {$suricatabindir}/barnyard2 -r {$suricata_uuid} -f unified2.alert --pid-path {$g['varrun_path']} --nolock-pidfile -c {$suricatadir}suricata_{$suricata_uuid}_{$if_real}/barnyard2.conf -d {$suricatalogdir}suricata_{$if_real}{$suricata_uuid} -D -q > /dev/null 2>&1
fi
-
EOE;
$stop_barnyard2 = <<<EOE
@@ -2851,8 +2939,8 @@ EOE;
break
fi
done
- if [ -f /var/run/barnyard2_{$if_real}{$suricata_uuid}.pid ]; then
- /bin/rm /var/run/barnyard2_{$if_real}{$suricata_uuid}.pid
+ if [ -f {$g['varrun_path']}/barnyard2_{$if_real}{$suricata_uuid}.pid ]; then
+ /bin/rm {$g['varrun_path']}/barnyard2_{$if_real}{$suricata_uuid}.pid
fi
else
pid=`/bin/pgrep -fn "barnyard2 -r {$suricata_uuid} "`
@@ -2868,7 +2956,6 @@ EOE;
done
fi
fi
-
EOE;
if ($value['barnyard_enable'] == 'on')
$start_barnyard2 = $start_barnyard;
@@ -2877,25 +2964,20 @@ EOE;
$start_suricata_iface_start[] = <<<EOE
-###### For Each Iface
- # Start suricata and barnyard2
+ ## Start suricata on {$value['descr']} ({$if_real}) ##
if [ ! -f {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid ]; then
pid=`/bin/pgrep -fn "suricata -i {$if_real} "`
else
pid=`/bin/pgrep -F {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid`
fi
- if [ ! -z \$pid ]; then
- /usr/bin/logger -p daemon.info -i -t SuricataStartup "Suricata SOFT RESTART for {$value['descr']}({$suricata_uuid}_{$if_real})..."
- /bin/pkill -USR2 \$pid
- else
+ if [ -z \$pid ]; then
/usr/bin/logger -p daemon.info -i -t SuricataStartup "Suricata START for {$value['descr']}({$suricata_uuid}_{$if_real})..."
- /usr/local/bin/suricata -i {$if_real} -D -c {$suricatadir}suricata_{$suricata_uuid}_{$if_real}/suricata.yaml --pidfile {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid
+ {$suricatabindir}suricata -i {$if_real} -D -c {$suricatadir}suricata_{$suricata_uuid}_{$if_real}/suricata.yaml --pidfile {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid > /dev/null 2>&1
fi
- sleep 2
+ sleep 1
{$start_barnyard2}
-
EOE;
$start_suricata_iface_stop[] = <<<EOE
@@ -2912,8 +2994,8 @@ EOE;
break
fi
done
- if [ -f /var/run/suricata_{$if_real}{$suricata_uuid}.pid ]; then
- /bin/rm /var/run/suricata_{$if_real}{$suricata_uuid}.pid
+ if [ -f {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid ]; then
+ /bin/rm {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid
fi
else
pid=`/bin/pgrep -fn "suricata -i {$if_real} "`
@@ -2931,9 +3013,8 @@ EOE;
fi
fi
- sleep 2
+ sleep 1
{$stop_barnyard2}
-
EOE;
}
@@ -2948,7 +3029,15 @@ EOE;
######## Start of main suricata.sh
rc_start() {
+
+ ### Lock out other start signals until we are done
+ /usr/bin/touch {$g['varrun_path']}/suricata_pkg_starting.lck
{$rc_start}
+
+ ### Remove the lock since we have started all interfaces
+ if [ -f {$g['varrun_path']}/suricata_pkg_starting.lck ]; then
+ /bin/rm {$g['varrun_path']}/suricata_pkg_starting.lck
+ fi
}
rc_stop() {
@@ -2957,7 +3046,11 @@ rc_stop() {
case $1 in
start)
- rc_start
+ if [ ! -f {$g['varrun_path']}/suricata_pkg_starting.lck ]; then
+ rc_start
+ else
+ /usr/bin/logger -p daemon.info -i -t SuricataStartup "Ignoring additional START command since Suricata is already starting..."
+ fi
;;
stop)
rc_stop
@@ -3108,7 +3201,7 @@ function suricata_generate_yaml($suricatacfg) {
$suricatadir = SURICATADIR;
$suricatalogdir = SURICATALOGDIR;
$flowbit_rules_file = FLOWBITS_FILENAME;
- $suricata_enforcing_rules_file = ENFORCING_RULES_FILENAME;
+ $suricata_enforcing_rules_file = SURICATA_ENFORCING_RULES_FILENAME;
$if_real = get_real_interface($suricatacfg['interface']);
$suricata_uuid = $suricatacfg['uuid'];
$suricatacfgdir = "{$suricatadir}suricata_{$suricata_uuid}_{$if_real}";
@@ -3237,7 +3330,7 @@ function suricata_do_xmlrpc_sync($syncdownloadrules, $sync_to_ip, $port, $userna
/*************************************************/
/* Send over any auto-SID management files */
/*************************************************/
- $sid_files = glob(SID_MODS_PATH . '*');
+ $sid_files = glob(SURICATA_SID_MODS_PATH . '*');
foreach ($sid_files as $file) {
$content = base64_encode(file_get_contents($file));
$payload = "@file_put_contents('{$file}', base64_decode('{$content}'));";
@@ -3332,7 +3425,9 @@ function suricata_do_xmlrpc_sync($syncdownloadrules, $sync_to_ip, $port, $userna
unset(\$g["suricata_postinstall"]);
log_error(gettext("[suricata] XMLRPC pkg CARP sync: Generating suricata.yaml file using Master Host settings..."));
\$rebuild_rules = true;
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
\$rebuild_rules = false;
{$suricatastart}
log_error(gettext("[suricata] XMLRPC pkg CARP sync process on this host is complete..."));
diff --git a/config/suricata/suricata.priv.inc b/config/suricata/suricata.priv.inc
index efa71366..84ede368 100644
--- a/config/suricata/suricata.priv.inc
+++ b/config/suricata/suricata.priv.inc
@@ -36,10 +36,16 @@ $priv_list['page-services-suricata']['match'][] = "suricata/suricata_rules_flowb
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_rulesets.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_os_policy_engine.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_global.php*";
+$priv_list['page-services-suricata']['match'][] = "suricata/suricata_ip_list_mgmt.php*";
+$priv_list['page-services-suricata']['match'][] = "suricata/suricata_ip_reputation.php*";
+$priv_list['page-services-suricata']['match'][] = "suricata/suricata_iprep_list_browser.php*";
$priv_list['page-services-suricata']['match'][] = "pkg_edit.php?xml=suricata/suricata.xml*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_check_cron_misc.inc*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_yaml_template.inc*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata.inc*";
+$priv_list['page-services-suricata']['match'][] = "suricata/suricata_defs.inc*";
+$priv_list['page-services-suricata']['match'][] = "suricata/suricata_geoipupdate.php*";
+$priv_list['page-services-suricata']['match'][] = "suricata/suricata_etiqrisk_update.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_post_install.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_uninstall.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_generate_yaml.php*";
diff --git a/config/suricata/suricata.xml b/config/suricata/suricata.xml
index 995ed900..c510d72b 100644
--- a/config/suricata/suricata.xml
+++ b/config/suricata/suricata.xml
@@ -42,7 +42,7 @@
<description>Suricata IDS/IPS Package</description>
<requirements>None</requirements>
<name>suricata</name>
- <version>2.0.3 pkg v2.0.2</version>
+ <version>2.0.4 pkg v2.1.3</version>
<title>Services: Suricata IDS</title>
<include_file>/usr/local/pkg/suricata/suricata.inc</include_file>
<menu>
@@ -108,6 +108,21 @@
<chmod>0755</chmod>
</additional_files_needed>
<additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_defs.inc</item>
+ <prefix>/usr/local/pkg/suricata/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_geoipupdate.php</item>
+ <prefix>/usr/local/pkg/suricata/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_etiqrisk_update.php</item>
+ <prefix>/usr/local/pkg/suricata/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
<item>https://packages.pfsense.org/packages/config/suricata/suricata_download_updates.php</item>
<prefix>/usr/local/www/suricata/</prefix>
<chmod>0755</chmod>
@@ -223,6 +238,21 @@
<chmod>0755</chmod>
</additional_files_needed>
<additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_ip_list_mgmt.php</item>
+ <prefix>/usr/local/www/suricata/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_ip_reputation.php</item>
+ <prefix>/usr/local/www/suricata/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_iprep_list_browser.php</item>
+ <prefix>/usr/local/www/suricata/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
<prefix>/usr/local/www/widgets/javascript/</prefix>
<chmod>0644</chmod>
<item>https://packages.pfsense.org/packages/config/suricata/suricata_alerts.js</item>
diff --git a/config/suricata/suricata_alerts.js b/config/suricata/suricata_alerts.js
index b6a5d3c3..e56b586d 100644
--- a/config/suricata/suricata_alerts.js
+++ b/config/suricata/suricata_alerts.js
@@ -18,7 +18,7 @@ function suricata_alerts_fetch_new_rules_callback(callback_data) {
line += '<td class="listMRr ellipsis" nowrap><div style="display:inline;" title="';
line += row_split[2] + '">' + row_split[2] + '</div><br/><div style="display:inline;" title="';
line += row_split[3] + '">' + row_split[3] + '</div></td>';
- line += '<td class="listMRr">' + 'Pri: ' + row_split[4] + ' ' + row_split[5] + '</td>';
+ line += '<td class="listMRr"><div style="display: fixed; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.2em; max-height: 2.4em; overflow: hidden; text-overflow: ellipsis;" title="' + row_split[4] + '">' + row_split[4] + '</div></td>';
new_data_to_add[new_data_to_add.length] = line;
}
suricata_alerts_update_div_rows(new_data_to_add);
diff --git a/config/suricata/suricata_alerts.php b/config/suricata/suricata_alerts.php
index 57ccbe27..f151e173 100644
--- a/config/suricata/suricata_alerts.php
+++ b/config/suricata/suricata_alerts.php
@@ -43,6 +43,7 @@
require_once("guiconfig.inc");
require_once("/usr/local/pkg/suricata/suricata.inc");
+global $g, $config;
$supplist = array();
$suri_pf_table = SURICATA_PF_TABLE;
$filterlogentries = FALSE;
@@ -127,7 +128,9 @@ function suricata_add_supplist_entry($suppress) {
/* and return true; otherwise return false. */
if ($found_list) {
write_config();
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
return true;
}
else
@@ -232,6 +235,7 @@ if ($_POST['filterlogentries_submit']) {
if ($_POST['filterlogentries_clear']) {
$filterfieldsarray = array();
+ $filterlogentries = TRUE;
}
if ($_POST['save']) {
@@ -377,11 +381,11 @@ if ($_POST['delete']) {
}
if ($_POST['download']) {
- $save_date = exec('/bin/date "+%Y-%m-%d-%H-%M-%S"');
+ $save_date = date("Y-m-d-H-i-s");
$file_name = "suricata_logs_{$save_date}_{$if_real}.tar.gz";
- exec("cd {$suricatalogdir}suricata_{$if_real}{$suricata_uuid} && /usr/bin/tar -czf /tmp/{$file_name} *");
+ exec("cd {$suricatalogdir}suricata_{$if_real}{$suricata_uuid} && /usr/bin/tar -czf {$g['tmp_path']}/{$file_name} *");
- if (file_exists("/tmp/{$file_name}")) {
+ if (file_exists("{$g['tmp_path']}/{$file_name}")) {
ob_start(); //important or other posts will fail
if (isset($_SERVER['HTTPS'])) {
header('Pragma: ');
@@ -391,13 +395,13 @@ if ($_POST['download']) {
header("Cache-Control: private, must-revalidate");
}
header("Content-Type: application/octet-stream");
- header("Content-length: " . filesize("/tmp/{$file_name}"));
+ header("Content-length: " . filesize("{$g['tmp_path']}/{$file_name}"));
header("Content-disposition: attachment; filename = {$file_name}");
ob_end_clean(); //important or other post will fail
- readfile("/tmp/{$file_name}");
+ readfile("{$g['tmp_path']}/{$file_name}");
// Clean up the temp file
- @unlink("/tmp/{$file_name}");
+ unlink_if_exists("{$g['tmp_path']}/{$file_name}");
}
else
$savemsg = gettext("An error occurred while creating archive");
@@ -451,6 +455,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td></tr>
@@ -578,7 +583,7 @@ if ($savemsg) {
</table>
</td>
</tr>
- <?php if ($filterlogentries) : ?>
+ <?php if ($filterlogentries && count($filterfieldsarray)) : ?>
<tr>
<td colspan="2" class="listtopic"><?php printf(gettext("Last %s Alert Entries"), $anentries); ?>&nbsp;&nbsp;
<?php echo gettext("(Most recent listed first) ** FILTERED VIEW ** clear filter to see all entries"); ?></td>
@@ -622,9 +627,9 @@ if ($savemsg) {
<?php
/* make sure alert file exists */
-if (file_exists("/var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.log")) {
- exec("tail -{$anentries} -r /var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.log > /tmp/alerts_suricata{$suricata_uuid}");
- if (file_exists("/tmp/alerts_suricata{$suricata_uuid}")) {
+if (file_exists("{$g['varlog_path']}/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.log")) {
+ exec("tail -{$anentries} -r {$g['varlog_path']}/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.log > {$g['tmp_path']}/alerts_suricata{$suricata_uuid}");
+ if (file_exists("{$g['tmp_path']}/alerts_suricata{$suricata_uuid}")) {
$tmpblocked = array_flip(suricata_get_blocked_ips());
$counter = 0;
@@ -638,7 +643,7 @@ if (file_exists("/var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.lo
/* 0 1 2 3 4 5 6 7 */
/************** *************************************************************************************************************************/
- $fd = fopen("/tmp/alerts_suricata{$suricata_uuid}", "r");
+ $fd = fopen("{$g['tmp_path']}/alerts_suricata{$suricata_uuid}", "r");
$buf = "";
while (($buf = fgets($fd)) !== FALSE) {
$fields = array();
@@ -834,7 +839,7 @@ if (file_exists("/var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.lo
}
unset($fields, $buf, $tmp);
fclose($fd);
- @unlink("/tmp/alerts_suricata{$suricata_uuid}");
+ unlink_if_exists("{$g['tmp_path']}/alerts_suricata{$suricata_uuid}");
}
}
?>
diff --git a/config/suricata/suricata_alerts.widget.php b/config/suricata/suricata_alerts.widget.php
index bc7a0e2a..81d17c2e 100644
--- a/config/suricata/suricata_alerts.widget.php
+++ b/config/suricata/suricata_alerts.widget.php
@@ -81,7 +81,7 @@ if (isset($_GET['getNewAlerts'])) {
$counter = 0;
foreach ($suri_alerts as $a) {
$response .= $a['instanceid'] . " " . $a['dateonly'] . "||" . $a['timeonly'] . "||" . $a['src'] . "||";
- $response .= $a['dst'] . "||" . $a['priority'] . "||" . $a['category'] . "\n";
+ $response .= $a['dst'] . "||" . $a['msg'] . "\n";
$counter++;
if($counter >= $suri_nentries)
break;
@@ -116,7 +116,7 @@ function suricata_widget_get_alerts() {
/*************** FORMAT without CSV patch -- ALERT -- ***********************************************************************************/
/* Line format: timestamp action[**] [gid:sid:rev] msg [**] [Classification: class] [Priority: pri] {proto} src:srcport -> dst:dstport */
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */
+ /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */
/****************************************************************************************************************************************/
/**************** FORMAT without CSV patch -- DECODER EVENT -- **************************************************************************/
@@ -134,37 +134,41 @@ function suricata_widget_get_alerts() {
$fields[0] = substr($buf, 0, strpos($buf, ' '));
// The regular expression match below returns an array as follows:
- // [1] => CLASSIFICATION, [2] = PRIORITY
- preg_match('/\s\[Classification:\s(.*)\]\s\[Priority:\s(\d+)\]\s/', $buf, $tmp);
- $fields[6] = trim($tmp[1]);
- $fields[7] = trim($tmp[2]);
+ // [2] => GID, [3] => SID, [4] => REV, [5] => MSG, [6] => CLASSIFICATION, [7] = PRIORITY
+ preg_match('/\[\*{2}\]\s\[((\d+):(\d+):(\d+))\]\s(.*)\[\*{2}\]\s\[Classification:\s(.*)\]\s\[Priority:\s(\d+)\]\s/', $buf, $tmp);
+ $fields['gid'] = trim($tmp[2]);
+ $fields['sid'] = trim($tmp[3]);
+ $fields['rev'] = trim($tmp[4]);
+ $fields['msg'] = trim($tmp[5]);
+ $fields['class'] = trim($tmp[6]);
+ $fields['priority'] = trim($tmp[7]);
// The regular expression match below looks for the PROTO, SRC and DST fields
// and returns an array as follows:
// [1] = PROTO, [2] => SRC:SPORT [3] => DST:DPORT
if (preg_match('/\{(.*)\}\s(.*)\s->\s(.*)/', $buf, $tmp)) {
// Get SRC
- $fields[9] = trim(substr($tmp[2], 0, strrpos($tmp[2], ':')));
- if (is_ipaddrv6($fields[9]))
- $fields[9] = inet_ntop(inet_pton($fields[9]));
+ $fields['src'] = trim(substr($tmp[2], 0, strrpos($tmp[2], ':')));
+ if (is_ipaddrv6($fields['src']))
+ $fields['src'] = inet_ntop(inet_pton($fields['src']));
// Get SPORT
- $fields[10] = trim(substr($tmp[2], strrpos($tmp[2], ':') + 1));
+ $fields['sport'] = trim(substr($tmp[2], strrpos($tmp[2], ':') + 1));
// Get DST
- $fields[11] = trim(substr($tmp[3], 0, strrpos($tmp[3], ':')));
- if (is_ipaddrv6($fields[11]))
- $fields[11] = inet_ntop(inet_pton($fields[11]));
+ $fields['dst'] = trim(substr($tmp[3], 0, strrpos($tmp[3], ':')));
+ if (is_ipaddrv6($fields['dst']))
+ $fields['dst'] = inet_ntop(inet_pton($fields['dst']));
// Get DPORT
- $fields[12] = trim(substr($tmp[3], strrpos($tmp[3], ':') + 1));
+ $fields['dport'] = trim(substr($tmp[3], strrpos($tmp[3], ':') + 1));
}
else {
// If no PROTO and IP ADDR, then this is a DECODER EVENT
- $fields[9] = gettext("Decoder Event");
- $fields[10] = "";
- $fields[11] = "";
- $fields[12] = "";
+ $fields['src'] = gettext("Decoder Event");
+ $fields['sport'] = "";
+ $fields['dst'] = "";
+ $fields['dport'] = "";
}
// Create a DateTime object from the event timestamp that
@@ -173,31 +177,30 @@ function suricata_widget_get_alerts() {
// Check the 'CATEGORY' field for the text "(null)" and
// substitute "No classtype defined".
- if ($fields[6] == "(null)")
- $fields[6] = "No classtype assigned";
+ if ($fields['class'] == "(null)")
+ $fields['class'] = "No classtype assigned";
$suricata_alerts[$counter]['instanceid'] = strtoupper(convert_friendly_interface_to_friendly_descr($a_instance[$instanceid]['interface']));
$suricata_alerts[$counter]['timestamp'] = strval(date_timestamp_get($event_tm));
$suricata_alerts[$counter]['timeonly'] = date_format($event_tm, "H:i:s");
$suricata_alerts[$counter]['dateonly'] = date_format($event_tm, "M d");
+ $suricata_alerts[$counter]['msg'] = $fields['msg'];
// Add square brackets around any IPv6 address
- if (is_ipaddrv6($fields[9]))
- $suricata_alerts[$counter]['src'] = "[" . $fields[9] . "]";
+ if (is_ipaddrv6($fields['src']))
+ $suricata_alerts[$counter]['src'] = "[" . $fields['src'] . "]";
else
- $suricata_alerts[$counter]['src'] = $fields[9];
+ $suricata_alerts[$counter]['src'] = $fields['src'];
// Add the SRC PORT if not null
- if (!empty($fields[10]) || $fields[10] == '0')
- $suricata_alerts[$counter]['src'] .= ":" . $fields[10];
+ if (!empty($fields['sport']) || $fields['sport'] == '0')
+ $suricata_alerts[$counter]['src'] .= ":" . $fields['sport'];
// Add square brackets around any IPv6 address
- if (is_ipaddrv6($fields[11]))
- $suricata_alerts[$counter]['dst'] = "[" . $fields[11] . "]";
+ if (is_ipaddrv6($fields['dst']))
+ $suricata_alerts[$counter]['dst'] = "[" . $fields['dst'] . "]";
else
- $suricata_alerts[$counter]['dst'] = $fields[11];
+ $suricata_alerts[$counter]['dst'] = $fields['dst'];
// Add the DST PORT if not null
- if (!empty($fields[12]) || $fields[12] == '0')
- $suricata_alerts[$counter]['dst'] .= ":" . $fields[12];
- $suricata_alerts[$counter]['priority'] = $fields[7];
- $suricata_alerts[$counter]['category'] = $fields[6];
+ if (!empty($fields['dport']) || $fields['dport'] == '0')
+ $suricata_alerts[$counter]['dst'] .= ":" . $fields['dport'];
$counter++;
};
fclose($fd);
@@ -238,7 +241,7 @@ function suricata_widget_get_alerts() {
<tr>
<th class="listhdrr"><?=gettext("IF/Date");?></th>
<th class="listhdrr"><?=gettext("Src/Dst Address");?></th>
- <th class="listhdrr"><?=gettext("Priority/Class");?></th>
+ <th class="listhdrr"><?=gettext("Description");?></th>
</tr>
</thead>
<tbody id="suricata-alert-entries">
@@ -251,7 +254,7 @@ function suricata_widget_get_alerts() {
echo(" <tr class='" . $evenRowClass . "'>
<td class='listMRr'>" . $alert['instanceid'] . " " . $alert['dateonly'] . "<br/>" . $alert['timeonly'] . "</td>
<td class='listMRr ellipsis' nowrap><div style='display:inline;' title='" . $alert['src'] . "'>" . $alert['src'] . "</div><br/><div style='display:inline;' title='" . $alert['dst'] . "'>" . $alert['dst'] . "</div></td>
- <td class='listMRr'>Pri: " . $alert['priority'] . " " . $alert['category'] . "</td></tr>");
+ <td class='listMRr'><div style='display: fixed; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.2em; max-height: 2.4em; overflow: hidden; text-overflow: ellipsis;' title='{$alert['msg']}'>" . $alert['msg'] . "</div></td></tr>");
$counter++;
if($counter >= $suri_nentries)
break;
diff --git a/config/suricata/suricata_app_parsers.php b/config/suricata/suricata_app_parsers.php
index 51514ee5..cfa34a54 100644
--- a/config/suricata/suricata_app_parsers.php
+++ b/config/suricata/suricata_app_parsers.php
@@ -475,6 +475,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
echo '</td></tr>';
echo '<tr><td>';
@@ -487,6 +488,7 @@ if ($savemsg) {
$tab_array[] = array($menu_iface . gettext("App Parsers"), true, "/suricata/suricata_app_parsers.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Variables"), false, "/suricata/suricata_define_vars.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Barnyard2"), false, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), false, "/suricata/suricata_ip_reputation.php?id={$id}");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_barnyard.php b/config/suricata/suricata_barnyard.php
index 987055fd..2938136f 100644
--- a/config/suricata/suricata_barnyard.php
+++ b/config/suricata/suricata_barnyard.php
@@ -89,6 +89,29 @@ if (isset($id) && $a_nat[$id]) {
}
if ($_POST['save']) {
+
+ // If disabling Barnyard2 on the interface, stop any
+ // currently running instance, then save the disabled
+ // state and exit so as to preserve settings.
+ if ($_POST['barnyard_enable'] != 'on') {
+ $a_nat[$id]['barnyard_enable'] = 'off';
+ write_config("Suricata pkg: modified Barnyard2 settings.");
+ suricata_barnyard_stop($a_nat[$id], get_real_interface($a_nat[$id]['interface']));
+
+ // No need to rebuild rules for Barnyard2 changes
+ $rebuild_rules = false;
+ conf_mount_rw();
+ sync_suricata_package_config();
+ conf_mount_ro();
+ header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
+ header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
+ header( 'Cache-Control: no-store, no-cache, must-revalidate' );
+ header( 'Cache-Control: post-check=0, pre-check=0', false );
+ header( 'Pragma: no-cache' );
+ header("Location: /suricata/suricata_barnyard.php");
+ exit;
+ }
+
// Check that at least one output plugin is enabled
if ($_POST['barnyard_mysql_enable'] != 'on' && $_POST['barnyard_syslog_enable'] != 'on' &&
$_POST['barnyard_bro_ids_enable'] != 'on' && $_POST['barnyard_enable'] == "on")
@@ -167,11 +190,13 @@ if ($_POST['save']) {
if ($_POST['barnconfigpassthru']) $natent['barnconfigpassthru'] = base64_encode(str_replace("\r\n", "\n", $_POST['barnconfigpassthru'])); else unset($natent['barnconfigpassthru']);
$a_nat[$id] = $natent;
- write_config();
+ write_config("Suricata pkg: modified Barnyard2 settings.");
// No need to rebuild rules for Barnyard2 changes
$rebuild_rules = false;
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
// If disabling Barnyard2 on the interface, stop any
// currently running instance. If an instance is
@@ -234,6 +259,7 @@ include_once("head.inc");
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
echo '</td></tr>';
echo '<tr><td class="tabnavtbl">';
@@ -246,6 +272,7 @@ include_once("head.inc");
$tab_array[] = array($menu_iface . gettext("App Parsers"), false, "/suricata/suricata_app_parsers.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Variables"), false, "/suricata/suricata_define_vars.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Barnyard2"), true, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), false, "/suricata/suricata_ip_reputation.php?id={$id}");
display_top_tabs($tab_array, true);
?>
</td></tr>
@@ -606,11 +633,11 @@ function enable_change(enable_change) {
document.iform.barnconfigpassthru.disabled = endis;
}
-enable_change(false);
toggle_mySQL();
toggle_syslog();
toggle_local_syslog();
toggle_bro_ids();
+enable_change(false);
</script>
diff --git a/config/suricata/suricata_blocked.php b/config/suricata/suricata_blocked.php
index 842d4073..4f4bf095 100644
--- a/config/suricata/suricata_blocked.php
+++ b/config/suricata/suricata_blocked.php
@@ -42,6 +42,8 @@
require_once("guiconfig.inc");
require_once("/usr/local/pkg/suricata/suricata.inc");
+global $g, $config;
+
$suricatalogdir = SURICATALOGDIR;
$suri_pf_table = SURICATA_PF_TABLE;
@@ -94,22 +96,22 @@ if ($_POST['download'])
exec("/sbin/pfctl -t {$suri_pf_table} -T show", $blocked_ips_array_save);
/* build the list */
if (is_array($blocked_ips_array_save) && count($blocked_ips_array_save) > 0) {
- $save_date = exec('/bin/date "+%Y-%m-%d-%H-%M-%S"');
+ $save_date = date("Y-m-d-H-i-s");
$file_name = "suricata_blocked_{$save_date}.tar.gz";
- exec('/bin/mkdir -p /tmp/suricata_blocked');
- file_put_contents("/tmp/suricata_blocked/suricata_block.pf", "");
+ safe_mkdir("{$g['tmp_path']}/suricata_blocked");
+ file_put_contents("{$g['tmp_path']}/suricata_blocked/suricata_block.pf", "");
foreach($blocked_ips_array_save as $counter => $fileline) {
if (empty($fileline))
continue;
$fileline = trim($fileline, " \n\t");
- file_put_contents("/tmp/suricata_blocked/suricata_block.pf", "{$fileline}\n", FILE_APPEND);
+ file_put_contents("{$g['tmp_path']}/suricata_blocked/suricata_block.pf", "{$fileline}\n", FILE_APPEND);
}
// Create a tar gzip archive of blocked host IP addresses
- exec("/usr/bin/tar -czf /tmp/{$file_name} -C/tmp/suricata_blocked suricata_block.pf");
+ exec("/usr/bin/tar -czf {$g['tmp_path']}/{$file_name} -C{$g['tmp_path']}/suricata_blocked suricata_block.pf");
// If we successfully created the archive, send it to the browser.
- if(file_exists("/tmp/{$file_name}")) {
+ if(file_exists("{$g['tmp_path']}/{$file_name}")) {
ob_start(); //important or other posts will fail
if (isset($_SERVER['HTTPS'])) {
header('Pragma: ');
@@ -119,14 +121,14 @@ if ($_POST['download'])
header("Cache-Control: private, must-revalidate");
}
header("Content-Type: application/octet-stream");
- header("Content-length: " . filesize("/tmp/{$file_name}"));
+ header("Content-length: " . filesize("{$g['tmp_path']}/{$file_name}"));
header("Content-disposition: attachment; filename = {$file_name}");
ob_end_clean(); //important or other post will fail
- readfile("/tmp/{$file_name}");
+ readfile("{$g['tmp_path']}/{$file_name}");
// Clean up the temp files and directory
- @unlink("/tmp/{$file_name}");
- exec("/bin/rm -fr /tmp/suricata_blocked");
+ unlink_if_exists("{$g['tmp_path']}/{$file_name}");
+ rmdir_recursive("{$g['tmp_path']}/suricata_blocked");
} else
$savemsg = gettext("An error occurred while creating archive");
} else
@@ -191,6 +193,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td>
@@ -257,19 +260,67 @@ if ($savemsg) {
foreach (glob("{$suricatalogdir}*/block.log*") as $alertfile) {
$fd = fopen($alertfile, "r");
if ($fd) {
- /* 0 1 2 3 4 5 6 7 8 9 10 */
- /* File format timestamp,action,sig_generator,sig_id,sig_rev,msg,classification,priority,proto,ip,port */
- while (($fields = fgetcsv($fd, 1000, ',', '"')) !== FALSE) {
- if(count($fields) != 11) {
- log_error("[suricata] ERROR: block.log entry failed to parse correctly with too many or not enough CSV entities, skipping this entry...");
- log_error("[suricata] Failed block.log entry fields are: " . print_r($fields, true));
- continue;
+
+ /*************** FORMAT for file -- BLOCK -- **************************************************************************/
+ /* Line format: timestamp action [**] [gid:sid:rev] msg [**] [Classification: class] [Priority: pri] {proto} ip:port */
+ /* 0 1 2 3 4 5 6 7 8 9 10 */
+ /**********************************************************************************************************************/
+
+ $buf = "";
+ while (($buf = fgets($fd)) !== FALSE) {
+ $fields = array();
+ $tmp = array();
+
+ /***************************************************************/
+ /* Parse block log entry to find the parts we want to display. */
+ /* We parse out all the fields even though we currently use */
+ /* just a few of them. */
+ /***************************************************************/
+
+ // Field 0 is the event timestamp
+ $fields['time'] = substr($buf, 0, strpos($buf, ' '));
+
+ // Field 1 is the action
+ if (strpos($buf, '[') !== FALSE && strpos($buf, ']') !== FALSE)
+ $fields['action'] = substr($buf, strpos($buf, '[') + 1, strpos($buf, ']') - strpos($buf, '[') - 1);
+ else
+ $fields['action'] = null;
+
+ // The regular expression match below returns an array as follows:
+ // [2] => GID, [3] => SID, [4] => REV, [5] => MSG, [6] => CLASSIFICATION, [7] = PRIORITY
+ preg_match('/\[\*{2}\]\s\[((\d+):(\d+):(\d+))\]\s(.*)\[\*{2}\]\s\[Classification:\s(.*)\]\s\[Priority:\s(\d+)\]\s/', $buf, $tmp);
+ $fields['gid'] = trim($tmp[2]);
+ $fields['sid'] = trim($tmp[3]);
+ $fields['rev'] = trim($tmp[4]);
+ $fields['msg'] = trim($tmp[5]);
+ $fields['class'] = trim($tmp[6]);
+ $fields['priority'] = trim($tmp[7]);
+
+ // The regular expression match below looks for the PROTO, IP and PORT fields
+ // and returns an array as follows:
+ // [1] = PROTO, [2] => IP:PORT
+ if (preg_match('/\{(.*)\}\s(.*)/', $buf, $tmp)) {
+ // Get PROTO
+ $fields['proto'] = trim($tmp[1]);
+
+ // Get IP
+ $fields['ip'] = trim(substr($tmp[2], 0, strrpos($tmp[2], ':')));
+ if (is_ipaddrv6($fields['ip']))
+ $fields['ip'] = inet_ntop(inet_pton($fields['ip']));
+
+ // Get PORT
+ $fields['port'] = trim(substr($tmp[2], strrpos($tmp[2], ':') + 1));
}
- $fields[9] = inet_pton($fields[9]);
- if (isset($tmpblocked[$fields[9]])) {
- if (!is_array($src_ip_list[$fields[9]]))
- $src_ip_list[$fields[9]] = array();
- $src_ip_list[$fields[9]][$fields[5]] = "{$fields[5]} - " . substr($fields[0], 0, -7);
+
+ // In the unlikely event we read an old log file and fail to parse
+ // out an IP address, just skip the record since we can't use it.
+ if (empty($fields['ip']))
+ continue;
+ $fields['ip'] = inet_pton($fields['ip']);
+ if (isset($tmpblocked[$fields['ip']])) {
+ if (!is_array($src_ip_list[$fields['ip']]))
+ $src_ip_list[$fields['ip']] = array();
+ $src_ip_list[$fields['ip']][$fields['msg']] = "{$fields['msg']} - " . substr($fields['time'], 0, -7);
}
}
fclose($fd);
diff --git a/config/suricata/suricata_check_cron_misc.inc b/config/suricata/suricata_check_cron_misc.inc
index 70394a23..eb1ba2d0 100644
--- a/config/suricata/suricata_check_cron_misc.inc
+++ b/config/suricata/suricata_check_cron_misc.inc
@@ -66,9 +66,9 @@ function suricata_check_dir_size_limit($suricataloglimitsize) {
conf_mount_rw();
// Truncate the Rules Update Log file if it exists
- if (file_exists(RULES_UPD_LOGFILE)) {
+ if (file_exists(SURICATA_RULES_UPD_LOGFILE)) {
log_error(gettext("[Suricata] Truncating the Rules Update Log file..."));
- @file_put_contents(RULES_UPD_LOGFILE, "");
+ @file_put_contents(SURICATA_RULES_UPD_LOGFILE, "");
}
// Initialize an array of the log files we want to prune
@@ -93,6 +93,14 @@ function suricata_check_dir_size_limit($suricataloglimitsize) {
}
}
+ // Cleanup any rotated logs
+ log_error(gettext("[Suricata] Deleting any rotated log files for {$value['descr']} ({$if_real})..."));
+ unlink_if_exists("{$suricata_log_dir}/*.log.*");
+
+ // Cleanup any rotated pcap logs
+ log_error(gettext("[Suricata] Deleting any rotated pcap log files for {$value['descr']} ({$if_real})..."));
+ unlink_if_exists("{$suricata_log_dir}/log.pcap.*");
+
// Check for any captured stored files and clean them up
unlink_if_exists("{$suricata_log_dir}/files/*");
@@ -217,6 +225,7 @@ if ($config['installedpackages']['suricata']['config'][0]['enable_log_mgmt'] ==
$config['installedpackages']['suricata']['config'][0]['file_store_retention'] > 0) {
$now = time();
$files = glob("{$suricata_log_dir}/files/file.*");
+ $prune_count = 0;
foreach ($files as $f) {
if (($now - filemtime($f)) > ($config['installedpackages']['suricata']['config'][0]['file_store_retention'] * 3600)) {
$prune_count++;
@@ -227,6 +236,25 @@ if ($config['installedpackages']['suricata']['config'][0]['enable_log_mgmt'] ==
log_error(gettext("[Suricata] File Store cleanup job removed {$prune_count} file(s) from {$suricata_log_dir}/files/..."));
unset($files);
}
+
+ // Prune any pcap log files over configured limit
+ $files = glob("{$suricata_log_dir}/log.pcap.*");
+ if (count($files) > $value['max_pcap_log_files']) {
+ $over = count($files) - $value['max_pcap_log_files'];
+ $remove_files = array();
+ while ($over > 0) {
+ $remove_files[] = array_shift($files);
+ $over--;
+ }
+ $prune_count = 0;
+ foreach ($remove_files as $f) {
+ $prune_count++;
+ unlink_if_exists($f);
+ }
+ if ($prune_count > 0)
+ log_error(gettext("[Suricata] Packet Capture log cleanup job removed {$prune_count} file(s) from {$suricata_log_dir}/..."));
+ unset($files, $remove_files);
+ }
}
}
diff --git a/config/suricata/suricata_check_for_rule_updates.php b/config/suricata/suricata_check_for_rule_updates.php
index eeb7be6c..0fa4fb2d 100644
--- a/config/suricata/suricata_check_for_rule_updates.php
+++ b/config/suricata/suricata_check_for_rule_updates.php
@@ -41,39 +41,13 @@
require_once("functions.inc");
require_once("service-utils.inc");
require_once("/usr/local/pkg/suricata/suricata.inc");
+require_once("/usr/local/pkg/suricata/suricata_defs.inc");
global $g, $pkg_interface, $suricata_gui_include, $rebuild_rules;
-if (!defined("VRT_DNLD_URL"))
- define("VRT_DNLD_URL", "https://www.snort.org/rules/");
-if (!defined("ET_VERSION"))
- define("ET_VERSION", "2.9.0");
-if (!defined("ET_BASE_DNLD_URL"))
- define("ET_BASE_DNLD_URL", "http://rules.emergingthreats.net/");
-if (!defined("ETPRO_BASE_DNLD_URL"))
- define("ETPRO_BASE_DNLD_URL", "https://rules.emergingthreatspro.com/");
-if (!defined("ET_DNLD_FILENAME"))
- define("ET_DNLD_FILENAME", "emerging.rules.tar.gz");
-if (!defined("ETPRO_DNLD_FILENAME"))
- define("ETPRO_DNLD_FILENAME", "etpro.rules.tar.gz");
-if (!defined("GPLV2_DNLD_FILENAME"))
- define("GPLV2_DNLD_FILENAME", "community-rules.tar.gz");
-if (!defined("GPLV2_DNLD_URL"))
- define("GPLV2_DNLD_URL", "https://s3.amazonaws.com/snort-org/www/rules/community/");
-if (!defined("RULES_UPD_LOGFILE"))
- define("RULES_UPD_LOGFILE", SURICATALOGDIR . "/suricata_rules_update.log");
-if (!defined("VRT_FILE_PREFIX"))
- define("VRT_FILE_PREFIX", "snort_");
-if (!defined("GPL_FILE_PREFIX"))
- define("GPL_FILE_PREFIX", "GPLv2_");
-if (!defined("ET_OPEN_FILE_PREFIX"))
- define("ET_OPEN_FILE_PREFIX", "emerging-");
-if (!defined("ET_PRO_FILE_PREFIX"))
- define("ET_PRO_FILE_PREFIX", "etpro-");
-
$suricatadir = SURICATADIR;
$suricatalogdir = SURICATALOGDIR;
-$suricata_rules_upd_log = RULES_UPD_LOGFILE;
+$mounted_rw = FALSE;
/* Save the state of $pkg_interface so we can restore it */
$pkg_interface_orig = $pkg_interface;
@@ -93,7 +67,7 @@ $vrt_enabled = $config['installedpackages']['suricata']['config'][0]['enable_vrt
$snortcommunityrules = $config['installedpackages']['suricata']['config'][0]['snortcommunityrules'] == 'on' ? 'on' : 'off';
/* Working directory for downloaded rules tarballs */
-$tmpfname = "/tmp/suricata_rules_up";
+$tmpfname = "{$g['tmp_path']}/suricata_rules_up";
/* Snort VRT Rules filenames and URL */
$snort_filename_md5 = "{$snort_filename}.md5";
@@ -105,7 +79,10 @@ $snort_community_rules_filename_md5 = GPLV2_DNLD_FILENAME . ".md5";
$snort_community_rules_url = GPLV2_DNLD_URL;
/* Mount the Suricata conf directories R/W so we can modify files there */
-conf_mount_rw();
+if (!is_subsystem_dirty('mount')) {
+ conf_mount_rw();
+ $mounted_rw = TRUE;
+}
/* Set up Emerging Threats rules filenames and URL */
if ($etpro == "on") {
@@ -115,7 +92,7 @@ if ($etpro == "on") {
$emergingthreats_url .= "{$etproid}/suricata/";
$et_name = "Emerging Threats Pro";
$et_md5_remove = ET_DNLD_FILENAME . ".md5";
- @unlink("{$suricatadir}{$et_md5_remove}");
+ unlink_if_exists("{$suricatadir}{$et_md5_remove}");
}
else {
$emergingthreats_filename = ET_DNLD_FILENAME;
@@ -126,7 +103,7 @@ else {
$emergingthreats_url .= "suricata/";
$et_name = "Emerging Threats Open";
$et_md5_remove = ETPRO_DNLD_FILENAME . ".md5";
- @unlink("{$suricatadir}{$et_md5_remove}");
+ unlink_if_exists("{$suricatadir}{$et_md5_remove}");
}
// Set a common flag for all Emerging Threats rules (open and pro).
@@ -209,7 +186,9 @@ function suricata_download_file_url($url, $file_out) {
curl_setopt($ch, CURLOPT_FILE, $fout);
// NOTE: required to suppress errors from XMLRPC due to progress bar output
- if ($g['suricata_sync_in_progress'])
+ // and to prevent useless spam from rules update cron job execution. This
+ // prevents progress bar output during package sync and rules update cron task.
+ if ($g['suricata_sync_in_progress'] || $pkg_interface == "console")
curl_setopt($ch, CURLOPT_HEADER, false);
else {
curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
@@ -283,21 +262,21 @@ function suricata_check_rule_md5($file_url, $file_dst, $desc = "") {
/* error occurred. */
/**********************************************************/
- global $pkg_interface, $suricata_rules_upd_log, $last_curl_error, $update_errors;
+ global $pkg_interface, $last_curl_error, $update_errors;
$suricatadir = SURICATADIR;
$filename_md5 = basename($file_dst);
if ($pkg_interface <> "console")
update_status(gettext("Downloading {$desc} md5 file..."));
- error_log(gettext("\tDownloading {$desc} md5 file {$filename_md5}...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tDownloading {$desc} md5 file {$filename_md5}...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$rc = suricata_download_file_url($file_url, $file_dst);
// See if download from URL was successful
if ($rc === true) {
if ($pkg_interface <> "console")
update_status(gettext("Done downloading {$filename_md5}."));
- error_log("\tChecking {$desc} md5 file...\n", 3, $suricata_rules_upd_log);
+ error_log("\tChecking {$desc} md5 file...\n", 3, SURICATA_RULES_UPD_LOGFILE);
// check md5 hash in new file against current file to see if new download is posted
if (file_exists("{$suricatadir}{$filename_md5}")) {
@@ -307,7 +286,7 @@ function suricata_check_rule_md5($file_url, $file_dst, $desc = "") {
if ($pkg_interface <> "console")
update_status(gettext("{$desc} are up to date..."));
log_error(gettext("[Suricata] {$desc} are up to date..."));
- error_log(gettext("\t{$desc} are up to date.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\t{$desc} are up to date.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
return false;
}
else
@@ -316,7 +295,7 @@ function suricata_check_rule_md5($file_url, $file_dst, $desc = "") {
return true;
}
else {
- error_log(gettext("\t{$desc} md5 download failed.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\t{$desc} md5 download failed.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$suricata_err_msg = gettext("Server returned error code {$rc}.");
if ($pkg_interface <> "console") {
update_status(gettext("{$desc} md5 error ... Server returned error code {$rc} ..."));
@@ -324,10 +303,10 @@ function suricata_check_rule_md5($file_url, $file_dst, $desc = "") {
}
log_error(gettext("[Suricata] {$desc} md5 download failed..."));
log_error(gettext("[Suricata] Server returned error code {$rc}..."));
- error_log(gettext("\t{$suricata_err_msg}\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\t{$suricata_err_msg}\n"), 3, SURICATA_RULES_UPD_LOGFILE);
if ($pkg_interface == "console")
- error_log(gettext("\tServer error message was: {$last_curl_error}\n"), 3, $suricata_rules_upd_log);
- error_log(gettext("\t{$desc} will not be updated.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tServer error message was: {$last_curl_error}\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ error_log(gettext("\t{$desc} will not be updated.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$update_errors = true;
return false;
}
@@ -352,7 +331,7 @@ function suricata_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
/* FALSE if download was not successful. */
/**********************************************************/
- global $pkg_interface, $suricata_rules_upd_log, $last_curl_error, $update_errors;
+ global $pkg_interface, $last_curl_error, $update_errors;
$suricatadir = SURICATADIR;
$filename = basename($file_dst);
@@ -360,8 +339,8 @@ function suricata_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
if ($pkg_interface <> "console")
update_status(gettext("There is a new set of {$desc} posted. Downloading..."));
log_error(gettext("[Suricata] There is a new set of {$desc} posted. Downloading {$filename}..."));
- error_log(gettext("\tThere is a new set of {$desc} posted.\n"), 3, $suricata_rules_upd_log);
- error_log(gettext("\tDownloading file '{$filename}'...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tThere is a new set of {$desc} posted.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ error_log(gettext("\tDownloading file '{$filename}'...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$rc = suricata_download_file_url($file_url, $file_dst);
// See if the download from the URL was successful
@@ -369,7 +348,7 @@ function suricata_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
if ($pkg_interface <> "console")
update_status(gettext("Done downloading {$desc} file."));
log_error("[Suricata] {$desc} file update downloaded successfully");
- error_log(gettext("\tDone downloading rules file.\n"),3, $suricata_rules_upd_log);
+ error_log(gettext("\tDone downloading rules file.\n"),3, SURICATA_RULES_UPD_LOGFILE);
// Test integrity of the rules file. Turn off update if file has wrong md5 hash
if ($file_md5 != trim(md5_file($file_dst))){
@@ -378,10 +357,10 @@ function suricata_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
log_error(gettext("[Suricata] {$desc} file download failed. Bad MD5 checksum..."));
log_error(gettext("[Suricata] Downloaded File MD5: " . md5_file($file_dst)));
log_error(gettext("[Suricata] Expected File MD5: {$file_md5}"));
- error_log(gettext("\t{$desc} file download failed. Bad MD5 checksum.\n"), 3, $suricata_rules_upd_log);
- error_log(gettext("\tDownloaded {$desc} file MD5: " . md5_file($file_dst) . "\n"), 3, $suricata_rules_upd_log);
- error_log(gettext("\tExpected {$desc} file MD5: {$file_md5}\n"), 3, $suricata_rules_upd_log);
- error_log(gettext("\t{$desc} file download failed. {$desc} will not be updated.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\t{$desc} file download failed. Bad MD5 checksum.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ error_log(gettext("\tDownloaded {$desc} file MD5: " . md5_file($file_dst) . "\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ error_log(gettext("\tExpected {$desc} file MD5: {$file_md5}\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ error_log(gettext("\t{$desc} file download failed. {$desc} will not be updated.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$update_errors = true;
return false;
}
@@ -391,10 +370,10 @@ function suricata_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
if ($pkg_interface <> "console")
update_output_window(gettext("{$desc} file download failed..."));
log_error(gettext("[Suricata] {$desc} file download failed... server returned error '{$rc}'..."));
- error_log(gettext("\t{$desc} file download failed. Server returned error {$rc}.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\t{$desc} file download failed. Server returned error {$rc}.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
if ($pkg_interface == "console")
- error_log(gettext("\tThe error text was: {$last_curl_error}\n"), 3, $suricata_rules_upd_log);
- error_log(gettext("\t{$desc} will not be updated.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tThe error text was: {$last_curl_error}\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ error_log(gettext("\t{$desc} will not be updated.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$update_errors = true;
return false;
}
@@ -405,21 +384,21 @@ function suricata_fetch_new_rules($file_url, $file_dst, $file_md5, $desc = "") {
/* remove old $tmpfname files if present */
if (is_dir("{$tmpfname}"))
- exec("/bin/rm -r {$tmpfname}");
+ rmdir_recursive("{$tmpfname}");
/* Make sure required suricatadirs exsist */
-exec("/bin/mkdir -p {$suricatadir}rules");
-exec("/bin/mkdir -p {$tmpfname}");
-exec("/bin/mkdir -p {$suricatalogdir}");
+safe_mkdir("{$suricatadir}rules");
+safe_mkdir("{$tmpfname}");
+safe_mkdir("{$suricatalogdir}");
/* See if we need to automatically clear the Update Log based on 1024K size limit */
-if (file_exists($suricata_rules_upd_log)) {
- if (1048576 < filesize($suricata_rules_upd_log))
- exec("/bin/rm -r {$suricata_rules_upd_log}");
+if (file_exists(SURICATA_RULES_UPD_LOGFILE)) {
+ if (1048576 < filesize(SURICATA_RULES_UPD_LOGFILE))
+ unlink_if_exists("{SURICATA_RULES_UPD_LOGFILE}");
}
/* Log start time for this rules update */
-error_log(gettext("Starting rules update... Time: " . date("Y-m-d H:i:s") . "\n"), 3, $suricata_rules_upd_log);
+error_log(gettext("Starting rules update... Time: " . date("Y-m-d H:i:s") . "\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$last_curl_error = "";
$update_errors = false;
@@ -439,7 +418,7 @@ if ($emergingthreats == 'on') {
if ($snortdownload == 'on') {
if (empty($snort_filename)) {
log_error(gettext("No snortrules-snapshot filename has been set on Snort pkg GLOBAL SETTINGS tab. Snort VRT rules cannot be updated."));
- error_log(gettext("\tWARNING-- No snortrules-snapshot filename set on GLOBAL SETTINGS tab. Snort VRT rules cannot be updated!\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tWARNING-- No snortrules-snapshot filename set on GLOBAL SETTINGS tab. Snort VRT rules cannot be updated!\n"), 3, SURICATA_RULES_UPD_LOGFILE);
$snortdownload = 'off';
}
elseif (suricata_check_rule_md5("{$snort_rule_url}{$snort_filename_md5}?oinkcode={$oinkid}", "{$tmpfname}/{$snort_filename_md5}", "Snort VRT rules")) {
@@ -454,7 +433,7 @@ if ($snortdownload == 'on') {
/* Check for and download any new Snort GPLv2 Community Rules sigs */
if ($snortcommunityrules == 'on') {
- if (suricata_check_rule_md5("{$snort_community_rules_url}{$snort_community_rules_filename_md5}", "{$tmpfname}/{$snort_community_rules_filename_md5}", "Snort GPLv2 Community Rules")) {
+ if (suricata_check_rule_md5("{$snort_community_rules_url}{$snort_community_rules_filename}/md5", "{$tmpfname}/{$snort_community_rules_filename_md5}", "Snort GPLv2 Community Rules")) {
/* download Snort GPLv2 Community Rules file */
$file_md5 = trim(file_get_contents("{$tmpfname}/{$snort_community_rules_filename_md5}"));
if (!suricata_fetch_new_rules("{$snort_community_rules_url}{$snort_community_rules_filename}", "{$tmpfname}/{$snort_community_rules_filename}", $file_md5, "Snort GPLv2 Community Rules"))
@@ -472,7 +451,7 @@ if ($emergingthreats == 'on') {
update_status(gettext("Extracting {$et_name} rules..."));
update_output_window(gettext("Installing {$et_name} rules..."));
}
- error_log(gettext("\tExtracting and installing {$et_name} rules...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tExtracting and installing {$et_name} rules...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
exec("/usr/bin/tar xzf {$tmpfname}/{$emergingthreats_filename} -C {$tmpfname}/emerging rules/");
/* Remove the old Emerging Threats rules files */
@@ -530,8 +509,8 @@ if ($emergingthreats == 'on') {
update_status(gettext("Extraction of {$et_name} rules completed..."));
update_output_window(gettext("Installation of {$et_name} rules completed..."));
}
- error_log(gettext("\tInstallation of {$et_name} rules completed.\n"), 3, $suricata_rules_upd_log);
- exec("rm -r {$tmpfname}/emerging");
+ error_log(gettext("\tInstallation of {$et_name} rules completed.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ rmdir_recursive("{$tmpfname}/emerging");
}
}
@@ -546,7 +525,7 @@ if ($snortdownload == 'on') {
update_status(gettext("Extracting Snort VRT rules..."));
update_output_window(gettext("Installing Sourcefire VRT rules..."));
}
- error_log(gettext("\tExtracting and installing Snort VRT rules...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tExtracting and installing Snort VRT rules...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
/* extract snort.org rules and add prefix to all snort.org files */
safe_mkdir("{$tmpfname}/snortrules");
@@ -563,7 +542,7 @@ if ($snortdownload == 'on') {
$newfile = basename($file);
@copy($file, "{$suricatadir}rules/{$newfile}");
}
- exec("rm -r {$tmpfname}/snortrules");
+ rmdir_recursive("{$tmpfname}/snortrules");
/* extract base etc files */
if ($pkg_interface <> "console") {
@@ -575,7 +554,7 @@ if ($snortdownload == 'on') {
if (file_exists("{$tmpfname}/etc/{$file}"))
@copy("{$tmpfname}/etc/{$file}", "{$tmpfname}/VRT_{$file}");
}
- exec("rm -r {$tmpfname}/etc");
+ rmdir_recursive("{$tmpfname}/etc");
if (file_exists("{$tmpfname}/{$snort_filename_md5}")) {
if ($pkg_interface <> "console")
update_status(gettext("Copying md5 signature to Suricata directory..."));
@@ -585,7 +564,7 @@ if ($snortdownload == 'on') {
update_status(gettext("Extraction of Snort VRT rules completed..."));
update_output_window(gettext("Installation of Sourcefire VRT rules completed..."));
}
- error_log(gettext("\tInstallation of Snort VRT rules completed.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tInstallation of Snort VRT rules completed.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
}
}
@@ -597,7 +576,7 @@ if ($snortcommunityrules == 'on') {
update_status(gettext("Extracting Snort GPLv2 Community Rules..."));
update_output_window(gettext("Installing Snort GPLv2 Community Rules..."));
}
- error_log(gettext("\tExtracting and installing Snort GPLv2 Community Rules...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tExtracting and installing Snort GPLv2 Community Rules...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
exec("/usr/bin/tar xzf {$tmpfname}/{$snort_community_rules_filename} -C {$tmpfname}/community/");
$files = glob("{$tmpfname}/community/community-rules/*.rules");
@@ -620,8 +599,8 @@ if ($snortcommunityrules == 'on') {
update_status(gettext("Extraction of Snort GPLv2 Community Rules completed..."));
update_output_window(gettext("Installation of Snort GPLv2 Community Rules file completed..."));
}
- error_log(gettext("\tInstallation of Snort GPLv2 Community Rules completed.\n"), 3, $suricata_rules_upd_log);
- exec("rm -r {$tmpfname}/community");
+ error_log(gettext("\tInstallation of Snort GPLv2 Community Rules completed.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
+ rmdir_recursive("{$tmpfname}/community");
}
}
@@ -643,7 +622,7 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
if ($pkg_interface <> "console")
update_status(gettext('Copying new config and map files...'));
- error_log(gettext("\tCopying new config and map files...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tCopying new config and map files...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
/******************************************************************/
/* Build the classification.config and reference.config files */
@@ -672,10 +651,14 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
/* Start the rules rebuild proccess for each configured interface */
if (is_array($config['installedpackages']['suricata']['rule']) &&
- !empty($config['installedpackages']['suricata']['rule'])) {
+ count($config['installedpackages']['suricata']['rule']) > 0) {
- /* Set the flag to force rule rebuilds since we downloaded new rules */
- $rebuild_rules = true;
+ /* Set the flag to force rule rebuilds since we downloaded new rules, */
+ /* except when in post-install mode. Post-install does its own rebuild. */
+ if ($g['suricata_postinstall'])
+ $rebuild_rules = false;
+ else
+ $rebuild_rules = true;
/* Create configuration for each active Suricata interface */
foreach ($config['installedpackages']['suricata']['rule'] as $value) {
@@ -693,7 +676,7 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
}
suricata_apply_customizations($value, $if_real);
$tmp = "\t" . $tmp . "\n";
- error_log($tmp, 3, $suricata_rules_upd_log);
+ error_log($tmp, 3, SURICATA_RULES_UPD_LOGFILE);
}
}
else {
@@ -701,44 +684,43 @@ if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules =
update_output_window(gettext("Warning: No interfaces configured for Suricata were found..."));
update_output_window(gettext("No interfaces currently have Suricata configured and enabled on them..."));
}
- error_log(gettext("\tWarning: No interfaces configured for Suricata were found...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tWarning: No interfaces configured for Suricata were found...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
}
/* Clear the rebuild rules flag. */
$rebuild_rules = false;
- /* Restart Suricata if already running and we are not rebooting to pick up the new rules. */
- if (is_process_running("suricata") && !$g['booting'] &&
- !empty($config['installedpackages']['suricata']['rule'])) {
+ /* Restart Suricata if already running and we are not in post-install, so as to pick up the new rules. */
+ if (is_process_running("suricata") && !$g['suricata_postinstall'] &&
+ count($config['installedpackages']['suricata']['rule']) > 0) {
// See if "Live Reload" is configured and signal each Suricata instance
// if enabled, else just do a hard restart of all the instances.
if ($config['installedpackages']['suricata']['config'][0]['live_swap_updates'] == 'on') {
if ($pkg_interface <> "console") {
- update_status(gettext('Signalling Suricata to live-load the new set of rules...'));
+ update_status(gettext('Signaling Suricata to live-load the new set of rules...'));
update_output_window(gettext("Please wait ... the process should complete in a few seconds..."));
}
log_error(gettext("[Suricata] Live-Reload of rules from auto-update is enabled..."));
- error_log(gettext("\tLive-Reload of updated rules is enabled...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tLive-Reload of updated rules is enabled...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
foreach ($config['installedpackages']['suricata']['rule'] as $value) {
- $if_real = get_real_interface($value['interface']);
suricata_reload_config($value);
- error_log(gettext("\tLive swap of updated rules requested for " . convert_friendly_interface_to_friendly_descr($value['interface']) . ".\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tLive swap of updated rules requested for " . convert_friendly_interface_to_friendly_descr($value['interface']) . ".\n"), 3, SURICATA_RULES_UPD_LOGFILE);
}
log_error(gettext("[Suricata] Live-Reload of updated rules completed..."));
- error_log(gettext("\tLive-Reload of the updated rules is complete.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tLive-Reload of the updated rules is complete.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
}
else {
if ($pkg_interface <> "console") {
update_status(gettext('Restarting Suricata to activate the new set of rules...'));
update_output_window(gettext("Please wait ... restarting Suricata will take some time..."));
}
- error_log(gettext("\tRestarting Suricata to activate the new set of rules...\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tRestarting Suricata to activate the new set of rules...\n"), 3, SURICATA_RULES_UPD_LOGFILE);
restart_service("suricata");
if ($pkg_interface <> "console")
update_output_window(gettext("Suricata has restarted with your new set of rules..."));
log_error(gettext("[Suricata] Suricata has restarted with your new set of rules..."));
- error_log(gettext("\tSuricata has restarted with your new set of rules.\n"), 3, $suricata_rules_upd_log);
+ error_log(gettext("\tSuricata has restarted with your new set of rules.\n"), 3, SURICATA_RULES_UPD_LOGFILE);
}
}
else {
@@ -753,7 +735,7 @@ if (is_dir("{$tmpfname}")) {
update_status(gettext("Cleaning up after rules extraction..."));
update_output_window(gettext("Removing {$tmpfname} directory..."));
}
- exec("/bin/rm -r {$tmpfname}");
+ rmdir_recursive("{$tmpfname}");
}
if ($pkg_interface <> "console") {
@@ -761,11 +743,10 @@ if ($pkg_interface <> "console") {
update_output_window("");
}
log_error(gettext("[Suricata] The Rules update has finished."));
-error_log(gettext("The Rules update has finished. Time: " . date("Y-m-d H:i:s"). "\n\n"), 3, $suricata_rules_upd_log);
+error_log(gettext("The Rules update has finished. Time: " . date("Y-m-d H:i:s"). "\n\n"), 3, SURICATA_RULES_UPD_LOGFILE);
-// Remount filesystem read-only unless we are in package post-install.
-// The post-install code will remount read-only when it completes.
-if (!$g['suricata_postinstall'])
+/* Remount filesystem read-only if we changed it in this module */
+if ($mounted_rw == TRUE)
conf_mount_ro();
// Restore the state of $pkg_interface
@@ -777,6 +758,6 @@ if ($update_errors)
else
$config['installedpackages']['suricata']['config'][0]['last_rule_upd_status'] = gettext("success");
$config['installedpackages']['suricata']['config'][0]['last_rule_upd_time'] = time();
-write_config("Suricata pkg: updated status for updated rules package(s) check.");
+write_config("Suricata pkg: updated status for updated rules package(s) check.", FALSE);
?>
diff --git a/config/suricata/suricata_define_vars.php b/config/suricata/suricata_define_vars.php
index 040244b0..b94292c3 100644
--- a/config/suricata/suricata_define_vars.php
+++ b/config/suricata/suricata_define_vars.php
@@ -187,6 +187,7 @@ if ($savemsg)
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
echo '</td></tr>';
echo '<tr><td class="tabnavtbl">';
@@ -199,6 +200,7 @@ if ($savemsg)
$tab_array[] = array($menu_iface . gettext("App Parsers"), false, "/suricata/suricata_app_parsers.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Variables"), true, "/suricata/suricata_define_vars.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Barnyard2"), false, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), false, "/suricata/suricata_ip_reputation.php?id={$id}");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_defs.inc b/config/suricata/suricata_defs.inc
new file mode 100644
index 00000000..7758a9f0
--- /dev/null
+++ b/config/suricata/suricata_defs.inc
@@ -0,0 +1,117 @@
+<?php
+/*
+ * suricata_defs.inc
+ *
+ * Significant portions of this code are based on original work done
+ * for the Snort package for pfSense from the following contributors:
+ *
+ * Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>.
+ * Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ * Copyright (C) 2006 Scott Ullrich
+ * Copyright (C) 2009 Robert Zelaya Sr. Developer
+ * Copyright (C) 2012 Ermal Luci
+ * All rights reserved.
+ *
+ * Adapted for Suricata by:
+ * Copyright (C) 2014 Bill Meeks
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("pkg-utils.inc");
+
+/*************************************************************************/
+/* This file contains definitions for various CONSTANTS used throughout */
+/* the Suricata package. It is included via a "require_once()" call in */
+/* the "suricata.inc" and "suricata_post_install.php" files. */
+/*************************************************************************/
+
+global $g, $config;
+
+if (!is_array($config['installedpackages']['suricata']))
+ $config['installedpackages']['suricata'] = array();
+
+/* Get installed package version for display */
+$suricata_package_version = "Suricata {$config['installedpackages']['package'][get_pkg_id("suricata")]['version']}";
+
+// Define the installed package version
+if (!defined('SURICATA_PKG_VER'))
+ define('SURICATA_PKG_VER', $suricata_package_version);
+
+// Define the PBI base directory
+if (!defined('SURICATA_PBI_BASEDIR'))
+ define('SURICATA_PBI_BASEDIR', '/usr/pbi/suricata-' . php_uname("m") . '/');
+
+// Define the PBI binary wrapper directory
+if (!defined('SURICATA_PBI_BINDIR'))
+ define('SURICATA_PBI_BINDIR', SURICATA_PBI_BASEDIR . 'bin/');
+
+// Define the name of the pf table used for IP blocks
+if (!defined('SURICATA_PF_TABLE'))
+ define('SURICATA_PF_TABLE', 'snort2c');
+
+// Create some other useful defines
+if (!defined('SURICATADIR'))
+ define('SURICATADIR', SURICATA_PBI_BASEDIR . 'etc/suricata/');
+if (!defined('SURICATALOGDIR'))
+ define('SURICATALOGDIR', "{$g['varlog_path']}/suricata/");
+if (!defined('SURICATA_RULES_UPD_LOGFILE'))
+ define('SURICATA_RULES_UPD_LOGFILE', SURICATALOGDIR . 'suricata_rules_update.log');
+if (!defined('SURICATA_SID_MODS_PATH'))
+ define('SURICATA_SID_MODS_PATH', "{$g['vardb_path']}/suricata/sidmods/");
+if (!defined('SURICATA_IPREP_PATH'))
+ define('SURICATA_IPREP_PATH', "{$g['vardb_path']}/suricata/iprep/");
+
+// Rule set download URLs, filenames and prefixes
+if (!defined("VRT_DNLD_URL"))
+ define("VRT_DNLD_URL", "https://www.snort.org/rules/");
+if (!defined("ET_VERSION"))
+ define("ET_VERSION", "2.9.0");
+if (!defined("ET_BASE_DNLD_URL"))
+ define("ET_BASE_DNLD_URL", "http://rules.emergingthreats.net/");
+if (!defined("ETPRO_BASE_DNLD_URL"))
+ define("ETPRO_BASE_DNLD_URL", "https://rules.emergingthreatspro.com/");
+if (!defined("ET_DNLD_FILENAME"))
+ define("ET_DNLD_FILENAME", "emerging.rules.tar.gz");
+if (!defined("ETPRO_DNLD_FILENAME"))
+ define("ETPRO_DNLD_FILENAME", "etpro.rules.tar.gz");
+if (!defined("ET_IQRISK_DNLD_URL"))
+ define("ET_IQRISK_DNLD_URL", "https://rules.emergingthreatspro.com/_xxx_/reputation/");
+if (!defined("GPLV2_DNLD_FILENAME"))
+ define("GPLV2_DNLD_FILENAME", "community-rules.tar.gz");
+if (!defined("GPLV2_DNLD_URL"))
+ define("GPLV2_DNLD_URL", "https://www.snort.org/downloads/community/");
+if (!defined("VRT_FILE_PREFIX"))
+ define("VRT_FILE_PREFIX", "snort_");
+if (!defined("GPL_FILE_PREFIX"))
+ define("GPL_FILE_PREFIX", "GPLv2_");
+if (!defined("ET_OPEN_FILE_PREFIX"))
+ define("ET_OPEN_FILE_PREFIX", "emerging-");
+if (!defined("ET_PRO_FILE_PREFIX"))
+ define("ET_PRO_FILE_PREFIX", "etpro-");
+if (!defined('SURICATA_ENFORCING_RULES_FILENAME'))
+ define('SURICATA_ENFORCING_RULES_FILENAME', 'suricata.rules');
+if (!defined('FLOWBITS_FILENAME'))
+ define('FLOWBITS_FILENAME', 'flowbit-required.rules');
+
+?>
diff --git a/config/suricata/suricata_download_updates.php b/config/suricata/suricata_download_updates.php
index 89e959c9..1abb32d6 100644
--- a/config/suricata/suricata_download_updates.php
+++ b/config/suricata/suricata_download_updates.php
@@ -44,7 +44,7 @@ require_once("/usr/local/pkg/suricata/suricata.inc");
/* Define some locally required variables from Suricata constants */
$suricatadir = SURICATADIR;
-$suricata_rules_upd_log = RULES_UPD_LOGFILE;
+$suricata_rules_upd_log = SURICATA_RULES_UPD_LOGFILE;
$snortdownload = $config['installedpackages']['suricata']['config'][0]['enable_vrt_rules'];
$emergingthreats = $config['installedpackages']['suricata']['config'][0]['enable_etopen_rules'];
@@ -116,7 +116,7 @@ if ($snortcommunityrules == 'on' && file_exists("{$suricatadir}{$snort_community
/* Check for postback to see if we should clear the update log file. */
if ($_POST['clear']) {
if (file_exists("{$suricata_rules_upd_log}"))
- mwexec("/bin/rm -f {$suricata_rules_upd_log}");
+ unlink_if_exists("{$suricata_rules_upd_log}");
}
if ($_POST['update']) {
@@ -130,12 +130,9 @@ if ($_POST['force']) {
conf_mount_rw();
// Remove the existing MD5 signature files to force a download
- if (file_exists("{$suricatadir}{$emergingthreats_filename}.md5"))
- @unlink("{$suricatadir}{$emergingthreats_filename}.md5");
- if (file_exists("{$suricatadir}{$snort_community_rules_filename}.md5"))
- @unlink("{$suricatadir}{$snort_community_rules_filename}.md5");
- if (file_exists("{$suricatadir}{$snort_rules_file}.md5"))
- @unlink("{$suricatadir}{$snort_rules_file}.md5");
+ unlink_if_exists("{$suricatadir}{$emergingthreats_filename}.md5");
+ unlink_if_exists("{$suricatadir}{$snort_community_rules_filename}.md5");
+ unlink_if_exists("{$suricatadir}{$snort_rules_file}.md5");
// Revert file system to R/O.
conf_mount_ro();
@@ -195,6 +192,7 @@ include_once("head.inc");
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_etiqrisk_update.php b/config/suricata/suricata_etiqrisk_update.php
new file mode 100644
index 00000000..70fbdb79
--- /dev/null
+++ b/config/suricata/suricata_etiqrisk_update.php
@@ -0,0 +1,216 @@
+<?php
+/*
+ * suricata_etiqrisk_update.php
+ *
+ * Significant portions of this code are based on original work done
+ * for the Snort package for pfSense from the following contributors:
+ *
+ * Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>.
+ * Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ * Copyright (C) 2006 Scott Ullrich
+ * Copyright (C) 2009 Robert Zelaya Sr. Developer
+ * Copyright (C) 2012 Ermal Luci
+ * All rights reserved.
+ *
+ * Adapted for Suricata by:
+ * Copyright (C) 2014 Bill Meeks
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require_once("config.inc");
+require_once("functions.inc");
+require_once("/usr/local/pkg/suricata/suricata.inc");
+require("/usr/local/pkg/suricata/suricata_defs.inc");
+
+/*************************************************************************
+ * Hack for backwards compatibility with older 2.1.x pfSense versions *
+ * that did not contain the new "download_file()" utility function *
+ * present in 2.2 and higher. *
+ *************************************************************************/
+if(!function_exists("download_file")) {
+ function download_file($url, $destination, $verify_ssl = false, $connect_timeout = 60, $timeout = 0) {
+ global $config, $g;
+
+ $fp = fopen($destination, "wb");
+
+ if (!$fp)
+ return false;
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify_ssl);
+ curl_setopt($ch, CURLOPT_FILE, $fp);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . rtrim(file_get_contents("/etc/version")));
+
+ if (!empty($config['system']['proxyurl'])) {
+ curl_setopt($ch, CURLOPT_PROXY, $config['system']['proxyurl']);
+ if (!empty($config['system']['proxyport']))
+ curl_setopt($ch, CURLOPT_PROXYPORT, $config['system']['proxyport']);
+ if (!empty($config['system']['proxyuser']) && !empty($config['system']['proxypass'])) {
+ @curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY | CURLAUTH_ANYSAFE);
+ curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$config['system']['proxyuser']}:{$config['system']['proxypass']}");
+ }
+ }
+
+ @curl_exec($ch);
+ $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ fclose($fp);
+ curl_close($ch);
+ return ($http_code == 200) ? true : $http_code;
+ }
+}
+
+function suricata_check_iprep_md5($filename) {
+
+ /**********************************************************/
+ /* This function attempts to download the MD5 hash for */
+ /* the passed file and compare its contents to the */
+ /* currently stored hash file to see if a new file has */
+ /* been posted. */
+ /* */
+ /* On Entry: $filename = IPREP file to check ('md5sum' */
+ /* is auto-appended to the supplied */
+ /* filename.) */
+ /* */
+ /* Returns: TRUE if new rule file download required. */
+ /* FALSE if rule download not required or an */
+ /* error occurred. */
+ /**********************************************************/
+
+ global $iqRisk_tmppath, $iprep_path;
+ $new_md5 = $old_md5 = "";
+ $et_iqrisk_url = str_replace("_xxx_", $config['installedpackages']['suricata']['config'][0]['iqrisk_code'], ET_IQRISK_DNLD_URL);
+
+ if (download_file("{$et_iqrisk_url}{$filename}.md5sum", "{$iqRisk_tmppath}{$filename}.md5") == true) {
+ if (file_exists("{$iqRisk_tmppath}{$filename}.md5"))
+ $new_md5 = trim(file_get_contents("{$iqRisk_tmppath}{$filename}.md5"));
+ if (file_exists("{$iprep_path}{$filename}.md5"))
+ $old_md5 = trim(file_get_contents("{$iprep_path}{$filename}.md5"));
+ if ($new_md5 != $old_md5)
+ return TRUE;
+ else
+ log_error(gettext("[Suricata] IPREP file '{$filename}' is up to date."));
+ }
+ else
+ log_error(gettext("[Suricata] An error occurred downloading {$et_iqrisk_url}{$filename}.md5sum for IPREP. Update of {$filename} file will be skipped."));
+
+ return FALSE;
+}
+
+/**********************************************************************
+ * Start of main code *
+ **********************************************************************/
+global $g, $config;
+$iprep_path = SURICATA_IPREP_PATH;
+$iqRisk_tmppath = "{$g['tmp_path']}/IQRisk/";
+$success = FALSE;
+
+if (!is_array($config['installedpackages']['suricata']['config'][0]))
+ $config['installedpackages']['suricata']['config'][0] = array();
+
+// If auto-updates of ET IQRisk are disabled, then exit
+if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == "off")
+ return(0);
+else
+ log_error(gettext("[Suricata] Updating the Emerging Threats IQRisk IP List..."));
+
+// Construct the download URL using the saved ET IQRisk Subscriber Code
+if (!empty($config['installedpackages']['suricata']['config'][0]['iqrisk_code'])) {
+ $et_iqrisk_url = str_replace("_xxx_", $config['installedpackages']['suricata']['config'][0]['iqrisk_code'], ET_IQRISK_DNLD_URL);
+}
+else {
+ log_error(gettext("[Suricata] No IQRisk subscriber code found! Aborting scheduled update of Emerging Threats IQRisk IP List."));
+ return(0);
+}
+
+// Download the IP List files to a temporary location
+safe_mkdir("$iqRisk_tmppath");
+
+// Test the posted MD5 checksum file against our local copy
+// to see if an update has been posted for 'categories.txt'.
+if (suricata_check_iprep_md5("categories.txt")) {
+ log_error(gettext("[Suricata] An updated IPREP 'categories.txt' file is available...downloading new file."));
+ if (download_file("{$et_iqrisk_url}categories.txt", "{$iqRisk_tmppath}categories.txt") != true)
+ log_error(gettext("[Suricata] An error occurred downloading the 'categories.txt' file for IQRisk."));
+ else {
+ // If the files downloaded successfully, unpack them and store
+ // the list files in the SURICATA_IPREP_PATH directory.
+ if (file_exists("{$iqRisk_tmppath}categories.txt") && file_exists("{$iqRisk_tmppath}categories.txt.md5")) {
+ $new_md5 = trim(file_get_contents("{$iqRisk_tmppath}categories.txt.md5"));
+ if ($new_md5 == md5_file("{$iqRisk_tmppath}categories.txt")) {
+ @rename("{$iqRisk_tmppath}categories.txt", "{$iprep_path}categories.txt");
+ @rename("{$iqRisk_tmppath}categories.txt.md5", "{$iprep_path}categories.txt.md5");
+ $success = TRUE;
+ log_error(gettext("[Suricata] Successfully updated IPREP file 'categories.txt'."));
+ }
+ else
+ log_error(gettext("[Suricata] MD5 integrity check of downloaded 'categories.txt' file failed! Skipping update of this IPREP file."));
+ }
+ }
+}
+
+// Test the posted MD5 checksum file against our local copy
+// to see if an update has been posted for 'iprepdata.txt.gz'.
+if (suricata_check_iprep_md5("iprepdata.txt.gz")) {
+ log_error(gettext("[Suricata] An updated IPREP 'iprepdata.txt' file is available...downloading new file."));
+ if (download_file("{$et_iqrisk_url}iprepdata.txt.gz", "{$iqRisk_tmppath}iprepdata.txt.gz") != true)
+ log_error(gettext("[Suricata] An error occurred downloading the 'iprepdata.txt.gz' file for IQRisk."));
+ else {
+ // If the files downloaded successfully, unpack them and store
+ // the list files in the SURICATA_IPREP_PATH directory.
+ if (file_exists("{$iqRisk_tmppath}iprepdata.txt.gz") && file_exists("{$iqRisk_tmppath}iprepdata.txt.gz.md5")) {
+ $new_md5 = trim(file_get_contents("{$iqRisk_tmppath}iprepdata.txt.gz.md5"));
+ if ($new_md5 == md5_file("{$iqRisk_tmppath}iprepdata.txt.gz")) {
+ mwexec("/usr/bin/gunzip -f {$iqRisk_tmppath}iprepdata.txt.gz");
+ @rename("{$iqRisk_tmppath}iprepdata.txt", "{$iprep_path}iprepdata.txt");
+ @rename("{$iqRisk_tmppath}iprepdata.txt.gz.md5", "{$iprep_path}iprepdata.txt.gz.md5");
+ $success = TRUE;
+ log_error(gettext("[Suricata] Successfully updated IPREP file 'iprepdata.txt'."));
+ }
+ else
+ log_error(gettext("[Suricata] MD5 integrity check of downloaded 'iprepdata.txt.gz' file failed! Skipping update of this IPREP file."));
+ }
+ }
+}
+
+// Cleanup the tmp directory path
+rmdir_recursive("$iqRisk_tmppath");
+
+log_error(gettext("[Suricata] Emerging Threats IQRisk IP List update finished."));
+
+// If successful, signal any running Suricata process to live reload the rules and IP lists
+if ($success == TRUE && is_process_running("suricata")) {
+ foreach ($config['installedpackages']['suricata']['rule'] as $value) {
+ if ($value['enable_iprep'] == "on") {
+ suricata_reload_config($value);
+ sleep(2);
+ }
+ }
+}
+
+?>
diff --git a/config/suricata/suricata_flow_stream.php b/config/suricata/suricata_flow_stream.php
index 53c4e010..9467ea7c 100644
--- a/config/suricata/suricata_flow_stream.php
+++ b/config/suricata/suricata_flow_stream.php
@@ -467,6 +467,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
echo '</td></tr>';
echo '<tr><td>';
@@ -479,6 +480,7 @@ if ($savemsg) {
$tab_array[] = array($menu_iface . gettext("App Parsers"), false, "/suricata/suricata_app_parsers.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Variables"), false, "/suricata/suricata_define_vars.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Barnyard2"), false, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), false, "/suricata/suricata_ip_reputation.php?id={$id}");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_generate_yaml.php b/config/suricata/suricata_generate_yaml.php
index 8e3e538c..328702b9 100644
--- a/config/suricata/suricata_generate_yaml.php
+++ b/config/suricata/suricata_generate_yaml.php
@@ -53,13 +53,6 @@ foreach ($config_files as $file) {
@copy("{$suricatadir}{$file}", "{$suricatacfgdir}/{$file}");
}
-// Create required files if they don't exist
-$suricata_files = array( "{$suricatacfgdir}/magic" );
-foreach ($suricata_files as $file) {
- if (!file_exists($file))
- file_put_contents($file, "\n");
-}
-
// Read the configuration parameters for the passed interface
// and construct appropriate string variables for use in the
// suricata.yaml template include file.
@@ -540,9 +533,10 @@ else
// Add the OS-specific host policies if configured, otherwise
// just set default to BSD for all networks.
+$host_os_policy = "";
if (!is_array($suricatacfg['host_os_policy']['item']))
$suricatacfg['host_os_policy']['item'] = array();
-if (empty($suricatacfg['host_os_policy']['item']))
+if (count($suricatacfg['host_os_policy']['item']) < 1)
$host_os_policy = "bsd: [0.0.0.0/0]";
else {
foreach ($suricatacfg['host_os_policy']['item'] as $k => $v) {
@@ -580,10 +574,12 @@ else {
// Add the HTTP Server-specific policies if configured, otherwise
// just set default to IDS for all networks.
+$http_hosts_policy = "";
+$http_hosts_default_policy = "";
if (!is_array($suricatacfg['libhtp_policy']['item']))
$suricatacfg['libhtp_policy']['item'] = array();
-if (empty($suricatacfg['libhtp_policy']['item'])) {
- $http_hosts_default_policy = "default-config:\n personality: IDS\n request-body-limit: 4096\n response-body-limit: 4096\n";
+if (count($suricatacfg['libhtp_policy']['item']) < 1) {
+ $http_hosts_default_policy = " personality: IDS\n request-body-limit: 4096\n response-body-limit: 4096\n";
$http_hosts_default_policy .= " double-decode-path: no\n double-decode-query: no\n uri-include-all: no\n";
}
else {
@@ -705,15 +701,41 @@ else
$http_parser_memcap = "67108864";
/* Configure the IP REP section */
-$iprep_path = rtrim(IPREP_PATH, '/');
+$iprep_path = rtrim(SURICATA_IPREP_PATH, '/');
+$iprep_config = "# IP Reputation\n";
+if ($suricatacfg['enable_iprep'] == "on") {
+ $iprep_config .= "default-reputation-path: {$iprep_path}\n";
+ $iprep_config .= "reputation-categories-file: {$iprep_path}/{$suricatacfg['iprep_catlist']}\n";
+ $iprep_config .= "reputation-files:";
+
+ if (!is_array($suricatacfg['iplist_files']['item']))
+ $suricatacfg['iplist_files']['item'] = array();
+
+ foreach ($suricatacfg['iplist_files']['item'] as $f)
+ $iprep_config .= "\n - $f";
+}
+
+/* Configure Host Table settings */
+if (!empty($suricatacfg['host_memcap']))
+ $host_memcap = $suricatacfg['host_memcap'];
+else
+ $host_memcap = "16777216";
+if (!empty($suricatacfg['host_hash_size']))
+ $host_hash_size = $suricatacfg['host_hash_size'];
+else
+ $host_hash_size = "4096";
+if (!empty($suricatacfg['host_prealloc']))
+ $host_prealloc = $suricatacfg['host_prealloc'];
+else
+ $host_prealloc = "1000";
// Create the rules files and save in the interface directory
suricata_prepare_rule_files($suricatacfg, $suricatacfgdir);
// Check and configure only non-empty rules files for the interface
$rules_files = "";
-if (filesize("{$suricatacfgdir}/rules/".ENFORCING_RULES_FILENAME) > 0)
- $rules_files .= ENFORCING_RULES_FILENAME;
+if (filesize("{$suricatacfgdir}/rules/".SURICATA_ENFORCING_RULES_FILENAME) > 0)
+ $rules_files .= SURICATA_ENFORCING_RULES_FILENAME;
if (filesize("{$suricatacfgdir}/rules/".FLOWBITS_FILENAME) > 0)
$rules_files .= "\n - " . FLOWBITS_FILENAME;
if (filesize("{$suricatacfgdir}/rules/custom.rules") > 0)
diff --git a/config/suricata/suricata_geoipupdate.php b/config/suricata/suricata_geoipupdate.php
new file mode 100644
index 00000000..46e1177e
--- /dev/null
+++ b/config/suricata/suricata_geoipupdate.php
@@ -0,0 +1,137 @@
+<?php
+/*
+ * suricata_geoipupdate.php
+ *
+ * Significant portions of this code are based on original work done
+ * for the Snort package for pfSense from the following contributors:
+ *
+ * Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>.
+ * Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ * Copyright (C) 2006 Scott Ullrich
+ * Copyright (C) 2009 Robert Zelaya Sr. Developer
+ * Copyright (C) 2012 Ermal Luci
+ * All rights reserved.
+ *
+ * Adapted for Suricata by:
+ * Copyright (C) 2014 Bill Meeks
+ * All rights reserved.
+ *
+ * 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 product includes GeoLite data created by MaxMind, available from
+ * http://www.maxmind.com
+*/
+
+require_once("config.inc");
+require_once("functions.inc");
+require("/usr/local/pkg/suricata/suricata_defs.inc");
+
+/*************************************************************************
+ * Hack for backwards compatibility with older 2.1.x pfSense versions *
+ * that did not contain the new "download_file()" utility function *
+ * present in 2.2 and higher. *
+ *************************************************************************/
+if(!function_exists("download_file")) {
+ function download_file($url, $destination, $verify_ssl = false, $connect_timeout = 60, $timeout = 0) {
+ global $config, $g;
+
+ $fp = fopen($destination, "wb");
+
+ if (!$fp)
+ return false;
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verify_ssl);
+ curl_setopt($ch, CURLOPT_FILE, $fp);
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
+ curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($ch, CURLOPT_HEADER, false);
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+ curl_setopt($ch, CURLOPT_USERAGENT, $g['product_name'] . '/' . rtrim(file_get_contents("/etc/version")));
+
+ if (!empty($config['system']['proxyurl'])) {
+ curl_setopt($ch, CURLOPT_PROXY, $config['system']['proxyurl']);
+ if (!empty($config['system']['proxyport']))
+ curl_setopt($ch, CURLOPT_PROXYPORT, $config['system']['proxyport']);
+ if (!empty($config['system']['proxyuser']) && !empty($config['system']['proxypass'])) {
+ @curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY | CURLAUTH_ANYSAFE);
+ curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$config['system']['proxyuser']}:{$config['system']['proxypass']}");
+ }
+ }
+
+ @curl_exec($ch);
+ $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+ fclose($fp);
+ curl_close($ch);
+ return ($http_code == 200) ? true : $http_code;
+ }
+}
+
+/**********************************************************************
+ * Start of main code *
+ **********************************************************************/
+global $g, $config;
+$suricata_geoip_dbdir = SURICATA_PBI_BASEDIR . 'share/GeoIP/';
+$geoip_tmppath = "{$g['tmp_path']}/geoipup/";
+
+// If auto-updates of GeoIP are disabled, then exit
+if ($config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] == "off")
+ exit(0);
+else
+ log_error(gettext("[Suricata] Updating the GeoIP country database files..."));
+
+
+// Download the free GeoIP Legacy country name databases for IPv4 and IPv6
+// to a temporary location.
+safe_mkdir("$geoip_tmppath");
+if (download_file("http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz", "{$geoip_tmppath}GeoIP.dat.gz") != true)
+ log_error(gettext("[Suricata] An error occurred downloading the 'GeoIP.dat.gz' update file for GeoIP."));
+if (download_file("http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz", "{$geoip_tmppath}GeoIPv6.dat.gz") != true)
+ log_error(gettext("[Suricata] An error occurred downloading the 'GeoIPv6.dat.gz' update file for GeoIP."));
+
+// Mount filesystem read-write since we need to write
+// the extracted databases to PBI_BASE/share/GeoIP.
+conf_mount_rw();
+
+// If the files downloaded successfully, unpack them and store
+// the DB files in the PBI_BASE/share/GeoIP directory.
+if (file_exists("{$geoip_tmppath}GeoIP.dat.gz")) {
+ mwexec("/usr/bin/gunzip -f {$geoip_tmppath}GeoIP.dat.gz");
+ @rename("{$geoip_tmppath}GeoIP.dat", "{$suricata_geoip_dbdir}GeoIP.dat");
+}
+
+if (file_exists("{$geoip_tmppath}GeoIPv6.dat.gz")) {
+ mwexec("/usr/bin/gunzip -f {$geoip_tmppath}GeoIPv6.dat.gz");
+ @rename("{$geoip_tmppath}GeoIPv6.dat", "{$suricata_geoip_dbdir}GeoIPv6.dat");
+}
+
+// Finished with filesystem mods, so remount read-only
+conf_mount_ro();
+
+// Cleanup the tmp directory path
+rmdir_recursive("$geoip_tmppath");
+
+log_error(gettext("[Suricata] GeoIP database update finished."));
+
+?>
diff --git a/config/suricata/suricata_global.php b/config/suricata/suricata_global.php
index 5f01a660..8eea8d2d 100644
--- a/config/suricata/suricata_global.php
+++ b/config/suricata/suricata_global.php
@@ -66,6 +66,7 @@ else {
$pconfig['forcekeepsettings'] = $config['installedpackages']['suricata']['config'][0]['forcekeepsettings'];
$pconfig['snortcommunityrules'] = $config['installedpackages']['suricata']['config'][0]['snortcommunityrules'];
$pconfig['snort_rules_file'] = $config['installedpackages']['suricata']['config'][0]['snort_rules_file'];
+ $pconfig['autogeoipupdate'] = $config['installedpackages']['suricata']['config'][0]['autogeoipupdate'];
}
// Do input validation on parameters
@@ -97,6 +98,7 @@ if (!$input_errors) {
$config['installedpackages']['suricata']['config'][0]['snortcommunityrules'] = $_POST['snortcommunityrules'] ? 'on' : 'off';
$config['installedpackages']['suricata']['config'][0]['enable_etopen_rules'] = $_POST['enable_etopen_rules'] ? 'on' : 'off';
$config['installedpackages']['suricata']['config'][0]['enable_etpro_rules'] = $_POST['enable_etpro_rules'] ? 'on' : 'off';
+ $config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] = $_POST['autogeoipupdate'] ? 'on' : 'off';
// If any rule sets are being turned off, then remove them
// from the active rules section of each interface. Start
@@ -140,12 +142,14 @@ if (!$input_errors) {
$config['installedpackages']['suricata']['config'][0]['autoruleupdate'] = $_POST['autoruleupdate'];
/* Check and adjust format of Rule Update Starttime string to add colon and leading zero if necessary */
- $pos = strpos($_POST['autoruleupdatetime'], ":");
- if ($pos === false) {
- $tmp = str_pad($_POST['autoruleupdatetime'], 4, "0", STR_PAD_LEFT);
- $_POST['autoruleupdatetime'] = substr($tmp, 0, 2) . ":" . substr($tmp, -2);
+ if ($_POST['autoruleupdatetime']) {
+ $pos = strpos($_POST['autoruleupdatetime'], ":");
+ if ($pos === false) {
+ $tmp = str_pad($_POST['autoruleupdatetime'], 4, "0", STR_PAD_LEFT);
+ $_POST['autoruleupdatetime'] = substr($tmp, 0, 2) . ":" . substr($tmp, -2);
+ }
+ $config['installedpackages']['suricata']['config'][0]['autoruleupdatetime'] = str_pad($_POST['autoruleupdatetime'], 4, "0", STR_PAD_LEFT);
}
- $config['installedpackages']['suricata']['config'][0]['autoruleupdatetime'] = str_pad($_POST['autoruleupdatetime'], 4, "0", STR_PAD_LEFT);
$config['installedpackages']['suricata']['config'][0]['log_to_systemlog'] = $_POST['log_to_systemlog'] ? 'on' : 'off';
$config['installedpackages']['suricata']['config'][0]['log_to_systemlog_facility'] = $_POST['log_to_systemlog_facility'];
$config['installedpackages']['suricata']['config'][0]['live_swap_updates'] = $_POST['live_swap_updates'] ? 'on' : 'off';
@@ -153,10 +157,20 @@ if (!$input_errors) {
$retval = 0;
+ write_config("Suricata pkg: modified global settings.");
+
+ /* Toggle cron task for GeoIP database updates if setting was changed */
+ if ($config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] == 'on' && !suricata_cron_job_exists("/usr/local/pkg/suricata/suricata_geoipupdate.php")) {
+ include("/usr/local/pkg/suricata/suricata_geoipupdate.php");
+ install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_geoipupdate.php", TRUE, 0, 0, 8, "*", "*", "root");
+ }
+ elseif ($config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] == 'off' && suricata_cron_job_exists("/usr/local/pkg/suricata/suricata_geoipupdate.php"))
+ install_cron_job("/usr/local/pkg/suricata/suricata_geoipupdate.php", FALSE);
+
/* create passlist and homenet file, then sync files */
+ conf_mount_rw();
sync_suricata_package_config();
-
- write_config("Suricata pkg: modified global settings.");
+ conf_mount_ro();
/* forces page to reload new settings */
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
@@ -202,6 +216,7 @@ if ($input_errors)
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td></tr>
@@ -221,13 +236,13 @@ if ($input_errors)
<tr>
<td valign="top" width="8%"><input name="enable_etopen_rules" type="checkbox" value="on" onclick="enable_et_rules();"
<?php if ($config['installedpackages']['suricata']['config'][0]['enable_etopen_rules']=="on") echo "checked"; ?>/></td>
- <td><span class="vexpl"><?php echo gettext("ETOpen is an open source set of Snort rules whose coverage " .
+ <td><span class="vexpl"><?php echo gettext("ETOpen is an open source set of Suricata rules whose coverage " .
"is more limited than ETPro."); ?></span></td>
</tr>
<tr>
<td valign="top" width="8%"><input name="enable_etpro_rules" type="checkbox" value="on" onclick="enable_pro_rules();"
<?php if ($config['installedpackages']['suricata']['config'][0]['enable_etpro_rules']=="on") echo "checked"; ?>/></td>
- <td><span class="vexpl"><?php echo gettext("ETPro for Snort offers daily updates and extensive coverage of current malware threats."); ?></span></td>
+ <td><span class="vexpl"><?php echo gettext("ETPro for Suricata offers daily updates and extensive coverage of current malware threats."); ?></span></td>
</tr>
<tr>
<td>&nbsp;</td>
@@ -348,6 +363,15 @@ if ($input_errors)
"If issues are encountered with live load, uncheck this option to perform a hard restart of all Suricata instances following an update."); ?></td>
</tr>
<tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("GeoIP DB Update"); ?></td>
+ <td width="78%" class="vtable"><input name="autogeoipupdate" id="autogeoipupdate" type="checkbox" value="yes"
+ <?php if ($config['installedpackages']['suricata']['config'][0]['autogeoipupdate']=="on") echo " checked"; ?>/>
+ &nbsp;<?php echo gettext("Enable downloading of free GeoIP Country Database updates. Default is ") . "<strong>" . gettext("Checked") . "</strong>"; ?><br/><br/>
+ <?php echo gettext("When enabled, Suricata will automatically download updates for the free legacy GeoIP country database on the 8th of each month at midnight.") .
+ "<br/><br/>" . gettext("If you have a subscription for more current GeoIP updates, uncheck this option and instead create your own process to place the required database files in " .
+ SURICATA_PBI_BASEDIR . "share/GeoIP/."); ?></td>
+</tr>
+<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Settings"); ?></td>
</tr>
<tr>
diff --git a/config/suricata/suricata_interfaces.php b/config/suricata/suricata_interfaces.php
index 3d093d45..e996a24f 100644
--- a/config/suricata/suricata_interfaces.php
+++ b/config/suricata/suricata_interfaces.php
@@ -68,8 +68,8 @@ if ($_POST['del_x']) {
$if_real = get_real_interface($a_nat[$rulei]['interface']);
$suricata_uuid = $a_nat[$rulei]['uuid'];
suricata_stop($a_nat[$rulei], $if_real);
- exec("/bin/rm -r {$suricatalogdir}suricata_{$if_real}{$suricata_uuid}");
- exec("/bin/rm -r {$suricatadir}suricata_{$suricata_uuid}_{$if_real}");
+ rmdir_recursive("{$suricatalogdir}suricata_{$if_real}{$suricata_uuid}");
+ rmdir_recursive("{$suricatadir}suricata_{$suricata_uuid}_{$if_real}");
unset($a_nat[$rulei]);
}
conf_mount_ro();
@@ -81,16 +81,9 @@ if ($_POST['del_x']) {
write_config("Suricata pkg: deleted one or more Suricata interfaces.");
sleep(2);
- /* if there are no ifaces remaining do not create suricata.sh */
- if (!empty($config['installedpackages']['suricata']['rule']))
- suricata_create_rc();
- else {
- conf_mount_rw();
- @unlink("{$rcdir}suricata.sh");
- conf_mount_ro();
- }
-
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
@@ -110,7 +103,9 @@ if ($_POST['bartoggle']) {
if (!suricata_is_running($suricatacfg['uuid'], $if_real, 'barnyard2')) {
log_error("Toggle (barnyard starting) for {$if_friendly}({$suricatacfg['descr']})...");
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
suricata_barnyard_start($suricatacfg, $if_real);
} else {
log_error("Toggle (barnyard stopping) for {$if_friendly}({$suricatacfg['descr']})...");
@@ -135,7 +130,9 @@ if ($_POST['toggle']) {
log_error("Toggle (suricata starting) for {$if_friendly}({$suricatacfg['descr']})...");
// set flag to rebuild interface rules before starting Snort
$rebuild_rules = true;
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
$rebuild_rules = false;
suricata_start($suricatacfg, $if_real);
}
@@ -185,6 +182,7 @@ include_once("head.inc");
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td>
diff --git a/config/suricata/suricata_interfaces_edit.php b/config/suricata/suricata_interfaces_edit.php
index c4a1775a..13526031 100644
--- a/config/suricata/suricata_interfaces_edit.php
+++ b/config/suricata/suricata_interfaces_edit.php
@@ -223,7 +223,9 @@ if ($_POST["save"] && !$input_errors) {
suricata_stop($a_rule[$id], get_real_interface($a_rule[$id]['interface']));
write_config("Suricata pkg: disabled Suricata on " . convert_friendly_interface_to_friendly_descr($a_rule[$id]['interface']));
$rebuild_rules = false;
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
@@ -316,9 +318,9 @@ if ($_POST["save"] && !$input_errors) {
}
else
$suricata_start = false;
- exec("mv -f {$suricatalogdir}suricata_{$oif_real}" . $a_rule[$id]['uuid'] . " {$suricatalogdir}suricata_{$if_real}" . $a_rule[$id]['uuid']);
+ @rename("{$suricatalogdir}suricata_{$oif_real}{$a_rule[$id]['uuid']}", "{$suricatalogdir}suricata_{$if_real}{$a_rule[$id]['uuid']}");
conf_mount_rw();
- exec("mv -f {$suricatadir}suricata_" . $a_rule[$id]['uuid'] . "_{$oif_real} {$suricatadir}suricata_" . $a_rule[$id]['uuid'] . "_{$if_real}");
+ @rename("{$suricatadir}suricata_{$a_rule[$id]['uuid']}_{$oif_real}", "{$suricatadir}suricata_{$a_rule[$id]['uuid']}_{$if_real}");
conf_mount_ro();
}
$a_rule[$id] = $natent;
@@ -392,6 +394,11 @@ if ($_POST["save"] && !$input_errors) {
$natent['smb_parser'] = "yes";
$natent['msn_parser'] = "detection-only";
+ $natent['enable_iprep'] = "off";
+ $natent['host_memcap'] = "16777216";
+ $natent['host_hash_size'] = "4096";
+ $natent['host_prealloc'] = "1000";
+
$default = array( "name" => "default", "bind_to" => "all", "policy" => "bsd" );
if (!is_array($natent['host_os_policy']['item']))
$natent['host_os_policy']['item'] = array();
@@ -423,7 +430,9 @@ if ($_POST["save"] && !$input_errors) {
write_config("Suricata pkg: modified interface configuration for " . convert_friendly_interface_to_friendly_descr($natent['interface']));
// Update suricata.conf and suricata.sh files for this interface
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
@@ -473,6 +482,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
echo '</td></tr>';
echo '<tr><td class="tabnavtbl">';
@@ -485,6 +495,7 @@ if ($savemsg) {
$tab_array[] = array($menu_iface . gettext("App Parsers"), false, "/suricata/suricata_app_parsers.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Variables"), false, "/suricata/suricata_define_vars.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Barnyard2"), false, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), false, "/suricata/suricata_ip_reputation.php?id={$id}");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_ip_list_mgmt.php b/config/suricata/suricata_ip_list_mgmt.php
new file mode 100644
index 00000000..37decaad
--- /dev/null
+++ b/config/suricata/suricata_ip_list_mgmt.php
@@ -0,0 +1,398 @@
+<?php
+/*
+ * suricata_ip_list_mgmt.php
+ *
+ * Significant portions of this code are based on original work done
+ * for the Snort package for pfSense from the following contributors:
+ *
+ * Copyright (C) 2005 Bill Marquette <bill.marquette@gmail.com>.
+ * Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ * Copyright (C) 2006 Scott Ullrich
+ * Copyright (C) 2009 Robert Zelaya Sr. Developer
+ * Copyright (C) 2012 Ermal Luci
+ * All rights reserved.
+ *
+ * Adapted for Suricata by:
+ * Copyright (C) 2014 Bill Meeks
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+require_once("guiconfig.inc");
+require_once("/usr/local/pkg/suricata/suricata.inc");
+
+global $config, $g;
+
+if (!is_array($config['installedpackages']['suricata']['rule']))
+ $config['installedpackages']['suricata']['rule'] = array();
+
+// Hard-code the path where IP Lists are stored
+// and disregard any user-supplied path element.
+$iprep_path = SURICATA_IPREP_PATH;
+
+// Set default to not show IP List editor controls
+$iplist_edit_style = "display: none;";
+
+function suricata_is_iplist_active($iplist) {
+
+ /***************************************************
+ * This function checks all configured Suricata *
+ * interfaces to see if the passed IP List is used *
+ * as a whitelist or blacklist by an interface. *
+ * *
+ * Returns: TRUE if IP List is in use *
+ * FALSE if IP List is not in use *
+ ***************************************************/
+
+ global $g, $config;
+
+ if (!is_array($config['installedpackages']['suricata']['rule']))
+ return FALSE;
+
+ foreach ($config['installedpackages']['suricata']['rule'] as $rule) {
+ if (is_array($rule['iplist_files']['item'])) {
+ foreach ($rule['iplist_files']['item'] as $file) {
+ if ($file == $iplist)
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+// If doing a postback, used typed values, else load from stored config
+if (!empty($_POST)) {
+ $pconfig = $_POST;
+}
+else {
+ $pconfig['et_iqrisk_enable'] = $config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'];
+ $pconfig['iqrisk_code'] = $config['installedpackages']['suricata']['config'][0]['iqrisk_code'];
+}
+
+// Validate IQRisk settings if enabled and saving them
+if ($_POST['save']) {
+ if ($pconfig['et_iqrisk_enable'] == 'on' && empty($pconfig['iqrisk_code']))
+ $input_errors[] = gettext("You must provide a valid IQRisk subscription code when IQRisk downloads are enabled!");
+
+ if (!$input_errors) {
+ $config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] = $_POST['et_iqrisk_enable'] ? 'on' : 'off';
+ $config['installedpackages']['suricata']['config'][0]['iqrisk_code'] = $_POST['iqrisk_code'];
+ write_config("Suricata pkg: modified IP Lists settings.");
+
+ /* Toggle cron task for ET IQRisk updates if setting was changed */
+ if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'on' && !suricata_cron_job_exists("/usr/local/pkg/suricata/suricata_etiqrisk_update.php")) {
+ install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_etiqrisk_update.php", TRUE, 0, "*/6", "*", "*", "*", "root");
+ }
+ elseif ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'off' && suricata_cron_job_exists("/usr/local/pkg/suricata/suricata_etiqrisk_update.php"))
+ install_cron_job("/usr/local/pkg/suricata/suricata_etiqrisk_update.php", FALSE);
+
+ /* Peform a manual ET IQRisk file check/download */
+ if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'on')
+ include("/usr/local/pkg/suricata/suricata_etiqrisk_update.php");
+ }
+}
+
+if (isset($_POST['upload'])) {
+ if ($_FILES["iprep_fileup"]["error"] == UPLOAD_ERR_OK) {
+ $tmp_name = $_FILES["iprep_fileup"]["tmp_name"];
+ $name = $_FILES["iprep_fileup"]["name"];
+ move_uploaded_file($tmp_name, "{$iprep_path}{$name}");
+ }
+ else
+ $input_errors[] = gettext("Failed to upload file {$_FILES["iprep_fileup"]["name"]}");
+}
+
+if (isset($_POST['iplist_delete']) && isset($_POST['iplist_fname'])) {
+ if (!suricata_is_iplist_active($_POST['iplist_fname']))
+ unlink_if_exists("{$iprep_path}{$_POST['iplist_fname']}");
+ else
+ $input_errors[] = gettext("This IP List is currently assigned to an interface and cannot be deleted until it is removed from the configured interface.");
+}
+
+if (isset($_POST['iplist_edit']) && isset($_POST['iplist_fname'])) {
+ $file = $iprep_path . basename($_POST['iplist_fname']);
+ $data = file_get_contents($file);
+ if ($data !== FALSE) {
+ $iplist_data = htmlspecialchars($data);
+ $iplist_edit_style = "display: table-row-group;";
+ $iplist_name = basename($_POST['iplist_fname']);
+ unset($data);
+ }
+ else {
+ $input_errors[] = gettext("An error occurred reading the file.");
+ }
+}
+
+if (isset($_POST['iplist_edit_save']) && isset($_POST['iplist_data'])) {
+ if (strlen(basename($_POST['iplist_name'])) > 0) {
+ $file = $iprep_path . basename($_POST['iplist_name']);
+ $data = str_replace("\r\n", "\n", $_POST['iplist_data']);
+ file_put_contents($file, $data);
+ unset($data);
+ }
+ else {
+ $input_errors[] = gettext("You must provide a valid filename for the IP List.");
+ $iplist_edit_style = "display: table-row-group;";
+ }
+}
+
+// Get all files in the IP Lists sub-directory as an array
+// Leave this as the last thing before spewing the page HTML
+// so we can pick up any changes made to files in code above.
+$ipfiles = return_dir_as_array($iprep_path);
+
+$pgtitle = gettext("Suricata: IP Reputation Lists");
+include_once("head.inc");
+
+?>
+
+<body link="#000000" vlink="#000000" alink="#000000">
+
+<?php
+include_once("fbegin.inc");
+if ($input_errors) {
+ print_input_errors($input_errors);
+}
+
+if ($savemsg)
+ print_info_box($savemsg);
+?>
+
+<form action="/suricata/suricata_ip_list_mgmt.php" enctype="multipart/form-data" method="post" name="iform" id="iform">
+<input type="hidden" name="MAX_FILE_SIZE" value="100000000" />
+<input type="hidden" name="iplist_fname" id="iplist_fname" value=""/>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
+<tr><td>
+<?php
+ $tab_array = array();
+ $tab_array[] = array(gettext("Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $tab_array[] = array(gettext("Global Settings"), false, "/suricata/suricata_global.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php?instance={$id}");
+ $tab_array[] = array(gettext("Blocks"), false, "/suricata/suricata_blocked.php");
+ $tab_array[] = array(gettext("Pass Lists"), false, "/suricata/suricata_passlist.php");
+ $tab_array[] = array(gettext("Suppress"), false, "/suricata/suricata_suppress.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
+ $tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), true, "/suricata/suricata_ip_list_mgmt.php");
+ display_top_tabs($tab_array, true);
+?>
+</td>
+</tr>
+<tr>
+ <td>
+ <div id="mainarea">
+ <table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
+ <?php if ($g['platform'] == "nanobsd") : ?>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("IP Reputation is not supported on NanoBSD installs"); ?></td>
+ </tr>
+ <?php else: ?>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Emerging Threats IQRisk Settings"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top"><?php echo gettext("Enable"); ?></td>
+ <td width="78%">
+ <input id="et_iqrisk_enable" name="et_iqrisk_enable" type="checkbox" value="on" <?php if ($pconfig['et_iqrisk_enable'] == "on") echo "checked"; ?> onclick="IQRisk_enablechange();"/>
+ <?php echo gettext("Checking this box enables auto-download of IQRisk List updates with a valid subscription code."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%"></td>
+ <td width="78%">
+ <table id="iqrisk_code_tbl" width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
+ <tr>
+ <td colspan="2" class="vexpl"><?=gettext("IQRisk IP lists will auto-update nightly at midnight. Visit ") .
+ "<a href='http://emergingthreats.net/products/iqrisk-rep-list/' target='_blank'>" . gettext("http://emergingthreats.net/products/iqrisk-rep-list/") . "</a>" .
+ gettext(" for more information or to purchase a subscription.");?><br/><br/></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top"><b><span class="vexpl"><?php echo gettext("IQRisk Subscription Configuration"); ?></span></b></td>
+ </tr>
+ <tr>
+ <td valign="top"><span class="vexpl"><strong><?php echo gettext("Code:"); ?></strong></span></td>
+ <td><input name="iqrisk_code" type="text" class="formfld unknown" id="iqrisk_code" size="52"
+ value="<?=htmlspecialchars($pconfig['iqrisk_code']);?>"/><br/>
+ <?php echo gettext("Obtain an Emerging Threats IQRisk List subscription code and paste it here."); ?></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" align="center"><input name="save" id="save" type="submit" class="formbtn" value="Save" title="<?=gettext("Save IQRisk settings");?>"/></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vtable"></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="listtopic"><?=gettext("IP Reputation List Files Management");?>
+ </td>
+ </tr>
+ <tbody id="uploader" style="display: none;">
+ <tr>
+ <td colspan="2" class="list"><br/><?php echo gettext("Click BROWSE to select a file to import, and then click UPLOAD. Click CLOSE to quit."); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list"><input type="file" name="iprep_fileup" id="iprep_fileup" class="formfld file" size="50" />
+ &nbsp;&nbsp;<input type="submit" name="upload" id="upload" value="<?=gettext("Upload");?>"
+ title="<?=gettext("Upload selected IP list to firewall");?>"/>&nbsp;&nbsp;<input type="button"
+ value="<?=gettext("Close");?>" onClick="document.getElementById('uploader').style.display='none';" /></td>
+ </tr>
+ </tbody>
+ <tr>
+ <td colspan="2">
+ <table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <colgroup>
+ <col style="width: 50%;">
+ <col style="width: 25%;">
+ <col style="width: 15%;">
+ <col style="width: 10%;">
+ </colgroup>
+ <thead>
+ <tr>
+ <th class="listhdrr"><?php echo gettext("IP List File Name"); ?></th>
+ <th class="listhdrr"><?php echo gettext("Last Modified Time"); ?></th>
+ <th class="listhdrr"><?php echo gettext("File Size"); ?></th>
+ <th class="list" align="left"><img style="cursor:pointer;" name="iplist_new" id="iplist_new"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17"
+ height="17" border="0" title="<?php echo gettext('Create a new IP List');?>"
+ onClick="document.getElementById('iplist_data').value=''; document.getElementById('iplist_name').value=''; document.getElementById('iplist_editor').style.display='table-row-group'; document.getElementById('iplist_name').focus();" />
+ <img style="cursor:pointer;" name="iplist_import" id="iplist_import"
+ onClick="document.getElementById('uploader').style.display='table-row-group';"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_import_alias.gif" width="17"
+ height="17" border="0" title="<?php echo gettext('Import/Upload an IP List');?>"/></th>
+ </tr>
+ </thead>
+ <?php foreach ($ipfiles as $file):
+ if (substr(strrchr($file, "."), 1) == "md5")
+ continue; ?>
+ <tr>
+ <td class="listr"><?php echo gettext($file); ?></td>
+ <td class="listr"><?=date('M-d Y g:i a', filemtime("{$iprep_path}{$file}")); ?></td>
+ <td class="listr"><?=format_bytes(filesize("{$iprep_path}{$file}")); ?> </td>
+ <td class="list"><input type="image" name="iplist_edit[]" id="iplist_edit[]"
+ onClick="document.getElementById('iplist_fname').value='<?=$file;?>';"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17"
+ height="17" border="0" title="<?php echo gettext('Edit this IP List');?>"/>
+ <input type="image" name="iplist_delete[]" id="iplist_delete[]"
+ onClick="document.getElementById('iplist_fname').value='<?=$file;?>';
+ return confirm('<?=gettext("Are you sure you want to permanently delete this IP List file? Click OK to continue or CANCEL to quit.");?>');"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17"
+ height="17" border="0" title="<?php echo gettext('Delete this IP List');?>"/></td>
+ </tr>
+ <?php endforeach; ?>
+ <tbody id="iplist_editor" style="<?=$iplist_edit_style;?>">
+ <tr>
+ <td colspan="4">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="4"><strong><?=gettext("File Name: ");?></strong><input type="text" size="45" class="formfld file" id="iplist_name" name="iplist_name" value="<?=$iplist_name;?>" />
+ &nbsp;&nbsp;<input type="submit" id="iplist_edit_save" name="iplist_edit_save" value="<?=gettext(" Save ");?>" title="<?=gettext("Save changes and close editor");?>" />
+ &nbsp;&nbsp;<input type="button" id="cancel" name="cancel" value="<?=gettext("Cancel");?>" onClick="document.getElementById('iplist_editor').style.display='none';"
+ title="<?=gettext("Abandon changes and quit editor");?>" /></td>
+ </tr>
+ <tr>
+ <td colspan="4">&nbsp;</td>
+ </tr>
+ <tr>
+ <td colspan="4"><textarea wrap="off" cols="80" rows="20" name="iplist_data" id="iplist_data"
+ style="width:95%; height:100%;"><?=$iplist_data;?></textarea>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="3" class="vexpl"><br/><span class="red"><strong><?php echo gettext("Notes:"); ?></strong></span>
+ <br/><?php echo gettext("1. A Categories file is required and contains CSV fields for Category Number, Short Name " .
+ "and Description per line."); ?></td>
+ <td class="list"></td>
+ </tr>
+ <tr>
+ <td colspan="3" class="vexpl"><?php echo gettext("2. IP Lists are CSV format text files " .
+ "with an IP address, category code and reputation score per line."); ?></td>
+ <td class="list"></td>
+ </tr>
+ <tr>
+ <td colspan="3" class="vexpl"><?php echo gettext("3. IP Lists are stored as local files " .
+ "on the firewall and their contents are not saved as part of the firewall configuration file."); ?></td>
+ <td class="list"></td>
+ </tr>
+ <tr>
+ <td colspan="3" class="vexpl"><?php echo gettext("4. Visit ") .
+ "<a href='https://redmine.openinfosecfoundation.org/projects/suricata/wiki/IPReputationFormat' target='_blank'>" .
+ gettext("https://redmine.openinfosecfoundation.org/projects/suricata/wiki/IPReputationFormat") . "</a>" .
+ gettext(" for IP Reputation file formats."); ?><br/></td>
+ <td class="list"></td>
+ </tr>
+ <tr>
+ <td colspan="3" class="vexpl"><br/><strong><?php echo gettext("IP List Controls:"); ?></strong><br/><br/>
+ &nbsp;&nbsp;<img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17" border="0" />
+ &nbsp;<?=gettext("Opens the editor window to create a new IP List. You must provide a valid filename before saving.");?><br/>
+ &nbsp;&nbsp;<img src="../themes/<?= $g['theme']; ?>/images/icons/icon_import_alias.gif" width="17" height="17" border="0" />
+ &nbsp;<?=gettext("Opens the file upload control for uploading a new IP List from your local machine.");?><br/>
+ &nbsp;&nbsp;<img src="../themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0" />
+ &nbsp;<?=gettext("Opens the IP List in a text edit control for viewing or editing its contents.");?><br/>
+ &nbsp;&nbsp;<img src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" />
+ &nbsp;<?=gettext("Deletes the IP List from the file system after confirmation.");?></td>
+ <td class="list"></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <?php endif; ?>
+ </tbody>
+ </table>
+ </div>
+ </td>
+</tr>
+</tbody>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+
+<script language="JavaScript">
+<!--
+
+function IQRisk_enablechange() {
+ var endis = !(document.iform.et_iqrisk_enable.checked);
+ if (endis)
+ document.getElementById("iqrisk_code_tbl").style.display = "none";
+ else
+ document.getElementById("iqrisk_code_tbl").style.display = "table";
+}
+
+// Initialize the form controls state based on saved settings
+IQRisk_enablechange();
+
+//-->
+</script>
+</body>
+</html>
diff --git a/config/suricata/suricata_ip_reputation.php b/config/suricata/suricata_ip_reputation.php
new file mode 100644
index 00000000..4615923a
--- /dev/null
+++ b/config/suricata/suricata_ip_reputation.php
@@ -0,0 +1,482 @@
+<?php
+/*
+ * suricata_ip_reputation.php
+ * part of pfSense
+ *
+ * Copyright (C) 2014 Bill Meeks
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+require_once("guiconfig.inc");
+require_once("/usr/local/pkg/suricata/suricata.inc");
+
+global $g, $rebuild_rules;
+
+if (isset($_POST['id']) && is_numericint($_POST['id']))
+ $id = $_POST['id'];
+elseif (isset($_GET['id']) && is_numericint($_GET['id']))
+ $id = htmlspecialchars($_GET['id']);
+
+if (is_null($id)) {
+ header("Location: /suricata/suricata_interfaces.php");
+ exit;
+}
+
+if (!is_array($config['installedpackages']['suricata']['rule'])) {
+ $config['installedpackages']['suricata']['rule'] = array();
+}
+if (!is_array($config['installedpackages']['suricata']['rule'][$id]['iplist_files']['item'])) {
+ $config['installedpackages']['suricata']['rule'][$id]['iplist_files']['item'] = array();
+}
+
+$a_nat = &$config['installedpackages']['suricata']['rule'];
+
+// If doing a postback, used typed values, else load from stored config
+if (!empty($_POST)) {
+ $pconfig = $_POST;
+}
+else {
+ $pconfig = $a_nat[$id];
+}
+
+$iprep_path = SURICATA_IPREP_PATH;
+$if_real = get_real_interface($a_nat[$id]['interface']);
+$suricata_uuid = $config['installedpackages']['suricata']['rule'][$id]['uuid'];
+
+if ($_POST['mode'] == 'iprep_catlist_add' && isset($_POST['iplist'])) {
+ $pconfig = $_POST;
+
+ // Test the supplied IP List file to see if it exists
+ if (file_exists($_POST['iplist'])) {
+ if (!$input_errors) {
+ $a_nat[$id]['iprep_catlist'] = basename($_POST['iplist']);
+ write_config("Suricata pkg: added new IP Rep Categories file for IP REPUTATION preprocessor.");
+ mark_subsystem_dirty('suricata_iprep');
+ }
+ }
+ else
+ $input_errors[] = gettext("The file '{$_POST['iplist']}' could not be found.");
+
+ $pconfig['iprep_catlist'] = $a_nat[$id]['iprep_catlist'];
+ $pconfig['iplist_files'] = $a_nat[$id]['iplist_files'];
+}
+
+if ($_POST['mode'] == 'iplist_add' && isset($_POST['iplist'])) {
+ $pconfig = $_POST;
+
+ // Test the supplied IP List file to see if it exists
+ if (file_exists($_POST['iplist'])) {
+ // See if the file is already assigned to the interface
+ foreach ($a_nat[$id]['iplist_files']['item'] as $f) {
+ if ($f == basename($_POST['iplist'])) {
+ $input_errors[] = gettext("The file {$f} is already assigned as a whitelist file.");
+ break;
+ }
+ }
+ if (!$input_errors) {
+ $a_nat[$id]['iplist_files']['item'][] = basename($_POST['iplist']);
+ write_config("Suricata pkg: added new whitelist file for IP REPUTATION preprocessor.");
+ mark_subsystem_dirty('suricata_iprep');
+ }
+ }
+ else
+ $input_errors[] = gettext("The file '{$_POST['iplist']}' could not be found.");
+
+ $pconfig['iprep_catlist'] = $a_nat[$id]['iprep_catlist'];
+ $pconfig['iplist_files'] = $a_nat[$id]['iplist_files'];
+}
+
+if ($_POST['iprep_catlist_del']) {
+ $pconfig = $_POST;
+ unset($a_nat[$id]['iprep_catlist']);
+ write_config("Suricata pkg: deleted blacklist file for IP REPUTATION preprocessor.");
+ mark_subsystem_dirty('suricata_iprep');
+ $pconfig['iprep_catlist'] = $a_nat[$id]['iprep_catlist'];
+ $pconfig['iplist_files'] = $a_nat[$id]['iplist_files'];
+}
+
+if ($_POST['iplist_del'] && is_numericint($_POST['list_id'])) {
+ $pconfig = $_POST;
+ unset($a_nat[$id]['iplist_files']['item'][$_POST['list_id']]);
+ write_config("Suricata pkg: deleted whitelist file for IP REPUTATION preprocessor.");
+ mark_subsystem_dirty('suricata_iprep');
+ $pconfig['iplist_files'] = $a_nat[$id]['iplist_files'];
+ $pconfig['iprep_catlist'] = $a_nat[$id]['iprep_catlist'];
+}
+
+if ($_POST['save'] || $_POST['apply']) {
+
+ $pconfig['iprep_catlist'] = $a_nat[$id]['iprep_catlist'];
+ $pconfig['iplist_files'] = $a_nat[$id]['iplist_files'];
+
+ // Validate HOST TABLE values
+ if ($_POST['host_memcap'] < 1000000 || !is_numericint($_POST['host_memcap']))
+ $input_errors[] = gettext("The value for 'Host Memcap' must be a numeric integer greater than 1MB (1,048,576!");
+ if ($_POST['host_hash_size'] < 1024 || !is_numericint($_POST['host_hash_size']))
+ $input_errors[] = gettext("The value for 'Host Hash Size' must be a numeric integer greater than 1024!");
+ if ($_POST['host_prealloc'] < 10 || !is_numericint($_POST['host_prealloc']))
+ $input_errors[] = gettext("The value for 'Host Preallocations' must be a numeric integer greater than 10!");
+
+ // Validate CATEGORIES FILE
+ if ($_POST['enable_iprep'] == 'on') {
+ if (empty($a_nat[$id]['iprep_catlist']))
+ $input_errors[] = gettext("Assignment of a 'Categories File' is required when IP Reputation is enabled!");
+ }
+
+ // If no errors write to conf
+ if (!$input_errors) {
+
+ $a_nat[$id]['enable_iprep'] = $_POST['enable_iprep'] ? 'on' : 'off';
+ $a_nat[$id]['host_memcap'] = str_replace(",", "", $_POST['host_memcap']);
+ $a_nat[$id]['host_hash_size'] = str_replace(",", "", $_POST['host_hash_size']);
+ $a_nat[$id]['host_prealloc'] = str_replace(",", "", $_POST['host_prealloc']);
+
+ write_config("Suricata pkg: modified IP REPUTATION preprocessor settings for {$a_nat[$id]['interface']}.");
+
+ // Update the suricata conf file for this interface
+ $rebuild_rules = false;
+ conf_mount_rw();
+ suricata_generate_yaml($a_nat[$id]);
+ conf_mount_ro();
+
+ // Soft-restart Suricata to live-load new variables
+ suricata_reload_config($a_nat[$id]);
+
+ // We have saved changes and done a soft restart, so clear "dirty" flag
+ clear_subsystem_dirty('suricata_iprep');
+ }
+}
+
+$if_friendly = convert_friendly_interface_to_friendly_descr($a_nat[$id]['interface']);
+$pgtitle = gettext("Suricata: Interface {$if_friendly} IP Reputation Preprocessor");
+include_once("head.inc");
+
+?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+
+<?php
+include("fbegin.inc");
+/* Display Alert message */
+if ($input_errors)
+ print_input_errors($input_errors);
+if ($savemsg)
+ print_info_box($savemsg);
+?>
+
+<form action="suricata_ip_reputation.php" method="post" name="iform" id="iform" >
+<input name="id" type="hidden" value="<?=$id;?>" />
+<input type="hidden" id="mode" name="mode" value="" />
+<input name="iplist" id="iplist" type="hidden" value="" />
+<input name="list_id" id="list_id" type="hidden" value="" />
+
+<?php if (is_subsystem_dirty('suricata_iprep') && !$input_errors): ?><p>
+<?php print_info_box_np(gettext("A change has been made to IP List file assignments.") . "<br/>" . gettext("You must apply the change in order for it to take effect."));?>
+<?php endif; ?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <td>
+ <?php
+ $tab_array = array();
+ $tab_array[] = array(gettext("Interfaces"), true, "/suricata/suricata_interfaces.php");
+ $tab_array[] = array(gettext("Global Settings"), false, "/suricata/suricata_global.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php?instance={$id}");
+ $tab_array[] = array(gettext("Blocks"), false, "/suricata/suricata_blocked.php");
+ $tab_array[] = array(gettext("Pass Lists"), false, "/suricata/suricata_passlist.php");
+ $tab_array[] = array(gettext("Suppress"), false, "/suricata/suricata_suppress.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
+ $tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
+ $tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
+ display_top_tabs($tab_array, true);
+ echo '</td></tr>';
+ echo '<tr><td class="tabnavtbl">';
+ $tab_array = array();
+ $menu_iface=($if_friendly?substr($if_friendly,0,5)." ":"Iface ");
+ $tab_array[] = array($menu_iface . gettext("Settings"), false, "/suricata/suricata_interfaces_edit.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("Categories"), false, "/suricata/suricata_rulesets.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("Rules"), false, "/suricata/suricata_rules.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("Flow/Stream"), false, "/suricata/suricata_flow_stream.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("App Parsers"), false, "/suricata/suricata_app_parsers.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("Variables"), false, "/suricata/suricata_define_vars.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("Barnyard2"), false, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), true, "/suricata/suricata_ip_reputation.php?id={$id}");
+ display_top_tabs($tab_array, true);
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <td><div id="mainarea">
+ <table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
+ <?php if ($g['platform'] == "nanobsd") : ?>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("IP Reputation is not supported on NanoBSD installs"); ?></td>
+ </tr>
+ <?php else: ?>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("IP Reputation Configuration"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign='top' class='vncell'><?php echo gettext("Enable"); ?>
+ </td>
+ <td width="78%" class="vtable"><input name="enable_iprep" type="checkbox" value="on" <?php if ($pconfig['enable_iprep'] == "on") echo "checked"; ?>/>
+ <?php echo gettext("Use IP Reputation Lists on this interface. Default is ") . "<strong>" . gettext("Not Checked.") . "</strong>"; ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Host Memcap"); ?></td>
+ <td width="78%" class="vtable"><input name="host_memcap" type="text"
+ class="formfld unknown" id="host_memcap" size="8" value="<?=htmlspecialchars($pconfig['host_memcap']); ?>"/>&nbsp;
+ <?php echo gettext("Host table memory cap in bytes. Default is ") . "<strong>" .
+ gettext("16777216") . "</strong>" . gettext(" (16 MB). Min value is 1048576 (1 MB)."); ?><br/><br/><?php echo gettext("When using large IP Reputation Lists, this value may need to be increased " .
+ "to avoid exhausting Host Table memory.") ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Host Hash Size"); ?></td>
+ <td width="78%" class="vtable"><input name="host_hash_size" type="text"
+ class="formfld unknown" id="host_hash_size" size="8" value="<?=htmlspecialchars($pconfig['host_hash_size']); ?>"/>&nbsp;
+ <?php echo gettext("Host Hash Size in bytes. Default is ") . "<strong>" .
+ gettext("4096") . "</strong>" . gettext(". Min value is 1024."); ?><br/><br/><?php echo gettext("When using large IP Reputation Lists, this value may need to be increased."); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Host Preallocations"); ?></td>
+ <td width="78%" class="vtable"><input name="host_prealloc" type="text"
+ class="formfld unknown" id="host_prealloc" size="8" value="<?=htmlspecialchars($pconfig['host_prealloc']); ?>"/>&nbsp;
+ <?php echo gettext("Number of Host Table entries to preallocate. Default is ") . "<strong>" .
+ gettext("1000") . "</strong>" . gettext(". Min value is 10."); ?><br/><br/><?php echo gettext("Increasing this value may slightly improve performance when using large IP Reputation Lists."); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input name="save" type="submit" class="formbtn" value="Save" title="<?=gettext("Save IP Reputation configuration");?>" />
+ &nbsp;&nbsp;<?=gettext("Click to save configuration settings and live-reload the running Suricata configuration.");?>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Assign Categories File"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign='top' class='vncell'><?php echo gettext("Categories File"); ?>
+ </td>
+ <td width="78%" class="vtable">
+ <!-- iprep_catlist_chooser -->
+ <div id="iprep_catlistChooser" name="iprep_catlistChooser" style="display:none; border:1px dashed gray; width:98%;"></div>
+ <table width="95%" border="0" cellpadding="2" cellspacing="0">
+ <colgroup>
+ <col style="text-align:left;">
+ <col style="width: 30%; text-align:left;">
+ <col style="width: 17px;">
+ </colgroup>
+ <thead>
+ <tr>
+ <th class="listhdrr"><?php echo gettext("Categories Filename"); ?></th>
+ <th class="listhdrr"><?php echo gettext("Modification Time"); ?></th>
+ <th class="list" align="left" valign="middle"><img style="cursor:pointer;" name="iprep_catlist_add" id="iprep_catlist_add"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17"
+ height="17" border="0" title="<?php echo gettext('Assign a Categories file');?>"/></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php if (!empty($pconfig['iprep_catlist'])) :
+ $class = "listr";
+ if (!file_exists("{$iprep_path}{$pconfig['iprep_catlist']}")) {
+ $filedate = gettext("Unknown -- file missing");
+ $class .= " red";
+ }
+ else
+ $filedate = date('M-d Y g:i a', filemtime("{$iprep_path}{$pconfig['iprep_catlist']}"));
+ ?>
+ <tr>
+ <td class="<?=$class;?>"><?=htmlspecialchars($pconfig['iprep_catlist']);?></td>
+ <td class="<?=$class;?>" align="center"><?=$filedate;?></td>
+ <td class="list"><input type="image" name="iprep_catlist_del[]" id="iprep_catlist_del[]" onClick="document.getElementById('list_id').value='0';"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17"
+ border="0" title="<?php echo gettext('Remove this Categories file');?>"/></td>
+ </tr>
+ <?php endif; ?>
+ <tr>
+ <td colspan="2" class="vexpl"><span class="red"><strong><?=gettext("Note: ");?></strong></span>
+ <?=gettext("change to Categories File assignment is immediately saved.");?></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Assign IP Reputation Lists"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign='top' class='vncell'><?php echo gettext("IP Reputation Files"); ?>
+ </td>
+ <td width="78%" class="vtable">
+ <table width="95%" border="0" cellpadding="2" cellspacing="0">
+ <!-- iplist_chooser -->
+ <div id="iplistChooser" name="iplistChooser" style="display:none; border:1px dashed gray; width:98%;"></div>
+ <colgroup>
+ <col style="text-align:left;">
+ <col style="width: 30%; text-align:left;">
+ <col style="width: 17px;">
+ </colgroup>
+ <thead>
+ <tr>
+ <th class="listhdrr"><?php echo gettext("IP Reputation List Filename"); ?></th>
+ <th class="listhdrr"><?php echo gettext("Modification Time"); ?></th>
+ <th class="list" align="left" valign="middle"><img style="cursor:pointer;" name="iplist_add" id="iplist_add"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17" height="17"
+ border="0" title="<?php echo gettext('Assign a whitelist file');?>"/></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php foreach($pconfig['iplist_files']['item'] as $k => $f):
+ $class = "listr";
+ if (!file_exists("{$iprep_path}{$f}")) {
+ $filedate = gettext("Unknown -- file missing");
+ $class .= " red";
+ }
+ else
+ $filedate = date('M-d Y g:i a', filemtime("{$iprep_path}{$f}"));
+ ?>
+ <tr>
+ <td class="<?=$class;?>"><?=htmlspecialchars($f);?></td>
+ <td class="<?=$class;?>" align="center"><?=$filedate;?></td>
+ <td class="list"><input type="image" name="iplist_del[]" id="iplist_del[]" onClick="document.getElementById('list_id').value='<?=$k;?>';"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17"
+ border="0" title="<?php echo gettext('Remove this whitelist file');?>"/></td>
+ </tr>
+ <?php endforeach; ?>
+ <tr>
+ <td colspan="2" class="vexpl"><span class="red"><strong><?=gettext("Note: ");?></strong></span>
+ <?=gettext("changes to IP Reputation List assignments are immediately saved.");?></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <?php endif; ?>
+ </tbody>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<?php if ($g['platform'] != "nanobsd") : ?>
+<script type="text/javascript">
+Event.observe(
+ window, "load",
+ function() {
+ Event.observe(
+ "iprep_catlist_add", "click",
+ function() {
+ Effect.Appear("iprep_catlistChooser", { duration: 0.25 });
+ iprep_catlistChoose();
+ }
+ );
+
+ Event.observe(
+ "iplist_add", "click",
+ function() {
+ Effect.Appear("iplistChooser", { duration: 0.25 });
+ iplistChoose();
+ }
+ );
+ }
+);
+
+function iprep_catlistChoose() {
+ Effect.Appear("iprep_catlistChooser", { duration: 0.25 });
+ if($("fbCurrentDir"))
+ $("fbCurrentDir").innerHTML = "Loading ...";
+
+ new Ajax.Request(
+ "/suricata/suricata_iprep_list_browser.php?container=iprep_catlistChooser&target=iplist&val=" + new Date().getTime(),
+ { method: "get", onComplete: iprep_catlistComplete }
+ );
+}
+
+function iplistChoose() {
+ Effect.Appear("iplistChooser", { duration: 0.25 });
+ if($("fbCurrentDir"))
+ $("fbCurrentDir").innerHTML = "Loading ...";
+
+ new Ajax.Request(
+ "/suricata/suricata_iprep_list_browser.php?container=iplistChooser&target=iplist&val=" + new Date().getTime(),
+ { method: "get", onComplete: iplistComplete }
+ );
+}
+
+function iprep_catlistComplete(req) {
+ $("iprep_catlistChooser").innerHTML = req.responseText;
+
+ var actions = {
+ fbClose: function() { $("iprep_catlistChooser").hide(); },
+ fbFile: function() { $("iplist").value = this.id;
+ $("mode").value = 'iprep_catlist_add';
+ document.getElementById('iform').submit();
+ }
+ }
+
+ for(var type in actions) {
+ var elem = $("iprep_catlistChooser");
+ var list = elem.getElementsByClassName(type);
+ for (var i=0; i<list.length; i++) {
+ Event.observe(list[i], "click", actions[type]);
+ list[i].style.cursor = "pointer";
+ }
+ }
+}
+
+function iplistComplete(req) {
+ $("iplistChooser").innerHTML = req.responseText;
+
+ var actions = {
+ fbClose: function() { $("iplistChooser").hide(); },
+ fbFile: function() { $("iplist").value = this.id;
+ $("mode").value = 'iplist_add';
+ document.getElementById('iform').submit();
+ }
+ }
+
+ for(var type in actions) {
+ var elem = $("iplistChooser");
+ var list = elem.getElementsByClassName(type);
+ for (var i=0; i<list.length; i++) {
+ Event.observe(list[i], "click", actions[type]);
+ list[i].style.cursor = "pointer";
+ }
+ }
+}
+
+</script>
+<?php endif; ?>
+
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/config/suricata/suricata_iprep_list_browser.php b/config/suricata/suricata_iprep_list_browser.php
new file mode 100644
index 00000000..9dd65311
--- /dev/null
+++ b/config/suricata/suricata_iprep_list_browser.php
@@ -0,0 +1,99 @@
+<?php
+
+require_once("guiconfig.inc");
+require_once("/usr/local/pkg/suricata/suricata.inc");
+
+// Fetch a list of files inside a given directory
+function get_content($dir) {
+ $files = array();
+
+ clearstatcache();
+ $fd = @opendir($dir);
+ while($entry = @readdir($fd)) {
+ if($entry == ".") continue;
+ if($entry == "..") continue;
+
+ if(is_dir("{$dir}/{$entry}"))
+ continue;
+ else
+ array_push($files, $entry);
+ }
+ @closedir($fd);
+ natsort($files);
+ return $files;
+}
+
+$path = SURICATA_IPREP_PATH;
+$container = htmlspecialchars($_GET['container']);
+$target = htmlspecialchars($_GET['target']);
+
+// ----- header -----
+?>
+<table width="100%">
+ <tr>
+ <td width="25px" align="left">
+ <img src="/filebrowser/images/icon_home.gif" alt="Home" title="Home" />
+ </td>
+ <td><b><?=$path;?></b></td>
+ <td class="fbClose" align="right">
+ <img onClick="$('<?=$container;?>').hide();" border="0" src="/filebrowser/images/icon_cancel.gif" alt="Close" title="Close" />
+ </td>
+ </tr>
+ <tr>
+ <td id="fbCurrentDir" colspan="3" class="vexpl" align="left">
+ </td>
+ </tr>
+<?php
+$files = get_content($path);
+
+// ----- files -----
+foreach($files as $file):
+ $ext = strrchr($file, ".");
+
+ if($ext == ".css" ) $type = "code";
+ elseif($ext == ".html") $type = "code";
+ elseif($ext == ".xml" ) $type = "code";
+ elseif($ext == ".rrd" ) $type = "database";
+ elseif($ext == ".gif" ) $type = "image";
+ elseif($ext == ".jpg" ) $type = "image";
+ elseif($ext == ".png" ) $type = "image";
+ elseif($ext == ".js" ) $type = "js";
+ elseif($ext == ".pdf" ) $type = "pdf";
+ elseif($ext == ".inc" ) $type = "php";
+ elseif($ext == ".php" ) $type = "php";
+ elseif($ext == ".conf") $type = "system";
+ elseif($ext == ".pid" ) $type = "system";
+ elseif($ext == ".sh" ) $type = "system";
+ elseif($ext == ".bz2" ) $type = "zip";
+ elseif($ext == ".gz" ) $type = "zip";
+ elseif($ext == ".tgz" ) $type = "zip";
+ elseif($ext == ".zip" ) $type = "zip";
+ else $type = "generic";
+
+ $fqpn = "{$path}/{$file}";
+
+ if(is_file($fqpn)) {
+ $fqpn = realpath($fqpn);
+ $size = sprintf("%.2f KiB", filesize($fqpn) / 1024);
+ }
+ else
+ $size = "";
+?>
+ <tr>
+ <td></td>
+ <td class="fbFile vexpl" id="<?=$fqpn;?>" align="left">
+ <?php $filename = str_replace("//","/", "{$path}/{$file}"); ?>
+ <div onClick="$('<?=$target;?>').value='<?=$filename?>'; $('<?=$container;?>').hide();">
+ <img src="/filebrowser/images/file_<?=$type;?>.gif" alt="" title="">
+ &nbsp;<?=$file;?>
+ </div>
+ </td>
+ <td align="right" class="vexpl">
+ <?=$size;?>
+ </td>
+ </tr>
+<?php
+endforeach;
+?>
+</table>
+
diff --git a/config/suricata/suricata_logs_browser.php b/config/suricata/suricata_logs_browser.php
index d4475625..320ba23f 100644
--- a/config/suricata/suricata_logs_browser.php
+++ b/config/suricata/suricata_logs_browser.php
@@ -151,6 +151,7 @@ if ($input_errors) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td>
diff --git a/config/suricata/suricata_logs_mgmt.php b/config/suricata/suricata_logs_mgmt.php
index fec2d149..aa353d6f 100644
--- a/config/suricata/suricata_logs_mgmt.php
+++ b/config/suricata/suricata_logs_mgmt.php
@@ -173,7 +173,9 @@ if ($_POST["save"] || $_POST['apply']) {
if ($_POST['enable_log_mgmt'] != 'on') {
$config['installedpackages']['suricata']['config'][0]['enable_log_mgmt'] = $_POST['enable_log_mgmt'] ? 'on' :'off';
write_config("Suricata pkg: saved updated configuration for LOGS MGMT.");
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
/* forces page to reload new settings */
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
@@ -222,7 +224,9 @@ if ($_POST["save"] || $_POST['apply']) {
$config['installedpackages']['suricata']['config'][0]['sid_changes_log_retention'] = $_POST['sid_changes_log_retention'];
write_config("Suricata pkg: saved updated configuration for LOGS MGMT.");
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
/* forces page to reload new settings */
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
@@ -274,6 +278,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), true, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_migrate_config.php b/config/suricata/suricata_migrate_config.php
index 4729109b..75e13315 100644
--- a/config/suricata/suricata_migrate_config.php
+++ b/config/suricata/suricata_migrate_config.php
@@ -71,12 +71,28 @@ if ($config['installedpackages']['suricata']['config'][0]['suricata_config_ver']
/**********************************************************/
/* Create new Auto SID Mgmt settings if not set */
/**********************************************************/
- if (empty($config['installedpackages']['suricata']['config'][0]['auto_manage_sids'])) {
- $config['installedpackages']['suricata']['config'][0]['auto_manage_sids'] = "off";
- $config['installedpackages']['suricata']['config'][0]['sid_changes_log_limit_size'] = "250";
- $config['installedpackages']['suricata']['config'][0]['sid_changes_log_retention'] = "336";
- $updated_cfg = true;
- }
+if (empty($config['installedpackages']['suricata']['config'][0]['auto_manage_sids'])) {
+ $config['installedpackages']['suricata']['config'][0]['auto_manage_sids'] = "off";
+ $config['installedpackages']['suricata']['config'][0]['sid_changes_log_limit_size'] = "250";
+ $config['installedpackages']['suricata']['config'][0]['sid_changes_log_retention'] = "336";
+ $updated_cfg = true;
+}
+
+/**********************************************************/
+/* Create new Auto GeoIP update setting if not set */
+/**********************************************************/
+if (empty($config['installedpackages']['suricata']['config'][0]['autogeoipupdate'])) {
+ $config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] = "on";
+ $updated_cfg = true;
+}
+
+/**********************************************************/
+/* Create new ET IQRisk IP Reputation setting if not set */
+/**********************************************************/
+if (empty($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'])) {
+ $config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] = "off";
+ $updated_cfg = true;
+}
// Now process the interface-specific settings
foreach ($rule as &$r) {
@@ -336,6 +352,26 @@ foreach ($rule as &$r) {
$updated_cfg = true;
}
+ /**********************************************************/
+ /* Create interface IP Reputation settings if not set */
+ /**********************************************************/
+ if (empty($pconfig['enable_iprep'])) {
+ $pconfig['enable_iprep'] = "off";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['host_memcap'])) {
+ $pconfig['host_memcap'] = "16777216";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['host_hash_size'])) {
+ $pconfig['host_hash_size'] = "4096";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['host_prealloc'])) {
+ $pconfig['host_prealloc'] = "1000";
+ $updated_cfg = true;
+ }
+
// Save the new configuration data into the $config array pointer
$r = $pconfig;
}
@@ -343,12 +379,8 @@ foreach ($rule as &$r) {
unset($r);
// Write out the new configuration to disk if we changed anything
-if ($updated_cfg) {
- $config['installedpackages']['suricata']['config'][0]['suricata_config_ver'] = "2.0.2";
- log_error("[Suricata] Saving configuration settings in new format...");
- write_config("Suricata pkg: migrate existing settings to new format during package upgrade.");
+if ($updated_cfg)
log_error("[Suricata] Settings successfully migrated to new configuration format...");
-}
else
log_error("[Suricata] Configuration version is current...");
diff --git a/config/suricata/suricata_passlist.php b/config/suricata/suricata_passlist.php
index 02aa4a3d..af1c4ff5 100644
--- a/config/suricata/suricata_passlist.php
+++ b/config/suricata/suricata_passlist.php
@@ -87,7 +87,9 @@ if ($_POST['del'] && is_numericint($_POST['list_id'])) {
if (!$input_errors) {
unset($a_passlist[$_POST['list_id']]);
write_config("Suricata pkg: deleted PASS LIST.");
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
header("Location: /suricata/suricata_passlist.php");
exit;
}
@@ -130,6 +132,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td>
diff --git a/config/suricata/suricata_passlist_edit.php b/config/suricata/suricata_passlist_edit.php
index 3e1502f3..5bfeb8b9 100644
--- a/config/suricata/suricata_passlist_edit.php
+++ b/config/suricata/suricata_passlist_edit.php
@@ -182,7 +182,9 @@ if ($_POST['save']) {
write_config("Suricata pkg: modified PASS LIST {$p_list['name']}.");
/* create pass list and homenet file, then sync files */
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
header("Location: /suricata/suricata_passlist.php");
exit;
@@ -224,6 +226,7 @@ if ($savemsg)
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td>
diff --git a/config/suricata/suricata_post_install.php b/config/suricata/suricata_post_install.php
index 42f72eca..070cf095 100644
--- a/config/suricata/suricata_post_install.php
+++ b/config/suricata/suricata_post_install.php
@@ -48,36 +48,36 @@
require_once("config.inc");
require_once("functions.inc");
require_once("/usr/local/pkg/suricata/suricata.inc");
+require("/usr/local/pkg/suricata/suricata_defs.inc");
global $config, $g, $rebuild_rules, $pkg_interface, $suricata_gui_include;
/****************************************
* Define any new constants here that *
* may not be yet defined in the old *
- * "suricata.inc" include file that *
- * might be cached and used by the *
- * package manager installation code. *
+ * "suricata_defs.inc" include file *
+ * that might be cached and used by *
+ * the package manager installation *
+ * code. *
* *
* This is a hack to work around the *
- * fact the old version of suricata.inc *
+ * fact the old version of the inc file *
* is cached and used instead of the *
- * updated version icluded with the *
+ * updated version included with the *
* updated GUI package. *
****************************************/
-if (!defined('SID_MODS_PATH'))
- define('SID_MODS_PATH', '/var/db/suricata/sidmods/');
-if (!defined('IPREP_PATH'))
- define('IPREP_PATH', '/var/db/suricata/iprep/');
+if (!defined('SURICATA_PBI_BASEDIR'))
+ define('SURICATA_PBI_BASEDIR', '/usr/pbi/suricata-' . php_uname("m"));
/****************************************
- * End of PHP cachine workaround *
+ * End of PHP caching workaround *
****************************************/
// Initialize some common values from defined constants
$suricatadir = SURICATADIR;
$suricatalogdir = SURICATALOGDIR;
$flowbit_rules_file = FLOWBITS_FILENAME;
-$suricata_enforcing_rules_file = ENFORCING_RULES_FILENAME;
+$suricata_enforcing_rules_file = SURICATA_ENFORCING_RULES_FILENAME;
$rcdir = RCFILEPREFIX;
// Hard kill any running Suricata process that may have been started by any
@@ -103,14 +103,32 @@ $g['suricata_postinstall'] = true;
conf_mount_rw();
// Remove any previously installed script since we rebuild it
-@unlink("{$rcdir}suricata.sh");
+unlink_if_exists("{$rcdir}suricata.sh");
// Create the top-tier log directory
safe_mkdir(SURICATALOGDIR);
// Create the IP Rep and SID Mods lists directory
-safe_mkdir(SID_MODS_PATH);
-safe_mkdir(IPREP_PATH);
+safe_mkdir(SURICATA_SID_MODS_PATH);
+safe_mkdir(SURICATA_IPREP_PATH);
+
+// Make sure config variable is an array
+if (!is_array($config['installedpackages']['suricata']['config'][0]))
+ $config['installedpackages']['suricata']['config'][0] = array();
+
+// Download the latest GeoIP DB updates and create cron task if the feature is not disabled
+if ($config['installedpackages']['suricata']['config'][0]['autogeoipupdate'] != 'off') {
+ log_error(gettext("[Suricata] Installing free GeoIP country database files..."));
+ include("/usr/local/pkg/suricata/suricata_geoipupdate.php");
+ install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_geoipupdate.php", TRUE, 0, 0, 8, "*", "*", "root");
+}
+
+// Download the latest ET IQRisk updates and create cron task if the feature is not disabled
+if ($config['installedpackages']['suricata']['config'][0]['et_iqrisk_enable'] == 'on') {
+ log_error(gettext("[Suricata] Installing Emerging Threats IQRisk IP List..."));
+ include("/usr/local/pkg/suricata/suricata_etiqrisk_update.php");
+ install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_etiqrisk_update.php", TRUE, 0, "*/6", "*", "*", "*", "root");
+}
// remake saved settings if previously flagged
if ($config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] == 'on') {
@@ -149,7 +167,6 @@ if ($config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] =
log_error(gettext("[Suricata] updated UUID for interface " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) . " from {$old_uuid} to {$new_uuid}."));
}
}
- write_config("Suricata pkg: updated interface UUIDs to eliminate duplicates.");
unset($uuids, $rulesets);
}
/****************************************************************/
@@ -167,6 +184,7 @@ if ($config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] =
include('/usr/local/pkg/suricata/suricata_check_for_rule_updates.php');
update_status(gettext("Generating suricata.yaml configuration file from saved settings..."));
$rebuild_rules = true;
+ conf_mount_rw();
// Create the suricata.yaml files for each enabled interface
$suriconf = $config['installedpackages']['suricata']['rule'];
@@ -174,6 +192,7 @@ if ($config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] =
$if_real = get_real_interface($suricatacfg['interface']);
$suricata_uuid = $suricatacfg['uuid'];
$suricatacfgdir = "{$suricatadir}suricata_{$suricata_uuid}_{$if_real}";
+ update_output_window(gettext("Generating configuration for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) . "..."));
// Pull in the PHP code that generates the suricata.yaml file
// variables that will be substituted further down below.
@@ -202,9 +221,6 @@ if ($config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] =
suricata_rm_blocked_install_cron($config['installedpackages']['suricata']['config'][0]['rm_blocked'] != "never_b" ? true : false);
suricata_rules_up_install_cron($config['installedpackages']['suricata']['config'][0]['autoruleupdate'] != "never_up" ? true : false);
- // Add the recurring jobs created above to crontab
- configure_cron();
-
// Restore the Dashboard Widget if it was previously enabled and saved
if (!empty($config['installedpackages']['suricata']['config'][0]['dashboard_widget']) && !empty($config['widgets']['sequence'])) {
if (strpos($config['widgets']['sequence'], "suricata_alerts-container") === FALSE)
@@ -216,16 +232,20 @@ if ($config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] =
}
$rebuild_rules = false;
- update_output_window(gettext("Finished rebuilding Suricata configuration files..."));
+ if ($pkg_interface <> "console")
+ update_output_window(gettext("Finished rebuilding Suricata configuration files..."));
log_error(gettext("[Suricata] Finished rebuilding installation from saved settings..."));
// Only try to start Suricata if not in reboot
if (!$g['booting']) {
- update_status(gettext("Starting Suricata using rebuilt configuration..."));
- update_output_window(gettext("Please wait... while Suricata is started..."));
- log_error(gettext("[Suricata] Starting Suricata using rebuilt configuration..."));
- mwexec_bg("{$rcdir}suricata.sh start");
- update_output_window(gettext("Suricata has been started using the rebuilt configuration..."));
+ if ($pkg_interface <> "console") {
+ update_status(gettext("Starting Suricata using rebuilt configuration..."));
+ update_output_window(gettext("Please wait while Suricata is started..."));
+ mwexec("{$rcdir}suricata.sh start");
+ update_output_window(gettext("Suricata has been started using the rebuilt configuration..."));
+ }
+ else
+ mwexec_bg("{$rcdir}suricata.sh start");
}
}
@@ -238,8 +258,8 @@ if (empty($config['installedpackages']['suricata']['config'][0]['forcekeepsettin
conf_mount_ro();
// Update Suricata package version in configuration
-$config['installedpackages']['suricata']['config'][0]['suricata_config_ver'] = "2.0.2";
-write_config("Suricata pkg: updated GUI package version number.");
+$config['installedpackages']['suricata']['config'][0]['suricata_config_ver'] = "2.1.2";
+write_config("Suricata pkg v2.1.2: post-install configuration saved.");
// Done with post-install, so clear flag
unset($g['suricata_postinstall']);
diff --git a/config/suricata/suricata_rules.php b/config/suricata/suricata_rules.php
index 539a1daf..480bf3dc 100644
--- a/config/suricata/suricata_rules.php
+++ b/config/suricata/suricata_rules.php
@@ -473,6 +473,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
echo '</td></tr>';
echo '<tr><td class="tabnavtbl">';
@@ -485,6 +486,7 @@ if ($savemsg) {
$tab_array[] = array($menu_iface . gettext("App Parsers"), false, "/suricata/suricata_app_parsers.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Variables"), false, "/suricata/suricata_define_vars.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Barnyard2"), false, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), false, "/suricata/suricata_ip_reputation.php?id={$id}");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_rules_flowbits.php b/config/suricata/suricata_rules_flowbits.php
index b16353cb..1bb945d8 100644
--- a/config/suricata/suricata_rules_flowbits.php
+++ b/config/suricata/suricata_rules_flowbits.php
@@ -139,7 +139,9 @@ if ($_POST['addsuppress'] && is_numeric($_POST['sid']) && is_numeric($_POST['gid
if ($found_list) {
write_config();
$rebuild_rules = false;
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
suricata_reload_config($a_nat[$id]);
$savemsg = gettext("An entry to suppress the Alert for 'gen_id {$_POST['gid']}, sig_id {$_POST['sid']}' has been added to Suppress List '{$a_nat[$id]['suppresslistname']}'.");
}
diff --git a/config/suricata/suricata_rulesets.php b/config/suricata/suricata_rulesets.php
index 7ea672b1..7f591b6c 100644
--- a/config/suricata/suricata_rulesets.php
+++ b/config/suricata/suricata_rulesets.php
@@ -142,8 +142,7 @@ if ($_POST["save"]) {
$a_nat[$id]['autoflowbitrules'] = 'on';
else {
$a_nat[$id]['autoflowbitrules'] = 'off';
- if (file_exists("{$suricatadir}suricata_{$suricata_uuid}_{$if_real}/rules/{$flowbit_rules_file}"))
- @unlink("{$suricatadir}suricata_{$suricata_uuid}_{$if_real}/rules/{$flowbit_rules_file}");
+ unlink_if_exists("{$suricatadir}suricata_{$suricata_uuid}_{$if_real}/rules/{$flowbit_rules_file}");
}
write_config("Suricata pkg: save enabled rule categories for {$a_nat[$id]['interface']}.");
@@ -170,17 +169,43 @@ if ($_POST["save"]) {
suricata_sync_on_changes();
}
elseif ($_POST['unselectall']) {
+ if ($_POST['ips_policy_enable'] == "on") {
+ $a_nat[$id]['ips_policy_enable'] = 'on';
+ $a_nat[$id]['ips_policy'] = $_POST['ips_policy'];
+ }
+ else {
+ $a_nat[$id]['ips_policy_enable'] = 'off';
+ unset($a_nat[$id]['ips_policy']);
+ }
+
+ $pconfig['autoflowbits'] = $_POST['autoflowbits'];
+ $pconfig['ips_policy_enable'] = $_POST['ips_policy_enable'];
+ $pconfig['ips_policy'] = $_POST['ips_policy'];
+
// Remove all but the default events and files rules
$enabled_rulesets_array = array();
$enabled_rulesets_array = implode("||", $default_rules);
$savemsg = gettext("All rule categories have been de-selected. ");
- if ($_POST['ips_policy_enable'])
+ if ($_POST['ips_policy_enable'] == "on")
$savemsg .= gettext("Only the rules included in the selected IPS Policy will be used.");
else
$savemsg .= gettext("There currently are no inspection rules enabled for this Suricata instance!");
}
elseif ($_POST['selectall']) {
+ if ($_POST['ips_policy_enable'] == "on") {
+ $a_nat[$id]['ips_policy_enable'] = 'on';
+ $a_nat[$id]['ips_policy'] = $_POST['ips_policy'];
+ }
+ else {
+ $a_nat[$id]['ips_policy_enable'] = 'off';
+ unset($a_nat[$id]['ips_policy']);
+ }
+
+ $pconfig['autoflowbits'] = $_POST['autoflowbits'];
+ $pconfig['ips_policy_enable'] = $_POST['ips_policy_enable'];
+ $pconfig['ips_policy'] = $_POST['ips_policy'];
+
// Start with the required default events and files rules
$enabled_rulesets_array = $default_rules;
@@ -265,6 +290,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
echo '</td></tr>';
echo '<tr><td class="tabnavtbl">';
@@ -277,6 +303,7 @@ if ($savemsg) {
$tab_array[] = array($menu_iface . gettext("App Parsers"), false, "/suricata/suricata_app_parsers.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Variables"), false, "/suricata/suricata_define_vars.php?id={$id}");
$tab_array[] = array($menu_iface . gettext("Barnyard2"), false, "/suricata/suricata_barnyard.php?id={$id}");
+ $tab_array[] = array($menu_iface . gettext("IP Rep"), false, "/suricata/suricata_ip_reputation.php?id={$id}");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_sid_mgmt.php b/config/suricata/suricata_sid_mgmt.php
index 2224e81a..c2d58af8 100644
--- a/config/suricata/suricata_sid_mgmt.php
+++ b/config/suricata/suricata_sid_mgmt.php
@@ -55,7 +55,7 @@ $pconfig['auto_manage_sids'] = $config['installedpackages']['suricata']['config'
// Hard-code the path where SID Mods Lists are stored
// and disregard any user-supplied path element.
-$sidmods_path = SID_MODS_PATH;
+$sidmods_path = SURICATA_SID_MODS_PATH;
// Set default to not show SID modification lists editor controls
$sidmodlist_edit_style = "display: none;";
@@ -216,7 +216,7 @@ if (isset($_POST['sidlist_dnload']) && isset($_POST['sidlist_fname'])) {
}
if (isset($_POST['sidlist_dnload_all_x'])) {
- $save_date = exec('/bin/date "+%Y-%m-%d-%H-%M-%S"');
+ $save_date = date("Y-m-d-H-i-s");
$file_name = "suricata_sid_conf_files_{$save_date}.tar.gz";
exec("cd {$sidmods_path} && /usr/bin/tar -czf /tmp/{$file_name} *");
@@ -236,7 +236,7 @@ if (isset($_POST['sidlist_dnload_all_x'])) {
readfile("/tmp/{$file_name}");
// Clean up the temp file
- @unlink("/tmp/{$file_name}");
+ unlink_if_exists("/tmp/{$file_name}");
}
else
$savemsg = gettext("An error occurred while creating the gzip archive!");
@@ -290,6 +290,7 @@ if ($savemsg) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), true, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td></tr>
@@ -297,6 +298,11 @@ if ($savemsg) {
<div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
<tbody>
+ <?php if ($g['platform'] == "nanobsd") : ?>
+ <tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("SID auto-management is not supported on NanoBSD installs"); ?></td>
+ </tr>
+ <?php else: ?>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Settings"); ?></td>
</tr>
@@ -571,6 +577,7 @@ if ($savemsg) {
&nbsp;&nbsp;<?=gettext("Remember to save changes before exiting this page"); ?>
</td>
</tr>
+ <?php endif; ?>
</tbody>
</table>
</div>
@@ -581,6 +588,8 @@ if ($savemsg) {
<?php include("fend.inc"); ?>
+
+<?php if ($g['platform'] != "nanobsd") : ?>
<script type="text/javascript">
function enable_sid_conf() {
@@ -596,5 +605,7 @@ function enable_sid_conf() {
enable_sid_conf();
</script>
+<?php endif; ?>
+
</body>
</html>
diff --git a/config/suricata/suricata_suppress.php b/config/suricata/suricata_suppress.php
index 80249724..8fcb3dd5 100644
--- a/config/suricata/suricata_suppress.php
+++ b/config/suricata/suricata_suppress.php
@@ -103,7 +103,9 @@ if ($_POST['del'] && is_numericint($_POST['list_id'])) {
else {
unset($a_suppress[$_POST['list_id']]);
write_config("Suricata pkg: deleted SUPPRESS LIST.");
+ conf_mount_rw();
sync_suricata_package_config();
+ conf_mount_ro();
header("Location: /suricata/suricata_suppress.php");
exit;
}
@@ -144,6 +146,7 @@ if ($input_errors) {
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td>
diff --git a/config/suricata/suricata_suppress_edit.php b/config/suricata/suricata_suppress_edit.php
index 24572789..8814d3db 100644
--- a/config/suricata/suricata_suppress_edit.php
+++ b/config/suricata/suricata_suppress_edit.php
@@ -168,6 +168,7 @@ if ($savemsg)
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
$tab_array[] = array(gettext("SID Mgmt"), false, "/suricata/suricata_sid_mgmt.php");
$tab_array[] = array(gettext("Sync"), false, "/pkg_edit.php?xml=suricata/suricata_sync.xml");
+ $tab_array[] = array(gettext("IP Lists"), false, "/suricata/suricata_ip_list_mgmt.php");
display_top_tabs($tab_array, true);
?>
</td></tr>
diff --git a/config/suricata/suricata_sync.xml b/config/suricata/suricata_sync.xml
index a85a3d63..28083d8d 100644
--- a/config/suricata/suricata_sync.xml
+++ b/config/suricata/suricata_sync.xml
@@ -110,6 +110,11 @@ POSSIBILITY OF SUCH DAMAGE.
<no_drop_down/>
<active/>
</tab>
+ <tab>
+ <text>IP Lists</text>
+ <url>/suricata/suricata_ip_list_mgmt.php</url>
+ <no_drop_down/>
+ </tab>
</tabs>
<fields>
<field>
diff --git a/config/suricata/suricata_uninstall.php b/config/suricata/suricata_uninstall.php
index 280e2394..c8048a1c 100644
--- a/config/suricata/suricata_uninstall.php
+++ b/config/suricata/suricata_uninstall.php
@@ -44,11 +44,12 @@ global $config, $g;
$suricatadir = SURICATADIR;
$suricatalogdir = SURICATALOGDIR;
-$sidmodspath = SID_MODS_PATH;
-$iprep_path = IPREP_PATH;
+$sidmodspath = SURICATA_SID_MODS_PATH;
+$iprep_path = SURICATA_IPREP_PATH;
$rcdir = RCFILEPREFIX;
-$suricata_rules_upd_log = RULES_UPD_LOGFILE;
+$suricata_rules_upd_log = SURICATA_RULES_UPD_LOGFILE;
$suri_pf_table = SURICATA_PF_TABLE;
+$mounted_rw = FALSE;
log_error(gettext("[Suricata] Suricata package uninstall in progress..."));
@@ -76,20 +77,29 @@ unlink_if_exists("{$g['varrun_path']}/barnyard2_*.pid");
install_cron_job("suricata_check_for_rule_updates.php", false);
install_cron_job("suricata_check_cron_misc.inc", false);
install_cron_job("{$suri_pf_table}" , false);
+install_cron_job("suricata_geoipupdate.php" , false);
+install_cron_job("suricata_etiqrisk_update.php", false);
/* See if we are to keep Suricata log files on uninstall */
if ($config['installedpackages']['suricata']['config'][0]['clearlogs'] == 'on') {
log_error(gettext("[Suricata] Clearing all Suricata-related log files..."));
- @unlink("{$suricata_rules_upd_log}");
- mwexec("/bin/rm -rf {$suricatalogdir}");
+ unlink_if_exists("{$suricata_rules_upd_log}");
+ rmdir_recursive("{$suricatalogdir}");
}
-// Mount filesystem read-write to remove our files
-conf_mount_rw();
+/**************************************************/
+/* If not already, set Suricata conf partition to */
+/* read-write so we can make changes there */
+/**************************************************/
+if (!is_subsystem_dirty('mount')) {
+ conf_mount_rw();
+ $mounted_rw = TRUE;
+}
/* Remove the Suricata GUI app directories */
-mwexec("/bin/rm -rf /usr/local/pkg/suricata");
-mwexec("/bin/rm -rf /usr/local/www/suricata");
+rmdir_recursive("/usr/local/pkg/suricata");
+rmdir_recursive("/usr/local/www/suricata");
+rmdir_recursive("/usr/local/etc/suricata");
/* Remove our associated Dashboard widget config and files. */
/* If "save settings" is enabled, then save old widget */
@@ -110,24 +120,26 @@ if (!empty($widgets)) {
}
}
$config['widgets']['sequence'] = implode(",", $widgetlist);
- write_config("Suricata pkg: remove Suricata Dashboard Widget on package deinstall.");
}
-@unlink("/usr/local/www/widgets/include/widget-suricata.inc");
-@unlink("/usr/local/www/widgets/widgets/suricata_alerts.widget.php");
-@unlink("/usr/local/www/widgets/javascript/suricata_alerts.js");
+unlink_if_exists("/usr/local/www/widgets/include/widget-suricata.inc");
+unlink_if_exists("/usr/local/www/widgets/widgets/suricata_alerts.widget.php");
+unlink_if_exists("/usr/local/www/widgets/javascript/suricata_alerts.js");
-// Finished with filesystem mods so remount it read-only
-conf_mount_ro();
+/*******************************************************/
+/* We're finished with conf partition mods, return to */
+/* read-only if we changed it */
+/*******************************************************/
+if ($mounted_rw == TRUE)
+ conf_mount_ro();
/* Keep this as a last step */
if ($config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] != 'on') {
log_error(gettext("Not saving settings... all Suricata configuration info and logs deleted..."));
unset($config['installedpackages']['suricata']);
unset($config['installedpackages']['suricatasync']);
- @unlink("{$suricata_rules_upd_log}");
- mwexec("/bin/rm -rf {$suricatalogdir}");
- mwexec("/bin/rm -rf {$sidmodspath}");
- mwexec("/bin/rm -rf {$iprep_path}");
+ unlink_if_exists("{$suricata_rules_upd_log}");
+ rmdir_recursive("{$suricatalogdir}");
+ rmdir_recursive("{$g['vardb_path']}/suricata");
log_error(gettext("[Suricata] The package has been removed from this system..."));
}
diff --git a/config/suricata/suricata_yaml_template.inc b/config/suricata/suricata_yaml_template.inc
index 82c449d3..a8b06ebe 100644
--- a/config/suricata/suricata_yaml_template.inc
+++ b/config/suricata/suricata_yaml_template.inc
@@ -225,9 +225,9 @@ reassembly:
# Host table is used by tagging and per host thresholding subsystems.
host:
- hash-size: 4096
- prealloc: 1000
- memcap: 16777216
+ hash-size: {$host_hash_size}
+ prealloc: {$host_prealloc}
+ memcap: {$host_memcap}
# Host specific policies for defragmentation and TCP stream reassembly.
host-os-policy:
@@ -286,18 +286,14 @@ vars:
port-groups:
{$port_vars}
-# Set the order of alerts bassed on actions
+# Set the order of alerts based on actions
action-order:
- pass
- drop
- reject
- alert
-# IP Reputation
-#reputation-categories-file: {$iprep_path}/categories.txt
-#default-reputation-path: {$iprep_path}
-#reputation-files:
-# - reputation.list
+{$iprep_config}
# Limit for the maximum number of asn1 frames to decode (default 256)
asn1-max-frames: {$asn1_max_frames}
diff --git a/config/systempatches/system_patches.php b/config/systempatches/system_patches.php
index 793448d7..43c8c22b 100644
--- a/config/systempatches/system_patches.php
+++ b/config/systempatches/system_patches.php
@@ -160,7 +160,7 @@ include("head.inc");
<?php include("fbegin.inc"); ?>
<form action="system_patches.php" method="post" name="iform">
<script type="text/javascript" language="javascript" src="/javascript/row_toggle.js"></script>
-<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if ($savemsg) print_info_box_np($savemsg, "Patches", "Close", false); ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0" summary="system patches">
<tr><td><div id="mainarea">
<table class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0" summary="main area">
diff --git a/config/systempatches/systempatches.xml b/config/systempatches/systempatches.xml
index b9875140..3cc1354a 100644
--- a/config/systempatches/systempatches.xml
+++ b/config/systempatches/systempatches.xml
@@ -40,7 +40,7 @@
<requirements>None</requirements>
<faq>Applies patches supplied by the user to the firewall.</faq>
<name>System Patches</name>
- <version>1.0.2</version>
+ <version>1.0.3</version>
<title>System: Patches</title>
<include_file>/usr/local/pkg/patches.inc</include_file>
<menu>
diff --git a/config/vnstat2/vnstat2.inc b/config/vnstat2/vnstat2.inc
index 9a684aa1..7418530f 100644
--- a/config/vnstat2/vnstat2.inc
+++ b/config/vnstat2/vnstat2.inc
@@ -248,7 +248,7 @@ function vnstat_php_frontend(){
// see file COPYING or at http://www.gnu.org/licenses/gpl.html
// for more information.
//
- error_reporting(E_ALL | E_NOTICE);
+ //error_reporting(E_ALL | E_NOTICE);
//
// configuration parameters
diff --git a/config/vnstat2/vnstat_php_frontend/README b/config/vnstat2/vnstat_php_frontend/README
index 20053152..c0259cfa 100644
--- a/config/vnstat2/vnstat_php_frontend/README
+++ b/config/vnstat2/vnstat_php_frontend/README
@@ -26,8 +26,8 @@ explained in config.php.
3. LICENSE
-vnstat PHP frontend 1.5.1
-Copyright (c)2006-2008 Bjorge Dijkstra (bjd@jooz.net)
+vnstat PHP frontend 1.5.2
+Copyright (c)2006-2011 Bjorge Dijkstra (bjd@jooz.net)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/config/vnstat2/vnstat_php_frontend/config.php b/config/vnstat2/vnstat_php_frontend/config.php
index 3a4cd51a..9f2102ac 100644
--- a/config/vnstat2/vnstat_php_frontend/config.php
+++ b/config/vnstat2/vnstat_php_frontend/config.php
@@ -17,10 +17,10 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
- // see file COPYING or at http://www.gnu.org/licenses/gpl.html
+ // see file COPYING or at http://www.gnu.org/licenses/gpl.html
// for more information.
//
- error_reporting(E_ALL | E_NOTICE);
+ //error_reporting(E_ALL | E_NOTICE);
//
// configuration parameters
@@ -30,6 +30,9 @@
$locale = 'en_US.UTF-8';
$language = 'en';
+ // Set local timezone
+ date_default_timezone_set("Europe/Amsterdam");
+
// list of network interfaces monitored by vnStat
$iface_list = array('em0', 'em1');
@@ -43,7 +46,7 @@
//
// There are two possible sources for vnstat data. If the $vnstat_bin
// variable is set then vnstat is called directly from the PHP script
- // to get the interface data.
+ // to get the interface data.
//
// The other option is to periodically dump the vnstat interface data to
// a file (e.g. by a cronjob). In that case the $vnstat_bin variable
@@ -52,18 +55,23 @@
//
// You can generate vnstat dumps with the command:
// vnstat --dumpdb -i $iface > /path/to/data_dir/vnstat_dump_$iface
- //
+ //
$vnstat_bin = '/usr/local/bin/vnstat';
$data_dir = './dumps';
// graphics format to use: svg or png
$graph_format='svg';
-
+
// Font to use for PNG graphs
define('GRAPH_FONT',dirname(__FILE__).'/VeraBd.ttf');
// Font to use for SVG graphs
define('SVG_FONT', 'Verdana');
- define('DEFAULT_COLORSCHEME', 'pfSense');
-?> \ No newline at end of file
+ // Default theme
+ define('DEFAULT_COLORSCHEME', 'pfSense');
+
+ // SVG Depth scaling factor
+ define('SVG_DEPTH_SCALING', 1);
+
+?>
diff --git a/config/vnstat2/vnstat_php_frontend/graph.php b/config/vnstat2/vnstat_php_frontend/graph.php
index fb00be67..3ef72f1a 100644
--- a/config/vnstat2/vnstat_php_frontend/graph.php
+++ b/config/vnstat2/vnstat_php_frontend/graph.php
@@ -17,7 +17,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
- // see file COPYING or at http://www.gnu.org/licenses/gpl.html
+ // see file COPYING or at http://www.gnu.org/licenses/gpl.html
// for more information.
//
require 'config.php';
@@ -32,7 +32,7 @@
{
return imagecolorallocatealpha($im, $colors[0], $colors[1], $colors[2], $colors[3]);
}
-
+
function init_image()
{
global $im, $xlm, $xrm, $ytm, $ybm, $iw, $ih,$graph, $cl, $iface, $colorscheme, $style;
@@ -42,7 +42,7 @@
//
// image object
- //
+ //
$xlm = 70;
$xrm = 20;
$ytm = 35;
@@ -50,7 +50,7 @@
if ($graph == 'small')
{
$iw = 300 + $xrm + $xlm;
- $ih = 100 + $ytm + $ybm;
+ $ih = 100 + $ytm + $ybm;
}
else
{
@@ -75,10 +75,10 @@
$cl['rx_border'] = allocate_color($im, $cs['rx_border']);
$cl['tx'] = allocate_color($im, $cs['tx']);
$cl['tx_border'] = allocate_color($im, $cs['tx_border']);
-
+
imagefilledrectangle($im,0,0,$iw,$ih,$cl['image_background']);
imagefilledrectangle($im,$xlm,$ytm,$iw-$xrm,$ih-$ybm, $cl['background']);
-
+
$x_step = ($iw - $xlm - $xrm) / 12;
$depth = ($x_step / 8) + 4;
imagefilledpolygon($im, array($xlm, $ytm, $xlm, $ih - $ybm, $xlm - $depth, $ih - $ybm + $depth, $xlm - $depth, $ytm + $depth), 4, $cl['background_2']);
@@ -89,7 +89,7 @@
$bbox = imagettfbbox(10, 0, GRAPH_FONT, $text);
$textwidth = $bbox[2] - $bbox[0];
imagettftext($im, 10, 0, ($iw-$textwidth)/2, ($ytm/2), $cl['text'], GRAPH_FONT, $text);
-
+
}
function draw_border()
@@ -98,16 +98,16 @@
imageline($im, 0, 0,$iw-1, 0, $cl['border']);
imageline($im, 0,$ih-1,$iw-1,$ih-1, $cl['border']);
- imageline($im, 0, 0, 0,$ih-1, $cl['border']);
+ imageline($im, 0, 0, 0,$ih-1, $cl['border']);
imageline($im, $iw-1, 0,$iw-1,$ih-1, $cl['border']);
}
-
+
function draw_grid($x_ticks, $y_ticks)
{
global $im, $cl, $iw, $ih, $xlm, $xrm, $ytm, $ybm;
$x_step = ($iw - $xlm - $xrm) / $x_ticks;
$y_step = ($ih - $ytm - $ybm) / $y_ticks;
-
+
$depth = 10;//($x_step / 8) + 4;
$ls = array($cl['grid_stipple_1'],$cl['grid_stipple_2']);
@@ -119,14 +119,13 @@
}
for ($i=$ytm;$i<=($ih-$ybm); $i += $y_step)
{
- imageline($im, $xlm, $i, $iw - $xrm, $i, IMG_COLOR_STYLED);
+ imageline($im, $xlm, $i, $iw - $xrm, $i, IMG_COLOR_STYLED);
imageline($im, $xlm, $i, $xlm - $depth, $i + $depth, IMG_COLOR_STYLED);
}
imageline($im, $xlm, $ytm, $xlm, $ih - $ybm, $cl['border']);
imageline($im, $xlm, $ih - $ybm, $iw - $xrm, $ih - $ybm, $cl['border']);
}
-
-
+
function draw_data($data)
{
global $im,$cl,$iw,$ih,$xlm,$xrm,$ytm,$ybm;
@@ -168,7 +167,7 @@
{
$prescale = $prescale * 1024;
$y_scale = $y_scale / 1024;
- if ($unit == 'K')
+ if ($unit == 'K')
$unit = 'M';
else if ($unit == 'M')
$unit = 'G';
@@ -178,7 +177,7 @@
}
draw_grid($x_ticks, $y_ticks);
-
+
//
// graph scale factor (per pixel)
//
@@ -187,7 +186,7 @@
if ($data[0] == 'nodata')
{
- $text = 'no data available';
+ $text = T('no data available');
$bbox = imagettfbbox(10, 0, GRAPH_FONT, $text);
$textwidth = $bbox[2] - $bbox[0];
imagettftext($im, 10, 0, ($iw-$textwidth)/2, $ytm + 80, $cl['text'], GRAPH_FONT, $text);
@@ -196,26 +195,26 @@
{
//
// draw bars
- //
+ //
for ($i=0; $i<$x_ticks; $i++)
{
$x = $xlm + ($i * $x_step);
$y = $ytm + ($ih - $ytm - $ybm) - (($data[$i]['rx'] - $offset) / $sf);
-
+
$depth = $x_step / 8;
$space = 0;
-
+
$x1 = $x;
$y1 = $y;
$x2 = $x + $bar_w - $space;
$y2 = $ih - $ybm;
-
+
imagefilledrectangle($im, $x1, $y1, $x2, $y2, $cl['rx']);
imagerectangle($im, $x1, $y1, $x2, $y2, $cl['rx_border']);
-
+
imagefilledrectangle($im, $x1 - $depth, $y1 + $depth, $x2 -$depth, $y2 + $depth, $cl['rx']);
imagerectangle($im, $x1 - $depth, $y1 + $depth, $x2 - $depth, $y2 + $depth, $cl['rx_border']);
-
+
imagefilledpolygon($im, array($x1, $y1, $x2, $y1, $x2 - $depth, $y1 + $depth, $x1 - $depth, $y1 + $depth), 4, $cl['rx']);
imagepolygon($im, array($x1, $y1, $x2, $y1, $x2 - $depth, $y1 + $depth, $x1 - $depth, $y1 + $depth), 4, $cl['rx_border']);
imagefilledpolygon($im, array($x2, $y1, $x2, $y2, $x2 - $depth, $y2 + $depth, $x2 - $depth, $y1 + $depth), 4, $cl['rx']);
@@ -227,16 +226,16 @@
imagefilledrectangle($im, $x1, $y1, $x2, $y2, $cl['tx']);
imagerectangle($im, $x1, $y1, $x2, $y2, $cl['tx_border']);
-
+
imagefilledrectangle($im, $x1 - $depth, $y1 + $depth, $x2 - $depth, $y2 + $depth, $cl['tx']);
- imagerectangle($im, $x1 - $depth, $y1 + $depth, $x2 - $depth, $y2 + $depth, $cl['tx_border']);
-
+ imagerectangle($im, $x1 - $depth, $y1 + $depth, $x2 - $depth, $y2 + $depth, $cl['tx_border']);
+
imagefilledpolygon($im, array($x1, $y1, $x2, $y1, $x2 - $depth, $y1 + $depth, $x1 - $depth, $y1 + $depth), 4, $cl['tx']);
imagepolygon($im, array($x1, $y1, $x2, $y1, $x2 - $depth, $y1 + $depth, $x1 - $depth, $y1 + $depth), 4, $cl['tx_border']);
imagefilledpolygon($im, array($x2, $y1, $x2, $y2, $x2 - $depth, $y2 + $depth, $x2 - $depth, $y1 + $depth), 4, $cl['tx']);
imagepolygon($im, array($x2, $y1, $x2, $y2, $x2 - $depth, $y2 + $depth, $x2 - $depth, $y1 + $depth), 4, $cl['tx_border']);
}
-
+
//
// axis labels
//
@@ -265,11 +264,11 @@
//
imagefilledrectangle($im, $xlm, $ih-$ybm+39, $xlm+8,$ih-$ybm+47,$cl['rx']);
imagerectangle($im, $xlm, $ih-$ybm+39, $xlm+8,$ih-$ybm+47,$cl['text']);
- imagettftext($im, 8,0, $xlm+14, $ih-$ybm+48,$cl['text'], GRAPH_FONT,'bytes in');
+ imagettftext($im, 8,0, $xlm+14, $ih-$ybm+48,$cl['text'], GRAPH_FONT,T('bytes in'));
imagefilledrectangle($im, $xlm+120 , $ih-$ybm+39, $xlm+128,$ih-$ybm+47,$cl['tx']);
imagerectangle($im, $xlm+120, $ih-$ybm+39, $xlm+128,$ih-$ybm+47,$cl['text']);
- imagettftext($im, 8,0, $xlm+134, $ih-$ybm+48,$cl['text'], GRAPH_FONT,'bytes out');
+ imagettftext($im, 8,0, $xlm+134, $ih-$ybm+48,$cl['text'], GRAPH_FONT,T('bytes out'));
}
function output_image()
@@ -293,11 +292,11 @@
{
draw_data($month);
}
-
- header('Content-type: image/png');
+
+ header('Content-type: image/png');
imagepng($im);
}
get_vnstat_data();
output_image();
-?>
+?>
diff --git a/config/vnstat2/vnstat_php_frontend/graph_svg.php b/config/vnstat2/vnstat_php_frontend/graph_svg.php
index 8992ed12..e67a894f 100644
--- a/config/vnstat2/vnstat_php_frontend/graph_svg.php
+++ b/config/vnstat2/vnstat_php_frontend/graph_svg.php
@@ -17,7 +17,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
- // see file COPYING or at http://www.gnu.org/licenses/gpl.html
+ // see file COPYING or at http://www.gnu.org/licenses/gpl.html
// for more information.
//
require 'config.php';
@@ -61,8 +61,8 @@
print "</g>\n";
}
- function svg_text($x, $y, $text, $options = array())
- {
+ function svg_text($x, $y, $text, $options = array())
+ {
printf("<text x=\"%F\" y=\"%F\" ", $x, $y);
svg_options($options);
print ">$text</text>\n";
@@ -75,7 +75,7 @@
print "/>\n";
}
- function svg_rect($x, $y, $w, $h, $options = array())
+ function svg_rect($x, $y, $w, $h, $options = array())
{
printf("<rect x=\"%F\" y=\"%F\" width=\"%F\" height=\"%F\" ", $x, $y, $w, $h);
svg_options($options);
@@ -98,7 +98,7 @@
$col['opacity'] = sprintf("%F", (127 - $colors[3]) / 127);
return $col;
}
-
+
function init_image()
{
global $xlm, $xrm, $ytm, $ybm, $iw, $ih,$graph, $cl, $iface, $colorscheme, $style;
@@ -108,7 +108,7 @@
//
// image object
- //
+ //
$xlm = 70;
$xrm = 20;
$ytm = 35;
@@ -116,14 +116,14 @@
if ($graph == 'small')
{
$iw = 300 + $xrm + $xlm;
- $ih = 100 + $ytm + $ybm;
+ $ih = 100 + $ytm + $ybm;
}
else
{
$iw = 600 + $xrm + $xlm;
$ih = 200 + $ytm + $ybm;
}
-
+
svg_create($iw, $ih);
//
@@ -141,11 +141,11 @@
$cl['rx_border'] = allocate_color($cs['rx_border']);
$cl['tx'] = allocate_color($cs['tx']);
$cl['tx_border'] = allocate_color($cs['tx_border']);
-
+
svg_rect(0, 0, $iw, $ih, array( 'stroke' => 'none', 'stroke-width' => 0, 'fill' => $cl['image_background']['rgb']) );
svg_rect($xlm, $ytm, $iw-$xrm-$xlm, $ih-$ybm-$ytm, array( 'stroke' => 'none', 'stroke-width' => 0, 'fill' => $cl['background']['rgb']) );
-
- $depth = 12;
+
+ $depth = 12*SVG_DEPTH_SCALING;
svg_group( array( 'stroke' => 'none', 'stroke-width' => 0, 'fill' => $cl['background_2']['rgb'], 'fill-opacity' => $cl['background_2']['opacity']) );
svg_poly(array($xlm, $ytm, $xlm, $ih - $ybm, $xlm - $depth, $ih - $ybm + $depth, $xlm - $depth, $ytm + $depth));
svg_poly(array($xlm, $ih - $ybm, $xlm - $depth, $ih - $ybm + $depth, $iw - $xrm - $depth, $ih - $ybm + $depth, $iw - $xrm, $ih - $ybm));
@@ -153,7 +153,7 @@
// draw title
$text = T('Traffic data for')." $iface";
- svg_text($iw / 2, ($ytm / 2), $text, array( 'stroke' => $cl['text'], 'fill' => $cl['text']['rgb'],'stroke-width' => 0, 'font-family' => SVG_FONT, 'font-weight' => 'bold', 'text-anchor' => 'middle' ));
+ svg_text($iw / 2, ($ytm / 2), $text, array( 'stroke' => 'none', 'fill' => $cl['text']['rgb'],'stroke-width' => 0, 'font-family' => SVG_FONT, 'font-weight' => 'bold', 'text-anchor' => 'middle' ));
}
function draw_border()
@@ -161,14 +161,14 @@
global $cl, $iw, $ih;
svg_rect(1, 1, $iw-2, $ih-2, array( 'stroke' => $cl['border']['rgb'], 'stroke-opacity' => $cl['border']['opacity'], 'stroke-width' => 1, 'fill' => 'none') );
}
-
+
function draw_grid($x_ticks, $y_ticks)
{
global $cl, $iw, $ih, $xlm, $xrm, $ytm, $ybm;
$x_step = ($iw - $xlm - $xrm) / $x_ticks;
$y_step = ($ih - $ytm - $ybm) / $y_ticks;
-
- $depth = 12;
+
+ $depth = 12*SVG_DEPTH_SCALING;
svg_group( array( 'stroke' => $cl['grid_stipple_1']['rgb'], 'stroke-opacity' => $cl['grid_stipple_1']['opacity'], 'stroke-width' => '1px', 'stroke-dasharray' => '1,1' ) );
for ($i = $xlm; $i <= ($iw - $xrm); $i += $x_step)
@@ -178,7 +178,7 @@
}
for ($i = $ytm; $i <= ($ih - $ybm); $i += $y_step)
{
- svg_line($xlm, $i, $iw - $xrm, $i);
+ svg_line($xlm, $i, $iw - $xrm, $i);
svg_line($xlm, $i, $xlm - $depth, $i + $depth);
}
svg_group_end();
@@ -188,8 +188,8 @@
svg_line($xlm, $ih - $ybm, $iw - $xrm, $ih - $ybm);
svg_group_end();
}
-
-
+
+
function draw_data($data)
{
global $cl,$iw,$ih,$xlm,$xrm,$ytm,$ybm;
@@ -231,7 +231,7 @@
{
$prescale = $prescale * 1024;
$y_scale = $y_scale / 1024;
- if ($unit == 'K')
+ if ($unit == 'K')
$unit = 'M';
else if ($unit == 'M')
$unit = 'G';
@@ -241,7 +241,7 @@
}
draw_grid($x_ticks, $y_ticks);
-
+
//
// graph scale factor (per pixel)
//
@@ -256,22 +256,22 @@
{
//
// draw bars
- //
+ //
for ($i=0; $i<$x_ticks; $i++)
{
$x = $xlm + ($i * $x_step);
$y = $ytm + ($ih - $ytm - $ybm) - (($data[$i]['rx'] - $offset) / $sf);
-
- $depth = ($x_ticks < 20) ? 8 : 6;
+
+ $depth = ($x_ticks < 20) ? 8*SVG_DEPTH_SCALING : 6*SVG_DEPTH_SCALING;
$space = 0;
-
+
$x1 = (int)$x;
$y1 = (int)$y;
$w = (int)($bar_w - $space);
$h = (int)($ih - $ybm - $y);
$x2 = (int)($x + $bar_w - $space);
$y2 = (int)($ih - $ybm);
-
+
svg_group( array( 'stroke' => $cl['rx_border']['rgb'], 'stroke-opacity' => $cl['rx_border']['opacity'],
'stroke-width' => 1, 'stroke-linejoin' => 'round',
'fill' => $cl['rx']['rgb'], 'fill-opacity' => $cl['rx']['opacity'] ) );
@@ -287,7 +287,7 @@
$w = (int)($bar_w - $space);
$h = (int)($ih - $ybm - $y1 - 1);
- svg_group( array( 'stroke' => $cl['tx_border']['rgb'], 'stroke-opacity' => $cl['tx_border']['opacity'],
+ svg_group( array( 'stroke' => $cl['tx_border']['rgb'], 'stroke-opacity' => $cl['tx_border']['opacity'],
'stroke-width' => 1, 'stroke-linejoin' => 'round',
'fill' => $cl['tx']['rgb'], 'fill-opacity' => $cl['tx']['opacity'] ) );
svg_rect($x1, $y1, $w, $h);
@@ -296,7 +296,7 @@
svg_poly(array($x2, $y1, $x2, $y2, $x2 - $depth, $y2 + $depth, $x2 - $depth, $y1 + $depth));
svg_group_end();
}
-
+
//
// axis labels
//
@@ -359,4 +359,4 @@
get_vnstat_data();
output_image();
-?>
+?>
diff --git a/config/vnstat2/vnstat_php_frontend/index.php b/config/vnstat2/vnstat_php_frontend/index.php
index 70c0427f..478665ee 100644
--- a/config/vnstat2/vnstat_php_frontend/index.php
+++ b/config/vnstat2/vnstat_php_frontend/index.php
@@ -17,7 +17,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
- // see file COPYING or at http://www.gnu.org/licenses/gpl.html
+ // see file COPYING or at http://www.gnu.org/licenses/gpl.html
// for more information.
//
require 'config.php';
@@ -31,15 +31,20 @@
function write_side_bar()
{
global $iface, $page, $graph, $script, $style;
- global $iface_list, $iface_title;
+ global $iface_list, $iface_title;
global $page_list, $page_title;
-
+
$p = "&amp;graph=$graph&amp;style=$style";
print "<ul class=\"iface\">\n";
foreach ($iface_list as $if)
{
- print "<li class=\"iface\">";
+ if ($iface == $if) {
+ print "<li class=\"iface active\">";
+ } else {
+ print "<li class=\"iface\">";
+ }
+ print "<a href=\"$script?if=$if$p\">";
if (isset($iface_title[$if]))
{
print $iface_title[$if];
@@ -48,17 +53,17 @@
{
print $if;
}
+ print "</a>";
print "<ul class=\"page\">\n";
foreach ($page_list as $pg)
{
print "<li class=\"page\"><a href=\"$script?if=$if$p&amp;page=$pg\">".$page_title[$pg]."</a></li>\n";
}
print "</ul></li>\n";
-
}
- print "</ul>\n";
+ print "</ul>\n";
}
-
+
function kbytes_to_string($kb)
{
@@ -70,10 +75,10 @@
{
$ui++;
$scale = $scale / 1024;
- }
+ }
return sprintf("%0.2f %s", ($kb/$scale),$units[$ui]);
}
-
+
function write_summary()
{
global $summary,$top,$day,$hour,$month;
@@ -108,8 +113,8 @@
print "<br/>\n";
write_data_table(T('Top 10 days'), $top);
}
-
-
+
+
function write_data_table($caption, $tab)
{
print "<table width=\"100%\" cellspacing=\"0\">\n";
@@ -118,7 +123,7 @@
print "<th class=\"label\" style=\"width:120px;\">&nbsp;</th>";
print "<th class=\"label\">".T('In')."</th>";
print "<th class=\"label\">".T('Out')."</th>";
- print "<th class=\"label\">".T('Total')."</th>";
+ print "<th class=\"label\">".T('Total')."</th>";
print "</tr>\n";
for ($i=0; $i<count($tab); $i++)
@@ -148,7 +153,7 @@
//
header('Content-type: text/html; charset=utf-8');
print '<?xml version="1.0"?>';
-?>
+?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
@@ -168,7 +173,7 @@
if ($graph_format == 'svg') {
print "<object type=\"image/svg+xml\" width=\"692\" height=\"297\" data=\"graph_svg.php?$graph_params\"></object>\n";
} else {
- print "<img src=\"graph.php?$graph_params\" alt=\"graph\"/>\n";
+ print "<img src=\"graph.php?$graph_params\" alt=\"graph\"/>\n";
}
if ($page == 's')
@@ -176,20 +181,20 @@
write_summary();
}
else if ($page == 'h')
- {
- write_data_table(T('Last 24 hours'), $hour);
+ {
+ write_data_table(T('Last 24 hours'), $hour);
}
else if ($page == 'd')
{
- write_data_table(T('Last 30 days'), $day);
+ write_data_table(T('Last 30 days'), $day);
}
else if ($page == 'm')
{
- write_data_table(T('Last 12 months'), $month);
+ write_data_table(T('Last 12 months'), $month);
}
?>
</div>
- <div id="footer"><a href="http://www.sqweek.com/">vnStat PHP frontend</a> 1.5.1 - &copy;2006-2010 Bjorge Dijkstra (bjd _at_ jooz.net)</div>
+ <div id="footer"><a href="http://www.sqweek.com/">vnStat PHP frontend</a> 1.5.2 - &copy;2006-2011 Bjorge Dijkstra (bjd _at_ jooz.net)</div>
</div>
</div>
diff --git a/config/vnstat2/vnstat_php_frontend/json.php b/config/vnstat2/vnstat_php_frontend/json.php
new file mode 100644
index 00000000..89d4c78e
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/json.php
@@ -0,0 +1,81 @@
+<?php
+ //
+ // vnStat PHP frontend (c)2006-2010 Bjorge Dijkstra (bjd@jooz.net)
+ //
+ // This program is free software; you can redistribute it and/or modify
+ // it under the terms of the GNU General Public License as published by
+ // the Free Software Foundation; either version 2 of the License, or
+ // (at your option) any later version.
+ //
+ // 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
+ //
+ //
+ // see file COPYING or at http://www.gnu.org/licenses/gpl.html
+ // for more information.
+ //
+ require 'config.php';
+ require 'localize.php';
+ require 'vnstat.php';
+
+ validate_input();
+
+ require "./themes/$style/theme.php";
+
+ function write_summary()
+ {
+ global $summary,$top,$day,$hour,$month;
+
+ $trx = $summary['totalrx']*1024+$summary['totalrxk'];
+ $ttx = $summary['totaltx']*1024+$summary['totaltxk'];
+
+ //
+ // build array for write_data_table
+ //
+ $sum['hour']['act'] = 1;
+ $sum['hour']['rx'] = $hour[0]['rx'];
+ $sum['hour']['tx'] = $hour[0]['tx'];
+
+ $sum['day']['act'] = 1;
+ $sum['day']['rx'] = $day[0]['rx'];
+ $sum['day']['tx'] = $day[0]['tx'];
+
+ $sum['month']['act'] = 1;
+ $sum['month']['rx'] = $month[0]['rx'];
+ $sum['month']['tx'] = $month[0]['tx'];
+
+ $sum['total']['act'] = 1;
+ $sum['total']['rx'] = $trx;
+ $sum['total']['tx'] = $ttx;
+
+ print json_encode($sum);
+ }
+
+
+ get_vnstat_data(false);
+
+ header('Content-type: application/json; charset=utf-8');
+ $graph_params = "if=$iface&amp;page=$page&amp;style=$style";
+ if ($page == 's')
+ {
+ write_summary();
+ }
+ else if ($page == 'h')
+ {
+ print json_encode(array('hours' => $hour));
+ }
+ else if ($page == 'd')
+ {
+ print json_encode(array('days' => $day));
+ }
+ else if ($page == 'm')
+ {
+ print json_encode(array('months' => $month));
+ }
+ ?> \ No newline at end of file
diff --git a/config/vnstat2/vnstat_php_frontend/lang/br.php b/config/vnstat2/vnstat_php_frontend/lang/br.php
new file mode 100644
index 00000000..ea2fd103
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/br.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'sumario';
+$L['hours'] = 'horas';
+$L['days'] = 'dias';
+$L['months'] = 'meses';
+
+// main table headers
+$L['Summary'] = 'Sumario';
+$L['Top 10 days'] = 'Top 10 - dias';
+$L['Last 24 hours'] = 'Ultimas 24 horas';
+$L['Last 30 days'] = 'Ultimos 30 dias';
+$L['Last 12 months'] = 'Ultimos 12 meses';
+
+// traffic table columns
+$L['In'] = 'Entrada';
+$L['Out'] = 'Saida';
+$L['Total'] = 'Total';
+
+// summary rows
+$L['This hour'] = 'Esta hora';
+$L['This day'] = 'Este dia';
+$L['This month'] = 'Este mes';
+$L['All time'] = 'Todos os tempos';
+
+// graph text
+$L['Traffic data for'] = 'Trafego da';
+$L['bytes in'] = 'bytes entrada';
+$L['bytes out'] = 'bytes saida';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%l%p';
+$L['datefmt_hours_img'] = '%l';
+$L['datefmt_top'] = '%d %B %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/cn.php b/config/vnstat2/vnstat_php_frontend/lang/cn.php
new file mode 100644
index 00000000..3be03cd5
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/cn.php
@@ -0,0 +1,40 @@
+<?php
+
+// sidebar labels
+$L['summary'] = '总计';
+$L['hours'] = '每时';
+$L['days'] = '每天';
+$L['months'] = '每月';
+
+// main table headers
+$L['Summary'] = '概览';
+$L['Top 10 days'] = '最高流量的10天';
+$L['Last 24 hours'] = '过去24小时';
+$L['Last 30 days'] = '过去30天';
+$L['Last 12 months'] = '过去12个月';
+
+// traffic table columns
+$L['In'] = '流入';
+$L['Out'] = '流出';
+$L['Total'] = '总流量';
+
+// summary rows
+$L['This hour'] = '本小时';
+$L['This day'] = '本日';
+$L['This month'] = '本月';
+$L['All time'] = '总计';
+
+// graph text
+$L['Traffic data for'] = '统计的网络:';
+$L['bytes in'] = '流入bytes';
+$L['bytes out'] = '流出bytes';
+
+// date formats
+$L['datefmt_days'] = '%B%d日';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%Y年%B';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%H:00';
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%Y年%m月%d日';
+
diff --git a/config/vnstat2/vnstat_php_frontend/lang/de.php b/config/vnstat2/vnstat_php_frontend/lang/de.php
new file mode 100644
index 00000000..b77fff83
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/de.php
@@ -0,0 +1,40 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'Übersicht';
+$L['hours'] = 'Stunden';
+$L['days'] = 'Tage';
+$L['months'] = 'Monate';
+
+// main table headers
+$L['Summary'] = 'Übersicht';
+$L['Top 10 days'] = 'Top 10 nach Tagen';
+$L['Last 24 hours'] = 'Letzte 24 Stunden';
+$L['Last 30 days'] = 'Letzte 30 Tage';
+$L['Last 12 months'] = 'Letzte 12 Monate';
+
+// traffic table columns
+$L['In'] = 'Rein';
+$L['Out'] = 'Raus';
+$L['Total'] = 'Total';
+
+// summary rows
+$L['This hour'] = 'Diese Stunde';
+$L['This day'] = 'Dieser Tag';
+$L['This month'] = 'Dieser Monat';
+$L['All time'] = 'Alles';
+
+// graph text
+$L['Traffic data for'] = 'Trafficdaten für';
+$L['bytes in'] = 'Bytes rein';
+$L['bytes out'] = 'Bytes raus';
+
+// date formats
+$L['datefmt_days'] = '%d.%B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B.%Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%H:%M';
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%d.%B.%Y';
+
diff --git a/config/vnstat2/vnstat_php_frontend/lang/es.php b/config/vnstat2/vnstat_php_frontend/lang/es.php
new file mode 100644
index 00000000..a2456295
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/es.php
@@ -0,0 +1,41 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'sumario';
+$L['hours'] = 'horas';
+$L['days'] = 'días';
+$L['months'] = 'meses';
+
+// main table headers
+$L['Summary'] = 'Sumario';
+$L['Top 10 days'] = 'Últimos 10 días';
+$L['Last 24 hours'] = 'Últimas 24 horas';
+$L['Last 30 days'] = 'Últimos 30 días';
+$L['Last 12 months'] = 'Últimos 12 meses';
+
+// traffic table columns
+$L['In'] = 'Entrada';
+$L['Out'] = 'Salida';
+$L['Total'] = 'Total';
+
+// summary rows
+$L['This hour'] = 'Esta hora';
+$L['This day'] = 'Este día';
+$L['This month'] = 'Este mes';
+$L['All time'] = 'Todo el tiempo';
+
+// graph text
+$L['Traffic data for'] = 'Trafico de datos para';
+$L['bytes in'] = 'entrada de bytes';
+$L['bytes out'] = 'salida de bytes';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%H:%M';
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%d %B %Y';
+
+// spanish version by Carlos Troetsch
diff --git a/config/vnstat2/vnstat_php_frontend/lang/fi.php b/config/vnstat2/vnstat_php_frontend/lang/fi.php
new file mode 100644
index 00000000..f1ce59b4
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/fi.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'yhteenveto';
+$L['hours'] = 'tunnit';
+$L['days'] = 'päivät';
+$L['months'] = 'kuukaudet';
+
+// main table headers
+$L['Summary'] = 'Yhteenveto';
+$L['Top 10 days'] = 'Top 10 päivää';
+$L['Last 24 hours'] = 'Viimeiset 24 tuntia';
+$L['Last 30 days'] = 'Viimeiset 30 päivää';
+$L['Last 12 months'] = 'Viimeiset 12 kuukautta';
+
+// traffic table columns
+$L['In'] = 'Sisään';
+$L['Out'] = 'Ulos';
+$L['Total'] = 'Yhteensä';
+
+// summary rows
+$L['This hour'] = 'Viimeisin tunti';
+$L['This day'] = 'Viimeisin päivä';
+$L['This month'] = 'Viimeisin kuukausi';
+$L['All time'] = 'Kaikkiaan';
+
+// graph text
+$L['Traffic data for'] = 'Liikennemäärä';
+$L['bytes in'] = 'tavua sisään';
+$L['bytes out'] = 'tavua ulos';
+
+// date formats
+$L['datefmt_days'] = '%d. %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%H';
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%a %d. %b %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/fr.php b/config/vnstat2/vnstat_php_frontend/lang/fr.php
new file mode 100644
index 00000000..abb76b0a
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/fr.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'Sommaire';
+$L['hours'] = 'Heures';
+$L['days'] = 'Jours';
+$L['months'] = 'Mois';
+
+// main table headers
+$L['Summary'] = 'Sommaire';
+$L['Top 10 days'] = 'Les 10 meilleurs jours';
+$L['Last 24 hours'] = 'Dernières 24 heures';
+$L['Last 30 days'] = 'Derniers 30 jours';
+$L['Last 12 months'] = 'Les 12 derniers mois';
+
+// traffic table columns
+$L['In'] = 'Entrant';
+$L['Out'] = 'Sortant';
+$L['Total'] = 'Total';
+
+// summary rows
+$L['This hour'] = 'Cette heure';
+$L['This day'] = 'Aujourd\' hui';
+$L['This month'] = 'Ce mois';
+$L['All time'] = 'Tout temps';
+
+// graph text
+$L['Traffic data for'] = 'Traffic de donnée pour :';
+$L['bytes in'] = 'bytes entrants';
+$L['bytes out'] = 'bytes sortants';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%Hh%M';
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%d %B %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/hr.php b/config/vnstat2/vnstat_php_frontend/lang/hr.php
new file mode 100644
index 00000000..f547f29d
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/hr.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'sažetak'; // summary
+$L['hours'] = 'sati';
+$L['days'] = 'dani';
+$L['months'] = 'mjeseci';
+
+// main table headers
+$L['Summary'] = 'Sažetak';
+$L['Top 10 days'] = '10 naprometnijih dana';
+$L['Last 24 hours'] = 'Zadnja 24 sata';
+$L['Last 30 days'] = 'Zadnjih 30 dana';
+$L['Last 12 months'] = 'Zadnjih 12 mjeseci';
+
+// traffic table columns
+$L['In'] = 'Primljeno';
+$L['Out'] = 'Poslano';
+$L['Total'] = 'Ukupno'; // Total
+
+// summary rows
+$L['This hour'] = 'Tekući sat';
+$L['This day'] = 'Danas';
+$L['This month'] = 'Tekući mjesec';
+$L['All time'] = 'Sveukupno';
+
+// graph text
+$L['Traffic data for'] = 'Promet za';
+$L['bytes in'] = 'bajta primljeno';
+$L['bytes out'] = 'bajta poslano';
+
+// date formats
+$L['datefmt_days'] = '%d. %m';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%m.%Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%H'; // %k
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%d.%m.%Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/hu.php b/config/vnstat2/vnstat_php_frontend/lang/hu.php
new file mode 100644
index 00000000..94a445f3
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/hu.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'Összegzés';
+$L['hours'] = 'órák';
+$L['days'] = 'napok';
+$L['months'] = 'hónapok';
+
+// main table headers
+$L['Summary'] = 'Öszegzés';
+$L['Top 10 days'] = 'Legjobb 10 nap';
+$L['Last 24 hours'] = 'Utolsó 24 óra';
+$L['Last 30 days'] = 'Utolsó 30 nap';
+$L['Last 12 months'] = 'Utolsó 12 hónap';
+
+// traffic table columns
+$L['In'] = 'Bejövő';
+$L['Out'] = 'Kimenő';
+$L['Total'] = 'Összesen';
+
+// summary rows
+$L['This hour'] = 'Ebben az órában';
+$L['This day'] = 'Ezen a napon';
+$L['This month'] = 'Ebben a hónapban';
+$L['All time'] = 'Összesen';
+
+// graph text
+$L['Traffic data for'] = 'Forgalmi adatok: ';
+$L['bytes in'] = 'bejövő bájtok';
+$L['bytes out'] = 'kimenő bájtok';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%l%p';
+$L['datefmt_hours_img'] = '%l';
+$L['datefmt_top'] = '%d %B %Y'; \ No newline at end of file
diff --git a/config/vnstat2/vnstat_php_frontend/lang/it.php b/config/vnstat2/vnstat_php_frontend/lang/it.php
new file mode 100644
index 00000000..d86cb479
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/it.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'Riepilogo';
+$L['hours'] = 'Ore';
+$L['days'] = 'Giorni';
+$L['months'] = 'Mesi';
+
+// main table headers
+$L['Summary'] = 'Riepilogo';
+$L['Top 10 days'] = '10 giorni piu intensivi';
+$L['Last 24 hours'] = 'Ultime 24 ore';
+$L['Last 30 days'] = 'Ultimi 30 giorni';
+$L['Last 12 months'] = 'Ultimi 12 mesi';
+
+// traffic table columns
+$L['In'] = 'Entrata';
+$L['Out'] = 'Uscita';
+$L['Total'] = 'Totale';
+
+// summary rows
+$L['This hour'] = 'Quest ora';
+$L['This day'] = 'Oggi';
+$L['This month'] = 'Questo mese';
+$L['All time'] = 'Sempre';
+
+// graph text
+$L['Traffic data for'] = 'Dati per';
+$L['bytes in'] = 'bytes entrati';
+$L['bytes out'] = 'bytes usciti';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%l%p';
+$L['datefmt_hours_img'] = '%l';
+$L['datefmt_top'] = '%d %B %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/no.php b/config/vnstat2/vnstat_php_frontend/lang/no.php
new file mode 100644
index 00000000..9f214942
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/no.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'Sammendrag';
+$L['hours'] = 'Timer';
+$L['days'] = 'Dager';
+$L['months'] = 'Måneder';
+
+// main table headers
+$L['Summary'] = 'Sammendrag';
+$L['Top 10 days'] = 'Topp 10 dager';
+$L['Last 24 hours'] = 'Siste 24 timer';
+$L['Last 30 days'] = 'Siste 30 dager';
+$L['Last 12 months'] = 'Siste 12 måneder';
+
+// traffic table columns
+$L['In'] = 'Inn';
+$L['Out'] = 'Ut';
+$L['Total'] = 'Totalt';
+
+// summary rows
+$L['This hour'] = 'Denne time';
+$L['This day'] = 'Idag';
+$L['This month'] = 'Denne måneden';
+$L['All time'] = 'Totalt';
+
+// graph text
+$L['Traffic data for'] = 'Trafikkdata for';
+$L['bytes in'] = 'bytes inn';
+$L['bytes out'] = 'bytes ut';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%H:%M';
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%d %B %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/pl.php b/config/vnstat2/vnstat_php_frontend/lang/pl.php
new file mode 100644
index 00000000..d04e5166
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/pl.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'podsumowanie';
+$L['hours'] = 'godziny';
+$L['days'] = 'dni';
+$L['months'] = 'miesiące';
+
+// main table headers
+$L['Summary'] = 'Podsumowanie';
+$L['Top 10 days'] = 'Top 10 dni';
+$L['Last 24 hours'] = 'Ostatnie 24 godziny';
+$L['Last 30 days'] = 'Ostatnie 30 dni';
+$L['Last 12 months'] = 'Ostatnie 12 miesięcy';
+
+// traffic table columns
+$L['In'] = 'Wyjście';
+$L['Out'] = 'Wejście';
+$L['Total'] = 'Suma';
+
+// summary rows
+$L['This hour'] = 'Ta godzina';
+$L['This day'] = 'Ten dzień';
+$L['This month'] = 'Ten miesiąc';
+$L['All time'] = 'Całość';
+
+// graph text
+$L['Traffic data for'] = 'Transfer dla';
+$L['bytes in'] = 'Wysłane';
+$L['bytes out'] = 'Odebrane';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%l%p';
+$L['datefmt_hours_img'] = '%l';
+$L['datefmt_top'] = '%d %B %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/ru.php b/config/vnstat2/vnstat_php_frontend/lang/ru.php
new file mode 100644
index 00000000..7a105b38
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/ru.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'сводка';
+$L['hours'] = 'по часам';
+$L['days'] = 'по дням';
+$L['months'] = 'по месяцам';
+
+// main table headers
+$L['Summary'] = 'Сводка';
+$L['Top 10 days'] = 'Топ 10 дней';
+$L['Last 24 hours'] = 'Последние 24 часа';
+$L['Last 30 days'] = 'Последние 30 дней';
+$L['Last 12 months'] = 'Последние 12 месяцев';
+
+// traffic table columns
+$L['In'] = 'Входящий';
+$L['Out'] = 'Исходящий';
+$L['Total'] = 'Общий';
+
+// summary rows
+$L['This hour'] = 'Текущий час';
+$L['This day'] = 'Текущий день';
+$L['This month'] = 'Текущий месяц';
+$L['All time'] = 'За все время';
+
+// graph text
+$L['Traffic data for'] = 'Статистика трафика для';
+$L['bytes in'] = 'получено';
+$L['bytes out'] = 'передано';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%H:%M';
+$L['datefmt_hours_img'] = '%H';
+$L['datefmt_top'] = '%d %B %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/lang/sk.php b/config/vnstat2/vnstat_php_frontend/lang/sk.php
new file mode 100644
index 00000000..bc972503
--- /dev/null
+++ b/config/vnstat2/vnstat_php_frontend/lang/sk.php
@@ -0,0 +1,39 @@
+<?php
+
+// sidebar labels
+$L['summary'] = 'zhrnutie';
+$L['hours'] = 'hodiny';
+$L['days'] = 'dni';
+$L['months'] = 'mesiace';
+
+// main table headers
+$L['Summary'] = 'Zhrnutie';
+$L['Top 10 days'] = 'Naj 10 dni';
+$L['Last 24 hours'] = 'Posledných 24 hodin';
+$L['Last 30 days'] = 'Posledných 30 dni';
+$L['Last 12 months'] = 'Posledných 12 mesiacov';
+
+// traffic table columns
+$L['In'] = 'Sťahovanie';
+$L['Out'] = 'Posielanie';
+$L['Total'] = 'Celkom';
+
+// summary rows
+$L['This hour'] = 'Túto hodinu';
+$L['This day'] = 'Tento deň';
+$L['This month'] = 'Tento mesiac';
+$L['All time'] = 'Celkom';
+
+// graph text
+$L['Traffic data for'] = 'Prehlad pre';
+$L['bytes in'] = 'bajtov stiahnuté';
+$L['bytes out'] = 'bajtov poslané';
+
+// date formats
+$L['datefmt_days'] = '%d %B';
+$L['datefmt_days_img'] = '%d';
+$L['datefmt_months'] = '%B %Y';
+$L['datefmt_months_img'] = '%b';
+$L['datefmt_hours'] = '%l%p';
+$L['datefmt_hours_img'] = '%l';
+$L['datefmt_top'] = '%d %B %Y';
diff --git a/config/vnstat2/vnstat_php_frontend/themes/dark/theme.php b/config/vnstat2/vnstat_php_frontend/themes/dark/theme.php
index 6df45cb2..91c6fca0 100644
--- a/config/vnstat2/vnstat_php_frontend/themes/dark/theme.php
+++ b/config/vnstat2/vnstat_php_frontend/themes/dark/theme.php
@@ -1,16 +1,16 @@
<?php
- // A dark colorscheme based on a contribution by Mart Visser
- $colorscheme = array(
- 'image_background' => array( 36, 36, 36, 0 ),
- 'graph_background' => array( 220, 220, 230, 0 ),
- 'graph_background_2' => array( 205, 205, 220, 0 ),
- 'grid_stipple_1' => array( 140, 140, 140, 0 ),
- 'grid_stipple_2' => array( 200, 200, 200, 0 ),
- 'border' => array( 71, 71, 71, 0 ),
- 'text' => array( 255, 255, 255,0 ),
- 'rx' => array( 10, 180, 10, 50 ),
- 'rx_border' => array( 0, 120, 0, 90 ),
- 'tx' => array( 130, 130, 130, 50 ),
- 'tx_border' => array( 60, 60, 60, 90 )
- );
+ // A dark colorscheme based on a contribution by Mart Visser
+ $colorscheme = array(
+ 'image_background' => array( 36, 36, 36, 0 ),
+ 'graph_background' => array( 220, 220, 230, 0 ),
+ 'graph_background_2' => array( 205, 205, 220, 0 ),
+ 'grid_stipple_1' => array( 140, 140, 140, 0 ),
+ 'grid_stipple_2' => array( 200, 200, 200, 0 ),
+ 'border' => array( 71, 71, 71, 0 ),
+ 'text' => array( 255, 255, 255, 0 ),
+ 'rx' => array( 10, 180, 10, 50 ),
+ 'rx_border' => array( 0, 120, 0, 90 ),
+ 'tx' => array( 130, 130, 130, 50 ),
+ 'tx_border' => array( 60, 60, 60, 90 )
+ );
?>
diff --git a/config/vnstat2/vnstat_php_frontend/themes/espresso/theme.php b/config/vnstat2/vnstat_php_frontend/themes/espresso/theme.php
index 3c7818f5..22a361f1 100644
--- a/config/vnstat2/vnstat_php_frontend/themes/espresso/theme.php
+++ b/config/vnstat2/vnstat_php_frontend/themes/espresso/theme.php
@@ -1,17 +1,17 @@
<?php
- // A dark colorscheme based on a contribution by Márcio Bremm
- // It is based also on Espresso (gtkrc theme) by Jesse L. Kay
- $colorscheme = array(
- 'image_background' => array( 065, 061, 057, 0 ),
- 'graph_background' => array( 117, 111, 104, 30 ),
- 'graph_background_2' => array( 128, 122, 102, 30 ),
- 'grid_stipple_1' => array( 140, 140, 140, 0 ),
- 'grid_stipple_2' => array( 200, 200, 200, 0 ),
- 'border' => array( 211, 202, 170, 0 ),
- 'text' => array( 211, 202, 170, 0 ),
- 'rx' => array( 211, 202, 170, 50 ),
- 'rx_border' => array( 80, 40, 40, 90 ),
- 'tx' => array( 163, 156, 131, 50 ),
- 'tx_border' => array( 60, 60, 60, 90 )
- );
+ // A dark colorscheme based on a contribution by Márcio Bremm
+ // It is based also on Espresso (gtkrc theme) by Jesse L. Kay
+ $colorscheme = array(
+ 'image_background' => array( 065, 061, 057, 0 ),
+ 'graph_background' => array( 117, 111, 104, 30 ),
+ 'graph_background_2' => array( 128, 122, 102, 30 ),
+ 'grid_stipple_1' => array( 140, 140, 140, 0 ),
+ 'grid_stipple_2' => array( 200, 200, 200, 0 ),
+ 'border' => array( 211, 202, 170, 0 ),
+ 'text' => array( 211, 202, 170, 0 ),
+ 'rx' => array( 211, 202, 170, 50 ),
+ 'rx_border' => array( 80, 40, 40, 90 ),
+ 'tx' => array( 163, 156, 131, 50 ),
+ 'tx_border' => array( 60, 60, 60, 90 )
+ );
?>
diff --git a/config/vnstat2/vnstat_php_frontend/themes/light/style.css b/config/vnstat2/vnstat_php_frontend/themes/light/style.css
index 28503f1d..6893d2a6 100644
--- a/config/vnstat2/vnstat_php_frontend/themes/light/style.css
+++ b/config/vnstat2/vnstat_php_frontend/themes/light/style.css
@@ -4,6 +4,18 @@ body
padding: 0;
}
+a[href]:link,
+a[href]:visited {
+ color: #00f;
+ text-decoration: none;
+}
+a[href]:hover,
+a[href]:active,
+a[href]:focus {
+ color: #c00;
+ text-decoration: none;
+}
+
#wrap
{
xwidth: 868px;
@@ -26,13 +38,24 @@ body
background-color: #eef;
}
+#sidebar li.iface ul
+{
+ display: none;
+}
+#sidebar li.iface.active ul
+{
+ display: block;
+}
+#sidebar li.iface:hover ul
+{
+ display: block;
+}
#sidebar li.iface
{
- margin: 0;
+ margin: 2px;
padding: 0;
list-style-type: none;
- font-family: 'Trebuchet MS', Verdana, sans-serif;
- font-size: 1em;
+ font-size: 12px;
font-weight: bold;
xborder-top: 1px solid #99b;
border-bottom: 1px solid #99b;
@@ -105,7 +128,8 @@ body
{
padding: 8px;
border-left: 1px solid #99b;
- border-right: 1px solid #99b;
+ border-right: 1px solid #99b;
+ border-bottom: 1px solid #99b;
border-collapse: collapse;
}
diff --git a/config/vnstat2/vnstat_php_frontend/themes/light/theme.php b/config/vnstat2/vnstat_php_frontend/themes/light/theme.php
index 2516c874..63bc234d 100644
--- a/config/vnstat2/vnstat_php_frontend/themes/light/theme.php
+++ b/config/vnstat2/vnstat_php_frontend/themes/light/theme.php
@@ -1,15 +1,15 @@
<?php
- $colorscheme = array(
- 'image_background' => array( 255, 255, 255, 0 ),
- 'graph_background' => array( 220, 220, 230, 0 ),
- 'graph_background_2' => array( 205, 205, 220, 0 ),
- 'grid_stipple_1' => array( 140, 140, 140, 0 ),
- 'grid_stipple_2' => array( 200, 200, 200, 0 ),
- 'border' => array( 0, 0, 0, 0 ),
- 'text' => array( 0, 0, 0, 0 ),
- 'rx' => array( 190, 190, 20, 50 ),
- 'rx_border' => array( 40, 80, 40, 90 ),
- 'tx' => array( 130, 160, 100, 50 ),
- 'tx_border' => array( 80, 40, 40, 90 )
- );
+ $colorscheme = array(
+ 'image_background' => array( 255, 255, 255, 0 ),
+ 'graph_background' => array( 220, 220, 230, 0 ),
+ 'graph_background_2' => array( 205, 205, 220, 0 ),
+ 'grid_stipple_1' => array( 140, 140, 140, 0 ),
+ 'grid_stipple_2' => array( 200, 200, 200, 0 ),
+ 'border' => array( 0, 0, 0, 0 ),
+ 'text' => array( 0, 0, 0, 0 ),
+ 'rx' => array( 190, 190, 20, 50 ),
+ 'rx_border' => array( 40, 80, 40, 90 ),
+ 'tx' => array( 130, 160, 100, 50 ),
+ 'tx_border' => array( 80, 40, 40, 90 )
+ );
?>
diff --git a/config/vnstat2/vnstat_php_frontend/themes/red/theme.php b/config/vnstat2/vnstat_php_frontend/themes/red/theme.php
index 2c9ba6f4..5edacbd2 100644
--- a/config/vnstat2/vnstat_php_frontend/themes/red/theme.php
+++ b/config/vnstat2/vnstat_php_frontend/themes/red/theme.php
@@ -1,16 +1,16 @@
<?php
- // A red colorscheme based on a contribution by Enrico Tröger
- $colorscheme = array(
- 'image_background' => array( 225, 225, 225, 0 ),
- 'graph_background' => array( 220, 220, 230, 0 ),
- 'graph_background_2' => array( 205, 205, 220, 0 ),
- 'grid_stipple_1' => array( 140, 140, 140, 0 ),
- 'grid_stipple_2' => array( 200, 200, 200, 0 ),
- 'border' => array( 0, 0, 0, 0 ),
- 'text' => array( 0, 0, 0, 0 ),
- 'rx' => array( 190, 20, 20, 50 ),
- 'rx_border' => array( 80, 40, 40, 90 ),
- 'tx' => array( 130, 130, 130, 50 ),
- 'tx_border' => array( 60, 60, 60, 90 )
- );
+ // A red colorscheme based on a contribution by Enrico Tröger
+ $colorscheme = array(
+ 'image_background' => array( 225, 225, 225, 0 ),
+ 'graph_background' => array( 220, 220, 230, 0 ),
+ 'graph_background_2' => array( 205, 205, 220, 0 ),
+ 'grid_stipple_1' => array( 140, 140, 140, 0 ),
+ 'grid_stipple_2' => array( 200, 200, 200, 0 ),
+ 'border' => array( 0, 0, 0, 0 ),
+ 'text' => array( 0, 0, 0, 0 ),
+ 'rx' => array( 190, 20, 20, 50 ),
+ 'rx_border' => array( 80, 40, 40, 90 ),
+ 'tx' => array( 130, 130, 130, 50 ),
+ 'tx_border' => array( 60, 60, 60, 90 )
+ );
?>
diff --git a/config/vnstat2/vnstat_php_frontend/vnstat.php b/config/vnstat2/vnstat_php_frontend/vnstat.php
index 9c7e211c..82e0e51f 100644
--- a/config/vnstat2/vnstat_php_frontend/vnstat.php
+++ b/config/vnstat2/vnstat_php_frontend/vnstat.php
@@ -17,10 +17,10 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//
- // see file COPYING or at http://www.gnu.org/licenses/gpl.html
+ // see file COPYING or at http://www.gnu.org/licenses/gpl.html
// for more information.
//
-
+
//
// Valid values for other parameters you can pass to the script.
// Input parameters will always be limited to one of the values listed here.
@@ -39,16 +39,16 @@
{
die('can\'t determine script name!');
}
-
+
$page_list = array('s','h','d','m');
-
+
$graph_list = array('large','small','none');
-
+
$page_title['s'] = T('summary');
$page_title['h'] = T('hours');
$page_title['d'] = T('days');
$page_title['m'] = T('months');
-
+
//
// functions
@@ -88,9 +88,9 @@
$style = DEFAULT_COLORSCHEME;
}
}
-
- function get_vnstat_data()
+
+ function get_vnstat_data($use_label=true)
{
global $iface, $vnstat_bin, $data_dir;
global $hour,$day,$month,$top,$summary;
@@ -100,7 +100,7 @@
if (file_exists("$data_dir/vnstat_dump_$iface"))
{
$vnstat_data = file("$data_dir/vnstat_dump_$iface");
- }
+ }
else
{
$vnstat_data = array();
@@ -126,7 +126,7 @@
//
// extract data
//
- foreach($vnstat_data as $line)
+ foreach($vnstat_data as $line)
{
$d = explode(';', trim($line));
if ($d[0] == 'd')
@@ -135,16 +135,16 @@
$day[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
$day[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
$day[$d[1]]['act'] = $d[7];
- if ($d[2] != 0)
+ if ($d[2] != 0 && $use_label)
{
$day[$d[1]]['label'] = strftime(T('datefmt_days'),$d[2]);
$day[$d[1]]['img_label'] = strftime(T('datefmt_days_img'), $d[2]);
}
- else
+ elseif($use_label)
{
$day[$d[1]]['label'] = '';
- $day[$d[1]]['img_label'] = '';
- }
+ $day[$d[1]]['img_label'] = '';
+ }
}
else if ($d[0] == 'm')
{
@@ -152,15 +152,15 @@
$month[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
$month[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
$month[$d[1]]['act'] = $d[7];
- if ($d[2] != 0)
+ if ($d[2] != 0 && $use_label)
{
$month[$d[1]]['label'] = strftime(T('datefmt_months'), $d[2]);
$month[$d[1]]['img_label'] = strftime(T('datefmt_months_img'), $d[2]);
}
- else
+ else if ($use_label)
{
$month[$d[1]]['label'] = '';
- $month[$d[1]]['img_label'] = '';
+ $month[$d[1]]['img_label'] = '';
}
}
else if ($d[0] == 'h')
@@ -169,27 +169,30 @@
$hour[$d[1]]['rx'] = $d[3];
$hour[$d[1]]['tx'] = $d[4];
$hour[$d[1]]['act'] = 1;
- if ($d[2] != 0)
+ if ($d[2] != 0 && $use_label)
{
$st = $d[2] - ($d[2] % 3600);
$et = $st + 3600;
$hour[$d[1]]['label'] = strftime(T('datefmt_hours'), $st).' - '.strftime(T('datefmt_hours'), $et);
$hour[$d[1]]['img_label'] = strftime(T('datefmt_hours_img'), $d[2]);
}
- else
+ else if ($use_label)
{
$hour[$d[1]]['label'] = '';
$hour[$d[1]]['img_label'] = '';
}
}
else if ($d[0] == 't')
- {
+ {
$top[$d[1]]['time'] = $d[2];
$top[$d[1]]['rx'] = $d[3] * 1024 + $d[5];
$top[$d[1]]['tx'] = $d[4] * 1024 + $d[6];
$top[$d[1]]['act'] = $d[7];
- $top[$d[1]]['label'] = strftime(T('datefmt_top'), $d[2]);
- $top[$d[1]]['img_label'] = '';
+ if($use_label)
+ {
+ $top[$d[1]]['label'] = strftime(T('datefmt_top'), $d[2]);
+ $top[$d[1]]['img_label'] = '';
+ }
}
else
{