IDS: Redesign backend for enabled/disabled sids in rulefiles.

The enabled or disabled sids now will be written to an own
provider exclusive configuration file which dynamically will
be included by oinkmaster if needed.

Signed-off-by: Stefan Schantl <stefan.schantl@ipfire.org>
This commit is contained in:
Stefan Schantl
2021-04-01 20:02:48 +02:00
parent 88eb5626b3
commit 15832b10c2
3 changed files with 97 additions and 78 deletions

View File

@@ -50,12 +50,15 @@ our $dns_servers_file = "$settingsdir/suricata-dns-servers.yaml";
# File where the HTTP ports definition is stored.
our $http_ports_file = "$settingsdir/suricata-http-ports.yaml";
# File which contains the enabled sids.
# DEPRECATED - File which contains the enabled sids.
our $enabled_sids_file = "$settingsdir/oinkmaster-enabled-sids.conf";
# File which contains the disabled sids.
# DEPRECATED - File which contains the disabled sids.
our $disabled_sids_file = "$settingsdir/oinkmaster-disabled-sids.conf";
# File which contains includes for provider specific rule modifications.
our $oinkmaster_provider_includes_file = "$settingsdir/oinkmaster-provider-includes.conf";
# File which contains wheater the rules should be changed.
our $modify_sids_file = "$settingsdir/oinkmaster-modify-sids.conf";
@@ -144,8 +147,7 @@ my %dl_type_to_suffix = (
#
sub check_and_create_filelayout() {
# Check if the files exist and if not, create them.
unless (-f "$enabled_sids_file") { &create_empty_file($enabled_sids_file); }
unless (-f "$disabled_sids_file") { &create_empty_file($disabled_sids_file); }
unless (-f "$oinkmaster_provider_includes_file") { &create_empty_file($oinkmaster_provider_includes_file); }
unless (-f "$modify_sids_file") { &create_empty_file($modify_sids_file); }
unless (-f "$suricata_used_providers_file") { &create_empty_file($suricata_used_providers_file); }
unless (-f "$ids_settings_file") { &create_empty_file($ids_settings_file); }

View File

@@ -182,11 +182,8 @@ update_files = \.rules$|\.config$|\.conf$|\.txt$|\.map$
# files from included files. Example to load stuff from "/etc/foo.conf".
# include /etc/foo.conf
# Include file for enabled sids.
include /var/ipfire/suricata/oinkmaster-enabled-sids.conf
# Include file for disabled sids.
include /var/ipfire/suricata/oinkmaster-disabled-sids.conf
# Include file for provider specific includes.
include /var/ipfire/suricata/oinkmaster-provider-includes.conf
# Include file which defines the runmode of suricata.
include /var/ipfire/suricata/oinkmaster-modify-sids.conf

View File

@@ -317,9 +317,6 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'ids apply'}) {
# Arrays to store which rulefiles have been enabled and will be used.
my @enabled_rulefiles;
# Hash to store the user-enabled and disabled sids.
my %enabled_disabled_sids;
# Store if a restart of suricata is required.
my $suricata_restart_required;
@@ -341,88 +338,111 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'ids apply'}) {
}
}
# Read-in the files for enabled/disabled sids.
# This will be done by calling the read_enabled_disabled_sids_file function two times
# and merge the returned hashes together into the enabled_disabled_sids hash.
%enabled_disabled_sids = (
&read_enabled_disabled_sids_file($IDS::disabled_sids_file),
&read_enabled_disabled_sids_file($IDS::enabled_sids_file));
# Open oinkmaster main include file for provider modifications.
open(OINKM_INCL_FILE, ">", "$IDS::oinkmaster_provider_includes_file") or die "Could not open $IDS::oinkmaster_provider_includes_file. $!\n";
# Loop through the hash of idsrules.
foreach my $rulefile (keys %idsrules) {
# Loop through the single rules of the rulefile.
foreach my $sid (keys %{$idsrules{$rulefile}}) {
# Skip the current sid if it is not numeric.
next unless ($sid =~ /\d+/ );
# Print file header and notice about autogenerated file.
print OINKM_INCL_FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
# Check if there exists a key in the cgiparams hash for this sid.
if (exists($cgiparams{$sid})) {
# Look if the rule is disabled.
if ($idsrules{$rulefile}{$sid}{'State'} eq "off") {
# Check if the state has been set to 'on'.
if ($cgiparams{$sid} eq "on") {
# Add/Modify the sid to/in the enabled_disabled_sids hash.
$enabled_disabled_sids{$sid} = "enabled";
# Get enabled providers.
my @enabled_providers = &IDS::get_enabled_providers();
# Loop through the array of enabled providers.
foreach my $provider (@enabled_providers) {
# Hash to store the used-enabled and disabled sids.
my %enabled_disabled_sids;
# Generate modified sids file name for the current processed provider.
my $providers_modified_sids_file = "$IDS::settingsdir/oinkmaster-$provider-modified-sids.conf";
# Check if a modified sids file for this provider exists.
if (-f $providers_modified_sids_file) {
# Read-in the file for enabled/disabled sids.
%enabled_disabled_sids = &read_enabled_disabled_sids_file($providers_modified_sids_file);
}
# Loop through the hash of idsrules.
foreach my $rulefile (keys %idsrules) {
# Split the rulefile to get the vendor.
my @filename_parts = split(/-/, $rulefile);
# Assign rulefile vendor.
my $rulefile_vendor = @filename_parts[0];
# Skip the rulefile if the vendor is not our current processed provider.
next unless ($rulefile_vendor eq $provider);
# Loop through the single rules of the rulefile.
foreach my $sid (keys %{$idsrules{$rulefile}}) {
# Skip the current sid if it is not numeric.
next unless ($sid =~ /\d+/ );
# Check if there exists a key in the cgiparams hash for this sid.
if (exists($cgiparams{$sid})) {
# Look if the rule is disabled.
if ($idsrules{$rulefile}{$sid}{'State'} eq "off") {
# Check if the state has been set to 'on'.
if ($cgiparams{$sid} eq "on") {
# Add/Modify the sid to/in the enabled_disabled_sids hash.
$enabled_disabled_sids{$sid} = "enabled";
# Drop item from cgiparams hash.
delete $cgiparams{$rulefile}{$sid};
}
}
} else {
# Look if the rule is enabled.
if ($idsrules{$rulefile}{$sid}{'State'} eq "on") {
# Check if the state is 'on' and should be disabled.
# In this case there is no entry
# for the sid in the cgiparams hash.
# Add/Modify it to/in the enabled_disabled_sids hash.
$enabled_disabled_sids{$sid} = "disabled";
# Drop item from cgiparams hash.
delete $cgiparams{$rulefile}{$sid};
}
}
} else {
# Look if the rule is enabled.
if ($idsrules{$rulefile}{$sid}{'State'} eq "on") {
# Check if the state is 'on' and should be disabled.
# In this case there is no entry
# for the sid in the cgiparams hash.
# Add/Modify it to/in the enabled_disabled_sids hash.
$enabled_disabled_sids{$sid} = "disabled";
}
}
# Drop item from cgiparams hash.
delete $cgiparams{$rulefile}{$sid};
# Check if the hash for enabled/disabled sids contains any entries.
if (%enabled_disabled_sids) {
# Open providers modified sids file for writing.
open(PROVIDER_MOD_FILE, ">$providers_modified_sids_file") or die "Could not write to $providers_modified_sids_file. $!\n";
# Write header to the files.
print PROVIDER_MOD_FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
# Loop through the hash.
foreach my $sid (keys %enabled_disabled_sids) {
# Check if the sid is enabled.
if ($enabled_disabled_sids{$sid} eq "enabled") {
# Print the sid to the enabled_sids file.
print PROVIDER_MOD_FILE "enablesid $sid\n";
# Check if the sid is disabled.
} elsif ($enabled_disabled_sids{$sid} eq "disabled") {
# Print the sid to the disabled_sids file.
print PROVIDER_MOD_FILE "disablesid $sid\n";
# Something strange happende - skip the current sid.
} else {
next;
}
}
# Close file handle for the providers modified sids file.
close(PROVIDER_MOD_FILE);
# Add the file to the oinkmasters include file.
print OINKM_INCL_FILE "include $providers_modified_sids_file\n";
}
}
# Open enabled sid's file for writing.
open(ENABLED_FILE, ">$IDS::enabled_sids_file") or die "Could not write to $IDS::enabled_sids_file. $!\n";
# Open disabled sid's file for writing.
open(DISABLED_FILE, ">$IDS::disabled_sids_file") or die "Could not write to $IDS::disabled_sids_file. $!\n";
# Write header to the files.
print ENABLED_FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
print DISABLED_FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
# Check if the hash for enabled/disabled files contains any entries.
if (%enabled_disabled_sids) {
# Loop through the hash.
foreach my $sid (keys %enabled_disabled_sids) {
# Check if the sid is enabled.
if ($enabled_disabled_sids{$sid} eq "enabled") {
# Print the sid to the enabled_sids file.
print ENABLED_FILE "enablesid $sid\n";
# Check if the sid is disabled.
} elsif ($enabled_disabled_sids{$sid} eq "disabled") {
# Print the sid to the disabled_sids file.
print DISABLED_FILE "disablesid $sid\n";
# Something strange happende - skip the current sid.
} else {
next;
}
}
}
# Close file for enabled_sids after writing.
close(ENABLED_FILE);
# Close file for disabled_sids after writing.
close(DISABLED_FILE);
# Close the file handle after writing.
close(OINKM_INCL_FILE);
# Handle enabled / disabled rulefiles.
#
# Get enabled providers.
my @enabled_providers = &IDS::get_enabled_providers();
# Loop through the array of enabled providers.
foreach my $provider(@enabled_providers) {