X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=blobdiff_plain;f=html%2Fcgi-bin%2Fids.cgi;h=313714486553d5debd53ec67477eb91912370009;hp=3e4822cd41f327afe10d76a3aec168777d049ec6;hb=5fbd7b29829caf0bcadcccd6f56ead51e2fb812e;hpb=a13ddf04d9b58ee469b5da6bc0dd5efb64d6ebad diff --git a/html/cgi-bin/ids.cgi b/html/cgi-bin/ids.cgi index 3e4822cd41..3137144865 100644 --- a/html/cgi-bin/ids.cgi +++ b/html/cgi-bin/ids.cgi @@ -34,6 +34,7 @@ my %color = (); my %mainsettings = (); my %idsrules = (); my %idssettings=(); +my %rulessettings=(); my %rulesetsources = (); my %cgiparams=(); my %checked=(); @@ -48,36 +49,18 @@ my %ignored=(); # the list of zones in an array. my @network_zones = &IDS::get_available_network_zones(); -# File where the used rulefiles are stored. -my $idsusedrulefilesfile = "$IDS::settingsdir/suricata-used-rulefiles.yaml"; - -# File where the addresses of the homenet are stored. -my $idshomenetfile = "$IDS::settingsdir/suricata-homenet.yaml"; - -# File which contains the enabled sids. -my $enabled_sids_file = "$IDS::settingsdir/oinkmaster-enabled-sids.conf"; - -# File which contains the disabled sids. -my $disabled_sids_file = "$IDS::settingsdir/oinkmaster-disabled-sids.conf"; - -# File which contains wheater the rules should be changed. -my $modify_sids_file = "$IDS::settingsdir/oinkmaster-modify-sids.conf"; - -# File which stores the configured settings for whitelisted addresses. -my $ignoredfile = "$IDS::settingsdir/ignored"; - -# File which contains the rules to whitelist addresses on suricata. -my $whitelistfile = "$IDS::rulespath/whitelist.rules"; - my $errormessage; # Create files if they does not exist yet. -unless (-f "$enabled_sids_file") { &IDS::create_empty_file($enabled_sids_file); } -unless (-f "$disabled_sids_file") { &IDS::create_empty_file($disabled_sids_file); } -unless (-f "$modify_sids_file") { &IDS::create_empty_file($modify_sids_file); } -unless (-f "$idsusedrulefilesfile") { &IDS::create_empty_file($idsusedrulefilesfile); } -unless (-f "$ignoredfile") { &IDS::create_empty_file($ignoredfile); } -unless (-f "$whitelistfile" ) { &IDS::create_empty_file($whitelistfile); } +&IDS::check_and_create_filelayout(); + +# Hash which contains the colour code of a network zone. +my %colourhash = ( + 'red' => $Header::colourred, + 'green' => $Header::colourgreen, + 'blue' => $Header::colourblue, + 'orange' => $Header::colourorange +); &Header::showhttpheaders(); @@ -110,7 +93,7 @@ if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq my $new_entry_remark = $cgiparams{'IGNORE_ENTRY_REMARK'}; # Read-in ignoredfile. - &General::readhasharray($ignoredfile, \%ignored); + &General::readhasharray($IDS::ignored_file, \%ignored); # Check if we should edit an existing entry and got an ID. if (($cgiparams{'WHITELIST'} eq $Lang::tr{'update'}) && ($cgiparams{'ID'})) { @@ -145,10 +128,10 @@ if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq $ignored{$id} = ["$new_entry_address", "$new_entry_remark", "$status"]; # Write the changed ignored hash to the ignored file. - &General::writehasharray($ignoredfile, \%ignored); + &General::writehasharray($IDS::ignored_file, \%ignored); # Regenerate the ignore file. - &GenerateIgnoreFile(); + &IDS::generate_ignore_file(); } # Check if the IDS is running. @@ -172,7 +155,7 @@ if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq undef($cgiparams{'ID'}); # Read-in ignoredfile. - &General::readhasharray($ignoredfile, \%ignored); + &General::readhasharray($IDS::ignored_file, \%ignored); # Grab the configured status of the corresponding entry. my $status = $ignored{$id}[2]; @@ -188,10 +171,10 @@ if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq $ignored{$id} = ["$ignored{$id}[0]", "$ignored{$id}[1]", "$status"]; # Write the changed ignored hash to the ignored file. - &General::writehasharray($ignoredfile, \%ignored); + &General::writehasharray($IDS::ignored_file, \%ignored); # Regenerate the ignore file. - &GenerateIgnoreFile(); + &IDS::generate_ignore_file(); # Check if the IDS is running. if(&IDS::ids_is_running()) { @@ -206,7 +189,7 @@ if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq my %ignored = (); # Read-in ignoredfile. - &General::readhasharray($ignoredfile, \%ignored); + &General::readhasharray($IDS::ignored_file, \%ignored); # Drop entry from the hash. delete($ignored{$cgiparams{'ID'}}); @@ -215,10 +198,10 @@ if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq undef($cgiparams{'ID'}); # Write the changed ignored hash to the ignored file. - &General::writehasharray($ignoredfile, \%ignored); + &General::writehasharray($IDS::ignored_file, \%ignored); # Regenerate the ignore file. - &GenerateIgnoreFile(); + &IDS::generate_ignore_file(); # Check if the IDS is running. if(&IDS::ids_is_running()) { @@ -227,6 +210,22 @@ if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq } } +# Check if the page is locked, in this case, the ids_page_lock_file exists. +if (-e $IDS::ids_page_lock_file) { + # Lock the webpage and print notice about autoupgrade of the ruleset + # is in progess. + &working_notice("$Lang::tr{'ids ruleset autoupdate in progress'}"); + + # Loop and check if the file still exists. + while(-e $IDS::ids_page_lock_file) { + # Sleep for a second and re-check. + sleep 1; + } + + # Page has been unlocked, perform a reload. + &reload(); +} + # Check if any error has been stored. if (-e $IDS::storederrorfile) { # Open file to read in the stored error message. @@ -242,10 +241,9 @@ if (-e $IDS::storederrorfile) { unlink($IDS::storederrorfile); } - -## Grab all available snort rules and store them in the idsrules hash. +## Grab all available rules and store them in the idsrules hash. # -# Open snort rules directory and do a directory listing. +# Open rules directory and do a directory listing. opendir(DIR, $IDS::rulespath) or die $!; # Loop through the direcory. while (my $file = readdir(DIR)) { @@ -275,9 +273,9 @@ closedir(DIR); # Gather used rulefiles. # # Check if the file for activated rulefiles is not empty. -if(-f $idsusedrulefilesfile) { +if(-f $IDS::used_rulefiles_file) { # Open the file for used rulefile and read-in content. - open(FILE, $idsusedrulefilesfile) or die "Could not open $idsusedrulefilesfile. $!\n"; + open(FILE, $IDS::used_rulefiles_file) or die "Could not open $IDS::used_rulefiles_file. $!\n"; # Read-in content. my @lines = ; @@ -311,8 +309,94 @@ if(-f $idsusedrulefilesfile) { } } +# Save ruleset configuration. +if ($cgiparams{'RULESET'} eq $Lang::tr{'save'}) { + my %oldsettings; + my %rulesetsources; + + # Read-in current (old) IDS settings. + &General::readhash("$IDS::rules_settings_file", \%oldsettings); + + # Get all available ruleset locations. + &General::readhash("$IDS::rulesetsourcesfile", \%rulesetsources); + + # Prevent form name from been stored in conf file. + delete $cgiparams{'RULESET'}; + + # Grab the URL based on the choosen vendor. + my $url = $rulesetsources{$cgiparams{'RULES'}}; + + # Check if the choosen vendor (URL) requires an subscription/oinkcode. + if ($url =~ /\/ ) { + # Check if an subscription/oinkcode has been provided. + if ($cgiparams{'OINKCODE'}) { + # Check if the oinkcode contains unallowed chars. + unless ($cgiparams{'OINKCODE'} =~ /^[a-z0-9]+$/) { + $errormessage = $Lang::tr{'invalid input for oink code'}; + } + } else { + # Print an error message, that an subsription/oinkcode is required for this + # vendor. + $errormessage = $Lang::tr{'ids oinkcode required'}; + } + } + + # Go on if there are no error messages. + if (!$errormessage) { + # Store settings into settings file. + &General::writehash("$IDS::rules_settings_file", \%cgiparams); + + # Check if the the automatic rule update hass been touched. + if($cgiparams{'AUTOUPDATE_INTERVAL'} ne $oldsettings{'AUTOUPDATE_INTERVAL'}) { + # Call suricatactrl to set the new interval. + &IDS::call_suricatactrl("cron", $cgiparams{'AUTOUPDATE_INTERVAL'}); + } + + # Check if a ruleset is present - if not or the source has been changed download it. + if((! %idsrules) || ($oldsettings{'RULES'} ne $cgiparams{'RULES'})) { + # Check if the red device is active. + unless (-e "${General::swroot}/red/active") { + $errormessage = "$Lang::tr{'could not download latest updates'} - $Lang::tr{'system is offline'}"; + } + + # Check if enought free disk space is availabe. + if(&IDS::checkdiskspace()) { + $errormessage = "$Lang::tr{'not enough disk space'}"; + } + + # Check if any errors happend. + unless ($errormessage) { + # Lock the webpage and print notice about downloading + # a new ruleset. + &working_notice("$Lang::tr{'ids working'}"); + + # Call subfunction to download the ruleset. + if(&IDS::downloadruleset()) { + $errormessage = $Lang::tr{'could not download latest updates'}; + + # Call function to store the errormessage. + &IDS::_store_error_message($errormessage); + } else { + # Call subfunction to launch oinkmaster. + &IDS::oinkmaster(); + } + + # Check if the IDS is running. + if(&IDS::ids_is_running()) { + # Call suricatactrl to stop the IDS - because of the changed + # ruleset - the use has to configure it before suricata can be + # used again. + &IDS::call_suricatactrl("stop"); + } + + # Perform a reload of the page. + &reload(); + } + } + } + # Save ruleset. -if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { +} elsif ($cgiparams{'RULESET'} eq $Lang::tr{'ids apply'}) { # Arrays to store which rulefiles have been enabled and will be used. my @enabled_rulefiles; @@ -335,8 +419,8 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { # 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($disabled_sids_file), - &read_enabled_disabled_sids_file($enabled_sids_file)); + &read_enabled_disabled_sids_file($IDS::disabled_sids_file), + &read_enabled_disabled_sids_file($IDS::enabled_sids_file)); # Loop through the hash of idsrules. foreach my $rulefile (keys %idsrules) { @@ -375,10 +459,10 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { } # Open enabled sid's file for writing. - open(ENABLED_FILE, ">$enabled_sids_file") or die "Could not write to $enabled_sids_file. $!\n"; + 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, ">$disabled_sids_file") or die "Could not write to $disabled_sids_file. $!\n"; + 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"; @@ -409,32 +493,11 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { # Close file for disabled_sids after writing. close(DISABLED_FILE); - # Open file for used rulefiles. - open (FILE, ">$idsusedrulefilesfile") or die "Could not write to $idsusedrulefilesfile. $!\n"; - - # Write yaml header to the file. - print FILE "%YAML 1.1\n"; - print FILE "---\n\n"; - - # Write header to file. - print FILE "#Autogenerated file. Any custom changes will be overwritten!\n"; - - # Check if the enabled_rulefiles array contains any entries. - if (@enabled_rulefiles) { - # Allways load the whitelist. - print FILE " - whitelist.rules\n"; - - # Loop through the array of rulefiles which should be loaded and write them to the file. - foreach my $file (@enabled_rulefiles) { - print FILE " - $file\n"; - } - } - - # Close file after writing. - close(FILE); + # Call function to generate and write the used rulefiles file. + &IDS::write_used_rulefiles_file(@enabled_rulefiles); # Lock the webpage and print message. - &working_notice("$Lang::tr{'snort working'}"); + &working_notice("$Lang::tr{'ids apply ruleset changes'}"); # Call oinkmaster to alter the ruleset. &IDS::oinkmaster(); @@ -449,10 +512,10 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { &reload(); # Download new ruleset. -} elsif ($cgiparams{'RULESET'} eq $Lang::tr{'download new ruleset'}) { +} elsif ($cgiparams{'RULESET'} eq $Lang::tr{'update ruleset'}) { # Check if the red device is active. unless (-e "${General::swroot}/red/active") { - $errormessage = $Lang::tr{'could not download latest updates'}; + $errormessage = "$Lang::tr{'could not download latest updates'} - $Lang::tr{'system is offline'}"; } # Check if enought free disk space is availabe. @@ -464,7 +527,7 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { unless ($errormessage) { # Lock the webpage and print notice about downloading # a new ruleset. - &working_notice("$Lang::tr{'snort working'}"); + &working_notice("$Lang::tr{'ids download new ruleset'}"); # Call subfunction to download the ruleset. if(&IDS::downloadruleset()) { @@ -489,61 +552,72 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { &reload(); } } -# Save snort settings. +# Save IDS settings. } elsif ($cgiparams{'IDS'} eq $Lang::tr{'save'}) { my %oldidssettings; my $reload_page; + my $monitored_zones = 0; # Read-in current (old) IDS settings. - &General::readhash("$IDS::settingsdir/settings", \%oldidssettings); + &General::readhash("$IDS::ids_settings_file", \%oldidssettings); # Prevent form name from been stored in conf file. delete $cgiparams{'IDS'}; - # Check if an oinkcode has been provided. - if ($cgiparams{'OINKCODE'}) { - # Check if the oinkcode contains unallowed chars. - unless ($cgiparams{'OINKCODE'} =~ /^[a-z0-9]+$/) { - $errormessage = $Lang::tr{'invalid input for oink code'}; + # Check if the IDS should be enabled. + if ($cgiparams{'ENABLE_IDS'} eq "on") { + # Check if any ruleset is available. Otherwise abort and display an error. + unless(%idsrules) { + $errormessage = $Lang::tr{'ids no ruleset available'}; + } + + # Loop through the array of available interfaces. + foreach my $zone (@network_zones) { + # Convert interface name into upper case. + my $zone_upper = uc($zone); + + # Check if the IDS is enabled for this interaces. + if ($cgiparams{"ENABLE_IDS_$zone_upper"}) { + # Increase count. + $monitored_zones++; + } + } + + # Check if at least one zone should be monitored, or show an error. + unless ($monitored_zones >= 1) { + $errormessage = $Lang::tr{'ids no network zone'}; } } # Go on if there are no error messages. if (!$errormessage) { # Store settings into settings file. - &General::writehash("$IDS::settingsdir/settings", \%cgiparams); + &General::writehash("$IDS::ids_settings_file", \%cgiparams); } # Generate file to store the home net. - &generate_home_net_file(); - - # Check if the the automatic rule update hass been touched. - if($cgiparams{'AUTOUPDATE_INTERVAL'} ne $oldidssettings{'AUTOUPDATE_INTERVAL'}) { - # Call suricatactrl to set the new interval. - &IDS::call_suricatactrl("cron", $cgiparams{'AUTOUPDATE_INTERVAL'}); - } - - # Check if the runmode has been changed. - if($cgiparams{'RUN_MODE'} ne $oldidssettings{'RUN_MODE'}) { - # Open modify sid's file for writing. - open(FILE, ">$modify_sids_file") or die "Could not write to $modify_sids_file. $!\n"; + &IDS::generate_home_net_file(); - # Write file header. - print FILE "#Autogenerated file. Any custom changes will be overwritten!\n"; + # Temporary variable to set the ruleaction. + # Default is "drop" to use suricata as IPS. + my $ruleaction="drop"; - # Check if the configured runmode is IPS. - if ($cgiparams{'RUN_MODE'} eq 'IPS') { - # Tell oinkmaster to switch all rules from alert to drop. - print FILE "modifysid \* \"alert\" \| \"drop\"\n"; - } + # Check if the traffic only should be monitored. + if($cgiparams{'MONITOR_TRAFFIC_ONLY'} eq 'on') { + # Switch the ruleaction to "alert". + # Suricata acts as an IDS only. + $ruleaction="alert"; + } - # Close file handle. - close(FILE); + # Write the modify sid's file and pass the taken ruleaction. + &IDS::write_modify_sids_file($ruleaction); + # Check if "MONITOR_TRAFFIC_ONLY" has been changed. + if($cgiparams{'MONITOR_TRAFFIC_ONLY'} ne $oldidssettings{'MONITOR_TRAFFIC_ONLY'}) { # Check if a ruleset exists. if (%idsrules) { # Lock the webpage and print message. - &working_notice("$Lang::tr{'snort working'}"); + &working_notice("$Lang::tr{'ids working'}"); # Call oinkmaster to alter the ruleset. &IDS::oinkmaster(); @@ -575,13 +649,14 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'update'}) { } } -# Read-in idssettings -&General::readhash("$IDS::settingsdir/settings", \%idssettings); +# Read-in idssettings and rulesetsettings +&General::readhash("$IDS::ids_settings_file", \%idssettings); +&General::readhash("$IDS::rules_settings_file", \%rulessettings); -# If the runmode has not been configured yet, set default value. -unless(exists($idssettings{'RUN_MODE'})) { - # Set default to IPS. - $idssettings{'RUN_MODE'} = 'IPS'; +# If no autoupdate intervall has been configured yet, set default value. +unless(exists($rulessettings{'AUTOUPDATE_INTERVAL'})) { + # Set default to "weekly". + $rulessettings{'AUTOUPDATE_INTERVAL'} = 'weekly'; } # Read-in ignored hosts. @@ -590,29 +665,59 @@ unless(exists($idssettings{'RUN_MODE'})) { $checked{'ENABLE_IDS'}{'off'} = ''; $checked{'ENABLE_IDS'}{'on'} = ''; $checked{'ENABLE_IDS'}{$idssettings{'ENABLE_IDS'}} = "checked='checked'"; -$checked{'RUN_MODE'}{'IDS'} = ''; -$checked{'RUN_MODE'}{'IPS'} = ''; -$checked{'RUN_MODE'}{$idssettings{'RUN_MODE'}} = "checked='checked'"; +$checked{'MONITOR_TRAFFIC_ONLY'}{'off'} = ''; +$checked{'MONITOR_TRAFFIC_ONLY'}{'on'} = ''; +$checked{'MONITOR_TRAFFIC_ONLY'}{$idssettings{'MONITOR_TRAFFIC_ONLY'}} = "checked='checked'"; $selected{'RULES'}{'nothing'} = ''; $selected{'RULES'}{'community'} = ''; $selected{'RULES'}{'emerging'} = ''; $selected{'RULES'}{'registered'} = ''; $selected{'RULES'}{'subscripted'} = ''; -$selected{'RULES'}{$idssettings{'RULES'}} = "selected='selected'"; +$selected{'RULES'}{$rulessettings{'RULES'}} = "selected='selected'"; $selected{'AUTOUPDATE_INTERVAL'}{'off'} = ''; $selected{'AUTOUPDATE_INTERVAL'}{'daily'} = ''; $selected{'AUTOUPDATE_INTERVAL'}{'weekly'} = ''; -$selected{'AUTOUPDATE_INTERVAL'}{$idssettings{'AUTOUPDATE_INTERVAL'}} = "selected='selected'"; +$selected{'AUTOUPDATE_INTERVAL'}{$rulessettings{'AUTOUPDATE_INTERVAL'}} = "selected='selected'"; &Header::openpage($Lang::tr{'intrusion detection system'}, 1, ''); ### Java Script ### +print" END @@ -677,131 +782,140 @@ END END } -&Header::closebox(); -# Draw elements for IDS configuration. -&Header::openbox('100%', 'center', $Lang::tr{'settings'}); +# Only show this area, if a ruleset is present. +if (%idsrules) { -my $rulesdate; + print <

