aboutsummaryrefslogtreecommitdiffstats
path: root/config/suricata
diff options
context:
space:
mode:
Diffstat (limited to 'config/suricata')
-rw-r--r--config/suricata/disablesid-sample.conf43
-rw-r--r--config/suricata/enablesid-sample.conf39
-rw-r--r--config/suricata/modifysid-sample.conf23
-rw-r--r--config/suricata/suricata.inc1653
-rw-r--r--config/suricata/suricata.priv.inc7
-rw-r--r--config/suricata/suricata.xml157
-rw-r--r--config/suricata/suricata_alerts.js2
-rw-r--r--config/suricata/suricata_alerts.php487
-rw-r--r--config/suricata/suricata_alerts.widget.php105
-rw-r--r--config/suricata/suricata_app_parsers.php348
-rw-r--r--config/suricata/suricata_barnyard.php69
-rw-r--r--config/suricata/suricata_blocked.php174
-rw-r--r--config/suricata/suricata_check_cron_misc.inc63
-rw-r--r--config/suricata/suricata_check_for_rule_updates.php184
-rw-r--r--config/suricata/suricata_define_vars.php25
-rw-r--r--config/suricata/suricata_defs.inc117
-rw-r--r--config/suricata/suricata_download_rules.php2
-rw-r--r--config/suricata/suricata_download_updates.php47
-rw-r--r--config/suricata/suricata_etiqrisk_update.php216
-rw-r--r--config/suricata/suricata_flow_stream.php64
-rw-r--r--config/suricata/suricata_generate_yaml.php234
-rw-r--r--config/suricata/suricata_geoipupdate.php137
-rw-r--r--config/suricata/suricata_global.php160
-rw-r--r--config/suricata/suricata_import_aliases.php4
-rw-r--r--config/suricata/suricata_interfaces.php83
-rw-r--r--config/suricata/suricata_interfaces_edit.php504
-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_libhtp_policy_engine.php22
-rw-r--r--config/suricata/suricata_list_view.php16
-rw-r--r--config/suricata/suricata_logs_browser.php81
-rw-r--r--config/suricata/suricata_logs_mgmt.php203
-rw-r--r--config/suricata/suricata_migrate_config.php387
-rw-r--r--config/suricata/suricata_os_policy_engine.php6
-rw-r--r--config/suricata/suricata_passlist.php47
-rw-r--r--config/suricata/suricata_passlist_edit.php154
-rw-r--r--config/suricata/suricata_post_install.php184
-rw-r--r--config/suricata/suricata_rules.php213
-rw-r--r--config/suricata/suricata_rules_edit.php4
-rw-r--r--config/suricata/suricata_rules_flowbits.php9
-rw-r--r--config/suricata/suricata_rulesets.php275
-rw-r--r--config/suricata/suricata_select_alias.php22
-rw-r--r--config/suricata/suricata_sid_mgmt.php611
-rw-r--r--config/suricata/suricata_suppress.php37
-rw-r--r--config/suricata/suricata_suppress_edit.php18
-rw-r--r--config/suricata/suricata_sync.xml221
-rw-r--r--config/suricata/suricata_uninstall.php57
-rw-r--r--config/suricata/suricata_yaml_template.inc91
49 files changed, 7480 insertions, 1104 deletions
diff --git a/config/suricata/disablesid-sample.conf b/config/suricata/disablesid-sample.conf
new file mode 100644
index 00000000..026f4d94
--- /dev/null
+++ b/config/suricata/disablesid-sample.conf
@@ -0,0 +1,43 @@
+# example disablesid.conf
+
+# Example of modifying state for individual rules
+# 1:1034,1:9837,1:1270,1:3390,1:710,1:1249,3:13010
+
+# Example of modifying state for rule ranges
+# 1:220-1:3264,3:13010-3:13013
+
+# Comments are allowed in this file, and can also be on the same line
+# As the modify state syntax, as long as it is a trailing comment
+# 1:1011 # I Disabled this rule because I could!
+
+# Example of modifying state for MS and cve rules, note the use of the :
+# in cve. This will modify MS09-008, cve 2009-0233, bugtraq 21301,
+# and all MS00 and all cve 2000 related sids! These support regular expression
+# matching only after you have specified what you are looking for, i.e.
+# MS00-<regex> or cve:<regex>, the first section CANNOT contain a regular
+# expression (MS\d{2}-\d+) will NOT work, use the pcre: keyword (below)
+# for this.
+# MS09-008,cve:2009-0233,bugtraq:21301,MS00-\d+,cve:2000-\d+
+
+# Example of using the pcre: keyword to modify rulestate. the pcre keyword
+# allows for full use of regular expression syntax, you do not need to designate
+# with / and all pcre searches are treated as case insensitive. For more information
+# about regular expression syntax: http://www.regular-expressions.info/
+# The following example modifies state for all MS07 through MS10
+# pcre:MS(0[7-9]|10)-\d+
+# pcre:"Joomla"
+
+# Example of modifying state for specific categories entirely.
+# "snort_" limits to Snort VRT rules, "emerging-" limits to
+# Emerging Threats Open rules, "etpro-" limits to ET-PRO rules.
+# "shellcode" with no prefix would match in any vendor set.
+# snort_web-iis,emerging-shellcode,etpro-imap,shellcode
+
+# Any of the above values can be on a single line or multiple lines, when
+# on a single line they simply need to be separated by a ,
+# 1:9837,1:220-1:3264,3:13010-3:13013,pcre:MS(0[0-7])-\d+,MS09-008,cve:2009-0233
+
+# The modifications in this file are for sample/example purposes only and
+# should not actively be used, you need to modify this file to fit your
+# environment.
+
diff --git a/config/suricata/enablesid-sample.conf b/config/suricata/enablesid-sample.conf
new file mode 100644
index 00000000..4cccc5dd
--- /dev/null
+++ b/config/suricata/enablesid-sample.conf
@@ -0,0 +1,39 @@
+# example enablesid.conf
+
+# Example of modifying state for individual rules
+# 1:1034,1:9837,1:1270,1:3390,1:710,1:1249,3:13010
+
+# Example of modifying state for rule ranges
+# 1:220-1:3264,3:13010-3:13013
+
+# Comments are allowed in this file, and can also be on the same line
+# As the modify state syntax, as long as it is a trailing comment
+# 1:1011 # I Disabled this rule because I could!
+
+# Example of modifying state for MS and cve rules, note the use of the :
+# in cve. This will modify MS09-008, cve 2009-0233, bugtraq 21301,
+# and all MS00 and all cve 2000 related sids! These support regular expression
+# matching only after you have specified what you are looking for, i.e.
+# MS00-<regex> or cve:<regex>, the first section CANNOT contain a regular
+# expression (MS\d{2}-\d+) will NOT work, use the pcre: keyword (below)
+# for this.
+# MS09-008,cve:2009-0233,bugtraq:21301,MS00-\d+,cve:2000-\d+
+
+# Example of using the pcre: keyword to modify rulestate. the pcre keyword
+# allows for full use of regular expression syntax, you do not need to designate
+# with / and all pcre searches are treated as case insensitive. For more information
+# about regular expression syntax: http://www.regular-expressions.info/
+# The following example modifies state for all MS07 through MS10
+# pcre:MS(0[7-9]|10)-\d+
+# pcre:"Joomla"
+
+# Example of modifying state for specific categories entirely.
+# "snort_" limits to Snort VRT rules, "emerging-" limits to
+# Emerging Threats Open rules, "etpro-" limits to ET-PRO rules.
+# "shellcode" with no prefix would match in any vendor set.
+# snort_web-iis,emerging-shellcode,etpro-imap,shellcode
+
+# Any of the above values can be on a single line or multiple lines, when
+# on a single line they simply need to be separated by a ,
+# 1:9837,1:220-1:3264,3:13010-3:13013,pcre:MS(0[0-7])-\d+,MS09-008,cve:2009-0233
+
diff --git a/config/suricata/modifysid-sample.conf b/config/suricata/modifysid-sample.conf
new file mode 100644
index 00000000..d59f84ba
--- /dev/null
+++ b/config/suricata/modifysid-sample.conf
@@ -0,0 +1,23 @@
+# example modifysid.conf
+#
+# formatting is simple
+# <sid or sid list> "what I'm replacing" "what I'm replacing it with"
+#
+# Note that this will only work with GID:1 rules, simply because modifying
+# GID:3 SO stub rules would not actually affect the rule.
+#
+# If you are attempting to change rulestate (enable,disable) from here
+# then you are doing it wrong. Do this from within the respective
+# rulestate modification configuration files.
+
+# the following applies to sid 10010 only and represents what would normally
+# be s/to_client/from_server/
+# 10010 "to_client" "from_server"
+
+# the following would replace HTTP_PORTS with HTTPS_PORTS for ALL GID:1
+# rules
+# "HTTP_PORTS" "HTTPS_PORTS"
+
+# multiple sids can be specified as noted below:
+# 302,429,1821 "\$EXTERNAL_NET" "\$HOME_NET"
+
diff --git a/config/suricata/suricata.inc b/config/suricata/suricata.inc
index c767f2d0..66c1e799 100644
--- a/config/suricata/suricata.inc
+++ b/config/suricata/suricata.inc
@@ -44,37 +44,12 @@ 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;
-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
-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');
-
-// Rule set download filenames and prefixes
-define('ET_DNLD_FILENAME', 'emerging.rules.tar.gz');
-define('ETPRO_DNLD_FILENAME', 'etpro.rules.tar.gz');
-define('VRT_DNLD_FILENAME', 'snortrules-snapshot-edge.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-');
+// Suricata GUI needs some extra PHP memory space to manipulate large rules arrays
+ini_set("memory_limit", "256M");
function suricata_generate_id() {
global $config;
@@ -130,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");
}
}
@@ -142,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;
@@ -154,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") {
/**************************************************************/
@@ -178,7 +210,6 @@ function suricata_reload_config($suricatacfg, $signal="USR2") {
/******************************************************/
if (isvalidpid("{$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid")) {
log_error("[Suricata] Suricata LIVE RULE RELOAD initiated for {$suricatacfg['descr']} ({$if_real})...");
-// sigkillbypid("{$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid", $signal);
mwexec_bg("/bin/pkill -{$signal} -F {$g['varrun_path']}/suricata_{$if_real}{$suricata_uuid}.pid");
}
}
@@ -207,7 +238,6 @@ function suricata_barnyard_reload_config($suricatacfg, $signal="HUP") {
/******************************************************/
if (isvalidpid("{$g['varrun_path']}/barnyard2_{$if_real}{$suricata_uuid}.pid")) {
log_error("[Suricata] Barnyard2 CONFIG RELOAD initiated for {$suricatacfg['descr']} ({$if_real})...");
-// sigkillbypid("{$g['varrun_path']}/barnyard2_{$if_real}{$suricata_uuid}.pid", $signal);
mwexec_bg("/bin/pkill -{$signal} -F {$g['varrun_path']}/barnyard2_{$if_real}{$suricata_uuid}.pid");
}
}
@@ -250,7 +280,7 @@ function suricata_find_list($find_name, $type = 'passlist') {
return array();
}
-function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
+function suricata_build_list($suricatacfg, $listname = "", $passlist = false, $externallist = false) {
/***********************************************************/
/* The default is to build a HOME_NET variable unless */
@@ -260,9 +290,10 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
global $config, $g, $aliastable, $filterdns;
$home_net = array();
- if ($listname == 'default' || empty($listname)) {
+ if (!$externallist && ($listname == 'default' || empty($listname))) {
$localnet = 'yes'; $wanip = 'yes'; $wangw = 'yes'; $wandns = 'yes'; $vips = 'yes'; $vpns = 'yes';
- } else {
+ }
+ else {
$list = suricata_find_list($listname);
if (empty($list))
return $list;
@@ -276,21 +307,25 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
$home_net = explode(" ", trim(filter_expand_alias($list['address'])));
}
- // Always add loopback to HOME_NET and passlist (ftphelper)
- if (!in_array("127.0.0.1", $home_net))
- $home_net[] = "127.0.0.1";
+ // Always add loopback to HOME_NET and passlist
+ if (!$externallist) {
+ if (!in_array("127.0.0.1/32", $home_net))
+ $home_net[] = "127.0.0.1/32";
+ if (!in_array("::1/128", $home_net))
+ $home_net[] = "::1/128";
+ }
/********************************************************************/
/* Always put the interface running Suricata in HOME_NET and */
- /* whitelist unless it's the WAN. WAN options are handled further */
+ /* pass list unless it's the WAN. WAN options are handled further */
/* down. If the user specifically chose not to include LOCAL_NETS */
/* in the PASS LIST, then do not include the Suricata interface */
/* subnet in the PASS LIST. We do include the actual LAN interface */
/* IP for Suricata, though, to prevent locking out the firewall. */
/********************************************************************/
$suricataip = get_interface_ip($suricatacfg['interface']);
- if (!$whitelist || $localnet == 'yes' || empty($localnet)) {
- if (is_ipaddr($suricataip)) {
+ if (($externallist && $localnet == 'yes') || (!$externallist && (!$passlist || $localnet == 'yes' || empty($localnet)))) {
+ if (is_ipaddrv4($suricataip)) {
if ($suricatacfg['interface'] <> "wan") {
$sn = get_interface_subnet($suricatacfg['interface']);
$ip = gen_subnet($suricataip, $sn) . "/{$sn}";
@@ -299,15 +334,19 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
}
}
}
- else {
- if (is_ipaddr($suricataip)) {
- if (!in_array($suricataip, $home_net))
- $home_net[] = $suricataip;
+ elseif (!$externallist && $localnet != 'yes') {
+ if (is_ipaddrv4($suricataip)) {
+ if (!in_array($suricataip . "/32", $home_net))
+ $home_net[] = $suricataip . "/32";
}
}
+ // Grab the IPv6 address if we have one assigned
$suricataip = get_interface_ipv6($suricatacfg['interface']);
- if (!$whitelist || $localnet == 'yes' || empty($localnet)) {
+ // Trim off the interface designation (e.g., %em1) if present
+ if (strpos($suricataip, "%") !== FALSE)
+ $suricataip = substr($suricataip, 0, strpos($suricataip, "%"));
+ if (($externallist && $localnet == 'yes') || (!$externallist && (!$passlist || $localnet == 'yes' || empty($localnet)))) {
if (is_ipaddrv6($suricataip)) {
if ($suricatacfg['interface'] <> "wan") {
$sn = get_interface_subnetv6($suricatacfg['interface']);
@@ -317,14 +356,24 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
}
}
}
- else {
+ elseif (!$externallist && $localnet != 'yes') {
if (is_ipaddrv6($suricataip)) {
- if (!in_array($suricataip, $home_net))
- $home_net[] = $suricataip;
+ if (!in_array($suricataip . "/128", $home_net))
+ $home_net[] = $suricataip . "/128";
}
}
- if (!$whitelist || $localnet == 'yes' || empty($localnet)) {
+ // Add link-local address if user included locally-attached networks
+ $suricataip = get_interface_linklocal($suricatacfg['interface']);
+ if (!empty($suricataip) && $localnet == 'yes') {
+ // Trim off the interface designation (e.g., %em1) if present
+ if (strpos($suricataip, "%") !== FALSE)
+ $suricataip = substr($suricataip, 0, strpos($suricataip, "%"));
+ if (!in_array($suricataip . "/128", $home_net))
+ $home_net[] = $suricataip . "/128";
+ }
+
+ if (($$externallist && $localnet == 'yes') || (!$externallist && (!$passlist || $localnet == 'yes' || empty($localnet)))) {
/*************************************************************************/
/* Iterate through the interface list and write out pass list items and */
/* also compile a HOME_NET list of all local interfaces for suricata. */
@@ -336,58 +385,89 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
if ($int == "wan")
continue;
$subnet = get_interface_ip($int);
- if (is_ipaddr($subnet)) {
+ if (is_ipaddrv4($subnet)) {
$sn = get_interface_subnet($int);
$ip = gen_subnet($subnet, $sn) . "/{$sn}";
if (!in_array($ip, $home_net))
$home_net[] = $ip;
}
- if ($int == "wan")
- continue;
+
$subnet = get_interface_ipv6($int);
+ // Trim off the interface designation (e.g., %em1) if present
+ if (strpos($subnet, "%") !== FALSE)
+ $subnet = substr($subnet, 0, strpos($subnet, "%"));
if (is_ipaddrv6($subnet)) {
$sn = get_interface_subnetv6($int);
$ip = gen_subnetv6($subnet, $sn). "/{$sn}";
if (!in_array($ip, $home_net))
$home_net[] = $ip;
}
+
+ // Add link-local address
+ $suricataip = get_interface_linklocal($int);
+ if (!empty($suricataip)) {
+ // Trim off the interface designation (e.g., %em1) if present
+ if (strpos($suricataip, "%") !== FALSE)
+ $suricataip = substr($suricataip, 0, strpos($suricataip, "%"));
+ if (!in_array($suricataip . "/128", $home_net))
+ $home_net[] = $suricataip . "/128";
+ }
}
}
if ($wanip == 'yes') {
$ip = get_interface_ip("wan");
- if (is_ipaddr($ip)) {
- if (!in_array($ip, $home_net))
- $home_net[] = $ip;
+ if (is_ipaddrv4($ip)) {
+ if (!in_array($ip . "/32", $home_net))
+ $home_net[] = $ip . "/32";
}
$ip = get_interface_ipv6("wan");
+ // Trim off the interface designation (e.g., %em1) if present
+ if (strpos($ip, "%") !== FALSE)
+ $ip = substr($ip, 0, strpos($ip, "%"));
if (is_ipaddrv6($ip)) {
- if (!in_array($ip, $home_net))
- $home_net[] = $ip;
+ if (!in_array($ip . "/128", $home_net))
+ $home_net[] = $ip . "/128";
+ }
+ // Explicitly grab the WAN Link-Local address
+ $ip = get_interface_linklocal("wan");
+ if (!empty($ip)) {
+ // Trim off the interface designation (e.g., %em1) if present
+ if (strpos($ip, "%") !== FALSE)
+ $ip = substr($ip, 0, strpos($ip, "%"));
+ if (!in_array($ip . "/128", $home_net))
+ $home_net[] = $ip . "/128";
}
}
if ($wangw == 'yes') {
// Grab the default gateway if set
$default_gw = exec("/sbin/route -n get default |grep 'gateway:' | /usr/bin/awk '{ print $2 }'");
- if (is_ipaddr($default_gw) && !in_array($default_gw, $home_net))
- $home_net[] = $default_gw;
- if (is_ipaddrv6($default_gw) && !in_array($default_gw, $home_net))
- $home_net[] = $default_gw;
+ if (is_ipaddrv4($default_gw) && !in_array($default_gw . "/32", $home_net))
+ $home_net[] = $default_gw . "/32";
+ if (is_ipaddrv6($default_gw) && !in_array($default_gw . "/128", $home_net))
+ $home_net[] = $default_gw . "/128";
// Get any other interface gateway and put in $HOME_NET if not there already
$gw = get_interface_gateway($suricatacfg['interface']);
- if (is_ipaddr($gw) && !in_array($gw, $home_net))
- $home_net[] = $gw;
+ if (is_ipaddrv4($gw) && !in_array($gw . "/32", $home_net))
+ $home_net[] = $gw . "/32";
$gw = get_interface_gateway_v6($suricatacfg['interface']);
- if (is_ipaddrv6($gw) && !in_array($gw, $home_net))
- $home_net[] = $gw;
+ // Trim off the interface designation (e.g., %em1) if present
+ if (strpos($gw, "%") !== FALSE)
+ $gw = substr($gw, 0, strpos($gw, "%"));
+ if (is_ipaddrv6($gw) && !in_array($gw . "/128", $home_net))
+ $home_net[] = $gw . "/128";
}
if ($wandns == 'yes') {
- // Add DNS server for WAN interface to whitelist
+ // Add DNS server for WAN interface to Pass List
$dns_servers = get_dns_servers();
foreach ($dns_servers as $dns) {
+ if (is_ipaddrv4($dns))
+ $dns .= "/32";
+ elseif (is_ipaddrv6($dns))
+ $dns .= "/128";
if ($dns && !in_array($dns, $home_net))
$home_net[] = $dns;
}
@@ -405,7 +485,7 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
}
}
- // grab a list of vpns and whitelist if user desires
+ // Grab a list of vpns enabled - these come back as CIDR mask networks
if ($vpns == 'yes') {
$vpns_list = filter_get_vpns_list();
if (!empty($vpns_list)) {
@@ -435,10 +515,61 @@ function suricata_build_list($suricatacfg, $listname = "", $passlist = false) {
return $valresult;
}
+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;
+
+ 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;
+}
+
function suricata_rules_up_install_cron($should_install=true) {
global $config, $g;
- $command = "/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/www/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'];
@@ -504,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");
}
@@ -517,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") {
@@ -600,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("pfctl -t {$suri_pf_table} -T expire" , 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 -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");
}
}
@@ -617,46 +777,39 @@ 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
suricata_create_rc();
- $suricataglob = $config['installedpackages']['suricata']['config'][0];
// 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);
- write_config();
- configure_cron();
-
// Do not attempt package sync if reinstalling package or booting
-// if (!$g['suricata_postinstall'] && !$g['booting'])
-// suricata_sync_on_changes();
-
- conf_mount_ro();
+ if (!isset($g['suricata_postinstall']) && !$g['booting'])
+ suricata_sync_on_changes();
}
function suricata_load_suppress_sigs($suricatacfg, $track_by=false) {
@@ -791,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);
}
}
@@ -933,7 +1086,7 @@ function suricata_build_sid_msg_map($rules_path, $sid_file) {
natcasesort($sidMap);
// Now print the result to the supplied file
- @file_put_contents($sid_file, "#v2\n# sid-msg.map file auto-generated by Snort.\n\n");
+ @file_put_contents($sid_file, "#v2\n# sid-msg.map file auto-generated by Suricata.\n\n");
@file_put_contents($sid_file, array_values($sidMap), FILE_APPEND);
}
@@ -1047,11 +1200,11 @@ function suricata_load_rules_map($rules_path) {
if (empty($rules_path))
return $map_ref;
- /***************************************************************
+ /************************************************************************************
* Read all the rules into the map array.
* The structure of the map array is:
*
- * map[gid][sid]['rule']['category']['disabled']['flowbits']
+ * map[gid][sid]['rule']['category']['action']['disabled']['managed']['flowbits']
*
* where:
* gid = Generator ID from rule, or 1 if general text
@@ -1062,9 +1215,11 @@ function suricata_load_rules_map($rules_path) {
* action = alert, drop, reject or pass
* disabled = 1 if rule is disabled (commented out), 0 if
* rule is enabled
+ * managed = 1 if rule is auto-managed by SID MGMT process,
+ * 0 if not auto-managed
* flowbits = Array of applicable flowbits if rule contains
* flowbits options
- ***************************************************************/
+ ************************************************************************************/
// First check if we were passed a directory, a single file
// or an array of filenames to read. Set our $rule_files
@@ -1537,6 +1692,854 @@ function suricata_load_vrt_policy($policy, $all_rules=null) {
return $vrt_policy_rules;
}
+function suricata_parse_sidconf_file($sidconf_file) {
+
+ /**********************************************/
+ /* This function loads and processes the file */
+ /* specified by '$sidconf_file'. The file is */
+ /* assumed to contain valid instructions for */
+ /* matching rule SIDs as supported by the */
+ /* Oinkmaster and PulledPork utilities. */
+ /* */
+ /* $sidconf_file ==> full path and name of */
+ /* file to process */
+ /* */
+ /* Returns ==> an array containing */
+ /* SID modifier tokens */
+ /**********************************************/
+
+ $buf = "";
+ $sid_mods = array();
+
+ $fd = fopen("{$sidconf_file}", "r");
+ if ($fd == FALSE) {
+ log_error("[Suricata] Failed to open SID MGMT file '{$sidconf_file}' for processing.");
+ return $sid_mods;
+ }
+
+ // Read and parse the conf file line-by-line
+ while (($buf = fgets($fd)) !== FALSE) {
+ $line = array();
+
+ // Skip any lines that may be just spaces.
+ if (trim($buf, " \r\n") == "")
+ continue;
+
+ // Skip line with leading "#" since it's a comment
+ if (preg_match('/^\s*#/', $buf))
+ continue;
+
+ // Trim off any trailing comment
+ $line = explode("#", $buf);
+
+ // Trim leading and trailing spaces plus newline and any carriage returns
+ $buf = trim($line[0], ' \r\n');
+
+ // Now split the SID mod arguments at the commas, if more than one
+ // per line, and add to our $sid_mods array.
+ $line = explode(",", $buf);
+ foreach ($line as $ent)
+ $sid_mods[] = trim($ent);
+ }
+
+ // Close the file, release unneeded memory and return
+ // the array of SID mod tokens parsed from the file.
+ fclose($fd);
+ unset($line, $buf);
+ return $sid_mods;
+}
+
+function suricata_sid_mgmt_auto_categories($suricatacfg, $log_results = FALSE) {
+
+ /****************************************************/
+ /* This function parses any auto-SID conf files */
+ /* configured for the interface and returns an */
+ /* array of rule categories adjusted from the */
+ /* ['enabled_rulesets'] element in the config for */
+ /* the interface in accordance with the contents */
+ /* of the SID Mgmt conf files. */
+ /* */
+ /* The returned array shows which files should be */
+ /* removed and which should be added to the list */
+ /* used when building the enforcing ruleset. */
+ /* */
+ /* $suricatacfg ==> pointer to interface */
+ /* configuration info */
+ /* $log_results ==> [optional] log results to */
+ /* 'sid_changes.log' in the */
+ /* interface directory in */
+ /* /var/log/suricata when TRUE */
+ /* */
+ /* Returns ==> array of category file names */
+ /* for the interface. The keys */
+ /* are category file names and */
+ /* the corresponding values show */
+ /* if the file should be added */
+ /* or removed from the enabled */
+ /* rulesets list. */
+ /* */
+ /* Example - */
+ /* $changes[file] = 'enabled' */
+ /* */
+ /****************************************************/
+
+ global $config;
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
+ $sid_mods = array();
+ $enables = array();
+ $disables = array();
+
+ // Check if auto-mgmt of SIDs is enabled, exit if not
+ if ($config['installedpackages']['suricata']['config'][0]['auto_manage_sids'] != 'on')
+ return array();
+ if (empty($suricatacfg['disable_sid_file']) && empty($suricatacfg['enable_sid_file']))
+ return array();
+
+ // Configure the interface's logging subdirectory if log results is enabled
+ if ($log_results == TRUE)
+ $log_file = SURICATALOGDIR . $suricatalogdir . "suricata_" . get_real_interface($suricatacfg['interface']) . "{$suricatacfg['uuid']}/sid_changes.log";
+ else
+ $log_file = NULL;
+
+ // Get the list of currently enabled categories for the interface
+ if (!empty($suricatacfg['rulesets']))
+ $enabled_cats = explode("||", $suricatacfg['rulesets']);
+
+ if ($log_results == TRUE) {
+ error_log(gettext("********************************************************\n"), 3, $log_file);
+ error_log(gettext("Starting auto RULE CATEGORY management for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) ."\n"), 3, $log_file);
+ error_log(gettext("Start Time: " . date("Y-m-d H:i:s") . "\n"), 3, $log_file);
+ }
+
+ switch ($suricatacfg['sid_state_order']) {
+ case "disable_enable":
+ if (!empty($suricatacfg['disable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing disable_sid file: {$suricatacfg['disable_sid_file']}\n"), 3, $log_file);
+
+ // Attempt to open the 'disable_sid_file' for the interface
+ if (!file_exists("{$suricata_sidmods_dir}{$suricatacfg['disable_sid_file']}")) {
+ log_error(gettext("[Suricata] Error - unable to open 'disable_sid_file' \"{$suricatacfg['disable_sid_file']}\" specified for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ if ($log_results == TRUE)
+ error_log(gettext("Unable to open disable_sid file \"{$suricatacfg['disable_sid_file']}\".\n"), 3, $log_file);
+ }
+ else
+ $sid_mods = suricata_parse_sidconf_file("{$suricata_sidmods_dir}{$suricatacfg['disable_sid_file']}");
+
+ if (!empty($sid_mods))
+ $disables = suricata_get_auto_category_mods($enabled_cats, $sid_mods, "disable", $log_results, $log_file);
+ elseif ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext("WARNING: no valid SID match tokens found in file \"{$suricatacfg['disable_sid_file']}\".\n"), 3, $log_file);
+ }
+ }
+ if (!empty($suricatacfg['enable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing enable_sid file: {$suricatacfg['enable_sid_file']}\n"), 3, $log_file);
+
+ // Attempt to open the 'enable_sid_file' for the interface
+ if (!file_exists("{$suricata_sidmods_dir}{$suricatacfg['enable_sid_file']}")) {
+ log_error(gettext("[Suricata] Error - unable to open 'enable_sid_file' \"{$suricatacfg['enable_sid_file']}\" specified for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ if ($log_results == TRUE)
+ error_log(gettext("Unable to open enable_sid file \"{$suricatacfg['enable_sid_file']}\".\n"), 3, $log_file);
+ }
+ else
+ $sid_mods = suricata_parse_sidconf_file("{$suricata_sidmods_dir}{$suricatacfg['enable_sid_file']}");
+
+ if (!empty($sid_mods))
+ $enables = suricata_get_auto_category_mods($enabled_cats, $sid_mods, "enable", $log_results, $log_file);
+ elseif ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext("WARNING: no valid SID match tokens found in file \"{$suricatacfg['enable_sid_file']}\".\n"), 3, $log_file);
+ }
+ }
+ break;
+
+ case "enable_disable":
+ if (!empty($suricatacfg['enable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing enable_sid file: {$suricatacfg['enable_sid_file']}\n"), 3, $log_file);
+
+ // Attempt to open the 'enable_sid_file' for the interface
+ if (!file_exists("{$suricata_sidmods_dir}{$suricatacfg['enable_sid_file']}")) {
+ log_error(gettext("[Suricata] Error - unable to open 'enable_sid_file' \"{$suricatacfg['enable_sid_file']}\" specified for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ if ($log_results == TRUE)
+ error_log(gettext("Unable to open enable_sid file \"{$suricatacfg['enable_sid_file']}\".\n"), 3, $log_file);
+ }
+ else
+ $sid_mods = suricata_parse_sidconf_file("{$suricata_sidmods_dir}{$suricatacfg['enable_sid_file']}");
+
+ if (!empty($sid_mods))
+ $enables = suricata_get_auto_category_mods($enabled_cats, $sid_mods, "enable", $log_results, $log_file);
+ elseif ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext("WARNING: no valid SID match tokens found in file \"{$suricatacfg['enable_sid_file']}\".\n"), 3, $log_file);
+ }
+ }
+ if (!empty($suricatacfg['disable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing disable_sid file: {$suricatacfg['disable_sid_file']}\n"), 3, $log_file);
+
+ // Attempt to open the 'disable_sid_file' for the interface
+ if (!file_exists("{$suricata_sidmods_dir}{$suricatacfg['disable_sid_file']}")) {
+ log_error(gettext("[Suricata] Error - unable to open 'disable_sid_file' \"{$suricatacfg['disable_sid_file']}\" specified for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ if ($log_results == TRUE)
+ error_log(gettext("Unable to open disable_sid file \"{$suricatacfg['disable_sid_file']}\".\n"), 3, $log_file);
+ }
+ else
+ $sid_mods = suricata_parse_sidconf_file("{$suricata_sidmods_dir}{$suricatacfg['disable_sid_file']}");
+
+ if (!empty($sid_mods))
+ $disables = suricata_get_auto_category_mods($enabled_cats, $sid_mods, "disable", $log_results, $log_file);
+ elseif ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext("WARNING: no valid SID match tokens found in file \"{$suricatacfg['disable_sid_file']}\".\n"), 3, $log_file);
+ }
+ }
+ break;
+
+ default:
+ log_error(gettext("[Suricata] Unrecognized 'sid_state_order' value. Skipping auto CATEGORY mgmt step for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ if ($log_results == TRUE) {
+ error_log(gettext("ERROR: unrecognized 'sid_state_order' value. Skipping auto CATEGORY mgmt step for ") . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']). ".\n", 3, $log_file);
+ }
+ }
+
+ if ($log_results == TRUE) {
+ error_log(gettext("End Time: " . date("Y-m-d H:i:s") . "\n"), 3, $log_file);
+ error_log(gettext("********************************************************\n\n"), 3, $log_file);
+ }
+
+ // Return the required rule category modifications as an array;
+ return array_merge($enables, $disables);
+}
+
+function suricata_get_auto_category_mods($categories, $sid_mods, $action, $log_results = FALSE, $log_file = NULL) {
+
+ /****************************************************/
+ /* This function parses the provided SID mod tokens */
+ /* in $sid_mods and returns an array of category */
+ /* files that must be added ('enabled') or removed */
+ /* ('disabled') from the provided $categories list */
+ /* of enabled rule categories as determined by the */
+ /* content of the SID Mgmt tokens in $sid_mods. */
+ /* */
+ /* The returned array shows which files should be */
+ /* removed and which should be added to the list */
+ /* used when building the enforcing ruleset. */
+ /* */
+ /* $categories ==> array of currently enabled */
+ /* ruleset categories */
+ /* $sid_mods ==> array of SID modification */
+ /* tokens */
+ /* $action ==> modification action for */
+ /* matching category targets: */
+ /* 'enable' or 'disable' */
+ /* $log_results ==> [optional] 'yes' to log */
+ /* results to $log_file */
+ /* $log_file ==> full path and filename of log */
+ /* file to write to */
+ /* */
+ /* Returns ==> array of category file names */
+ /* for the interface. The keys */
+ /* are category file names and */
+ /* the corresponding values show */
+ /* if the file should be added */
+ /* or removed from the enabled */
+ /* rulesets list. */
+ /* */
+ /* Example - */
+ /* $changes[file] = 'enabled' */
+ /* */
+ /****************************************************/
+
+ $suricatadir = SURICATADIR;
+ $all_cats = array();
+ $changes = array();
+ $counter = 0;
+ $matchcount = 0;
+
+ // Get a list of all possible categories by loading all rules files
+ foreach (array( VRT_FILE_PREFIX, ET_OPEN_FILE_PREFIX, ET_PRO_FILE_PREFIX, GPL_FILE_PREFIX ) as $prefix) {
+ $files = glob("{$suricatadir}rules/{$prefix}*.rules");
+ foreach ($files as $file)
+ $all_cats[] = basename($file);
+ }
+
+ // Walk the SID mod tokens and decode looking for rule
+ // category enable/disable changes.
+ foreach ($sid_mods as $tok) {
+ $matches = array();
+ // Test the SID token for a GID:SID range and skip if true
+ if (preg_match('/^(\d+):(\d+)-\1:(\d+)/', $tok))
+ continue;
+ // Test the token for a single GID:SID and skip if true
+ elseif (preg_match('/^(\d+):(\d+)$/', $tok))
+ continue;
+ // Test the token for the PCRE: keyword and skip if true
+ elseif (preg_match('/(^pcre\:)(.+)/i', $tok))
+ continue;
+ // Test the token for the MS reference keyword and skip if true
+ elseif (preg_match('/^MS\d+-.+/i', $tok))
+ continue;
+ // Test the token for other keywords delimited with a colon and skip if true
+ elseif (preg_match('/^[a-xA-X]+\:.+/', $tok))
+ continue;
+ // Test the SID token for a rule category name. Anything that
+ // failed to match above is considered a potential category name.
+ elseif (preg_match('/[a-xA-X]+(-|\w).*/', $tok, $matches)) {
+ $counter++;
+ $regex = "/" . preg_quote(trim($matches[0]), '/') . "/i";
+ // Search through the $all_cats array for any matches to the regex
+ $matches = preg_grep($regex, $all_cats);
+
+ // See if any matches are in the $categories array
+ foreach ($matches as $cat) {
+ switch ($action) {
+ case 'enable':
+ if (!isset($changes[$cat])) {
+ $changes[$cat] = 'enabled';
+ if ($log_results == TRUE && !empty($log_file))
+ error_log(gettext(" Enabled rule category: {$cat}\n"), 3, $log_file);
+ $matchcount++;
+ }
+ break;
+
+ case 'disable':
+ if (!isset($changes[$cat])) {
+ $changes[$cat] = 'disabled';
+ if ($log_results == TRUE && !empty($log_file))
+ error_log(gettext(" Disabled rule category: {$cat}\n"), 3, $log_file);
+ $matchcount++;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ else {
+ if ($log_results == TRUE && !empty($log_file))
+ error_log(gettext("WARNING: unrecognized token '{$tok}' encountered while processing an automatic SID MGMT file.\n"), 3, $log_file);
+ }
+ }
+
+ if ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext(" Parsed {$counter} potential Rule Categories to match from the list of tokens.\n"), 3, $log_file);
+ error_log(gettext(" " . ucfirst($action) . "d {$matchcount} matching Rule Categories.\n"), 3, $log_file);
+ }
+
+ // Release memory no longer needed
+ unset($all_cats, $matches);
+
+ // Return array of rule category file changes
+ return $changes;
+}
+
+function suricata_modify_sid_state(&$rule_map, $sid_mods, $action, $log_results = FALSE, $log_file = NULL) {
+
+ /**********************************************/
+ /* This function walks the provided array of */
+ /* SID modification tokens and locates the */
+ /* target SID or SIDs in the $rule_map array. */
+ /* It then performs the change specified by */
+ /* $action on the target SID or SIDs. */
+ /* */
+ /* $rule_map ==> reference to array of */
+ /* current rules */
+ /* $sid_mods ==> array of SID modification */
+ /* tokens */
+ /* $action ==> modification action for */
+ /* matching SID targets: */
+ /* 'enable' or 'disable' */
+ /* $log_results ==> [optional] 'yes' to log */
+ /* results to $log_file */
+ /* $log_file ==> full path and filename */
+ /* of log file to write to */
+ /* */
+ /* On Return ==> $rule_map array modified */
+ /* by changing state for */
+ /* matching SIDs. */
+ /* */
+ /* Returns a two-dimension */
+ /* array of matching GID:SID */
+ /* pairs. */
+ /**********************************************/
+
+ $sids = array();
+
+ // If no rules in $rule_map or mods in $sid_mods,
+ // then nothing to do.
+ if (empty($rule_map) || empty($sid_mods))
+ return $sids;
+
+ // Validate the action keyword as we only accept
+ // 'enable' and 'disable' as valid.
+ switch ($action) {
+
+ case "enable":
+ break;
+
+ case "disable":
+ break;
+
+ default:
+ log_error(gettext("[Suricata] Error - unknown action '{$action}' supplied to suricata_modify_sid_state() function...no SIDs modified."));
+ return $sids;
+ }
+
+ // Walk the SID mod tokens and decode each one
+ foreach ($sid_mods as $tok) {
+ $matches = array();
+ // Test the SID token for a GID:SID range
+ if (preg_match('/^(\d+):(\d+)-\1:(\d+)/', $tok, $matches)) {
+ // It was a range, so find all the intervening SIDs
+ $gid = trim($matches[1]);
+ $lsid = trim($matches[2]);
+ $usid = trim($matches[3]);
+ $sids[$gid][$lsid] = $action;
+ while ($lsid < $usid) {
+ $lsid++;
+ $sids[$gid][$lsid] = $action;
+ }
+ }
+ // Test the SID token for a single GID:SID
+ elseif (preg_match('/^(\d+):(\d+)$/', $tok, $matches)) {
+ // It's a single GID:SID, so grab it
+ $sids[$matches[1]][$matches[2]] = $action;
+ }
+ // Test the SID token for the PCRE: keyword
+ elseif (preg_match('/(^pcre\:)(.+)/i', $tok, $matches)) {
+ $regex = '/' . preg_quote($matches[2], '/') . '/i';
+
+ // Now search through the $rule_map in the 'rule'
+ // element for any matches to the regex and get
+ // the GID:SID.
+ foreach ($rule_map as $k1 => $rulem) {
+ foreach ($rulem as $k2 => $v) {
+ if (preg_match($regex, $v['rule'])) {
+ $sids[$k1][$k2] = $action;
+ }
+ }
+ }
+ }
+ // Test the SID token for the MS reference keyword
+ elseif (preg_match('/^MS\d+-.+/i', $tok, $matches)) {
+ $regex = "/" . preg_quote($matches[0], '/') . "/i";
+
+ // Now search through the $rule_map in the 'rule'
+ // element for any matches to the regex and get
+ // the GID:SID.
+ foreach ($rule_map as $k1 => $rulem) {
+ foreach ($rulem as $k2 => $v) {
+ if (preg_match($regex, $v['rule'])) {
+ $sids[$k1][$k2] = $action;
+ }
+ }
+ }
+ }
+ // Test the SID token for other keywords delimited with a colon
+ elseif (preg_match('/^[a-xA-X]+\:.+/', $tok, $matches)) {
+ $regex = "/" . str_replace(':', ",", preg_quote($matches[0], '/')) . "/i";
+
+ // Now search through the $rule_map in the 'rule'
+ // element for any matches to the regex and get
+ // the GID:SID.
+ foreach ($rule_map as $k1 => $rulem) {
+ foreach ($rulem as $k2 => $v) {
+ if (preg_match($regex, $v['rule'])) {
+ $sids[$k1][$k2] = $action;
+ }
+ }
+ }
+ }
+ // Test the SID token for a rule category name. Anything that
+ // failed to match above is considered a potential category name.
+ elseif (preg_match('/[a-xA-X]+(-|\w).*/', $tok, $matches)) {
+ $regex = "/" . preg_quote(trim($matches[0]), '/') . "/i";
+ // Now search through the $rule_map in the 'category'
+ // element for any matches to the regex and get
+ // the GID:SID.
+ foreach ($rule_map as $k1 => $rulem) {
+ foreach ($rulem as $k2 => $v) {
+ if (preg_match($regex, $v['category'] . ".rules")) {
+ $sids[$k1][$k2] = $action;
+ }
+ }
+ }
+ }
+ else {
+ if ($log_results == TRUE && !empty($log_file))
+ error_log(gettext("WARNING: unrecognized token '{$tok}' encountered while processing an automatic SID MGMT file.\n"), 3, $log_file);
+ }
+ }
+
+ // Change state of all the matching GID:SID pairs we found
+ // above in the $rule_map array passed to us.
+ $modcount = $changecount = 0;
+ $counter = count($sids, COUNT_RECURSIVE) - count($sids);
+
+ if ($log_results == TRUE && !empty($log_file))
+ error_log(gettext(" Parsed {$counter} potential SIDs to match from the provided list of tokens.\n"), 3, $log_file);
+
+ foreach (array_keys($sids) as $k1) {
+ foreach (array_keys($sids[$k1]) as $k2) {
+ if (isset($rule_map[$k1][$k2])) {
+ if ($action == 'enable' && $rule_map[$k1][$k2]['disabled'] == 1) {
+ $rule_map[$k1][$k2]['rule'] = ltrim($rule_map[$k1][$k2]['rule'], " \t#");
+ $rule_map[$k1][$k2]['disabled'] = 0;
+ $rule_map[$k1][$k2]['managed'] = 1;
+ $changecount++;
+ $modcount++;
+ }
+ elseif ($action == 'disable' && $rule_map[$k1][$k2]['disabled'] == 0) {
+ $rule_map[$k1][$k2]['rule'] = "# " . $rule_map[$k1][$k2]['rule'];
+ $rule_map[$k1][$k2]['disabled'] = 1;
+ $rule_map[$k1][$k2]['managed'] = 1;
+ $changecount++;
+ $modcount++;
+ }
+ }
+ }
+ }
+
+ if ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext(" Found {$modcount} matching SIDs in the active rules.\n"), 3, $log_file);
+ error_log(gettext(" Changed state for {$changecount} SIDs to '{$action}d'.\n"), 3, $log_file);
+ }
+
+ // Return the array of matching SIDs
+ return $sids;
+}
+
+function suricata_modify_sid_content(&$rule_map, $sid_mods, $log_results = FALSE, $log_file = NULL) {
+
+ /************************************************/
+ /* This function walks the provided array of */
+ /* SID modification tokens and locates the */
+ /* target SID or SIDs in the $rule_map array. */
+ /* It then modifies the content of the target */
+ /* SID or SIDs. Modifications are only valid */
+ /* for normal GID=1 text rules. */
+ /* */
+ /* $rule_map ==> reference to array of */
+ /* current rules */
+ /* $sid_mods ==> array of SID modification */
+ /* tokens */
+ /* $log_results ==> [optional] 'yes' to log */
+ /* results to $log_file */
+ /* $log_file ==> full path and filename */
+ /* of log file to write to */
+ /* */
+ /* On Return ==> $rule_map array modified */
+ /* by changing content for */
+ /* matching SIDs. */
+ /* */
+ /* Returns a two-dimension */
+ /* array of matching */
+ /* GID:SID pairs. */
+ /************************************************/
+
+ $sids = array();
+ $tokencounter = $modcount = $modifiedcount = 0;
+
+ // If no rules in $rule_map or mods in $sid_mods,
+ // then nothing to do.
+ if (empty($rule_map) || empty($sid_mods))
+ return $sids;
+
+ // Walk the SID mod tokens and decode each one
+ foreach ($sid_mods as $tok) {
+ $matches = array();
+ if (preg_match('/([\d+|,|\*]*)\s+"(.+)"\s+"(.*)"/', $tok, $matches)) {
+ $tokencounter++;
+ $sidlist = explode(",", $matches[1]);
+ $from = '/' . preg_quote($matches[2], '/') . '/';
+ $to = $matches[3];
+ $count = 0;
+
+ // Now walk the provided rule map and make the modifications
+ if ($matches[1] == "*") {
+ // If wildcard '*' provided for SID, then check them all
+ foreach ($rule_map[1] as $rulem) {
+ foreach ($rulem as $k2 => $v) {
+ $modcount++;
+ $rule_map[1][$k2]['rule'] = preg_replace($from, $to, $v['rule'], -1, $count);
+ if ($count > 0) {
+ $rule_map[1][$k2]['managed'] = 1;
+ $sids[1][$k2] = 'modify';
+ $modifiedcount++;
+ }
+ }
+ }
+ }
+ else {
+ // Otherwise just check the provided SIDs
+ foreach ($sidlist as $sid) {
+ if (isset($rule_map[1][$sid])) {
+ $modcount++;
+ $rule_map[1][$sid]['rule'] = preg_replace($from, $to, $rule_map[1][$sid]['rule'], -1, $count);
+ if ($count > 0) {
+ $rule_map[1][$sid]['managed'] = 1;
+ $sids[1][$sid] = 'modify';
+ $modifiedcount++;
+ }
+ }
+ }
+ }
+ }
+ else {
+ if ($log_results == TRUE && !empty($log_file))
+ error_log(gettext("WARNING: unrecognized token '{$tok}' encountered while processing an automatic SID MGMT file.\n"), 3, $log_file);
+ }
+ }
+
+ if ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext(" Parsed {$tokencounter} potential SIDs to match from the provided list of tokens.\n"), 3, $log_file);
+ error_log(gettext(" Found {$modcount} matching SIDs in the active rules.\n"), 3, $log_file);
+ error_log(gettext(" Modified rule text for {$modifiedcount} SIDs.\n"), 3, $log_file);
+ }
+
+ // Return the array of matching SIDs
+ return $sids;
+}
+
+function suricata_process_enablesid(&$rule_map, $suricatacfg, $log_results = FALSE, $log_file = NULL) {
+
+ /**********************************************/
+ /* This function loads and processes the file */
+ /* specified by 'enable_sid_file' for the */
+ /* interface. The file is assumed to be a */
+ /* valid enablesid.conf file containing */
+ /* instructions for enabling matching rule */
+ /* SIDs. */
+ /* */
+ /* $rule_map ==> reference to array of */
+ /* current rules */
+ /* $suricatacfg ==> interface config params */
+ /* $log_results ==> [optional] 'yes' to log */
+ /* results to $log_file */
+ /* $log_file ==> full path and filename */
+ /* of log file to write to */
+ /* */
+ /* On Return ==> suitably modified */
+ /* $rule_map array */
+ /**********************************************/
+
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
+ $suricatalogdir = SURICATALOGDIR;
+ $sid_mods = array();
+
+ // If no rules in $rule_map, then nothing to do
+ if (empty($rule_map))
+ return;
+
+ // Attempt to open the 'enable_sid_file' for the interface
+ if (!file_exists("{$suricata_sidmods_dir}{$suricatacfg['enable_sid_file']}")) {
+ log_error(gettext("[Suricata] Error - unable to open 'enable_sid_file' \"{$suricatacfg['enable_sid_file']}\" specified for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ return;
+ }
+ else
+ $sid_mods = suricata_parse_sidconf_file("{$suricata_sidmods_dir}{$suricatacfg['enable_sid_file']}");
+
+ if (!empty($sid_mods))
+ suricata_modify_sid_state($rule_map, $sid_mods, "enable", $log_results, $log_file);
+ elseif ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext("WARNING: no valid SID match tokens found in file \"{$suricatacfg['enable_sid_file']}\".\n"), 3, $log_file);
+ }
+
+ unset($sid_mods);
+}
+
+function suricata_process_disablesid(&$rule_map, $suricatacfg, $log_results = FALSE, $log_file = NULL) {
+
+ /**********************************************/
+ /* This function loads and processes the file */
+ /* specified by 'disable_sid_file' for the */
+ /* interface. The file is assumed to be a */
+ /* valid disablesid.conf file containing */
+ /* instructions for disabling matching rule */
+ /* SIDs. */
+ /* */
+ /* $rule_map ==> reference to array of */
+ /* current rules */
+ /* $suricatacfg ==> interface config params */
+ /* $log_results ==> [optional] 'yes' to log */
+ /* results to $log_file */
+ /* $log_file ==> full path and filename */
+ /* of log file to write to */
+ /* */
+ /* On Return ==> suitably modified */
+ /* $rule_map array */
+ /**********************************************/
+
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
+ $suricatalogdir = SURICATALOGDIR;
+ $sid_mods = array();
+
+ // If no rules in $rule_map, then nothing to do
+ if (empty($rule_map))
+ return;
+
+ // Attempt to open the 'disable_sid_file' for the interface
+ if (!file_exists("{$suricata_sidmods_dir}{$suricatacfg['disable_sid_file']}")) {
+ log_error(gettext("[Suricata] Error - unable to open 'disable_sid_file' \"{$suricatacfg['disable_sid_file']}\" specified for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ return;
+ }
+ else
+ $sid_mods = suricata_parse_sidconf_file("{$suricata_sidmods_dir}{$suricatacfg['disable_sid_file']}");
+
+ if (!empty($sid_mods))
+ suricata_modify_sid_state($rule_map, $sid_mods, "disable", $log_results, $log_file);
+ elseif ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext("WARNING: no valid SID match tokens found in file \"{$suricatacfg['disable_sid_file']}\".\n"), 3, $log_file);
+ }
+
+ unset($sid_mods);
+}
+
+function suricata_process_modifysid(&$rule_map, $suricatacfg, $log_results = FALSE, $log_file = NULL) {
+
+ /**********************************************/
+ /* This function loads and processes the file */
+ /* specified by 'modify_sid_file' for the */
+ /* interface. The file is assumed to be a */
+ /* valid modifysid.conf file containing */
+ /* instructions for modifying matching rule */
+ /* SIDs. */
+ /* */
+ /* $rule_map ==> reference to array of */
+ /* current rules */
+ /* $suricatacfg ==> interface config params */
+ /* $log_results ==> [optional] 'yes' to log */
+ /* results to $log_file */
+ /* $log_file ==> full path and filename */
+ /* of log file to write to */
+ /* */
+ /* On Return ==> suitably modified */
+ /* $rule_map array */
+ /**********************************************/
+
+ $suricata_sidmods_dir = SURICATA_SID_MODS_PATH;
+ $suricatalogdir = SURICATALOGDIR;
+ $sid_mods = array();
+
+ // If no rules in $rule_map, then nothing to do
+ if (empty($rule_map))
+ return;
+
+ // Attempt to open the 'modify_sid_file' for the interface
+ if (!file_exists("{$suricata_sidmods_dir}{$suricatacfg['modify_sid_file']}")) {
+ log_error(gettext("[Suricata] Error - unable to open 'modify_sid_file' \"{$suricatacfg['modify_sid_file']}\" specified for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ return;
+ }
+ else
+ $sid_mods = suricata_parse_sidconf_file("{$suricata_sidmods_dir}{$suricatacfg['modify_sid_file']}");
+
+ if (!empty($sid_mods))
+ suricata_modify_sid_content($rule_map, $sid_mods, $log_results, $log_file);
+ elseif ($log_results == TRUE && !empty($log_file)) {
+ error_log(gettext("WARNING: no valid SID match tokens found in file \"{$suricatacfg['modify_sid_file']}\".\n"), 3, $log_file);
+ }
+
+ unset($sid_mods);
+}
+
+function suricata_auto_sid_mgmt(&$rule_map, $suricatacfg, $log_results = FALSE) {
+
+ /**************************************************/
+ /* This function modifies the rules in the */
+ /* passed rule_map array based on values in the */
+ /* files 'enable_sid_file', 'disable_sid_file' */
+ /* and 'modify_sid_file' for the interface. */
+ /* */
+ /* If auto-mgmt of SIDs is enabled via the */
+ /* settings on the UPDATE RULES tab, then the */
+ /* rules are processed against these settings. */
+ /* */
+ /* $rule_map ==> array of current rules */
+ /* $suricatacfg ==> interface config settings */
+ /* $log_results ==> [optional] log results to */
+ /* 'sid_changes.log' in the */
+ /* interface directory in */
+ /* /var/log/suricata when TRUE */
+ /* */
+ /* Returns ==> TRUE if rules were changed; */
+ /* otherwise FALSE */
+ /**************************************************/
+
+ global $config;
+ $result = FALSE;
+
+ // Configure the interface's logging subdirectory if log results is enabled
+ if ($log_results == TRUE)
+ $log_file = SURICATALOGDIR . $suricatalogdir . "suricata_" . get_real_interface($suricatacfg['interface']) . "{$suricatacfg['uuid']}/sid_changes.log";
+ else
+ $log_file = NULL;
+
+ // Check if auto-mgmt of SIDs is enabled and files are specified
+ // for the interface.
+ if ($config['installedpackages']['suricata']['config'][0]['auto_manage_sids'] == 'on' &&
+ (!empty($suricatacfg['disable_sid_file']) || !empty($suricatacfg['enable_sid_file']) ||
+ !empty($suricatacfg['modify_sid_file']))) {
+ if ($log_results == TRUE) {
+ error_log(gettext("********************************************************\n"), 3, $log_file);
+ error_log(gettext("Starting auto SID management for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) ."\n"), 3, $log_file);
+ error_log(gettext("Start Time: " . date("Y-m-d H:i:s") . "\n"), 3, $log_file);
+ }
+
+ switch ($suricatacfg['sid_state_order']) {
+ case "disable_enable":
+ if (!empty($suricatacfg['disable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing disable_sid file: {$suricatacfg['disable_sid_file']}\n"), 3, $log_file);
+ suricata_process_disablesid($rule_map, $suricatacfg, $log_results, $log_file);
+ }
+ if (!empty($suricatacfg['enable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing enable_sid file: {$suricatacfg['enable_sid_file']}\n"), 3, $log_file);
+ suricata_process_enablesid($rule_map, $suricatacfg, $log_results, $log_file);
+ }
+ if (!empty($suricatacfg['modify_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing modify_sid file: {$suricatacfg['modify_sid_file']}\n"), 3, $log_file);
+ suricata_process_modifysid($rule_map, $suricatacfg, $log_results, $log_file);
+ }
+ $result = TRUE;
+ break;
+
+ case "enable_disable":
+ if (!empty($suricatacfg['enable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing enable_sid file: {$suricatacfg['enable_sid_file']}\n"), 3, $log_file);
+ suricata_process_enablesid($rule_map, $suricatacfg, $log_results, $log_file);
+ }
+ if (!empty($suricatacfg['disable_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing disable_sid file: {$suricatacfg['disable_sid_file']}\n"), 3, $log_file);
+ suricata_process_disablesid($rule_map, $suricatacfg, $log_results, $log_file);
+ }
+ if (!empty($suricatacfg['modify_sid_file'])) {
+ if ($log_results == TRUE)
+ error_log(gettext("Processing modify_sid file: {$suricatacfg['modify_sid_file']}\n"), 3, $log_file);
+ suricata_process_modifysid($rule_map, $suricatacfg, $log_results, $log_file);
+ }
+ $result = TRUE;
+ break;
+
+ default:
+ log_error(gettext("[Suricata] Unrecognized 'sid_state_order' value. Skipping auto SID mgmt step for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface'])));
+ if ($log_results == TRUE) {
+ error_log(gettext("ERROR: unrecognized 'sid_state_order' value. Skipping auto SID mgmt step for ") . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']). ".\n", 3, $log_file);
+ }
+ $result = FALSE;
+ }
+
+ if ($log_results == TRUE) {
+ error_log(gettext("End Time: " . date("Y-m-d H:i:s") . "\n"), 3, $log_file);
+ error_log(gettext("********************************************************\n\n"), 3, $log_file);
+ }
+ }
+ return $result;
+}
+
function suricata_load_sid_mods($sids) {
/*****************************************/
@@ -1572,15 +2575,15 @@ function suricata_load_sid_mods($sids) {
function suricata_modify_sids(&$rule_map, $suricatacfg) {
- /*****************************************/
- /* This function modifies the rules in */
- /* the passed rules_map array based on */
- /* values in the enablesid/disablesid */
- /* configuration parameters. */
- /* */
- /* $rule_map = array of current rules */
- /* $suricatacfg = config settings */
- /*****************************************/
+ /***********************************************/
+ /* This function modifies the rules in the */
+ /* passed rules_map array based on values in */
+ /* the enablesid/disablesid configuration */
+ /* parameters for the interface. */
+ /* */
+ /* $rule_map = array of current rules */
+ /* $suricatacfg = interface config settings */
+ /***********************************************/
if (!isset($suricatacfg['rule_sid_on']) &&
!isset($suricatacfg['rule_sid_off']))
@@ -1634,11 +2637,15 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
/* to be written. */
/***********************************************************/
- global $rebuild_rules;
+ global $config, $rebuild_rules;
$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();
+ $cat_mods = array();
$no_rules_defined = true;
// If there is no reason to rebuild the rules, exit to save time.
@@ -1648,11 +2655,12 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
// Log a message for rules rebuild in progress
log_error(gettext("[Suricata] Updating rules configuration for: " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) . " ..."));
+ // Get any automatic rule category enable/disable modifications
+ // if auto-SID Mgmt is enabled and conf files exist for the interface.
+ $cat_mods = suricata_sid_mgmt_auto_categories($suricatacfg, TRUE);
+
// Only rebuild rules if some are selected or an IPS Policy is enabled
- if (!empty($suricatacfg['rulesets']) || $suricatacfg['ips_policy_enable'] == 'on') {
- $enabled_rules = array();
- $enabled_files = array();
- $all_rules = array();
+ if (!empty($suricatacfg['rulesets']) || $suricatacfg['ips_policy_enable'] == 'on' || !empty($cat_mods)) {
$no_rules_defined = false;
// Load up all the rules into a Rules Map array.
@@ -1660,12 +2668,37 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
// Create an array with the filenames of the enabled
// rule category files if we have any.
- if (!empty($suricatacfg['rulesets'])) {
- foreach (explode("||", $suricatacfg['rulesets']) as $file){
- $category = basename($file, ".rules");
- if (!is_array($enabled_files[$category]))
- $enabled_files[$category] = array();
- $enabled_files[$category] = $file;
+ if (!empty($suricatacfg['rulesets']) || !empty($cat_mods)) {
+ // First get all the user-enabled category files
+ if (!empty($suricatacfg['rulesets'])) {
+ foreach (explode("||", $suricatacfg['rulesets']) as $file){
+ $category = basename($file, ".rules");
+ if (!is_array($enabled_files[$category]))
+ $enabled_files[$category] = array();
+ $enabled_files[$category] = $file;
+ }
+ }
+
+ // Now adjust the list using any required changes as
+ // determined by auto-SID Mgmt policy files.
+ if (!empty($cat_mods)) {
+ foreach ($cat_mods as $k => $action) {
+ $key = basename($k, ".rules");
+ switch ($action) {
+ case 'enabled':
+ if (!isset($enabled_files[$key]))
+ $enabled_files[$key] = $k;
+ break;
+
+ case 'disabled':
+ if (isset($enabled_files[$key]))
+ unset($enabled_files[$key]);
+ break;
+
+ default:
+ break;
+ }
+ }
}
/****************************************************/
@@ -1689,7 +2722,7 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
}
// Release memory we no longer need.
- unset($enabled_files, $rulem, $v);
+ unset($enabled_files, $cat_mods, $rulem, $v);
}
// Check if a pre-defined Snort VRT policy is selected. If so,
@@ -1712,6 +2745,8 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
}
// Process any enablesid or disablesid modifications for the selected rules.
+ // Do the auto-SID managment first, if enabled, then do any manual SID state changes.
+ suricata_auto_sid_mgmt($enabled_rules, $suricatacfg, TRUE);
suricata_modify_sids($enabled_rules, $suricatacfg);
// Write the enforcing rules file to the Suricata interface's "rules" directory.
@@ -1730,7 +2765,45 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
} else
// Just put an empty file to always have the file present
suricata_write_flowbit_rules_file(array(), "{$suricatacfgdir}/rules/{$flowbit_rules_file}");
- } else {
+ unset($all_rules);
+ }
+ // If no rule categories were enabled, then use auto-SID management if enabled, since it may enable some rules
+ elseif ($config['installedpackages']['suricata']['config'][0]['auto_manage_sids'] == 'on' &&
+ (!empty($suricatacfg['disable_sid_file']) || !empty($suricatacfg['enable_sid_file']) ||
+ !empty($suricatacfg['modify_sid_file']))) {
+
+ suricata_auto_sid_mgmt($enabled_rules, $suricatacfg, TRUE);
+ if (!empty($enabled_rules)) {
+ // Auto-SID management generated some rules, so use them
+ $no_rules_defined = false;
+ suricata_modify_sids($enabled_rules, $suricatacfg);
+
+ // Write the enforcing rules file to the Suricata interface's "rules" directory.
+ suricata_write_enforcing_rules_file($enabled_rules, "{$suricatacfgdir}/rules/{$suricata_enforcing_rules_file}");
+
+ // If auto-flowbit resolution is enabled, generate the dependent flowbits rules file.
+ if ($suricatacfg['autoflowbitrules'] == 'on') {
+ log_error('[Suricata] Enabling any flowbit-required rules for: ' . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) . '...');
+
+ // Load up all rules into a Rules Map array for flowbits assessment
+ $all_rules = suricata_load_rules_map("{$suricatadir}rules/");
+ $fbits = suricata_resolve_flowbits($all_rules, $enabled_rules);
+
+ // Check for and disable any flowbit-required rules the
+ // user has manually forced to a disabled state.
+ suricata_modify_sids($fbits, $suricatacfg);
+ suricata_write_flowbit_rules_file($fbits, "{$suricatacfgdir}/rules/{$flowbit_rules_file}");
+ unset($all_rules, $fbits);
+ } else
+ // Just put an empty file to always have the file present
+ suricata_write_flowbit_rules_file(array(), "{$suricatacfgdir}/rules/{$flowbit_rules_file}");
+ }
+ else {
+ suricata_write_enforcing_rules_file(array(), "{$suricatacfgdir}/rules/{$suricata_enforcing_rules_file}");
+ suricata_write_flowbit_rules_file(array(), "{$suricatacfgdir}/rules/{$flowbit_rules_file}");
+ }
+ }
+ else {
suricata_write_enforcing_rules_file(array(), "{$suricatacfgdir}/rules/{$suricata_enforcing_rules_file}");
suricata_write_flowbit_rules_file(array(), "{$suricatacfgdir}/rules/{$flowbit_rules_file}");
}
@@ -1748,7 +2821,7 @@ function suricata_prepare_rule_files($suricatacfg, $suricatacfgdir) {
// Build a new sid-msg.map file from the enabled
// rules and copy it to the interface directory.
- log_error(gettext("[Suricata] Building new sig-msg.map file for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) . "..."));
+ log_error(gettext("[Suricata] Building new sid-msg.map file for " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) . "..."));
suricata_build_sid_msg_map("{$suricatacfgdir}/rules/", "{$suricatacfgdir}/sid-msg.map");
}
@@ -1767,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
@@ -1816,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
@@ -1833,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']);
@@ -1846,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
@@ -1869,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} "`
@@ -1886,7 +2956,6 @@ EOE;
done
fi
fi
-
EOE;
if ($value['barnyard_enable'] == 'on')
$start_barnyard2 = $start_barnyard;
@@ -1895,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
@@ -1930,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} "`
@@ -1949,9 +3013,8 @@ EOE;
fi
fi
- sleep 2
+ sleep 1
{$stop_barnyard2}
-
EOE;
}
@@ -1966,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() {
@@ -1975,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
@@ -1989,8 +3064,8 @@ esac
EOD;
// Write out the suricata.sh script file
- @file_put_contents("{$rcdir}/suricata.sh", $suricata_sh_text);
- @chmod("{$rcdir}/suricata.sh", 0755);
+ @file_put_contents("{$rcdir}suricata.sh", $suricata_sh_text);
+ @chmod("{$rcdir}suricata.sh", 0755);
unset($suricata_sh_text);
}
@@ -2051,7 +3126,7 @@ function suricata_generate_barnyard2_conf($suricatacfg, $if_real) {
$suricatabarnyardlog_output_plugins .= "# syslog_full: log to a syslog receiver\n";
$suricatabarnyardlog_output_plugins .= "output alert_syslog_full: sensor_name {$suricatabarnyardlog_hostname_info_chk}, ";
if ($suricatacfg['barnyard_syslog_local'] == 'on')
- $suricatabarnyardlog_output_plugins .= "local, log_facility LOG_AUTH, log_priority LOG_INFO\n\n";
+ $suricatabarnyardlog_output_plugins .= "local, log_facility {$suricatacfg['barnyard_syslog_facility']}, log_priority {$suricatacfg['barnyard_syslog_priority']}\n\n";
else {
$suricatabarnyardlog_output_plugins .= "server {$suricatacfg['barnyard_syslog_rhost']}, protocol {$suricatacfg['barnyard_syslog_proto']}, ";
$suricatabarnyardlog_output_plugins .= "port {$suricatacfg['barnyard_syslog_dport']}, operation_mode {$suricatacfg['barnyard_syslog_opmode']}, ";
@@ -2126,30 +3201,296 @@ 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}";
- conf_mount_rw();
-
if (!is_array($config['installedpackages']['suricata']['rule']))
return;
// Pull in the PHP code that generates the suricata.yaml file
// variables that will be substitued further down below.
- include("/usr/local/www/suricata/suricata_generate_yaml.php");
+ include("/usr/local/pkg/suricata/suricata_generate_yaml.php");
// Pull in the boilerplate template for the suricata.yaml
// configuration file. The contents of the template along
- // with substituted variables is stored in $suricata_conf_text
+ // with substituted variables are stored in $suricata_conf_text
// (which is defined in the included file).
include("/usr/local/pkg/suricata/suricata_yaml_template.inc");
// Now write out the conf file using $suricata_conf_text contents
@file_put_contents("{$suricatacfgdir}/suricata.yaml", $suricata_conf_text);
unset($suricata_conf_text);
+}
+
+/* Uses XMLRPC to synchronize the changes to a remote node */
+function suricata_sync_on_changes() {
+ global $config, $g;
+
+ /* Do not attempt a package sync while booting up or installing package */
+ if ($g['booting'] || $g['suricata_postinstall'] == TRUE) {
+ log_error("[suricata] No xmlrpc sync to CARP targets when booting up or during package reinstallation.");
+ return;
+ }
+
+ if (is_array($config['installedpackages']['suricatasync']['config'])){
+ $suricata_sync=$config['installedpackages']['suricatasync']['config'][0];
+ $synconchanges = $suricata_sync['varsynconchanges'];
+ $synctimeout = $suricata_sync['varsynctimeout'];
+ $syncdownloadrules = $suricata_sync['vardownloadrules'];
+ switch ($synconchanges){
+ case "manual":
+ if (is_array($suricata_sync[row])){
+ $rs=$suricata_sync[row];
+ }
+ else{
+ log_error("[suricata] xmlrpc CARP sync is enabled but there are no hosts configured as replication targets.");
+ 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'];
+ $rs[0]['varsyncsuricatastart']="no";
+ if ($system_carp['synchronizetoip'] ==""){
+ log_error("[suricata] xmlrpc CARP sync is enabled but there are no system backup hosts configured as replication targets.");
+ return;
+ }
+ }
+ else{
+ log_error("[suricata] xmlrpc CARP sync is enabled but there are no system backup hosts configured as replication targets.");
+ return;
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+ if (is_array($rs)){
+ log_error("[suricata] Suricata pkg xmlrpc CARP sync is starting.");
+ foreach($rs as $sh){
+ if ($sh['varsyncsuricatastart'])
+ $syncstartsuricata = $sh['varsyncsuricatastart'];
+ else
+ $syncstartsuricata = "OFF";
+ $sync_to_ip = $sh['varsyncipaddress'];
+ $port = $sh['varsyncport'];
+ $password = $sh['varsyncpassword'];
+ if($sh['varsyncusername'])
+ $username = $sh['varsyncusername'];
+ else
+ $username = 'admin';
+ if($password && $sync_to_ip)
+ suricata_do_xmlrpc_sync($syncdownloadrules, $sync_to_ip, $port, $username, $password, $synctimeout, $syncstartsuricata);
+ }
+ log_error("[suricata] Suricata pkg xmlrpc CARP sync completed.");
+ }
+ }
+}
+
+/* Do the actual XMLRPC sync */
+function suricata_do_xmlrpc_sync($syncdownloadrules, $sync_to_ip, $port, $username, $password, $synctimeout = 150, $syncstartsuricata) {
+ global $config, $g;
+
+ /* Do not attempt a package sync while booting up or installing package */
+ if ($g['booting'] || isset($g['suricata_postinstall'])) {
+ log_error("[suricata] No xmlrpc sync to CARP targets when booting up or during package reinstallation.");
+ return;
+ }
+
+ if($username == "" || $password == "" || $sync_to_ip == "") {
+ log_error("[suricata] A required XMLRPC CARP sync parameter (user, host IP or password) is empty ... aborting pkg sync");
+ return;
+ }
+
+ /* Test key variables and set defaults if empty */
+ if(!$synctimeout)
+ $synctimeout=150;
+
+ $xmlrpc_sync_neighbor = $sync_to_ip;
+ if($config['system']['webgui']['protocol'] != "") {
+ $synchronizetoip = $config['system']['webgui']['protocol'];
+ $synchronizetoip .= "://";
+ }
+ $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";
+ }
+ $synchronizetoip .= $sync_to_ip;
+ $url = $synchronizetoip;
+
+ /*************************************************/
+ /* Send over any auto-SID management files */
+ /*************************************************/
+ $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}'));";
+
+ /* assemble xmlrpc payload */
+ $method = 'pfsense.exec_php';
+ $params = array( XML_RPC_encode($password), XML_RPC_encode($payload) );
+
+ log_error("[suricata] Suricata XMLRPC CARP sync sending auto-SID conf files to {$url}:{$port}.");
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials($username, $password);
+ $resp = $cli->send($msg, $synctimeout);
+ $error = "";
+ if(!$resp) {
+ $error = "A communications error occurred while attempting Suricata XMLRPC CARP sync with {$url}:{$port}. Failed to transfer file: " . basename($file);
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $error = "An error code was received while attempting Suricata XMLRPC CARP sync with {$url}:{$port}. Failed to transfer file: " . basename($file) . " - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ }
+ }
+
+ if (!empty($sid_files) && $error == "")
+ log_error("[suricata] Suricata pkg XMLRPC CARP sync auto-SID conf files success with {$url}:{$port} (pfsense.exec_php).");
+
+ /**************************************************/
+ /* Send over the <suricata> portion of config.xml */
+ /* $xml will hold the section to sync. */
+ /**************************************************/
+ $xml = array();
+ $xml['suricata'] = $config['installedpackages']['suricata'];
+ /* assemble xmlrpc payload */
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($xml)
+ );
+
+ log_error("[suricata] Beginning Suricata pkg configuration XMLRPC sync 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);
+
+ /* send our XMLRPC message and timeout after defined sync timeout value*/
+ $resp = $cli->send($msg, $synctimeout);
+ if(!$resp) {
+ $error = "A communications error occurred while attempting Suricata XMLRPC CARP sync with {$url}:{$port}.";
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $error = "An error code was received while attempting Suricata XMLRPC CARP sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ } else {
+ log_error("[suricata] Suricata pkg configuration XMLRPC CARP sync successfully completed with {$url}:{$port}.");
+ }
+
+ $downloadrulescmd = "";
+ if ($syncdownloadrules == "yes") {
+ $downloadrulescmd = "log_error(gettext(\"[suricata] XMLRPC pkg CARP sync: Update of downloaded rule sets requested...\"));\n";
+ $downloadrulescmd .= "\tinclude_once(\"/usr/local/pkg/suricata/suricata_check_for_rule_updates.php\");\n";
+ }
+ $suricatastart = "";
+ if ($syncstartsuricata == "ON") {
+ $suricatastart = "log_error(gettext(\"[suricata] XMLRPC pkg CARP sync: Checking Suricata status...\"));\n";
+ $suricatastart .= "\tif (!is_process_running(\"suricata\")) {\n";
+ $suricatastart .= "\t\tlog_error(gettext(\"[suricata] XMLRPC pkg CARP sync: Suricata not running. Sending a start command...\"));\n";
+ $suricatastart .= "\t\t\$sh_script = RCFILEPREFIX . \"suricata.sh\";\n";
+ $suricatastart .= "\t\tmwexec_bg(\"{\$sh_script} start\");\n\t}\n";
+ $suricatastart .= "\telse {\n\t\tlog_error(gettext(\"[suricata] XMLRPC pkg CARP sync: Suricata is running...\"));\n\t}\n";
+ }
+
+ /*************************************************/
+ /* Build a series of commands as a PHP file for */
+ /* the secondary host to execute to load the new */
+ /* settings. */
+ /*************************************************/
+ $suricata_sync_cmd = <<<EOD
+ <?php
+ require_once("/usr/local/pkg/suricata/suricata.inc");
+ require_once("service-utils.inc");
+ global \$g, \$rebuild_rules, \$suricata_gui_include, \$pkg_interface;
+ \$orig_pkg_interface = \$pkg_interface;
+ \$g["suricata_postinstall"] = true;
+ \$g["suricata_sync_in_progress"] = true;
+ \$suricata_gui_include = false;
+ \$pkg_interface = "console";
+ {$downloadrulescmd}
+ 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..."));
+ \$pkg_interface = \$orig_pkg_interface;
+ unset(\$g["suricata_sync_in_progress"]);
+ return true;
+ ?>
+
+EOD;
+
+ /*************************************************/
+ /* First, have target host write the commands */
+ /* to a PHP file in the /tmp directory. */
+ /*************************************************/
+ $execcmd = "file_put_contents('/tmp/suricata_sync_cmds.php', '{$suricata_sync_cmd}');";
+
+ /* assemble xmlrpc payload */
+ $method = 'pfsense.exec_php';
+ $params = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($execcmd)
+ );
+
+ log_error("[suricata] Suricata XMLRPC CARP sync sending reload configuration cmd set as a file to {$url}:{$port}.");
+ $msg = new XML_RPC_Message($method, $params);
+ $cli = new XML_RPC_Client('/xmlrpc.php', $url, $port);
+ $cli->setCredentials($username, $password);
+ $resp = $cli->send($msg, $synctimeout);
+ if(!$resp) {
+ $error = "A communications error occurred while attempting Suricata XMLRPC CARP sync with {$url}:{$port} (pfsense.exec_php).";
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $error = "An error code was received while attempting Suricata XMLRPC CARP sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ } else {
+ log_error("[suricata] Suricata pkg XMLRPC CARP sync reload configuration success with {$url}:{$port} (pfsense.exec_php).");
+ }
+
+ /*************************************************/
+ /* Now assemble a command to execute the */
+ /* previously sent PHP file in the background. */
+ /*************************************************/
+ $execcmd = "exec(\"/usr/local/bin/php -f '/tmp/suricata_sync_cmds.php' > /dev/null 2>&1 &\");";
+ $params2 = array(
+ XML_RPC_encode($password),
+ XML_RPC_encode($execcmd)
+ );
+ log_error("[suricata] Suricata XMLRPC CARP sync sending {$url}:{$port} cmd to execute configuration reload.");
+ $msg2 = new XML_RPC_Message($method, $params2);
+ $resp = $cli->send($msg2, $synctimeout);
+ if(!$resp) {
+ $error = "A communications error occurred while attempting Suricata XMLRPC CARP sync with {$url}:{$port} (pfsense.exec_php).";
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ } elseif($resp->faultCode()) {
+ $error = "An error code was received while attempting Suricata XMLRPC CARP sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString();
+ log_error($error);
+ file_notice("sync_settings", $error, "Suricata Settings Sync", "");
+ } else {
+ log_error("[suricata] Suricata pkg XMLRPC CARP sync reload configuration success with {$url}:{$port} (pfsense.exec_php).");
+ }
}
?>
diff --git a/config/suricata/suricata.priv.inc b/config/suricata/suricata.priv.inc
index 3bbee55a..84ede368 100644
--- a/config/suricata/suricata.priv.inc
+++ b/config/suricata/suricata.priv.inc
@@ -25,6 +25,7 @@ $priv_list['page-services-suricata']['match'][] = "suricata/suricata_select_alia
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_list_view.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_logs_browser.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_logs_mgmt.php*";
+$priv_list['page-services-suricata']['match'][] = "suricata/suricata_sid_mgmt.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_passlist.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_passlist_edit.php*";
$priv_list['page-services-suricata']['match'][] = "suricata/suricata_post_install.php*";
@@ -35,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 1a64d619..c510d72b 100644
--- a/config/suricata/suricata.xml
+++ b/config/suricata/suricata.xml
@@ -9,49 +9,40 @@
/*
suricata.xml
part of the Suricata package for pfSense
+ Copyright (C) 2014 Bill meeks
- Significant portions 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.
+ 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>Suricata IDS/IPS Package</description>
<requirements>None</requirements>
<name>suricata</name>
- <version>1.4.6 pkg v1.0</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>
@@ -77,18 +68,58 @@
<chmod>0755</chmod>
</additional_files_needed>
<additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_sync.xml</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_check_cron_misc.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_check_for_rule_updates.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_yaml_template.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_generate_yaml.php</item>
- <prefix>/usr/local/www/suricata/</prefix>
+ <prefix>/usr/local/pkg/suricata/</prefix>
+ <chmod>0755</chmod>
+ </additional_files_needed>
+ <additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_migrate_config.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_post_install.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_uninstall.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_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>
@@ -122,11 +153,6 @@
<chmod>0755</chmod>
</additional_files_needed>
<additional_files_needed>
- <item>https://packages.pfsense.org/packages/config/suricata/suricata_check_for_rule_updates.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_rules.php</item>
<prefix>/usr/local/www/suricata/</prefix>
<chmod>0755</chmod>
@@ -182,6 +208,11 @@
<chmod>0755</chmod>
</additional_files_needed>
<additional_files_needed>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_sid_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_list_view.php</item>
<prefix>/usr/local/www/suricata/</prefix>
<chmod>0755</chmod>
@@ -197,26 +228,46 @@
<chmod>0755</chmod>
</additional_files_needed>
<additional_files_needed>
- <item>https://packages.pfsense.org/packages/config/suricata/suricata_uninstall.php</item>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_define_vars.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_define_vars.php</item>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_barnyard.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_barnyard.php</item>
+ <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_post_install.php</item>
+ <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>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/widgets/widgets/</prefix>
+ <chmod>0644</chmod>
+ <item>https://packages.pfsense.org/packages/config/suricata/suricata_alerts.widget.php</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/www/widgets/include/</prefix>
+ <chmod>0644</chmod>
+ <item>https://packages.pfsense.org/packages/config/suricata/widget-suricata.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
<prefix>/usr/local/www/suricata/</prefix>
<chmod>0644</chmod>
<item>https://packages.pfsense.org/packages/config/suricata/suricata_blocked.php</item>
@@ -237,19 +288,19 @@
<item>https://packages.pfsense.org/packages/config/suricata/suricata_select_alias.php</item>
</additional_files_needed>
<additional_files_needed>
- <prefix>/usr/local/www/widgets/javascript/</prefix>
+ <prefix>/var/db/suricata/sidmods/</prefix>
<chmod>0644</chmod>
- <item>https://packages.pfsense.org/packages/config/suricata/suricata_alerts.js</item>
+ <item>https://packages.pfsense.org/packages/config/suricata/disablesid-sample.conf</item>
</additional_files_needed>
<additional_files_needed>
- <prefix>/usr/local/www/widgets/widgets/</prefix>
+ <prefix>/var/db/suricata/sidmods/</prefix>
<chmod>0644</chmod>
- <item>https://packages.pfsense.org/packages/config/suricata/suricata_alerts.widget.php</item>
+ <item>https://packages.pfsense.org/packages/config/suricata/enablesid-sample.conf</item>
</additional_files_needed>
<additional_files_needed>
- <prefix>/usr/local/www/widgets/include/</prefix>
+ <prefix>/var/db/suricata/sidmods/</prefix>
<chmod>0644</chmod>
- <item>https://packages.pfsense.org/packages/config/suricata/widget-suricata.inc</item>
+ <item>https://packages.pfsense.org/packages/config/suricata/modifysid-sample.conf</item>
</additional_files_needed>
<!-- configpath gets expanded out automatically and config items will be stored in that location -->
<configpath>['installedpackages']['suricata']</configpath>
@@ -259,12 +310,12 @@
</fields>
<custom_php_install_command>
<![CDATA[
- include_once("/usr/local/www/suricata/suricata_post_install.php");
+ include_once("/usr/local/pkg/suricata/suricata_post_install.php");
]]>
</custom_php_install_command>
<custom_php_deinstall_command>
<![CDATA[
- include_once("/usr/local/www/suricata/suricata_uninstall.php");
+ include_once("/usr/local/pkg/suricata/suricata_uninstall.php");
]]>
</custom_php_deinstall_command>
<custom_php_resync_config_command>
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 07e4eb1f..f151e173 100644
--- a/config/suricata/suricata_alerts.php
+++ b/config/suricata/suricata_alerts.php
@@ -11,6 +11,7 @@
* Copyright (C) 2006 Scott Ullrich
* Copyright (C) 2009 Robert Zelaya Sr. Developer
* Copyright (C) 2012 Ermal Luci
+ * Copyright (C) 2014 Jim Pingle jim@pingle.org
* All rights reserved.
*
* Adapted for Suricata by:
@@ -42,8 +43,10 @@
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;
function suricata_is_alert_globally_suppressed($list, $gid, $sid) {
@@ -125,13 +128,40 @@ 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
return false;
}
+function suricata_escape_filter_regex($filtertext) {
+ /* If the caller (user) has not already put a backslash before a slash, to escape it in the regex, */
+ /* then this will do it. Take out any "\/" already there, then turn all ordinary "/" into "\/". */
+ return str_replace('/', '\/', str_replace('\/', '/', $filtertext));
+}
+
+function suricata_match_filter_field($flent, $fields) {
+ foreach ($fields as $key => $field) {
+ if ($field == null)
+ continue;
+ if ((strpos($field, '!') === 0)) {
+ $field = substr($field, 1);
+ $field_regex = suricata_escape_filter_regex($field);
+ if (@preg_match("/{$field_regex}/i", $flent[$key]))
+ return false;
+ }
+ else {
+ $field_regex = suricata_escape_filter_regex($field);
+ if (!@preg_match("/{$field_regex}/i", $flent[$key]))
+ return false;
+ }
+ }
+ return true;
+}
+
if (isset($_POST['instance']) && is_numericint($_POST['instance']))
$instanceid = $_POST['instance'];
// This is for the auto-refresh so we can stay on the same interface
@@ -164,6 +194,50 @@ if (empty($pconfig['arefresh']))
$pconfig['arefresh'] = 'off';
$anentries = $pconfig['alertnumber'];
+# --- AJAX REVERSE DNS RESOLVE Start ---
+if (isset($_POST['resolve'])) {
+ $ip = strtolower($_POST['resolve']);
+ $res = (is_ipaddr($ip) ? gethostbyaddr($ip) : '');
+
+ if ($res && $res != $ip)
+ $response = array('resolve_ip' => $ip, 'resolve_text' => $res);
+ else
+ $response = array('resolve_ip' => $ip, 'resolve_text' => gettext("Cannot resolve"));
+
+ echo json_encode(str_replace("\\","\\\\", $response)); // single escape chars can break JSON decode
+ exit;
+}
+# --- AJAX REVERSE DNS RESOLVE End ---
+
+if ($_POST['filterlogentries_submit']) {
+ // Set flag for filtering alert entries
+ $filterlogentries = TRUE;
+
+ // -- IMPORTANT --
+ // Note the order of these fields must match the order decoded from the alerts log
+ $filterfieldsarray = array();
+ $filterfieldsarray['time'] = $_POST['filterlogentries_time'] ? $_POST['filterlogentries_time'] : null;
+ $filterfieldsarray['action'] = null;
+ $filterfieldsarray['gid'] = $_POST['filterlogentries_gid'] ? $_POST['filterlogentries_gid'] : null;
+ $filterfieldsarray['sid'] = $_POST['filterlogentries_sid'] ? $_POST['filterlogentries_sid'] : null;
+ $filterfieldsarray['rev'] = null;
+ $filterfieldsarray['msg'] = $_POST['filterlogentries_description'] ? $_POST['filterlogentries_description'] : null;
+ $filterfieldsarray['class'] = $_POST['filterlogentries_classification'] ? $_POST['filterlogentries_classification'] : null;
+ $filterfieldsarray['priority'] = $_POST['filterlogentries_priority'] ? $_POST['filterlogentries_priority'] : null;
+ $filterfieldsarray['proto'] = $_POST['filterlogentries_protocol'] ? $_POST['filterlogentries_protocol'] : null;
+ // Remove any zero-length spaces added to the IP address that could creep in from a copy-paste operation
+ $filterfieldsarray['src'] = $_POST['filterlogentries_sourceipaddress'] ? str_replace("\xE2\x80\x8B", "", $_POST['filterlogentries_sourceipaddress']) : null;
+ $filterfieldsarray['sport'] = $_POST['filterlogentries_sourceport'] ? $_POST['filterlogentries_sourceport'] : null;
+ // Remove any zero-length spaces added to the IP address that could creep in from a copy-paste operation
+ $filterfieldsarray['dst'] = $_POST['filterlogentries_destinationipaddress'] ? str_replace("\xE2\x80\x8B", "", $_POST['filterlogentries_destinationipaddress']) : null;
+ $filterfieldsarray['dport'] = $_POST['filterlogentries_destinationport'] ? $_POST['filterlogentries_destinationport'] : null;
+}
+
+if ($_POST['filterlogentries_clear']) {
+ $filterfieldsarray = array();
+ $filterlogentries = TRUE;
+}
+
if ($_POST['save']) {
if (!is_array($config['installedpackages']['suricata']['alertsblocks']))
$config['installedpackages']['suricata']['alertsblocks'] = array();
@@ -224,6 +298,9 @@ if (($_POST['addsuppress_srcip'] || $_POST['addsuppress_dstip'] || $_POST['addsu
if (suricata_add_supplist_entry($suppress)) {
suricata_reload_config($a_instance[$instanceid]);
$savemsg = $success;
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
sleep(2);
}
else
@@ -277,11 +354,16 @@ if ($_POST['togglesid'] && is_numeric($_POST['sidid']) && is_numeric($_POST['gen
/* rules for this interface. */
/*************************************************/
$rebuild_rules = true;
+ conf_mount_rw();
suricata_generate_yaml($a_instance[$instanceid]);
+ conf_mount_ro();
$rebuild_rules = false;
/* Signal Suricata to live-load the new rules */
suricata_reload_config($a_instance[$instanceid]);
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
sleep(2);
$savemsg = gettext("The state for rule {$gid}:{$sid} has been modified. Suricata is 'live-reloading' the new rules list. Please wait at least 15 secs for the process to complete before toggling additional rules.");
@@ -299,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: ');
@@ -313,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");
@@ -334,7 +416,6 @@ include_once("head.inc");
?>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
-<script src="/javascript/filter_log.js" type="text/javascript"></script>
<?php
include_once("fbegin.inc");
@@ -359,24 +440,29 @@ if ($savemsg) {
<input type="hidden" name="descr" id="descr" value=""/>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), true, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
$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>
<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("Alert Log View Settings"); ?></td>
</tr>
@@ -410,16 +496,104 @@ if ($savemsg) {
<td width="78%" class="vtable">
<input name="save" type="submit" class="formbtns" value=" Save " title="<?=gettext("Save auto-refresh and view settings");?>"/>
&nbsp;<?php echo gettext('Refresh');?>&nbsp;&nbsp;<input name="arefresh" type="checkbox" value="on"
- <?php if ($config['installedpackages']['snortglobal']['alertsblocks']['arefresh']=="on") echo "checked"; ?>/>
+ <?php if ($config['installedpackages']['suricata']['alertsblocks']['arefresh']=="on") echo "checked"; ?>/>
<?php printf(gettext('%sDefault%s is %sON%s.'), '<strong>', '</strong>', '<strong>', '</strong>'); ?>&nbsp;&nbsp;
<input name="alertnumber" type="text" class="formfld unknown" id="alertnumber" size="5" value="<?=htmlspecialchars($anentries);?>"/>
&nbsp;<?php printf(gettext('Enter number of log entries to view. %sDefault%s is %s250%s.'), '<strong>', '</strong>', '<strong>', '</strong>'); ?>
</td>
</tr>
<tr>
+ <td colspan="2" class="listtopic"><?php echo gettext("Alert Log View Filter"); ?></td>
+ </tr>
+ <tr id="filter_enable_row" style="display:<?php if (!$filterlogentries) {echo "table-row;";} else {echo "none;";} ?>">
+ <td width="22%" class="vncell"><?php echo gettext('Alert Log Filter Options'); ?></td>
+ <td width="78%" class="vtable">
+ <input name="show_filter" id="show_filter" type="button" class="formbtns" value="<?=gettext("Show Filter");?>" onclick="enable_showFilter();" />
+ &nbsp;&nbsp;<?=gettext("Click to display advanced filtering options dialog");?>
+ </td>
+ </tr>
+ <tr id="filter_options_row" style="display:<?php if (!$filterlogentries) {echo "none;";} else {echo "table-row;";} ?>">
+ <td colspan="2">
+ <table width="100%" border="0" cellpadding="0" cellspacing="1" summary="action">
+ <tr>
+ <td valign="top">
+ <div align="center"><?=gettext("Date");?></div>
+ <div align="center"><input id="filterlogentries_time" name="filterlogentries_time" class="formfld search" type="text" size="10" value="<?= $filterfieldsarray['time'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("Source IP Address");?></div>
+ <div align="center"><input id="filterlogentries_sourceipaddress" name="filterlogentries_sourceipaddress" class="formfld search" type="text" size="28" value="<?= $filterfieldsarray['src'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("Source Port");?></div>
+ <div align="center"><input id="filterlogentries_sourceport" name="filterlogentries_sourceport" class="formfld search" type="text" size="5" value="<?= $filterfieldsarray['sport'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("Description");?></div>
+ <div align="center"><input id="filterlogentries_description" name="filterlogentries_description" class="formfld search" type="text" size="28" value="<?= $filterfieldsarray['msg'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("GID");?></div>
+ <div align="center"><input id="filterlogentries_gid" name="filterlogentries_gid" class="formfld search" type="text" size="6" value="<?= $filterfieldsarray['gid'] ?>" /></div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div align="center"><?=gettext("Priority");?></div>
+ <div align="center"><input id="filterlogentries_priority" name="filterlogentries_priority" class="formfld search" type="text" size="10" value="<?= $filterfieldsarray['priority'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("Destination IP Address");?></div>
+ <div align="center"><input id="filterlogentries_destinationipaddress" name="filterlogentries_destinationipaddress" class="formfld search" type="text" size="28" value="<?= $filterfieldsarray['dst'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("Destination Port");?></div>
+ <div align="center"><input id="filterlogentries_destinationport" name="filterlogentries_destinationport" class="formfld search" type="text" size="5" value="<?= $filterfieldsarray['dport'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("Classification");?></div>
+ <div align="center"><input id="filterlogentries_classification" name="filterlogentries_classification" class="formfld search" type="text" size="28" value="<?= $filterfieldsarray['class'] ?>" /></div>
+ </td>
+ <td valign="top">
+ <div align="center"><?=gettext("SID");?></div>
+ <div align="center"><input id="filterlogentries_sid" name="filterlogentries_sid" class="formfld search" type="text" size="6" value="<?= $filterfieldsarray['sid'] ?>" /></div>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <div align="center"><?=gettext("Protocol");?></div>
+ <div align="center"><input id="filterlogentries_protocol" name="filterlogentries_protocol" class="formfld search" type="text" size="10" value="<?= $filterfieldsarray['proto'] ?>" /></div>
+ </td>
+ <td valign="top">
+ </td>
+ <td valign="top">
+ </td>
+ <td colspan="2" style="vertical-align:bottom">
+ <div align="right"><input id="filterlogentries_submit" name="filterlogentries_submit" type="submit" class="formbtns" value="<?=gettext("Filter");?>" title="<?=gettext("Apply filter"); ?>" />
+ &nbsp;&nbsp;&nbsp;<input id="filterlogentries_clear" name="filterlogentries_clear" type="submit" class="formbtns" value="<?=gettext("Clear");?>" title="<?=gettext("Remove filter");?>" />
+ &nbsp;&nbsp;&nbsp;<input id="filterlogentries_hide" name="filterlogentries_hide" type="button" class="formbtns" value="<?=gettext("Hide");?>" onclick="enable_hideFilter();" title="<?=gettext("Hide filter options");?>" /></div>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="5" style="vertical-align:bottom">
+ &nbsp;<?printf(gettext('Matches %1$s regular expression%2$s.'), '<a target="_blank" href="http://www.php.net/manual/en/book.pcre.php">', '</a>');?>&nbsp;&nbsp;
+ <?=gettext("Precede with exclamation (!) as first character to exclude match.");?>&nbsp;&nbsp;
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ <?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>
+ </tr>
+ <?php else: ?>
+ <tr>
<td colspan="2" class="listtopic"><?php printf(gettext("Last %s Alert Entries"), $anentries); ?>&nbsp;&nbsp;
<?php echo gettext("(Most recent entries are listed first)"); ?></td>
</tr>
+ <?php endif; ?>
<tr>
<td width="100%" colspan="2">
<table id="myTable" style="table-layout: fixed;" width="100%" class="sortable" border="0" cellpadding="0" cellspacing="0">
@@ -436,7 +610,7 @@ if ($savemsg) {
<col axis="string">
</colgroup>
<thead>
- <tr>
+ <tr class="sortableHeaderRowIdentifier">
<th class="listhdrr" axis="date"><?php echo gettext("Date"); ?></th>
<th class="listhdrr" axis="number"><?php echo gettext("Pri"); ?></th>
<th class="listhdrr" axis="string"><?php echo gettext("Proto"); ?></th>
@@ -445,7 +619,7 @@ if ($savemsg) {
<th class="listhdrr" axis="string"><?php echo gettext("SPort"); ?></th>
<th class="listhdrr" axis="string"><?php echo gettext("Dst"); ?></th>
<th class="listhdrr" axis="string"><?php echo gettext("DPort"); ?></th>
- <th class="listhdrr" axis="number"><?php echo gettext("SID"); ?></th>
+ <th class="listhdrr" axis="number"><?php echo gettext("GID:SID"); ?></th>
<th class="listhdrr" axis="string"><?php echo gettext("Description"); ?></th>
</tr>
</thead>
@@ -453,100 +627,180 @@ 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;
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */
- /* File format timestamp,action,sig_generator,sig_id,sig_rev,msg,classification,priority,proto,src,srcport,dst,dstport */
- $fd = fopen("/tmp/alerts_suricata{$suricata_uuid}", "r");
- while (($fields = fgetcsv($fd, 1000, ',', '"')) !== FALSE) {
- if(count($fields) < 13)
- continue;
+
+ /*************** 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 */
+ /****************************************************************************************************************************************/
+
+ /**************** FORMAT without CSV patch -- DECODER EVENT -- **************************************************************************/
+ /* Line format: timestamp action[**] [gid:sid:rev] msg [**] [Classification: class] [Priority: pri] [**] [Raw pkt: ...] */
+ /* 0 1 2 3 4 5 6 7 */
+ /************** *************************************************************************************************************************/
+
+ $fd = fopen("{$g['tmp_path']}/alerts_suricata{$suricata_uuid}", "r");
+ $buf = "";
+ while (($buf = fgets($fd)) !== FALSE) {
+ $fields = array();
+ $tmp = array();
+ $decoder_event = FALSE;
+
+ /**************************************************************/
+ /* Parse alert log entry to find the parts we want to display */
+ /**************************************************************/
+
+ // Field 0 is the event timestamp
+ $fields['time'] = substr($buf, 0, strpos($buf, ' '));
+
+ // Field 1 is currently not used, so set to NULL
+ $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, 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 PROTO
+ $fields['proto'] = trim($tmp[1]);
+
+ // Get SRC
+ $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['sport'] = trim(substr($tmp[2], strrpos($tmp[2], ':') + 1));
+
+ // Get DST
+ $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['dport'] = trim(substr($tmp[3], strrpos($tmp[3], ':') + 1));
+ }
+ else {
+ // If no PROTO nor IP ADDR, then this is a DECODER EVENT
+ $decoder_event = TRUE;
+ $fields['proto'] = gettext("n/a");
+ $fields['sport'] = gettext("n/a");
+ $fields['dport'] = gettext("n/a");
+ }
// Create a DateTime object from the event timestamp that
// we can use to easily manipulate output formats.
- $event_tm = date_create_from_format("m/d/Y-H:i:s.u", $fields[0]);
+ $event_tm = date_create_from_format("m/d/Y-H:i:s.u", $fields['time']);
// Check the 'CATEGORY' field for the text "(null)" and
// substitute "Not Assigned".
- if ($fields[6] == "(null)")
- $fields[6] = "Not Assigned";
+ if ($fields['class'] == "(null)")
+ $fields['class'] = gettext("Not Assigned");
+
+ $fields['time'] = date_format($event_tm, "m/d/Y") . " " . date_format($event_tm, "H:i:s");
+ if ($filterlogentries && !suricata_match_filter_field($fields, $filterfieldsarray)) {
+ continue;
+ }
/* Time */
$alert_time = date_format($event_tm, "H:i:s");
/* Date */
$alert_date = date_format($event_tm, "m/d/Y");
/* Description */
- $alert_descr = $fields[5];
- $alert_descr_url = urlencode($fields[5]);
+ $alert_descr = $fields['msg'];
+ $alert_descr_url = urlencode($fields['msg']);
/* Priority */
- $alert_priority = $fields[7];
+ $alert_priority = $fields['priority'];
/* Protocol */
- $alert_proto = $fields[8];
+ $alert_proto = $fields['proto'];
+
/* IP SRC */
- $alert_ip_src = $fields[9];
- /* Add zero-width space as soft-break opportunity after each colon if we have an IPv6 address */
- $alert_ip_src = str_replace(":", ":&#8203;", $alert_ip_src);
- /* Add Reverse DNS lookup icons */
- $alert_ip_src .= "<br/><a onclick=\"javascript:getURL('/diag_dns.php?host={$fields[9]}&dialog_output=true', outputrule);\">";
- $alert_ip_src .= "<img src='../themes/{$g['theme']}/images/icons/icon_log_d.gif' width='11' height='11' border='0' ";
- $alert_ip_src .= "title='" . gettext("Resolve host via reverse DNS lookup (quick pop-up)") . "' style=\"cursor: pointer;\"></a>&nbsp;";
- $alert_ip_src .= "<a href='/diag_dns.php?host={$fields[9]}&instance={$instanceid}'>";
- $alert_ip_src .= "<img src='../themes/{$g['theme']}/images/icons/icon_log.gif' width='11' height='11' border='0' ";
- $alert_ip_src .= "title='" . gettext("Resolve host via reverse DNS lookup") . "'></a>";
- /* Add icons for auto-adding to Suppress List if appropriate */
- if (!suricata_is_alert_globally_suppressed($supplist, $fields[2], $fields[3]) &&
- !isset($supplist[$fields[2]][$fields[3]]['by_src'][$fields[9]])) {
- $alert_ip_src .= "&nbsp;&nbsp;<input type='image' name='addsuppress_srcip[]' onClick=\"encRuleSig('{$fields[2]}','{$fields[3]}','{$fields[9]}','{$alert_descr}');\" ";
- $alert_ip_src .= "src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' ";
- $alert_ip_src .= "title='" . gettext("Add this alert to the Suppress List and track by_src IP") . "'/>";
- }
- elseif (isset($supplist[$fields[2]][$fields[3]]['by_src'][$fields[9]])) {
- $alert_ip_src .= "&nbsp;&nbsp;<img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='12' height='12' border='0' ";
- $alert_ip_src .= "title='" . gettext("This alert track by_src IP is already in the Suppress List") . "'/>";
+ if ($decoder_event == FALSE) {
+ $alert_ip_src = $fields['src'];
+ /* Add zero-width space as soft-break opportunity after each colon if we have an IPv6 address */
+ $alert_ip_src = str_replace(":", ":&#8203;", $alert_ip_src);
+ /* Add Reverse DNS lookup icon */
+ $alert_ip_src .= "<br/><img onclick=\"javascript:resolve_with_ajax('{$fields['src']}');\" title=\"";
+ $alert_ip_src .= gettext("Resolve host via reverse DNS lookup") . "\" border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" alt=\"Icon Reverse Resolve with DNS\" ";
+ $alert_ip_src .= " style=\"cursor: pointer;\"/>";
+ /* Add icons for auto-adding to Suppress List if appropriate */
+ if (!suricata_is_alert_globally_suppressed($supplist, $fields['gid'], $fields['sid']) &&
+ !isset($supplist[$fields['gid']][$fields['sid']]['by_src'][$fields['src']])) {
+ $alert_ip_src .= "&nbsp;&nbsp;<input type='image' name='addsuppress_srcip[]' onClick=\"encRuleSig('{$fields['gid']}','{$fields['sid']}','{$fields['src']}','{$alert_descr}');\" ";
+ $alert_ip_src .= "src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' ";
+ $alert_ip_src .= "title='" . gettext("Add this alert to the Suppress List and track by_src IP") . "'/>";
+ }
+ elseif (isset($supplist[$fields['gid']][$fields['sid']]['by_src'][$fields['src']])) {
+ $alert_ip_src .= "&nbsp;&nbsp;<img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='12' height='12' border='0' ";
+ $alert_ip_src .= "title='" . gettext("This alert track by_src IP is already in the Suppress List") . "'/>";
+ }
+ /* Add icon for auto-removing from Blocked Table if required */
+ if (isset($tmpblocked[$fields['src']])) {
+ $alert_ip_src .= "&nbsp;<input type='image' name='unblock[]' onClick=\"document.getElementById('ip').value='{$fields['src']}';\" ";
+ $alert_ip_src .= "title='" . gettext("Remove host from Blocked Table") . "' border='0' width='12' height='12' src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/>";
+ }
}
- /* Add icon for auto-removing from Blocked Table if required */
- if (isset($tmpblocked[$fields[9]])) {
- $alert_ip_src .= "&nbsp;<input type='image' name='unblock[]' onClick=\"document.getElementById('ip').value='{$fields[9]}';\" ";
- $alert_ip_src .= "title='" . gettext("Remove host from Blocked Table") . "' border='0' width='12' height='12' src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/>";
+ else {
+ if (preg_match('/\s\[Raw pkt:(.*)\]/', $buf, $tmp))
+ $alert_ip_src = "<div title='[Raw pkt: {$tmp[1]}]'>" . gettext("Decoder Event") . "</div>";
+ else
+ $alert_ip_src = gettext("Decoder Event");
}
+
/* IP SRC Port */
- $alert_src_p = $fields[10];
- /* IP Destination */
- $alert_ip_dst = $fields[11];
- /* Add zero-width space as soft-break opportunity after each colon if we have an IPv6 address */
- $alert_ip_dst = str_replace(":", ":&#8203;", $alert_ip_dst);
- /* Add Reverse DNS lookup icons */
- $alert_ip_dst .= "<br/><a onclick=\"javascript:getURL('/diag_dns.php?host={$fields[11]}&dialog_output=true', outputrule);\">";
- $alert_ip_dst .= "<img src='../themes/{$g['theme']}/images/icons/icon_log_d.gif' width='11' height='11' border='0' ";
- $alert_ip_dst .= "title='" . gettext("Resolve host via reverse DNS lookup (quick pop-up)") . "' style=\"cursor: pointer;\"></a>&nbsp;";
- $alert_ip_dst .= "<a href='/diag_dns.php?host={$fields[11]}&instance={$instanceid}'>";
- $alert_ip_dst .= "<img src='../themes/{$g['theme']}/images/icons/icon_log.gif' width='11' height='11' border='0' ";
- $alert_ip_dst .= "title='" . gettext("Resolve host via reverse DNS lookup") . "'></a>";
- /* Add icons for auto-adding to Suppress List if appropriate */
- if (!suricata_is_alert_globally_suppressed($supplist, $fields[2], $fields[3]) &&
- !isset($supplist[$fields[2]][$fields[3]]['by_dst'][$fields[11]])) {
- $alert_ip_dst .= "&nbsp;&nbsp;<input type='image' name='addsuppress_dstip[]' onClick=\"encRuleSig('{$fields[2]}','{$fields[3]}','{$fields[11]}','{$alert_descr}');\" ";
- $alert_ip_dst .= "src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' ";
- $alert_ip_dst .= "title='" . gettext("Add this alert to the Suppress List and track by_dst IP") . "'/>";
- }
- elseif (isset($supplist[$fields[2]][$fields[3]]['by_dst'][$fields[11]])) {
- $alert_ip_dst .= "&nbsp;&nbsp;<img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='12' height='12' border='0' ";
- $alert_ip_dst .= "title='" . gettext("This alert track by_dst IP is already in the Suppress List") . "'/>";
+ $alert_src_p = $fields['sport'];
+
+ /* IP DST */
+ if ($decoder_event == FALSE) {
+ $alert_ip_dst = $fields['dst'];
+ /* Add zero-width space as soft-break opportunity after each colon if we have an IPv6 address */
+ $alert_ip_dst = str_replace(":", ":&#8203;", $alert_ip_dst);
+ /* Add Reverse DNS lookup icons */
+ $alert_ip_dst .= "<br/><img onclick=\"javascript:resolve_with_ajax('{$fields['dst']}');\" title=\"";
+ $alert_ip_dst .= gettext("Resolve host via reverse DNS lookup") . "\" border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" alt=\"Icon Reverse Resolve with DNS\" ";
+ $alert_ip_dst .= " style=\"cursor: pointer;\"/>";
+ /* Add icons for auto-adding to Suppress List if appropriate */
+ if (!suricata_is_alert_globally_suppressed($supplist, $fields['gid'], $fields['sid']) &&
+ !isset($supplist[$fields['gid']][$fields['sid']]['by_dst'][$fields['dst']])) {
+ $alert_ip_dst .= "&nbsp;&nbsp;<input type='image' name='addsuppress_dstip[]' onClick=\"encRuleSig('{$fields['gid']}','{$fields['sid']}','{$fields['dst']}','{$alert_descr}');\" ";
+ $alert_ip_dst .= "src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' ";
+ $alert_ip_dst .= "title='" . gettext("Add this alert to the Suppress List and track by_dst IP") . "'/>";
+ }
+ elseif (isset($supplist[$fields['gid']][$fields['sid']]['by_dst'][$fields['dst']])) {
+ $alert_ip_dst .= "&nbsp;&nbsp;<img src='../themes/{$g['theme']}/images/icons/icon_plus_d.gif' width='12' height='12' border='0' ";
+ $alert_ip_dst .= "title='" . gettext("This alert track by_dst IP is already in the Suppress List") . "'/>";
+ }
+
+ /* Add icon for auto-removing from Blocked Table if required */
+ if (isset($tmpblocked[$fields['dst']])) {
+ $alert_ip_dst .= "&nbsp;<input type='image' name='unblock[]' onClick=\"document.getElementById('ip').value='{$fields['dst']}';\" ";
+ $alert_ip_dst .= "title='" . gettext("Remove host from Blocked Table") . "' border='0' width='12' height='12' src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/>";
+ }
}
- /* Add icon for auto-removing from Blocked Table if required */
- if (isset($tmpblocked[$fields[11]])) {
- $alert_ip_dst .= "&nbsp;<input type='image' name='unblock[]' onClick=\"document.getElementById('ip').value='{$fields[11]}';\" ";
- $alert_ip_dst .= "title='" . gettext("Remove host from Blocked Table") . "' border='0' width='12' height='12' src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\"/>";
+ else {
+ $alert_ip_dst = gettext("n/a");
}
+
/* IP DST Port */
- $alert_dst_p = $fields[12];
+ $alert_dst_p = $fields['dport'];
+
/* SID */
- $alert_sid_str = "{$fields[2]}:{$fields[3]}";
- if (!suricata_is_alert_globally_suppressed($supplist, $fields[2], $fields[3])) {
- $sidsupplink = "<input type='image' name='addsuppress[]' onClick=\"encRuleSig('{$fields[2]}','{$fields[3]}','','{$alert_descr}');\" ";
+ $alert_sid_str = "{$fields['gid']}:{$fields['sid']}";
+ if (!suricata_is_alert_globally_suppressed($supplist, $fields['gid'], $fields['sid'])) {
+ $sidsupplink = "<input type='image' name='addsuppress[]' onClick=\"encRuleSig('{$fields['gid']}','{$fields['sid']}','','{$alert_descr}');\" ";
$sidsupplink .= "src='../themes/{$g['theme']}/images/icons/icon_plus.gif' width='12' height='12' border='0' ";
$sidsupplink .= "title='" . gettext("Add this alert to the Suppress List") . "'/>";
}
@@ -555,46 +809,47 @@ if (file_exists("/var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.lo
$sidsupplink .= "title='" . gettext("This alert is already in the Suppress List") . "'/>";
}
/* Add icon for toggling rule state */
- if (isset($disablesid[$fields[2]][$fields[3]])) {
- $sid_dsbl_link = "<input type='image' name='togglesid[]' onClick=\"encRuleSig('{$fields[2]}','{$fields[3]}','','');\" ";
+ if (isset($disablesid[$fields['gid']][$fields['sid']])) {
+ $sid_dsbl_link = "<input type='image' name='togglesid[]' onClick=\"encRuleSig('{$fields['gid']}','{$fields['sid']}','','');\" ";
$sid_dsbl_link .= "src='../themes/{$g['theme']}/images/icons/icon_reject.gif' width='11' height='11' border='0' ";
$sid_dsbl_link .= "title='" . gettext("Rule is forced to a disabled state. Click to remove the force-disable action from this rule.") . "'/>";
}
else {
- $sid_dsbl_link = "<input type='image' name='togglesid[]' onClick=\"encRuleSig('{$fields[2]}','{$fields[3]}','','');\" ";
+ $sid_dsbl_link = "<input type='image' name='togglesid[]' onClick=\"encRuleSig('{$fields['gid']}','{$fields['sid']}','','');\" ";
$sid_dsbl_link .= "src='../themes/{$g['theme']}/images/icons/icon_block.gif' width='11' height='11' border='0' ";
$sid_dsbl_link .= "title='" . gettext("Force-disable this rule and remove it from current rules set.") . "'/>";
}
/* DESCRIPTION */
- $alert_class = $fields[6];
+ $alert_class = $fields['class'];
echo "<tr>
<td class='listr' align='center'>{$alert_date}<br/>{$alert_time}</td>
<td class='listr' align='center'>{$alert_priority}</td>
<td class='listr' align='center'>{$alert_proto}</td>
<td class='listr' style=\"word-wrap:break-word;\">{$alert_class}</td>
- <td class='listr' align='center' sorttable_customkey='{$fields[9]}'>{$alert_ip_src}</td>
+ <td class='listr' style=\"sorttable_customkey:{$fields['src']};\" sorttable_customkey=\"{$fields['src']}\" align='center'>{$alert_ip_src}</td>
<td class='listr' align='center'>{$alert_src_p}</td>
- <td class='listr' align='center' sorttable_customkey='{$fields[11]}'>{$alert_ip_dst}</td>
+ <td class='listr' align='center' style=\"sorttable_customkey:{$fields['dst']};\" sorttable_customkey=\"{$fields['dst']}\">{$alert_ip_dst}</td>
<td class='listr' align='center'>{$alert_dst_p}</td>
- <td class='listr' align='center' sorttable_customkey='{$fields[3]}'>{$alert_sid_str}<br/>{$sidsupplink}&nbsp;&nbsp;{$sid_dsbl_link}</td>
+ <td class='listr' align='center' style=\"sorttable_customkey:{$fields['sid']};\" sorttable_customkey=\"{$fields['sid']}\">{$alert_sid_str}<br/>{$sidsupplink}&nbsp;&nbsp;{$sid_dsbl_link}</td>
<td class='listbg' style=\"word-wrap:break-word;\">{$alert_descr}</td>
</tr>\n";
$counter++;
}
+ unset($fields, $buf, $tmp);
fclose($fd);
- @unlink("/tmp/alerts_suricata{$suricata_uuid}");
+ unlink_if_exists("{$g['tmp_path']}/alerts_suricata{$suricata_uuid}");
}
}
?>
</tbody>
</table>
</td>
-</tr>
+</tr></tbody>
</table>
</div>
-</td></tr>
+</td></tr></tbody>
</table>
</form>
<?php
@@ -615,6 +870,50 @@ function encRuleSig(rulegid,rulesid,srcip,ruledescr) {
document.getElementById("ip").value = srcip;
document.getElementById("descr").value = ruledescr;
}
+
+function enable_showFilter() {
+ document.getElementById("filter_enable_row").style.display="none";
+ document.getElementById("filter_options_row").style.display="table-row";
+}
+
+function enable_hideFilter() {
+ document.getElementById("filter_enable_row").style.display="table-row";
+ document.getElementById("filter_options_row").style.display="none";
+}
+
+</script>
+
+<!-- The following AJAX code was borrowed from the diag_logs_filter.php -->
+<!-- file in pfSense. See copyright info at top of this page. -->
+<script type="text/javascript">
+//<![CDATA[
+function resolve_with_ajax(ip_to_resolve) {
+ var url = "/suricata/suricata_alerts.php";
+
+ jQuery.ajax(
+ url,
+ {
+ type: 'post',
+ dataType: 'json',
+ data: {
+ resolve: ip_to_resolve,
+ },
+ complete: resolve_ip_callback
+ });
+}
+
+function resolve_ip_callback(transport) {
+ var response = jQuery.parseJSON(transport.responseText);
+ var msg = 'IP address "' + response.resolve_ip + '" resolves to\n';
+ alert(msg + 'host "' + htmlspecialchars(response.resolve_text) + '"');
+}
+
+// From http://stackoverflow.com/questions/5499078/fastest-method-to-escape-html-tags-as-html-entities
+function htmlspecialchars(str) {
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
+}
+//]]>
</script>
+
</body>
</html>
diff --git a/config/suricata/suricata_alerts.widget.php b/config/suricata/suricata_alerts.widget.php
index 21fad03d..81d17c2e 100644
--- a/config/suricata/suricata_alerts.widget.php
+++ b/config/suricata/suricata_alerts.widget.php
@@ -42,8 +42,8 @@ if (!is_array($config['installedpackages']['suricata']['rule']))
$a_instance = &$config['installedpackages']['suricata']['rule'];
/* array sorting */
-function sksort(&$array, $subkey="id", $sort_ascending=false) {
- /* an empty array causes sksort to fail - this test alleviates the error */
+function suricata_sksort(&$array, $subkey="id", $sort_ascending=false) {
+ /* an empty array causes suricata_sksort to fail - this test alleviates the error */
if(empty($array))
return false;
if (count($array)){
@@ -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;
@@ -114,12 +114,62 @@ function suricata_widget_get_alerts() {
exec("tail -{$suri_nentries} -r /var/log/suricata/suricata_{$if_real}{$suricata_uuid}/alerts.log > /tmp/surialerts_{$suricata_uuid}");
if (file_exists("/tmp/surialerts_{$suricata_uuid}")) {
- /* 0 1 2 3 4 5 6 7 8 9 10 11 12 */
- /* File format: timestamp,action,sig_generator,sig_id,sig_rev,msg,classification,priority,proto,src,srcport,dst,dstport */
+ /*************** 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 */
+ /****************************************************************************************************************************************/
+
+ /**************** FORMAT without CSV patch -- DECODER EVENT -- **************************************************************************/
+ /* Line format: timestamp action[**] [gid:sid:rev] msg [**] [Classification: class] [Priority: pri] [**] [Raw pkt: ...] */
+ /* 0 1 2 3 4 5 6 7 */
+ /************** *************************************************************************************************************************/
+
$fd = fopen("/tmp/surialerts_{$suricata_uuid}", "r");
- while (($fields = fgetcsv($fd, 1000, ',', '"')) !== FALSE) {
- if(count($fields) < 13)
- continue;
+ $buf = "";
+ while (($buf = fgets($fd)) !== FALSE) {
+ $fields = array();
+ $tmp = array();
+
+ // Parse alert log entry to find the parts we want to display
+ $fields[0] = substr($buf, 0, strpos($buf, ' '));
+
+ // 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, 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['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['sport'] = trim(substr($tmp[2], strrpos($tmp[2], ':') + 1));
+
+ // Get DST
+ $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['dport'] = trim(substr($tmp[3], strrpos($tmp[3], ':') + 1));
+ }
+ else {
+ // If no PROTO and IP ADDR, then this is a DECODER EVENT
+ $fields['src'] = gettext("Decoder Event");
+ $fields['sport'] = "";
+ $fields['dst'] = "";
+ $fields['dport'] = "";
+ }
// Create a DateTime object from the event timestamp that
// we can use to easily manipulate output formats.
@@ -127,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($a_instance[$instanceid]['interface']);
+ $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]))
- $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];
- // Add the SRC PORT if not null
- if (!empty($fields[12]))
- $suricata_alerts[$counter]['dst'] .= ":" . $fields[12];
- $suricata_alerts[$counter]['priority'] = $fields[7];
- $suricata_alerts[$counter]['category'] = $fields[6];
+ $suricata_alerts[$counter]['dst'] = $fields['dst'];
+ // Add the DST PORT if not null
+ if (!empty($fields['dport']) || $fields['dport'] == '0')
+ $suricata_alerts[$counter]['dst'] .= ":" . $fields['dport'];
$counter++;
};
fclose($fd);
@@ -162,9 +211,9 @@ function suricata_widget_get_alerts() {
// Sort the alerts array
if (isset($config['syslog']['reverse'])) {
- sksort($suricata_alerts, 'timestamp', false);
+ suricata_sksort($suricata_alerts, 'timestamp', false);
} else {
- sksort($suricata_alerts, 'timestamp', true);
+ suricata_sksort($suricata_alerts, 'timestamp', true);
}
return $suricata_alerts;
@@ -192,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("Classification");?></th>
+ <th class="listhdrr"><?=gettext("Description");?></th>
</tr>
</thead>
<tbody id="suricata-alert-entries">
@@ -205,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 c28b99d1..cfa34a54 100644
--- a/config/suricata/suricata_app_parsers.php
+++ b/config/suricata/suricata_app_parsers.php
@@ -86,13 +86,14 @@ if (isset($id) && $a_nat[$id]) {
if (empty($pconfig['libhtp_policy']['item'])) {
$default = array( "name" => "default", "bind_to" => "all", "personality" => "IDS",
"request-body-limit" => 4096, "response-body-limit" => 4096,
- "double-decode-path" => "no", "double-decode-query" => "no" );
+ "double-decode-path" => "no", "double-decode-query" => "no",
+ "uri-include-all" => "no" );
$pconfig['libhtp_policy']['item'] = array();
$pconfig['libhtp_policy']['item'][] = $default;
if (!is_array($a_nat[$id]['libhtp_policy']['item']))
$a_nat[$id]['libhtp_policy']['item'] = array();
$a_nat[$id]['libhtp_policy']['item'][] = $default;
- write_config();
+ write_config("Suricata pkg: created a new default HTTP server configuration for " . convert_friendly_interface_to_friendly_descr($a_nat[$id]['interface']));
$libhtp_engine_next_id++;
}
else
@@ -121,6 +122,7 @@ elseif ($_POST['select_alias']) {
$eng_resp_body_limit = $_POST['resp_body_limit'];
$eng_enable_double_decode_path = $_POST['enable_double_decode_path'];
$eng_enable_double_decode_query = $_POST['enable_double_decode_query'];
+ $eng_enable_uri_include_all = $_POST['enable_uri_include_all'];
$mode = "add_edit_libhtp_policy";
}
if ($_POST['save_libhtp_policy']) {
@@ -161,6 +163,7 @@ if ($_POST['save_libhtp_policy']) {
if ($_POST['enable_double_decode_path']) { $engine['double-decode-path'] = 'yes'; }else{ $engine['double-decode-path'] = 'no'; }
if ($_POST['enable_double_decode_query']) { $engine['double-decode-query'] = 'yes'; }else{ $engine['double-decode-query'] = 'no'; }
+ if ($_POST['enable_uri_include_all']) { $engine['uri-include-all'] = 'yes'; }else{ $engine['uri-include-all'] = 'no'; }
// Can only have one "all" Bind_To address
if ($engine['bind_to'] == "all" && $engine['name'] <> "default")
@@ -196,7 +199,7 @@ if ($_POST['save_libhtp_policy']) {
}
// Now write the new engine array to conf
- write_config();
+ write_config("Suricata pkg: saved updated HTTP server configuration for " . convert_friendly_interface_to_friendly_descr($a_nat[$id]['interface']));
$pconfig['libhtp_policy']['item'] = $a_nat[$id]['libhtp_policy']['item'];
}
else {
@@ -209,7 +212,7 @@ elseif ($_POST['add_libhtp_policy']) {
$add_edit_libhtp_policy = true;
$pengcfg = array( "name" => "engine_{$libhtp_engine_next_id}", "bind_to" => "", "personality" => "IDS",
"request-body-limit" => "4096", "response-body-limit" => "4096",
- "double-decode-path" => "no", "double-decode-query" => "no" );
+ "double-decode-path" => "no", "double-decode-query" => "no", "uri-include-all" => "no" );
$eng_id = $libhtp_engine_next_id;
}
elseif ($_POST['edit_libhtp_policy']) {
@@ -229,7 +232,7 @@ elseif ($_POST['del_libhtp_policy']) {
}
if (isset($id) && $a_nat[$id]) {
$a_nat[$id] = $natent;
- write_config();
+ write_config("Suricata pkg: deleted a HTTP server configuration for " . convert_friendly_interface_to_friendly_descr($a_nat[$id]['interface']));
}
}
elseif ($_POST['cancel_libhtp_policy']) {
@@ -239,9 +242,24 @@ elseif ($_POST['ResetAll']) {
/* Reset all the settings to defaults */
$pconfig['asn1_max_frames'] = "256";
+ $pconfig['dns_global_memcap'] = "16777216";
+ $pconfig['dns_state_memcap'] = "524288";
+ $pconfig['dns_request_flood_limit'] = "500";
+ $pconfig['http_parser_memcap'] = "67108864";
+ $pconfig['dns_parser_udp'] = "yes";
+ $pconfig['dns_parser_tcp'] = "yes";
+ $pconfig['http_parser'] = "yes";
+ $pconfig['tls_parser'] = "yes";
+ $pconfig['smtp_parser'] = "yes";
+ $pconfig['imap_parser'] = "detection-only";
+ $pconfig['ssh_parser'] = "yes";
+ $pconfig['ftp_parser'] = "yes";
+ $pconfig['dcerpc_parser'] = "yes";
+ $pconfig['smb_parser'] = "yes";
+ $pconfig['msn_parser'] = "detection-only";
/* Log a message at the top of the page to inform the user */
- $savemsg = gettext("All flow and stream settings have been reset to their defaults.");
+ $savemsg = gettext("All flow and stream settings on this page have been reset to their defaults. Click APPLY if you wish to keep these new settings.");
}
elseif ($_POST['save_import_alias']) {
// If saving out of "select alias" mode,
@@ -257,6 +275,7 @@ elseif ($_POST['save_import_alias']) {
$pengcfg['response-body-limit'] = $_POST['eng_resp_body_limit'];
$pengcfg['double-decode-path'] = $_POST['eng_enable_double_decode_path'];
$pengcfg['double-decode-query'] = $_POST['eng_enable_double_decode_query'];
+ $pengcfg['uri-include-all'] = $_POST['eng_enable_uri_include_all'];
$add_edit_libhtp_policy = true;
$mode = "add_edit_libhtp_policy";
@@ -277,12 +296,13 @@ elseif ($_POST['save_import_alias']) {
$eng_resp_body_limit = $_POST['eng_resp_body_limit'];
$eng_enable_double_decode_path = $_POST['eng_enable_double_decode_path'];
$eng_enable_double_decode_query = $_POST['eng_enable_double_decode_query'];
+ $eng_enable_uri_include_all = $_POST['eng_enable_uri_include_all'];
}
}
else {
$engine = array( "name" => "", "bind_to" => "", "personality" => "IDS",
"request-body-limit" => "4096", "response-body-limit" => "4096",
- "double-decode-path" => "no", "double-decode-query" => "no" );
+ "double-decode-path" => "no", "double-decode-query" => "no", "uri-include-all" => "no" );
// See if anything was checked to import
if (is_array($_POST['aliastoimport']) && count($_POST['aliastoimport']) > 0) {
@@ -322,7 +342,7 @@ elseif ($_POST['save_import_alias']) {
}
// Write the new engine array to config file
- write_config();
+ write_config("Suricata pkg: saved an updated HTTP server configuration for " . convert_friendly_interface_to_friendly_descr($a_nat[$id]['interface']));
$importalias = false;
}
}
@@ -344,10 +364,11 @@ elseif ($_POST['cancel_import_alias']) {
$pengcfg['response-body-limit'] = $_POST['eng_resp_body_limit'];
$pengcfg['double-decode-path'] = $_POST['eng_enable_double_decode_path'];
$pengcfg['double-decode-query'] = $_POST['eng_enable_double_decode_query'];
+ $pengcfg['uri-include-all'] = $_POST['eng_enable_uri_include_all'];
$add_edit_libhtp_policy = true;
}
}
-elseif ($_POST['save']) {
+elseif ($_POST['save'] || $_POST['apply']) {
$natent = array();
$natent = $pconfig;
@@ -355,9 +376,37 @@ elseif ($_POST['save']) {
if (!is_numeric($_POST['asn1_max_frames'] ) || $_POST['asn1_max_frames'] < 1)
$input_errors[] = gettext("The value for 'ASN1 Max Frames' must be all numbers and greater than 0.");
+ if (!is_numeric($_POST['dns_global_memcap'] ) || $_POST['dns_global_memcap'] < 1)
+ $input_errors[] = gettext("The value for 'DNS Global Memcap' must be all numbers and greater than 0.");
+
+ if (!is_numeric($_POST['dns_state_memcap'] ) || $_POST['dns_state_memcap'] < 1)
+ $input_errors[] = gettext("The value for 'DNS Flow/State Memcap' must be all numbers and greater than 0.");
+
+ if (!is_numeric($_POST['dns_request_flood_limit'] ) || $_POST['dns_request_flood_limit'] < 1)
+ $input_errors[] = gettext("The value for 'DNS Request Flood Limit' must be all numbers and greater than 0.");
+
+ if (!is_numeric($_POST['http_parser_memcap'] ) || $_POST['http_parser_memcap'] < 1)
+ $input_errors[] = gettext("The value for 'HTTP Memcap' must be all numbers and greater than 0.");
+
/* if no errors write to conf */
if (!$input_errors) {
if ($_POST['asn1_max_frames'] != "") { $natent['asn1_max_frames'] = $_POST['asn1_max_frames']; }else{ $natent['asn1_max_frames'] = "256"; }
+ if ($_POST['dns_global_memcap'] != ""){ $natent['dns_global_memcap'] = $_POST['dns_global_memcap']; }else{ $natent['dns_global_memcap'] = "16777216"; }
+ if ($_POST['dns_state_memcap'] != ""){ $natent['dns_state_memcap'] = $_POST['dns_state_memcap']; }else{ $natent['dns_state_memcap'] = "524288"; }
+ if ($_POST['dns_request_flood_limit'] != ""){ $natent['dns_request_flood_limit'] = $_POST['dns_request_flood_limit']; }else{ $natent['dns_request_flood_limit'] = "500"; }
+ if ($_POST['http_parser_memcap'] != ""){ $natent['http_parser_memcap'] = $_POST['http_parser_memcap']; }else{ $natent['http_parser_memcap'] = "67108864"; }
+
+ $natent['dns_parser_udp'] = $_POST['dns_parser_udp'];
+ $natent['dns_parser_tcp'] = $_POST['dns_parser_tcp'];
+ $natent['http_parser'] = $_POST['http_parser'];
+ $natent['tls_parser'] = $_POST['tls_parser'];
+ $natent['smtp_parser'] = $_POST['smtp_parser'];
+ $natent['imap_parser'] = $_POST['imap_parser'];
+ $natent['ssh_parser'] = $_POST['ssh_parser'];
+ $natent['ftp_parser'] = $_POST['ftp_parser'];
+ $natent['dcerpc_parser'] = $_POST['dcerpc_parser'];
+ $natent['smb_parser'] = $_POST['smb_parser'];
+ $natent['msn_parser'] = $_POST['msn_parser'];
/**************************************************/
/* If we have a valid rule ID, save configuration */
@@ -366,9 +415,14 @@ elseif ($_POST['save']) {
/**************************************************/
if (isset($id) && $a_nat[$id]) {
$a_nat[$id] = $natent;
- write_config();
+ write_config("Suricata pkg: saved updated app-layer parser configuration for " . convert_friendly_interface_to_friendly_descr($a_nat[$id]['interface']));
$rebuild_rules = false;
+ conf_mount_rw();
suricata_generate_yaml($natent);
+ conf_mount_ro();
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
}
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
@@ -382,37 +436,46 @@ elseif ($_POST['save']) {
}
$if_friendly = convert_friendly_interface_to_friendly_descr($pconfig['interface']);
-$pgtitle = gettext("Suricata: Interface {$if_friendly} - Layer 7 Application Parsers");
+$pgtitle = gettext("Suricata: Interface {$if_friendly} - Application Layer Parsers");
include_once("head.inc");
?>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<?php include("fbegin.inc");
- /* Display error or save message */
+ /* Display error message */
if ($input_errors) {
print_input_errors($input_errors);
}
- if ($savemsg) {
- print_info_box($savemsg);
- }
?>
<form action="suricata_app_parsers.php" method="post" name="iform" id="iform">
<input name="id" type="hidden" value="<?=$id;?>"/>
<input type="hidden" name="eng_id" id="eng_id" value="<?=$eng_id;?>"/>
+
+<?php
+if ($savemsg) {
+ /* Display save message */
+ print_info_box($savemsg);
+}
+?>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.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("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $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>';
@@ -425,6 +488,7 @@ include_once("head.inc");
$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>
@@ -440,6 +504,7 @@ include_once("head.inc");
echo '<input type="hidden" name="eng_resp_body_limit" value="' . $eng_resp_body_limit . '"/>';
echo '<input type="hidden" name="eng_enable_double_decode_path" value="' . $eng_enable_double_decode_path . '"/>';
echo '<input type="hidden" name="eng_enable_double_decode_query" value="' . $eng_enable_double_decode_query . '"/>';
+ echo '<input type="hidden" name="eng_enable_uri_include_all" value="' . $eng_enable_uri_include_all . '"/>';
}
?>
@@ -449,6 +514,7 @@ include_once("head.inc");
<?php else: ?>
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Abstract Syntax One Settings"); ?></td>
@@ -465,11 +531,103 @@ include_once("head.inc");
gettext("H.323 (VoIP), and SNMP, use ASN.1 to describe the protocol data units (PDUs) they exchange."); ?>
</td>
</tr>
+
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("DNS App-Layer Parser Settings"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Global Memcap"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="dns_global_memcap" type="text" class="formfld unknown" id="dns_global_memcap" size="9"
+ value="<?=htmlspecialchars($pconfig['dns_global_memcap']);?>">&nbsp;
+ <?php echo gettext("Sets the global memcap limit for the DNS parser. Default is ") .
+ "<strong>" . gettext("16777216") . "</strong>" . gettext(" bytes (16MB)."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Flow/State Memcap"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="dns_state_memcap" type="text" class="formfld unknown" id="dns_state_memcap" size="9"
+ value="<?=htmlspecialchars($pconfig['dns_state_memcap']);?>">&nbsp;
+ <?php echo gettext("Sets per flow/state memcap limit for the DNS parser. Default is ") .
+ "<strong>" . gettext("524288") . "</strong>" . gettext(" bytes (512KB)."); ?>
+ </td>
+ </tr>
<tr>
- <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Host-Specific HTTP Server Settings"); ?></td>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Request Flood Limit"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="dns_request_flood_limit" type="text" class="formfld unknown" id="dns_request_flood_limit" size="9"
+ value="<?=htmlspecialchars($pconfig['dns_request_flood_limit']);?>">&nbsp;
+ <?php echo gettext("How many unreplied DNS requests are considered a flood. Default is ") .
+ "<strong>" . gettext("500") . "</strong>" . gettext(" requests."); ?><br/>
+ <?php echo gettext("If this limit is reached, 'app-layer-event:dns.flooded' will match and alert. "); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("UDP Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="dns_parser_udp" id="dns_parser_udp" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['dns_parser_udp'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for UDP. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("TCP Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="dns_parser_tcp" id="dns_parser_tcp" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['dns_parser_tcp'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for TCP. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("HTTP App-Layer Parser Settings"); ?></td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncell"><?php echo gettext("Server Configuration"); ?></td>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Memcap"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="http_parser_memcap" type="text" class="formfld unknown" id="http_parser_memcap" size="9"
+ value="<?=htmlspecialchars($pconfig['http_parser_memcap']);?>">&nbsp;
+ <?php echo gettext("Sets the memcap limit for the HTTP parser. Default is ") .
+ "<strong>" . gettext("67108864") . "</strong>" . gettext(" bytes (64MB)."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("HTTP Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="http_parser" id="http_parser" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['http_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for HTTP. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Server Configurations"); ?></td>
<td width="78%" class="vtable">
<table width="95%" align="left" id="libhtpEnginesTable" style="table-layout: fixed;" border="0" cellspacing="0" cellpadding="0">
<colgroup>
@@ -487,6 +645,7 @@ include_once("head.inc");
height="17" border="0" title="<?php echo gettext("Add a new server configuration");?>"></th>
</tr>
</thead>
+ <tbody>
<?php foreach ($pconfig['libhtp_policy']['item'] as $f => $v): ?>
<tr>
<td class="listlr" align="left"><?=gettext($v['name']);?></td>
@@ -505,19 +664,159 @@ include_once("head.inc");
</td>
</tr>
<?php endforeach; ?>
+ </tbody>
</table>
</td>
</tr>
<tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Other App-Layer Parser Settings"); ?></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("TLS Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="tls_parser" id="tls_parser" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['tls_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for TLS. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("SMTP Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="smtp_parser" id="smtp_parser" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['smtp_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for SMTP. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("IMAP Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="imap_parser" id="imap_parser" class="formselect">
+ <?php
+ $opt = array( "detection-only", "yes", "no" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['imap_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for IMAP. Default is ") . "<strong>" . gettext("detection-only") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("SSH Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="ssh_parser" id="ssh_parser" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['ssh_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for SSH. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("FTP Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="ftp_parser" id="ftp_parser" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['ftp_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for FTP. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("DCERPC Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="dcerpc_parser" id="dcerpc_parser" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['dcerpc_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for DCERPC. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("SMB Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="smb_parser" id="smb_parser" class="formselect">
+ <?php
+ $opt = array( "yes", "no", "detection-only" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['smb_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for SMB. Default is ") . "<strong>" . gettext("yes") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("MSN Parser"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="msn_parser" id="msn_parser" class="formselect">
+ <?php
+ $opt = array( "detection-only", "yes", "no" );
+ foreach ($opt as $val) {
+ $selected = "";
+ if ($val == $pconfig['msn_parser'])
+ $selected = " selected";
+ echo "<option value='{$val}'{$selected}>" . $val . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Choose the parser/detection setting for MSN. Default is ") . "<strong>" . gettext("detection-only") . "</strong>" . gettext("."); ?><br/>
+ <?php echo gettext("Selecting \"yes\" enables detection and parser, \"no\" disables both and \"detection-only\" disables parser."); ?>
+ </td>
+ </tr>
+ <tr>
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
<input name="save" type="submit" class="formbtn" value="Save" title="<?php echo
- gettext("Save flow and stream settings"); ?>">
+ gettext("Save flow and stream settings"); ?>"/>
&nbsp;&nbsp;&nbsp;&nbsp;
<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 App Parsers settings to their defaults. Click OK to continue or CANCEL to quit.") .
- "');\""; ?>></td>
+ "');\""; ?>/></td>
</tr>
<tr>
<td width="22%" valign="top">&nbsp;</td>
@@ -525,12 +824,13 @@ include_once("head.inc");
<?php echo gettext("Please save your settings before you exit. Changes will rebuild the rules file. This "); ?>
<?php echo gettext("may take several seconds. Suricata must also be restarted to activate any changes made on this screen."); ?></td>
</tr>
+ </tbody>
</table>
<?php endif; ?>
</div>
-</td></tr></table>
+</td></tr></tbody></table>
</form>
<?php include("fend.inc"); ?>
</body>
diff --git a/config/suricata/suricata_barnyard.php b/config/suricata/suricata_barnyard.php
index d4afe4f4..2938136f 100644
--- a/config/suricata/suricata_barnyard.php
+++ b/config/suricata/suricata_barnyard.php
@@ -79,23 +79,50 @@ if (isset($id) && $a_nat[$id]) {
if (empty($a_nat[$id]['barnyard_syslog_opmode']))
$pconfig['barnyard_syslog_opmode'] = "default";
if (empty($a_nat[$id]['barnyard_syslog_facility']))
- $pconfig['barnyard_syslog_facility'] = "LOG_USER";
+ $pconfig['barnyard_syslog_facility'] = "LOG_LOCAL1";
if (empty($a_nat[$id]['barnyard_syslog_priority']))
$pconfig['barnyard_syslog_priority'] = "LOG_INFO";
if (empty($a_nat[$id]['barnyard_bro_ids_dport']))
$pconfig['barnyard_bro_ids_dport'] = "47760";
if (empty($a_nat[$id]['barnyard_sensor_id']))
$pconfig['barnyard_sensor_id'] = "0";
- if (empty($a_nat[$id]['barnyard_sensor_name']))
- $pconfig['barnyard_sensor_name'] = php_uname("n");
}
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")
$input_errors[] = gettext("You must enable at least one output option when using Barnyard2.");
+ // Validate Sensor Name contains no spaces
+ if ($_POST['barnyard_enable'] == 'on') {
+ if (!empty($_POST['barnyard_sensor_name']) && strpos($_POST['barnyard_sensor_name'], " ") !== FALSE)
+ $input_errors[] = gettext("The value for 'Sensor Name' cannot contain spaces.");
+ }
+
// Validate Sensor ID is a valid integer
if ($_POST['barnyard_enable'] == 'on') {
if (!is_numericint($_POST['barnyard_sensor_id']) || $_POST['barnyard_sensor_id'] < 0)
@@ -160,14 +187,16 @@ if ($_POST['save']) {
if ($_POST['barnyard_syslog_priority']) $natent['barnyard_syslog_priority'] = $_POST['barnyard_syslog_priority']; else $natent['barnyard_syslog_priority'] = 'LOG_INFO';
if ($_POST['barnyard_bro_ids_rhost']) $natent['barnyard_bro_ids_rhost'] = $_POST['barnyard_bro_ids_rhost']; else unset($natent['barnyard_bro_ids_rhost']);
if ($_POST['barnyard_bro_ids_dport']) $natent['barnyard_bro_ids_dport'] = $_POST['barnyard_bro_ids_dport']; else $natent['barnyard_bro_ids_dport'] = '47760';
- if ($_POST['barnconfigpassthru']) $natent['barnconfigpassthru'] = base64_encode($_POST['barnconfigpassthru']); else unset($natent['barnconfigpassthru']);
+ 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
@@ -215,18 +244,22 @@ include_once("head.inc");
<form action="suricata_barnyard.php" method="post" name="iform" id="iform">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.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("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $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">';
@@ -239,12 +272,14 @@ 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>
<tr>
<td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("General Barnyard2 " .
"Settings"); ?></td>
@@ -382,7 +417,7 @@ include_once("head.inc");
<input name="barnyard_syslog_local" type="checkbox" value="on" <?php if ($pconfig['barnyard_syslog_local'] == "on") echo "checked"; ?>
onClick="toggle_local_syslog()"/>
<?php echo gettext("Enable logging of alerts to the local system only"); ?><br/>
- <?php echo gettext("This will send alert data to the local system only and overrides the host, port, protocol, facility and priority values below."); ?></td>
+ <?php echo gettext("This will send alert data to the local system only and overrides the host, port and protocol values below."); ?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Remote Host"); ?></td>
@@ -416,8 +451,8 @@ include_once("head.inc");
<td width="78%" class="vtable">
<select name="barnyard_syslog_facility" id="barnyard_syslog_facility" class="formselect">
<?php
- $log_facility = array( "LOG_AUTH", "LOG_AUTHPRIV", "LOG_DAEMON", "LOG_KERN", "LOG_SYSLOG", "LOG_USER", "LOG_LOCAL1",
- "LOG_LOCAL2", "LOG_LOCAL3", "LOG_LOCAL4", "LOG_LOCAL5", "LOG_LOCAL6", "LOG_LOCAL7" );
+ $log_facility = array( "LOG_AUTH", "LOG_AUTHPRIV", "LOG_DAEMON", "LOG_KERN", "LOG_SYSLOG", "LOG_USER", "LOG_LOCAL0",
+ "LOG_LOCAL1", "LOG_LOCAL2", "LOG_LOCAL3", "LOG_LOCAL4", "LOG_LOCAL5", "LOG_LOCAL6", "LOG_LOCAL7" );
foreach ($log_facility as $facility) {
$selected = "";
if ($facility == $pconfig['barnyard_syslog_facility'])
@@ -425,7 +460,7 @@ include_once("head.inc");
echo "<option value='{$facility}'{$selected}>" . $facility . "</option>\n";
}
?></select>&nbsp;&nbsp;
- <?php echo gettext("Select Syslog Facility to use for remote reporting. Default is ") . "<strong>" . gettext("LOG_USER") . "</strong>."; ?>
+ <?php echo gettext("Select Syslog Facility to use for remote reporting. Default is ") . "<strong>" . gettext("LOG_LOCAL1") . "</strong>."; ?>
</td>
</tr>
<tr>
@@ -433,7 +468,7 @@ include_once("head.inc");
<td width="78%" class="vtable">
<select name="barnyard_syslog_priority" id="barnyard_syslog_priority" class="formselect">
<?php
- $log_priority = array( "LOG_EMERG", "LOG_ALERT", "LOG_CRIT", "LOG_ERR", "LOG_WARNING", "LOG_NOTICE", "LOG_INFO" );
+ $log_priority = array( "LOG_EMERG", "LOG_CRIT", "LOG_ALERT", "LOG_ERR", "LOG_WARNING", "LOG_NOTICE", "LOG_INFO" );
foreach ($log_priority as $priority) {
$selected = "";
if ($priority == $pconfig['barnyard_syslog_priority'])
@@ -498,10 +533,12 @@ include_once("head.inc");
<br/>
<?php echo gettext("Please save your settings before you click start."); ?> </td>
</tr>
+ </tbody>
</table>
</div>
</td>
</tr>
+ </tbody>
</table>
</form>
@@ -549,8 +586,6 @@ function toggle_local_syslog() {
document.iform.barnyard_syslog_dport.disabled = endis;
document.iform.barnyard_syslog_proto_udp.disabled = endis;
document.iform.barnyard_syslog_proto_tcp.disabled = endis;
- document.iform.barnyard_syslog_facility.disabled = endis;
- document.iform.barnyard_syslog_priority.disabled = endis;
}
}
@@ -598,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 96171c1e..4f4bf095 100644
--- a/config/suricata/suricata_blocked.php
+++ b/config/suricata/suricata_blocked.php
@@ -10,6 +10,7 @@
* Copyright (C) 2006 Scott Ullrich
* Copyright (C) 2009 Robert Zelaya Sr. Developer
* Copyright (C) 2012 Ermal Luci
+ * Copyright (C) 2014 Jim Pingle jim@pingle.org
* All rights reserved.
*
* Adapted for Suricata by:
@@ -41,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;
@@ -55,6 +58,21 @@ if (empty($pconfig['blertnumber']))
else
$bnentries = $pconfig['blertnumber'];
+# --- AJAX REVERSE DNS RESOLVE Start ---
+if (isset($_POST['resolve'])) {
+ $ip = strtolower($_POST['resolve']);
+ $res = (is_ipaddr($ip) ? gethostbyaddr($ip) : '');
+
+ if ($res && $res != $ip)
+ $response = array('resolve_ip' => $ip, 'resolve_text' => $res);
+ else
+ $response = array('resolve_ip' => $ip, 'resolve_text' => gettext("Cannot resolve"));
+
+ echo json_encode(str_replace("\\","\\\\", $response)); // single escape chars can break JSON decode
+ exit;
+}
+# --- AJAX REVERSE DNS RESOLVE End ---
+
if ($_POST['todelete']) {
$ip = "";
if ($_POST['ip'])
@@ -78,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: ');
@@ -103,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
@@ -138,8 +156,6 @@ include_once("head.inc");
?>
<body link="#000000" vlink="#000000" alink="#000000">
-<script src="/javascript/filter_log.js" type="text/javascript"></script>
-
<?php
include_once("fbegin.inc");
@@ -161,19 +177,23 @@ if ($savemsg) {
<input type="hidden" name="ip" id="ip" value=""/>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr>
<td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), true, "/suricata/suricata_blocked.php");
+ $tab_array[] = array(gettext("Blocks"), true, "/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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
$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>
@@ -181,6 +201,7 @@ if ($savemsg) {
<tr>
<td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" class="listtopic"><?php echo gettext("Blocked Hosts Log View Settings"); ?></td>
</tr>
@@ -190,7 +211,7 @@ if ($savemsg) {
<input name="download" type="submit" class="formbtns" value="Download" title="<?=gettext("Download list of blocked hosts as a gzip archive");?>"/>
&nbsp;<?php echo gettext("All blocked hosts will be saved."); ?>&nbsp;&nbsp;
<input name="remove" type="submit" class="formbtns" value="Clear" title="<?=gettext("Remove blocks for all listed hosts");?>"
- onClick="return confirm('<?=gettext("Are you sure you want to remove all blocked hosts? Click OK to continue or CANCLE to quit.");?>');"/>&nbsp;
+ onClick="return confirm('<?=gettext("Are you sure you want to remove all blocked hosts? Click OK to continue or CANCEL to quit.");?>');"/>&nbsp;
<span class="red"><strong><?php echo gettext("Warning:"); ?></strong></span>&nbsp;<?php echo gettext("all hosts will be removed."); ?>
</td>
</tr>
@@ -219,11 +240,11 @@ if ($savemsg) {
<col width="10%" align="center">
</colgroup>
<thead>
- <tr>
+ <tr class="sortableHeaderRowIdentifier">
<th class="listhdrr" axis="number">#</th>
<th class="listhdrr" axis="string"><?php echo gettext("IP"); ?></th>
<th class="listhdrr" axis="string"><?php echo gettext("Alert Description"); ?></th>
- <th class="listhdrr"><?php echo gettext("Remove"); ?></th>
+ <th class="listhdrr sorttable_nosort"><?php echo gettext("Remove"); ?></th>
</tr>
</thead>
<tbody>
@@ -239,16 +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)
+
+ /*************** 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));
+ }
+
+ // 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[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);
+ $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);
@@ -274,18 +346,15 @@ if ($savemsg) {
$tmp_ip = str_replace(":", ":&#8203;", $block_ip_str);
/* Add reverse DNS lookup icons */
$rdns_link = "";
- $rdns_link .= "<a onclick=\"javascript:getURL('/diag_dns.php?host={$block_ip_str}&dialog_output=true', outputrule);\">";
- $rdns_link .= "<img src='../themes/{$g['theme']}/images/icons/icon_log_d.gif' width='11' height='11' border='0' ";
- $rdns_link .= "title='" . gettext("Resolve host via reverse DNS lookup (quick pop-up)") . "' style=\"cursor: pointer;\"></a>&nbsp;";
- $rdns_link .= "<a href='/diag_dns.php?host={$block_ip_str}'>";
- $rdns_link .= "<img src='../themes/{$g['theme']}/images/icons/icon_log.gif' width='11' height='11' border='0' ";
- $rdns_link .= "title='" . gettext("Resolve host via reverse DNS lookup") . "'></a>";
+ $rdns_link .= "<img onclick=\"javascript:resolve_with_ajax('{$block_ip_str}');\" title=\"";
+ $rdns_link .= gettext("Resolve host via reverse DNS lookup") . "\" border=\"0\" src=\"/themes/{$g['theme']}/images/icons/icon_log.gif\" alt=\"Icon Reverse Resolve with DNS\" ";
+ $rdns_link.= " style=\"cursor: pointer;\"/>";
/* use one echo to do the magic*/
echo "<tr>
<td align=\"center\" valign=\"middle\" class=\"listr\">{$counter}</td>
<td align=\"center\" valign=\"middle\" class=\"listr\">{$tmp_ip}<br/>{$rdns_link}</td>
<td valign=\"middle\" class=\"listr\">{$blocked_desc}</td>
- <td align=\"center\" valign=\"middle\" class=\"listr\" sorttable_customkey=\"\">
+ <td align=\"center\" valign=\"middle\" class=\"listr\">
<input type=\"image\" name=\"todelete[]\" onClick=\"document.getElementById('ip').value='{$block_ip_str}';\"
src=\"../themes/{$g['theme']}/images/icons/icon_x.gif\" title=\"" . gettext("Delete host from Blocked Table") . "\" border=\"0\" /></td>
</tr>\n";
@@ -310,14 +379,49 @@ if ($savemsg) {
?>
</td>
</tr>
+ </tbody>
</table>
</div>
</td>
</tr>
+</tbody>
</table>
</form>
<?php
include("fend.inc");
?>
+
+<!-- The following AJAX code was borrowed from the diag_logs_filter.php -->
+<!-- file in pfSense. See copyright info at top of this page. -->
+<script type="text/javascript">
+//<![CDATA[
+function resolve_with_ajax(ip_to_resolve) {
+ var url = "/suricata/suricata_blocked.php";
+
+ jQuery.ajax(
+ url,
+ {
+ type: 'post',
+ dataType: 'json',
+ data: {
+ resolve: ip_to_resolve,
+ },
+ complete: resolve_ip_callback
+ });
+}
+
+function resolve_ip_callback(transport) {
+ var response = jQuery.parseJSON(transport.responseText);
+ var msg = 'IP address "' + response.resolve_ip + '" resolves to\n';
+ alert(msg + 'host "' + htmlspecialchars(response.resolve_text) + '"');
+}
+
+// From http://stackoverflow.com/questions/5499078/fastest-method-to-escape-html-tags-as-html-entities
+function htmlspecialchars(str) {
+ return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;');
+}
+//]]>
+</script>
+
</body>
</html>
diff --git a/config/suricata/suricata_check_cron_misc.inc b/config/suricata/suricata_check_cron_misc.inc
index f750c530..eb1ba2d0 100644
--- a/config/suricata/suricata_check_cron_misc.inc
+++ b/config/suricata/suricata_check_cron_misc.inc
@@ -66,13 +66,13 @@ 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
- $logs = array ( "alerts.log", "http.log", "files-json.log", "tls.log", "stats.log" );
+ $logs = array ( "alerts.log", "block.log", "dns.log", "eve.json", "http.log", "files-json.log", "sid_changes.log", "stats.log", "tls.log" );
// Clean-up the logs for each configured Suricata instance
foreach ($config['installedpackages']['suricata']['rule'] as $value) {
@@ -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/*");
@@ -126,8 +134,10 @@ function suricata_check_rotate_log($log_file, $log_limit, $retention) {
// Check the current log to see if it needs rotating.
// If it does, rotate it and put the current time
// on the end of the filename as UNIX timestamp.
+ if (!file_exists($log_file))
+ return;
if (($log_limit > 0) && (filesize($log_file) >= $log_limit)) {
- $newfile = $log_file . "." . strval(time());
+ $newfile = $log_file . "." . date('Y_md_Hi');
try {
copy($log_file, $newfile);
file_put_contents($log_file, "");
@@ -168,10 +178,18 @@ $logs = array ();
// Build an arry of files to check and limits to check them against from our saved configuration
$logs['alerts.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['alert_log_limit_size'];
$logs['alerts.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['alert_log_retention'];
+$logs['block.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['block_log_limit_size'];
+$logs['block.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['block_log_retention'];
+$logs['dns.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['dns_log_limit_size'];
+$logs['dns.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['dns_log_retention'];
+$logs['eve.json']['limit'] = $config['installedpackages']['suricata']['config'][0]['eve_log_limit_size'];
+$logs['eve.json']['retention'] = $config['installedpackages']['suricata']['config'][0]['eve_log_retention'];
$logs['files-json.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['files_json_log_limit_size'];
$logs['files-json.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['files_json_log_retention'];
$logs['http.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['http_log_limit_size'];
$logs['http.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['http_log_retention'];
+$logs['sid_changes.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['sid_changes_log_limit_size'];
+$logs['sid_changes.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['sid_changes_log_retention'];
$logs['stats.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['stats_log_limit_size'];
$logs['stats.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['stats_log_retention'];
$logs['tls.log']['limit'] = $config['installedpackages']['suricata']['config'][0]['tls_log_limit_size'];
@@ -190,24 +208,53 @@ if ($config['installedpackages']['suricata']['config'][0]['enable_log_mgmt'] ==
$config['installedpackages']['suricata']['config'][0]['u2_archive_log_retention'] > 0) {
$now = time();
$files = glob("{$suricata_log_dir}/barnyard2/archive/unified2.alert.*");
+ $prune_count = 0;
foreach ($files as $f) {
- if (($now - filemtime($f)) > ($config['installedpackages']['suricata']['config'][0]['u2_archive_log_retention'] * 3600))
+ if (($now - filemtime($f)) > ($config['installedpackages']['suricata']['config'][0]['u2_archive_log_retention'] * 3600)) {
+ $prune_count++;
unlink_if_exists($f);
+ }
}
+ if ($prune_count > 0)
+ log_error(gettext("[Suricata] Barnyard2 archived logs cleanup job removed {$prune_count} file(s) from {$suricata_log_dir}/barnyard2/archive/..."));
+ unset($files);
}
- unset($files);
// Prune aged-out File Store files if any exist
if (is_dir("{$suricata_log_dir}/files") &&
$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))
+ if (($now - filemtime($f)) > ($config['installedpackages']['suricata']['config'][0]['file_store_retention'] * 3600)) {
+ $prune_count++;
unlink_if_exists($f);
+ }
+ }
+ if ($prune_count > 0)
+ 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);
}
- unset($files);
}
}
diff --git a/config/suricata/suricata_check_for_rule_updates.php b/config/suricata/suricata_check_for_rule_updates.php
index bb29078f..0fa4fb2d 100644
--- a/config/suricata/suricata_check_for_rule_updates.php
+++ b/config/suricata/suricata_check_for_rule_updates.php
@@ -41,41 +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/reg-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("VRT_DNLD_FILENAME"))
- define("VRT_DNLD_FILENAME", "snortrules-snapshot-edge.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;
@@ -86,6 +58,7 @@ else
/* define checks */
$oinkid = $config['installedpackages']['suricata']['config'][0]['oinkcode'];
+$snort_filename = $config['installedpackages']['suricata']['config'][0]['snort_rules_file'];
$etproid = $config['installedpackages']['suricata']['config'][0]['etprocode'];
$snortdownload = $config['installedpackages']['suricata']['config'][0]['enable_vrt_rules'] == 'on' ? 'on' : 'off';
$etpro = $config['installedpackages']['suricata']['config'][0]['enable_etpro_rules'] == 'on' ? 'on' : 'off';
@@ -94,10 +67,9 @@ $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 Edge VRT Rules filenames and URL */
-$snort_filename = VRT_DNLD_FILENAME;
+/* Snort VRT Rules filenames and URL */
$snort_filename_md5 = "{$snort_filename}.md5";
$snort_rule_url = VRT_DNLD_URL;
@@ -107,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") {
@@ -117,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;
@@ -128,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).
@@ -211,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');
@@ -285,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}")) {
@@ -309,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
@@ -318,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} ..."));
@@ -326,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;
}
@@ -354,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);
@@ -362,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
@@ -371,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))){
@@ -380,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;
}
@@ -393,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;
}
@@ -407,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,10 +416,15 @@ if ($emergingthreats == 'on') {
/* Check for and download any new Snort VRT sigs */
if ($snortdownload == 'on') {
- if (suricata_check_rule_md5("{$snort_rule_url}{$snort_filename_md5}/{$oinkid}/", "{$tmpfname}/{$snort_filename_md5}", "Snort VRT rules")) {
+ 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_LOGFILE);
+ $snortdownload = 'off';
+ }
+ elseif (suricata_check_rule_md5("{$snort_rule_url}{$snort_filename_md5}?oinkcode={$oinkid}", "{$tmpfname}/{$snort_filename_md5}", "Snort VRT rules")) {
/* download snortrules file */
$file_md5 = trim(file_get_contents("{$tmpfname}/{$snort_filename_md5}"));
- if (!suricata_fetch_new_rules("{$snort_rule_url}{$snort_filename}/{$oinkid}/", "{$tmpfname}/{$snort_filename}", $file_md5, "Snort VRT rules"))
+ if (!suricata_fetch_new_rules("{$snort_rule_url}{$snort_filename}?oinkcode={$oinkid}", "{$tmpfname}/{$snort_filename}", $file_md5, "Snort VRT rules"))
$snortdownload = 'off';
}
else
@@ -451,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"))
@@ -469,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 */
@@ -483,7 +465,7 @@ if ($emergingthreats == 'on') {
// The code below renames ET files with a prefix, so we
// skip renaming the Suricata default events rule files
// that are also bundled in the ET rules.
- $default_rules = array( "decoder-events.rules", "files.rules", "http-events.rules", "smtp-events.rules", "stream-events.rules", "tls-events.rules" );
+ $default_rules = array( "decoder-events.rules", "dns-events.rules", "files.rules", "http-events.rules", "smtp-events.rules", "stream-events.rules", "tls-events.rules" );
$files = glob("{$tmpfname}/emerging/rules/*.rules");
// Determine the correct prefix to use based on which
// Emerging Threats rules package is enabled.
@@ -527,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");
}
}
@@ -543,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");
@@ -560,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") {
@@ -572,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..."));
@@ -582,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);
}
}
@@ -594,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");
@@ -617,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");
}
}
@@ -640,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 */
@@ -669,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) {
@@ -690,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 {
@@ -698,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 {
@@ -750,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") {
@@ -758,8 +743,11 @@ 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);
-conf_mount_ro();
+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 if we changed it in this module */
+if ($mounted_rw == TRUE)
+ conf_mount_ro();
// Restore the state of $pkg_interface
$pkg_interface = $pkg_interface_orig;
@@ -770,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();
+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 d072ff42..b94292c3 100644
--- a/config/suricata/suricata_define_vars.php
+++ b/config/suricata/suricata_define_vars.php
@@ -64,7 +64,7 @@ $suricata_servers = array (
"dns_servers" => "\$HOME_NET", "smtp_servers" => "\$HOME_NET", "http_servers" => "\$HOME_NET",
"sql_servers" => "\$HOME_NET", "telnet_servers" => "\$HOME_NET", "dnp3_server" => "\$HOME_NET",
"dnp3_client" => "\$HOME_NET", "modbus_server" => "\$HOME_NET", "modbus_client" => "\$HOME_NET",
- "enip_server" => "\$HOME_NET", "enip_client" => "\$HOME_NET",
+ "enip_server" => "\$HOME_NET", "enip_client" => "\$HOME_NET", "ftp_servers" => "\$HOME_NET", "ssh_servers" => "\$HOME_NET",
"aim_servers" => "64.12.24.0/23,64.12.28.0/23,64.12.161.0/24,64.12.163.0/24,64.12.200.0/24,205.188.3.0/24,205.188.5.0/24,205.188.7.0/24,205.188.9.0/24,205.188.153.0/24,205.188.179.0/24,205.188.248.0/24"
);
@@ -74,6 +74,7 @@ if(is_array($config['system']['ssh']) && isset($config['system']['ssh']['port'])
else
$ssh_port = "22";
$suricata_ports = array(
+ "ftp_ports" => "21",
"http_ports" => "80",
"oracle_ports" => "1521",
"ssh_ports" => $ssh_port,
@@ -127,11 +128,16 @@ if ($_POST) {
/* Update the suricata.yaml file for this interface. */
$rebuild_rules = false;
+ conf_mount_rw();
suricata_generate_yaml($a_nat[$id]);
+ conf_mount_ro();
/* Soft-restart Suricaa to live-load new variables. */
suricata_reload_config($a_nat[$id]);
+ /* Sync to configured CARP slaves if any are enabled */
+ suricata_sync_on_changes();
+
/* after click go to this page */
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . ' GMT' );
@@ -166,18 +172,22 @@ if ($savemsg)
</script>
<form action="suricata_define_vars.php" method="post" name="iform" id="iform">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.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("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $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">';
@@ -190,12 +200,14 @@ 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>
<tr>
<td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Define Servers (IP variables)"); ?></td>
</tr>
@@ -254,9 +266,10 @@ if ($savemsg)
<input name="id" type="hidden" value="<?=$id;?>">
</td>
</tr>
+ </tbody>
</table>
</div>
-</td></tr>
+</td></tr></tbody>
</table>
</form>
<script type="text/javascript">
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_rules.php b/config/suricata/suricata_download_rules.php
index 2de286ba..f0fbffeb 100644
--- a/config/suricata/suricata_download_rules.php
+++ b/config/suricata/suricata_download_rules.php
@@ -101,7 +101,7 @@ include("head.inc");
<?php
$suricata_gui_include = true;
-include("/usr/local/www/suricata/suricata_check_for_rule_updates.php");
+include("/usr/local/pkg/suricata/suricata_check_for_rule_updates.php");
/* hide progress bar and lets end this party */
echo "\n<script type=\"text/javascript\">document.progressbar.style.visibility='hidden';\n</script>";
diff --git a/config/suricata/suricata_download_updates.php b/config/suricata/suricata_download_updates.php
index b5377351..1abb32d6 100644
--- a/config/suricata/suricata_download_updates.php
+++ b/config/suricata/suricata_download_updates.php
@@ -44,12 +44,13 @@ 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'];
$etpro = $config['installedpackages']['suricata']['config'][0]['enable_etpro_rules'];
$snortcommunityrules = $config['installedpackages']['suricata']['config'][0]['snortcommunityrules'];
+$snort_rules_file = $config['installedpackages']['suricata']['config'][0]['snort_rules_file'];
/* Get last update information if available */
if (!empty($config['installedpackages']['suricata']['config'][0]['last_rule_upd_time']))
@@ -61,7 +62,6 @@ if (!empty($config['installedpackages']['suricata']['config'][0]['last_rule_upd_
else
$last_rule_upd_status = gettext("Unknown");
-$snort_rules_file = VRT_DNLD_FILENAME;
$snort_community_rules_filename = GPLV2_DNLD_FILENAME;
if ($etpro == "on") {
@@ -82,7 +82,7 @@ else {
$snort_org_sig_chk_local = 'Not Enabled';
$snort_org_sig_date = 'Not Enabled';
}
-if (file_exists("{$suricatadir}{$snort_rules_file}.md5")){
+if ($snortdownload == 'on' && file_exists("{$suricatadir}{$snort_rules_file}.md5")){
$snort_org_sig_chk_local = file_get_contents("{$suricatadir}{$snort_rules_file}.md5");
$snort_org_sig_date = date(DATE_RFC850, filemtime("{$suricatadir}{$snort_rules_file}.md5"));
}
@@ -95,7 +95,7 @@ else {
$emergingt_net_sig_chk_local = 'Not Enabled';
$emergingt_net_sig_date = 'Not Enabled';
}
-if (file_exists("{$suricatadir}{$emergingthreats_filename}.md5")) {
+if (($etpro == "on" || $emergingthreats == "on") && file_exists("{$suricatadir}{$emergingthreats_filename}.md5")) {
$emergingt_net_sig_chk_local = file_get_contents("{$suricatadir}{$emergingthreats_filename}.md5");
$emergingt_net_sig_date = date(DATE_RFC850, filemtime("{$suricatadir}{$emergingthreats_filename}.md5"));
}
@@ -108,7 +108,7 @@ else {
$snort_community_sig_chk_local = 'Not Enabled';
$snort_community_sig_sig_date = 'Not Enabled';
}
-if (file_exists("{$suricatadir}{$snort_community_rules_filename}.md5")) {
+if ($snortcommunityrules == 'on' && file_exists("{$suricatadir}{$snort_community_rules_filename}.md5")) {
$snort_community_sig_chk_local = file_get_contents("{$suricatadir}{$snort_community_rules_filename}.md5");
$snort_community_sig_sig_date = date(DATE_RFC850, filemtime("{$suricatadir}{$snort_community_rules_filename}.md5"));
}
@@ -116,10 +116,10 @@ if (file_exists("{$suricatadir}{$snort_community_rules_filename}.md5")) {
/* 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['check']) {
+if ($_POST['update']) {
// Go see if new updates for rule sets are available
header("Location: /suricata/suricata_download_rules.php");
exit;
@@ -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();
@@ -177,21 +174,25 @@ include_once("head.inc");
print_info_box($savemsg);
}
?>
-<form action="suricata_download_updates.php" method="post" name="iform" id="iform">
+<form action="suricata_download_updates.php" enctype="multipart/form-data" method="post" name="iform" id="iform">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), true, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), true, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php");
$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>
@@ -199,6 +200,7 @@ include_once("head.inc");
<td>
<div id="mainarea">
<table id="maintable4" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
<tr>
<td valign="top" class="listtopic" align="center"><?php echo gettext("INSTALLED RULE SET MD5 SIGNATURE");?></td>
</tr>
@@ -212,6 +214,7 @@ include_once("head.inc");
<th class="listhdrr"><?=gettext("MD5 Signature Date");?></th>
</tr>
</thead>
+ <tbody>
<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>
@@ -227,6 +230,7 @@ include_once("head.inc");
<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>
</tr>
+ </tbody>
</table><br/>
</td>
</tr>
@@ -262,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 all enabled rule sets. Click OK to continue or CANCEL to quit");?>');"/>
@@ -271,7 +275,6 @@ include_once("head.inc");
<?php endif; ?>
</td>
</tr>
-
<tr>
<td valign="top" class="listtopic" align="center"><?php echo gettext("MANAGE RULE SET LOG");?></td>
</tr>
@@ -318,10 +321,12 @@ include_once("head.inc");
gettext(" will go down from time to time. Please be patient."); ?></span><br/>
</td>
</tr>
+ </tbody>
</table>
</div>
</td>
</tr>
+</tbody>
</table>
<!-- end of final table -->
</form>
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 ba594d55..9467ea7c 100644
--- a/config/suricata/suricata_flow_stream.php
+++ b/config/suricata/suricata_flow_stream.php
@@ -251,7 +251,6 @@ elseif ($_POST['ResetAll']) {
$pconfig['flow_icmp_emerg_established_timeout'] = '100';
$pconfig['stream_memcap'] = '33554432';
- $pconfig['stream_max_sessions'] = '262144';
$pconfig['stream_prealloc_sessions'] = '32768';
$pconfig['reassembly_memcap'] = '67108864';
$pconfig['reassembly_depth'] = '1048576';
@@ -261,9 +260,9 @@ elseif ($_POST['ResetAll']) {
$pconfig['enable_async_sessions'] = 'off';
/* Log a message at the top of the page to inform the user */
- $savemsg = gettext("All flow and stream settings have been reset to their defaults.");
+ $savemsg = gettext("All flow and stream settings have been reset to their defaults. Click APPLY to save the changes.");
}
-elseif ($_POST['save']) {
+elseif ($_POST['save'] || $_POST['apply']) {
$natent = array();
$natent = $pconfig;
@@ -300,7 +299,6 @@ elseif ($_POST['save']) {
if ($_POST['flow_icmp_emerg_established_timeout'] != "") { $natent['flow_icmp_emerg_established_timeout'] = $_POST['flow_icmp_emerg_established_timeout']; }else{ $natent['flow_icmp_emerg_established_timeout'] = "100"; }
if ($_POST['stream_memcap'] != "") { $natent['stream_memcap'] = $_POST['stream_memcap']; }else{ $natent['stream_memcap'] = "33554432"; }
- if ($_POST['stream_max_sessions'] != "") { $natent['stream_max_sessions'] = $_POST['stream_max_sessions']; }else{ $natent['stream_max_sessions'] = "262144"; }
if ($_POST['stream_prealloc_sessions'] != "") { $natent['stream_prealloc_sessions'] = $_POST['stream_prealloc_sessions']; }else{ $natent['stream_prealloc_sessions'] = "32768"; }
if ($_POST['enable_midstream_sessions'] == "on") { $natent['enable_midstream_sessions'] = 'on'; }else{ $natent['enable_midstream_sessions'] = 'off'; }
if ($_POST['enable_async_sessions'] == "on") { $natent['enable_async_sessions'] = 'on'; }else{ $natent['enable_async_sessions'] = 'off'; }
@@ -318,7 +316,12 @@ elseif ($_POST['save']) {
$a_nat[$id] = $natent;
write_config();
$rebuild_rules = false;
+ conf_mount_rw();
suricata_generate_yaml($natent);
+ conf_mount_ro();
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
}
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
@@ -431,32 +434,40 @@ include_once("head.inc");
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<?php include("fbegin.inc");
-
- /* Display error or save message */
- if ($input_errors) {
- print_input_errors($input_errors); // TODO: add checks
- }
- if ($savemsg) {
- print_info_box($savemsg);
- }
+/* Display error message */
+if ($input_errors) {
+ print_input_errors($input_errors); // TODO: add checks
+}
?>
<form action="suricata_flow_stream.php" method="post" name="iform" id="iform">
<input type="hidden" name="eng_id" id="eng_id" value="<?=$eng_id;?>"/>
<input type="hidden" name="id" id="id" value="<?=$id;?>"/>
+<?php
+if ($savemsg) {
+ /* Display save message */
+ print_info_box($savemsg);
+}
+?>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $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>';
@@ -469,6 +480,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"), 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>
@@ -489,6 +501,7 @@ include_once("head.inc");
<?php else: ?>
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Host-Specific Defrag and Stream Settings"); ?></td>
</tr>
@@ -511,6 +524,7 @@ include_once("head.inc");
height="17" border="0" title="<?php echo gettext("Add a new policy configuration");?>"/></th>
</tr>
</thead>
+ <tbody>
<?php foreach ($pconfig['host_os_policy']['item'] as $f => $v): ?>
<tr>
<td class="listlr" align="left"><?=gettext($v['name']);?></td>
@@ -529,6 +543,7 @@ include_once("head.inc");
</td>
</tr>
<?php endforeach; ?>
+ </tbody>
</table>
</td>
</tr>
@@ -633,6 +648,7 @@ include_once("head.inc");
<td width="22%" valign="top" class="vncell"><?php echo gettext("TCP Connections"); ?></td>
<td width="78%" class="vtable">
<table width="100%" cellspacing="4" cellpadding="0" border="0">
+ <tbody>
<tr>
<td class="vexpl"><input name="flow_tcp_new_timeout" type="text" class="formfld unknown" id="flow_tcp_new_timeout"
size="9" value="<?=htmlspecialchars($pconfig['flow_tcp_new_timeout']);?>">&nbsp;
@@ -669,6 +685,7 @@ include_once("head.inc");
<?php echo gettext("Emergency Closed TCP connection timeout in seconds. Default is ") . "<strong>" . gettext("20") . "</strong>."; ?>
</td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -676,6 +693,7 @@ include_once("head.inc");
<td width="22%" valign="top" class="vncell"><?php echo gettext("UDP Connections"); ?></td>
<td width="78%" class="vtable">
<table width="100%" cellspacing="4" cellpadding="0" border="0">
+ <tbody>
<tr>
<td class="vexpl"><input name="flow_udp_new_timeout" type="text" class="formfld unknown" id="flow_udp_new_timeout"
size="9" value="<?=htmlspecialchars($pconfig['flow_udp_new_timeout']);?>">&nbsp;
@@ -700,6 +718,7 @@ include_once("head.inc");
<?php echo gettext("Emergency Established UDP connection timeout in seconds. Default is ") . "<strong>" . gettext("100") . "</strong>."; ?>
</td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -707,6 +726,7 @@ include_once("head.inc");
<td width="22%" valign="top" class="vncell"><?php echo gettext("ICMP Connections"); ?></td>
<td width="78%" class="vtable">
<table width="100%" cellspacing="4" cellpadding="0" border="0">
+ <tbody>
<tr>
<td class="vexpl"><input name="flow_icmp_new_timeout" type="text" class="formfld unknown" id="flow_icmp_new_timeout"
size="9" value="<?=htmlspecialchars($pconfig['flow_icmp_new_timeout']);?>">&nbsp;
@@ -731,6 +751,7 @@ include_once("head.inc");
<?php echo gettext("Emergency Established ICMP connection timeout in seconds. Default is ") . "<strong>" . gettext("100") . "</strong>."; ?>
</td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -748,16 +769,6 @@ include_once("head.inc");
</td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncell"><?php echo gettext("Max Sessions"); ?></td>
- <td width="78%" class="vtable">
- <input name="stream_max_sessions" type="text" class="formfld unknown" id="stream_max_sessions" size="9"
- value="<?=htmlspecialchars($pconfig['stream_max_sessions']);?>">&nbsp;
- <?php echo gettext("Max concurrent stream engine sessions. Default is ") .
- "<strong>" . gettext("262,144") . "</strong>" . gettext(" sessions."); ?><br/><br/>
- <?php echo gettext("Sets the maximum number of concurrent sessions to be used by the stream engine."); ?>
- </td>
- </tr>
- <tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Preallocated Sessions"); ?></td>
<td width="78%" class="vtable">
<input name="stream_prealloc_sessions" type="text" class="formfld unknown" id="stream_prealloc_sessions" size="9"
@@ -835,12 +846,13 @@ include_once("head.inc");
<?php echo gettext("Please save your settings before you exit. Changes will rebuild the rules file. This "); ?>
<?php echo gettext("may take several seconds. Suricata must also be restarted to activate any changes made on this screen."); ?></td>
</tr>
+ </tbody>
</table>
<?php endif; ?>
</div>
-</td></tr></table>
+</td></tr></tbody></table>
</form>
<?php include("fend.inc"); ?>
</body>
diff --git a/config/suricata/suricata_generate_yaml.php b/config/suricata/suricata_generate_yaml.php
index bd3ce368..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.
@@ -68,11 +61,17 @@ foreach ($suricata_files as $file) {
$home_net_list = suricata_build_list($suricatacfg, $suricatacfg['homelistname']);
$home_net = implode(",", $home_net_list);
$home_net = trim($home_net);
-$external_net = '!$HOME_NET';
+$external_net = "";
if (!empty($suricatacfg['externallistname']) && $suricatacfg['externallistname'] != 'default') {
- $external_net_list = suricata_build_list($suricatacfg, $suricatacfg['externallistname']);
+ $external_net_list = suricata_build_list($suricatacfg, $suricatacfg['externallistname'], false, true);
$external_net = implode(",", $external_net_list);
- $external_net = trim($external_net);
+ $external_net = "[" . trim($external_net) . "]";
+}
+else {
+ $external_net = "[";
+ foreach ($home_net_list as $ip)
+ $external_net .= "!{$ip},";
+ $external_net = trim($external_net, ', ') . "]";
}
// Set the PASS LIST and write its contents to disk
@@ -85,7 +84,7 @@ $suricata_servers = array (
"dns_servers" => "\$HOME_NET", "smtp_servers" => "\$HOME_NET", "http_servers" => "\$HOME_NET",
"sql_servers" => "\$HOME_NET", "telnet_servers" => "\$HOME_NET", "dnp3_server" => "\$HOME_NET",
"dnp3_client" => "\$HOME_NET", "modbus_server" => "\$HOME_NET", "modbus_client" => "\$HOME_NET",
- "enip_server" => "\$HOME_NET", "enip_client" => "\$HOME_NET",
+ "enip_server" => "\$HOME_NET", "enip_client" => "\$HOME_NET", "ftp_servers" => "\$HOME_NET", "ssh_servers" => "\$HOME_NET",
"aim_servers" => "64.12.24.0/23,64.12.28.0/23,64.12.161.0/24,64.12.163.0/24,64.12.200.0/24,205.188.3.0/24,205.188.5.0/24,205.188.7.0/24,205.188.9.0/24,205.188.153.0/24,205.188.179.0/24,205.188.248.0/24"
);
$addr_vars = "";
@@ -102,6 +101,7 @@ if(is_array($config['system']['ssh']) && isset($config['system']['ssh']['port'])
else
$ssh_port = "22";
$suricata_ports = array(
+ "ftp_ports" => "21",
"http_ports" => "80",
"oracle_ports" => "1521",
"ssh_ports" => $ssh_port,
@@ -158,6 +158,11 @@ if ($suricatacfg['delayed_detect'] == 'on')
else
$delayed_detect = "no";
+if ($suricatacfg['intf_promisc_mode'] == 'on')
+ $intf_promisc_mode = "yes";
+else
+ $intf_promisc_mode = "no";
+
// Add interface-specific blocking settings
if ($suricatacfg['blockoffenders'] == 'on')
$suri_blockoffenders = "yes";
@@ -184,6 +189,26 @@ if ($suricatacfg['alertsystemlog'] == 'on')
else
$alert_syslog = "no";
+if (!empty($suricatacfg['alertsystemlog_facility']))
+ $alert_syslog_facility = $suricatacfg['alertsystemlog_facility'];
+else
+ $alert_syslog_facility = "local5";
+
+if (!empty($suricatacfg['alertsystemlog_priority']))
+ $alert_syslog_priority = $suricatacfg['alertsystemlog_priority'];
+else
+ $alert_syslog_priority = "Info";
+
+if ($suricatacfg['enable_dns_log'] == 'on')
+ $dns_log_enabled = "yes";
+else
+ $dns_log_enabled = "no";
+
+if ($suricatacfg['append_dns_log'] == 'on')
+ $dns_log_append = "yes";
+else
+ $dns_log_append = "no";
+
if ($suricatacfg['enable_stats_log'] == 'on')
$stats_log_enabled = "yes";
else
@@ -209,6 +234,11 @@ if ($suricatacfg['append_http_log'] == 'on')
else
$http_log_append = "no";
+if ($suricatacfg['http_log_extended'] == 'on')
+ $http_log_extended = "yes";
+else
+ $http_log_extended = "no";
+
if ($suricatacfg['enable_tls_log'] == 'on')
$tls_log_enabled = "yes";
else
@@ -277,6 +307,66 @@ if (isset($suricatacfg['barnyard_sensor_id']))
else
$unified2_sensor_id = "0";
+// EVE JSON log output settings
+if ($suricatacfg['enable_eve_log'] == 'on')
+ $enable_eve_log = "yes";
+else
+ $enable_eve_log = "no";
+
+if ($suricatacfg['eve_output_type'] == 'syslog')
+ $eve_output_type = "syslog";
+else
+ $eve_output_type = "file";
+
+if (!empty($suricatacfg['eve_systemlog_facility']))
+ $eve_systemlog_facility = $suricatacfg['eve_systemlog_facility'];
+else
+ $eve_systemlog_facility = "local1";
+
+if (!empty($suricatacfg['eve_systemlog_priority']))
+ $eve_systemlog_priority = $suricatacfg['eve_systemlog_priority'];
+else
+ $eve_systemlog_priority = "info";
+
+// EVE log output included information
+$eve_out_types = "";
+if ($suricatacfg['eve_log_alerts'] == 'on')
+ $eve_out_types .= "\n - alert";
+
+if ($suricatacfg['eve_log_http'] == 'on') {
+ $eve_out_types .= "\n - http:";
+ if ($suricatacfg['http_log_extended'] == 'on')
+ $eve_out_types .= "\n extended: yes";
+ else
+ $eve_out_types .= "\n extended: no";
+}
+
+if ($suricatacfg['eve_log_dns'] == 'on')
+ $eve_out_types .= "\n - dns";
+
+if ($suricatacfg['eve_log_tls'] == 'on') {
+ $eve_out_types .= "\n - tls:";
+ if ($suricatacfg['tls_log_extended'] == 'on')
+ $eve_out_types .= "\n extended: yes";
+ else
+ $eve_out_types .= "\n extended: no";
+}
+
+if ($suricatacfg['eve_log_files'] == 'on') {
+ $eve_out_types .= "\n - files:";
+ if ($suricatacfg['enable_tracked_files_magic'] == 'on')
+ $eve_out_types .= "\n force-magic: yes";
+ else
+ $eve_out_types .= "\n force-magic: no";
+ if ($suricatacfg['enable_tracked_files_md5'] == 'on')
+ $eve_out_types .= "\n force-md5: yes";
+ else
+ $eve_out_types .= "\n force-md5: no";
+}
+
+if ($suricatacfg['eve_log_ssh'] == 'on')
+ $eve_out_types .= "\n - ssh";
+
// Add interface-specific IP defrag settings
if (!empty($suricatacfg['frag_memcap']))
$frag_memcap = $suricatacfg['frag_memcap'];
@@ -406,11 +496,6 @@ if (!empty($suricatacfg['stream_memcap']))
else
$stream_memcap = "33554432";
-if (!empty($suricatacfg['stream_max_sessions']))
- $stream_max_sessions = $suricatacfg['stream_max_sessions'];
-else
- $stream_max_sessions = "262144";
-
if (!empty($suricatacfg['stream_prealloc_sessions']))
$stream_prealloc_sessions = $suricatacfg['stream_prealloc_sessions'];
else
@@ -448,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) {
@@ -488,11 +574,13 @@ 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";
- $http_hosts_default_policy .= " double-decode-path: no\n double-decode-query: no\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 {
foreach ($suricatacfg['libhtp_policy']['item'] as $k => $v) {
@@ -519,6 +607,7 @@ else {
$engine .= " response-body-limit: {$v['response-body-limit']}\n";
$engine .= " double-decode-path: {$v['double-decode-path']}\n";
$engine .= " double-decode-query: {$v['double-decode-query']}\n";
+ $engine .= " uri-include-all: {$v['uri-include-all']}\n";
$http_hosts_policy .= " {$engine}\n";
}
else {
@@ -531,6 +620,7 @@ else {
$http_hosts_default_policy .= " response-body-limit: {$v['response-body-limit']}\n";
$http_hosts_default_policy .= " double-decode-path: {$v['double-decode-path']}\n";
$http_hosts_default_policy .= " double-decode-query: {$v['double-decode-query']}\n";
+ $http_hosts_default_policy .= " uri-include-all: {$v['uri-include-all']}\n";
}
}
// Remove trailing newline
@@ -544,13 +634,108 @@ if (!empty($suricatacfg['asn1_max_frames']))
else
$asn1_max_frames = "256";
+// Configure App-Layer Parsers/Detection
+if (!empty($suricatacfg['tls_parser']))
+ $tls_parser = $suricatacfg['tls_parser'];
+else
+ $tls_parser = "yes";
+if (!empty($suricatacfg['dcerpc_parser']))
+ $dcerpc_parser = $suricatacfg['dcerpc_parser'];
+else
+ $dcerpc_parser = "yes";
+if (!empty($suricatacfg['ftp_parser']))
+ $ftp_parser = $suricatacfg['ftp_parser'];
+else
+ $ftp_parser = "yes";
+if (!empty($suricatacfg['ssh_parser']))
+ $ssh_parser = $suricatacfg['ssh_parser'];
+else
+ $ssh_parser = "yes";
+if (!empty($suricatacfg['smtp_parser']))
+ $smtp_parser = $suricatacfg['smtp_parser'];
+else
+ $smtp_parser = "yes";
+if (!empty($suricatacfg['imap_parser']))
+ $imap_parser = $suricatacfg['imap_parser'];
+else
+ $imap_parser = "detection-only";
+if (!empty($suricatacfg['msn_parser']))
+ $msn_parser = $suricatacfg['msn_parser'];
+else
+ $msn_parser = "detection-only";
+if (!empty($suricatacfg['smb_parser']))
+ $smb_parser = $suricatacfg['smb_parser'];
+else
+ $smb_parser = "yes";
+
+/* DNS Parser */
+if (!empty($suricatacfg['dns_parser_tcp']))
+ $dns_parser_tcp = $suricatacfg['dns_parser_tcp'];
+else
+ $dns_parser_tcp = "yes";
+if (!empty($suricatacfg['dns_parser_udp']))
+ $dns_parser_udp = $suricatacfg['dns_parser_udp'];
+else
+ $dns_parser_udp = "yes";
+if (!empty($suricatacfg['dns_global_memcap']))
+ $dns_global_memcap = $suricatacfg['dns_global_memcap'];
+else
+ $dns_global_memcap = "16777216";
+if (!empty($suricatacfg['dns_state_memcap']))
+ $dns_state_memcap = $suricatacfg['dns_state_memcap'];
+else
+ $dns_state_memcap = "524288";
+if (!empty($suricatacfg['dns_request_flood_limit']))
+ $dns_request_flood_limit = $suricatacfg['dns_request_flood_limit'];
+else
+ $dns_request_flood_limit = "500";
+
+/* HTTP Parser */
+if (!empty($suricatacfg['http_parser']))
+ $http_parser = $suricatacfg['http_parser'];
+else
+ $http_parser = "yes";
+if (!empty($suricatacfg['http_parser_memcap']))
+ $http_parser_memcap = $suricatacfg['http_parser_memcap'];
+else
+ $http_parser_memcap = "67108864";
+
+/* Configure the IP REP section */
+$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)
@@ -563,4 +748,9 @@ if ($config['installedpackages']['suricata']['config'][0]['log_to_systemlog'] ==
else
$suricata_use_syslog = "no";
+if (!empty($config['installedpackages']['suricata']['config'][0]['log_to_systemlog']))
+ $suricata_use_syslog_facility = $config['installedpackages']['suricata']['config'][0]['log_to_systemlog'];
+else
+ $suricata_use_syslog_facility = "local1";
+
?>
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 9c932222..eb657465 100644
--- a/config/suricata/suricata_global.php
+++ b/config/suricata/suricata_global.php
@@ -45,29 +45,46 @@ require_once("/usr/local/pkg/suricata/suricata.inc");
global $g;
$suricatadir = SURICATADIR;
+$pconfig = array();
-$pconfig['enable_vrt_rules'] = $config['installedpackages']['suricata']['config'][0]['enable_vrt_rules'];
-$pconfig['oinkcode'] = $config['installedpackages']['suricata']['config'][0]['oinkcode'];
-$pconfig['etprocode'] = $config['installedpackages']['suricata']['config'][0]['etprocode'];
-$pconfig['enable_etopen_rules'] = $config['installedpackages']['suricata']['config'][0]['enable_etopen_rules'];
-$pconfig['enable_etpro_rules'] = $config['installedpackages']['suricata']['config'][0]['enable_etpro_rules'];
-$pconfig['rm_blocked'] = $config['installedpackages']['suricata']['config'][0]['rm_blocked'];
-$pconfig['autoruleupdate'] = $config['installedpackages']['suricata']['config'][0]['autoruleupdate'];
-$pconfig['autoruleupdatetime'] = $config['installedpackages']['suricata']['config'][0]['autoruleupdatetime'];
-$pconfig['live_swap_updates'] = $config['installedpackages']['suricata']['config'][0]['live_swap_updates'];
-$pconfig['log_to_systemlog'] = $config['installedpackages']['suricata']['config'][0]['log_to_systemlog'];
-$pconfig['forcekeepsettings'] = $config['installedpackages']['suricata']['config'][0]['forcekeepsettings'];
-$pconfig['snortcommunityrules'] = $config['installedpackages']['suricata']['config'][0]['snortcommunityrules'];
+// If doing a postback, used typed values, else load from stored config
+if (!empty($_POST)) {
+ $pconfig = $_POST;
+}
+else {
+ $pconfig['enable_vrt_rules'] = $config['installedpackages']['suricata']['config'][0]['enable_vrt_rules'];
+ $pconfig['oinkcode'] = $config['installedpackages']['suricata']['config'][0]['oinkcode'];
+ $pconfig['etprocode'] = $config['installedpackages']['suricata']['config'][0]['etprocode'];
+ $pconfig['enable_etopen_rules'] = $config['installedpackages']['suricata']['config'][0]['enable_etopen_rules'];
+ $pconfig['enable_etpro_rules'] = $config['installedpackages']['suricata']['config'][0]['enable_etpro_rules'];
+ $pconfig['rm_blocked'] = $config['installedpackages']['suricata']['config'][0]['rm_blocked'];
+ $pconfig['autoruleupdate'] = $config['installedpackages']['suricata']['config'][0]['autoruleupdate'];
+ $pconfig['autoruleupdatetime'] = $config['installedpackages']['suricata']['config'][0]['autoruleupdatetime'];
+ $pconfig['live_swap_updates'] = $config['installedpackages']['suricata']['config'][0]['live_swap_updates'];
+ $pconfig['log_to_systemlog'] = $config['installedpackages']['suricata']['config'][0]['log_to_systemlog'];
+ $pconfig['log_to_systemlog_facility'] = $config['installedpackages']['suricata']['config'][0]['log_to_systemlog_facility'];
+ $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
if (empty($pconfig['autoruleupdatetime']))
$pconfig['autoruleupdatetime'] = '00:30';
+if (empty($pconfig['log_to_systemlog_facility']))
+ $pconfig['log_to_systemlog_facility'] = "local1";
+
if ($_POST['autoruleupdatetime']) {
if (!preg_match('/^([01]?[0-9]|2[0-3]):?([0-5][0-9])$/', $_POST['autoruleupdatetime']))
$input_errors[] = "Invalid Rule Update Start Time! Please supply a value in 24-hour format as 'HH:MM'.";
}
-if ($_POST['suricatadownload'] == "on" && empty($_POST['oinkcode']))
+if ($_POST['enable_vrt_rules'] == "on" && empty($_POST['snort_rules_file']))
+ $input_errors[] = "You must supply a snort rules tarball filename in the box provided in order to enable Snort VRT rules!";
+
+if ($_POST['enable_vrt_rules'] == "on" && empty($_POST['oinkcode']))
$input_errors[] = "You must supply an Oinkmaster code in the box provided in order to enable Snort VRT rules!";
if ($_POST['enable_etpro_rules'] == "on" && empty($_POST['etprocode']))
@@ -81,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
@@ -117,28 +135,42 @@ if (!$input_errors) {
}
}
+ $config['installedpackages']['suricata']['config'][0]['snort_rules_file'] = $_POST['snort_rules_file'];
$config['installedpackages']['suricata']['config'][0]['oinkcode'] = $_POST['oinkcode'];
$config['installedpackages']['suricata']['config'][0]['etprocode'] = $_POST['etprocode'];
$config['installedpackages']['suricata']['config'][0]['rm_blocked'] = $_POST['rm_blocked'];
$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';
$config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] = $_POST['forcekeepsettings'] ? 'on' : 'off';
$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();
+ conf_mount_ro();
/* forces page to reload new settings */
header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' );
@@ -161,9 +193,6 @@ include_once("head.inc");
<?php
include_once("fbegin.inc");
-if($pfsense_stable == 'yes')
- echo '<p class="pgtitle">' . $pgtitle . '</p>';
-
/* Display Alert message, under form tag or no refresh */
if ($input_errors)
print_input_errors($input_errors);
@@ -172,25 +201,30 @@ if ($input_errors)
<form action="suricata_global.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
- $tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
- $tab_array[] = array(gettext("Global Settings"), true, "/suricata/suricata_global.php");
- $tab_array[] = array(gettext("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array = array();
+ $tab_array[] = array(gettext("Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $tab_array[] = array(gettext("Global Settings"), true, "/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");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php");
$tab_array[] = array(gettext("Logs Mgmt"), false, "/suricata/suricata_logs_mgmt.php");
- display_top_tabs($tab_array, true);
+ $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>
<tr>
<td>
<div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+<tbody>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Please Choose The Type Of Rules You Wish To Download");?></td>
</tr>
@@ -198,6 +232,7 @@ if ($input_errors)
<td width="22%" valign="top" class="vncell"><?php echo gettext("Install ") . "<strong>" . gettext("Emerging Threats") . "</strong>" . gettext(" rules");?></td>
<td width="78%" class="vtable">
<table width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<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>
@@ -218,8 +253,10 @@ if ($input_errors)
<td class="vexpl"><?php echo "<span class='red'><strong>" . gettext("Note:") . "</strong></span>" . "&nbsp;" .
gettext("The ETPro rules contain all of the ETOpen rules, so the ETOpen rules are not required and are disabled when the ETPro rules are selected."); ?></td>
</tr>
+ </tbody>
</table>
<table id="etpro_code_tbl" width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2">&nbsp;</td>
</tr>
@@ -232,6 +269,7 @@ if ($input_errors)
value="<?=htmlspecialchars($pconfig['etprocode']);?>"/><br/>
<?php echo gettext("Obtain an ETPro subscription code and paste it here."); ?></td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -239,36 +277,45 @@ if ($input_errors)
<td width="22%" valign="top" class="vncell"><?php echo gettext("Install ") . "<strong>" . gettext("Snort VRT") . "</strong>" . gettext(" rules");?></td>
<td width="78%" class="vtable">
<table width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
<td><input name="enable_vrt_rules" type="checkbox" id="enable_vrt_rules" value="on" onclick="enable_snort_vrt();"
<?php if($pconfig['enable_vrt_rules']=='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>
- <td><a href="https://www.snort.org/signup" target="_blank"><?php echo gettext("Sign Up for a free Registered User Rule Account"); ?> </a><br/>
- <a href="http://www.snort.org/vrt/buy-a-subscription" target="_blank">
+ <td><a href="https://www.snort.org/users/sign_up" target="_blank"><?php echo gettext("Sign Up for a free Registered User Rule Account"); ?> </a><br/>
+ <a href="https://www.snort.org/products" target="_blank">
<?php echo gettext("Sign Up for paid Sourcefire VRT Certified Subscriber Rules"); ?></a></td>
</tr>
+ </tbody>
</table>
<table id="snort_oink_code_tbl" width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
- <td colspan="2">&nbsp;</td>
+ <td colspan="2" valign="top"><b><span class="vexpl"><?php echo gettext("Snort VRT Configuration"); ?></span></b></td>
</tr>
<tr>
- <td colspan="2" valign="top"><b><span class="vexpl"><?php echo gettext("Snort VRT Oinkmaster Configuration"); ?></span></b></td>
+ <td valign="top" align="right"><span class="vexpl"><strong><?php echo gettext("Rules Filename:"); ?></strong></span>&nbsp;</td>
+ <td><input name="snort_rules_file" type="text" class="formfld unknown" id="snort_rules_file" size="52"
+ value="<?=htmlspecialchars($pconfig['snort_rules_file']);?>"/><br/>
+ <?php echo gettext("Enter the rules tarball filename (filename only, do not include the URL.)"); ?>
+ <br/><span class="red"><strong><?php echo gettext("Example: ") . "</strong></span>" . gettext("snortrules-snapshot-2962.tar.gz");?><br/><br/></td>
</tr>
<tr>
- <td valign="top"><span class="vexpl"><strong><?php echo gettext("Code:"); ?></strong></span></td>
+ <td valign="top" align="right"><span class="vexpl"><strong><?php echo gettext("Oinkmaster Code:"); ?></strong></span>&nbsp;</td>
<td><input name="oinkcode" type="text" class="formfld unknown" id="oinkcode" size="52"
value="<?=htmlspecialchars($pconfig['oinkcode']);?>"/><br/>
<?php echo gettext("Obtain a snort.org Oinkmaster code and paste it here."); ?></td>
</tr>
+ </tbody>
</table>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Install ") . "<strong>" . gettext("Snort Community") . "</strong>" . gettext(" rules");?></td>
<td width="78%" class="vtable">
<table width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
<td valign="top" width="8%"><input name="snortcommunityrules" type="checkbox" value="on"
<?php if ($config['installedpackages']['suricata']['config'][0]['snortcommunityrules']=="on") echo " checked";?>/></td>
@@ -278,6 +325,7 @@ if ($input_errors)
gettext("If you are a Snort VRT Paid Subscriber, the community ruleset is already built into your download of the ") .
gettext("Snort VRT rules, and there is no benefit in adding this rule set.");?><br/></td>
</tr>
+ </tbody>
</table></td>
</tr>
<tr>
@@ -315,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>
@@ -334,10 +391,29 @@ if ($input_errors)
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Log to System Log"); ?></td>
- <td width="78%" class="vtable"><input name="log_to_systemlog" id="log_to_systemlog" type="checkbox" value="yes"
+ <td width="78%" class="vtable"><input name="log_to_systemlog" id="log_to_systemlog" type="checkbox" value="yes" onclick="toggle_log_to_systemlog();"
<?php if ($config['installedpackages']['suricata']['config'][0]['log_to_systemlog']=="on") echo " checked"; ?>/>&nbsp;
<?php echo gettext("Copy Suricata messages to the firewall system log."); ?></td>
</tr>
+ <tbody id="log_to_systemlog_rows">
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Log Facility"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="log_to_systemlog_facility" id="log_to_systemlog_facility" class="formselect">
+ <?php
+ $log_facility = array( "auth", "authpriv", "daemon", "kern", "security", "syslog", "user", "local0",
+ "local1", "local2", "local3", "local4", "local5", "local6", "local7" );
+ foreach ($log_facility as $facility) {
+ $selected = "";
+ if ($facility == $pconfig['log_to_systemlog_facility'])
+ $selected = " selected";
+ echo "<option value='{$facility}'{$selected}>" . $facility . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Select system log facility to use for reporting. Default is ") . "<strong>" . gettext("local1") . "</strong>."; ?>
+ </td>
+ </tr>
+ </tbody>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Keep Suricata Settings After Deinstall"); ?></td>
<td width="78%" class="vtable"><input name="forcekeepsettings" id="forcekeepsettings" type="checkbox" value="yes"
@@ -351,9 +427,10 @@ if ($input_errors)
<td colspan="2" class="vexpl" align="center"><span class="red"><strong><?php echo gettext("Note:");?></strong>&nbsp;
</span><?php echo gettext("Changing any settings on this page will affect all Suricata-configured interfaces.");?></td>
</tr>
+</tbody>
</table>
</div><br/>
-</td></tr>
+</td></tr></tbody>
</table>
</form>
<?php include("fend.inc"); ?>
@@ -396,11 +473,20 @@ function enable_change_rules_upd() {
document.iform.autoruleupdatetime.disabled="";
}
+function toggle_log_to_systemlog() {
+ var endis = !document.iform.log_to_systemlog.checked;
+ if (endis)
+ document.getElementById("log_to_systemlog_rows").style.display="none";
+ else
+ document.getElementById("log_to_systemlog_rows").style.display="";
+}
+
// Initialize the form controls state based on saved settings
enable_snort_vrt();
enable_et_rules();
enable_pro_rules();
enable_change_rules_upd();
+toggle_log_to_systemlog();
//-->
</script>
diff --git a/config/suricata/suricata_import_aliases.php b/config/suricata/suricata_import_aliases.php
index ccaaf29d..e2fa4f40 100644
--- a/config/suricata/suricata_import_aliases.php
+++ b/config/suricata/suricata_import_aliases.php
@@ -79,8 +79,8 @@
<col width="35%" align="left" axis="string">
</colgroup>
<thead>
- <tr>
- <th class="listhdrr"></th>
+ <tr class="sortableHeaderRowIdentifier">
+ <th class="listhdrr sorttable_nosort"></th>
<th class="listhdrr" axis="string"><?=gettext("Alias Name"); ?></th>
<th class="listhdrr" axis="string"><?=gettext("Values"); ?></th>
<th class="listhdrr" axis="string"><?=gettext("Description"); ?></th>
diff --git a/config/suricata/suricata_interfaces.php b/config/suricata/suricata_interfaces.php
index 26d57b71..e996a24f 100644
--- a/config/suricata/suricata_interfaces.php
+++ b/config/suricata/suricata_interfaces.php
@@ -57,6 +57,9 @@ if (!is_array($config['installedpackages']['suricata']['rule']))
$a_nat = &$config['installedpackages']['suricata']['rule'];
$id_gen = count($config['installedpackages']['suricata']['rule']);
+// Get list of configured firewall interfaces
+$ifaces = get_configured_interface_list();
+
if ($_POST['del_x']) {
/* delete selected interfaces */
if (is_array($_POST['rule'])) {
@@ -65,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();
@@ -75,19 +78,12 @@ if ($_POST['del_x']) {
if (empty($a_nat))
unset($a_nat);
- write_config();
+ 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' );
@@ -107,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']})...");
@@ -132,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);
}
@@ -166,19 +166,23 @@ include_once("head.inc");
?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr>
<td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), true, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php");
$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>
@@ -187,7 +191,6 @@ include_once("head.inc");
<td>
<div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
-
<colgroup>
<col width="3%" align="center">
<col width="12%">
@@ -207,12 +210,26 @@ include_once("head.inc");
<th class="listhdrr"><?php echo gettext("Block"); ?></th>
<th class="listhdrr"><?php echo gettext("Barnyard2"); ?></th>
<th class="listhdr"><?php echo gettext("Description"); ?></th>
- <th class="list"><a href="suricata_interfaces_edit.php?id=<?php echo $id_gen;?>">
- <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif"
- width="17" height="17" border="0" title="<?php echo gettext('Add Suricata interface mapping');?>"></a>
+ <th class="list">
+ <?php if ($id_gen < count($ifaces)): ?>
+ <a href="suricata_interfaces_edit.php?id=<?php echo $id_gen;?>">
+ <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif"
+ width="17" height="17" border="0" title="<?php echo gettext('Add Suricata interface mapping');?>"></a>
+ <?php else: ?>
+ <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus_d.gif" width="17" height="17" border="0"
+ title="<?php echo gettext('No available interfaces for a new Suricata mapping');?>">
+ <?php endif; ?>
+ <?php if ($id_gen == 0): ?>
+ <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" width="17" height="17" " border="0">
+ <?php else: ?>
+ <input name="del" type="image" src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif"
+ width="17" height="17" title="<?php echo gettext("Delete selected Suricata interface mapping(s)"); ?>"
+ onclick="return intf_del()">
+ <?php endif; ?>
</th>
</tr>
</thead>
+ <tbody>
<?php $nnats = $i = 0;
// Turn on buffering to speed up rendering
@@ -342,7 +359,15 @@ include_once("head.inc");
<td valign="middle" class="list" nowrap>
<a href="suricata_interfaces_edit.php?id=<?=$i;?>">
<img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif"
- width="17" height="17" border="0" title="<?php echo gettext('Edit Suricata interface mapping'); ?>"></a>
+ width="17" height="17" border="0" title="<?php echo gettext('Edit this Suricata interface mapping'); ?>"></a>
+ <?php if ($id_gen < count($ifaces)): ?>
+ <a href="suricata_interfaces_edit.php?id=<?=$i;?>&action=dup">
+ <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif"
+ width="17" height="17" border="0" title="<?php echo gettext('Add new interface mapping based on this one'); ?>"></a>
+ <?php else: ?>
+ <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus_d.gif" width="17" height="17" border="0"
+ title="<?php echo gettext('No available interfaces for a new Suricata mapping');?>">
+ <?php endif; ?>
</td>
</tr>
<?php $i++; $nnats++; endforeach; ob_end_flush(); ?>
@@ -354,8 +379,16 @@ include_once("head.inc");
<?php else: ?>&nbsp;
<?php endif; ?>
</td>
- <td class="list" valign="middle" nowrap>
- <?php if ($nnats == 0): ?>
+ <td class="list">
+ <?php if ($id_gen < count($ifaces)): ?>
+ <a href="suricata_interfaces_edit.php?id=<?php echo $id_gen;?>">
+ <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif"
+ width="17" height="17" border="0" title="<?php echo gettext('Add Suricata interface mapping');?>"></a>
+ <?php else: ?>
+ <img src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus_d.gif" width="17" height="17" border="0"
+ title="<?php echo gettext('No available interfaces for a new Suricata mapping');?>">
+ <?php endif; ?>
+ <?php if ($id_gen == 0): ?>
<img src="../themes/<?= $g['theme']; ?>/images/icons/icon_x_d.gif" width="17" height="17" " border="0">
<?php else: ?>
<input name="del" type="image" src="../themes/<?= $g['theme']; ?>/images/icons/icon_x.gif"
@@ -371,6 +404,7 @@ include_once("head.inc");
<td>&nbsp;</td>
<td colspan="6">
<table class="tabcont" width="100%" border="0" cellpadding="1" cellspacing="0">
+ <tbody>
<tr>
<td colspan="3" class="vexpl"><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span> <br>
<?php echo gettext("This is the ") . "<strong>" . gettext("Suricata Menu ") .
@@ -423,14 +457,17 @@ include_once("head.inc");
delete an interface and settings.
</td>
</tr>
+ </tbody>
</table>
</td>
<td>&nbsp;</td>
</tr>
+ </tbody>
</table>
</div>
</td>
</tr>
+</tbody>
</table>
</form>
diff --git a/config/suricata/suricata_interfaces_edit.php b/config/suricata/suricata_interfaces_edit.php
index 3b61755c..13526031 100644
--- a/config/suricata/suricata_interfaces_edit.php
+++ b/config/suricata/suricata_interfaces_edit.php
@@ -59,12 +59,21 @@ if (isset($_POST['id']) && is_numericint($_POST['id']))
elseif (isset($_GET['id']) && is_numericint($_GET['id']));
$id = htmlspecialchars($_GET['id'], ENT_QUOTES | ENT_HTML401);
-if (is_null($id))
- $id = 0;
+if (is_null($id)) {
+ header("Location: /suricata/suricata_interfaces.php");
+ exit;
+}
+
+if (isset($_POST['action']))
+ $action = htmlspecialchars($_POST['action'], ENT_QUOTES | ENT_HTML401);
+elseif (isset($_GET['action']))
+ $action = htmlspecialchars($_GET['action'], ENT_QUOTES | ENT_HTML401);
+else
+ $action = "";
$pconfig = array();
if (empty($suricataglob['rule'][$id]['uuid'])) {
- /* Adding new interface, so flag rules to build. */
+ /* Adding new interface, so generate a new UUID and flag rules to build. */
$pconfig['uuid'] = suricata_generate_id();
$rebuild_rules = true;
}
@@ -80,14 +89,15 @@ $interfaces = get_configured_interface_with_descr();
// See if interface is already configured, and use its values
if (isset($id) && $a_rule[$id]) {
+ /* old options */
$pconfig = $a_rule[$id];
if (!empty($pconfig['configpassthru']))
$pconfig['configpassthru'] = base64_decode($pconfig['configpassthru']);
if (empty($pconfig['uuid']))
$pconfig['uuid'] = $suricata_uuid;
}
+// Must be a new interface, so try to pick next available physical interface to use
elseif (isset($id) && !isset($a_rule[$id])) {
- // Must be a new interface, so try to pick next available physical interface to use
$ifaces = get_configured_interface_list();
$ifrules = array();
foreach($a_rule as $r)
@@ -123,55 +133,109 @@ if (empty($pconfig['enable_http_log']))
$pconfig['enable_http_log'] = "on";
if (empty($pconfig['append_http_log']))
$pconfig['append_http_log'] = "on";
-if (empty($pconfig['enable_tls_log']))
- $pconfig['enable_tls_log'] = "off";
+if (empty($pconfig['http_log_extended']))
+ $pconfig['http_log_extended'] = "on";
if (empty($pconfig['tls_log_extended']))
$pconfig['tls_log_extended'] = "on";
-if (empty($pconfig['enable_stats_log']))
- $pconfig['enable_stats_log'] = "off";
if (empty($pconfig['stats_upd_interval']))
$pconfig['stats_upd_interval'] = "10";
-if (empty($pconfig['append_stats_log']))
- $pconfig['append_stats_log'] = "off";
+if (empty($pconfig['append_dns_log']))
+ $pconfig['append_dns_log'] = "on";
if (empty($pconfig['append_json_file_log']))
$pconfig['append_json_file_log'] = "on";
-if (empty($pconfig['enable_pcap_log']))
- $pconfig['enable_pcap_log'] = "off";
if (empty($pconfig['max_pcap_log_size']))
$pconfig['max_pcap_log_size'] = "32";
if (empty($pconfig['max_pcap_log_files']))
$pconfig['max_pcap_log_files'] = "1000";
+if (empty($pconfig['alertsystemlog_facility']))
+ $pconfig['alertsystemlog_facility'] = "local1";
+if (empty($pconfig['alertsystemlog_priority']))
+ $pconfig['alertsystemlog_priority'] = "notice";
+if (empty($pconfig['eve_output_type']))
+ $pconfig['eve_output_type'] = "file";
+if (empty($pconfig['eve_systemlog_facility']))
+ $pconfig['eve_systemlog_facility'] = "local1";
+if (empty($pconfig['eve_systemlog_priority']))
+ $pconfig['eve_systemlog_priority'] = "notice";
+if (empty($pconfig['eve_log_alerts']))
+ $pconfig['eve_log_alerts'] = "on";
+if (empty($pconfig['eve_log_http']))
+ $pconfig['eve_log_http'] = "on";
+if (empty($pconfig['eve_log_dns']))
+ $pconfig['eve_log_dns'] = "on";
+if (empty($pconfig['eve_log_tls']))
+ $pconfig['eve_log_tls'] = "on";
+if (empty($pconfig['eve_log_files']))
+ $pconfig['eve_log_files'] = "on";
+if (empty($pconfig['eve_log_ssh']))
+ $pconfig['eve_log_ssh'] = "on";
+if (empty($pconfig['intf_promisc_mode']))
+ $pconfig['intf_promisc_mode'] = "on";
-if ($_POST["save"]) {
- // If the interface is not enabled, stop any running Suricata
- // instance on it, save the new state and exit.
- if (!isset($_POST['enable'])) {
- if (isset($id) && $a_rule[$id]) {
- $a_rule[$id]['enable'] = 'off';
- $a_rule[$id]['interface'] = htmlspecialchars($_POST['interface']);
- $a_rule[$id]['descr'] = htmlspecialchars($_POST['descr']);
- suricata_stop($a_rule[$id], get_real_interface($a_rule[$id]['interface']));
-
- // Save configuration changes
- write_config();
-
- // Update suricata.conf and suricata.sh files for this interface
- sync_suricata_package_config();
-
- 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_interfaces.php");
- exit;
+// See if creating a new interface by duplicating an existing one
+if (strcasecmp($action, 'dup') == 0) {
+
+ // Try to pick the next available physical interface to use
+ $ifaces = get_configured_interface_list();
+ $ifrules = array();
+ foreach($a_rule as $r)
+ $ifrules[] = $r['interface'];
+ foreach ($ifaces as $i) {
+ if (!in_array($i, $ifrules)) {
+ $pconfig['interface'] = $i;
+ $pconfig['enable'] = 'on';
+ $pconfig['descr'] = strtoupper($i);
+ $pconfig['inspect_recursion_limit'] = '3000';
+ break;
}
}
+ if (count($ifrules) == count($ifaces)) {
+ $input_errors[] = gettext("No more available interfaces to configure for Suricata!");
+ $interfaces = array();
+ $pconfig = array();
+ }
- // Validate inputs
+ // Set Home Net, External Net, Suppress List and Pass List to defaults
+ unset($pconfig['suppresslistname']);
+ unset($pconfig['passlistname']);
+ unset($pconfig['homelistname']);
+ unset($pconfig['externallistname']);
+}
+
+if ($_POST["save"] && !$input_errors) {
if (!isset($_POST['interface']))
$input_errors[] = gettext("Choosing an Interface is mandatory!");
+ /* See if assigned interface is already in use */
+ if (isset($_POST['interface'])) {
+ foreach ($a_rule as $k => $v) {
+ if (($v['interface'] == $_POST['interface']) && ($id <> $k)) {
+ $input_errors[] = gettext("The '{$_POST['interface']}' interface is already assigned to another Suricata instance.");
+ break;
+ }
+ }
+ }
+
+ // If Suricata is disabled on this interface, stop any running instance,
+ // save the change and exit.
+ if ($_POST['enable'] != 'on') {
+ $a_rule[$id]['enable'] = $_POST['enable'] ? 'on' : 'off';
+ 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' );
+ header( 'Cache-Control: post-check=0, pre-check=0', false );
+ header( 'Pragma: no-cache' );
+ header("Location: /suricata/suricata_interfaces.php");
+ exit;
+ }
+
+ // Validate inputs
if (isset($_POST['stats_upd_interval']) && !is_numericint($_POST['stats_upd_interval']))
$input_errors[] = gettext("The value for Stats Update Interval must contain only digits and evaluate to an integer.");
@@ -187,16 +251,6 @@ if ($_POST["save"]) {
if (!empty($_POST['inspect_recursion_limit']) && !is_numeric($_POST['inspect_recursion_limit']))
$input_errors[] = gettext("The value for Inspect Recursion Limit can either be blank or contain only digits evaluating to an integer greater than or equal to 0.");
- /* See if assigned interface is already in use */
- if (isset($_POST['interface'])) {
- foreach ($a_rule as $k => $v) {
- if (($v['interface'] == $_POST['interface']) && ($id <> $k)) {
- $input_errors[] = gettext("The '{$_POST['interface']}' interface is already assigned to another Suricata instance.");
- break;
- }
- }
- }
-
// if no errors write to suricata.yaml
if (!$input_errors) {
$natent = $a_rule[$id];
@@ -213,6 +267,7 @@ if ($_POST["save"]) {
if ($_POST['enable_http_log'] == "on") { $natent['enable_http_log'] = 'on'; }else{ $natent['enable_http_log'] = 'off'; }
if ($_POST['append_http_log'] == "on") { $natent['append_http_log'] = 'on'; }else{ $natent['append_http_log'] = 'off'; }
if ($_POST['enable_tls_log'] == "on") { $natent['enable_tls_log'] = 'on'; }else{ $natent['enable_tls_log'] = 'off'; }
+ if ($_POST['http_log_extended'] == "on") { $natent['http_log_extended'] = 'on'; }else{ $natent['http_log_extended'] = 'off'; }
if ($_POST['tls_log_extended'] == "on") { $natent['tls_log_extended'] = 'on'; }else{ $natent['tls_log_extended'] = 'off'; }
if ($_POST['enable_pcap_log'] == "on") { $natent['enable_pcap_log'] = 'on'; }else{ $natent['enable_pcap_log'] = 'off'; }
if ($_POST['enable_json_file_log'] == "on") { $natent['enable_json_file_log'] = 'on'; }else{ $natent['enable_json_file_log'] = 'off'; }
@@ -220,6 +275,7 @@ if ($_POST["save"]) {
if ($_POST['enable_tracked_files_magic'] == "on") { $natent['enable_tracked_files_magic'] = 'on'; }else{ $natent['enable_tracked_files_magic'] = 'off'; }
if ($_POST['enable_tracked_files_md5'] == "on") { $natent['enable_tracked_files_md5'] = 'on'; }else{ $natent['enable_tracked_files_md5'] = 'off'; }
if ($_POST['enable_file_store'] == "on") { $natent['enable_file_store'] = 'on'; }else{ $natent['enable_file_store'] = 'off'; }
+ if ($_POST['enable_eve_log'] == "on") { $natent['enable_eve_log'] = 'on'; }else{ $natent['enable_eve_log'] = 'off'; }
if ($_POST['max_pending_packets']) $natent['max_pending_packets'] = $_POST['max_pending_packets']; else unset($natent['max_pending_packets']);
if ($_POST['inspect_recursion_limit'] >= '0') $natent['inspect_recursion_limit'] = $_POST['inspect_recursion_limit']; else unset($natent['inspect_recursion_limit']);
if ($_POST['detect_eng_profile']) $natent['detect_eng_profile'] = $_POST['detect_eng_profile']; else unset($natent['detect_eng_profile']);
@@ -233,11 +289,26 @@ if ($_POST["save"]) {
if ($_POST['externallistname']) $natent['externallistname'] = $_POST['externallistname']; else unset($natent['externallistname']);
if ($_POST['suppresslistname']) $natent['suppresslistname'] = $_POST['suppresslistname']; else unset($natent['suppresslistname']);
if ($_POST['alertsystemlog'] == "on") { $natent['alertsystemlog'] = 'on'; }else{ $natent['alertsystemlog'] = 'off'; }
+ if ($_POST['alertsystemlog_facility']) $natent['alertsystemlog_facility'] = $_POST['alertsystemlog_facility'];
+ if ($_POST['alertsystemlog_priority']) $natent['alertsystemlog_priority'] = $_POST['alertsystemlog_priority'];
+ if ($_POST['enable_dns_log'] == "on") { $natent['enable_dns_log'] = 'on'; }else{ $natent['enable_dns_log'] = 'off'; }
+ if ($_POST['append_dns_log'] == "on") { $natent['append_dns_log'] = 'on'; }else{ $natent['append_dns_log'] = 'off'; }
+ if ($_POST['enable_eve_log'] == "on") { $natent['enable_eve_log'] = 'on'; }else{ $natent['enable_eve_log'] = 'off'; }
+ if ($_POST['eve_output_type']) $natent['eve_output_type'] = $_POST['eve_output_type'];
+ if ($_POST['eve_systemlog_facility']) $natent['eve_systemlog_facility'] = $_POST['eve_systemlog_facility'];
+ if ($_POST['eve_systemlog_priority']) $natent['eve_systemlog_priority'] = $_POST['eve_systemlog_priority'];
+ if ($_POST['eve_log_alerts'] == "on") { $natent['eve_log_alerts'] = 'on'; }else{ $natent['eve_log_alerts'] = 'off'; }
+ if ($_POST['eve_log_http'] == "on") { $natent['eve_log_http'] = 'on'; }else{ $natent['eve_log_http'] = 'off'; }
+ if ($_POST['eve_log_dns'] == "on") { $natent['eve_log_dns'] = 'on'; }else{ $natent['eve_log_dns'] = 'off'; }
+ if ($_POST['eve_log_tls'] == "on") { $natent['eve_log_tls'] = 'on'; }else{ $natent['eve_log_tls'] = 'off'; }
+ if ($_POST['eve_log_files'] == "on") { $natent['eve_log_files'] = 'on'; }else{ $natent['eve_log_files'] = 'off'; }
+ if ($_POST['eve_log_ssh'] == "on") { $natent['eve_log_ssh'] = 'on'; }else{ $natent['eve_log_ssh'] = 'off'; }
if ($_POST['delayed_detect'] == "on") { $natent['delayed_detect'] = 'on'; }else{ $natent['delayed_detect'] = 'off'; }
- if ($_POST['configpassthru']) $natent['configpassthru'] = base64_encode($_POST['configpassthru']); else unset($natent['configpassthru']);
+ if ($_POST['intf_promisc_mode'] == "on") { $natent['intf_promisc_mode'] = 'on'; }else{ $natent['intf_promisc_mode'] = 'off'; }
+ if ($_POST['configpassthru']) $natent['configpassthru'] = base64_encode(str_replace("\r\n", "\n", $_POST['configpassthru'])); else unset($natent['configpassthru']);
$if_real = get_real_interface($natent['interface']);
- if (isset($id) && $a_rule[$id]) {
+ if (isset($id) && $a_rule[$id] && $action == '') {
// See if moving an existing Suricata instance to another physical interface
if ($natent['interface'] != $a_rule[$id]['interface']) {
$oif_real = get_real_interface($a_rule[$id]['interface']);
@@ -247,13 +318,24 @@ if ($_POST["save"]) {
}
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;
- } else {
+ }
+ elseif (strcasecmp($action, 'dup') == 0) {
+ // Duplicating an existing interface to a new interface, so set flag to build new rules
+ $rebuild_rules = true;
+
+ // Duplicating an interface, so need to generate a new UUID for the cloned interface
+ $natent['uuid'] = suricata_generate_id();
+
+ // Add the new duplicated interface configuration to the [rule] array in config
+ $a_rule[] = $natent;
+ }
+ else {
// Adding new interface, so set interface configuration parameter defaults
$natent['ip_max_frags'] = "65535";
$natent['ip_frag_timeout'] = "60";
@@ -285,7 +367,6 @@ if ($_POST["save"]) {
$natent['flow_icmp_emerg_established_timeout'] = '100';
$natent['stream_memcap'] = '33554432';
- $natent['stream_max_sessions'] = '262144';
$natent['stream_prealloc_sessions'] = '32768';
$natent['reassembly_memcap'] = '67108864';
$natent['reassembly_depth'] = '1048576';
@@ -294,8 +375,29 @@ if ($_POST["save"]) {
$natent['enable_midstream_sessions'] = 'off';
$natent['enable_async_sessions'] = 'off';
$natent['delayed_detect'] = 'off';
+ $natent['intf_promisc_mode'] = 'on';
$natent['asn1_max_frames'] = '256';
+ $natent['dns_global_memcap'] = "16777216";
+ $natent['dns_state_memcap'] = "524288";
+ $natent['dns_request_flood_limit'] = "500";
+ $natent['http_parser_memcap'] = "67108864";
+ $natent['dns_parser_udp'] = "yes";
+ $natent['dns_parser_tcp'] = "yes";
+ $natent['http_parser'] = "yes";
+ $natent['tls_parser'] = "yes";
+ $natent['smtp_parser'] = "yes";
+ $natent['imap_parser'] = "detection-only";
+ $natent['ssh_parser'] = "yes";
+ $natent['ftp_parser'] = "yes";
+ $natent['dcerpc_parser'] = "yes";
+ $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']))
@@ -304,13 +406,14 @@ if ($_POST["save"]) {
$default = array( "name" => "default", "bind_to" => "all", "personality" => "IDS",
"request-body-limit" => 4096, "response-body-limit" => 4096,
- "double-decode-path" => "no", "double-decode-query" => "no" );
+ "double-decode-path" => "no", "double-decode-query" => "no",
+ "uri-include-all" => "no" );
if (!is_array($natent['libhtp_policy']['item']))
$natent['libhtp_policy']['item'] = array();
$natent['libhtp_policy']['item'][] = $default;
// Enable the basic default rules for the interface
- $natent['rulesets'] = "decoder-events.rules||files.rules||http-events.rules||smtp-events.rules||stream-events.rules||tls-events.rules";
+ $natent['rulesets'] = "decoder-events.rules||dns-events.rules||files.rules||http-events.rules||smtp-events.rules||stream-events.rules||tls-events.rules";
// Adding a new interface, so set flag to build new rules
$rebuild_rules = true;
@@ -324,10 +427,12 @@ if ($_POST["save"]) {
suricata_stop($natent, $if_real);
// Save configuration changes
- write_config();
+ 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' );
@@ -358,19 +463,26 @@ if ($savemsg) {
?>
<form action="suricata_interfaces_edit.php<?php echo "?id=$id";?>" method="post" name="iform" id="iform">
+<input name="id" type="hidden" value="<?=$id;?>"/>
+<input name="action" type="hidden" value="<?=$action;?>"/>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.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("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $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">';
@@ -383,11 +495,13 @@ 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>
<tr><td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" class="listtopic"><?php echo gettext("General Settings"); ?></td>
</tr>
@@ -423,9 +537,57 @@ if ($savemsg) {
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Send Alerts to System Log"); ?></td>
- <td width="78%" class="vtable"><input name="alertsystemlog" type="checkbox" value="on" <?php if ($pconfig['alertsystemlog'] == "on") echo "checked"; ?>/>
- <?php echo gettext("Suricata will send Alerts to the firewall's system log."); ?></td>
+ <td width="78%" class="vtable"><input name="alertsystemlog" type="checkbox" value="on" onclick="toggle_system_log();" <?php if ($pconfig['alertsystemlog'] == "on") echo "checked"; ?>/>
+ <?php echo gettext("Suricata will send Alerts from this interface to the firewall's system log."); ?></td>
</tr>
+ <tbody id="alertsystemlog_rows">
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Log Facility"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="alertsystemlog_facility" id="alertsystemlog_facility" class="formselect">
+ <?php
+ $log_facility = array( "auth", "authpriv", "daemon", "kern", "security", "syslog", "user", "local0",
+ "local1", "local2", "local3", "local4", "local5", "local6", "local7" );
+ foreach ($log_facility as $facility) {
+ $selected = "";
+ if ($facility == $pconfig['alertsystemlog_facility'])
+ $selected = " selected";
+ echo "<option value='{$facility}'{$selected}>" . $facility . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Select system log Facility to use for reporting. Default is ") . "<strong>" . gettext("local1") . "</strong>."; ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Log Priority"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="alertsystemlog_priority" id="alertsystemlog_priority" class="formselect">
+ <?php
+ $log_priority = array( "emerg", "crit", "alert", "err", "warning", "notice", "info" );
+ foreach ($log_priority as $priority) {
+ $selected = "";
+ if ($priority == $pconfig['alertsystemlog_priority'])
+ $selected = " selected";
+ echo "<option value='{$priority}'{$selected}>" . $priority . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Select system log Priority (Level) to use for reporting. Default is ") . "<strong>" . gettext("notice") . "</strong>."; ?>
+ </td>
+ </tr>
+ </tbody>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable DNS Log"); ?></td>
+ <td width="78%" class="vtable"><input name="enable_dns_log" type="checkbox" value="on" <?php if ($pconfig['enable_dns_log'] == "on") echo "checked"; ?>
+ onClick="toggle_dns_log();" id="enable_dns_log"/>
+ <?php echo gettext("Suricata will log DNS requests and replies for the interface. Default is ") . "<strong>" . gettext("Not Checked") . "</strong>."; ?>
+ </td>
+ </tr>
+ <tr id="dns_log_append_row">
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Append DNS Log"); ?></td>
+ <td width="78%" class="vtable"><input name="append_dns_log" type="checkbox" value="on" <?php if ($pconfig['append_dns_log'] == "on") echo "checked"; ?>/>
+ <?php echo gettext("Suricata will append-to instead of clearing DNS log file when restarting. Default is ") . "<strong>" . gettext("Checked") . "</strong>."; ?></td>
+ </tr>
+
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable Stats Log"); ?></td>
<td width="78%" class="vtable"><input name="enable_stats_log" type="checkbox" value="on" <?php if ($pconfig['enable_stats_log'] == "on") echo "checked"; ?>
@@ -457,6 +619,11 @@ if ($savemsg) {
<td width="78%" class="vtable"><input name="append_http_log" type="checkbox" value="on" <?php if ($pconfig['append_http_log'] == "on") echo "checked"; ?>/>
<?php echo gettext("Suricata will append-to instead of clearing HTTP log file when restarting. Default is ") . "<strong>" . gettext("Checked") . "</strong>."; ?></td>
</tr>
+ <tr id="http_log_extended_row">
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Log Extended HTTP Info"); ?></td>
+ <td width="78%" class="vtable"><input name="http_log_extended" type="checkbox" value="on" <?php if ($pconfig['http_log_extended'] == "on") echo "checked"; ?>/>
+ <?php echo gettext("Suricata will log extended HTTP information. Default is ") . "<strong>" . gettext("Checked") . "</strong>."; ?></td>
+ </tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Enable TLS Log"); ?></td>
<td width="78%" class="vtable"><input name="enable_tls_log" type="checkbox" value="on" <?php if ($pconfig['enable_tls_log'] == "on") echo "checked"; ?>
@@ -524,6 +691,99 @@ if ($savemsg) {
<?php echo gettext("Enter maximum number of packet log files to maintain. Default is ") . "<strong>" .
gettext("1000") . "</strong>."; ?><br/><br/><?php echo gettext("When the number of packet log files reaches the set limit, the oldest file will be overwritten.") ?></td>
</tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("EVE JSON Log"); ?></td>
+ <td width="78%" class="vtable"><input name="enable_eve_log" id="enable_eve_log" type="checkbox" value="on" <?php if ($pconfig['enable_eve_log'] == "on") echo "checked"; ?>
+ onClick="toggle_eve_log()"/>
+ <?php echo gettext("Suricata will output selected info in JSON format to a single file or to syslog. Default is ") . "<strong>" . gettext("Not Checked") . "</strong>."; ?>
+ <div id="file_eve_warning" style="display: none;"><br/><span class="red"><strong><?php echo gettext("Warning: ") . "</strong></span>" .
+ gettext("This can consume a significant amount of disk space when enabled!"); ?></div>
+ </td>
+ </tr>
+ <tbody id="eve_log_option_rows">
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("EVE Output Type"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="eve_output_type" class="formselect" id="eve_output_type" onChange="eveOutSelect();" >
+ <?php
+ foreach (array("file", "syslog") as $btype) {
+ if ($btype == $pconfig['eve_output_type'])
+ echo "<option value='{$btype}' selected>";
+ else
+ echo "<option value='{$btype}'>";
+ echo htmlspecialchars($btype) . '</option>';
+ }
+ ?>
+ </select>&nbsp;&nbsp;
+ <?php echo gettext("Select EVE log output destination."); ?><br/>
+ <span class="red"><?php echo gettext("Hint:") . "</span>&nbsp;" . gettext("Choosing FILE is suggested, and it is the default value."); ?><br/>
+ </td>
+ </tr>
+ <tr id="eve_systemlog_facility_row">
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("EVE Syslog Facility"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="eve_systemlog_facility" id="eve_systemlog_facility" class="formselect">
+ <?php
+ $log_facility = array( "auth", "authpriv", "daemon", "kern", "security", "syslog", "user", "local0",
+ "local1", "local2", "local3", "local4", "local5", "local6", "local7" );
+ foreach ($log_facility as $facility) {
+ $selected = "";
+ if ($facility == $pconfig['eve_systemlog_facility'])
+ $selected = " selected";
+ echo "<option value='{$facility}'{$selected}>" . $facility . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Select system log Facility to use for reporting by EVE. Default is ") . "<strong>" . gettext("local1") . "</strong>."; ?>
+ </td>
+ </tr>
+ <tr id="eve_systemlog_priority_row">
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("EVE Syslog Priority"); ?></td>
+ <td width="78%" class="vtable">
+ <select name="eve_systemlog_priority" id="eve_systemlog_priority" class="formselect">
+ <?php
+ $log_priority = array( "emerg", "crit", "alert", "err", "warning", "notice", "info" );
+ foreach ($log_priority as $priority) {
+ $selected = "";
+ if ($priority == $pconfig['eve_systemlog_priority'])
+ $selected = " selected";
+ echo "<option value='{$priority}'{$selected}>" . $priority . "</option>\n";
+ }
+ ?></select>&nbsp;&nbsp;
+ <?php echo gettext("Select system log Priority (Level) to use for reporting by EVE. Default is ") . "<strong>" . gettext("notice") . "</strong>."; ?>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("EVE Logged Info"); ?></td>
+ <td width="78%" class="vtable"><?php echo gettext("Choose the information to log via EVE JSON output. Default is ") . "<strong>" . gettext("All Checked") . "</strong>."; ?><br/>
+ <table width="100%" cellpadding="0" cellspacing="0" border="0">
+ <tbody>
+ <tr>
+ <td class="vexpl"><input name="eve_log_alerts" id="eve_log_alerts" type="checkbox" value="on"
+ <?php if ($pconfig['eve_log_alerts'] == "on") echo "checked"; ?>/>Alerts
+ </td>
+ <td class="vexpl"><input name="eve_log_http" id="eve_log_http" type="checkbox" value="on"
+ <?php if ($pconfig['eve_log_http'] == "on") echo "checked"; ?>/>HTTP Traffic
+ </td>
+ <td class="vexpl"><input name="eve_log_dns" id="eve_log_dns" type="checkbox" value="on"
+ <?php if ($pconfig['eve_log_dns'] == "on") echo "checked"; ?>/>DNS Requests/Replies
+ </td>
+ </tr>
+ <tr>
+ <td class="vexpl"><input name="eve_log_tls" id="eve_log_tls" type="checkbox" value="on" onClick="toggle_eve_tls();"
+ <?php if ($pconfig['eve_log_tls'] == "on") echo "checked"; ?>/>TLS Handshakes
+ </td>
+ <td class="vexpl"><input name="eve_log_files" id="eve_log_files" type="checkbox" value="on"
+ <?php if ($pconfig['eve_log_files'] == "on") echo "checked"; ?>/>Tracked Files
+ </td>
+ <td class="vexpl"><input name="eve_log_ssh" id="eve_log_ssh" type="checkbox" value="on"
+ <?php if ($pconfig['eve_log_ssh'] == "on") echo "checked"; ?>/>SSH Handshakes
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
<tr>
<td colspan="2" class="listtopic"><?php echo gettext("Alert Settings"); ?></td>
</tr>
@@ -556,7 +816,7 @@ if ($savemsg) {
?>
</select>&nbsp;&nbsp;
<?php echo gettext("Select which IP extracted from the packet you wish to block."); ?><br/>
- <span class="red"><?php echo gettext("Hint:") . "</span>&nbsp;" . gettext("Choosing BOTH is suggested, and it is the default value."); ?></span><br/></td>
+ <span class="red"><?php echo gettext("Hint:") . "</span>&nbsp;" . gettext("Choosing BOTH is suggested, and it is the default value."); ?><br/>
</td>
</tr>
<tr>
@@ -595,8 +855,8 @@ if ($savemsg) {
<td width="78%" class="vtable">
<select name="mpm_algo" class="formselect" id="mpm_algo">
<?php
- $interfaces2 = array('ac' => 'AC', 'ac-gfbs' => 'AC-GFBS', 'ac-bs' => 'AC-BS',
- 'b2g' => 'B2G', 'b3g' => 'B3G', 'wumanber' => 'WUMANBER');
+ $interfaces2 = array('ac' => 'AC', 'ac-gfbs' => 'AC-GFBS', 'b2g' => 'B2G',
+ 'b2gc' => 'B2GC', 'b2gm' => 'B2GM', 'b3g' => 'B3G', 'wumanber' => 'WUMANBER');
foreach ($interfaces2 as $iface2 => $ifacename2): ?>
<option value="<?=$iface2;?>"
<?php if ($iface2 == $pconfig['mpm_algo']) echo "selected"; ?>>
@@ -643,6 +903,14 @@ if ($savemsg) {
"<strong>" . gettext("Not Checked") . "</strong>."; ?></td>
</tr>
<tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Promiscuous Mode"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="intf_promisc_mode" id="intf_promisc_mode" type="checkbox" value="on"
+ <?php if ($pconfig['intf_promisc_mode'] == "on") echo " checked"; ?>/>
+ <?php echo gettext("Suricata will place the monitored interface in promiscuous mode when checked. Default is ") .
+ "<strong>" . gettext("Checked") . "</strong>."; ?></td>
+ </tr>
+ <tr>
<td colspan="2" class="listtopic"><?php echo gettext("Networks " . "Suricata Should Inspect and Protect"); ?></td>
</tr>
<tr>
@@ -651,9 +919,9 @@ if ($savemsg) {
<select name="homelistname" class="formselect" id="homelistname">
<?php
echo "<option value='default' >default</option>";
- /* find whitelist names and filter by type */
- if (is_array($suricataglob['whitelist']['item'])) {
- foreach ($suricataglob['whitelist']['item'] as $value) {
+ /* find Pass List names and filter by type */
+ if (is_array($suricataglob['passlist']['item'])) {
+ foreach ($suricataglob['passlist']['item'] as $value) {
$ilistname = $value['name'];
if ($ilistname == $pconfig['homelistname'])
echo "<option value='$ilistname' selected>";
@@ -668,12 +936,13 @@ if ($savemsg) {
onclick="viewList('<?=$id;?>','homelistname','homenet')" id="btnHomeNet"
title="<?php echo gettext("Click to view currently selected Home Net contents"); ?>"/>
<br/>
- <span class="vexpl"><?php echo gettext("Choose the Home Net you want this interface to use."); ?></span>
+ <span class="vexpl"><?php echo gettext("Choose the Home Net you want this interface to use. Most users should choose 'default'."); ?></span>
<br/><br/>
<span class="red"><?php echo gettext("Note:"); ?></span>&nbsp;<?php echo gettext("Default Home " .
"Net adds only local networks, WAN IPs, Gateways, VPNs and VIPs."); ?><br/>
<span class="red"><?php echo gettext("Hint:"); ?></span>&nbsp;<?php echo gettext("Create an Alias to hold a list of " .
- "friendly IPs that the firewall cannot see or to customize the default Home Net."); ?><br/>
+ "friendly IPs that the firewall cannot see or to customize the default Home Net. Assign the Alias to a Pass List, and " .
+ "then assign that Pass List to Home Net."); ?><br/>
</td>
</tr>
<tr>
@@ -682,9 +951,9 @@ if ($savemsg) {
<select name="externallistname" class="formselect" id="externallistname">
<?php
echo "<option value='default' >default</option>";
- /* find whitelist names and filter by type */
- if (is_array($suricataglob['whitelist']['item'])) {
- foreach ($suricataglob['whitelist']['item'] as $value) {
+ /* find Pass List names and filter by type */
+ if (is_array($suricataglob['passlist']['item'])) {
+ foreach ($suricataglob['passlist']['item'] as $value) {
$ilistname = $value['name'];
if ($ilistname == $pconfig['externallistname'])
echo "<option value='$ilistname' selected>";
@@ -694,7 +963,11 @@ if ($savemsg) {
}
}
?>
- </select>&nbsp;&nbsp;
+ </select>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="button" class="formbtns" value="View List"
+ onclick="viewList('<?=$id;?>','externallistname','externalnet')" id="btnExternalNet"
+ title="<?php echo gettext("Click to view currently selected External Net contents"); ?>"/>
+ <br/>
<?php echo gettext("Choose the External Net you want this interface " .
"to use."); ?>&nbsp;<br/><br/>
<span class="red"><?php echo gettext("Note:"); ?></span>&nbsp;<?php echo gettext("Default " .
@@ -724,7 +997,7 @@ if ($savemsg) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="button" class="formbtns" value="View List" onclick="viewList('<?=$id;?>','passlistname','passlist')"
id="btnPasslist" title="<?php echo gettext("Click to view currently selected Pass List contents"); ?>"/>
<br/>
- <?php echo gettext("Choose the Pass List you want this interface to use."); ?> <br/><br/>
+ <?php echo gettext("Choose the Pass List you want this interface to use. Addresses in a Pass List are never blocked."); ?> <br/><br/>
<span class="red"><?php echo gettext("Note:"); ?></span>&nbsp;<?php echo gettext("This option will only be used when block offenders is on."); ?><br/>
<span class="red"><?php echo gettext("Hint:"); ?></span>&nbsp;<?php echo gettext("Default " .
"Pass List adds local networks, WAN IPs, Gateways, VPNs and VIPs. Create an Alias to customize."); ?>
@@ -773,7 +1046,6 @@ if ($savemsg) {
<tr>
<td colspan="2" align="center" valign="middle"><input name="save" type="submit" class="formbtn" value="Save" title="<?php echo
gettext("Click to save settings and exit"); ?>"/>
- <input name="id" type="hidden" value="<?=$id;?>"/>
</td>
</tr>
<tr>
@@ -781,14 +1053,32 @@ if ($savemsg) {
gettext("Please save your settings before you attempt to start Suricata."); ?>
</td>
</tr>
+</tbody>
</table>
</div>
</td></tr>
+</tbody>
</table>
</form>
<script language="JavaScript">
+function toggle_system_log() {
+ var endis = !(document.iform.alertsystemlog.checked);
+ if (endis)
+ document.getElementById("alertsystemlog_rows").style.display="none";
+ else
+ document.getElementById("alertsystemlog_rows").style.display="";
+}
+
+function toggle_dns_log() {
+ var endis = !(document.iform.enable_dns_log.checked);
+ if (endis)
+ document.getElementById("dns_log_append_row").style.display="none";
+ else
+ document.getElementById("dns_log_append_row").style.display="table-row";
+}
+
function enable_blockoffenders() {
var endis = !(document.iform.blockoffenders.checked);
document.iform.blockoffenderskill.disabled=endis;
@@ -813,18 +1103,27 @@ function toggle_stats_log() {
function toggle_http_log() {
var endis = !(document.iform.enable_http_log.checked);
- if (endis)
+ if (endis) {
document.getElementById("http_log_append_row").style.display="none";
- else
+ document.getElementById("http_log_extended_row").style.display="none";
+ }
+ else {
document.getElementById("http_log_append_row").style.display="table-row";
+ document.getElementById("http_log_extended_row").style.display="table-row";
+ }
}
function toggle_tls_log() {
var endis = !(document.iform.enable_tls_log.checked);
if (endis)
document.getElementById("tls_log_extended_row").style.display="none";
- else
+ else {
document.getElementById("tls_log_extended_row").style.display="table-row";
+ if (document.iform.enable_eve_log.checked && document.iform.eve_log_tls.checked) {
+ alert('Only one TLS log instance permitted...removing TLS log from EVE JSON output in order to enable standalone TLS logging.');
+ document.iform.eve_log_tls.checked = false;
+ }
+ }
}
function toggle_json_file_log() {
@@ -865,6 +1164,25 @@ function toggle_pcap_log() {
}
}
+function toggle_eve_log() {
+ var endis = !(document.iform.enable_eve_log.checked);
+ if (endis) {
+ document.getElementById("eve_log_option_rows").style.display = "none";
+ }
+ else {
+ document.getElementById("eve_log_option_rows").style.display = "";
+ if (document.iform.enable_tls_log.checked)
+ document.iform.eve_log_tls.checked = false;
+ }
+}
+
+function toggle_eve_tls() {
+ if (document.iform.enable_tls_log.checked) {
+ alert('Only one TLS log instance permitted...removing standalone TLS output in order to add EVE JSON TLS output.');
+ document.iform.enable_tls_log.checked = false;
+ }
+}
+
function enable_change(enable_change) {
endis = !(document.iform.enable.checked || enable_change);
// make sure a default answer is called if this is invoked.
@@ -874,6 +1192,7 @@ function enable_change(enable_change) {
document.iform.append_stats_log.disabled = endis;
document.iform.enable_http_log.disabled = endis;
document.iform.append_http_log.disabled = endis;
+ document.iform.http_log_extended.disabled = endis;
document.iform.enable_tls_log.disabled = endis;
document.iform.tls_log_extended.disabled = endis;
document.iform.enable_json_file_log.disabled = endis;
@@ -884,6 +1203,14 @@ function enable_change(enable_change) {
document.iform.enable_pcap_log.disabled = endis;
document.iform.max_pcap_log_size.disabled = endis;
document.iform.max_pcap_log_files.disabled = endis;
+ document.iform.eve_output_type.disabled = endis;
+ document.iform.enable_eve_log.disabled = endis;
+ document.iform.eve_log_alerts.disabled = endis;
+ document.iform.eve_log_http.disabled = endis;
+ document.iform.eve_log_dns.disabled = endis;
+ document.iform.eve_log_tls.disabled = endis;
+ document.iform.eve_log_files.disabled = endis;
+ document.iform.eve_log_ssh.disabled = endis;
document.iform.max_pending_packets.disabled = endis;
document.iform.detect_eng_profile.disabled = endis;
document.iform.mpm_algo.disabled = endis;
@@ -901,8 +1228,9 @@ function enable_change(enable_change) {
document.iform.btnHomeNet.disabled=endis;
document.iform.btnPasslist.disabled=endis;
document.iform.btnSuppressList.disabled=endis;
-} document.iform.delayed_detect.disabled=endis;
-
+ document.iform.delayed_detect.disabled=endis;
+ document.iform.intf_promisc_mode.disabled=endis;
+}
function wopen(url, name, w, h) {
// Fudge factors for window decoration space.
@@ -923,6 +1251,18 @@ function getSelectedValue(elemID) {
return ctrl.options[ctrl.selectedIndex].value;
}
+function eveOutSelect() {
+ var ctrl = document.getElementById("eve_output_type");
+ if (ctrl.options[ctrl.selectedIndex].value == 'syslog') {
+ document.getElementById("eve_systemlog_facility_row").style.display = "table-row";
+ document.getElementById("eve_systemlog_priority_row").style.display = "table-row";
+ }
+ else {
+ document.getElementById("eve_systemlog_facility_row").style.display = "none";
+ document.getElementById("eve_systemlog_priority_row").style.display = "none";
+ }
+}
+
function viewList(id, elemID, elemType) {
if (typeof elemType == "undefined") {
elemType = "passlist";
@@ -935,12 +1275,16 @@ function viewList(id, elemID, elemType) {
enable_change(false);
//enable_blockoffenders();
+toggle_system_log();
+toggle_dns_log();
toggle_stats_log();
toggle_http_log();
toggle_tls_log();
toggle_json_file_log();
toggle_file_store();
toggle_pcap_log();
+toggle_eve_log();
+eveOutSelect();
</script>
<?php include("fend.inc"); ?>
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_libhtp_policy_engine.php b/config/suricata/suricata_libhtp_policy_engine.php
index 7e6ffd6d..248f4c74 100644
--- a/config/suricata/suricata_libhtp_policy_engine.php
+++ b/config/suricata/suricata_libhtp_policy_engine.php
@@ -60,12 +60,14 @@
resp_body_limit --> Response Body Limit size
enable_double_decode_path --> double-decode path part of URI
enable_double_decode_query --> double-decode query string part of URI
+ enable_uri_include_all --> inspect all of URI
save_libhtp_policy --> Submit button for save operation and exit
cancel_libhtp_policy --> Submit button to cancel operation and exit
**************************************************************************************/
?>
<table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" valign="middle" class="listtopic"><?php echo gettext("Suricata Target-Based HTTP Server Policy Configuration"); ?></td>
</tr>
@@ -73,7 +75,7 @@
<td valign="top" class="vncell"><?php echo gettext("Engine Name"); ?></td>
<td class="vtable">
<input name="policy_name" type="text" class="formfld unknown" id="policy_name" size="25" maxlength="25"
- value="<?=htmlspecialchars($pengcfg['name']);?>"<?php if (htmlspecialchars($pengcfg['name']) == "default") echo "readonly";?>>&nbsp;
+ value="<?=htmlspecialchars($pengcfg['name']);?>"<?php if (htmlspecialchars($pengcfg['name']) == " default") echo " readonly";?>>&nbsp;
<?php if (htmlspecialchars($pengcfg['name']) <> "default")
echo gettext("Name or description for this engine. (Max 25 characters)");
else
@@ -87,6 +89,7 @@
<td class="vtable">
<?php if ($pengcfg['name'] <> "default") : ?>
<table width="95%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
<td class="vexpl"><input name="policy_bind_to" type="text" class="formfldalias" id="policy_bind_to" size="32"
value="<?=htmlspecialchars($pengcfg['bind_to']);?>" title="<?=trim(filter_expand_alias($pengcfg['bind_to']));?>" autocomplete="off">&nbsp;
@@ -97,6 +100,7 @@
<tr>
<td class="vexpl" colspan="2"><?php echo gettext("This policy will apply for packets with destination addresses contained within this IP List.");?></td>
</tr>
+ </tbody>
</table>
<br/><span class="red"><strong><?php echo gettext("Note: ") . "</strong></span>" . gettext("Supplied value must be a pre-configured Alias or the keyword 'all'.");?>
<?php else : ?>
@@ -112,7 +116,7 @@
<td width="78%" class="vtable">
<select name="personality" class="formselect" id="personality">
<?php
- $profile = array( 'Apache', 'Apache_2_2', 'Generic', 'IDS', 'IIS_4_0', 'IIS_5_0', 'IIS_5_1', 'IIS_6_0', 'IIS_7_0', 'IIS_7_5', 'Minimal' );
+ $profile = array( 'Apache_2', 'Generic', 'IDS', 'IIS_4_0', 'IIS_5_0', 'IIS_5_1', 'IIS_6_0', 'IIS_7_0', 'IIS_7_5', 'Minimal' );
foreach ($profile as $val): ?>
<option value="<?=$val;?>"
<?php if ($val == $pengcfg['personality']) echo "selected"; ?>>
@@ -120,7 +124,7 @@
<?php endforeach; ?>
</select>&nbsp;&nbsp;<?php echo gettext("Choose the web server personality appropriate for the protected hosts. The default is ") .
"<strong>" . gettext("IDS") . "</strong>"; ?>.<br/><br/>
- <?php echo gettext("Available web server personality targets are: Apache, Apache 2.2, Generic, IDS (default), IIS_4_0, IIS_5_0, IIS_5_1, IIS_6_0, IIS_7_0, IIS_7_5 and Minimal."); ?><br/>
+ <?php echo gettext("Available web server personality targets are: Apache 2, Generic, IDS (default), IIS_4_0, IIS_5_0, IIS_5_1, IIS_6_0, IIS_7_0, IIS_7_5 and Minimal."); ?><br/>
</td>
</tr>
<tr>
@@ -155,15 +159,22 @@
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Double-Decode Path"); ?></td>
- <td width="78%" class="vtable"><input name="enable_double_decode_path" type="checkbox" value="yes" <?php if ($pengcfg['double-decode-path'] == "yes") echo "checked"; ?>>
+ <td width="78%" class="vtable"><input name="enable_double_decode_path" type="checkbox" value="yes" <?php if ($pengcfg['double-decode-path'] == "yes") echo " checked"; ?>>
<?php echo gettext("Suricata will double-decode path section of the URI. Default is ") . "<strong>" . gettext("Not Checked") . "</strong>."; ?></td>
</tr>
<tr>
<td width="22%" valign="top" class="vncell"><?php echo gettext("Double-Decode Query"); ?></td>
- <td width="78%" class="vtable"><input name="enable_double_decode_query" type="checkbox" value="yes" <?php if ($pengcfg['double-decode-query'] == "yes") echo "checked"; ?>>
+ <td width="78%" class="vtable"><input name="enable_double_decode_query" type="checkbox" value="yes" <?php if ($pengcfg['double-decode-query'] == "yes") echo " checked"; ?>>
<?php echo gettext("Suricata will double-decode query string section of the URI. Default is ") . "<strong>" . gettext("Not Checked") . "</strong>."; ?></td>
</tr>
<tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("URI Include-All"); ?></td>
+ <td width="78%" class="vtable"><input name="enable_uri_include_all" type="checkbox" value="yes" <?php if ($pengcfg['uri-include-all'] == "yes") echo " checked"; ?>>
+ <?php echo gettext("Include all parts of the URI. Default is ") . "<strong>" . gettext("Not Checked") . "</strong>."; ?><br/><br/>
+ <?php echo gettext("By default the 'scheme', username/password, hostname and port are excluded from inspection. Enabling this option " .
+ "adds all of them to the normalized uri. This was the default in Suricata versions prior to 2.0."); ?></td>
+ </tr>
+ <tr>
<td width="22%" valign="bottom">&nbsp;</td>
<td width="78%" valign="bottom">
<input name="save_libhtp_policy" id="save_libhtp_policy" type="submit" class="formbtn" value=" Save " title="<?php echo
@@ -172,6 +183,7 @@
<input name="cancel_libhtp_policy" id="cancel_libhtp_policy" type="submit" class="formbtn" value="Cancel" title="<?php echo
gettext("Cancel changes and return to App Parsers tab"); ?>"></td>
</tr>
+ </tbody>
</table>
<script type="text/javascript" src="/javascript/autosuggest.js">
diff --git a/config/suricata/suricata_list_view.php b/config/suricata/suricata_list_view.php
index 722bf47a..ec335abd 100644
--- a/config/suricata/suricata_list_view.php
+++ b/config/suricata/suricata_list_view.php
@@ -42,7 +42,7 @@ $type = htmlspecialchars($_GET['type']);
$title = "List";
if (isset($id) && isset($wlist)) {
- $a_rule = $config['installedpackages']['suricataglobal']['rule'][$id];
+ $a_rule = $config['installedpackages']['suricata']['rule'][$id];
if ($type == "homenet") {
$list = suricata_build_list($a_rule, $wlist);
$contents = implode("\n", $list);
@@ -58,6 +58,20 @@ if (isset($id) && isset($wlist)) {
$contents = str_replace("\r", "", base64_decode($list['suppresspassthru']));
$title = "Suppress List";
}
+ elseif ($type == "externalnet") {
+ if ($wlist == "default") {
+ $list = suricata_build_list($a_rule, $a_rule['homelistname']);
+ $contents = "";
+ foreach ($list as $ip)
+ $contents .= "!{$ip}\n";
+ $contents = trim($contents, "\n");
+ }
+ else {
+ $list = suricata_build_list($a_rule, $wlist, false, true);
+ $contents = implode("\n", $list);
+ }
+ $title = "EXTERNAL_NET";
+ }
else
$contents = gettext("\n\nERROR -- Requested List Type entity is not valid!");
}
diff --git a/config/suricata/suricata_logs_browser.php b/config/suricata/suricata_logs_browser.php
index 04edf373..320ba23f 100644
--- a/config/suricata/suricata_logs_browser.php
+++ b/config/suricata/suricata_logs_browser.php
@@ -55,21 +55,22 @@ $suricata_uuid = $a_instance[$instanceid]['uuid'];
$if_real = get_real_interface($a_instance[$instanceid]['interface']);
// Construct a pointer to the instance's logging subdirectory
-$suricatalogdir = SURICATALOGDIR . "suricata_{$if_real}{$suricata_uuid}";
+$suricatalogdir = SURICATALOGDIR . "suricata_{$if_real}{$suricata_uuid}/";
-$logfile = $_POST['file'];
+// Limit all file access to just the currently selected interface's logging subdirectory
+$logfile = htmlspecialchars($suricatalogdir . basename($_POST['file']));
if ($_POST['action'] == 'load') {
- if(!is_file($_POST['file'])) {
+ if(!is_file($logfile)) {
echo "|3|" . gettext("Log file does not exist or that logging feature is not enabled") . ".|";
}
else {
- $data = file_get_contents($_POST['file']);
+ $data = file_get_contents($logfile);
if($data === false) {
echo "|1|" . gettext("Failed to read log file") . ".|";
} else {
$data = base64_encode($data);
- echo "|0|{$_POST['file']}|{$data}|";
+ echo "|0|{$logfile}|{$data}|";
}
}
exit;
@@ -84,7 +85,6 @@ include_once("head.inc");
<?php
include_once("fbegin.inc");
-if($pfsense_stable == 'yes'){echo '<p class="pgtitle">' . $pgtitle . '</p>';}
if ($input_errors) {
print_input_errors($input_errors);
}
@@ -94,21 +94,21 @@ if ($input_errors) {
<script type="text/javascript">
function loadFile() {
jQuery("#fileStatus").html("<?=gettext("Loading file"); ?> ...");
- jQuery("#fileStatusBox").show(500);
- jQuery("#filePathBox").show(500);
+ jQuery("#fileStatusBox").show(250);
+ jQuery("#filePathBox").show(250);
jQuery("#fbTarget").html("");
jQuery.ajax(
"<?=$_SERVER['SCRIPT_NAME'];?>", {
type: 'POST',
- data: "action=load&file=" + jQuery("#logFile").val(),
+ data: "instance=" + jQuery("#instance").val() + "&action=load&file=" + jQuery("#logFile").val(),
complete: loadComplete
}
);
}
function loadComplete(req) {
- jQuery("#fileContent").show(1000);
+ jQuery("#fileContent").show(250);
var values = req.responseText.split("|");
values.shift(); values.pop();
@@ -117,14 +117,17 @@ if ($input_errors) {
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);
}
- jQuery("#fileContent").show(1000);
}
</script>
@@ -133,18 +136,22 @@ if ($input_errors) {
<input type="hidden" id="instance" value="<?=$instanceid;?>"/>
<?php if ($savemsg) print_info_box($savemsg); ?>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php?instance={$instanceid}");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), true, "/suricata/suricata_logs_browser.php");
+ $tab_array[] = array(gettext("Logs View"), true, "/suricata/suricata_logs_browser.php");
$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>
@@ -152,6 +159,7 @@ if ($input_errors) {
<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("Logs Browser Selections"); ?></td>
</tr>
@@ -175,12 +183,12 @@ if ($input_errors) {
<td width="78%" class="vtable">
<select name="logFile" id="logFile" class="formselect" onChange="loadFile();">
<?php
- $logs = array( "alerts.log", "block.log", "files-json.log", "http.log", "stats.log", "suricata.log", "tls.log" );
+ $logs = array( "alerts.log", "block.log", "dns.log", "eve.json", "files-json.log", "http.log", "sid_changes.log", "stats.log", "suricata.log", "tls.log" );
foreach ($logs as $log) {
$selected = "";
if ($log == basename($logfile))
$selected = "selected";
- echo "<option value='{$suricatalogdir}/{$log}' {$selected}>" . $log . "</option>\n";
+ echo "<option value='{$suricatalogdir}{$log}' {$selected}>" . $log . "</option>\n";
}
?>
</select>&nbsp;&nbsp;<?php echo gettext('Choose which log you want to view.'); ?>
@@ -191,38 +199,55 @@ if ($input_errors) {
</tr>
<tr>
<td colspan="2">
- <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>
+ <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">
+ <input type="button" name="refresh" id="refresh" value="Refresh" class="formbtn" onclick="loadFile();" title="<?=gettext("Refresh current display");?>" />
+ </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"></textarea>
+ <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>
+ </tbody>
</table>
</form>
-<?php if(empty($logfile)): ?>
+<?php if(empty($_POST['file'])): ?>
<script type="text/javascript">
document.getElementById("logFile").selectedIndex=-1;
</script>
diff --git a/config/suricata/suricata_logs_mgmt.php b/config/suricata/suricata_logs_mgmt.php
index 16376c5b..aa353d6f 100644
--- a/config/suricata/suricata_logs_mgmt.php
+++ b/config/suricata/suricata_logs_mgmt.php
@@ -67,6 +67,12 @@ $pconfig['tls_log_retention'] = $config['installedpackages']['suricata']['config
$pconfig['unified2_log_limit'] = $config['installedpackages']['suricata']['config'][0]['unified2_log_limit'];
$pconfig['u2_archive_log_retention'] = $config['installedpackages']['suricata']['config'][0]['u2_archive_log_retention'];
$pconfig['file_store_retention'] = $config['installedpackages']['suricata']['config'][0]['file_store_retention'];
+$pconfig['dns_log_limit_size'] = $config['installedpackages']['suricata']['config'][0]['dns_log_limit_size'];
+$pconfig['dns_log_retention'] = $config['installedpackages']['suricata']['config'][0]['dns_log_retention'];
+$pconfig['eve_log_limit_size'] = $config['installedpackages']['suricata']['config'][0]['eve_log_limit_size'];
+$pconfig['eve_log_retention'] = $config['installedpackages']['suricata']['config'][0]['eve_log_retention'];
+$pconfig['sid_changes_log_limit_size'] = $config['installedpackages']['suricata']['config'][0]['sid_changes_log_limit_size'];
+$pconfig['sid_changes_log_retention'] = $config['installedpackages']['suricata']['config'][0]['sid_changes_log_retention'];
// Load up some arrays with selection values (we use these later).
// The keys in the $retentions array are the retention period
@@ -88,40 +94,99 @@ if (empty($pconfig['suricataloglimitsize'])) {
}
// Set default retention periods for rotated logs
-if (empty($pconfig['alert_log_retention']))
+if (!isset($pconfig['alert_log_retention']))
$pconfig['alert_log_retention'] = "336";
-if (empty($pconfig['block_log_retention']))
+if (!isset($pconfig['block_log_retention']))
$pconfig['block_log_retention'] = "336";
-if (empty($pconfig['files_json_log_retention']))
+if (!isset($pconfig['files_json_log_retention']))
$pconfig['files_json_log_retention'] = "168";
-if (empty($pconfig['http_log_retention']))
+if (!isset($pconfig['http_log_retention']))
$pconfig['http_log_retention'] = "168";
-if (empty($pconfig['stats_log_retention']))
+if (!isset($pconfig['dns_log_retention']))
+ $pconfig['dns_log_retention'] = "168";
+if (!isset($pconfig['stats_log_retention']))
$pconfig['stats_log_retention'] = "168";
-if (empty($pconfig['tls_log_retention']))
+if (!isset($pconfig['tls_log_retention']))
$pconfig['tls_log_retention'] = "336";
-if (empty($pconfig['u2_archive_log_retention']))
+if (!isset($pconfig['u2_archive_log_retention']))
$pconfig['u2_archive_log_retention'] = "168";
-if (empty($pconfig['file_store_retention']))
+if (!isset($pconfig['file_store_retention']))
$pconfig['file_store_retention'] = "168";
+if (!isset($pconfig['eve_log_retention']))
+ $pconfig['eve_log_retention'] = "168";
+if (!isset($pconfig['sid_changes_log_retention']))
+ $pconfig['sid_changes_log_retention'] = "336";
// Set default log file size limits
-if (empty($pconfig['alert_log_limit_size']))
+if (!isset($pconfig['alert_log_limit_size']))
$pconfig['alert_log_limit_size'] = "500";
-if (empty($pconfig['block_log_limit_size']))
+if (!isset($pconfig['block_log_limit_size']))
$pconfig['block_log_limit_size'] = "500";
-if (empty($pconfig['files_json_log_limit_size']))
+if (!isset($pconfig['files_json_log_limit_size']))
$pconfig['files_json_log_limit_size'] = "1000";
-if (empty($pconfig['http_log_limit_size']))
+if (!isset($pconfig['http_log_limit_size']))
$pconfig['http_log_limit_size'] = "1000";
-if (empty($pconfig['stats_log_limit_size']))
+if (!isset($pconfig['dns_log_limit_size']))
+ $pconfig['dns_log_limit_size'] = "750";
+if (!isset($pconfig['stats_log_limit_size']))
$pconfig['stats_log_limit_size'] = "500";
-if (empty($pconfig['tls_log_limit_size']))
+if (!isset($pconfig['tls_log_limit_size']))
$pconfig['tls_log_limit_size'] = "500";
-if (empty($pconfig['unified2_log_limit']))
+if (!isset($pconfig['unified2_log_limit']))
$pconfig['unified2_log_limit'] = "32";
+if (!isset($pconfig['eve_log_limit_size']))
+ $pconfig['eve_log_limit_size'] = "5000";
+if (!isset($pconfig['sid_changes_log_limit_size']))
+ $pconfig['sid_changes_log_limit_size'] = "250";
+
+if ($_POST['ResetAll']) {
+
+ // Reset all settings to their defaults
+ $pconfig['alert_log_retention'] = "336";
+ $pconfig['block_log_retention'] = "336";
+ $pconfig['files_json_log_retention'] = "168";
+ $pconfig['http_log_retention'] = "168";
+ $pconfig['dns_log_retention'] = "168";
+ $pconfig['stats_log_retention'] = "168";
+ $pconfig['tls_log_retention'] = "336";
+ $pconfig['u2_archive_log_retention'] = "168";
+ $pconfig['file_store_retention'] = "168";
+ $pconfig['eve_log_retention'] = "168";
+ $pconfig['sid_changes_log_retention'] = "336";
+
+ $pconfig['alert_log_limit_size'] = "500";
+ $pconfig['block_log_limit_size'] = "500";
+ $pconfig['files_json_log_limit_size'] = "1000";
+ $pconfig['http_log_limit_size'] = "1000";
+ $pconfig['dns_log_limit_size'] = "750";
+ $pconfig['stats_log_limit_size'] = "500";
+ $pconfig['tls_log_limit_size'] = "500";
+ $pconfig['unified2_log_limit'] = "32";
+ $pconfig['eve_log_limit_size'] = "5000";
+ $pconfig['sid_changes_log_limit_size'] = "250";
+
+ /* 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.");
+}
+
+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' );
+ 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_logs_mgmt.php");
+ exit;
+ }
-if ($_POST["save"]) {
if ($_POST['suricataloglimit'] == 'on') {
if (!is_numericint($_POST['suricataloglimitsize']) || $_POST['suricataloglimitsize'] < 1)
$input_errors[] = gettext("The 'Log Directory Size Limit' must be an integer value greater than zero.");
@@ -151,9 +216,17 @@ if ($_POST["save"]) {
$config['installedpackages']['suricata']['config'][0]['unified2_log_limit'] = $_POST['unified2_log_limit'];
$config['installedpackages']['suricata']['config'][0]['u2_archive_log_retention'] = $_POST['u2_archive_log_retention'];
$config['installedpackages']['suricata']['config'][0]['file_store_retention'] = $_POST['file_store_retention'];
+ $config['installedpackages']['suricata']['config'][0]['dns_log_limit_size'] = $_POST['dns_log_limit_size'];
+ $config['installedpackages']['suricata']['config'][0]['dns_log_retention'] = $_POST['dns_log_retention'];
+ $config['installedpackages']['suricata']['config'][0]['eve_log_limit_size'] = $_POST['eve_log_limit_size'];
+ $config['installedpackages']['suricata']['config'][0]['eve_log_retention'] = $_POST['eve_log_retention'];
+ $config['installedpackages']['suricata']['config'][0]['sid_changes_log_limit_size'] = $_POST['sid_changes_log_limit_size'];
+ $config['installedpackages']['suricata']['config'][0]['sid_changes_log_retention'] = $_POST['sid_changes_log_retention'];
- write_config();
+ 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' );
@@ -179,23 +252,33 @@ include_once("fbegin.inc");
/* Display Alert message, under form tag or no refresh */
if ($input_errors)
print_input_errors($input_errors);
-
?>
<form action="suricata_logs_mgmt.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+
+<?php
+if ($savemsg) {
+ /* Display save message */
+ print_info_box($savemsg);
+}
+?>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php");
$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>
@@ -267,7 +350,7 @@ if ($input_errors)
<colgroup>
<col style="width: 15%;">
<col style="width: 18%;">
- <col style="width: 20%;">
+ <col style="width: 18%;">
<col>
</colgroup>
<thead>
@@ -320,6 +403,46 @@ if ($input_errors)
<td class="listbg"><?=gettext("Suricata blocked IPs and event details");?></td>
</tr>
<tr>
+ <td class="listbg">dns</td>
+ <td class="listr" align="center"><select name="dns_log_limit_size" class="formselect" id="dns_log_limit_size">
+ <?php foreach ($log_sizes as $k => $l): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['dns_log_limit_size']) echo "selected"; ?>>
+ <?=htmlspecialchars($l);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listr" align="center"><select name="dns_log_retention" class="formselect" id="dns_log_retention">
+ <?php foreach ($retentions as $k => $p): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['dns_log_retention']) echo "selected"; ?>>
+ <?=htmlspecialchars($p);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listbg"><?=gettext("DNS request/reply details");?></td>
+ </tr>
+ <tr>
+ <td class="listbg">eve-json</td>
+ <td class="listr" align="center"><select name="eve_log_limit_size" class="formselect" id="eve_log_limit_size">
+ <?php foreach ($log_sizes as $k => $l): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['eve_log_limit_size']) echo "selected"; ?>>
+ <?=htmlspecialchars($l);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listr" align="center"><select name="eve_log_retention" class="formselect" id="eve_log_retention">
+ <?php foreach ($retentions as $k => $p): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['eve_log_retention']) echo "selected"; ?>>
+ <?=htmlspecialchars($p);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listbg"><?=gettext("Eve-JSON (JavaScript Object Notation) data");?></td>
+ </tr>
+ <tr>
<td class="listbg">files-json</td>
<td class="listr" align="center"><select name="files_json_log_limit_size" class="formselect" id="files_json_log_limit_size">
<?php foreach ($log_sizes as $k => $l): ?>
@@ -359,6 +482,28 @@ if ($input_errors)
</td>
<td class="listbg"><?=gettext("Captured HTTP events and session info");?></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">
+ <?php foreach ($log_sizes as $k => $l): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['sid_changes_log_limit_size']) echo "selected"; ?>>
+ <?=htmlspecialchars($l);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listr" align="center"><select name="sid_changes_log_retention" class="formselect" id="sid_changes_log_retention">
+ <?php foreach ($retentions as $k => $p): ?>
+ <option value="<?=$k;?>"
+ <?php if ($k == $pconfig['sid_changes_log_retention']) echo "selected"; ?>>
+ <?=htmlspecialchars($p);?></option>
+ <?php endforeach; ?>
+ </select>
+ </td>
+ <td class="listbg"><?=gettext("Log of SID changes made by SID Mgmt conf files");?></td>
+ </tr>
+
<tr>
<td class="listbg">stats</td>
<td class="listr" align="center"><select name="stats_log_limit_size" class="formselect" id="stats_log_limit_size">
@@ -444,7 +589,11 @@ if ($input_errors)
</tr>
<tr>
<td width="22%"></td>
- <td width="78%" class="vexpl"><input name="save" type="submit" class="formbtn" value="Save"/><br/>
+ <td width="78%" class="vexpl"><input name="save" type="submit" class="formbtn" value="Save"/>
+ &nbsp;&nbsp;&nbsp;&nbsp;<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 Log Management settings to their defaults. Click OK to continue or CANCEL to quit.") .
+ "');\""; ?>/><br/>
<br/><span class="red"><strong><?php echo gettext("Note:");?></strong>&nbsp;
</span><?php echo gettext("Changing any settings on this page will affect all Suricata-configured interfaces.");?></td>
</tr>
@@ -472,6 +621,12 @@ function enable_change() {
document.iform.unified2_log_limit.disabled = endis;
document.iform.u2_archive_log_retention.disabled = endis;
document.iform.file_store_retention.disabled = endis;
+ document.iform.dns_log_retention.disabled = endis;
+ document.iform.dns_log_limit_size.disabled = endis;
+ document.iform.eve_log_retention.disabled = endis;
+ document.iform.eve_log_limit_size.disabled = endis;
+ document.iform.sid_changes_log_retention.disabled = endis;
+ document.iform.sid_changes_log_limit_size.disabled = endis;
}
function enable_change_dirSize() {
diff --git a/config/suricata/suricata_migrate_config.php b/config/suricata/suricata_migrate_config.php
new file mode 100644
index 00000000..75e13315
--- /dev/null
+++ b/config/suricata/suricata_migrate_config.php
@@ -0,0 +1,387 @@
+<?php
+/*
+ * suricata_migrate_config.php
+ *
+ * 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");
+
+/****************************************************************************/
+/* The code in this module is called once during the post-install process */
+/* via an "include" line. It is used to perform a one-time migration of */
+/* Suricata configuration parameters to any new format required by the */
+/* latest package version. */
+/****************************************************************************/
+
+global $config;
+
+if (!is_array($config['installedpackages']['suricata']))
+ $config['installedpackages']['suricata'] = array();
+if (!is_array($config['installedpackages']['suricata']['rule']))
+ $config['installedpackages']['suricata']['rule'] = array();
+
+// Just exit if this is a clean install with no saved settings
+if (empty($config['installedpackages']['suricata']['rule']))
+ return;
+
+$rule = &$config['installedpackages']['suricata']['rule'];
+
+/****************************************************************************/
+/* Loop through all the <rule> elements in the Suricata configuration and */
+/* migrate relevant parameters to the new format. */
+/****************************************************************************/
+
+$updated_cfg = false;
+log_error("[Suricata] Checking configuration settings version...");
+
+// Check the configuration version to see if XMLRPC Sync should
+// auto-disabled as part of the upgrade due to config format changes.
+if ($config['installedpackages']['suricata']['config'][0]['suricata_config_ver'] < 2 &&
+ ($config['installedpackages']['suricatasync']['config'][0]['varsynconchanges'] == 'auto' ||
+ $config['installedpackages']['suricatasync']['config'][0]['varsynconchanges'] == 'manual')) {
+ $config['installedpackages']['suricatasync']['config'][0]['varsynconchanges'] = "disabled";
+ log_error("[Suricata] Turning off Suricata Sync on this host due to configuration format changes in this update. Upgrade all Suricata Sync targets to this same Suricata package version before re-enabling Suricata Sync.");
+ $updated_cfg = true;
+}
+
+/**********************************************************/
+/* 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;
+}
+
+/**********************************************************/
+/* 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) {
+
+ // Initialize arrays for supported preprocessors if necessary
+ if (!is_array($r['libhtp_policy']['item']))
+ $r['libhtp_policy']['item'] = array();
+
+ $pconfig = array();
+ $pconfig = $r;
+
+ /***********************************************************/
+ /* This setting is deprecated in Suricata 2.0 and higher, */
+ /* so remove it from the configuration. */
+ /***********************************************************/
+ if (isset($pconfig['stream_max_sessions'])) {
+ unset($pconfig['stream_max_sessions']);
+ $updated_cfg = true;
+ }
+
+ /***********************************************************/
+ /* HTTP server personalities for "Apache" and "Apache_2_2" */
+ /* are deprecated and replaced with "Apache_2" in Suricata */
+ /* versions greater than 2.0. */
+ /***********************************************************/
+ $http_serv = &$pconfig['libhtp_policy']['item'];
+ foreach ($http_serv as &$policy) {
+ if ($policy['personality'] == "Apache" || $policy['personality'] == "Apache_2_2") {
+ $policy['personality'] = "Apache_2";
+ $updated_cfg = true;
+ }
+ // Set new URI inspect option for Suricata 2.0 and higher
+ if (!isset($policy['uri-include-all'])) {
+ $policy['uri-include-all'] = "no";
+ $updated_cfg = true;
+ }
+ }
+
+ /***********************************************************/
+ /* Add the new 'dns-events.rules' file to the rulesets. */
+ /***********************************************************/
+ if (strpos($pconfig['rulesets'], "dns-events.rules") === FALSE) {
+ $pconfig['rulesets'] = rtrim($pconfig['rulesets'], "||") . "||dns-events.rules";
+ $updated_cfg = true;
+ }
+
+ /***********************************************************/
+ /* Add new interface promisc mode value and default 'on'. */
+ /***********************************************************/
+ if (empty($pconfig['intf_promisc_mode'])) {
+ $pconfig['intf_promisc_mode'] = "on";
+ $updated_cfg = true;
+ }
+
+ /***********************************************************/
+ /* Add new HTTP Log Extended Info setting if not present */
+ /***********************************************************/
+ if (!isset($pconfig['http_log_extended'])) {
+ $pconfig['http_log_extended'] = "on";
+ $updated_cfg = true;
+ }
+
+ /***********************************************************/
+ /* Add new EVE logging settings if not present */
+ /***********************************************************/
+ if (!isset($pconfig['eve_output_type'])) {
+ $pconfig['eve_output_type'] = "file";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['eve_systemlog_facility'])) {
+ $pconfig['eve_systemlog_facility'] = "local1";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['eve_systemlog_priority'])) {
+ $pconfig['eve_systemlog_priority'] = "info";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['eve_log_alerts'])) {
+ $pconfig['eve_log_alerts'] = "on";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['eve_log_http'])) {
+ $pconfig['eve_log_http'] = "on";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['eve_log_dns'])) {
+ $pconfig['eve_log_dns'] = "on";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['eve_log_tls'])) {
+ $pconfig['eve_log_tls'] = "on";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['eve_log_files'])) {
+ $pconfig['eve_log_files'] = "on";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['eve_log_ssh'])) {
+ $pconfig['eve_log_ssh'] = "on";
+ $updated_cfg = true;
+ }
+
+ /******************************************************************/
+ /* Create default log size and retention limits if not set */
+ /******************************************************************/
+ if (!isset($pconfig['alert_log_retention']) && $pconfig['alert_log_retention'] != '0') {
+ $pconfig['alert_log_retention'] = "336";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['alert_log_limit_size']) && $pconfig['alert_log_limit_size'] != '0') {
+ $pconfig['alert_log_limit_size'] = "500";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['block_log_retention']) && $pconfig['block_log_retention'] != '0') {
+ $pconfig['block_log_retention'] = "336";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['block_log_limit_size']) && $pconfig['block_log_limit_size'] != '0') {
+ $pconfig['block_log_limit_size'] = "500";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['dns_log_retention']) && $pconfig['dns_log_retention'] != '0') {
+ $pconfig['dns_log_retention'] = "168";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['dns_log_limit_size']) && $pconfig['dns_log_limit_size'] != '0') {
+ $pconfig['dns_log_limit_size'] = "750";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['eve_log_retention']) && $pconfig['eve_log_retention'] != '0') {
+ $pconfig['eve_log_retention'] = "168";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['eve_log_limit_size']) && $pconfig['eve_log_limit_size'] != '0') {
+ $pconfig['eve_log_limit_size'] = "5000";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['files_json_log_retention']) && $pconfig['files_json_log_retention'] != '0') {
+ $pconfig['files_json_log_retention'] = "168";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['files_json_log_limit_size']) && $pconfig['files_json_log_limit_size'] != '0') {
+ $pconfig['files_json_log_limit_size'] = "1000";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['http_log_retention']) && $pconfig['http_log_retention'] != '0') {
+ $pconfig['http_log_retention'] = "168";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['http_log_limit_size']) && $pconfig['http_log_limit_size'] != '0') {
+ $pconfig['http_log_limit_size'] = "1000";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['stats_log_retention']) && $pconfig['stats_log_retention'] != '0') {
+ $pconfig['stats_log_retention'] = "168";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['stats_log_limit_size']) && $pconfig['stats_log_limit_size'] != '0') {
+ $pconfig['stats_log_limit_size'] = "500";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['tls_log_retention']) && $pconfig['tls_log_retention'] != '0') {
+ $pconfig['tls_log_retention'] = "336";
+ $updated_cfg = true;
+ }
+ if (!isset($pconfig['tls_log_limit_size']) && $pconfig['tls_log_limit_size'] != '0') {
+ $pconfig['tls_log_limit_size'] = "500";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['file_store_retention']) && $pconfig['file_store_retention'] != '0') {
+ $pconfig['file_store_retention'] = "168";
+ $updated_cfg = true;
+ }
+
+ if (!isset($pconfig['u2_archive_log_retention']) && $pconfig['u2_archive_log_retention'] != '0') {
+ $pconfig['u2_archive_log_retention'] = "168";
+ $updated_cfg = true;
+ }
+
+ /************************************************************/
+ /* Create new DNS App-Layer parser settings if not set */
+ /************************************************************/
+ if (empty($pconfig['dns_global_memcap'])) {
+ $pconfig['dns_global_memcap'] = "16777216";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['dns_state_memcap'])) {
+ $pconfig['dns_state_memcap'] = "524288";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['dns_request_flood_limit'])) {
+ $pconfig['dns_request_flood_limit'] = "500";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['dns_parser_udp'])) {
+ $pconfig['dns_parser_udp'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['dns_parser_tcp'])) {
+ $pconfig['dns_parser_tcp'] = "yes";
+ $updated_cfg = true;
+ }
+
+ /***********************************************************/
+ /* Create new HTTP App-Layer parser settings if not set */
+ /***********************************************************/
+ if (empty($pconfig['http_parser'])) {
+ $pconfig['http_parser'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['http_parser_memcap'])) {
+ $pconfig['http_parser_memcap'] = "67108864";
+ $updated_cfg = true;
+ }
+
+ /**********************************************************/
+ /* Create other App-Layer parser settings if not set */
+ /**********************************************************/
+ if (empty($pconfig['tls_parser'])) {
+ $pconfig['tls_parser'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['smtp_parser'])) {
+ $pconfig['smtp_parser'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['imap_parser'])) {
+ $pconfig['imap_parser'] = "detection-only";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['ssh_parser'])) {
+ $pconfig['ssh_parser'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['ftp_parser'])) {
+ $pconfig['ftp_parser'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['dcerpc_parser'])) {
+ $pconfig['dcerpc_parser'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['smb_parser'])) {
+ $pconfig['smb_parser'] = "yes";
+ $updated_cfg = true;
+ }
+ if (empty($pconfig['msn_parser'])) {
+ $pconfig['msn_parser'] = "detection-only";
+ $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;
+}
+// Release reference to final array element
+unset($r);
+
+// Write out the new configuration to disk if we changed anything
+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_os_policy_engine.php b/config/suricata/suricata_os_policy_engine.php
index 869d940c..9a881f3d 100644
--- a/config/suricata/suricata_os_policy_engine.php
+++ b/config/suricata/suricata_os_policy_engine.php
@@ -62,6 +62,7 @@
?>
<table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" align="center" class="listtopic"><?php echo gettext("Suricata Target-Based Host OS Policy Engine Configuration"); ?></td>
</tr>
@@ -69,7 +70,7 @@
<td valign="top" class="vncell"><?php echo gettext("Policy Name"); ?></td>
<td class="vtable">
<input name="policy_name" type="text" class="formfld unknown" id="policy_name" size="25" maxlength="25"
- value="<?=htmlspecialchars($pengcfg['name']);?>"<?php if (htmlspecialchars($pengcfg['name']) == "default") echo "readonly";?>/>&nbsp;
+ value="<?=htmlspecialchars($pengcfg['name']);?>"<?php if (htmlspecialchars($pengcfg['name']) == " default") echo " readonly";?>/>&nbsp;
<?php if (htmlspecialchars($pengcfg['name']) <> "default")
echo gettext("Name or description for this engine. (Max 25 characters)");
else
@@ -83,6 +84,7 @@
<td class="vtable">
<?php if ($pengcfg['name'] <> "default") : ?>
<table width="95%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
<td class="vexpl"><input name="policy_bind_to" type="text" class="formfldalias" id="policy_bind_to" size="32"
value="<?=htmlspecialchars($pengcfg['bind_to']);?>" title="<?=trim(filter_expand_alias($pengcfg['bind_to']));?>" autocomplete="off"/>&nbsp;
@@ -93,6 +95,7 @@
<tr>
<td class="vexpl" colspan="2"><?php echo gettext("This policy will apply for packets with destination addresses contained within this IP List.");?></td>
</tr>
+ </tbody>
</table>
<span class="red"><strong><?php echo gettext("Note: ") . "</strong></span>" . gettext("Supplied value must be a pre-configured Alias or the keyword 'all'.");?>
&nbsp;&nbsp;&nbsp;&nbsp;
@@ -129,6 +132,7 @@
<input name="cancel_os_policy" id="cancel_os_policy" type="submit" class="formbtn" value="Cancel" title="<?php echo
gettext("Cancel changes and return to Flow/Stream tab"); ?>"></td>
</tr>
+ </tbody>
</table>
<script type="text/javascript" src="/javascript/autosuggest.js">
</script>
diff --git a/config/suricata/suricata_passlist.php b/config/suricata/suricata_passlist.php
index fc7c60e2..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;
}
@@ -115,18 +117,22 @@ if ($savemsg) {
<form action="/suricata/suricata_passlist.php" method="post">
<input type="hidden" name="list_id" id="list_id" value=""/>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $tab_array[] = array(gettext("Blocks"), false, "/suricata/suricata_blocked.php");
$tab_array[] = array(gettext("Pass Lists"), true, "/suricata/suricata_passlist.php");
$tab_array[] = array(gettext("Suppress"), false, "/suricata/suricata_suppress.php");
- $tab_array[] = array(gettext("Logs Browser"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
$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>
@@ -134,6 +140,7 @@ if ($savemsg) {
<tr>
<td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td width="25%" class="listhdrr">List Name</td>
<td width="30%" class="listhdrr">Assigned Alias</td>
@@ -142,19 +149,19 @@ if ($savemsg) {
</tr>
<?php foreach ($a_passlist as $i => $list): ?>
<tr>
- <td class="listlr"
+ <td class="listlr"
ondblclick="document.location='suricata_passlist_edit.php?id=<?=$i;?>';">
<?=htmlspecialchars($list['name']);?></td>
- <td class="listr"
+ <td class="listr"
ondblclick="document.location='suricata_passlist_edit.php?id=<?=$i;?>';"
title="<?=filter_expand_alias($list['address']);?>">
<?php echo gettext($list['address']);?></td>
- <td class="listbg"
+ <td class="listbg"
ondblclick="document.location='suricata_passlist_edit.php?id=<?=$i;?>';">
- <font color="#FFFFFF"> <?=htmlspecialchars($list['descr']);?>&nbsp;
- </td>
+ <font color="#FFFFFF"><?=htmlspecialchars($list['descr']);?></font></td>
<td valign="middle" nowrap class="list">
<table border="0" cellspacing="0" cellpadding="1">
+ <tbody>
<tr>
<td valign="middle"><a href="suricata_passlist_edit.php?id=<?=$i;?>">
<img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17" height="17" border="0" title="<?php echo gettext("Edit pass list"); ?>"></a>
@@ -163,6 +170,7 @@ if ($savemsg) {
src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" width="17" height="17" border="0" title="<?php echo gettext("Delete pass list"); ?>"/>
</td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -171,6 +179,7 @@ if ($savemsg) {
<td class="list" colspan="3"></td>
<td class="list">
<table border="0" cellspacing="0" cellpadding="1">
+ <tbody>
<tr>
<td valign="middle" width="17">&nbsp;</td>
<td valign="middle"><a href="suricata_passlist_edit.php?id=<?php echo $id_gen;?> ">
@@ -178,27 +187,31 @@ if ($savemsg) {
width="17" height="17" border="0" title="<?php echo gettext("add a new pass list"); ?>"/></a>
</td>
</tr>
+ </tbody>
</table>
</td>
</tr>
+ </tbody>
</table>
</div>
</td>
</tr>
+ </tbody>
</table>
<br>
-<table width="100%" border="0" cellpadding="1"
- cellspacing="1">
+<table width="100%" border="0" cellpadding="1" cellspacing="1">
+ <tbody>
<tr>
- <td width="100%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Notes:"); ?></strong></span>
- <p><?php echo gettext("1. Here you can create Pass List files for your Suricata package rules. Hosts on a Pass List are never blocked by Suricata."); ?><br/>
- <?php echo gettext("2. Add all the IP addresses or networks (in CIDR notation) you want to protect against Suricata block decisions."); ?><br/>
- <?php echo gettext("3. The default Pass List includes the WAN IP and gateway, defined DNS servers, VPNs and locally-attached networks."); ?><br/>
- <?php echo gettext("4. Be careful, it is very easy to get locked out of your system by altering the default settings."); ?></p></span></td>
+ <td width="100%"><span class="vexpl"><span class="red"><strong><?php echo gettext("Notes:"); ?></strong></span>
+ <p><?php echo gettext("1. Here you can create Pass List files for your Suricata package rules. Hosts on a Pass List are never blocked by Suricata."); ?><br/>
+ <?php echo gettext("2. Add all the IP addresses or networks (in CIDR notation) you want to protect against Suricata block decisions."); ?><br/>
+ <?php echo gettext("3. The default Pass List includes the WAN IP and gateway, defined DNS servers, VPNs and locally-attached networks."); ?><br/>
+ <?php echo gettext("4. Be careful, it is very easy to get locked out of your system by altering the default settings."); ?></p></span></td>
</tr>
<tr>
- <td width="100%"><span class="vexpl"><?php echo gettext("Remember you must restart Suricata on the interface for changes to take effect!"); ?></span></td>
+ <td width="100%"><span class="vexpl"><?php echo gettext("Remember you must restart Suricata on the interface for changes to take effect!"); ?></span></td>
</tr>
+ </tbody>
</table>
</form>
<?php include("fend.inc"); ?>
diff --git a/config/suricata/suricata_passlist_edit.php b/config/suricata/suricata_passlist_edit.php
index 35c7b66e..5bfeb8b9 100644
--- a/config/suricata/suricata_passlist_edit.php
+++ b/config/suricata/suricata_passlist_edit.php
@@ -63,15 +63,53 @@ if (is_null($id)) {
exit;
}
+if (isset($id) && isset($a_passlist[$id])) {
+ /* Retrieve saved settings */
+ $pconfig['name'] = $a_passlist[$id]['name'];
+ $pconfig['uuid'] = $a_passlist[$id]['uuid'];
+ $pconfig['address'] = $a_passlist[$id]['address'];
+ $pconfig['descr'] = html_entity_decode($a_passlist[$id]['descr']);
+ $pconfig['localnets'] = $a_passlist[$id]['localnets'];
+ $pconfig['wanips'] = $a_passlist[$id]['wanips'];
+ $pconfig['wangateips'] = $a_passlist[$id]['wangateips'];
+ $pconfig['wandnsips'] = $a_passlist[$id]['wandnsips'];
+ $pconfig['vips'] = $a_passlist[$id]['vips'];
+ $pconfig['vpnips'] = $a_passlist[$id]['vpnips'];
+}
+
+// Check for returned "selected alias" if action is import
+if ($_GET['act'] == "import") {
+
+ // Retrieve previously typed values we passed to SELECT ALIAS page
+ $pconfig['name'] = htmlspecialchars($_GET['name']);
+ $pconfig['uuid'] = htmlspecialchars($_GET['uuid']);
+ $pconfig['address'] = htmlspecialchars($_GET['address']);
+ $pconfig['descr'] = htmlspecialchars($_GET['descr']);
+ $pconfig['localnets'] = htmlspecialchars($_GET['localnets'])? 'yes' : 'no';
+ $pconfig['wanips'] = htmlspecialchars($_GET['wanips'])? 'yes' : 'no';
+ $pconfig['wangateips'] = htmlspecialchars($_GET['wangateips'])? 'yes' : 'no';
+ $pconfig['wandnsips'] = htmlspecialchars($_GET['wandnsips'])? 'yes' : 'no';
+ $pconfig['vips'] = htmlspecialchars($_GET['vips'])? 'yes' : 'no';
+ $pconfig['vpnips'] = htmlspecialchars($_GET['vpnips'])? 'yes' : 'no';
+
+ // Now retrieve the "selected alias" returned from SELECT ALIAS page
+ if ($_GET['varname'] == "address" && isset($_GET['varvalue']))
+ $pconfig[$_GET['varname']] = htmlspecialchars($_GET['varvalue']);
+}
+
/* If no entry for this passlist, then create a UUID and treat it like a new list */
-if (!isset($a_passlist[$id]['uuid'])) {
+if (!isset($a_passlist[$id]['uuid']) && empty($pconfig['uuid'])) {
$passlist_uuid = 0;
while ($passlist_uuid > 65535 || $passlist_uuid == 0) {
$passlist_uuid = mt_rand(1, 65535);
$pconfig['uuid'] = $passlist_uuid;
$pconfig['name'] = "passlist_{$passlist_uuid}";
}
-} else
+}
+elseif (!empty($pconfig['uuid'])) {
+ $passlist_uuid = $pconfig['uuid'];
+}
+else
$passlist_uuid = $a_passlist[$id]['uuid'];
/* returns true if $name is a valid name for a pass list file name or ip */
@@ -85,28 +123,6 @@ function is_validpasslistname($name) {
return false;
}
-if (isset($id) && $a_passlist[$id]) {
- /* old settings */
- $pconfig = array();
- $pconfig['name'] = $a_passlist[$id]['name'];
- $pconfig['uuid'] = $a_passlist[$id]['uuid'];
- $pconfig['detail'] = $a_passlist[$id]['detail'];
- $pconfig['address'] = $a_passlist[$id]['address'];
- $pconfig['descr'] = html_entity_decode($a_passlist[$id]['descr']);
- $pconfig['localnets'] = $a_passlist[$id]['localnets'];
- $pconfig['wanips'] = $a_passlist[$id]['wanips'];
- $pconfig['wangateips'] = $a_passlist[$id]['wangateips'];
- $pconfig['wandnsips'] = $a_passlist[$id]['wandnsips'];
- $pconfig['vips'] = $a_passlist[$id]['vips'];
- $pconfig['vpnips'] = $a_passlist[$id]['vpnips'];
-}
-
-// Check for returned "selected alias" if action is import
-if ($_GET['act'] == "import") {
- if ($_GET['varname'] == "address" && isset($_GET['varvalue']))
- $pconfig[$_GET['varname']] = htmlspecialchars($_GET['varvalue']);
-}
-
if ($_POST['save']) {
unset($input_errors);
$pconfig = $_POST;
@@ -114,7 +130,12 @@ if ($_POST['save']) {
/* input validation */
$reqdfields = explode(" ", "name");
$reqdfieldsn = explode(",", "Name");
- do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ $pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
+ if ($pf_version < 2.1)
+ $input_errors = eval('do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); return $input_errors;');
+ else
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if(strtolower($_POST['name']) == "defaultpasslist")
$input_errors[] = gettext("Pass List file names may not be named defaultpasslist.");
@@ -123,11 +144,11 @@ if ($_POST['save']) {
$input_errors[] = gettext("Pass List file name may only consist of the characters \"a-z, A-Z, 0-9 and _\". Note: No Spaces or dashes. Press Cancel to reset.");
/* check for name conflicts */
- foreach ($a_passlist as $w_list) {
- if (isset($id) && ($a_passlist[$id]) && ($a_passlist[$id] === $w_list))
+ foreach ($a_passlist as $p_list) {
+ if (isset($id) && ($a_passlist[$id]) && ($a_passlist[$id] === $p_list))
continue;
- if ($w_list['name'] == $_POST['name']) {
+ if ($p_list['name'] == $_POST['name']) {
$input_errors[] = gettext("A Pass List file name with this name already exists.");
break;
}
@@ -138,30 +159,32 @@ if ($_POST['save']) {
$input_errors[] = gettext("A valid alias must be provided");
if (!$input_errors) {
- $w_list = array();
+ $p_list = array();
/* post user input */
- $w_list['name'] = $_POST['name'];
- $w_list['uuid'] = $passlist_uuid;
- $w_list['localnets'] = $_POST['localnets']? 'yes' : 'no';
- $w_list['wanips'] = $_POST['wanips']? 'yes' : 'no';
- $w_list['wangateips'] = $_POST['wangateips']? 'yes' : 'no';
- $w_list['wandnsips'] = $_POST['wandnsips']? 'yes' : 'no';
- $w_list['vips'] = $_POST['vips']? 'yes' : 'no';
- $w_list['vpnips'] = $_POST['vpnips']? 'yes' : 'no';
-
- $w_list['address'] = $_POST['address'];
- $w_list['descr'] = mb_convert_encoding($_POST['descr'],"HTML-ENTITIES","auto");
- $w_list['detail'] = $final_address_details;
+ $p_list['name'] = $_POST['name'];
+ $p_list['uuid'] = $passlist_uuid;
+ $p_list['localnets'] = $_POST['localnets']? 'yes' : 'no';
+ $p_list['wanips'] = $_POST['wanips']? 'yes' : 'no';
+ $p_list['wangateips'] = $_POST['wangateips']? 'yes' : 'no';
+ $p_list['wandnsips'] = $_POST['wandnsips']? 'yes' : 'no';
+ $p_list['vips'] = $_POST['vips']? 'yes' : 'no';
+ $p_list['vpnips'] = $_POST['vpnips']? 'yes' : 'no';
+
+ $p_list['address'] = $_POST['address'];
+ $p_list['descr'] = mb_convert_encoding(str_replace("\r\n", "\n", $_POST['descr']),"HTML-ENTITIES","auto");
+ $p_list['detail'] = $final_address_details;
if (isset($id) && $a_passlist[$id])
- $a_passlist[$id] = $w_list;
+ $a_passlist[$id] = $p_list;
else
- $a_passlist[] = $w_list;
+ $a_passlist[] = $p_list;
- write_config("Snort pkg: modified PASS LIST {$w_list['name']}.");
+ 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;
@@ -188,24 +211,29 @@ if ($savemsg)
<form action="suricata_passlist_edit.php" method="post" name="iform" id="iform">
<input name="id" type="hidden" value="<?=$id;?>" />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $tab_array[] = array(gettext("Blocks"), false, "/suricata/suricata_blocked.php");
$tab_array[] = array(gettext("Pass Lists"), true, "/suricata/suricata_passlist.php");
$tab_array[] = array(gettext("Suppress"), false, "/suricata/suricata_suppress.php");
- $tab_array[] = array(gettext("Logs Browser"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php?instance={$instanceid}");
$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>
<tr><td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tbody>
<tr>
<td colspan="2" valign="top" class="listtopic"><?php echo gettext("Add the name and " .
"description of the file."); ?></td>
@@ -281,8 +309,8 @@ if ($savemsg)
</td>
<td width="78%" class="vtable">
<input autocomplete="off" name="address" type="text" class="formfldalias" id="address" size="30" value="<?=htmlspecialchars($pconfig['address']);?>"
- title="<?=trim(filter_expand_alias($pconfig['address']));?>"/>
- &nbsp;&nbsp;&nbsp;&nbsp;<input type="button" class="formbtns" value="Aliases" onclick="parent.location='suricata_select_alias.php?id=0&type=host|network&varname=address&act=import&multi_ip=yes&returl=<?=urlencode($_SERVER['PHP_SELF']);?>'"
+ title="<?=trim(filter_expand_alias($pconfig['address']));?>"/>&nbsp;&nbsp;&nbsp;&nbsp;
+ <input type="button" class="formbtns" value="Aliases" onclick="selectAlias();"
title="<?php echo gettext("Select an existing IP alias");?>"/>
</td>
</tr>
@@ -293,9 +321,10 @@ if ($savemsg)
<input id="cancel" name="cancel" type="submit" class="formbtn" value="Cancel" />
</td>
</tr>
+ </tbody>
</table>
</div>
-</td></tr>
+</td></tr></tbody>
</table>
</form>
<script type="text/javascript">
@@ -321,6 +350,29 @@ function createAutoSuggest() {
?>
}
+function selectAlias() {
+
+ var loc;
+ var fields = [ "name", "descr", "localnets", "wanips", "wangateips", "wandnsips", "vips", "vpnips", "address" ];
+
+ // Scrape current form field values and add to
+ // the select alias URL as a query string.
+ var loc = '/suricata/suricata_select_alias.php?id=<?=$id;?>&act=import&type=host|network';
+ loc = loc + '&varname=address&multi_ip=yes';
+ loc = loc + '&returl=<?=urlencode($_SERVER['PHP_SELF']);?>';
+ loc = loc + '&uuid=<?=$passlist_uuid;?>';
+
+ // Iterate over just the specific form fields we want to pass to
+ // the select alias URL.
+ fields.forEach(function(entry) {
+ var tmp = $(entry).serialize();
+ if (tmp.length > 0)
+ loc = loc + '&' + tmp;
+ });
+
+ window.parent.location = loc;
+}
+
setTimeout("createAutoSuggest();", 500);
</script>
diff --git a/config/suricata/suricata_post_install.php b/config/suricata/suricata_post_install.php
index c44b392f..070cf095 100644
--- a/config/suricata/suricata_post_install.php
+++ b/config/suricata/suricata_post_install.php
@@ -48,10 +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_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 the inc file *
+ * is cached and used instead of the *
+ * updated version included with the *
+ * updated GUI package. *
+ ****************************************/
+if (!defined('SURICATA_PBI_BASEDIR'))
+ define('SURICATA_PBI_BASEDIR', '/usr/pbi/suricata-' . php_uname("m"));
+
+/****************************************
+ * 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 = SURICATA_ENFORCING_RULES_FILENAME;
$rcdir = RCFILEPREFIX;
// Hard kill any running Suricata process that may have been started by any
@@ -60,60 +86,131 @@ if(is_process_running("suricata")) {
killbyname("suricata");
sleep(2);
// Delete any leftover suricata PID files in /var/run
- unlink_if_exists("/var/run/suricata_*.pid");
+ unlink_if_exists("{$g['varrun_path']}/suricata_*.pid");
}
// Hard kill any running Barnyard2 processes
if(is_process_running("barnyard")) {
killbyname("barnyard2");
sleep(2);
// Delete any leftover barnyard2 PID files in /var/run
- unlink_if_exists("/var/run/barnyard2_*.pid");
+ unlink_if_exists("{$g['varrun_path']}/barnyard2_*.pid");
}
// Set flag for post-install in progress
$g['suricata_postinstall'] = true;
+// Mount file system read/write so we can modify some files
+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);
-// remake saved settings
+// Create the IP Rep and SID Mods lists directory
+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') {
log_error(gettext("[Suricata] Saved settings detected... rebuilding installation with saved settings..."));
update_status(gettext("Saved settings detected..."));
+
+ /****************************************************************/
+ /* Do test and fix for duplicate UUIDs if this install was */
+ /* impacted by the DUP (clone) bug that generated a duplicate */
+ /* UUID for the cloned interface. Also fix any duplicate */
+ /* entries in ['rulesets'] for "dns-events.rules". */
+ /****************************************************************/
+ if (count($config['installedpackages']['suricata']['rule']) > 0) {
+ $uuids = array();
+ $suriconf = &$config['installedpackages']['suricata']['rule'];
+ foreach ($suriconf as &$suricatacfg) {
+ // Remove any duplicate ruleset names from earlier bug
+ $rulesets = explode("||", $suricatacfg['rulesets']);
+ $suricatacfg['rulesets'] = implode("||", array_keys(array_flip($rulesets)));
+
+ // Now check for and fix a duplicate UUID
+ $if_real = get_real_interface($suricatacfg['interface']);
+ if (!isset($uuids[$suricatacfg['uuid']])) {
+ $uuids[$suricatacfg['uuid']] = $if_real;
+ continue;
+ }
+ else {
+ // Found a duplicate UUID, so generate a
+ // new one for the affected interface.
+ $old_uuid = $suricatacfg['uuid'];
+ $new_uuid = suricata_generate_id();
+ if (file_exists("{$suricatalogdir}suricata_{$if_real}{$old_uuid}/"))
+ @rename("{$suricatalogdir}suricata_{$if_real}{$old_uuid}/", "{$suricatalogdir}suricata_{$if_real}{$new_uuid}/");
+ $suricatacfg['uuid'] = $new_uuid;
+ $uuids[$new_uuid] = $if_real;
+ log_error(gettext("[Suricata] updated UUID for interface " . convert_friendly_interface_to_friendly_descr($suricatacfg['interface']) . " from {$old_uuid} to {$new_uuid}."));
+ }
+ }
+ unset($uuids, $rulesets);
+ }
+ /****************************************************************/
+ /* End of duplicate UUID and "dns-events.rules" bug fix. */
+ /****************************************************************/
+
+ /* Do one-time settings migration for new version configuration */
+ update_output_window(gettext("Please wait... migrating settings to new configuration..."));
+ include('/usr/local/pkg/suricata/suricata_migrate_config.php');
update_output_window(gettext("Please wait... rebuilding installation with saved settings..."));
log_error(gettext("[Suricata] Downloading and updating configured rule types..."));
update_output_window(gettext("Please wait... downloading and updating configured rule types..."));
if ($pkg_interface <> "console")
$suricata_gui_include = true;
- include('/usr/local/www/suricata/suricata_check_for_rule_updates.php');
+ 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'];
- foreach ($suriconf as $value) {
- $if_real = get_real_interface($value['interface']);
-
- // ## BETA pkg bug fix-up -- be sure default rules enabled ##
- $rules = explode("||", $value['rulesets']);
- foreach (array( "decoder-events.rules", "files.rules", "http-events.rules", "smtp-events.rules", "stream-events.rules", "tls-events.rules" ) as $r){
- if (!in_array($r, $rules))
- $rules[] = $r;
- }
- natcasesort($rules);
- $value['rulesets'] = implode("||", $rules);
- write_config();
- // ## end of BETA pkg bug fix-up ##
+ foreach ($suriconf as $suricatacfg) {
+ $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']) . "..."));
- // create a suricata.yaml file for interface
- suricata_generate_yaml($value);
+ // Pull in the PHP code that generates the suricata.yaml file
+ // variables that will be substituted further down below.
+ include("/usr/local/pkg/suricata/suricata_generate_yaml.php");
+
+ // Pull in the boilerplate template for the suricata.yaml
+ // configuration file. The contents of the template along
+ // with substituted variables are stored in $suricata_conf_text
+ // (which is defined in the included file).
+ include("/usr/local/pkg/suricata/suricata_yaml_template.inc");
+
+ // Now write out the conf file using $suricata_conf_text contents
+ @file_put_contents("{$suricatacfgdir}/suricata.yaml", $suricata_conf_text);
+ unset($suricata_conf_text);
// create barnyard2.conf file for interface
- if ($value['barnyard_enable'] == 'on')
- suricata_generate_barnyard2_conf($value, $if_real);
+ if ($suricatacfg['barnyard_enable'] == 'on')
+ suricata_generate_barnyard2_conf($suricatacfg, $if_real);
}
// create Suricata bootup file suricata.sh
@@ -124,32 +221,45 @@ 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']))
- $config['widgets']['sequence'] .= "," . $config['installedpackages']['suricata']['config'][0]['dashboard_widget'];
- if (!empty($config['installedpackages']['suricata']['config'][0]['dashboard_widget_rows']) && !empty($config['widgets']))
- $config['widgets']['widget_suricata_display_lines'] = $config['installedpackages']['suricata']['config'][0]['dashboard_widget_rows'];
+ if (!empty($config['installedpackages']['suricata']['config'][0]['dashboard_widget']) && !empty($config['widgets']['sequence'])) {
+ if (strpos($config['widgets']['sequence'], "suricata_alerts-container") === FALSE)
+ $config['widgets']['sequence'] .= "," . $config['installedpackages']['suricata']['config'][0]['dashboard_widget'];
+ }
+ if (!empty($config['installedpackages']['suricata']['config'][0]['dashboard_widget_rows']) && !empty($config['widgets'])) {
+ if (empty($config['widgets']['widget_suricata_display_lines']))
+ $config['widgets']['widget_suricata_display_lines'] = $config['installedpackages']['suricata']['config'][0]['dashboard_widget_rows'];
+ }
$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..."));
- start_service("suricata");
- 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");
}
}
+// If this is first install and "forcekeepsettings" is empty,
+// then default it to 'on'.
+if (empty($config['installedpackages']['suricata']['config'][0]['forcekeepsettings']))
+ $config['installedpackages']['suricata']['config'][0]['forcekeepsettings'] = 'on';
+
+// Finished with file system mods, so remount it read-only
+conf_mount_ro();
+
// Update Suricata package version in configuration
-$config['installedpackages']['suricata']['config'][0]['suricata_config_ver'] = "v1.0.1";
-write_config();
+$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 82bb33eb..480bf3dc 100644
--- a/config/suricata/suricata_rules.php
+++ b/config/suricata/suricata_rules.php
@@ -41,7 +41,7 @@
require_once("guiconfig.inc");
require_once("/usr/local/pkg/suricata/suricata.inc");
-global $g, $rebuild_rules;
+global $g, $config, $rebuild_rules;
$suricatadir = SURICATADIR;
$rules_map = array();
@@ -107,9 +107,27 @@ $emergingdownload = $config['installedpackages']['suricata']['config'][0]['enabl
$etpro = $config['installedpackages']['suricata']['config'][0]['enable_etpro_rules'];
$categories = explode("||", $pconfig['rulesets']);
-// Add any previously saved rules files to the categories array
-if (!empty($pconfig['rulesets']))
- $categories = explode("||", $pconfig['rulesets']);
+// Get any automatic rule category enable/disable modifications
+// if auto-SID Mgmt is enabled, and adjust the available rulesets
+// in the CATEGORY drop-down box as necessary.
+$cat_mods = suricata_sid_mgmt_auto_categories($a_rule[$id], FALSE);
+foreach ($cat_mods as $k => $v) {
+ switch ($v) {
+ case 'disabled':
+ if (($key = array_search($k, $categories)) !== FALSE)
+ unset($categories[$key]);
+ break;
+
+ case 'enabled':
+ if (!in_array($k, $categories))
+ $categories[] = $k;
+ break;
+
+ default:
+ break;
+ }
+}
+
if ($_GET['openruleset'])
$currentruleset = htmlspecialchars($_GET['openruleset'], ENT_QUOTES | ENT_HTML401);
@@ -148,7 +166,10 @@ if ($currentruleset != 'custom.rules') {
$rules_map = suricata_load_rules_map($rulefile);
}
-/* Load up our enablesid and disablesid arrays with enabled or disabled SIDs */
+/* Process the current category rules through any auto SID MGMT changes if enabled */
+suricata_auto_sid_mgmt($rules_map, $a_rule[$id], FALSE);
+
+/* Load up our enablesid and disablesid arrays with manually enabled or disabled SIDs */
$enablesid = suricata_load_sid_mods($a_rule[$id]['rule_sid_on']);
$disablesid = suricata_load_sid_mods($a_rule[$id]['rule_sid_off']);
@@ -159,12 +180,16 @@ if ($_POST['toggle'] && is_numeric($_POST['sid']) && is_numeric($_POST['gid']) &
$sid = $_POST['sid'];
// See if the target SID is in our list of modified SIDs,
- // and toggle it back to default if present; otherwise,
+ // and toggle it opposite state if present; otherwise,
// add it to the appropriate modified SID list.
- if (isset($enablesid[$gid][$sid]))
+ if (isset($enablesid[$gid][$sid])) {
unset($enablesid[$gid][$sid]);
- elseif (isset($disablesid[$gid][$sid]))
+ $disablesid[$gid][$sid] = "disablesid";
+ }
+ elseif (isset($disablesid[$gid][$sid])) {
unset($disablesid[$gid][$sid]);
+ $enablesid[$gid][$sid] = "enablesid";
+ }
else {
if ($rules_map[$gid][$sid]['disabled'] == 1)
$enablesid[$gid][$sid] = "enablesid";
@@ -198,8 +223,12 @@ if ($_POST['toggle'] && is_numeric($_POST['sid']) && is_numeric($_POST['gid']) &
unset($a_rule[$id]['rule_sid_off']);
/* Update the config.xml file. */
- write_config();
+ write_config("Suricata pkg: modified state for rule {$gid}:{$sid} on {$a_rule[$id]['interface']}.");
+
+ // We changed a rule state, remind user to apply the changes
+ mark_subsystem_dirty('suricata_rules');
+ // Set a scroll-to anchor location
$anchor = "rule_{$gid}_{$sid}";
}
elseif ($_POST['disable_all'] && !empty($rules_map)) {
@@ -238,7 +267,10 @@ elseif ($_POST['disable_all'] && !empty($rules_map)) {
else
unset($a_rule[$id]['rule_sid_off']);
- write_config();
+ // We changed a rule state, remind user to apply the changes
+ mark_subsystem_dirty('suricata_rules');
+
+ write_config("Suricata pkg: disabled all rules in category {$currentruleset} for {$a_rule[$id]['interface']}.");
}
elseif ($_POST['enable_all'] && !empty($rules_map)) {
@@ -275,7 +307,10 @@ elseif ($_POST['enable_all'] && !empty($rules_map)) {
else
unset($a_rule[$id]['rule_sid_off']);
- write_config();
+ // We changed a rule state, remind user to apply the changes
+ mark_subsystem_dirty('suricata_rules');
+
+ write_config("Suricata pkg: enable all rules in category {$currentruleset} for {$a_rule[$id]['interface']}.");
}
elseif ($_POST['resetcategory'] && !empty($rules_map)) {
@@ -314,7 +349,10 @@ elseif ($_POST['resetcategory'] && !empty($rules_map)) {
else
unset($a_rule[$id]['rule_sid_off']);
- write_config();
+ // We changed a rule state, remind user to apply the changes
+ mark_subsystem_dirty('suricata_rules');
+
+ write_config("Suricata pkg: remove enablesid/disablesid changes for category {$currentruleset} on {$a_rule[$id]['interface']}.");
}
elseif ($_POST['resetall'] && !empty($rules_map)) {
@@ -322,51 +360,73 @@ elseif ($_POST['resetall'] && !empty($rules_map)) {
unset($a_rule[$id]['rule_sid_on']);
unset($a_rule[$id]['rule_sid_off']);
+ // We changed a rule state, remind user to apply the changes
+ mark_subsystem_dirty('suricata_rules');
+
/* Update the config.xml file. */
- write_config();
+ write_config("Suricata pkg: remove all enablesid/disablesid changes for {$a_rule[$id]['interface']}.");
}
elseif ($_POST['clear']) {
unset($a_rule[$id]['customrules']);
- write_config();
+ write_config("Suricata pkg: clear all custom rules for {$a_rule[$id]['interface']}.");
$rebuild_rules = true;
+ conf_mount_rw();
suricata_generate_yaml($a_rule[$id]);
+ conf_mount_ro();
$rebuild_rules = false;
$pconfig['customrules'] = '';
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
}
elseif ($_POST['cancel']) {
$pconfig['customrules'] = base64_decode($a_rule[$id]['customrules']);
+ clear_subsystem_dirty('suricata_rules');
}
elseif ($_POST['save']) {
$pconfig['customrules'] = $_POST['customrules'];
if ($_POST['customrules'])
- $a_rule[$id]['customrules'] = base64_encode($_POST['customrules']);
+ $a_rule[$id]['customrules'] = base64_encode(str_replace("\r\n", "\n", $_POST['customrules']));
else
unset($a_rule[$id]['customrules']);
- write_config();
+ write_config("Suricata pkg: save modified custom rules for {$a_rule[$id]['interface']}.");
$rebuild_rules = true;
+ conf_mount_rw();
suricata_generate_yaml($a_rule[$id]);
+ conf_mount_ro();
$rebuild_rules = false;
/* Signal Suricata to "live reload" the rules */
suricata_reload_config($a_rule[$id]);
+ clear_subsystem_dirty('suricata_rules');
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
}
elseif ($_POST['apply']) {
/* Save new configuration */
- write_config();
+ write_config("Suricata pkg: new rules configuration for {$a_rule[$id]['interface']}.");
/*************************************************/
/* Update the suricata.yaml file and rebuild the */
/* rules for this interface. */
/*************************************************/
$rebuild_rules = true;
+ conf_mount_rw();
suricata_generate_yaml($a_rule[$id]);
+ conf_mount_ro();
$rebuild_rules = false;
/* Signal Suricata to "live reload" the rules */
suricata_reload_config($a_rule[$id]);
+
+ // We have saved changes and done a soft restart, so clear "dirty" flag
+ clear_subsystem_dirty('suricata_rules');
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
}
-require_once("guiconfig.inc");
include_once("head.inc");
$if_friendly = convert_friendly_interface_to_friendly_descr($pconfig['interface']);
@@ -392,19 +452,28 @@ if ($savemsg) {
<input type='hidden' name='openruleset' id='openruleset' value='<?=$currentruleset;?>'/>
<input type='hidden' name='sid' id='sid' value=''/>
<input type='hidden' name='gid' id='gid' value=''/>
+
+<?php if (is_subsystem_dirty('suricata_rules')): ?><p>
+<?php print_info_box_np(gettext("A change has been made to a rule state.") . "<br/>" . gettext("Click APPLY when finished to send the changes to the running configuration."));?>
+<?php endif; ?>
+
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.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("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $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">';
@@ -417,11 +486,13 @@ 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>
<tr><td><div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="4" cellspacing="0">
+ <tbody>
<tr>
<td class="listtopic"><?php echo gettext("Available Rule Categories"); ?></td>
</tr>
@@ -430,7 +501,7 @@ if ($savemsg) {
<select id="selectbox" name="selectbox" class="formselect" onChange="go();">
<option value='custom.rules'>custom.rules</option>
<?php
- $files = explode("||", $pconfig['rulesets']);
+ $files = $categories;
if ($a_rule[$id]['ips_policy_enable'] == 'on')
$files[] = "IPS Policy - " . ucfirst($a_rule[$id]['ips_policy']);
if ($a_rule[$id]['autoflowbitrules'] == 'on')
@@ -478,6 +549,7 @@ if ($savemsg) {
<tr>
<td class="vncell">
<table width="100%" align="center" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
<tr>
<td rowspan="5" width="48%" valign="middle"><input type="submit" name="apply" id="apply" value="<?php echo gettext("Apply"); ?>" class="formbtn"
title="<?php echo gettext("Click to rebuild the rules with your changes"); ?>"/><br/><br/>
@@ -534,6 +606,7 @@ if ($savemsg) {
gettext("clicking here") . ".</a>";?></td>
</tr>
<?php endif;?>
+ </tbody>
</table>
</td>
</tr>
@@ -544,7 +617,7 @@ if ($savemsg) {
<td>
<table id="myTable" class="sortable" style="table-layout: fixed;" width="100%" border="0" cellpadding="0" cellspacing="0">
<colgroup>
- <col width="14" align="left" valign="middle">
+ <col width="16" align="center" valign="middle">
<col width="6%" align="center" axis="number">
<col width="9%" align="center" axis="number">
<col width="52" align="center" axis="string">
@@ -555,8 +628,8 @@ if ($savemsg) {
<col axis="string">
</colgroup>
<thead>
- <tr>
- <th class="list">&nbsp;</th>
+ <tr class="sortableHeaderRowIdentifier">
+ <th class="list sorttable_nosort">&nbsp;</th>
<th class="listhdrr"><?php echo gettext("GID"); ?></th>
<th class="listhdrr"><?php echo gettext("SID"); ?></th>
<th class="listhdrr"><?php echo gettext("Proto"); ?></th>
@@ -570,18 +643,36 @@ if ($savemsg) {
<tbody>
<?php
- $counter = $enable_cnt = $disable_cnt = 0;
+ $counter = $enable_cnt = $disable_cnt = $user_enable_cnt = $user_disable_cnt = $managed_count = 0;
foreach ($rules_map as $k1 => $rulem) {
foreach ($rulem as $k2 => $v) {
$sid = suricata_get_sid($v['rule']);
$gid = suricata_get_gid($v['rule']);
-
- if (isset($disablesid[$gid][$sid])) {
+ $ruleset = $currentruleset;
+ $style = "";
+
+ if ($v['managed'] == 1) {
+ if ($v['disabled'] == 1) {
+ $textss = "<span class=\"gray\">";
+ $textse = "</span>";
+ $style= "style=\"opacity: 0.4; filter: alpha(opacity=40);\"";
+ $title = gettext("Auto-disabled by settings on SID Mgmt tab");
+ }
+ else {
+ $textss = $textse = "";
+ $ruleset = "suricata.rules";
+ $title = gettext("Auto-managed by settings on SID Mgmt tab");
+ }
+ $iconb = "icon_advanced.gif";
+ $managed_count++;
+ }
+ elseif (isset($disablesid[$gid][$sid])) {
$textss = "<span class=\"gray\">";
$textse = "</span>";
$iconb = "icon_reject_d.gif";
$disable_cnt++;
- $title = gettext("Disabled by user. Click to toggle to default state");
+ $user_disable_cnt++;
+ $title = gettext("Disabled by user. Click to toggle to enabled state");
}
elseif (($v['disabled'] == 1) && (!isset($enablesid[$gid][$sid]))) {
$textss = "<span class=\"gray\">";
@@ -594,7 +685,8 @@ if ($savemsg) {
$textss = $textse = "";
$iconb = "icon_reject.gif";
$enable_cnt++;
- $title = gettext("Enabled by user. Click to toggle to default state");
+ $user_enable_cnt++;
+ $title = gettext("Enabled by user. Click to toggle to disabled state");
}
else {
$textss = $textse = "";
@@ -623,36 +715,44 @@ if ($savemsg) {
$message = suricata_get_msg($v['rule']);
$sid_tooltip = gettext("View the raw text for this rule");
- echo "<tr><td class=\"listt\" align=\"left\" valign=\"middle\" sorttable_customkey=\"\">{$textss}
- <a id=\"rule_{$gid}_{$sid}\" href='#'><input type=\"image\" onClick=\"document.getElementById('sid').value='{$sid}';
- document.getElementById('gid').value='{$gid}';\"
- src=\"../themes/{$g['theme']}/images/icons/{$iconb}\" width=\"11\" height=\"11\" border=\"0\"
- title='{$title}' name=\"toggle[]\"/></a>{$textse}
- </td>
- <td class=\"listr\" style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ echo "<tr><td class=\"listt\" style=\"align:center;\" valign=\"middle\">{$textss}";
+
+ if ($v['managed'] == 1) {
+ echo "<img {$style} src=\"../themes/{$g['theme']}/images/icons/{$iconb}\" width=\"11\" height=\"11\" border=\"0\"
+ title='{$title}'/>{$textse}";
+ }
+ else {
+ echo "<a id=\"rule_{$gid}_{$sid}\" href='#'><input type=\"image\" onClick=\"document.getElementById('sid').value='{$sid}';
+ document.getElementById('gid').value='{$gid}';\"
+ src=\"../themes/{$g['theme']}/images/icons/{$iconb}\" width=\"11\" height=\"11\" border=\"0\"
+ title='{$title}' name=\"toggle[]\"/></a>{$textse}";
+ }
+ echo "</td>
+
+ <td class=\"listr\" style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
{$textss}{$gid}{$textse}
</td>
- <td class=\"listr\" style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ <td class=\"listr\" style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
<a href=\"javascript: void(0)\"
- onclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\"
+ onclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\"
title='{$sid_tooltip}'>{$textss}{$sid}{$textse}</a>
</td>
- <td class=\"listr\" style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ <td class=\"listr\" style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
{$textss}{$protocol}{$textse}
</td>
- <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
{$srcspan}{$source}</span>
</td>
- <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
{$srcprtspan}{$source_port}</span>
</td>
- <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
{$dstspan}{$destination}</span>
</td>
- <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ <td class=\"listr ellipsis\" nowrap style=\"text-align:center;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
{$dstprtspan}{$destination_port}</span>
</td>
- <td class=\"listbg\" style=\"word-wrap:break-word; whitespace:pre-line;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$currentruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
+ <td class=\"listbg\" style=\"word-wrap:break-word; whitespace:pre-line;\" ondblclick=\"wopen('suricata_rules_edit.php?id={$id}&openruleset={$ruleset}&sid={$sid}&gid={$gid}','FileViewer',800,600);\">
{$textss}{$message}{$textse}
</td>
</tr>";
@@ -667,13 +767,17 @@ if ($savemsg) {
<tr>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="1">
+ <tbody>
<tr>
<td width="16"></td>
<td class="vexpl" height="35" valign="top">
<strong><?php echo gettext("--- Category Rules Summary ---") . "</strong><br/>" .
gettext("Total Rules: {$counter}") . "&nbsp;&nbsp;&nbsp;&nbsp;" .
gettext("Enabled: {$enable_cnt}") . "&nbsp;&nbsp;&nbsp;&nbsp;" .
- gettext("Disabled: {$disable_cnt}"); ?></td>
+ gettext("Disabled: {$disable_cnt}") . "&nbsp;&nbsp;&nbsp;&nbsp;" .
+ gettext("User Enabled: {$user_enable_cnt}") . "&nbsp;&nbsp;&nbsp;&nbsp;" .
+ gettext("User Disabled: {$user_disable_cnt}") . "&nbsp;&nbsp;&nbsp;&nbsp;" .
+ gettext("Auto-Managed: {$managed_count}"); ?></td>
</tr>
<tr>
<td width="16"><img src="../themes/<?= $g['theme']; ?>/images/icons/icon_block.gif"
@@ -695,14 +799,29 @@ if ($savemsg) {
width="11" height="11"></td>
<td nowrap><?php echo gettext("Rule changed to Disabled by user"); ?></td>
</tr>
+ <?php if (!empty($cat_mods)): ?>
+ <tr>
+ <td width="16"><img src="../themes/<?= $g['theme']; ?>/images/icons/icon_advanced.gif"
+ width="11" height="11"></td>
+ <td nowrap><?php echo gettext("Rule auto-enabled by files configured on SID Mgmt tab"); ?></td>
+ </tr>
+ <tr>
+ <td width="16"><img style="opacity: 0.4; filter: alpha(opacity=40);" src="../themes/<?= $g['theme']; ?>/images/icons/icon_advanced.gif"
+ width="11" height="11"></td>
+ <td nowrap><?php echo gettext("Rule auto-disabled by files configured on SID Mgmt tab"); ?></td>
+ </tr>
+ <?php endif; ?>
+ </tbody>
</table>
</td>
</tr>
<?php endif;?>
+ </tbody>
</table>
</div>
</td>
</tr>
+ </tbody>
</table>
</form>
<script language="javascript" type="text/javascript">
diff --git a/config/suricata/suricata_rules_edit.php b/config/suricata/suricata_rules_edit.php
index 0a4bd62a..8329272f 100644
--- a/config/suricata/suricata_rules_edit.php
+++ b/config/suricata/suricata_rules_edit.php
@@ -73,6 +73,8 @@ $wrap_flag = "off";
// Correct displayed file title if necessary
if ($file == "Auto-Flowbit Rules")
$displayfile = FLOWBITS_FILENAME;
+elseif ($file == "suricata.rules")
+ $displayfile = "Currently Active Rules";
else
$displayfile = $file;
@@ -102,6 +104,8 @@ elseif (isset($_GET['sid']) && is_numericint($_GET['sid']) && isset($_GET['gid']
// If flowbit rule, point to interface-specific file
if ($file == "Auto-Flowbit Rules")
$rules_map = suricata_load_rules_map("{$suricatacfgdir}rules/" . FLOWBITS_FILENAME);
+ elseif ($file == "suricata.rules")
+ $rules_map = suricata_load_rules_map("{$suricatacfgdir}rules/suricata.rules");
else
$rules_map = suricata_load_rules_map("{$suricatadir}rules/{$file}");
$contents = $rules_map[$_GET['gid']][trim($_GET['sid'])]['rule'];
diff --git a/config/suricata/suricata_rules_flowbits.php b/config/suricata/suricata_rules_flowbits.php
index c5193a8b..1bb945d8 100644
--- a/config/suricata/suricata_rules_flowbits.php
+++ b/config/suricata/suricata_rules_flowbits.php
@@ -65,7 +65,7 @@ if (is_null($id)) {
// Set who called us so we can return to the correct page with
// the RETURN ('cancel') button.
-if ($_POST['referrer'])
+if (isset($_POST['referrer']) && strpos($_POST['referrer'], '://'.$_SERVER['SERVER_NAME'].'/') !== FALSE)
$referrer = $_POST['referrer'];
else
$referrer = $_SERVER['HTTP_REFERER'];
@@ -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']}'.");
}
@@ -159,7 +161,6 @@ include_once("head.inc");
?>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC" >
-
<?php
include("fbegin.inc");
if ($input_errors) print_input_errors($input_errors);
@@ -227,7 +228,7 @@ if ($savemsg)
<col axis="string">
</colgroup>
<thead>
- <tr>
+ <tr class="sortableHeaderRowIdentifier">
<th class="listhdrr" axis="number"><?php echo gettext("SID"); ?></th>
<th class="listhdrr" axis="string"><?php echo gettext("Proto"); ?></th>
<th class="listhdrr" axis="string"><?php echo gettext("Source"); ?></th>
@@ -274,7 +275,7 @@ if ($savemsg)
// Use "echo" to write the table HTML row-by-row.
echo "<tr>" .
- "<td class=\"listr\" sorttable_customkey=\"{$sid}\">{$sid}&nbsp;{$supplink}</td>" .
+ "<td class=\"listr\" style=\"sorttable_customkey:{$sid};\" sorttable_customkey=\"{$sid}\">{$sid}&nbsp;{$supplink}</td>" .
"<td class=\"listr\" style=\"text-align:center;\">{$protocol}</td>" .
"<td class=\"listr ellipsis\" nowrap style=\"text-align:center;\"><span title=\"{$rule_content[2]}\">{$source}</span></td>" .
"<td class=\"listr ellipsis\" nowrap style=\"text-align:center;\"><span title=\"{$rule_content[5]}\">{$destination}</span></td>" .
diff --git a/config/suricata/suricata_rulesets.php b/config/suricata/suricata_rulesets.php
index c939ef25..7f591b6c 100644
--- a/config/suricata/suricata_rulesets.php
+++ b/config/suricata/suricata_rulesets.php
@@ -47,7 +47,7 @@ $suricatadir = SURICATADIR;
$flowbit_rules_file = FLOWBITS_FILENAME;
// Array of default events rules for Suricata
-$default_rules = array( "decoder-events.rules", "files.rules", "http-events.rules",
+$default_rules = array( "decoder-events.rules", "dns-events.rules", "files.rules", "http-events.rules",
"smtp-events.rules", "stream-events.rules", "tls-events.rules" );
if (!is_array($config['installedpackages']['suricata']['rule'])) {
@@ -63,15 +63,12 @@ if (is_null($id))
$id = 0;
if (isset($id) && $a_nat[$id]) {
- $pconfig['enable'] = $a_nat[$id]['enable'];
- $pconfig['interface'] = $a_nat[$id]['interface'];
- $pconfig['rulesets'] = $a_nat[$id]['rulesets'];
- $pconfig['autoflowbitrules'] = $a_nat[$id]['autoflowbitrules'];
+ $pconfig['autoflowbits'] = $a_nat[$id]['autoflowbitrules'];
$pconfig['ips_policy_enable'] = $a_nat[$id]['ips_policy_enable'];
$pconfig['ips_policy'] = $a_nat[$id]['ips_policy'];
}
-$if_real = get_real_interface($pconfig['interface']);
+$if_real = get_real_interface($a_nat[$id]['interface']);
$suricata_uuid = $a_nat[$id]['uuid'];
$snortdownload = $config['installedpackages']['suricata']['config'][0]['enable_vrt_rules'] == 'on' ? 'on' : 'off';
$emergingdownload = $config['installedpackages']['suricata']['config'][0]['enable_etopen_rules'] == 'on' ? 'on' : 'off';
@@ -81,6 +78,8 @@ $snortcommunitydownload = $config['installedpackages']['suricata']['config'][0][
$no_emerging_files = false;
$no_snort_files = false;
+$enabled_rulesets_array = explode("||", $a_nat[$id]['rulesets']);
+
/* Test rule categories currently downloaded to $SURICATADIR/rules and set appropriate flags */
if ($emergingdownload == 'on') {
$test = glob("{$suricatadir}rules/" . ET_OPEN_FILE_PREFIX . "*.rules");
@@ -143,27 +142,33 @@ 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();
+ write_config("Suricata pkg: save enabled rule categories for {$a_nat[$id]['interface']}.");
/*************************************************/
/* Update the suricata.yaml file and rebuild the */
/* rules for this interface. */
/*************************************************/
$rebuild_rules = true;
+ conf_mount_rw();
suricata_generate_yaml($a_nat[$id]);
+ conf_mount_ro();
$rebuild_rules = false;
/* Signal Suricata to "live reload" the rules */
suricata_reload_config($a_nat[$id]);
+
+ $pconfig = $_POST;
+ $enabled_rulesets_array = explode("||", $enabled_items);
+ if (suricata_is_running($suricata_uuid, $if_real))
+ $savemsg = gettext("Suricata is 'live-loading' the new rule set on this interface.");
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
}
elseif ($_POST['unselectall']) {
- // Remove all but the default events and files rules
- $a_nat[$id]['rulesets'] = implode("||", $default_rules);
-
if ($_POST['ips_policy_enable'] == "on") {
$a_nat[$id]['ips_policy_enable'] = 'on';
$a_nat[$id]['ips_policy'] = $_POST['ips_policy'];
@@ -173,13 +178,21 @@ elseif ($_POST['unselectall']) {
unset($a_nat[$id]['ips_policy']);
}
- write_config();
- sync_suricata_package_config();
+ $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'] == "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']) {
- // Start with the required default events and files rules
- $rulesets = $default_rules;
-
if ($_POST['ips_policy_enable'] == "on") {
$a_nat[$id]['ips_policy_enable'] = 'on';
$a_nat[$id]['ips_policy'] = $_POST['ips_policy'];
@@ -189,39 +202,45 @@ elseif ($_POST['selectall']) {
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;
+
if ($emergingdownload == 'on') {
$files = glob("{$suricatadir}rules/" . ET_OPEN_FILE_PREFIX . "*.rules");
foreach ($files as $file)
- $rulesets[] = basename($file);
+ $enabled_rulesets_array[] = basename($file);
}
elseif ($etpro == 'on') {
$files = glob("{$suricatadir}rules/" . ET_PRO_FILE_PREFIX . "*.rules");
foreach ($files as $file)
- $rulesets[] = basename($file);
+ $enabled_rulesets_array[] = basename($file);
}
if ($snortcommunitydownload == 'on') {
$files = glob("{$suricatadir}rules/" . GPL_FILE_PREFIX . "community.rules");
foreach ($files as $file)
- $rulesets[] = basename($file);
+ $enabled_rulesets_array[] = basename($file);
}
/* Include the Snort VRT rules only if enabled and no IPS policy is set */
- if ($snortdownload == 'on' && $a_nat[$id]['ips_policy_enable'] == 'off') {
+ if ($snortdownload == 'on' && empty($_POST['ips_policy_enable'])) {
$files = glob("{$suricatadir}rules/" . VRT_FILE_PREFIX . "*.rules");
foreach ($files as $file)
- $rulesets[] = basename($file);
+ $enabled_rulesets_array[] = basename($file);
}
-
- $a_nat[$id]['rulesets'] = implode("||", $rulesets);
-
- write_config();
- sync_suricata_package_config();
}
+// Get any automatic rule category enable/disable modifications
+// if auto-SID Mgmt is enabled.
+$cat_mods = suricata_sid_mgmt_auto_categories($a_nat[$id], FALSE);
+
// See if we have any Auto-Flowbit rules and enable
// the VIEW button if we do.
-if ($a_nat[$id]['autoflowbitrules'] == 'on') {
+if ($pconfig['autoflowbits'] == 'on') {
if (file_exists("{$suricatadir}suricata_{$suricata_uuid}_{$if_real}/rules/{$flowbit_rules_file}") &&
filesize("{$suricatadir}suricata_{$suricata_uuid}_{$if_real}/rules/{$flowbit_rules_file}") > 0) {
$btn_view_flowb_rules = " title=\"" . gettext("View flowbit-required rules") . "\"";
@@ -232,9 +251,7 @@ if ($a_nat[$id]['autoflowbitrules'] == 'on') {
else
$btn_view_flowb_rules = " disabled";
-$enabled_rulesets_array = explode("||", $a_nat[$id]['rulesets']);
-
-$if_friendly = convert_friendly_interface_to_friendly_descr($pconfig['interface']);
+$if_friendly = convert_friendly_interface_to_friendly_descr($a_nat[$id]['interface']);
$pgtitle = gettext("Suricata IDS: Interface {$if_friendly} - Categories");
include_once("head.inc");
?>
@@ -258,18 +275,22 @@ if ($savemsg) {
<form action="suricata_rulesets.php" method="post" name="iform" id="iform">
<input type="hidden" name="id" id="id" value="<?=$id;?>" />
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.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("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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 Browser"), false, "/suricata/suricata_logs_browser.php?instance={$id}");
+ $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">';
@@ -282,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>
@@ -289,6 +311,7 @@ if ($savemsg) {
<td>
<div id="mainarea">
<table id="maintable" class="tabcont" width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
<?php
$isrulesfolderempty = glob("{$suricatadir}rules/*.rules");
$iscfgdirempty = array();
@@ -307,18 +330,19 @@ if ($savemsg) {
<?php else: ?>
<tr>
<td>
- <table width="100%" border="0"
- cellpadding="0" cellspacing="0">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tbody>
<tr>
<td colspan="4" class="listtopic"><?php echo gettext("Automatic flowbit resolution"); ?><br/></td>
</tr>
<tr>
- <td colspan="4" valign="center" class="listn">
+ <td colspan="4" style="vertical-align: middle;" class="listn">
<table width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
<td width="15%" class="listn"><?php echo gettext("Resolve Flowbits"); ?></td>
<td width="85%"><input name="autoflowbits" id="autoflowbitrules" type="checkbox" value="on"
- <?php if ($a_nat[$id]['autoflowbitrules'] == "on" || empty($a_nat[$id]['autoflowbitrules'])) echo "checked"; ?>/>
+ <?php if ($pconfig['autoflowbits'] == "on" || empty($pconfig['autoflowbits'])) echo "checked"; ?>/>
&nbsp;&nbsp;<span class="vexpl"><?php echo gettext("If checked, Suricata will auto-enable rules required for checked flowbits. ");
echo gettext("The Default is "); ?><strong><?php echo gettext("Checked."); ?></strong></span></td>
</tr>
@@ -340,6 +364,7 @@ if ($savemsg) {
<?php echo "<span class=\"red\"><strong>" . gettext("Note: ") . "</strong></span>" . gettext("Auto-enabled rules generating unwanted alerts should have their GID:SID added to the Suppression List for the interface."); ?>
<br/></td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -349,8 +374,9 @@ if ($savemsg) {
<td colspan="4" class="listtopic"><?php echo gettext("Snort IPS Policy selection"); ?><br/></td>
</tr>
<tr>
- <td colspan="4" valign="center" class="listn">
+ <td colspan="4" style="vertical-align: middle;" class="listn">
<table width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
<tr>
<td width="15%" class="listn"><?php echo gettext("Use IPS Policy"); ?></td>
<td width="85%"><input name="ips_policy_enable" id="ips_policy_enable" type="checkbox" value="on" <?php if ($a_nat[$id]['ips_policy_enable'] == "on") echo "checked"; ?>
@@ -365,7 +391,9 @@ if ($savemsg) {
"although Emerging Threats categories may still be selected if enabled on the Global Settings tab. " .
"These will be added to the pre-defined Snort IPS policy rules from the Snort VRT."); ?><br/></td>
</tr>
- <tr id="ips_row1">
+ </tbody>
+ <tbody id="ips_controls">
+ <tr>
<td width="15%" class="listn"><?php echo gettext("IPS Policy Selection"); ?></td>
<td width="85%"><select name="ips_policy" class="formselect" <?=$policy_select_disable?> >
<option value="connectivity" <?php if ($pconfig['ips_policy'] == "connected") echo "selected"; ?>><?php echo gettext("Connectivity"); ?></option>
@@ -374,7 +402,7 @@ if ($savemsg) {
</select>
&nbsp;&nbsp;<span class="vexpl"><?php echo gettext("Snort IPS policies are: Connectivity, Balanced or Security."); ?></span></td>
</tr>
- <tr id="ips_row2">
+ <tr>
<td width="15%">&nbsp;</td>
<td width="85%">
<?php echo gettext("Connectivity blocks most major threats with few or no false positives. " .
@@ -383,6 +411,7 @@ if ($savemsg) {
"Security is a stringent policy. It contains everything in the first two " .
"plus policy-type rules such as Flash in an Excel file."); ?><br/></td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -392,15 +421,27 @@ if ($savemsg) {
</tr>
<tr>
<td colspan="4">
- <table width=90% align="center" border="0" cellpadding="2" cellspacing="0">
- <tr height="45px">
- <td valign="middle"><input value="Select All" class="formbtns" type="submit" name="selectall" id="selectall" title="<?php echo gettext("Add all to enforcing rules"); ?>"/></td>
- <td valign="middle"><input value="Unselect All" class="formbtns" type="submit" name="unselectall" id="unselectall" title="<?php echo gettext("Remove all from enforcing rules"); ?>"/></td>
- <td valign="middle"><input value=" Save " class="formbtns" type="submit" name="save" id="save" title="<?php echo gettext("Save changes to enforcing rules and rebuild"); ?>"/></td>
- <td valign="middle"><span class="vexpl"><?php echo gettext("Click to save changes and auto-resolve flowbit rules (if option is selected above)"); ?></span></td>
+ <table width="95%" style="margin-left: auto; margin-right: auto;" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
+ <tr height="32px">
+ <td style="vertical-align: middle;"><input value="Select All" class="formbtns" type="submit" name="selectall" id="selectall" title="<?php echo gettext("Add all to enforcing rules"); ?>"/></td>
+ <td style="vertical-align: middle;"><input value="Unselect All" class="formbtns" type="submit" name="unselectall" id="unselectall" title="<?php echo gettext("Remove all from enforcing rules"); ?>"/></td>
+ <td style="vertical-align: middle;"><input value=" Save " class="formbtns" type="submit" name="save" id="save" title="<?php echo gettext("Save changes to enforcing rules and rebuild"); ?>"/></td>
+ <td style="vertical-align: middle;"><span class="vexpl"><?php echo gettext("Click to save changes and auto-resolve flowbit rules (if option is selected above)"); ?></span></td>
+ </tr>
+ <?php if (!empty($cat_mods)): ?>
+ <tr height="20px">
+ <td colspan="4" style="vertical-align: middle;"><img style="vertical-align: text-top;" src="../themes/<?=$g['theme'];?>/images/icons/icon_advanced.gif" width="11" height="11" border="0" />
+ <?=gettext("- Category is auto-enabled by SID Mgmt conf files");?>&nbsp;&nbsp;&nbsp;
+ <img style="opacity: 0.4; filter: alpha(opacity=40); vertical-align: text-top;" src="../themes/<?=$g['theme'];?>/images/icons/icon_advanced.gif" width="11" height="11" border="0" />
+ <?=gettext("- Category is auto-disabled by SID Mgmt conf files");?></td>
</tr>
+ <?php endif; ?>
+ </tbody>
</table>
+ </td>
</tr>
+
<?php if ($no_community_files)
$msg_community = "NOTE: Snort Community Rules have not been downloaded. Perform a Rules Update to enable them.";
else
@@ -412,15 +453,29 @@ if ($savemsg) {
<td width="5%" class="listhdrr"><?php echo gettext("Enabled"); ?></td>
<td colspan="5" class="listhdrr"><?php echo gettext('Ruleset: Snort GPLv2 Community Rules');?></td>
</tr>
- <?php if (in_array($community_rules_file, $enabled_rulesets_array)): ?>
+ <?php if (isset($cat_mods[$community_rules_file])): ?>
+ <?php if ($cat_mods[$community_rules_file] == 'enabled') : ?>
+ <tr>
+ <td width="5%" class="listr" style="text-align: center;">
+ <img src="../themes/<?=$g['theme'];?>/images/icons/icon_advanced.gif" width="11" height="11" border="0" title="<?=gettext("Auto-managed by settings on SID Mgmt tab");?>" /></td>
+ <td colspan="5" class="listr"><a href='suricata_rules.php?id=<?=$id;?>&openruleset=<?=$community_rules_file;?>'><?=gettext("{$msg_community}");?></a></td>
+ </tr>
+ <?php else: ?>
+ <tr>
+ <td width="5%" class="listr" style="text-align: center;">
+ <img style="opacity: 0.4; filter: alpha(opacity=40);" src="../themes/<?=$g['theme'];?>/images/icons/icon_advanced.gif" width="11" height="11" border="0" title="<?=gettext("Auto-managed by settings on SID Mgmt tab");?>" /></td>
+ <td colspan="5" class="listr"><?=gettext("{$msg_community}"); ?></td>
+ </tr>
+ <?php endif; ?>
+ <?php elseif (in_array($community_rules_file, $enabled_rulesets_array)): ?>
<tr>
- <td width="5" class="listr" align="center" valign="top">
+ <td width="5%" class="listr" style="text-align: center;">
<input type="checkbox" name="toenable[]" value="<?=$community_rules_file;?>" checked="checked"/></td>
<td colspan="5" class="listr"><a href='suricata_rules.php?id=<?=$id;?>&openruleset=<?=$community_rules_file;?>'><?php echo gettext("{$msg_community}"); ?></a></td>
</tr>
<?php else: ?>
<tr>
- <td width="5" class="listr" align="center" valign="top">
+ <td width="5%" class="listr" style="text-align: center;">
<input type="checkbox" name="toenable[]" value="<?=$community_rules_file;?>" <?php if ($snortcommunitydownload == 'off') echo "disabled"; ?>/></td>
<td colspan="5" class="listr"><?php echo gettext("{$msg_community}"); ?></td>
</tr>
@@ -438,19 +493,19 @@ if ($savemsg) {
?>
<tr id="frheader">
<?php if ($emergingdownload == 'on' && !$no_emerging_files): ?>
- <td width="5%" class="listhdrr" align="center"><?php echo gettext("Enabled"); ?></td>
+ <td width="5%" class="listhdrr" style="text-align: center;"><?php echo gettext("Enabled"); ?></td>
<td width="45%" class="listhdrr"><?php echo gettext('Ruleset: ET Open Rules');?></td>
<?php elseif ($etpro == 'on' && !$no_emerging_files): ?>
- <td width="5%" class="listhdrr" align="center"><?php echo gettext("Enabled"); ?></td>
+ <td width="5%" class="listhdrr" style="text-align: center;"><?php echo gettext("Enabled"); ?></td>
<td width="45%" class="listhdrr"><?php echo gettext('Ruleset: ET Pro Rules');?></td>
<?php else: ?>
- <td colspan="2" align="center" width="50%" class="listhdrr"><?php echo gettext("{$et_type} rules {$msg_emerging}"); ?></td>
+ <td colspan="2" style="text-align: center;" width="50%" class="listhdrr"><?php echo gettext("{$et_type} rules {$msg_emerging}"); ?></td>
<?php endif; ?>
<?php if ($snortdownload == 'on' && !$no_snort_files): ?>
- <td width="5%" class="listhdrr" align="center"><?php echo gettext("Enabled"); ?></td>
+ <td width="5%" class="listhdrr" style="text-align: center;"><?php echo gettext("Enabled"); ?></td>
<td width="45%" class="listhdrr"><?php echo gettext('Ruleset: Snort VRT Rules');?></td>
<?php else: ?>
- <td colspan="2" align="center" width="50%" class="listhdrr"><?php echo gettext("Snort VRT rules {$msg_snort}"); ?></td>
+ <td colspan="2" style="text-align: center;" width="50%" class="listhdrr"><?php echo gettext("Snort VRT rules {$msg_snort}"); ?></td>
<?php endif; ?>
</tr>
<?php
@@ -482,15 +537,28 @@ if ($savemsg) {
echo "<tr>\n";
if (!empty($emergingrules[$j])) {
$file = $emergingrules[$j];
- echo "<td width='5%' class='listr' align=\"center\" valign=\"top\">";
+ echo "<td width='5%' class='listr' align=\"center\">";
if(is_array($enabled_rulesets_array)) {
- if(in_array($file, $enabled_rulesets_array))
+ if(in_array($file, $enabled_rulesets_array) && !isset($cat_mods[$file]))
$CHECKED = " checked=\"checked\"";
else
$CHECKED = "";
} else
$CHECKED = "";
- echo " \n<input type='checkbox' name='toenable[]' value='$file' {$CHECKED} />\n";
+ if (isset($cat_mods[$file])) {
+ if (in_array($file, $enabled_rulesets_array))
+ echo "<input type='hidden' name='toenable[]' value='{$file}' />\n";
+ if ($cat_mods[$file] == 'enabled') {
+ $CHECKED = "enabled";
+ echo " \n<img src=\"../themes/{$g['theme']}/images/icons/icon_advanced.gif\" width=\"11\" height=\"11\" border=\"0\" title=\"" . gettext("Auto-enabled by settings on SID Mgmt tab") . "\" />\n";
+ }
+ else {
+ echo " \n<img style=\"opacity: 0.4; filter: alpha(opacity=40);\" src=\"../themes/{$g['theme']}/images/icons/icon_advanced.gif\" width=\"11\" height=\"11\" border=\"0\" title=\"" . gettext("Auto-disabled by settings on SID Mgmt tab") . "\" />\n";
+ }
+ }
+ else {
+ echo " \n<input type='checkbox' name='toenable[]' value='{$file}' {$CHECKED} />\n";
+ }
echo "</td>\n";
echo "<td class='listr' width='45%' >\n";
if (empty($CHECKED))
@@ -503,17 +571,30 @@ if ($savemsg) {
if (!empty($snortrules[$j])) {
$file = $snortrules[$j];
- echo "<td class='listr' width='5%' align=\"center\" valign=\"top\">";
+ echo "<td class='listr' width='5%' align=\"center\">";
if(is_array($enabled_rulesets_array)) {
if (!empty($disable_vrt_rules))
$CHECKED = $disable_vrt_rules;
- elseif(in_array($file, $enabled_rulesets_array))
+ elseif(in_array($file, $enabled_rulesets_array) && !isset($cat_mods[$file]))
$CHECKED = " checked=\"checked\"";
else
$CHECKED = "";
} else
$CHECKED = "";
- echo " \n<input type='checkbox' name='toenable[]' value='{$file}' {$CHECKED} />\n";
+ if (isset($cat_mods[$file])) {
+ if (in_array($file, $enabled_rulesets_array))
+ echo "<input type='hidden' name='toenable[]' value='{$file}' />\n";
+ if ($cat_mods[$file] == 'enabled') {
+ $CHECKED = "enabled";
+ echo " \n<img src=\"../themes/{$g['theme']}/images/icons/icon_advanced.gif\" width=\"11\" height=\"11\" border=\"0\" title=\"" . gettext("Auto-enabled by settings on SID Mgmt tab") . "\" />\n";
+ }
+ else {
+ echo " \n<img style=\"opacity: 0.4; filter: alpha(opacity=40);\" src=\"../themes/{$g['theme']}/images/icons/icon_advanced.gif\" width=\"11\" height=\"11\" border=\"0\" title=\"" . gettext("Auto-disabled by settings on SID Mgmt tab") . "\" />\n";
+ }
+ }
+ else {
+ echo " \n<input type='checkbox' name='toenable[]' value='{$file}' {$CHECKED} />\n";
+ }
echo "</td>\n";
echo "<td class='listr' width='45%' >\n";
if (empty($CHECKED) || $CHECKED == "disabled")
@@ -526,21 +607,30 @@ if ($savemsg) {
echo "</tr>\n";
}
?>
- </table>
+ </tbody>
+ </table>
</td>
</tr>
-<tr>
-<td colspan="4" class="vexpl">&nbsp;<br/></td>
-</tr>
- <tr>
- <td colspan="4" align="center" valign="middle">
- <input value="Save" type="submit" name="save" id="save" class="formbtn" title=" <?php echo gettext("Click to Save changes and rebuild rules"); ?>"/></td>
- </tr>
+ <?php if (!empty($cat_mods)): ?>
+ <tr>
+ <td colspan="4" style="vertical-align: middle;"><br/>
+ <img style="vertical-align: text-top;" src="../themes/<?=$g['theme'];?>/images/icons/icon_advanced.gif" width="11" height="11" border="0" />
+ <?=gettext(" - Category auto-enabled by parameters in SID Mgmt conf files");?><br/>
+ <img style="opacity: 0.4; filter: alpha(opacity=40); vertical-align: text-top;" src="../themes/<?=$g['theme'];?>/images/icons/icon_advanced.gif" width="11" height="11" border="0" />
+ <?=gettext(" - Category auto-disabled by parameters in SID Mgmt conf files");?><br/><br/></td>
+ </tr>
+ <?php endif; ?>
+ <tr height="32px">
+ <td colspan="4" style="vertical-align: bottom; text-align: center;">
+ <input value="Save" type="submit" name="save" id="save" class="formbtn" title=" <?php echo gettext("Click to Save changes and rebuild rules"); ?>"/></td>
+ </tr>
<?php endif; ?>
+</tbody>
</table>
</div>
</td>
</tr>
+</tbody>
</table>
</form>
<?php
@@ -566,28 +656,29 @@ h += 96;
function enable_change()
{
- var endis = !(document.iform.ips_policy_enable.checked);
- document.iform.ips_policy.disabled=endis;
-
- if (endis) {
- document.getElementById("ips_row1").style.display="none";
- document.getElementById("ips_row2").style.display="none";
- document.getElementById("ips_col1").className="vexpl";
- document.getElementById("ips_col2").className="vexpl";
- }
- else {
- document.getElementById("ips_row1").style.display="table-row";
- document.getElementById("ips_row2").style.display="table-row";
- document.getElementById("ips_col1").className="vncell";
- document.getElementById("ips_col2").className="vtable";
- }
- for (var i = 0; i < document.iform.elements.length; i++) {
- if (document.iform.elements[i].type == 'checkbox') {
- var str = document.iform.elements[i].value;
- if (str.substr(0,6) == "snort_")
- document.iform.elements[i].disabled = !(endis);
- }
- }
+
+ if (document.getElementById("ips_policy_enable")) {
+ var endis = !(document.iform.ips_policy_enable.checked);
+ document.iform.ips_policy.disabled=endis;
+
+ if (endis) {
+ document.getElementById("ips_controls").style.display="none";
+ document.getElementById("ips_col1").className="";
+ document.getElementById("ips_col2").className="";
+ }
+ else {
+ document.getElementById("ips_controls").style.display="";
+ document.getElementById("ips_col1").className="vncell";
+ document.getElementById("ips_col2").className="vtable";
+ }
+ }
+ for (var i = 0; i < document.iform.elements.length; i++) {
+ if (document.iform.elements[i].type == 'checkbox') {
+ var str = document.iform.elements[i].value;
+ if (str.substr(0,6) == "snort_")
+ document.iform.elements[i].disabled = !(endis);
+ }
+ }
}
// Set initial state of dynamic HTML form controls
diff --git a/config/suricata/suricata_select_alias.php b/config/suricata/suricata_select_alias.php
index 527412d1..47bbec4a 100644
--- a/config/suricata/suricata_select_alias.php
+++ b/config/suricata/suricata_select_alias.php
@@ -47,29 +47,31 @@ else
// Retrieve any passed QUERY STRING or POST variables
if (isset($_POST['type']))
- $type = $_POST['type'];
+ $type = htmlspecialchars($_POST['type']);
elseif (isset($_GET['type']))
$type = htmlspecialchars($_GET['type']);
if (isset($_POST['varname']))
- $varname = $_POST['varname'];
+ $varname = htmlspecialchars($_POST['varname']);
elseif (isset($_GET['varname']))
$varname = htmlspecialchars($_GET['varname']);
if (isset($_POST['multi_ip']))
- $multi_ip = $_POST['multi_ip'];
+ $multi_ip = htmlspecialchars($_POST['multi_ip']);
elseif (isset($_GET['multi_ip']))
$multi_ip = htmlspecialchars($_GET['multi_ip']);
-if (isset($_POST['returl']))
+if (isset($_POST['returl']) && substr($_POST['returl'], 0, 1) == '/')
$referrer = urldecode($_POST['returl']);
-elseif (isset($_GET['returl']))
+elseif (isset($_GET['returl']) && substr($_GET['returl'], 0, 1) == '/')
$referrer = urldecode($_GET['returl']);
+else
+ $referrer = $_SERVER['HTTP_REFERER'];
// Make sure we have a valid VARIABLE name
// and ALIAS TYPE, or else bail out.
if (is_null($type) || is_null($varname)) {
- header("Location: http://{$referrer}?{$querystr}");
+ header("Location: {$referrer}?{$querystr}");
exit;
}
@@ -132,8 +134,8 @@ include("head.inc");
<input type="hidden" name="varname" value="<?=$varname;?>"/>
<input type="hidden" name="type" value="<?=$type;?>"/>
<input type="hidden" name="multi_ip" value="<?=$multi_ip;?>"/>
-<input type="hidden" name="returl" value="<?=$referrer;?>"/>
-<input type="hidden" name="org_querystr" value="<?=$querystr;?>"/>
+<input type="hidden" name="returl" value="<?=htmlspecialchars($referrer);?>"/>
+<input type="hidden" name="org_querystr" value="<?=htmlspecialchars($querystr);?>"/>
<?php if ($input_errors) print_input_errors($input_errors); ?>
<div id="boxarea">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
@@ -151,8 +153,8 @@ include("head.inc");
<col width="35%" align="left" axis="string">
</colgroup>
<thead>
- <tr>
- <th class="listhdrr"></th>
+ <tr class="sortableHeaderRowIdentifier">
+ <th class="listhdrr sorttable_nosort"></th>
<th class="listhdrr" axis="string"><?=gettext("Alias Name"); ?></th>
<th class="listhdrr" axis="string"><?=gettext("Values"); ?></th>
<th class="listhdrr" axis="string"><?=gettext("Description"); ?></th>
diff --git a/config/suricata/suricata_sid_mgmt.php b/config/suricata/suricata_sid_mgmt.php
new file mode 100644
index 00000000..c2d58af8
--- /dev/null
+++ b/config/suricata/suricata_sid_mgmt.php
@@ -0,0 +1,611 @@
+<?php
+/*
+ * suricata_sid_mgmt.php
+ *
+ * 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 $g, $config, $rebuild_rules;
+
+$suricatadir = SURICATADIR;
+$pconfig = array();
+
+// Grab saved settings from configuration
+if (!is_array($config['installedpackages']['suricata']['rule']))
+ $config['installedpackages']['suricata']['rule'] = array();
+$a_nat = &$config['installedpackages']['suricata']['rule'];
+
+$pconfig['auto_manage_sids'] = $config['installedpackages']['suricata']['config'][0]['auto_manage_sids'];
+
+// Hard-code the path where SID Mods Lists are stored
+// and disregard any user-supplied path element.
+$sidmods_path = SURICATA_SID_MODS_PATH;
+
+// Set default to not show SID modification lists editor controls
+$sidmodlist_edit_style = "display: none;";
+
+if (!empty($_POST))
+ $pconfig = $_POST;
+
+function suricata_is_sidmodslist_active($sidlist) {
+
+ /*****************************************************
+ * This function checks all the configured Suricata *
+ * interfaces to see if the passed SID Mods List is *
+ * used by an interface. *
+ * *
+ * Returns: TRUE if List is in use *
+ * FALSE if 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 ($rule['enable_sid_file'] == $sidlist) {
+ return TRUE;
+ }
+ if ($rule['disable_sid_file'] == $sidlist) {
+ return TRUE;
+ }
+ if ($rule['modify_sid_file'] == $sidlist) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+if (isset($_POST['upload'])) {
+ if ($_FILES["sidmods_fileup"]["error"] == UPLOAD_ERR_OK) {
+ $tmp_name = $_FILES["sidmods_fileup"]["tmp_name"];
+ $name = basename($_FILES["sidmods_fileup"]["name"]);
+ move_uploaded_file($tmp_name, "{$sidmods_path}{$name}");
+ }
+ else
+ $input_errors[] = gettext("Failed to upload file {$_FILES["sidmods_fileup"]["name"]}");
+}
+
+if (isset($_POST['sidlist_delete']) && isset($_POST['sidlist_fname'])) {
+ if (!suricata_is_sidmodslist_active(basename($_POST['sidlist_fname'])))
+ unlink_if_exists($sidmods_path . basename($_POST['sidlist_fname']));
+ else
+ $input_errors[] = gettext("This SID Mods List is currently assigned to an interface and cannot be deleted.");
+}
+
+if (isset($_POST['sidlist_edit']) && isset($_POST['sidlist_fname'])) {
+ $file = $sidmods_path . basename($_POST['sidlist_fname']);
+ $data = file_get_contents($file);
+ if ($data !== FALSE) {
+ $sidmodlist_data = htmlspecialchars($data);
+ $sidmodlist_edit_style = "display: table-row-group;";
+ $sidmodlist_name = basename($_POST['sidlist_fname']);
+ unset($data);
+ }
+ else {
+ $input_errors[] = gettext("An error occurred reading the file.");
+ }
+}
+
+if (isset($_POST['save']) && isset($_POST['sidlist_data'])) {
+ if (strlen(basename($_POST['sidlist_name'])) > 0) {
+ $file = $sidmods_path . basename($_POST['sidlist_name']);
+ $data = str_replace("\r\n", "\n", $_POST['sidlist_data']);
+ file_put_contents($file, $data);
+ unset($data);
+ }
+ else {
+ $input_errors[] = gettext("You must provide a valid filename for the SID Mods List.");
+ $sidmodlist_edit_style = "display: table-row-group;";
+ }
+}
+
+if (isset($_POST['save_auto_sid_conf'])) {
+ $config['installedpackages']['suricata']['config'][0]['auto_manage_sids'] = $pconfig['auto_manage_sids'] ? "on" : "off";
+
+ // Grab the SID Mods config for the interfaces from the form's controls array
+ foreach ($_POST['sid_state_order'] as $k => $v) {
+ $a_nat[$k]['sid_state_order'] = $v;
+ }
+ foreach ($_POST['enable_sid_file'] as $k => $v) {
+ if ($v == "None") {
+ unset($a_nat[$k]['enable_sid_file']);
+ continue;
+ }
+ $a_nat[$k]['enable_sid_file'] = $v;
+ }
+ foreach ($_POST['disable_sid_file'] as $k => $v) {
+ if ($v == "None") {
+ unset($a_nat[$k]['disable_sid_file']);
+ continue;
+ }
+ $a_nat[$k]['disable_sid_file'] = $v;
+ }
+ foreach ($_POST['modify_sid_file'] as $k => $v) {
+ if ($v == "None") {
+ unset($a_nat[$k]['modify_sid_file']);
+ continue;
+ }
+ $a_nat[$k]['modify_sid_file'] = $v;
+ }
+
+ // Write the new configuration
+ write_config("Suricata pkg: updated automatic SID management settings.");
+
+ $intf_msg = "";
+
+ // If any interfaces were marked for restart, then do it
+ if (is_array($_POST['torestart'])) {
+ foreach ($_POST['torestart'] as $k) {
+ // Update the suricata.yaml file and
+ // rebuild rules for this interface.
+ $rebuild_rules = true;
+ conf_mount_rw();
+ suricata_generate_yaml($a_nat[$k]);
+ conf_mount_ro();
+ $rebuild_rules = false;
+
+ // Signal Suricata to "live reload" the rules
+ suricata_reload_config($a_nat[$k]);
+
+ $intf_msg .= convert_friendly_interface_to_friendly_descr($a_nat[$k]['interface']) . ", ";
+ }
+ $savemsg = gettext("Changes were applied to these interfaces: " . trim($intf_msg, ' ,') . " and Suricata signaled to live-load the new rules.");
+
+ // Sync to configured CARP slaves if any are enabled
+ suricata_sync_on_changes();
+ }
+}
+
+if (isset($_POST['sidlist_dnload']) && isset($_POST['sidlist_fname'])) {
+ $file = $sidmods_path . basename($_POST['sidlist_fname']);
+ if (file_exists($file)) {
+ 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($file));
+ header("Content-disposition: attachment; filename = " . basename($file));
+ ob_end_clean(); //important or other post will fail
+ readfile($file);
+ }
+ else
+ $savemsg = gettext("Unable to locate the file specified!");
+}
+
+if (isset($_POST['sidlist_dnload_all_x'])) {
+ $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} *");
+
+ if (file_exists("/tmp/{$file_name}")) {
+ 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("/tmp/{$file_name}"));
+ header("Content-disposition: attachment; filename = {$file_name}");
+ ob_end_clean(); //important or other post will fail
+ readfile("/tmp/{$file_name}");
+
+ // Clean up the temp file
+ unlink_if_exists("/tmp/{$file_name}");
+ }
+ else
+ $savemsg = gettext("An error occurred while creating the gzip archive!");
+}
+
+// Get all files in the SID Mods 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.
+$sidmodfiles = return_dir_as_array($sidmods_path);
+$sidmodselections = array_merge(Array( "None" ), $sidmodfiles);
+
+$pgtitle = gettext("Suricata: SID Management");
+include_once("head.inc");
+
+?>
+
+<body link="#000000" vlink="#000000" alink="#000000">
+
+<?php
+include_once("fbegin.inc");
+
+/* Display Alert message, under form tag or no refresh */
+if ($input_errors)
+ print_input_errors($input_errors);
+?>
+
+<form action="suricata_sid_mgmt.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<input type="hidden" name="MAX_FILE_SIZE" value="100000000" />
+<input type="hidden" name="sidlist_fname" id="sidlist_fname" value=""/>
+
+<?php
+if ($savemsg) {
+ /* Display save message */
+ print_info_box($savemsg);
+}
+?>
+
+<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");
+ $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");
+ $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>
+ <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("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>
+ <tr>
+ <td width="22%" valign="top" class="vncell"><?php echo gettext("Enable Automatic SID State Management"); ?></td>
+ <td width="78%" class="vtable"><input type="checkbox" id="auto_manage_sids" name="auto_manage_sids" value="on"
+ <?php if ($pconfig['auto_manage_sids'] == 'on') echo " checked"; ?> onclick="enable_sid_conf();" />&nbsp;<?=gettext("Enable automatic management of rule state ") .
+ gettext("and content using configuration files. Default is ") . "<strong>" . gettext("Not Checked") . "</strong>";?>.<br/><br/>
+ <?=gettext("Suricata will automatically enable/disable/modify text rules upon each update using criteria specified in configuration files. ") .
+ gettext("The supported configuration file format is the same as that used in the PulledPork and Oinkmaster enablesid.conf, disablesid.conf and ") .
+ gettext("modifysid.conf files. You can either upload existing files or create your own."); ?>
+ </td>
+ </tr>
+ </tbody>
+ <tbody id="sid_conf_rows">
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("SID Management Configuration Files"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vtable" align="center" >
+ <table width="100%" border="0" cellpadding="4" cellspacing="0">
+ <tbody id="uploader" style="display: none;">
+ <tr>
+ <td 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 class="list"><input type="file" name="sidmods_fileup" id="sidmods_fileup" class="formfld file" size="50" />
+ &nbsp;&nbsp;<input type="submit" name="upload" id="upload" value="<?=gettext("Upload");?>"
+ title="<?=gettext("Upload selected SID mods 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>
+ <tbody>
+ <tr>
+ <td>
+ <table id="maintable" width="100%" border="0" cellpadding="4" cellspacing="0">
+ <colgroup>
+ <col style="width: 45%;">
+ <col style="width: 25%;">
+ <col style="width: 15%;">
+ <col style="width: 15%;">
+ </colgroup>
+ <thead>
+ <tr>
+ <th class="listhdrr"><?php echo gettext("SID Mods 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="sidlist_new" id="sidlist_new"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" width="17"
+ height="17" border="0" title="<?php echo gettext('Create a new SID Mods List');?>"
+ onClick="document.getElementById('sidlist_data').value=''; document.getElementById('sidlist_name').value=''; document.getElementById('sidlist_editor').style.display='table-row-group'; document.getElementById('sidlist_name').focus();" />
+ <img style="cursor:pointer;" name="sidlist_import" id="sidlist_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 a SID Mods List');?>"/>
+ <input type="image" name="sidlist_dnload_all" id="sidlist_dnload_all"
+ src="../tree/page-file_play.gif" width="16" height="16" border="0"
+ title="<?php echo gettext('Download all SID Mods List files in a single gzip archive');?>"/>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php foreach ($sidmodfiles as $file): ?>
+ <tr>
+ <td class="listr"><?php echo gettext($file); ?></td>
+ <td class="listr"><?=date('M-d Y g:i a', filemtime("{$sidmods_path}{$file}")); ?></td>
+ <td class="listr"><?=format_bytes(filesize("{$sidmods_path}{$file}")); ?> </td>
+ <td class="list"><input type="image" name="sidlist_edit[]" id="sidlist_edit[]"
+ onClick="document.getElementById('sidlist_fname').value='<?=$file;?>';"
+ src="../themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" width="17"
+ height="17" border="0" title="<?php echo gettext('Edit this SID Mods List');?>"/>
+ <input type="image" name="sidlist_delete[]" id="sidlist_delete[]"
+ onClick="document.getElementById('sidlist_fname').value='<?=$file;?>';
+ return confirm('<?=gettext("Are you sure you want to permanently delete this 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 SID Mods List');?>"/>
+ <input type="image" name="sidlist_dnload[]" id="sidlist_dnload[]"
+ onClick="document.getElementById('sidlist_fname').value='<?=$file;?>';"
+ src="../tree/page-file_play.gif" width="16" height="16" border="0"
+ title="<?php echo gettext('Download this SID Mods List file');?>"/>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </tbody>
+ <tbody id="sidlist_editor" style="<?=$sidmodlist_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="sidlist_name" name="sidlist_name" value="<?=$sidmodlist_name;?>" />
+ &nbsp;&nbsp;<input type="submit" id="save" name="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('sidlist_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="sidlist_data" id="sidlist_data"
+ style="width:95%; height:100%;"><?=$sidmodlist_data;?></textarea>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="3" class="vexpl"><br/><span class="red"><strong><?php echo gettext("Note:"); ?></strong></span>
+ <br/><?php echo gettext("SID Mods 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"><br/><strong><?php echo gettext("File 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 SID Mods 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 SID Mods 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 SID Mods 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 SID Mods List from the file system after confirmation.");?><br/>
+ &nbsp;&nbsp;<img src="../tree/page-file_play.gif" width="16" height="16" border="0" />
+ &nbsp;<?=gettext("Downloads the SID Mods List file to your local machine.");?><br/>
+ </td>
+ <td class="list"></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic"><?php echo gettext("Interface SID Management File Assignments"); ?></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="vtable" align="center" >
+ <table width="100%" border="0" cellpadding="2" cellspacing="0">
+ <tbody>
+ <tr>
+ <td>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <colgroup>
+ <col width="4%" align="center">
+ <col width="20" align="center">
+ <col width="16%" align="center">
+ <col width="20%" align="center">
+ <col width="20%" align="center">
+ <col width="20%" align="center">
+ </colgroup>
+ <thead>
+ <tr>
+ <th class="listhdrr"><?=gettext("Rebuild"); ?></th>
+ <th class="listhdrr"><?=gettext("Interface"); ?></th>
+ <th class="listhdrr"><?=gettext("SID State Order"); ?></th>
+ <th class="listhdrr"><?=gettext("Enable SID File"); ?></th>
+ <th class="listhdrr"><?=gettext("Disable SID File"); ?></th>
+ <th class="listhdrr"><?=gettext("Modify SID File"); ?></th>
+ </tr>
+ </thead>
+ <tbody>
+ <?php foreach ($a_nat as $k => $natent): ?>
+ <tr>
+ <td class="listr" align="center">
+ <input type="checkbox" name="torestart[]" id="torestart[]" value="<?=$k;?>" title="<?=gettext("Apply new configuration and rebuild rules for this interface when saving");?>" />
+ </td>
+ <td class="listbg"><?=convert_friendly_interface_to_friendly_descr($natent['interface']); ?></td>
+ <td class="listr" align="center">
+ <select name="sid_state_order[<?=$k?>]" class="formselect" id="sid_state_order[<?=$k?>]">
+ <?php
+ foreach (array("disable_enable" => "Disable, Enable", "enable_disable" => "Enable, Disable") as $key => $order) {
+ if ($key == $natent['sid_state_order'])
+ echo "<option value='{$key}' selected>";
+ else
+ echo "<option value='{$key}'>";
+ echo htmlspecialchars($order) . '</option>';
+ }
+ ?>
+ </select>
+ </td>
+ <td class="listr" align="center">
+ <select name="enable_sid_file[<?=$k?>]" class="formselect" id="enable_sid_file[<?=$k?>]">
+ <?php
+ foreach ($sidmodselections as $choice) {
+ if ($choice == $natent['enable_sid_file'])
+ echo "<option value='{$choice}' selected>";
+ else
+ echo "<option value='{$choice}'>";
+ echo htmlspecialchars(gettext($choice)) . '</option>';
+ }
+ ?>
+ </select>
+ </td>
+ <td class="listr" align="center">
+ <select name="disable_sid_file[<?=$k?>]" class="formselect" id="disable_sid_file[<?=$k?>]">
+ <?php
+ foreach ($sidmodselections as $choice) {
+ if ($choice == $natent['disable_sid_file'])
+ echo "<option value='{$choice}' selected>";
+ else
+ echo "<option value='{$choice}'>";
+ echo htmlspecialchars(gettext($choice)) . '</option>';
+ }
+ ?>
+ </select>
+ </td>
+ <td class="listr" align="center">
+ <select name="modify_sid_file[<?=$k?>]" class="formselect" id="modify_sid_file[<?=$k?>]">
+ <?php
+ foreach ($sidmodselections as $choice) {
+ if ($choice == $natent['modify_sid_file'])
+ echo "<option value='{$choice}' selected>";
+ else
+ echo "<option value='{$choice}'>";
+ echo htmlspecialchars(gettext($choice)) . '</option>';
+ }
+ ?>
+ </select>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td class="vexpl">&nbsp;
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <table width="100%" cellpadding="2" cellspacing="2" border="0">
+ <tbody>
+ <tr>
+ <td colspan="2" class="vexpl" style="text-align: bottom;"><strong><span class="red"><?=gettext("Notes:");?></span></strong></td>
+ </tr>
+ <tr>
+ <td class="vexpl" style="vertical-align: top;"><?=gettext("1.");?></td>
+ <td class="vexpl"><?=gettext("Check the box beside an interface to immediately apply new auto-SID management ") .
+ gettext("changes and signal Suricata to live-load the new rules for the interface when clicking SAVE; ") .
+ gettext("otherwise only the new file assignments will be saved.");?>
+ </td>
+ </tr>
+ <tr>
+ <td class="vexpl" style="vertical-align: top;"><?=gettext("2.");?></td>
+ <td class="vexpl"><?=gettext("SID State Order controls the order in which enable and disable state modifications are performed. ") .
+ gettext("An example would be to disable an entire category and later enable only a rule or two from it. In this case you would ") .
+ gettext("choose 'disable,enable' for the State Order. Note that the last action performed takes priority.");?>
+ </td>
+ </tr>
+ <tr>
+ <td class="vexpl" style="vertical-align: top;"><?=gettext("3.");?></td>
+ <td class="vexpl"><?=gettext("The Enable SID File, Disable SID File and Modify SID File controls specify which rule modification ") .
+ gettext("files are run automatically for the interface. Setting a file control to 'None' disables that modification. ") .
+ gettext("Setting all file controls for an interface to 'None' disables automatic SID state management for the interface.");?>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ <tbody>
+ <tr>
+ <td colspan="2" class="vexpl" align="center"><input type="submit" id="save_auto_sid_conf" name="save_auto_sid_conf" class="formbtn" value="<?=gettext("Save");?>" title="<?=gettext("Save SID Management configuration");?>" />
+ &nbsp;&nbsp;<?=gettext("Remember to save changes before exiting this page"); ?>
+ </td>
+ </tr>
+ <?php endif; ?>
+ </tbody>
+ </table>
+ </div>
+ </td></tr>
+ </tbody>
+</table>
+</form>
+
+
+<?php include("fend.inc"); ?>
+
+<?php if ($g['platform'] != "nanobsd") : ?>
+<script type="text/javascript">
+
+function enable_sid_conf() {
+ var endis = !document.iform.auto_manage_sids.checked;
+ if (endis) {
+ document.getElementById("sid_conf_rows").style.display = "none";
+ }
+ else {
+ document.getElementById("sid_conf_rows").style.display = "";
+ }
+}
+
+enable_sid_conf();
+
+</script>
+<?php endif; ?>
+
+</body>
+</html>
diff --git a/config/suricata/suricata_suppress.php b/config/suricata/suricata_suppress.php
index 4f2e8d0d..8fcb3dd5 100644
--- a/config/suricata/suricata_suppress.php
+++ b/config/suricata/suricata_suppress.php
@@ -94,15 +94,18 @@ function suricata_find_suppresslist_interface($supplist) {
return false;
}
-if ($_GET['act'] == "del") {
- if ($a_suppress[$_GET['id']]) {
+if ($_POST['del'] && is_numericint($_POST['list_id'])) {
+ if ($a_suppress[$_POST['list_id']]) {
// make sure list is not being referenced by any Suricata-configured interface
- if (suricata_suppresslist_used($a_suppress[$_GET['id']]['name'])) {
+ if (suricata_suppresslist_used($a_suppress[$_POST['list_id']]['name'])) {
$input_errors[] = gettext("ERROR -- Suppress List is currently assigned to an interface and cannot be removed!");
}
else {
- unset($a_suppress[$_GET['id']]);
- write_config();
+ 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;
}
@@ -126,19 +129,24 @@ if ($input_errors) {
?>
<form action="/suricata/suricata_suppress.php" method="post"><?php if ($savemsg) print_info_box($savemsg); ?>
+<input type="hidden" name="list_id" id="list_id" value=""/>
<table width="100%" border="0" cellpadding="0" cellspacing="0">
+<tbody>
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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"), true, "/suricata/suricata_suppress.php");
- $tab_array[] = array(gettext("Logs Browser"), false, "/suricata/suricata_logs_browser.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php");
$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>
@@ -172,6 +180,7 @@ if ($input_errors) {
</td>
<td height="20px" valign="middle" nowrap class="list">
<table border="0" cellspacing="0" cellpadding="1">
+ <tbody>
<tr>
<td valign="middle"><a
href="suricata_suppress_edit.php?id=<?=$i;?>"><img
@@ -185,13 +194,12 @@ if ($input_errors) {
width="17" height="17" border="0" title="<?php echo gettext("Goto first instance associated with this Suppress List");?>"/></a>
</td>
<?php else : ?>
- <td><a href="/suricata/suricata_suppress.php?act=del&id=<?=$i;?>"
- onclick="return confirm('<?php echo gettext("Do you really want to delete this Suppress List?"); ?>')"><img
- src="/themes/<?=$g['theme'];?>/images/icons/icon_x.gif"
- width="17" height="17" border="0" title="<?php echo gettext("delete Suppress List"); ?>"></a></td>
+ <td><input type="image" name="del[]" onclick="document.getElementById('list_id').value='<?=$i;?>';return confirm('<?=gettext("Do you really want to delete this Suppress List?");?>');"
+ src="/themes/<?=$g['theme'];?>/images/icons/icon_x.gif" width="17" height="17" border="0" title="<?=gettext("delete Suppress List");?>"/></td>
<td>&nbsp;</td>
<?php endif; ?>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -200,6 +208,7 @@ if ($input_errors) {
<td class="list" colspan="2"></td>
<td class="list">
<table border="0" cellspacing="0" cellpadding="1">
+ <tbody>
<tr>
<td valign="middle" width="17">&nbsp;</td>
<td valign="middle"><a
@@ -207,6 +216,7 @@ if ($input_errors) {
src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif"
width="17" height="17" border="0" title="<?php echo gettext("add a new list"); ?>"></a></td>
</tr>
+ </tbody>
</table>
</td>
</tr>
@@ -224,6 +234,7 @@ if ($input_errors) {
gettext("You must first unassign the Suppress List on the Interface Edit tab."); ?>
</p></span></td>
</tr>
+</tbody>
</table>
</form>
<?php include("fend.inc"); ?>
diff --git a/config/suricata/suricata_suppress_edit.php b/config/suricata/suricata_suppress_edit.php
index a46e9e99..8814d3db 100644
--- a/config/suricata/suricata_suppress_edit.php
+++ b/config/suricata/suricata_suppress_edit.php
@@ -88,7 +88,12 @@ if ($_POST['save']) {
$reqdfields = explode(" ", "name");
$reqdfieldsn = array("Name");
- do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ $pf_version=substr(trim(file_get_contents("/etc/version")),0,3);
+ if ($pf_version < 2.1)
+ $input_errors = eval('do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); return $input_errors;');
+ else
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
if(strtolower($_POST['name']) == "defaultwhitelist")
$input_errors[] = "Whitelist file names may not be named defaultwhitelist.";
@@ -152,15 +157,18 @@ if ($savemsg)
<tr><td>
<?php
$tab_array = array();
- $tab_array[] = array(gettext("Suricata Interfaces"), false, "/suricata/suricata_interfaces.php");
+ $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("Update Rules"), false, "/suricata/suricata_download_updates.php");
+ $tab_array[] = array(gettext("Updates"), false, "/suricata/suricata_download_updates.php");
$tab_array[] = array(gettext("Alerts"), false, "/suricata/suricata_alerts.php");
- $tab_array[] = array(gettext("Blocked"), false, "/suricata/suricata_blocked.php");
+ $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"), true, "/suricata/suricata_suppress.php");
- $tab_array[] = array(gettext("Logs Browser"), false, "/suricata/suricata_logs_browser.php");
+ $tab_array[] = array(gettext("Logs View"), false, "/suricata/suricata_logs_browser.php");
$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
new file mode 100644
index 00000000..28083d8d
--- /dev/null
+++ b/config/suricata/suricata_sync.xml
@@ -0,0 +1,221 @@
+<?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$ */
+/* ========================================================================== */
+/*
+based on snortsync.xml developed as part
+of pfSense (http://www.pfSense.com)
+Copyright (C) 2013 Marcello Coutinho
+based on pfblocker_sync.xml
+All rights reserved.
+
+modified for use with Suricata package
+Copyright (C) 2014 Bill Meeks
+All rights reserved.
+
+Based on m0n0wall (http://m0n0.ch/wall)
+Copyright (C) 2003-2006 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.
+*/
+/* ========================================================================== */
+]]></copyright>
+ <description><![CDATA[Describe your package here]]></description>
+ <requirements>Describe your package requirements here</requirements>
+ <faq>Currently there are no FAQ items provided.</faq>
+ <name>suricatasync</name>
+ <version>1.0</version>
+ <title>Suricata: XMLRPC Sync</title>
+ <include_file>/usr/local/pkg/suricata/suricata.inc</include_file>
+ <tabs>
+ <tab>
+ <text>Interfaces</text>
+ <url>/suricata/suricata_interfaces.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Global Settings</text>
+ <url>/suricata/suricata_global.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Updates</text>
+ <url>/suricata/suricata_download_updates.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Alerts</text>
+ <url>/suricata/suricata_alerts.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Blocks</text>
+ <url>/suricata/suricata_blocked.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Pass Lists</text>
+ <url>/suricata/suricata_passlist.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Suppress</text>
+ <url>/suricata/suricata_suppress.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Logs View</text>
+ <url>/suricata/suricata_logs_browser.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Logs Mgmt</text>
+ <url>/suricata/suricata_logs_mgmt.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>SID Mgmt</text>
+ <url>/suricata/suricata_sid_mgmt.php</url>
+ <no_drop_down/>
+ </tab>
+ <tab>
+ <text>Sync</text>
+ <url>/pkg_edit.php?xml=suricata/suricata_sync.xml</url>
+ <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>
+ <name>Suricata Package XMLRPC Sync Settings</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Enable Sync</fielddescr>
+ <fieldname>varsynconchanges</fieldname>
+ <description><![CDATA[All changes will be synced with apply config to the IPs listed below if this option is checked.<br/><br/>
+ <b>Important:</b> While using "Sync to hosts defined below", only sync from host A to B, A to C 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>Sync to configured system backup server</name><value>auto</value></option>
+ <option><name>Sync to host(s) defined below</name><value>manual</value></option>
+ <option><name>Do not sync this package configuration</name><value>disabled</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>Refresh Rule Sets</fielddescr>
+ <fieldname>vardownloadrules</fieldname>
+ <description><![CDATA[Ask target hosts to refresh rule sets files on each sync operation.<br/><br/>
+ During each Suricata package sync operation, ask the target remote host to check for
+ a new set of posted rule sets files and refresh the local copies if necessary. The default is
+ to refresh the files if newer versions have been posted.<br/><br/>
+ <b>Note: </b>The sync process will wait for the rules download and rebuild to finish on the target remote host before returning.]]></description>
+ <type>select</type>
+ <default_value>yes</default_value>
+ <options>
+ <option><name>Signal target host to refresh rules files</name><value>yes</value></option>
+ <option><name>Do NOT ask target host to refresh rules files</name><value>no</value></option>
+ </options>
+ </field>
+
+ <field>
+ <fielddescr>Replication Targets</fielddescr>
+ <fieldname>none</fieldname>
+ <type>rowhelper</type>
+ <rowhelper>
+ <rowhelperfield>
+ <fielddescr>Enable</fielddescr>
+ <fieldname>varsyncdestinenable</fieldname>
+ <description><![CDATA[Enable this host as a replication target]]></description>
+ <type>checkbox</type>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Protocol</fielddescr>
+ <fieldname>varsyncprotocol</fieldname>
+ <description><![CDATA[Choose the protocol of the destination host. Probably <b>http</b> or <b>https</b>]]></description>
+ <type>select</type>
+ <default_value>HTTP</default_value>
+ <options>
+ <option><name>HTTP</name><value>http</value></option>
+ <option><name>HTTPS</name><value>https</value></option>
+ </options>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>IP-Address</fielddescr>
+ <fieldname>varsyncipaddress</fieldname>
+ <description><![CDATA[IP Address of the destination host.]]></description>
+ <type>input</type>
+ <size>15</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Port</fielddescr>
+ <fieldname>varsyncport</fieldname>
+ <description><![CDATA[Choose the sync port of the destination host.]]></description>
+ <type>input</type>
+ <size>3</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Admin Password</fielddescr>
+ <fieldname>varsyncpassword</fieldname>
+ <description><![CDATA[Password of the user "admin" on the destination host.]]></description>
+ <type>password</type>
+ <size>20</size>
+ </rowhelperfield>
+ <rowhelperfield>
+ <fielddescr>Start Suricata</fielddescr>
+ <fieldname>varsyncsuricatastart</fieldname>
+ <description><![CDATA[Start Suricata on target host if not already running.]]></description>
+ <type>checkbox</type>
+ <value>ON</value>
+ </rowhelperfield>
+ </rowhelper>
+ </field>
+ </fields>
+ <custom_delete_php_command>
+ </custom_delete_php_command>
+ <custom_php_resync_config_command>
+ write_config("Suricata pkg: updating CARP sync info.");suricata_sync_on_changes();
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/suricata/suricata_uninstall.php b/config/suricata/suricata_uninstall.php
index 2317578e..c8048a1c 100644
--- a/config/suricata/suricata_uninstall.php
+++ b/config/suricata/suricata_uninstall.php
@@ -44,9 +44,12 @@ global $config, $g;
$suricatadir = SURICATADIR;
$suricatalogdir = SURICATALOGDIR;
+$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..."));
@@ -58,7 +61,7 @@ killbyname("suricata");
sleep(1);
// Delete any leftover suricata PID files in /var/run
-array_map('@unlink', glob("/var/run/suricata_*.pid"));
+unlink_if_exists("{$g['varrun_path']}/suricata_*.pid");
/* Make sure all active Barnyard2 processes are terminated */
/* Log a message only if a running process is detected */
@@ -68,26 +71,35 @@ killbyname("barnyard2");
sleep(1);
// Delete any leftover barnyard2 PID files in /var/run
-array_map('@unlink', glob("/var/run/barnyard2_*.pid"));
-
-/* Remove the suricata user and group */
-mwexec('/usr/sbin/pw userdel suricata; /usr/sbin/pw groupdel suricata', true);
+unlink_if_exists("{$g['varrun_path']}/barnyard2_*.pid");
/* Remove the Suricata cron jobs. */
-install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/www/suricata/suricata_check_for_rule_updates.php", false);
-install_cron_job("/usr/bin/nice -n20 /usr/local/bin/php -f /usr/local/pkg/suricata/suricata_check_cron_misc.inc", false);
-install_cron_job("pfctl -t {$suri_pf_table} -T expire" , false);
+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}");
+}
+
+/**************************************************/
+/* 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 */
@@ -108,19 +120,26 @@ if (!empty($widgets)) {
}
}
$config['widgets']['sequence'] = implode(",", $widgetlist);
- write_config();
}
-@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");
+
+/*******************************************************/
+/* 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}");
+ 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 c20ca8db..a8b06ebe 100644
--- a/config/suricata/suricata_yaml_template.inc
+++ b/config/suricata/suricata_yaml_template.inc
@@ -15,6 +15,10 @@ max-pending-packets: {$max_pend_pkts}
# Runmode the engine should use.
runmode: autofp
+# If set to auto, the variable is internally switched to 'router' in IPS
+# mode and 'sniffer-only' in IDS mode.
+host-mode: auto
+
# Specifies the kind of flow load balancer used by the flow pinned autofp mode.
autofp-scheduler: active-packets
@@ -29,7 +33,7 @@ default-log-dir: {$suricatalogdir}suricata_{$if_real}{$suricata_uuid}
# Configure the type of alert (and other) logging.
outputs:
- # alert_pf blocking plugin
+ # alert-pf blocking plugin
- alert-pf:
enabled: {$suri_blockoffenders}
kill-state: {$suri_killstates}
@@ -55,9 +59,7 @@ outputs:
enabled: {$http_log_enabled}
filename: http.log
append: {$http_log_append}
- #extended: yes # enable this for extended logging information
- #custom: yes # enabled the custom logging format (defined by customformat)
- #customformat: "%{%D-%H:%M:%S}t.%z %{X-Forwarded-For}i %H %m %h %u %s %B %a:%p -> %A:%P"
+ extended: {$http_log_extended}
filetype: regular
- pcap-log:
@@ -82,8 +84,8 @@ outputs:
- syslog:
enabled: {$alert_syslog}
identity: suricata
- facility: auth
- level: Info
+ facility: {$alert_syslog_facility}
+ level: {$alert_syslog_priority}
- drop:
enabled: no
@@ -94,8 +96,8 @@ outputs:
- file-store:
enabled: {$file_store_enabled}
log-dir: files
- force-magic: no
- force-md5: no
+ force-magic: {$json_log_magic}
+ force-md5: {$json_log_md5}
waldo: file.waldo
- file-log:
@@ -106,6 +108,21 @@ outputs:
force-magic: {$json_log_magic}
force-md5: {$json_log_md5}
+ - dns-log:
+ enabled: {$dns_log_enabled}
+ filename: dns.log
+ append: {$dns_log_append}
+ filetype: regular
+
+ - eve-log:
+ enabled: {$enable_eve_log}
+ type: {$eve_output_type}
+ filename: eve.json
+ identity: "suricata"
+ facility: {$eve_systemlog_facility}
+ level: {$eve_systemlog_priority}
+ types: {$eve_out_types}
+
# Magic file. The extension .mgc is added to the value here.
magic-file: /usr/share/misc/magic
@@ -208,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:
@@ -233,12 +250,13 @@ logging:
filename: {$suricatalogdir}suricata_{$if_real}{$suricata_uuid}/suricata.log
- syslog:
enabled: {$suricata_use_syslog}
- facility: auth
+ facility: {$suricata_use_syslog_facility}
format: "[%i] <%d> -- "
pcap:
- interface: {$if_real}
checksum-checks: auto
+ promisc: {$intf_promisc_mode}
# For FreeBSD ipfw(8) divert(4) support.
# ipfw add 100 divert 8000 ip from any to any
@@ -268,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: {$suricatacfgdir}/iprep/categories.txt
-#default-reputation-path: {$suricatacfgdir}/iprep
-#reputation-files:
-# - reputation.list
+{$iprep_config}
# Limit for the maximum number of asn1 frames to decode (default 256)
asn1-max-frames: {$asn1_max_frames}
@@ -293,6 +307,47 @@ pcre:
match-limit: 3500
match-limit-recursion: 1500
+# Holds details on the app-layer. The protocols section details each protocol.
+app-layer:
+ protocols:
+ tls:
+ enabled: {$tls_parser}
+ detection-ports:
+ dp: 443
+ #no-reassemble: yes
+ dcerpc:
+ enabled: {$dcerpc_parser}
+ ftp:
+ enabled: {$ftp_parser}
+ ssh:
+ enabled: {$ssh_parser}
+ smtp:
+ enabled: {$smtp_parser}
+ imap:
+ enabled: {$imap_parser}
+ msn:
+ enabled: {$msn_parser}
+ smb:
+ enabled: {$smb_parser}
+ detection-ports:
+ dp: 139
+ dns:
+ global-memcap: {$dns_global_memcap}
+ state-memcap: {$dns_state_memcap}
+ request-flood: {$dns_request_flood_limit}
+
+ tcp:
+ enabled: {$dns_parser_tcp}
+ detection-ports:
+ dp: 53
+ udp:
+ enabled: {$dns_parser_udp}
+ detection-ports:
+ dp: 53
+ http:
+ enabled: {$http_parser}
+ memcap: {$http_parser_memcap}
+
###########################################################################
# Configure libhtp.
libhtp: