From 31905aef52131b7067441f8f7902b343a4588f72 Mon Sep 17 00:00:00 2001 From: bmeeks8 Date: Tue, 9 Apr 2013 20:10:36 -0400 Subject: Update Snort to 2.5.5 - New features and bug fixes --- config/snort/snort.inc | 331 +++++++++++++++---- config/snort/snort.xml | 10 +- config/snort/snort_check_for_rule_updates.php | 459 ++++++++++++++++++-------- config/snort/snort_define_servers.php | 4 +- config/snort/snort_download_updates.php | 77 +++-- config/snort/snort_interfaces.php | 8 +- config/snort/snort_interfaces_edit.php | 27 +- config/snort/snort_interfaces_global.php | 147 +++++---- config/snort/snort_log_view.php | 86 +++++ config/snort/snort_preprocessors.php | 103 ++++-- config/snort/snort_rules.php | 39 ++- config/snort/snort_rules_edit.php | 10 +- config/snort/snort_rulesets.php | 155 ++++++--- 13 files changed, 1076 insertions(+), 380 deletions(-) create mode 100644 config/snort/snort_log_view.php (limited to 'config/snort') diff --git a/config/snort/snort.inc b/config/snort/snort.inc index 27d0b7e5..d8a7cc19 100755 --- a/config/snort/snort.inc +++ b/config/snort/snort.inc @@ -37,17 +37,46 @@ require_once("functions.inc"); // Needed on 2.0 because of filter_get_vpns_list() require_once("filter.inc"); +// Explicitly declare these as global so they work through function call includes +global $snort_rules_file, $snort_version, $emerging_threats_version, $snort_rules_upd_log; +global $flowbit_rules_file, $snort_enforcing_rules_file, $rebuild_rules, $is_postinstall; +global $snort_community_rules_filename, $snort_community_rules_url, $emergingthreats_filename; + /* package version */ $snort_version = "2.9.4.1"; -$pfSense_snort_version = "2.5.4"; +$pfSense_snort_version = "2.5.5"; $snort_package_version = "Snort {$snort_version} pkg v. {$pfSense_snort_version}"; + +// Define SNORTDIR and SNORTLIBDIR constants according to FreeBSD version (PBI support or no PBI) +if (floatval(php_uname("r")) >= 8.3) { + exec("/usr/local/sbin/pbi_info | grep 'snort-{$snort_version}' | xargs /usr/local/sbin/pbi_info | awk '/Prefix/ {print $2}'",$pbidirarray); + $snort_pbidir = "{$pbidirarray[0]}"; + define("SNORTDIR", "{$snort_pbidir}/etc/snort"); + define("SNORTLIBDIR", "{$snort_pbidir}/lib/snort"); +} +else { + define("SNORTDIR", "/usr/local/etc/snort"); + define("SNORTLIBDIR", "/usr/local/lib/snort"); +} + +define("SNORTLOGDIR", "/var/log/snort"); + +/* Important file definitions */ $snort_rules_file = "snortrules-snapshot-2941.tar.gz"; $emerging_threats_version = "2.9.0"; +$emergingthreats_filename = "emerging.rules.tar.gz"; +$snort_community_rules_url = "https://s3.amazonaws.com/snort-org/www/rules/community/"; +$snort_community_rules_filename = "community-rules.tar.gz"; $flowbit_rules_file = "flowbit-required.rules"; $snort_enforcing_rules_file = "snort.rules"; +$snort_rules_upd_log = SNORTLOGDIR; +$snort_rules_upd_log .= "/snort_rules_update.log"; -define("SNORTDIR", "/usr/local/etc/snort"); -define("SNORTLOGDIR", "/var/log/snort"); +/* Rebuild Rules Flag -- if "on", rebuild enforcing rules and flowbit-rules files */ +$rebuild_rules = "off"; + +/* Post-install Flag -- normally "false" except during post-install of package */ +$is_postinstall = false; if (!is_array($config['installedpackages']['snortglobal'])) $config['installedpackages']['snortglobal'] = array(); @@ -427,9 +456,14 @@ function snort_post_delete_logs($snort_uuid = 0) { } function snort_postinstall() { - global $config, $g; + global $config, $g, $snort_rules_file, $emerging_threats_version; + global $snort_version, $rebuild_rules, $is_postinstall; $snortdir = SNORTDIR; + $snortlibdir = SNORTLIBDIR; + + /* Set flag for post-install in progress */ + $is_postinstall = true; /* cleanup default files */ @rename("{$snortdir}/snort.conf-sample", "{$snortdir}/snort.conf"); @@ -440,25 +474,41 @@ function snort_postinstall() { @rename("{$snortdir}/generators-sample", "{$snortdir}/generators"); @rename("{$snortdir}/reference.config-sample", "{$snortdir}/reference.config"); @rename("{$snortdir}/gen-msg.map-sample", "{$snortdir}/gen-msg.map"); + + /* fix up the preprocessor rules filenames from a PBI package install */ + $preproc_rules = array("decoder.rules", "preprocessor.rules", "sensitive-data.rules"); + foreach ($preproc_rules as $file) { + if (file_exists("{$snortdir}/preproc_rules/{$file}-sample")) + @rename("{$snortdir}/preproc_rules/{$file}-sample", "{$snortdir}/preproc_rules/{$file}"); + } + + /* Remove any previously installed scripts since we rebuild them */ @unlink("{$snortdir}/sid"); @unlink("/usr/local/etc/rc.d/snort"); @unlink("/usr/local/etc/rc.d/barnyard2"); - /* remove example files */ - if (file_exists('/usr/local/lib/snort/dynamicrules/lib_sfdynamic_example_rule.so.0')) - exec('rm /usr/local/lib/snort/dynamicrules/lib_sfdynamic_example*'); - - if (file_exists('/usr/local/lib/snort/dynamicpreprocessor/lib_sfdynamic_preprocessor_example.so')) - exec('/bin/rm /usr/local/lib/snort/dynamicpreprocessor/lib_sfdynamic_preprocessor_example*'); + /* remove example library files */ + $files = glob("{$snortlibdir}/dynamicrules/*_example*"); + foreach ($files as $f) + @unlink($f); + $files = glob("{$snortlibdir}/dynamicpreprocessor/*_example*"); + foreach ($files as $f) + @unlink($f); /* remake saved settings */ if ($config['installedpackages']['snortglobal']['forcekeepsettings'] == 'on') { update_status(gettext("Saved settings detected...")); - update_output_window(gettext("Please wait... rebuilding files...")); + update_output_window(gettext("Please wait... rebuilding installation with saved settings...")); @include_once("/usr/local/pkg/snort/snort_check_for_rule_updates.php"); + update_status(gettext("Generating snort.conf configuration file from saved settings...")); + $rebuild_rules = "on"; sync_snort_package_config(); - update_output_window(gettext("Finnished Rebuilding files...")); + $rebuild_rules = "off"; + update_output_window(gettext("Finished rebuilding files...")); } + + /* Done with post-install, so clear flag */ + $is_postinstall = false; } function snort_Getdirsize($node) { @@ -693,12 +743,15 @@ function snort_rules_up_install_cron($should_install) { /* Only run when all ifaces needed to sync. Expects filesystem rw */ function sync_snort_package_config() { - global $config, $g; + global $config, $g, $flowbit_rules_file, $snort_enforcing_rules_file; + global $snort_version, $rebuild_rules; + + $snortdir = SNORTDIR; conf_mount_rw(); - /* do not start config build if rules is empty */ - if (!is_array($config['installedpackages']['snortglobal']) && !is_array($config['installedpackages']['snortglobal']['rule'])) { + /* do not start config build if rules is empty or there are no Snort settings */ + if (!is_array($config['installedpackages']['snortglobal']) || !is_array($config['installedpackages']['snortglobal']['rule'])) { exec('/bin/rm /usr/local/etc/rc.d/snort.sh'); conf_mount_ro(); return; @@ -708,10 +761,10 @@ function sync_snort_package_config() { foreach ($snortconf as $value) { $if_real = snort_get_real_interface($value['interface']); - /* create snort configuration file */ + /* create a snort.conf file for interface */ snort_generate_conf($value); - /* create barnyard2 configuration file */ + /* create barnyard2.conf file for interface */ if ($value['barnyard_enable'] == 'on') snort_create_barnyard2_conf($value, $if_real); } @@ -748,7 +801,7 @@ function snort_build_sid_msg_map($rules_path, $sid_file) { /* First check if we were passed a directory, a single file */ /* or an array of filenames to read. Set our $rule_files */ /* variable accordingly. If we can't figure it out, return */ - /* an empty rules map array. */ + /* and don't write a sid_msg_map file. */ if (is_string($rules_path)) { if (is_dir($rules_path)) $rule_files = glob($rules_path . "*.rules"); @@ -1272,11 +1325,13 @@ function snort_write_flowbit_rules_file($flowbit_rules, $rule_file) { /* given. */ /************************************************/ + global $flowbit_rules_file; + /* See if we were passed a directory or full */ /* filename to write the rules to, and adjust */ /* the destination argument accordingly. */ if (is_dir($rule_file)) - $rule_file = rtrim($rule_file, '/').'/flowbit-required.rules'; + $rule_file = rtrim($rule_file, '/')."/{$flowbit_rules_file}"; if (empty($flowbit_rules)) { @file_put_contents($rule_file, ""); @@ -1363,7 +1418,7 @@ function snort_write_enforcing_rules_file($rule_map, $rule_path) { global $snort_enforcing_rules_file; - $rule_file = "/snort.rules"; + $rule_file = "/{$snort_enforcing_rules_file}"; /* See if we were passed a directory or full */ /* filename to write the rules to, and adjust */ @@ -1584,6 +1639,7 @@ case $1 in rc_stop ;; restart) + rc_stop rc_start ;; esac @@ -1642,7 +1698,7 @@ function snort_generate_barnyard2_conf($snortcfg, $if_real) { config reference_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/reference.config config classification_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/classification.config config gen_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/gen-msg.map -config sid_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/sid-msg.map +config sid_file: {$snortdir}/snort_{$snort_uuid}_{$if_real}/sid-msg.map config hostname: $snortbarnyardlog_hostname_info_chk config interface: {$if_real} @@ -1671,12 +1727,13 @@ EOD; } function snort_deinstall() { - global $config, $g; + + global $config, $g, $snort_rules_upd_log; $snortdir = SNORTDIR; - $snortlogdir = SNORTLOGDIR; + $snortlibdir = SNORTLIBDIR; - /* decrease bpf buffers back to 4096, from 20480 */ + /* Make sure all active Snort processes are terminated */ mwexec('/usr/bin/killall snort', true); sleep(2); mwexec('/usr/bin/killall -9 snort', true); @@ -1685,9 +1742,11 @@ function snort_deinstall() { sleep(2); mwexec('/usr/bin/killall -9 barnyard2', true); sleep(2); + + /* Remove the snort user and group */ mwexec('/usr/sbin/pw userdel snort; /usr/sbin/pw groupdel snort', true); - /* Remove snort cron entries Ugly code needs smoothness*/ + /* Remove snort cron entries Ugly code needs smoothness */ if (!function_exists('snort_deinstall_cron')) { function snort_deinstall_cron($crontask) { global $config, $g; @@ -1709,22 +1768,49 @@ function snort_deinstall() { } } - mwexec("/bin/rm {$snortdir}/*.md5; /bin/rm -r {$snortdir}/snort_*"); + /* Remove all the Snort cron jobs. */ snort_deinstall_cron("snort2c"); snort_deinstall_cron("snort_check_for_rule_updates.php"); snort_deinstall_cron("snort_check_cron_misc.inc"); configure_cron(); + /**********************************************************/ + /* Test for existence of library backup tarballs in /tmp. */ + /* If these are present, then a package "delete" */ + /* operation is in progress and we need to wipe out the */ + /* configuration files. Otherwise we leave the binary- */ + /* side configuration intact since only a GUI files */ + /* deinstall and reinstall operation is in progress. */ + /* */ + /* XXX: hopefully a better method presents itself in */ + /* future versions of pfSense. */ + /**********************************************************/ + if (file_exists("/tmp/pkg_libs.tgz") || file_exists("/tmp/pkg_bins.tgz")) { + mwexec("/bin/rm -rf {$snortdir}"); + mwexec("/bin/rm -rf {$snortlibdir}/dynamicrules"); + } + /* Keep this as a last step */ - if ($config['installedpackages']['snortglobal']['forcekeepsettings'] != 'on') + if ($config['installedpackages']['snortglobal']['forcekeepsettings'] != 'on') { unset($config['installedpackages']['snortglobal']); + @unlink("{$snort_rules_upd_log}"); + } } function snort_prepare_rule_files($snortcfg, $snortcfgdir) { - global $snort_enforcing_rules_file, $flowbit_rules_file; + + global $snort_enforcing_rules_file, $flowbit_rules_file, $rebuild_rules; $snortdir = SNORTDIR; + /* If there is no reason to rebuild the rules, exit to save time. */ + if ($rebuild_rules == "off") + return; + + /* Log a message for rules rebuild in progress */ + log_error(gettext("Updating rules configuration for: " . snort_get_friendly_interface($snortcfg['interface']) . " ...")); + + /* Only rebuild rules if some are selected or an IPS Policy is enabled */ if (!empty($snortcfg['rulesets']) || $snortcfg['ips_policy_enable'] == 'on') { $enabled_rules = array(); $enabled_files = array(); @@ -1741,16 +1827,6 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { $enabled_rules = snort_load_rules_map($enabled_files); } - /* Remove any existing rules files (except custom rules) prior to building a new set. */ - foreach (glob("{$snortcfgdir}/rules/*.rules") as $file) { - $tmpfile = basename($file); - if (in_array("{$snortdir}/rules/{$tmpfile}", $enabled_files)) - continue; - if ($tmpfile != "custom.rules" && $tmpfile != $flowbit_rules_file && - $tmpfile != $snort_enforcing_rules_file) - @unlink($file); - } - /* Check if a pre-defined Snort VRT policy is selected. If so, */ /* add all the VRT policy rules to our enforcing rule set. */ if (!empty($snortcfg['ips_policy'])) { @@ -1773,9 +1849,12 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { /* Process any enablesid or disablesid modifications for the selected rules. */ snort_modify_sids($enabled_rules, $snortcfg); - /* Check for and disable any rules dependent upon disabled preprocessors. */ - log_error('Checking for and disabling any rules dependent upon disabled preprocessors for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); - snort_filter_preproc_rules($snortcfg, $enabled_rules); + /* Check for and disable any rules dependent upon disabled preprocessors if */ + /* this option is enabled for the interface. */ + if ($snortcfg['preproc_auto_rule_disable'] == "on") { + log_error('Auto-disabling rules dependent on disabled preprocessors for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); + snort_filter_preproc_rules($snortcfg, $enabled_rules); + } /* Write the enforcing rules file to the Snort interface's "rules" directory. */ snort_write_enforcing_rules_file($enabled_rules, "{$snortcfgdir}/rules/{$snort_enforcing_rules_file}"); @@ -1783,9 +1862,19 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { /* If auto-flowbit resolution is enabled, generate the dependent flowbits rules file. */ if ($snortcfg['autoflowbitrules'] == 'on') { - log_error('Resolving and auto-enabling flowbit required rules for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); + log_error('Resolving and auto-enabling any flowbit-required rules for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); $enabled_files[] = "{$snortcfgdir}/rules/{$snort_enforcing_rules_file}"; - snort_write_flowbit_rules_file(snort_resolve_flowbits($enabled_files), "{$snortcfgdir}/rules/{$flowbit_rules_file}"); + $fbits = snort_resolve_flowbits($enabled_files); + + /* Check for and disable any flowbit-required rules dependent upon */ + /* disabled preprocessors if this option is enabled for the interface. */ + if ($snortcfg['preproc_auto_rule_disable'] == "on") { + log_error('Auto-disabling flowbit-required rules dependent on disabled preprocessors for ' . snort_get_friendly_interface($snortcfg['interface']) . '...'); + snort_filter_preproc_rules($snortcfg, $fbits, true); + } + snort_filter_preproc_rules($snortcfg, $fbits, true); + snort_write_flowbit_rules_file($fbits, "{$snortcfgdir}/rules/{$flowbit_rules_file}"); + unset($fbits); } else /* Just put an empty file to always have the file present */ snort_write_flowbit_rules_file(array(), "{$snortcfgdir}/rules/{$flowbit_rules_file}"); @@ -1803,10 +1892,11 @@ function snort_prepare_rule_files($snortcfg, $snortcfgdir) { /* Build a new sid-msg.map file from the enabled */ /* rules and copy it to the interface directory. */ + log_error(gettext("Building new sig-msg.map file for " . snort_get_friendly_interface($snortcfg['interface']) . "...")); snort_build_sid_msg_map("{$snortcfgdir}/rules/", "{$snortcfgdir}/sid-msg.map"); } -function snort_filter_preproc_rules($snortcfg, &$active_rules) { +function snort_filter_preproc_rules($snortcfg, &$active_rules, $persist_log = false) { /**************************************************/ /* This function checks the $active_rules array */ @@ -1819,11 +1909,22 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { /* the interface */ /* $active_rules -> rules_map array of enabled */ /* rules for the interface */ + /* */ + /* NOTE: This feature must be enabled in the GUI */ + /* by the user. Use of this feature can */ + /* severely degrade Snort's ability to */ + /* detect threats by disabling potentially */ + /* crucial detection rules. */ /**************************************************/ global $config; - if (empty($active_rules)) + $snortlogdir = SNORTLOGDIR; + $disabled_count = 0; + $log_msg = array(); + + /* Check if no rules or if this option is disabled */ + if (empty($active_rules) || $snortcfg['preproc_auto_rule_disable'] <> 'on') return; /*************************************************** @@ -1833,8 +1934,20 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { * IMPORTANT -- Keep this part of the code current * * with changes to preprocessor rule options in * * Snort VRT rules. * + * * + * * + * Format of array is: * + * "rule_option" => "dependent_preprocessor" * + * * + * Last Update: 04/05/2013 * + * * + * Added: http_inspect content modifiers and * + * various "service" metadata values. * + * * ***************************************************/ $rule_opts_preprocs = array("ssl_version:" => "ssl_preproc","ssl_state:" => "ssl_preproc", + "service ssl" => "ssl_preproc", "service ftp" => "ftp_preprocessor", + "service telnet" => "ftp_preprocessor", "service dns" => "dns_preprocessor", "dce_iface:" => "dce_rpc_2", "dce_opnum:" => "dce_rpc_2", "dce_stub_data;" => "dce_rpc_2", "sd_pattern:" => "sensitive_data", "sip_method:" => "sip_preproc", "sip_stat_code:" => "sip_preproc", @@ -1843,7 +1956,16 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { "gtp_version:" => "gtp_preproc", "modbus_func:" => "modbus_preproc", "modbus_unit:" => "modbus_preproc", "modbus_data;" => "modbus_preproc", "dnp3_func:" => "dnp3_preproc", "dnp3_obj:" => "dnp3_preproc", - "dnp3_ind:" => "dnp3_preproc", "dnp3_data;" => "dnp3_preproc"); + "dnp3_ind:" => "dnp3_preproc", "dnp3_data;" => "dnp3_preproc", + "http_client_body;" => "http_inspect", "http_cookie;" => "http_inspect", + "http_raw_cookie;" => "http_inspect", "http_header;" => "http_inspect", + "http_raw_header;" => "http_inspect", "http_method;" => "http_inspect", + "http_uri;" => "http_inspect", "http_raw_uri;" => "http_inspect", + "http_stat_code;" => "http_inspect", "http_stat_msg;" => "http_inspect", + "uricontent:" => "http_inspect", "urilen:" => "http_inspect", + "http_encode;" => "http_inspect", "service http" => "http_inspect", + "service imap" => "imap_preproc", "service pop2" => "pop_preproc", + "service pop3" => "pop_preproc", "service smtp" => "smtp_preprocessor"); /*************************************************** * Iterate the enabled rules, and check for rule * @@ -1855,32 +1977,94 @@ function snort_filter_preproc_rules($snortcfg, &$active_rules) { ***************************************************/ foreach ($active_rules as $k1 => $rulem) { foreach ($rulem as $k2 => $v) { + /* If rule is already disabled, skip it. */ if ($v['disabled'] == 1) continue; + foreach ($rule_opts_preprocs as $opt => $preproc) { - $pcre = "/\s*\b" . $opt . "/i"; + $pcre = "/\s*\b" . preg_quote($opt) . "/i"; if (($snortcfg[$preproc] != 'on') && preg_match($pcre, $v['rule'])) { $active_rules[$k1][$k2]['rule'] = "# " . $v['rule']; $active_rules[$k1][$k2]['disabled'] = 1; + $disabled_count++; + + /* Accumulate auto-disabled rules for logging */ + $tmp = $active_rules[$k1][$k2]['category'] . " "; + $tmp .= "{$k1}:{$k2} Preproc: {$preproc} Param: {$opt}"; + $log_msg[] = $tmp; break; } } } } + + /***************************************************************/ + /* If we are persisting the log from the last pass, then open */ + /* the log file in append mode. Otherwise open in overwrite */ + /* to clear the log in case we have zero disabled rules. */ + /* */ + /* Typically "persist log" mode is used on the second pass */ + /* when flowbit-required rules are being assessed after the */ + /* primary enforcing rules have been evaluated. */ + /***************************************************************/ + $iface = snort_get_friendly_interface($snortcfg['interface']); + $file = "{$snortlogdir}/{$iface}_disabled_preproc_rules.log"; + if ($persist_log) + $fp = fopen($file, 'a'); + else + $fp = fopen($file, 'w'); + + /***************************************************/ + /* Log a warning if we auto-disabled any rules */ + /* just so the user is aware protection is less */ + /* than optimal with the preprocessors disabled. */ + /***************************************************/ + if ($disabled_count > 0) { + log_error(gettext("Warning: auto-disabled {$disabled_count} rules due to disabled preprocessor dependencies.")); + natcasesort($log_msg); + if ($fp) { + /* Only write the header when not persisting the log */ + if (!$persist_log) { + @fwrite($fp, "#\n# Run Time: " . date("Y-m-d H:i:s") . "\n#\n"); + @fwrite($fp, "#\n# These rules were auto-disabled because they contain options or operators\n"); + @fwrite($fp, "# dependent on preprocessors that are currently NOT ENABLED on the Preprocessors\n"); + @fwrite($fp, "# tab. Without these dependent preprocessors enabled, Snort would fail to start\n"); + @fwrite($fp, "# if the rules listed below were enabled. Therefore the listed rules have been\n"); + @fwrite($fp, "# automatically disabled. This behavior is controlled by the Auto-Rule Disable\n"); + @fwrite($fp, "# feature on the Preprocessors tab.\n#\n"); + @fwrite($fp, "# WARNING: Using the auto-disable rule feature is not recommended because it can\n"); + @fwrite($fp, "# significantly reduce the threat detection capabilities of Snort!\n#\n"); + @fwrite($fp, "# Log Format is: RULE CATEGORY GID:SID PREPROC METADATA/CONTENT PARAMETER\n#\n"); + } + foreach ($log_msg as $m) { + @fwrite($fp, $m . "\n"); + } + } + log_error(gettext("See '{$file}' for list of auto-disabled rules.")); + unset($log_msg); + } + if ($fp) + fclose($fp); } function snort_generate_conf($snortcfg) { - global $config, $g; + + global $config, $g, $flowbit_rules_file, $snort_enforcing_rules_file, $rebuild_rules; $snortdir = SNORTDIR; + $snortlibdir = SNORTLIBDIR; $snortlogdir = SNORTLOGDIR; - $flowbit_rules_file = "flowbit-required.rules"; - $snort_enforcing_rules_file = "snort.rules"; if (!is_array($config['installedpackages']['snortglobal']['rule'])) return; + /* See if we should protect and not modify the preprocessor rules files */ + if (!empty($snortcfg['protect_preproc_rules'])) + $protect_preproc_rules = $snortcfg['protect_preproc_rules']; + else + $protect_preproc_rules = "off"; + $if_real = snort_get_real_interface($snortcfg['interface']); $snort_uuid = $snortcfg['uuid']; $snortcfgdir = "{$snortdir}/snort_{$snort_uuid}_{$if_real}"; @@ -1903,8 +2087,8 @@ function snort_generate_conf($snortcfg) { "{$snortlogdir}/snort_{$if_real}{$snort_uuid}", "{$snortlogdir}/snort_{$if_real}{$snort_uuid}/barnyard2", "{$snortcfgdir}/preproc_rules", - "dynamicrules" => "/usr/local/lib/snort/dynamicrules", - "dynamicengine" => "/usr/local/lib/snort/dynamicengine", + "dynamicrules" => "{$snortlibdir}/dynamicrules", + "dynamicengine" => "{$snortlibdir}/dynamicengine", "dynamicpreprocessor" => "{$snortcfgdir}/dynamicpreprocessor" ); foreach ($snort_dirs as $dir) { @@ -1912,13 +2096,24 @@ function snort_generate_conf($snortcfg) { safe_mkdir($dir); } + /********************************************************************/ + /* For fail-safe on an initial startup following installation, and */ + /* before a rules update has occurred, copy the default config */ + /* files to the interface directory. If files already exist in */ + /* the interface directory, or they are newer, that means a rule */ + /* update has been done and we should leave the customized files */ + /* put in place by the rules update process. */ + /********************************************************************/ $snort_files = array("gen-msg.map", "classification.config", "reference.config", "sid-msg.map", "unicode.map", "threshold.conf", "preproc_rules/preprocessor.rules", "preproc_rules/decoder.rules", "preproc_rules/sensitive-data.rules" ); foreach ($snort_files as $file) { - if (file_exists("{$snortdir}/{$file}")) - @copy("{$snortdir}/{$file}", "{$snortcfgdir}/{$file}"); + if (file_exists("{$snortdir}/{$file}")) { + $ftime = filemtime("{$snortdir}/{$file}"); + if (!file_exists("{$snortcfgdir}/{$file}") || ($ftime > filemtime("{$snortcfgdir}/{$file}"))) + @copy("{$snortdir}/{$file}", "{$snortcfgdir}/{$file}"); + } } /* define alertsystemlog */ @@ -2012,7 +2207,7 @@ EOD; if ((!empty($snortcfg['client_flow_depth'])) || ($snortcfg['client_flow_depth'] == '0')) $def_client_flow_depth_type = $snortcfg['client_flow_depth']; - if ($snortcfg['noalert_http_inspect'] == 'on') + if ($snortcfg['noalert_http_inspect'] == 'on' || empty($snortcfg['noalert_http_inspect'])) $noalert_http_inspect = "no_alerts "; else $noalert_http_inspect = ""; @@ -2257,6 +2452,16 @@ EOD; if (!empty($snortcfg['stream5_mem_cap'])) $def_stream5_mem_cap = ", memcap {$snortcfg['stream5_mem_cap']}"; + /* Default the HTTP_INSPECT preprocessor to "on" if not set. */ + /* The preprocessor is required by hundreds of Snort rules, */ + /* and without it Snort may not start and/or the number of */ + /* rules required to be disabled reduces Snort's capability. */ + /* Alerts from the HTTP_INSPECT preprocessor default to "off" */ + /* unless a specific value has been set by the user. */ + /**************************************************************/ + if (empty($snortcfg['http_inspect'])) + $snortcfg['http_inspect'] = 'on'; + /* define servers and ports snortdefservers */ $snort_servers = array ( "dns_servers" => "\$HOME_NET", "smtp_servers" => "\$HOME_NET", "http_servers" => "\$HOME_NET", @@ -2295,8 +2500,8 @@ EOD; if (!empty($snort_preproc_libs[$preproc])) { $preproclib = "libsf_" . $snort_preproc_libs[$preproc]; if (!file_exists($snort_dirs['dynamicpreprocessor'] . "{$preproclib}.so")) { - if (file_exists("/usr/local/lib/snort/dynamicpreprocessor/{$preproclib}.so")) { - @copy("/usr/local/lib/snort/dynamicpreprocessor/{$preproclib}.so", "{$snort_dirs['dynamicpreprocessor']}/{$preproclib}.so"); + if (file_exists("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so")) { + @copy("{$snortlibdir}/dynamicpreprocessor/{$preproclib}.so", "{$snort_dirs['dynamicpreprocessor']}/{$preproclib}.so"); $snort_preprocessors .= $$preproc; $snort_preprocessors .= "\n"; } else @@ -2318,22 +2523,26 @@ EOD; if (file_exists("{$snortcfgdir}/classification.config")) $snort_misc_include_rules .= "include {$snortcfgdir}/classification.config\n"; if (is_dir("{$snortcfgdir}/preproc_rules")) { - if ($snortcfg['sensitive_data'] == 'on') { + if ($snortcfg['sensitive_data'] == 'on' && $protect_preproc_rules == "off") { $sedcmd = '/^#alert.*classtype:sdf/s/^#//'; if (file_exists("{$snortcfgdir}/preproc_rules/sensitive-data.rules")) $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/sensitive-data.rules\n"; } else $sedcmd = '/^alert.*classtype:sdf/s/^/#/'; if (file_exists("{$snortcfgdir}/preproc_rules/decoder.rules") && - file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules")) { + file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules") && $protect_preproc_rules == "off") { @file_put_contents("{$g['tmp_path']}/sedcmd", $sedcmd); mwexec("/usr/bin/sed -I '' -f {$g['tmp_path']}/sedcmd {$snortcfgdir}/preproc_rules/preprocessor.rules"); mwexec("/usr/bin/sed -I '' -f {$g['tmp_path']}/sedcmd {$snortcfgdir}/preproc_rules/decoder.rules"); @unlink("{$g['tmp_path']}/sedcmd"); - $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/decoder.rules\n"; $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/preprocessor.rules\n"; - } else { + } else if (file_exists("{$snortcfgdir}/preproc_rules/decoder.rules") && + file_exists("{$snortcfgdir}/preproc_rules/preprocessor.rules") && $protect_preproc_rules == "on") { + $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/decoder.rules\n"; + $snort_misc_include_rules .= "include \$PREPROC_RULE_PATH/preprocessor.rules\n"; + } + else { $snort_misc_include_rules .= "config autogenerate_preprocessor_decoder_rules\n"; log_error("Seems preprocessor/decoder rules are missing, enabling autogeneration of them"); } diff --git a/config/snort/snort.xml b/config/snort/snort.xml index b18e66e1..fff8d251 100755 --- a/config/snort/snort.xml +++ b/config/snort/snort.xml @@ -46,8 +46,8 @@ Describe your package requirements here Currently there are no FAQ items provided. Snort - 2.9.2.3 - Services:2.9.2.3 pkg v. 2.5.3 + 2.9.4.1 + Services:2.9.4.1 pkg v. 2.5.5 /usr/local/pkg/snort/snort.inc Snort @@ -163,6 +163,11 @@ 077 http://www.pfsense.com/packages/config/snort/snort_interfaces_suppress_edit.php + + /usr/local/www/snort/ + 077 + http://www.pfsense.com/packages/config/snort/snort_log_view.php + @@ -177,3 +182,4 @@ snort_deinstall(); + diff --git a/config/snort/snort_check_for_rule_updates.php b/config/snort/snort_check_for_rule_updates.php index af5d378c..740dc591 100755 --- a/config/snort/snort_check_for_rule_updates.php +++ b/config/snort/snort_check_for_rule_updates.php @@ -31,54 +31,72 @@ require_once("functions.inc"); require_once("service-utils.inc"); -require_once("/usr/local/pkg/snort/snort.inc"); +require_once "/usr/local/pkg/snort/snort.inc"; -global $snort_gui_include; +global $snort_gui_include, $vrt_enabled, $et_enabled, $rebuild_rules, $snort_rules_upd_log; +global $protect_preproc_rules, $is_postinstall, $snort_community_rules_filename; +global $snort_community_rules_url, $snort_rules_file, $emergingthreats_filename; $snortdir = SNORTDIR; +$snortlibdir = SNORTLIBDIR; +$snortlogdir = SNORTLOGDIR; if (!isset($snort_gui_include)) $pkg_interface = "console"; -$tmpfname = "{$snortdir}/tmp/snort_rules_up"; -$snort_filename_md5 = "{$snort_rules_file}.md5"; -$snort_filename = "{$snort_rules_file}"; -$emergingthreats_filename_md5 = "emerging.rules.tar.gz.md5"; -$emergingthreats_filename = "emerging.rules.tar.gz"; - /* define checks */ $oinkid = $config['installedpackages']['snortglobal']['oinkmastercode']; $snortdownload = $config['installedpackages']['snortglobal']['snortdownload']; $emergingthreats = $config['installedpackages']['snortglobal']['emergingthreats']; +$snortcommunityrules = $config['installedpackages']['snortglobal']['snortcommunityrules']; $vrt_enabled = $config['installedpackages']['snortglobal']['snortdownload']; $et_enabled = $config['installedpackages']['snortglobal']['emergingthreats']; -/* Start of code */ -conf_mount_rw(); +/* Directory where we download rule tarballs */ +$tmpfname = "{$snortdir}/tmp/snort_rules_up"; + +/* Snort VRT rules files and URL */ +$snort_filename_md5 = "{$snort_rules_file}.md5"; +$snort_filename = "{$snort_rules_file}"; +$snort_rule_url = "http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/"; -if (!is_dir($tmpfname)) - exec("/bin/mkdir -p {$tmpfname}"); +/* Emerging Threats rules MD5 file */ +$emergingthreats_filename_md5 = "{$emergingthreats_filename}.md5"; -/* Set user agent to Mozilla */ -ini_set('user_agent','Mozilla/4.0 (compatible; MSIE 6.0)'); -ini_set("memory_limit","150M"); +/* Snort GPLv2 Community Rules MD5 file */ +$snort_community_rules_filename_md5 = "{$snort_community_rules_filename}.md5"; + +/* Start of code */ +conf_mount_rw(); /* remove old $tmpfname files */ if (is_dir("{$tmpfname}")) exec("/bin/rm -r {$tmpfname}"); -/* Make sure snortdir exits */ +/* Make sure required snortdirs exsist */ exec("/bin/mkdir -p {$snortdir}/rules"); exec("/bin/mkdir -p {$snortdir}/signatures"); +exec("/bin/mkdir -p {$snortdir}/preproc_rules"); exec("/bin/mkdir -p {$tmpfname}"); -exec("/bin/mkdir -p /usr/local/lib/snort/dynamicrules"); +exec("/bin/mkdir -p {$snortlibdir}/dynamicrules"); +exec("/bin/mkdir -p {$snortlogdir}"); + +/* See if we need to automatically clear the Update Log based on 1024K size limit */ +if (file_exists($snort_rules_upd_log)) { + if (1048576 < filesize($snort_rules_upd_log)) + exec("/bin/rm -r {$snort_rules_upd_log}"); +} + +/* Log start time for this rules update */ +error_log(gettext("Starting rules update... Time: " . date("Y-m-d H:i:s") . "\n"), 3, $snort_rules_upd_log); /* download md5 sig from snort.org */ if ($snortdownload == 'on') { - update_status(gettext("Downloading snort.org md5 file...")); + update_status(gettext("Downloading Snort VRT md5 file...")); + error_log(gettext("\tDownloading Snort VRT md5 file...\n"), 3, $snort_rules_upd_log); $max_tries = 4; while ($max_tries > 0) { - $image = @file_get_contents("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename_md5}"); + $image = @file_get_contents("{$snort_rule_url}{$snort_filename_md5}"); if (false === $image) { $max_tries--; if ($max_tries > 0) @@ -88,14 +106,16 @@ if ($snortdownload == 'on') { break; } log_error("Snort MD5 Attempts: " . (4 - $max_tries + 1)); + error_log("\tChecking Snort VRT md5 file...\n", 3, $snort_rules_upd_log); @file_put_contents("{$tmpfname}/{$snort_filename_md5}", $image); if (0 == filesize("{$tmpfname}/{$snort_filename_md5}")) { update_status(gettext("Please wait... You may only check for New Rules every 15 minutes...")); log_error(gettext("Please wait... You may only check for New Rules every 15 minutes...")); update_output_window(gettext("Rules are released every month from snort.org. You may download the Rules at any time.")); $snortdownload = 'off'; + error_log(gettext("\tSnort VRT md5 download failed. Site may be offline or Oinkcode is not authorized for this level or version.\n"), 3, $snort_rules_upd_log); } else - update_status(gettext("Done downloading snort.org md5")); + update_status(gettext("Done downloading snort.org md5.")); } /* Check if were up to date snort.org */ @@ -104,8 +124,9 @@ if ($snortdownload == 'on') { $md5_check_new = file_get_contents("{$tmpfname}/{$snort_filename_md5}"); $md5_check_old = file_get_contents("{$snortdir}/{$snort_filename_md5}"); if ($md5_check_new == $md5_check_old) { - update_status(gettext("Snort rules are up to date...")); - log_error("Snort rules are up to date..."); + update_status(gettext("Snort VRT rules are up to date...")); + log_error(gettext("Snort VRT rules are up to date...")); + error_log(gettext("\tSnort VRT rules are up to date.\n"), 3, $snort_rules_upd_log); $snortdownload = 'off'; } } @@ -113,11 +134,12 @@ if ($snortdownload == 'on') { /* download snortrules file */ if ($snortdownload == 'on') { - update_status(gettext("There is a new set of Snort.org rules posted. Downloading...")); - log_error(gettext("There is a new set of Snort.org rules posted. Downloading...")); + update_status(gettext("There is a new set of Snort VRT rules posted. Downloading...")); + log_error(gettext("There is a new set of Snort VRT rules posted. Downloading...")); + error_log(gettext("\tThere is a new set of Snort VRT rules posted. Downloading...\n"), 3, $snort_rules_upd_log); $max_tries = 4; while ($max_tries > 0) { - download_file_with_progress_bar("http://www.snort.org/pub-bin/oinkmaster.cgi/{$oinkid}/{$snort_filename}", "{$tmpfname}/{$snort_filename}"); + download_file_with_progress_bar("{$snort_rule_url}{$snort_filename}", "{$tmpfname}/{$snort_filename}"); if (300000 > filesize("{$tmpfname}/$snort_filename")){ $max_tries--; if ($max_tries > 0) @@ -126,19 +148,104 @@ if ($snortdownload == 'on') { } else break; } - update_status(gettext("Done downloading rules file.")); + update_status(gettext("Done downloading Snort VRT rules file.")); log_error("Snort Rules Attempts: " . (4 - $max_tries + 1)); + error_log(gettext("\tDone downloading rules file.\n"),3, $snort_rules_upd_log); if (300000 > filesize("{$tmpfname}/$snort_filename")){ - update_output_window(gettext("Snort rules file download failed...")); - log_error(gettext("Snort rules file download failed...")); + update_output_window(gettext("Snort VRT rules file download failed...")); + log_error(gettext("Snort VRT rules file download failed...")); log_error("Failed Rules Filesize: " . filesize("{$tmpfname}/$snort_filename")); + error_log(gettext("\tSnort VRT rules file download failed. Snort VRT rules will not be updated.\n"), 3, $snort_rules_upd_log); $snortdownload = 'off'; } } +/* download md5 sig from Snort GPLv2 Community Rules */ +if ($snortcommunityrules == 'on') { + update_status(gettext("Downloading Snort GPLv2 Community Rules md5 file...")); + error_log(gettext("\tDownloading Snort GPLv2 Community Rules md5 file...\n"), 3, $snort_rules_upd_log); + $image = file_get_contents("{$snort_community_rules_url}{$snort_community_rules_filename_md5}"); + update_status(gettext("Done downloading Snort GPLv2 Community Rules md5")); + error_log(gettext("\tChecking Snort GPLv2 Community Rules md5.\n"), 3, $snort_rules_upd_log); + @file_put_contents("{$tmpfname}/{$snort_community_rules_filename_md5}", $image); + + /* See if the file download was successful, and turn off Snort GPLv2 update if it failed. */ + if (0 == filesize("{$tmpfname}/{$snort_community_rules_filename_md5}")){ + update_output_window(gettext("Snort GPLv2 Community Rules md5 file download failed. Community Rules will not be updated.")); + log_error(gettext("Snort GPLv2 Community Rules md5 file download failed. Community Rules will not be updated.")); + error_log(gettext("\tSnort GPLv2 Community Rules md5 file download failed. Community Rules will not be updated.\n"), 3, $snort_rules_upd_log); + $snortcommunityrules = 'off'; + } + + if (file_exists("{$snortdir}/{$snort_community_rules_filename_md5}") && $snortcommunityrules == "on") { + /* Check if were up to date Snort GPLv2 Community Rules */ + $snort_comm_md5_check_new = file_get_contents("{$tmpfname}/{$snort_community_rules_filename_md5}"); + $snort_comm_md5_check_old = file_get_contents("{$snortdir}/{$snort_community_rules_filename_md5}"); + if ($snort_comm_md5_check_new == $snort_comm_md5_check_old) { + update_status(gettext("Snort GPLv2 Community Rules are up to date...")); + log_error(gettext("Snort GPLv2 Community Rules are up to date...")); + error_log(gettext("\tSnort GPLv2 Community Rules are up to date.\n"), 3, $snort_rules_upd_log); + $snortcommunityrules = 'off'; + } + } +} + +/* download Snort GPLv2 Community rules file */ +if ($snortcommunityrules == "on") { + update_status(gettext("There is a new set of Snort GPLv2 Community Rules posted. Downloading...")); + log_error(gettext("There is a new set of Snort GPLv2 Community Rules posted. Downloading...")); + error_log(gettext("\tThere is a new set of Snort GPLv2 Community Rules posted. Downloading...\n"), 3, $snort_rules_upd_log); + download_file_with_progress_bar("{$snort_community_rules_url}{$snort_community_rules_filename}", "{$tmpfname}/{$snort_community_rules_filename}"); + + /* Test for a valid rules file download. Turn off Snort Community update if download failed. */ + if (150000 > filesize("{$tmpfname}/{$snort_community_rules_filename}")){ + update_output_window(gettext("Snort GPLv2 Community Rules file download failed...")); + log_error(gettext("Snort GPLv2 Community Rules file download failed...")); + log_error("Failed Rules Filesize: " . filesize("{$tmpfname}/{$snort_community_rules_filename}")); + error_log(gettext("\tSnort GPLv2 Community Rules file download failed. Community Rules will not be updated.\n"), 3, $snort_rules_upd_log); + $snortcommunityrules = 'off'; + } + else { + update_status(gettext('Done downloading Snort GPLv2 Community Rules file.')); + log_error("Snort GPLv2 Community Rules file update downloaded succsesfully"); + error_log(gettext("\tDone downloading Snort GPLv2 Community Rules file.\n"), 3, $snort_rules_upd_log); + } +} + +/* Untar Snort GPLv2 Community rules to tmp */ +if ($snortcommunityrules == 'on') { + safe_mkdir("{$snortdir}/tmp/community"); + if (file_exists("{$tmpfname}/{$snort_community_rules_filename}")) { + update_status(gettext("Extracting Snort GPLv2 Community Rules...")); + error_log(gettext("\tExtracting and installing Snort GPLv2 Community Rules...\n"), 3, $snort_rules_upd_log); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_community_rules_filename} -C {$snortdir}/tmp/community/"); + + $files = glob("{$snortdir}/tmp/community/community-rules/*.rules"); + foreach ($files as $file) { + $newfile = basename($file); + @copy($file, "{$snortdir}/rules/GPLv2_{$newfile}"); + } + /* base etc files for Snort GPLv2 Community rules */ + foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { + if (file_exists("{$snortdir}/tmp/community/community-rules/{$file}")) + @copy("{$snortdir}/tmp/community/community-rules/{$file}", "{$snortdir}/tmp/GPLv2_{$file}"); + } + + /* Copy snort community md5 sig to snort dir */ + if (file_exists("{$tmpfname}/{$snort_community_rules_filename_md5}")) { + update_status(gettext("Copying md5 signature to snort directory...")); + @copy("{$tmpfname}/$snort_community_rules_filename_md5", "{$snortdir}/{$snort_community_rules_filename_md5}"); + } + update_status(gettext("Extraction of Snort GPLv2 Community Rules completed...")); + error_log(gettext("\tInstallation of Snort GPLv2 Community Rules completed.\n"), 3, $snort_rules_upd_log); + exec("rm -r {$snortdir}/tmp/community"); + } +} + /* download md5 sig from emergingthreats.net */ if ($emergingthreats == 'on') { - update_status(gettext("Downloading emergingthreats md5 file...")); + update_status(gettext("Downloading EmergingThreats md5 file...")); + error_log(gettext("\tDownloading EmergingThreats md5 file...\n"), 3, $snort_rules_upd_log); /* If using Sourcefire VRT rules with ET, then we should use the open-nogpl ET rules. */ if ($vrt_enabled == "on") @@ -146,17 +253,26 @@ if ($emergingthreats == 'on') { else $image = @file_get_contents("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz.md5"); - /* XXX: error checking */ + update_status(gettext("Done downloading EmergingThreats md5")); + error_log(gettext("\tChecking EmergingThreats md5.\n"), 3, $snort_rules_upd_log); @file_put_contents("{$tmpfname}/{$emergingthreats_filename_md5}", $image); - update_status(gettext("Done downloading emergingthreats md5")); - if (file_exists("{$snortdir}/{$emergingthreats_filename_md5}")) { + /* See if the file download was successful, and turn off ET update if it failed. */ + if (0 == filesize("{$tmpfname}/$emergingthreats_filename_md5")){ + update_output_window(gettext("EmergingThreats md5 file download failed. EmergingThreats rules will not be updated.")); + log_error(gettext("EmergingThreats md5 file download failed. EmergingThreats rules will not be updated.")); + error_log(gettext("\tEmergingThreats md5 file download failed. EmergingThreats rules will not be updated.\n"), 3, $snort_rules_upd_log); + $emergingthreats = 'off'; + } + + if (file_exists("{$snortdir}/{$emergingthreats_filename_md5}") && $emergingthreats == "on") { /* Check if were up to date emergingthreats.net */ $emerg_md5_check_new = file_get_contents("{$tmpfname}/{$emergingthreats_filename_md5}"); $emerg_md5_check_old = file_get_contents("{$snortdir}/{$emergingthreats_filename_md5}"); if ($emerg_md5_check_new == $emerg_md5_check_old) { - update_status(gettext("Emerging threat rules are up to date...")); - log_error(gettext("Emerging threat rules are up to date...")); + update_status(gettext("Emerging Threats rules are up to date...")); + log_error(gettext("Emerging Threat rules are up to date...")); + error_log(gettext("\tEmerging Threats rules are up to date.\n"), 3, $snort_rules_upd_log); $emergingthreats = 'off'; } } @@ -164,8 +280,9 @@ if ($emergingthreats == 'on') { /* download emergingthreats rules file */ if ($emergingthreats == "on") { - update_status(gettext("There is a new set of Emergingthreats rules posted. Downloading...")); - log_error(gettext("There is a new set of Emergingthreats rules posted. Downloading...")); + update_status(gettext("There is a new set of EmergingThreats rules posted. Downloading...")); + log_error(gettext("There is a new set of EmergingThreats rules posted. Downloading...")); + error_log(gettext("\tThere is a new set of EmergingThreats rules posted. Downloading...\n"), 3, $snort_rules_upd_log); /* If using Sourcefire VRT rules with ET, then we should use the open-nogpl ET rules. */ if ($vrt_enabled == "on") @@ -173,24 +290,27 @@ if ($emergingthreats == "on") { else download_file_with_progress_bar("http://rules.emergingthreats.net/open/snort-{$emerging_threats_version}/emerging.rules.tar.gz", "{$tmpfname}/{$emergingthreats_filename}"); - update_status(gettext('Done downloading Emergingthreats rules file.')); - log_error("Emergingthreats rules file update downloaded succsesfully"); + /* Test for a valid rules file download. Turn off ET update if download failed. */ + if (150000 > filesize("{$tmpfname}/$emergingthreats_filename")){ + update_output_window(gettext("EmergingThreats rules file download failed...")); + log_error(gettext("EmergingThreats rules file download failed...")); + log_error("Failed Rules Filesize: " . filesize("{$tmpfname}/$emergingthreats_filename")); + error_log(gettext("\tEmergingThreats rules file download failed. EmergingThreats rules will not be updated.\n"), 3, $snort_rules_upd_log); + $emergingthreats = 'off'; + } + else { + update_status(gettext('Done downloading EmergingThreats rules file.')); + log_error("EmergingThreats rules file update downloaded succsesfully"); + error_log(gettext("\tDone downloading EmergingThreats rules file.\n"), 3, $snort_rules_upd_log); + } } -/* Normalize rulesets */ -$sedcmd = "s/^#alert/# alert/g\n"; -$sedcmd .= "s/^##alert/# alert/g\n"; -$sedcmd .= "s/^#[ \\t#]*alert/# alert/g\n"; -$sedcmd .= "s/^##\\talert/# alert/g\n"; -$sedcmd .= "s/^\\talert/alert/g\n"; -$sedcmd .= "s/^[ \\t]*alert/alert/g\n"; -@file_put_contents("{$snortdir}/tmp/sedcmd", $sedcmd); - /* Untar emergingthreats rules to tmp */ if ($emergingthreats == 'on') { safe_mkdir("{$snortdir}/tmp/emerging"); if (file_exists("{$tmpfname}/{$emergingthreats_filename}")) { update_status(gettext("Extracting EmergingThreats.org rules...")); + error_log(gettext("\tExtracting and installing EmergingThreats.org rules...\n"), 3, $snort_rules_upd_log); exec("/usr/bin/tar xzf {$tmpfname}/{$emergingthreats_filename} -C {$snortdir}/tmp/emerging rules/"); $files = glob("{$snortdir}/tmp/emerging/rules/*.rules"); @@ -199,7 +319,7 @@ if ($emergingthreats == 'on') { @copy($file, "{$snortdir}/rules/{$newfile}"); } /* IP lists for Emerging Threats rules */ - $files = glob("{$snortdir}/tmp/emerging/rules/*.txt"); + $files = glob("{$snortdir}/tmp/emerging/rules/*ips.txt"); foreach ($files as $file) { $newfile = basename($file); @copy($file, "{$snortdir}/rules/{$newfile}"); @@ -207,31 +327,33 @@ if ($emergingthreats == 'on') { /* base etc files for Emerging Threats rules */ foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { if (file_exists("{$snortdir}/tmp/emerging/rules/{$file}")) - @copy("{$snortdir}/tmp/emerging/rules/{$file}", "{$snortdir}/ET_{$file}"); + @copy("{$snortdir}/tmp/emerging/rules/{$file}", "{$snortdir}/tmp/ET_{$file}"); } -// /* make sure default rules are in the right format */ -// exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/emerging*.rules"); - /* Copy emergingthreats md5 sig to snort dir */ if (file_exists("{$tmpfname}/$emergingthreats_filename_md5")) { - update_status(gettext("Copying md5 sig to snort directory...")); + update_status(gettext("Copying md5 signature to snort directory...")); @copy("{$tmpfname}/$emergingthreats_filename_md5", "{$snortdir}/$emergingthreats_filename_md5"); } update_status(gettext("Extraction of EmergingThreats.org rules completed...")); + error_log(gettext("\tInstallation of EmergingThreats.org rules completed.\n"), 3, $snort_rules_upd_log); + exec("rm -r {$snortdir}/tmp/emerging"); } } /* Untar snort rules file individually to help people with low system specs */ if ($snortdownload == 'on') { if (file_exists("{$tmpfname}/{$snort_filename}")) { - if ($pfsense_stable == 'yes') - $freebsd_version_so = 'FreeBSD-7-2'; - else - $freebsd_version_so = 'FreeBSD-8-1'; + + /* Currently, only FreeBSD-8-1 and FreeBSD-9-0 precompiled SO rules exist from Snort.org */ + /* Default to FreeBSD 8.1, and then test for FreeBSD 9.x */ + $freebsd_version_so = 'FreeBSD-8-1'; + if (substr(php_uname("r"), 0, 1) == '9') + $freebsd_version_so = 'FreeBSD-9-0'; update_status(gettext("Extracting Snort VRT rules...")); - /* extract snort.org rules and add prefix to all snort.org files*/ + error_log(gettext("\tExtracting and installing Snort VRT rules...\n"), 3, $snort_rules_upd_log); + /* extract snort.org rules and add prefix to all snort.org files */ safe_mkdir("{$snortdir}/tmp/snortrules"); exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp/snortrules rules/"); $files = glob("{$snortdir}/tmp/snortrules/rules/*.rules"); @@ -249,151 +371,196 @@ if ($snortdownload == 'on') { /* extract so rules */ update_status(gettext("Extracting Snort VRT Shared Objects rules...")); - exec('/bin/mkdir -p /usr/local/lib/snort/dynamicrules/'); + exec('/bin/mkdir -p {$snortlibdir}/dynamicrules/'); + error_log(gettext("\tUsing Snort VRT precompiled SO rules for {$freebsd_version_so} ...\n"), 3, $snort_rules_upd_log); $snort_arch = php_uname("m"); $nosorules = false; if ($snort_arch == 'i386'){ exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/$freebsd_version_so/i386/{$snort_version}/"); - exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/i386/{$snort_version}/* /usr/local/lib/snort/dynamicrules/"); - } else if ($snort_arch == 'amd64') { + exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/i386/{$snort_version}/* {$snortlibdir}/dynamicrules/"); + } elseif ($snort_arch == 'amd64') { exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/precompiled/$freebsd_version_so/x86-64/{$snort_version}/"); - exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/x86-64/{$snort_version}/* /usr/local/lib/snort/dynamicrules/"); + exec("/bin/cp {$snortdir}/tmp/so_rules/precompiled/$freebsd_version_so/x86-64/{$snort_version}/* {$snortlibdir}/dynamicrules/"); } else $nosorules = true; exec("rm -r {$snortdir}/tmp/so_rules"); if ($nosorules == false) { - /* extract so rules none bin and rename */ + /* extract so stub rules, rename and copy to the rules folder. */ update_status(gettext("Copying Snort VRT Shared Objects rules...")); - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp so_rules/"); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp --exclude precompiled/ --exclude src/ so_rules/"); $files = glob("{$snortdir}/tmp/so_rules/*.rules"); foreach ($files as $file) { $newfile = basename($file, ".rules"); @copy($file, "{$snortdir}/rules/snort_{$newfile}.so.rules"); } exec("rm -r {$snortdir}/tmp/so_rules"); - - /* extract base etc files */ - update_status(gettext("Extracting Snort VRT base config files...")); - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp etc/"); - foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { - if (file_exists("{$snortdir}/tmp/etc/{$file}")) - @copy("{$snortdir}/tmp/etc/{$file}", "{$snortdir}/VRT_{$file}"); - } - exec("rm -r {$snortdir}/tmp/etc"); - - /* Untar snort signatures */ - $signature_info_chk = $config['installedpackages']['snortglobal']['signatureinfo']; - if ($premium_url_chk == 'on') { - update_status(gettext("Extracting Snort VRT Signatures...")); - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} doc/signatures/"); - update_status(gettext("Done extracting Signatures.")); - - if (is_dir("{$snortdir}/doc/signatures")) { - update_status(gettext("Copying Snort VRT signatures...")); - exec("/bin/cp -r {$snortdir}/doc/signatures {$snortdir}/signatures"); - update_status(gettext("Done copying signatures.")); - } + } + + /* extract base etc files */ + update_status(gettext("Extracting Snort VRT config and map files...")); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp etc/"); + foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { + if (file_exists("{$snortdir}/tmp/etc/{$file}")) + @copy("{$snortdir}/tmp/etc/{$file}", "{$snortdir}/tmp/VRT_{$file}"); + } + exec("rm -r {$snortdir}/tmp/etc"); + + /* Untar snort signatures */ + $signature_info_chk = $config['installedpackages']['snortglobal']['signatureinfo']; + if ($premium_url_chk == 'on') { + update_status(gettext("Extracting Snort VRT Signatures...")); + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} doc/signatures/"); + update_status(gettext("Done extracting Signatures.")); + + if (is_dir("{$snortdir}/doc/signatures")) { + update_status(gettext("Copying Snort VRT signatures...")); + exec("/bin/cp -r {$snortdir}/doc/signatures {$snortdir}/signatures"); + update_status(gettext("Done copying signatures.")); } + } - foreach (glob("/usr/local/lib/snort/dynamicrules/*example*") as $file) - @unlink($file); - - exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir} preproc_rules/"); - -// /* make sure default rules are in the right format */ -// exec("/usr/bin/sed -I '' -f {$snortdir}/tmp/sedcmd {$snortdir}/rules/snort_*.rules"); + /* Extract the Snort preprocessor rules */ + exec("/usr/bin/tar xzf {$tmpfname}/{$snort_filename} -C {$snortdir}/tmp preproc_rules/"); - if (file_exists("{$tmpfname}/{$snort_filename_md5}")) { - update_status(gettext("Copying md5 sig to snort directory...")); - @copy("{$tmpfname}/$snort_filename_md5", "{$snortdir}/$snort_filename_md5"); - } + if (file_exists("{$tmpfname}/{$snort_filename_md5}")) { + update_status(gettext("Copying md5 signature to snort directory...")); + @copy("{$tmpfname}/$snort_filename_md5", "{$snortdir}/$snort_filename_md5"); } - update_status(gettext("Extraction of Snort VRT rules completed...")); + update_status(gettext("Extraction of Snort VRT rules completed...")); + error_log(gettext("\tInstallation of Snort VRT rules completed.\n"), 3, $snort_rules_upd_log); } } -/* remove old $tmpfname files */ -if (is_dir("{$snortdir}/tmp")) { - update_status(gettext("Cleaning up after rules extraction...")); - exec("/bin/rm -r {$snortdir}/tmp"); -} - function snort_apply_customizations($snortcfg, $if_real) { + global $vrt_enabled; $snortdir = SNORTDIR; + + /* Update the Preprocessor rules for the master configuration and for the interface if Snort VRT rules are in use. */ + if ($vrt_enabled == 'on') { + exec("/bin/mkdir -p {$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/preproc_rules"); + $preproc_files = glob("{$snortdir}/tmp/preproc_rules/*.rules"); + foreach ($preproc_files as $file) { + $newfile = basename($file); + @copy($file, "{$snortdir}/preproc_rules/{$newfile}"); + /* Check if customized preprocessor rule protection is enabled for interface before overwriting them. */ + if ($snortcfg['protect_preproc_rules'] <> 'on') + @copy($file, "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/preproc_rules/{$newfile}"); + } + } + else { + exec("/bin/mkdir -p {$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/preproc_rules"); + } + snort_prepare_rule_files($snortcfg, "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}"); - /* Copy the master *.config and other *.map files to the interface's directory */ - @copy("{$snortdir}/classification.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/classification.config"); - @copy("{$snortdir}/gen-msg.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/gen-msg.map"); - @copy("{$snortdir}/reference.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/reference.config"); - @copy("{$snortdir}/unicode.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/unicode.map"); + /* Copy the master config and map files to the interface directory */ + @copy("{$snortdir}/tmp/classification.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/classification.config"); + @copy("{$snortdir}/tmp/gen-msg.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/gen-msg.map"); + @copy("{$snortdir}/tmp/reference.config", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/reference.config"); + @copy("{$snortdir}/tmp/unicode.map", "{$snortdir}/snort_{$snortcfg['uuid']}_{$if_real}/unicode.map"); } -if ($snortdownload == 'on' || $emergingthreats == 'on') { +if ($snortdownload == 'on' || $emergingthreats == 'on' || $snortcommunityrules == 'on') { update_status(gettext('Copying new config and map files...')); + error_log(gettext("\tCopying new config and map files...\n"), 3, $snort_rules_upd_log); - /* Determine which base etc file set to use for the master copy. */ - /* If the Snort VRT rules are not enabled, then use Emerging Threats. */ + /* Determine which config and map file set to use for the master copy. */ + /* If the Snort VRT rules are not enabled, then use Emerging Threats. */ if (($vrt_enabled == 'off') && ($et_enabled == 'on')) { foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { - if (file_exists("{$snortdir}/ET_{$file}")) - @rename("{$snortdir}/ET_{$file}", "{$snortdir}/{$file}"); + if (file_exists("{$snortdir}/tmp/ET_{$file}")) + @rename("{$snortdir}/tmp/ET_{$file}", "{$snortdir}/tmp/{$file}"); } } elseif (($vrt_enabled == 'on') && ($et_enabled == 'off')) { foreach (array("classification.config", "reference.config", "gen-msg.map", "unicode.map") as $file) { - if (file_exists("{$snortdir}/VRT_{$file}")) - @rename("{$snortdir}/VRT_{$file}", "{$snortdir}/{$file}"); + if (file_exists("{$snortdir}/tmp/VRT_{$file}")) + @rename("{$snortdir}/tmp/VRT_{$file}", "{$snortdir}/tmp/{$file}"); } } - else { + elseif (($vrt_enabled == 'on') && ($et_enabled == 'on')) { /* Both VRT and ET rules are enabled, so build combined */ /* reference.config and classification.config files. */ - $cfgs = glob("{$snortdir}/*reference.config"); - snort_merge_reference_configs($cfgs, "{$snortdir}/reference.config"); - $cfgs = glob("{$snortdir}/*classification.config"); - snort_merge_classification_configs($cfgs, "{$snortdir}/classification.config"); - } - - /* Clean-up our temp versions of the config and map files. */ - update_status(gettext('Cleaning up temp files...')); - $cfgs = glob("{$snortdir}/??*_*.config"); - foreach ($cfgs as $file) { - if (file_exists($file)) - @unlink($file); - } - $cfgs = glob("{$snortdir}/??*_*.map"); - foreach ($cfgs as $file) { - if (file_exists($file)) - @unlink($file); + $cfgs = glob("{$snortdir}/tmp/*reference.config"); + snort_merge_reference_configs($cfgs, "{$snortdir}/tmp/reference.config"); + $cfgs = glob("{$snortdir}/tmp/*classification.config"); + snort_merge_classification_configs($cfgs, "{$snortdir}/tmp/classification.config"); + + /* Use the unicode.map and gen-msg.map files from VRT rules. */ + if (file_exists("{$snortdir}/tmp/VRT_unicode.map")) + @rename("{$snortdir}/tmp/VRT_unicode.map", "{$snortdir}/tmp/gen-msg.map"); + if (file_exists("{$snortdir}/tmp/VRT_gen-msg.map")) + @rename("{$snortdir}/tmp/VRT_gen-msg.map", "{$snortdir}/tmp/gen-msg.map"); } + else { + /* Just Snort GPLv2 Community Rules may be enabled, so make sure required */ + /* default config files are present in the rules extraction tmp working */ + /* directory. Only copy missing files not captured in logic above. */ + + $snort_files = array("gen-msg.map", "classification.config", "reference.config", "unicode.map"); + foreach ($snort_files as $file) { + if (file_exists("{$snortdir}/{$file}") && !file_exists("{$snortdir}/tmp/{$file}")) + @copy("{$snortdir}/{$file}", "{$snortdir}/tmp/{$file}"); + } + } - /* Start the proccess for each configured interface */ + /* Start the rules rebuild proccess for each configured interface */ if (is_array($config['installedpackages']['snortglobal']['rule'])) { - foreach ($config['installedpackages']['snortglobal']['rule'] as $id => $value) { - /* Create configuration for each active Snort interface */ + /* 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 ($is_postinstall) + $rebuild_rules = 'off'; + else + $rebuild_rules = 'on'; + + /* Create configuration for each active Snort interface */ + foreach ($config['installedpackages']['snortglobal']['rule'] as $id => $value) { $if_real = snort_get_real_interface($value['interface']); $tmp = "Updating rules configuration for: " . snort_get_friendly_interface($value['interface']) . " ..."; update_status(gettext($tmp)); - log_error($tmp); snort_apply_customizations($value, $if_real); + + /* Log a message in Update Log if protecting customized preprocessor rules. */ + $tmp = "\t" . $tmp . "\n"; + if ($value['protect_preproc_rules'] == 'on') { + $tmp .= gettext("\tPreprocessor text rules flagged as protected and not updated for "); + $tmp .= snort_get_friendly_interface($value['interface']) . "...\n"; + } + error_log($tmp, 3, $snort_rules_upd_log); } } - update_status(gettext('Restarting Snort to activate the new set of rules...')); - exec("/bin/sh /usr/local/etc/rc.d/snort.sh restart"); - sleep(20); - if (!is_process_running("snort")) - exec("/bin/sh /usr/local/etc/rc.d/snort.sh start"); - update_output_window(gettext("Snort has restarted with your new set of rules...")); - log_error("Snort has restarted with your new set of rules..."); + else { + update_output_window(gettext("Warning: No interfaces configured for Snort were found...")); + error_log(gettext("\tWarning: No interfaces configured for Snort were found...\n"), 3, $snort_rules_upd_log); + } + + /* Clear the rebuild rules flag. */ + $rebuild_rules = 'off'; + + /* remove old $tmpfname files */ + if (is_dir("{$snortdir}/tmp")) { + update_status(gettext("Cleaning up after rules extraction...")); + exec("/bin/rm -r {$snortdir}/tmp"); + } + + /* Restart snort if already running to pick up the new rules. */ + if (is_process_running("snort")) { + update_status(gettext('Restarting Snort to activate the new set of rules...')); + error_log(gettext("\tRestarting Snort to activate the new set of rules...\n"), 3, $snort_rules_upd_log); + exec("/bin/sh /usr/local/etc/rc.d/snort.sh restart"); + update_output_window(gettext("Snort has restarted with your new set of rules...")); + log_error(gettext("Snort has restarted with your new set of rules...")); + error_log(gettext("\tSnort has restarted with your new set of rules.\n"), 3, $snort_rules_upd_log); + } } update_status(gettext("The Rules update has finished...")); -log_error("The Rules update has finished..."); +log_error(gettext("The Rules update has finished.")); +error_log(gettext("The Rules update has finished. Time: " . date("Y-m-d H:i:s"). "\n\n"), 3, $snort_rules_upd_log); conf_mount_ro(); ?> diff --git a/config/snort/snort_define_servers.php b/config/snort/snort_define_servers.php index 4085b325..7fb435ed 100755 --- a/config/snort/snort_define_servers.php +++ b/config/snort/snort_define_servers.php @@ -126,7 +126,9 @@ if ($_POST) { write_config(); - sync_snort_package_config(); + /* Update the snort conf file for this interface. */ + $rebuild_rules = "off"; + snort_generate_conf($a_nat[$id]); /* after click go to this page */ header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); diff --git a/config/snort/snort_download_updates.php b/config/snort/snort_download_updates.php index 0c879e44..369e3094 100755 --- a/config/snort/snort_download_updates.php +++ b/config/snort/snort_download_updates.php @@ -36,16 +36,18 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $snort_rules_upd_log, $snort_rules_file, $emergingthreats_filename; $snortdir = SNORTDIR; -$snort_upd_log = "/tmp/snort_update.log"; + +$log = $snort_rules_upd_log; /* load only javascript that is needed */ $snort_load_jquery = 'yes'; $snort_load_jquery_colorbox = 'yes'; $snortdownload = $config['installedpackages']['snortglobal']['snortdownload']; $emergingthreats = $config['installedpackages']['snortglobal']['emergingthreats']; +$snortcommunityrules = $config['installedpackages']['snortglobal']['snortcommunityrules']; /* quick md5s chk */ $snort_org_sig_chk_local = 'N/A'; @@ -53,13 +55,28 @@ if (file_exists("{$snortdir}/{$snort_rules_file}.md5")) $snort_org_sig_chk_local = file_get_contents("{$snortdir}/{$snort_rules_file}.md5"); $emergingt_net_sig_chk_local = 'N/A'; -if (file_exists("{$snortdir}/emerging.rules.tar.gz.md5")) - $emergingt_net_sig_chk_local = file_get_contents("{$snortdir}/emerging.rules.tar.gz.md5"); +if (file_exists("{$snortdir}/{$emergingthreats_filename}.md5")) + $emergingt_net_sig_chk_local = file_get_contents("{$snortdir}/{$emergingthreats_filename}.md5"); + +$snort_community_sig_chk_local = 'N/A'; +if (file_exists("{$snortdir}/{$snort_community_rules_filename}.md5")) + $snort_community_sig_chk_local = file_get_contents("{$snortdir}/{$snort_community_rules_filename}.md5"); + +/* Check for postback to see if we should clear the update log file. */ +if (isset($_POST['clear'])) { + if (file_exists("{$snort_rules_upd_log}")) + mwexec("/bin/rm -f {$snort_rules_upd_log}"); +} + +if (isset($_POST['update'])) { + header("Location: /snort/snort_download_rules.php"); + exit; +} /* check for logfile */ -$update_logfile_chk = 'no'; -if (file_exists("{$snort_upd_log}")) - $update_logfile_chk = 'yes'; +$snort_rules_upd_logfile_chk = 'no'; +if (file_exists("{$snort_rules_upd_log}")) + $snort_rules_upd_logfile_chk = 'yes'; $pgtitle = "Services: Snort: Updates"; include_once("head.inc"); @@ -78,12 +95,14 @@ function popup(url) params += ', top=0, left=0' params += ', fullscreen=yes'; - newwin=window.open(url,'windowname4', params); + newwin=window.open(url,'LogViewer', params); if (window.focus) {newwin.focus()} return false; } +
+
- +
@@ -133,14 +152,14 @@ function popup(url)

