From d96be7309cbd375db4e7118ea7f86f35baa2ca1a Mon Sep 17 00:00:00 2001 From: bmeeks8 Date: Wed, 19 Mar 2014 17:01:32 -0400 Subject: Add Log Mgmt tab to rotate and prune large log files. --- config/suricata/suricata_check_cron_misc.inc | 194 +++++++++++++++++++-------- 1 file changed, 141 insertions(+), 53 deletions(-) (limited to 'config/suricata/suricata_check_cron_misc.inc') diff --git a/config/suricata/suricata_check_cron_misc.inc b/config/suricata/suricata_check_cron_misc.inc index b2678059..25e8bb8a 100644 --- a/config/suricata/suricata_check_cron_misc.inc +++ b/config/suricata/suricata_check_cron_misc.inc @@ -30,74 +30,162 @@ require_once("/usr/local/pkg/suricata/suricata.inc"); -// 'B' => 1, -// 'KB' => 1024, -// 'MB' => 1024 * 1024, -// 'GB' => 1024 * 1024 * 1024, -// 'TB' => 1024 * 1024 * 1024 * 1024, -// 'PB' => 1024 * 1024 * 1024 * 1024 * 1024, +function suricata_check_dir_size_limit($suricataloglimitsize) { + /******************************************************** + * This function checks the total size of the Suricata * + * logging sub-directory structure and prunes the files * + * for all Suricata interfaces if the size exceeds the * + * passed limit. * + * * + * On Entry: $surictaaloglimitsize = dir size limit * + * in megabytes * + ********************************************************/ + + // Convert Log Limit Size setting from MB to KB + $suricataloglimitsizeKB = round($suricataloglimitsize * 1024); + $suricatalogdirsizeKB = suricata_Getdirsize(SURICATALOGDIR); -/* chk if snort log dir is full if so clear it */ -$suricataloglimit = $config['installedpackages']['suricata']['config'][0]['suricataloglimit']; -$suricataloglimitsize = $config['installedpackages']['suricata']['config'][0]['suricataloglimitsize']; + if ($suricatalogdirsizeKB > 0 && $suricatalogdirsizeKB > $suricataloglimitsizeKB) { + log_error(gettext("[Suricata] Log directory size exceeds configured limit of " . number_format($suricataloglimitsize) . " MB set on Global Settings tab. All Suricata log files will be truncated.")); + conf_mount_rw(); -if ($g['booting']==true) - return; + // Truncate the Rules Update Log file if it exists + if (file_exists(RULES_UPD_LOGFILE)) { + log_error(gettext("[Suricata] Truncating the Rules Update Log file...")); + @file_put_contents(RULES_UPD_LOGFILE, ""); + } -if ($suricataloglimit == 'off') - return; + // Initialize an array of the log files we want to prune + $logs = array ( "alerts.log", "http.log", "files-json.log", "tls.log", "stats.log" ); -if (!is_array($config['installedpackages']['suricata']['rule'])) - return; + // Clean-up the logs for each configured Suricata instance + foreach ($config['installedpackages']['suricata']['rule'] as $value) { + $if_real = get_real_interface($value['interface']); + $suricata_uuid = $value['uuid']; + $suricata_log_dir = SURICATALOGDIR . "suricata_{$if_real}{$suricata_uuid}"; + log_error(gettext("[Suricata] Truncating logs for {$value['descr']} ({$if_real})...")); + suricata_post_delete_logs($suricata_uuid); + + foreach ($logs as $file) { + // Truncate the log file if it exists + if (file_exists("{$suricata_log_dir}/{$file}")) { + try { + file_put_contents("{$suricata_log_dir}/{$file}", ""); + } catch (Exception $e) { + log_error("[Suricata] Failed to truncate file '{$suricata_log_dir}/{$file}' -- error was {$e->getMessage()}"); + } + } + } -/* Convert Log Limit Size setting from MB to KB */ -$suricataloglimitsizeKB = round($suricataloglimitsize * 1024); -$suricatalogdirsizeKB = suricata_Getdirsize(SURICATALOGDIR); -if ($suricatalogdirsizeKB > 0 && $suricatalogdirsizeKB > $suricataloglimitsizeKB) { - log_error(gettext("[Suricata] Log directory size exceeds configured limit of " . number_format($suricataloglimitsize) . " MB set on Global Settings tab. All Suricata log files will be truncated.")); - conf_mount_rw(); - - /* Truncate the Rules Update Log file if it exists */ - if (file_exists(RULES_UPD_LOGFILE)) { - log_error(gettext("[Suricata] Truncating the Rules Update Log file...")); - $fd = @fopen(RULES_UPD_LOGFILE, "w+"); - if ($fd) - fclose($fd); + // Check for any captured stored files and clean them up + unlink_if_exists("{$suricata_log_dir}/files/*"); + + // This is needed if suricata is run as suricata user + mwexec('/bin/chmod 660 /var/log/suricata/*', true); + } + conf_mount_ro(); + log_error(gettext("[Suricata] Automatic clean-up of Suricata logs completed.")); } +} - /* Clean-up the logs for each configured Suricata instance */ - foreach ($config['installedpackages']['suricata']['rule'] as $value) { - $if_real = get_real_interface($value['interface']); - $suricata_uuid = $value['uuid']; - $suricata_log_dir = SURICATALOGDIR . "suricata_{$if_real}{$suricata_uuid}"; - log_error(gettext("[Suricata] Truncating logs for {$value['descr']} ({$if_real})...")); - suricata_post_delete_logs($suricata_uuid); +function suricata_check_rotate_log($log_file, $log_limit, $retention) { - // Initialize an array of the log files we want to prune - $logs = array ( "alerts.log", "http.log", "files-json.log", "tls.log", "stats.log" ); + /******************************************************** + * This function checks the passed log file against * + * the passed size limit and rotates the log file if * + * necessary. It also checks the age of previously * + * rotated logs and removes those older than the * + * rentention parameter. * + * * + * On Entry: $log_file -> full pathname/filename of * + * log file to check * + * $log_limit -> size of file in bytes to * + * trigger rotation. Zero * + * means no rotation. * + * $retention -> retention period in hours * + * for rotated logs. Zero * + * means never remove. * + ********************************************************/ - foreach ($logs as $file) { - // Truncate the log file if it exists - if (file_exists("{$suricata_log_dir}/$file")) { - $fd = @fopen("{$suricata_log_dir}/$file", "w+"); - if ($fd) - fclose($fd); - } + // 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 (($log_limit > 0) && (filesize($log_file) >= $log_limit)) { + $newfile = $log_file . "." . strval(time()); + try { + copy($log_file, $newfile); + file_put_contents($log_file, ""); + } catch (Exception $e) { + log_error("[Suricata] Failed to rotate file '{$log_file}' -- error was {$e->getMessage()}"); } + } - // Check for any captured stored files and clean them up - $filelist = glob("{$suricata_log_dir}/files/*"); - if (!empty($filelist)) { - foreach ($filelist as $file) - @unlink($file); + // Check previously rotated logs to see if time to + // delete any older than the retention period. + // Rotated logs have a UNIX timestamp appended to + // filename. + if ($retention > 0) { + $now = time(); + $rotated_files = glob("{$log_file}.*"); + foreach ($rotated_files as $file) { + if (($now - filemtime($file)) > ($retention * 3600)) + unlink_if_exists($file); } + unset($rotated_files); + } +} + +/************************* + * Start of main code * + *************************/ + +// If firewall is booting, do nothing +if ($g['booting'] == true) + return; + +// If no interfaces defined, there is nothing to clean up +if (!is_array($config['installedpackages']['suricata']['rule'])) + return; - // This is needed if suricata is run as suricata user - mwexec('/bin/chmod 660 /var/log/suricata/*', true); +$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['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['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']; +$logs['tls.log']['retention'] = $config['installedpackages']['suricata']['config'][0]['tls_log_retention']; + +// Check log limits and retention in the interface logging directories if enabled +if ($config['installedpackages']['suricata']['config'][0]['enable_log_mgmt'] == 'on') { + foreach ($config['installedpackages']['suricata']['rule'] as $value) { + $if_real = get_real_interface($value['interface']); + $suricata_log_dir = SURICATALOGDIR . "suricata_{$if_real}{$value['uuid']}"; + foreach ($logs as $k => $p) + suricata_check_rotate_log("{$suricata_log_dir}/{$k}", $p['limit']*1024, $p['retention']); } - conf_mount_ro(); - log_error(gettext("[Suricata] Automatic clean-up of Suricata logs completed.")); + + // Prune any aged-out Barnyard2 archived logs if any exist + if (is_dir("{$suricata_log_dir}/barnyard2/archive") && + $config['installedpackages']['suricata']['config'][0]['u2_archive_log_retention'] > 0) { + $now = time(); + $files = glob("{$suricata_log_dir}/barnyard2/archive/unified2.alert.*"); + foreach ($files as $f) { + if (($now - filemtime($f)) > ($config['installedpackages']['suricata']['config'][0]['u2_archive_log_retention'] * 3600)) + unlink_if_exists($f); + } + } + unset($files); } +// Check the overall log directory limit (if enabled) and prune if necessary +if ($config['installedpackages']['suricata']['config'][0]['suricataloglimit'] == 'on') + suricata_check_dir_size_limit($config['installedpackages']['suricata']['config'][0]['suricataloglimitsize']); + ?> -- cgit v1.2.3