$Lang::tr{'settings'}

- # Grab details about the creation time. - $rulesdate = localtime($Info[9]); -} +
+ + + -print < -
+  $Lang::tr{'ids enable'} +
- - - + - - - + + + + + + - - - + + + - - - + +END +; - - - + # Loop through the array of available networks and print config options. + foreach my $zone (@network_zones) { + my $checked_input; + my $checked_forward; - - - + # Convert current zone name to upper case. + my $zone_upper = uc($zone); - -END -; + # Set zone name. + my $zone_name = $zone; -# Loop through the array of available networks and print config options. -foreach my $zone (@network_zones) { - my $checked_input; - my $checked_forward; + # Dirty hack to get the correct language string for the red zone. + if ($zone eq "red") { + $zone_name = "red1"; + } - # Convert current zone name to upper case. - my $zone_upper = uc($zone); + # Grab checkbox status from settings hash. + if ($idssettings{"ENABLE_IDS_$zone_upper"} eq "on") { + $checked_input = "checked = 'checked'"; + } - # Grab checkbox status from settings hash. - if ($idssettings{"ENABLE_IDS_$zone_upper"} eq "on") { - $checked_input = "checked = 'checked'"; + print "\n"; } - print "\n"; +print < +
- $Lang::tr{'ids activate'} $Lang::tr{'intrusion detection system'} + +  $Lang::tr{'ids monitor traffic only'}