-
+

' . gettext("Update Rules") . '    
+

' . gettext("WARNING:") . '  ' . gettext('No rule types have been selected for download. "Global Settings Tab"') . '
'; @@ -148,7 +167,7 @@ function popup(url) } else { echo ' -
' . "\n"; +
' . "\n"; } @@ -166,19 +185,19 @@ function popup(url)

-
+

- " . gettext("Update Log") . "    \n"; + "; + echo "          \n"; }else{ echo " - \n"; +    " . gettext("Log is empty.") . "\n"; } - + echo '

' . gettext("The log file is limited to 1024K in size and automatically clears when the limit is exceeded."); ?>

@@ -194,8 +213,8 @@ function popup(url)

@@ -112,14 +130,15 @@ function popup(url)
- +

-
-
- SNORT.ORG >>> +

+ SNORT.ORG  -->   
- EMERGINGTHREATS.NET >>> + EMERGINGTHREATS.NET  -->   
+ SNORT GPLv2 COMMUNITY RULES  --> +   

-     
@@ -207,16 +226,12 @@ function popup(url)
- - - - -
+
diff --git a/config/snort/snort_interfaces.php b/config/snort/snort_interfaces.php index e8e690a8..4f85c1f4 100755 --- a/config/snort/snort_interfaces.php +++ b/config/snort/snort_interfaces.php @@ -61,10 +61,14 @@ if (isset($_POST['del_x'])) { } conf_mount_ro(); + /* If all the Snort interfaces are removed, then unset the config array. */ + if (empty($a_nat)) + unset($a_nat); + write_config(); sleep(2); - /* if there are no ifaces do not create snort.sh */ + /* if there are no ifaces remaining do not create snort.sh */ if (!empty($config['installedpackages']['snortglobal']['rule'])) snort_create_rc(); else { @@ -228,7 +232,7 @@ if ($pfsense_stable == 'yes') else $biconfn = 'block'; - ?> +?> + + +
+ + diff --git a/config/snort/snort_log_view.php b/config/snort/snort_log_view.php new file mode 100644 index 00000000..6d38a8cb --- /dev/null +++ b/config/snort/snort_log_view.php @@ -0,0 +1,86 @@ + + + + + + + + + +
@@ -124,7 +142,8 @@ if ($input_errors) $tab_array[6] = array(gettext("Suppress"), false, "/snort/snort_interfaces_suppress.php"); display_top_tabs($tab_array); ?> -
@@ -132,55 +151,69 @@ if ($input_errors) - + - - + + + + + +   

+ + ','
'); ?> @@ -209,20 +242,20 @@ if ($input_errors)

:
- MB +  MB - @@ -255,10 +286,9 @@ if ($input_errors) > -
-
-
+    +

+ ', ''); ?> + >   + "interfaces. Double check that your oink code is correct, and verify the " . + "type of Snort.org account you hold."); ?>
' , ''); ?> - +
- + + - - + + + -
> - ', ''); ?> >  ', ''); ?>
>
-          
-          
>
 
+ +
- - + +
 
+ - - + + + - + value="" + 'on') echo 'disabled'; ?>>
+ +
+
-
-
' , ''); ?> - >
-
+ + + + + +
> +

' ,'
'); ?>
' , ''); ?> + + + + +
> +
+
> -
-
-
+> + () @@ -231,18 +264,16 @@ if ($input_errors)
> - ()
> -
+> +

:
 
- +
- - - + + +
MB - 20% MB   + ', ''); ?>
- >
-
@@ -279,8 +308,8 @@ if ($input_errors)  
+ + + +
+ + + + + + + + +
+ + +  ' . $_GET['logfile']; ?>     +
+
+ +
+
+
+
+ + + diff --git a/config/snort/snort_preprocessors.php b/config/snort/snort_preprocessors.php index 7d0348e9..5cd5a408 100755 --- a/config/snort/snort_preprocessors.php +++ b/config/snort/snort_preprocessors.php @@ -34,7 +34,12 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g; +global $g, $rebuild_rules; + +if (!is_array($config['installedpackages']['snortglobal'])) { + $config['installedpackages']['snortglobal'] = array(); +} +$vrt_enabled = $config['installedpackages']['snortglobal']['snortdownload']; if (!is_array($config['installedpackages']['snortglobal']['rule'])) { $config['installedpackages']['snortglobal']['rule'] = array(); @@ -77,6 +82,13 @@ if (isset($id) && $a_nat[$id]) { $pconfig['dnp3_preproc'] = $a_nat[$id]['dnp3_preproc']; $pconfig['modbus_preproc'] = $a_nat[$id]['modbus_preproc']; $pconfig['gtp_preproc'] = $a_nat[$id]['gtp_preproc']; + $pconfig['preproc_auto_rule_disable'] = $a_nat[$id]['preproc_auto_rule_disable']; + $pconfig['protect_preproc_rules'] = $a_nat[$id]['protect_preproc_rules']; + + /* If not using the Snort VRT rules, then disable */ + /* the Sensitive Data (sdf) preprocessor. */ + if ($vrt_enabled == "off") + $pconfig['sensitive_data'] = "off"; } if ($_POST) { @@ -120,6 +132,8 @@ if ($_POST) { $natent['sip_preproc'] = $_POST['sip_preproc'] ? 'on' : 'off'; $natent['modbus_preproc'] = $_POST['modbus_preproc'] ? 'on' : 'off'; $natent['gtp_preproc'] = $_POST['gtp_preproc'] ? 'on' : 'off'; + $natent['preproc_auto_rule_disable'] = $_POST['preproc_auto_rule_disable'] ? 'on' : 'off'; + $natent['protect_preproc_rules'] = $_POST['protect_preproc_rules'] ? 'on' : 'off'; if (isset($id) && $a_nat[$id]) $a_nat[$id] = $natent; @@ -132,8 +146,15 @@ if ($_POST) { write_config(); - $if_real = snort_get_real_interface($pconfig['interface']); - sync_snort_package_config(); + /* Set flag to rebuild rules for this interface */ + $rebuild_rules = "on"; + + /*************************************************/ + /* Update the snort conf file and rebuild the */ + /* rules for this interface. */ + /*************************************************/ + snort_generate_conf($natent); + $rebuild_rules = "off"; /* after click go to this page */ header( 'Expires: Sat, 26 Jul 1997 05:00:00 GMT' ); @@ -191,22 +212,58 @@ include_once("head.inc"); - + + - + + - + + + + + + + + @@ -214,9 +271,10 @@ include_once("head.inc"); + "Normalize/Decode and detect HTTP traffic and protocol anomalies. Default is "); ?> + @@ -241,7 +299,7 @@ include_once("head.inc"); + + onClick="enable_change(false)"> + @@ -469,9 +528,14 @@ include_once("head.inc"); @@ -507,7 +571,8 @@ include_once("head.inc"); + +
-
+
-
-
onClick="enable_change(false)">
'on') echo "disabled"; ?> + onClick="enable_change(false)"> + + + + + +
 

+ ', ''); ?>
+
+ onClick="enable_change(false)"> ' . gettext("Not Checked."); ?>
+ + + + + +
  +
+
+ onClick="enable_change(false)">
- onClick="enable_change(false)">

+ onClick="enable_change(false)">
- +
+
 
-
diff --git a/config/snort/snort_rules.php b/config/snort/snort_rules.php index 7457632d..5e8e145d 100755 --- a/config/snort/snort_rules.php +++ b/config/snort/snort_rules.php @@ -33,7 +33,7 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g, $flowbit_rules_file; +global $g, $flowbit_rules_file, $rebuild_rules; $snortdir = SNORTDIR; $rules_map = array(); @@ -92,6 +92,11 @@ if (empty($categories[0]) && ($currentruleset != "custom.rules")) { $currentruleset = "custom.rules"; } +/* One last sanity check -- if the rules directory is empty, default to loading custom rules */ +$tmp = glob("{$snortdir}/rules/*.rules"); +if (empty($tmp)) + $currentruleset = "custom.rules"; + $ruledir = "{$snortdir}/rules"; $rulefile = "{$ruledir}/{$currentruleset}"; if ($currentruleset != 'custom.rules') { @@ -100,7 +105,7 @@ if ($currentruleset != 'custom.rules') { if (substr($currentruleset, 0, 10) == "IPS Policy") $rules_map = snort_load_vrt_policy($a_rule[$id]['ips_policy']); elseif (!file_exists($rulefile)) - $input_errors[] = "{$currentruleset} seems to be missing!!! Please go to the Category tab and save the rule set again to regenerate it."; + $input_errors[] = gettext("{$currentruleset} seems to be missing!!! Please verify rules files have been downloaded, then go to the Categories tab and save the rule set again."); else $rules_map = snort_load_rules_map($rulefile); } @@ -221,11 +226,31 @@ if ($_POST['customrules']) { for($i = $start; $i > $end; $i--) $error .= $output[$i]; $input_errors[] = "Custom rules have errors:\n {$error}"; - } else { + } + else { header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); exit; } -} else if ($_POST) { +} + +else if ($_POST['apply']) { + + /* Save new configuration */ + write_config(); + + /*************************************************/ + /* Update the snort conf file and rebuild the */ + /* rules for this interface. */ + /*************************************************/ + $rebuild_rules = "on"; + snort_generate_conf($a_rule[$id]); + $rebuild_rules = "off"; + + /* Return to this same page */ + header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); + exit; +} +else if($_POST) { unset($a_rule[$id]['customrules']); write_config(); header("Location: /snort/snort_rules.php?id={$id}&openruleset={$currentruleset}"); @@ -361,7 +386,9 @@ function popup(url)   -   + +     + " width="17" height="17" border="0"> diff --git a/config/snort/snort_rules_edit.php b/config/snort/snort_rules_edit.php index ab1a24b2..8ee6a645 100755 --- a/config/snort/snort_rules_edit.php +++ b/config/snort/snort_rules_edit.php @@ -62,6 +62,7 @@ $if_real = snort_get_real_interface($pconfig['interface']); $snort_uuid = $a_rule[$id]['uuid']; $file = $_GET['openruleset']; $contents = ''; +$wrap_flag = "off"; // Read the contents of the argument passed to us. // It may be an IPS policy string, an individual SID, @@ -69,8 +70,10 @@ $contents = ''; // Test for the special case of an IPS Policy file. if (substr($file, 0, 10) == "IPS Policy") { $rules_map = snort_load_vrt_policy($a_rule[$id]['ips_policy']); - if (isset($_GET['ids'])) + if (isset($_GET['ids'])) { $contents = $rules_map[$_GET['gid']][trim($_GET['ids'])]['rule']; + $wrap_flag = "on"; + } else { $contents = "# Snort IPS Policy - " . ucfirst($a_rule[$id]['ips_policy']) . "\n\n"; foreach (array_keys($rules_map) as $k1) { @@ -86,6 +89,7 @@ if (substr($file, 0, 10) == "IPS Policy") { elseif (isset($_GET['ids'])) { $rules_map = snort_load_rules_map("{$snortdir}/rules/{$file}"); $contents = $rules_map[$_GET['gid']][trim($_GET['ids'])]['rule']; + $wrap_flag = "on"; } // Is it our special flowbit rules file? elseif ($file == $flowbit_rules_file) @@ -102,7 +106,7 @@ else { exit; } -$pgtitle = array(gettext("Advanced"), gettext("File Viewer")); +$pgtitle = array(gettext("Snort"), gettext("File Viewer")); ?> @@ -124,7 +128,7 @@ $pgtitle = array(gettext("Advanced"), gettext("File Viewer"));
- +
diff --git a/config/snort/snort_rulesets.php b/config/snort/snort_rulesets.php index 23a24bea..1bf815fb 100755 --- a/config/snort/snort_rulesets.php +++ b/config/snort/snort_rulesets.php @@ -32,7 +32,7 @@ require_once("guiconfig.inc"); require_once("/usr/local/pkg/snort/snort.inc"); -global $g, $flowbit_rules_file; +global $g, $flowbit_rules_file, $rebuild_rules; $snortdir = SNORTDIR; @@ -62,6 +62,21 @@ $if_real = snort_get_real_interface($pconfig['interface']); $snort_uuid = $a_nat[$id]['uuid']; $snortdownload = $config['installedpackages']['snortglobal']['snortdownload']; $emergingdownload = $config['installedpackages']['snortglobal']['emergingthreats']; +$snortcommunitydownload = $config['installedpackages']['snortglobal']['snortcommunityrules']; + +$no_emerging_files = false; +$no_snort_files = false; +$no_community_files = false; + +/* Test rule categories currently downloaded to $SNORTDIR/rules and set appropriate flags */ +$test = glob("{$snortdir}/rules/emerging-*.rules"); +if (empty($test)) + $no_emerging_files = true; +$test = glob("{$snortdir}/rules/snort_*.rules"); +if (empty($test)) + $no_snort_files = true; +if (!file_exists("{$snortdir}/rules/GPLv2_community.rules")) + $no_community_files = true; if (($snortdownload == 'off') || ($a_nat[$id]['ips_policy_enable'] != 'on')) $policy_select_disable = "disabled"; @@ -119,7 +134,14 @@ if ($_POST["Submit"]) { } write_config(); - sync_snort_package_config(); + + /*************************************************/ + /* Update the snort conf file and rebuild the */ + /* rules for this interface. */ + /*************************************************/ + $rebuild_rules = "on"; + snort_generate_conf($a_nat[$id]); + $rebuild_rules = "off"; header("Location: /snort/snort_rulesets.php?id=$id"); exit; @@ -142,6 +164,11 @@ if ($_POST['selectall']) { foreach ($files as $file) $rulesets[] = basename($file); } + if ($snortcommunitydownload == 'on') { + $files = glob("{$snortdir}/rules/sc_*.rules"); + foreach ($files as $file) + $rulesets[] = basename($file); + } if ($snortdownload == 'on') { $files = glob("{$snortdir}/rules/snort*.rules"); foreach ($files as $file) @@ -233,12 +260,12 @@ function enable_change() $iscfgdirempty = array(); if (file_exists("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/custom.rules")) $iscfgdirempty = (array)("{$snortdir}/snort_{$snort_uuid}_{$if_real}/rules/custom.rules"); - if (empty($isrulesfolderempty) && empty($iscfgdirempty)): + if (empty($isrulesfolderempty)): ?> - -
- +
+ ',$snortdir,''); ?>

+ ' ,'', '' ,''); ?> - +
- + + "be automatically enabled and added to the list of files in the interface rules directory."); ?>
- + + ', ''); ?> +
/>/> +   
  -

/>/> +   
  -

@@ -289,20 +319,20 @@ function enable_change() - +
+ onClick="enable_change()"/>   + + "These will be added to the pre-defined Snort IPS policy rules from the Snort VRT."); ?>
@@ -311,15 +341,16 @@ function enable_change() - +    +
- onClick="enable_change()"/>
  -
+ ',''); ?>

  -

@@ -327,27 +358,75 @@ function enable_change()
+   -

-

-
-
+ + + + + + + + +
-   + +   + + + + + + + + + + + + + + + + + + /> + + + + + + +   + + + + - - + + - + - - - - - + + + + + - +