$Lang::tr{'runmode'}
$Lang::tr{'ids monitored interfaces'}
- $Lang::tr{'intrusion detection system2'}     - $Lang::tr{'intrusion prevention system'} -

$Lang::tr{'ids traffic analyze'}
\n"; + print "\n"; + print " $Lang::tr{'enabled on'} $Lang::tr{$zone_name}\n"; + print "\n"; - print "$Lang::tr{'enabled on'} $Lang::tr{$zone}\n"; - print "
+ +

+ + + + + +
+
+END +; + } -print < +&Header::closebox(); - -

- +# Draw elements for ruleset configuration. +&Header::openbox('100%', 'center', $Lang::tr{'ids ruleset settings'}); +print < + - - + + - - - + - - + + - + - -
$Lang::tr{'ids rules update'}$Lang::tr{'ids automatic rules update'}$Lang::tr{'ids rules update'}$Lang::tr{'ids automatic rules update'}
+
-
$Lang::tr{'ids rules license'} www.snort.org$Lang::tr{'ids rules license1'}
-
$Lang::tr{'ids rules license2'} Get an Oinkcode, $Lang::tr{'ids rules license3'}
-


Oinkcode: 

-  $Lang::tr{'updates installed'}: $rulesdate -
 
- -

+ +END +; + # Show the "Update Ruleset"-Button only if a ruleset has been downloaded yet and automatic updates are disabled. + if ((%idsrules) && ($rulessettings{'AUTOUPDATE_INTERVAL'} eq "off")) { + # Display button to update the ruleset. + print"\n"; + } +print < + - - -
@@ -944,17 +1058,26 @@ END # Only show the section for configuring the ruleset if one is present. if (%idsrules) { - &Header::openbox('100%', 'LEFT', $Lang::tr{'intrusion detection system rules'}); + # Load neccessary perl modules for file stat and to format the timestamp. + use File::stat; + use POSIX qw( strftime ); + + # Call stat on the rulestarball. + my $stat = stat("$IDS::rulestarball"); + + # Get timestamp the file creation. + my $mtime = $stat->mtime; + + # Convert into human read-able format. + my $rulesdate = strftime('%Y-%m-%d %H:%M:%S', localtime($mtime)); + + &Header::openbox('100%', 'LEFT', "$Lang::tr{'intrusion detection system rules'} ($rulesdate)" ); print"
\n"; # Output display table for rule files print "\n"; - # Local variable required for java script to show/hide - # rules of a rulefile. - my $rulesetcount = 1; - # Loop over each rule file foreach my $rulefile (sort keys(%idsrules)) { my $rulechecked = ''; @@ -964,6 +1087,9 @@ if (%idsrules) { $rulechecked = 'CHECKED'; } + # Convert rulefile name into category name. + my $categoryname = &_rulefile_to_category($rulefile); + # Table and rows for the rule files. print"\n"; print"\n"; print"\n"; print"\n"; print"\n"; # Rows which will be hidden per default and will contain the single rules. - print"\n"; + print"\n"; print"
\n"; @@ -971,12 +1097,12 @@ if (%idsrules) { print"$rulefile\n"; - print"SHOW\n"; + print"$Lang::tr{'ids show'}\n"; print"
"; - - # Finished whith the rule file, increase count. - $rulesetcount++; } # Close display table @@ -1043,9 +1166,7 @@ if (%idsrules) { print < - -   - + @@ -1182,135 +1303,6 @@ sub get_memory_usage($) { return; } -# -## Function to generate the file which contains the home net information. -# -sub generate_home_net_file() { - my %netsettings; - - # Read-in network settings. - &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); - - # Get available network zones. - my @network_zones = &IDS::get_available_network_zones(); - - # Temporary array to store network address and prefix of the configured - # networks. - my @networks; - - # Loop through the array of available network zones. - foreach my $zone (@network_zones) { - # Skip the red network - It never can be part to the home_net! - next if($zone eq "red"); - - # Convert current zone name into upper case. - $zone = uc($zone); - - # Generate key to access the required data from the netsettings hash. - my $zone_netaddress = $zone . "_NETADDRESS"; - my $zone_netmask = $zone . "_NETMASK"; - - # Obtain the settings from the netsettings hash. - my $netaddress = $netsettings{$zone_netaddress}; - my $netmask = $netsettings{$zone_netmask}; - - # Convert the subnetmask into prefix notation. - my $prefix = &Network::convert_netmask2prefix($netmask); - - # Generate full network string. - my $network = join("/", $netaddress,$prefix); - - # Check if the network is valid. - if(&Network::check_subnet($network)) { - # Add the generated network to the array of networks. - push(@networks, $network); - } - } - - # Format home net declaration. - my $line = "\"\["; - - # Loop through the array of networks. - foreach my $network (@networks) { - # Add the network to the line. - $line = "$line" . "$network"; - - # Check if the current network was the last in the array. - if ($network eq $networks[-1]) { - # Close the line. - $line = "$line" . "\]\""; - } else { - # Add "," for the next network. - $line = "$line" . "\,"; - } - } - - # Open file to store the addresses of the home net. - open(FILE, ">$idshomenetfile") or die "Could not open $idshomenetfile. $!\n"; - - # Print yaml header. - print FILE "%YAML 1.1\n"; - print FILE "---\n\n"; - - # Print notice about autogenerated file. - print FILE "#Autogenerated file. Any custom changes will be overwritten!\n"; - - # Print the generated and required HOME_NET declaration to the file. - print FILE "HOME_NET:\t$line\n"; - - # Close file handle. - close(FILE); - -} - -# -## Function to generate the rules file with whitelisted addresses. -# -sub GenerateIgnoreFile() { - my %ignored = (); - - # SID range 1000000-1999999 Reserved for Local Use - # Put your custom rules in this range to avoid conflicts - my $sid = 1500000; - - # Read-in ignoredfile. - &General::readhasharray($ignoredfile, \%ignored); - - # Open ignorefile for writing. - open(FILE, ">$whitelistfile") or die "Could not write to $whitelistfile. $!\n"; - - # Config file header. - print FILE "# Autogenerated file.\n"; - print FILE "# All user modifications will be overwritten.\n\n"; - - # Add all user defined addresses to the whitelist. - # - # Check if the hash contains any elements. - if (keys (%ignored)) { - # Loop through the entire hash and write the host/network - # and remark to the ignore file. - while ( (my $key) = each %ignored) { - my $address = $ignored{$key}[0]; - my $remark = $ignored{$key}[1]; - my $status = $ignored{$key}[2]; - - # Check if the status of the entry is "enabled". - if ($status eq "enabled") { - # Check if the address/network is valid. - if ((&General::validip($address)) || (&General::validipandmask($address))) { - # Write rule line to the file to pass any traffic from this IP - print FILE "pass ip $address any -> any any (msg:\"pass all traffic from/to $address\"\; sid:$sid\;)\n"; - - # Increment sid. - $sid++; - } - } - } - } - - close(FILE); -} - # ## Function to read-in the given enabled or disables sids file. # @@ -1361,3 +1353,27 @@ sub read_enabled_disabled_sids_file($) { # Return the hash. return %temphash; } + +# +## Private function to convert a given rulefile to a category name. +## ( No file extension anymore and if the name contained a dot, it +## would be replaced by a underline sign.) +# +sub _rulefile_to_category($) { + my ($filename) = @_; + + # Splitt the filename into single chunks and store them in a + # temorary array. + my @parts = split(/\./, $filename); + + # Return / Remove last element of the temporary array. + # This removes the file extension. + pop @parts; + + # Join together the single elements of the temporary array. + # If these are more than one, use a "underline" for joining. + my $category = join '_', @parts; + + # Return the converted filename. + return $category; +}