Merge remote-tracking branch 'stevee/next-suricata' into next
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 14 Mar 2019 13:19:35 +0000 (13:19 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 14 Mar 2019 13:19:35 +0000 (13:19 +0000)
57 files changed:
config/backup/backup.pl
config/backup/include
config/cfgroot/general-functions.pl
config/cfgroot/ids-functions.pl [new file with mode: 0644]
config/collectd/collectd.conf
config/etc/group
config/etc/logrotate.conf
config/etc/passwd
config/etc/syslog.conf
config/menu/40-services.menu
config/menu/50-firewall.menu
config/oinkmaster/oinkmaster.conf [new file with mode: 0644]
config/rootfiles/common/aarch64/initscripts
config/rootfiles/common/aarch64/stage2
config/rootfiles/common/armv5tel/initscripts
config/rootfiles/common/configroot
config/rootfiles/common/daq [deleted file]
config/rootfiles/common/i586/initscripts
config/rootfiles/common/ids-ruleset-sources [new file with mode: 0644]
config/rootfiles/common/libcap-ng [new file with mode: 0644]
config/rootfiles/common/libhtp [new file with mode: 0644]
config/rootfiles/common/misc-progs
config/rootfiles/common/oinkmaster
config/rootfiles/common/snort [deleted file]
config/rootfiles/common/stage2
config/rootfiles/common/suricata [new file with mode: 0644]
config/rootfiles/common/x86_64/initscripts
config/rootfiles/common/x86_64/stage2
config/rootfiles/common/yaml [new file with mode: 0644]
config/snort/snort.conf [deleted file]
config/suricata/convert-snort [new file with mode: 0644]
config/suricata/ruleset-sources [new file with mode: 0644]
config/suricata/suricata.yaml [new file with mode: 0644]
html/cgi-bin/aliases.cgi
html/cgi-bin/ids.cgi
html/cgi-bin/logs.cgi/ids.dat
html/cgi-bin/logs.cgi/log.dat
html/cgi-bin/services.cgi
langs/de/cgi-bin/de.pl
langs/en/cgi-bin/en.pl
lfs/configroot
lfs/ids-ruleset-sources [new file with mode: 0644]
lfs/initscripts
lfs/libcap-ng [moved from lfs/snort with 74% similarity]
lfs/libhtp [new file with mode: 0644]
lfs/oinkmaster
lfs/suricata [new file with mode: 0644]
lfs/yaml [moved from lfs/daq with 93% similarity]
make.sh
src/initscripts/networking/red.up/23-suricata [new file with mode: 0644]
src/initscripts/system/firewall
src/initscripts/system/snort [deleted file]
src/initscripts/system/suricata [new file with mode: 0644]
src/misc-progs/Makefile
src/misc-progs/snortctrl.c [deleted file]
src/misc-progs/suricatactrl.c [new file with mode: 0644]
src/scripts/update-ids-ruleset [new file with mode: 0644]

index 3accbcf..5737740 100644 (file)
@@ -129,6 +129,15 @@ restore_backup() {
        # Convert old OpenVPN CCD files (CN change, Core Update 75)
        convert-ovpn
 
+       # Snort to suricata converter.
+       if [ -d "/var/ipfire/snort" ]; then
+               # Run converter
+               convert-snort
+
+               # Remove old configuration directory.
+               rm -rf "/var/ipfire/snort"
+       fi
+
        return 0
 }
 
index 6c7affa..1190eda 100644 (file)
 /var/ipfire/proxy
 /var/ipfire/qos/*
 /var/ipfire/qos/bin/qos.sh
+/var/ipfire/suricata/*.conf
+/var/ipfire/suricata/*.yaml
 /var/ipfire/*/settings
 /var/ipfire/time/
 /var/ipfire/urlfilter
 /var/ipfire/vpn
+/var/lib/suricata
 /var/log/ip-acct/*
 /var/log/rrd/*
 /var/log/rrd/collectd
index e8495e8..04e3696 100644 (file)
@@ -149,6 +149,10 @@ sub readhash
        while (<FILE>)
        {
                chop;
+
+               # Skip comments.
+               next if ($_ =~ /^#/);
+
                ($var, $val) = split /=/, $_, 2;
                if ($var)
                {
diff --git a/config/cfgroot/ids-functions.pl b/config/cfgroot/ids-functions.pl
new file mode 100644 (file)
index 0000000..016c0e4
--- /dev/null
@@ -0,0 +1,981 @@
+#!/usr/bin/perl -w
+############################################################################
+#                                                                          #
+# This file is part of the IPFire Firewall.                                #
+#                                                                          #
+# IPFire is free software; you can redistribute it and/or modify           #
+# it under the terms of the GNU General Public License as published by     #
+# the Free Software Foundation; either version 2 of the License, or        #
+# (at your option) any later version.                                      #
+#                                                                          #
+# IPFire is distributed in the hope that it will be useful,                #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of           #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            #
+# GNU General Public License for more details.                             #
+#                                                                          #
+# You should have received a copy of the GNU General Public License        #
+# along with IPFire; if not, write to the Free Software                    #
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA #
+#                                                                          #
+# Copyright (C) 2018 IPFire Team <info@ipfire.org>.                        #
+#                                                                          #
+############################################################################
+
+package IDS;
+
+require '/var/ipfire/general-functions.pl';
+
+# Location where all config and settings files are stored.
+our $settingsdir = "${General::swroot}/suricata";
+
+# File where the used rulefiles are stored.
+our $used_rulefiles_file = "$settingsdir/suricata-used-rulefiles.yaml";
+
+# File where the addresses of the homenet are stored.
+our $homenet_file = "$settingsdir/suricata-homenet.yaml";
+
+# File which contains the enabled sids.
+our $enabled_sids_file = "$settingsdir/oinkmaster-enabled-sids.conf";
+
+# File which contains the disabled sids.
+our $disabled_sids_file = "$settingsdir/oinkmaster-disabled-sids.conf";
+
+# File which contains wheater the rules should be changed.
+our $modify_sids_file = "$settingsdir/oinkmaster-modify-sids.conf";
+
+# File which stores the configured IPS settings.
+our $ids_settings_file = "$settingsdir/settings";
+
+# File which stores the configured rules-settings.
+our $rules_settings_file = "$settingsdir/rules-settings";
+
+# File which stores the configured settings for whitelisted addresses.
+our $ignored_file = "$settingsdir/ignored";
+
+# Location and name of the tarball which contains the ruleset.
+our $rulestarball = "/var/tmp/idsrules.tar.gz";
+
+# File to store any errors, which also will be read and displayed by the wui.
+our $storederrorfile = "/tmp/ids_storederror";
+
+# File to lock the WUI, while the autoupdate script runs.
+our $ids_page_lock_file = "/tmp/ids_page_locked";
+
+# Location where the rulefiles are stored.
+our $rulespath = "/var/lib/suricata";
+
+# File which contains the rules to whitelist addresses on suricata.
+our $whitelist_file = "$rulespath/whitelist.rules";
+
+# File which contains a list of all supported ruleset sources.
+# (Sourcefire, Emergingthreads, etc..)
+our $rulesetsourcesfile = "$settingsdir/ruleset-sources";
+
+# The pidfile of the IDS.
+our $idspidfile = "/var/run/suricata.pid";
+
+# Location of suricatactrl.
+my $suricatactrl = "/usr/local/bin/suricatactrl";
+
+# Array with allowed commands of suricatactrl.
+my @suricatactrl_cmds = ( 'start', 'stop', 'restart', 'reload', 'fix-rules-dir', 'cron' );
+
+# Array with supported cron intervals.
+my @cron_intervals = ('off', 'daily', 'weekly' );
+
+#
+## Function to check and create all IDS related files, if the does not exist.
+#
+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 "$modify_sids_file") { &create_empty_file($modify_sids_file); }
+       unless (-f "$used_rulefiles_file") { &create_empty_file($used_rulefiles_file); }
+       unless (-f "$ids_settings_file") { &create_empty_file($ids_settings_file); }
+       unless (-f "$rules_settings_file") { &create_empty_file($rules_settings_file); }
+       unless (-f "$ignored_file") { &create_empty_file($ignored_file); }
+       unless (-f "$whitelist_file" ) { &create_empty_file($whitelist_file); }
+}
+
+#
+## Function for checking if at least 300MB of free disk space are available
+## on the "/var" partition.
+#
+sub checkdiskspace () {
+       # Call diskfree to gather the free disk space of /var.
+       my @df = `/bin/df -B M /var`;
+
+       # Loop through the output.
+       foreach my $line (@df) {
+               # Ignore header line.
+               next if $line =~ m/^Filesystem/;
+
+               # Search for a line with the device information.
+               if ($line =~ m/dev/ ) {
+                       # Split the line into single pieces.
+                       my @values = split(' ', $line);
+                       my ($filesystem, $blocks, $used, $available, $used_perenctage, $mounted_on) = @values;
+
+                       # Check if the available disk space is more than 300MB.
+                       if ($available < 300) {
+                               # Log error to syslog.
+                               &_log_to_syslog("Not enough free disk space on /var. Only $available MB from 300 MB available.");
+
+                               # Exit function and return "1" - False.
+                               return 1;
+                       }
+               }
+       }
+
+       # Everything okay, return nothing.
+       return;
+}
+
+#
+## This function is responsible for downloading the configured IDS ruleset.
+##
+## * At first it obtains from the stored rules settings which ruleset should be downloaded.
+## * The next step is to get the download locations for all available rulesets.
+## * After that, the function will check if an upstream proxy should be used and grab the settings.
+## * The last step will be to generate the final download url, by obtaining the URL for the desired
+##   ruleset, add the settings for the upstream proxy and final grab the rules tarball from the server.
+#
+sub downloadruleset {
+       # Get rules settings.
+       my %rulessettings=();
+       &General::readhash("$rules_settings_file", \%rulessettings);
+
+       # Check if a ruleset has been configured.
+       unless($rulessettings{'RULES'}) {
+               # Log that no ruleset has been configured and abort.
+               &_log_to_syslog("No ruleset source has been configured.");
+
+               # Return "1".
+               return 1;
+       }
+
+       # Get all available ruleset locations.
+       my %rulesetsources=();
+       &General::readhash($rulesetsourcesfile, \%rulesetsources);
+
+       # Read proxysettings.
+       my %proxysettings=();
+       &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+
+       # Load required perl module to handle the download.
+       use LWP::UserAgent;
+
+       # Init the download module.
+       my $downloader = LWP::UserAgent->new;
+
+       # Set timeout to 10 seconds.
+       $downloader->timeout(10);
+
+       # Check if an upstream proxy is configured.
+       if ($proxysettings{'UPSTREAM_PROXY'}) {
+               my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+               my $proxy_url;
+
+               # Check if we got a peer.
+               if ($peer) {
+                       $proxy_url = "http://";
+
+                       # Check if the proxy requires authentication.
+                       if (($proxysettings{'UPSTREAM_USER'}) && ($proxysettings{'UPSTREAM_PASSWORD'})) {
+                               $proxy_url .= "$proxysettings{'UPSTREAM_USER'}\:$proxysettings{'UPSTREAM_PASSWORD'}\@";
+                       }
+
+                       # Add proxy server address and port.
+                       $proxy_url .= "$peer\:$peerport";
+               } else {
+                       # Log error message and break.
+                       &_log_to_syslog("Could not proper configure the proxy server access.");
+
+                       # Return "1" - false.
+                       return 1;
+               }
+
+               # Setup proxy settings.
+               $downloader->proxy(['http', 'https'], $proxy_url);
+       }
+
+       # Grab the right url based on the configured vendor.
+       my $url = $rulesetsources{$rulessettings{'RULES'}};
+
+       # Check if the vendor requires an oinkcode and add it if needed.
+       $url =~ s/\<oinkcode\>/$rulessettings{'OINKCODE'}/g;
+
+       # Abort if no url could be determined for the vendor.
+       unless ($url) {
+               # Log error and abort.
+               &_log_to_syslog("Unable to gather a download URL for the selected ruleset.");
+               return 1;
+       }
+
+       # Variable to store the filesize of the remote object.
+       my $remote_filesize;
+
+       # The sourcfire (snort rules) does not allow to send "HEAD" requests, so skip this check
+       # for this webserver.
+       #
+       # Check if the ruleset source contains "snort.org".
+       unless ($url =~ /\.snort\.org/) {
+               # Pass the requrested url to the downloader.
+               my $request = HTTP::Request->new(HEAD => $url);
+
+               # Accept the html header.
+               $request->header('Accept' => 'text/html');
+
+               # Perform the request and fetch the html header.
+               my $response = $downloader->request($request);
+
+               # Check if there was any error.
+               unless ($response->is_success) {
+                       # Obtain error.
+                       my $error = $response->status_line();
+
+                       # Log error message.
+                       &_log_to_syslog("Unable to download the ruleset. \($error\)");
+
+                       # Return "1" - false.
+                       return 1;
+               }
+
+               # Assign the fetched header object.
+               my $header = $response->headers();
+
+               # Grab the remote file size from the object and store it in the
+               # variable.
+               $remote_filesize = $header->content_length;
+       }
+
+       # Load perl module to deal with temporary files.
+       use File::Temp;
+
+       # Generate temporay file name, located in "/var/tmp" and with a suffix of ".tar.gz".
+       my $tmp = File::Temp->new( SUFFIX => ".tar.gz", DIR => "/var/tmp/", UNLINK => 0 );
+       my $tmpfile = $tmp->filename();
+
+       # Pass the requested url to the downloader.
+       my $request = HTTP::Request->new(GET => $url);
+
+       # Perform the request and save the output into the tmpfile.
+       my $response = $downloader->request($request, $tmpfile);
+
+       # Check if there was any error.
+       unless ($response->is_success) {
+               # Obtain error.
+               my $error = $response->content;
+
+               # Log error message.
+               &_log_to_syslog("Unable to download the ruleset. \($error\)");
+
+               # Return "1" - false.
+               return 1;
+       }
+
+       # Load perl stat module.
+       use File::stat;
+
+       # Perform stat on the tmpfile.
+       my $stat = stat($tmpfile);
+
+       # Grab the local filesize of the downloaded tarball.
+       my $local_filesize = $stat->size;
+
+       # Check if both file sizes match.
+       if (($remote_filesize) && ($remote_filesize ne $local_filesize)) {
+               # Log error message.
+               &_log_to_syslog("Unable to completely download the ruleset. ");
+               &_log_to_syslog("Only got $local_filesize Bytes instead of $remote_filesize Bytes. ");
+
+               # Delete temporary file.
+               unlink("$tmpfile");
+
+               # Return "1" - false.
+               return 1;
+       }
+
+       # Load file copy module, which contains the move() function.
+       use File::Copy;
+
+       # Overwrite existing rules tarball with the new downloaded one.
+       move("$tmpfile", "$rulestarball");
+
+       # If we got here, everything worked fine. Return nothing.
+       return;
+}
+
+#
+## A tiny wrapper function to call the oinkmaster script.
+#
+sub oinkmaster () {
+       # Check if the files in rulesdir have the correct permissions.
+       &_check_rulesdir_permissions();
+
+       # Cleanup the rules directory before filling it with the new rulest.
+       &_cleanup_rulesdir();
+
+       # Load perl module to talk to the kernel syslog.
+       use Sys::Syslog qw(:DEFAULT setlogsock);
+
+       # Establish the connection to the syslog service.
+       openlog('oinkmaster', 'cons,pid', 'user');
+
+       # Call oinkmaster to generate ruleset.
+       open(OINKMASTER, "/usr/local/bin/oinkmaster.pl -v -s -u file://$rulestarball -C $settingsdir/oinkmaster.conf -o $rulespath|") or die "Could not execute oinkmaster $!\n";
+
+       # Log output of oinkmaster to syslog.
+       while(<OINKMASTER>) {
+               # The syslog function works best with an array based input,
+               # so generate one before passing the message details to syslog.
+               my @syslog = ("INFO", "$_");
+
+               # Send the log message.
+               syslog(@syslog);
+       }
+
+       # Close the pipe to oinkmaster process.
+       close(OINKMASTER);
+
+       # Close the log handle.
+       closelog();
+}
+
+#
+## Function to do all the logging stuff if the downloading or updating of the ruleset fails.
+#
+sub log_error ($) {
+       my ($error) = @_;
+
+       # Remove any newline.
+       chomp($error);
+
+       # Call private function to log the error message to syslog.
+       &_log_to_syslog($error);
+
+       # Call private function to write/store the error message in the storederrorfile.
+       &_store_error_message($error);
+}
+
+#
+## Function to log a given error message to the kernel syslog.
+#
+sub _log_to_syslog ($) {
+       my ($message) = @_;
+
+       # Load perl module to talk to the kernel syslog.
+       use Sys::Syslog qw(:DEFAULT setlogsock);
+
+       # The syslog function works best with an array based input,
+       # so generate one before passing the message details to syslog.
+       my @syslog = ("ERR", "<ERROR> $message");
+
+       # Establish the connection to the syslog service.
+       openlog('oinkmaster', 'cons,pid', 'user');
+
+       # Send the log message.
+       syslog(@syslog);
+
+       # Close the log handle.
+       closelog();
+}
+
+#
+## Private function to write a given error message to the storederror file.
+#
+sub _store_error_message ($) {
+        my ($message) = @_;
+
+       # Remove any newline.
+       chomp($message);
+
+        # Open file for writing.
+        open (ERRORFILE, ">$storederrorfile") or die "Could not write to $storederrorfile. $!\n";
+
+        # Write error to file.
+        print ERRORFILE "$message\n";
+
+        # Close file.
+        close (ERRORFILE);
+
+       # Set correct ownership for the file.
+       &set_ownership("$storederrorfile");
+}
+
+#
+## Function to get a list of all available network zones.
+#
+sub get_available_network_zones () {
+       # Get netsettings.
+       my %netsettings = ();
+       &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
+
+       # Obtain the configuration type from the netsettings hash.
+       my $config_type = $netsettings{'CONFIG_TYPE'};
+
+       # Hash which contains the conversation from the config mode
+       # to the existing network interface names. They are stored like
+       # an array.
+       #
+       # Mode "0" red is a modem and green
+       # Mode "1" red is a netdev and green
+       # Mode "2" red, green and orange
+       # Mode "3" red, green and blue
+       # Mode "4" red, green, blue, orange
+       my %config_type_to_interfaces = (
+               "0" => [ "red", "green" ],
+               "1" => [ "red", "green" ],
+               "2" => [ "red", "green", "orange" ],
+               "3" => [ "red", "green", "blue" ],
+               "4" => [ "red", "green", "blue", "orange" ]
+       );
+
+       # Obtain and dereference the corresponding network interaces based on the read
+       # network config type.
+       my @network_zones = @{ $config_type_to_interfaces{$config_type} };
+
+       # Return them.
+       return @network_zones;
+}
+
+#
+## Function to check if the IDS is running.
+#
+sub ids_is_running () {
+       if(-f $idspidfile) {
+               # Open PID file for reading.
+               open(PIDFILE, "$idspidfile") or die "Could not open $idspidfile. $!\n";
+
+               # Grab the process-id.
+               my $pid = <PIDFILE>;
+
+               # Close filehandle.
+               close(PIDFILE);
+
+               # Remove any newline.
+               chomp($pid);
+
+               # Check if a directory for the process-id exists in proc.
+               if(-d "/proc/$pid") {
+                       # The IDS daemon is running return the process id.
+                       return $pid;
+               }
+       }
+
+       # Return nothing - IDS is not running.
+       return;
+}
+
+#
+## Function to call suricatactrl binary with a given command.
+#
+sub call_suricatactrl ($) {
+       # Get called option.
+       my ($option, $interval) = @_;
+
+       # Loop through the array of supported commands and check if
+       # the given one is part of it.
+       foreach my $cmd (@suricatactrl_cmds) {
+               # Skip current command unless the given one has been found.
+               next unless($cmd eq $option);
+
+               # Check if the given command is "cron".
+               if ($option eq "cron") {
+                       # Check if an interval has been given.
+                       if ($interval) {
+                               # Check if the given interval is valid.
+                               foreach my $element (@cron_intervals) {
+                                       # Skip current element until the given one has been found.
+                                       next unless($element eq $interval);
+
+                                       # Call the suricatactrl binary and pass the "cron" command
+                                       # with the requrested interval.
+                                       system("$suricatactrl $option $interval &>/dev/null");
+
+                                       # Return "1" - True.
+                                       return 1;
+                               }
+                       }
+
+                       # If we got here, the given interval is not supported or none has been given. - Return nothing.
+                       return;
+               } else {
+                       # Call the suricatactrl binary and pass the requrested
+                       # option to it.
+                       system("$suricatactrl $option &>/dev/null");
+
+                       # Return "1" - True.
+                       return 1;
+               }
+       }
+
+       # Command not found - return nothing.
+       return;
+}
+
+#
+## Function to create a new empty file.
+#
+sub create_empty_file($) {
+       my ($file) = @_;
+
+       # Check if the given file exists.
+       if(-e $file) {
+               # Do nothing to prevent from overwriting existing files.
+               return;
+       }
+
+       # Open the file for writing.
+       open(FILE, ">$file") or die "Could not write to $file. $!\n";
+
+       # Close file handle.
+       close(FILE);
+
+       # Return true.
+       return 1;
+}
+
+#
+## Private function to check if the file permission of the rulespath are correct.
+## If not, call suricatactrl to fix them.
+#
+sub _check_rulesdir_permissions() {
+       # Check if the rulepath main directory is writable.
+       unless (-W $rulespath) {
+               # If not call suricatctrl to fix it.
+               &call_suricatactrl("fix-rules-dir");
+       }
+
+       # Open snort rules directory and do a directory listing.
+       opendir(DIR, $rulespath) or die $!;
+       # Loop through the direcory.
+       while (my $file = readdir(DIR)) {
+               # We only want files.
+               next unless (-f "$rulespath/$file");
+
+               # Check if the file is writable by the user.
+               if (-W "$rulespath/$file") {
+                       # Everything is okay - go on to the next file.
+                       next;
+               } else {
+                       # There are wrong permissions, call suricatactrl to fix it.
+                       &call_suricatactrl("fix-rules-dir");
+               }
+       }
+}
+
+#
+## Private function to cleanup the directory which contains
+## the IDS rules, before extracting and modifing the new ruleset.
+#
+sub _cleanup_rulesdir() {
+       # Open rules directory and do a directory listing.
+       opendir(DIR, $rulespath) or die $!;
+
+       # Loop through the direcory.
+       while (my $file = readdir(DIR)) {
+               # We only want files.
+               next unless (-f "$rulespath/$file");
+
+               # Skip element if it has config as file extension.
+               next if ($file =~ m/\.config$/);
+
+               # Delete the current processed file, if not, exit this function
+               # and return an error message.
+               unlink("$rulespath/$file") or return "Could not delete $rulespath/$file. $!\n";
+       }
+
+       # Return nothing;
+       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 = &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) {
+               # Check if the current processed zone is red.
+               if($zone eq "red") {
+                       # Grab the IP-address of the red interface.
+                       my $red_address = &get_red_address();
+
+                       # Check if an address has been obtained.
+                       if ($red_address) {
+                               # Generate full network string.
+                               my $red_network = join("/", $red_address, "32");
+
+                               # Add the red network to the array of networks.
+                               push(@networks, $red_network);
+                       }
+
+                       # Check if the configured RED_TYPE is static.
+                       if ($netsettings{'RED_TYPE'} eq "STATIC") {
+                               # Get configured and enabled aliases.
+                               my @aliases = &get_aliases();
+
+                               # Loop through the array.
+                               foreach my $alias (@aliases) {
+                                       # Add "/32" prefix.
+                                       my $network = join("/", $alias, "32");
+
+                                       # Add the generated network to the array of networks.
+                                       push(@networks, $network);
+                               }
+                       }
+               # Process remaining network zones.
+               } else {
+                       # 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, ">$homenet_file") or die "Could not open $homenet_file. $!\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 and write the file for used rulefiles.
+#
+sub write_used_rulefiles_file(@) {
+       my @files = @_;
+
+       # Open file for used rulefiles.
+       open (FILE, ">$used_rulefiles_file") or die "Could not write to $used_rulefiles_file. $!\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";
+
+       # Allways use the whitelist.
+       print FILE " - whitelist.rules\n";
+
+       # Loop through the array of given files.
+       foreach my $file (@files) {
+               # Check if the given filename exists and write it to the file of used rulefiles.
+               if(-f "$rulespath/$file") {
+                       print FILE " - $file\n";
+               }
+       }
+
+       # Close file after writing.
+       close(FILE);
+}
+
+#
+## Function to generate and write the file for modify the ruleset.
+#
+sub write_modify_sids_file($) {
+       my ($ruleaction) = @_;
+
+       # Open modify sid's file for writing.
+       open(FILE, ">$modify_sids_file") or die "Could not write to $modify_sids_file. $!\n";
+
+       # Write file header.
+       print FILE "#Autogenerated file. Any custom changes will be overwritten!\n";
+
+       # Tune rules to monitor in both directions.
+       print FILE "modifysid \* \"\-\>\" \| \"\<\>\"\n";
+
+       # Check if the traffic only should be monitored.
+       unless($ruleaction eq "alert") {
+               # Tell oinkmaster to switch all rules from alert to drop.
+               print FILE "modifysid \* \"alert\" \| \"drop\"\n";
+       }
+
+       # Close file handle.
+       close(FILE);
+}
+
+#
+## Function to gather the version of suricata.
+#
+sub get_suricata_version($) {
+       my ($format) = @_;
+
+       # Execute piped suricata command and return the version information.
+       open(SURICATA, "suricata -V |") or die "Couldn't execute program: $!";
+
+       # Grab and store the output of the piped program.
+       my $version_string = <SURICATA>;
+
+       # Close pipe.
+        close(SURICATA);
+
+       # Remove newlines.
+        chomp($version_string);
+
+       # Grab the version from the version string. 
+       $version_string =~ /([0-9]+([.][0-9]+)+)/;
+
+       # Splitt the version into single chunks.
+       my ($major_ver, $minor_ver, $patchlevel) = split(/\./, $1);
+
+       # Check and return the requested version sheme.
+       if ($format eq "major") {
+               # Return the full version.
+               return "$major_ver";
+       } elsif ($format eq "minor") {
+               # Return the major and minor part.
+               return "$major_ver.$minor_ver";
+       } else {
+               # Return the full version string.
+               return "$major_ver.$minor_ver.$patchlevel";
+       } 
+}
+
+#
+## Function to generate the rules file with whitelisted addresses.
+#
+sub generate_ignore_file() {
+       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($IDS::ignored_file, \%ignored);
+
+       # Open ignorefile for writing.
+       open(FILE, ">$IDS::whitelist_file") or die "Could not write to $IDS::whitelist_file. $!\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 set correct ownership for single files and directories.
+#
+
+sub set_ownership($) {
+       my ($target) = @_;
+
+       # User and group of the WUI.
+       my $uname = "nobody";
+       my $grname = "nobody";
+
+       # The chown function implemented in perl requies the user and group as nummeric id's.
+       my $uid = getpwnam($uname);
+       my $gid = getgrnam($grname);
+
+       # Check if the given target exists.
+       unless ($target) {
+               # Stop the script and print error message.
+               die "The $target does not exist. Cannot change the ownership!\n";
+       }
+
+       # Check weather the target is a file or directory.
+       if (-f $target) {
+               # Change ownership ot the single file.
+               chown($uid, $gid, "$target");
+       } elsif (-d $target) {
+               # Do a directory listing.
+               opendir(DIR, $target) or die $!;
+                       # Loop through the direcory.
+                       while (my $file = readdir(DIR)) {
+
+                               # We only want files.
+                               next unless (-f "$target/$file");
+
+                               # Set correct ownership for the files.
+                               chown($uid, $gid, "$target/$file");
+                       }
+
+               closedir(DIR);
+
+               # Change ownership of the directory.
+               chown($uid, $gid, "$target");
+       }
+}
+
+#
+## Function to read-in the aliases file and returns all configured and enabled aliases.
+#
+sub get_aliases() {
+       # Location of the aliases file.
+       my $aliases_file = "${General::swroot}/ethernet/aliases";
+
+       # Array to store the aliases.
+       my @aliases;
+
+       # Check if the file is empty.
+       if (-z $aliases_file) {
+               # Abort nothing to do.
+               return;
+       }
+
+       # Open the aliases file.
+       open(ALIASES, $aliases_file) or die "Could not open $aliases_file. $!\n";
+
+       # Loop through the file content.
+       while (my $line = <ALIASES>) {
+               # Remove newlines.
+               chomp($line);
+
+               # Splitt line content into single chunks.
+               my ($address, $state, $remark) = split(/\,/, $line);
+
+               # Check if the state of the current processed alias is "on".
+               if ($state eq "on") {
+                       # Check if the address is valid.
+                       if(&Network::check_ip_address($address)) {
+                               # Add the alias to the array of aliases.
+                               push(@aliases, $address);
+                       }
+               }
+       }
+
+       # Close file handle.
+       close(ALIASES);
+
+       # Return the array.
+       return @aliases;
+}
+
+#
+## Function to grab the current assigned IP-address on red.
+#
+sub get_red_address() {
+       # File, which contains the current IP-address of the red interface.
+       my $file = "${General::swroot}/red/local-ipaddress";
+
+       # Check if the file exists.
+       if (-e $file) {
+               # Open the given file.
+               open(FILE, "$file") or die "Could not open $file.";
+
+               # Obtain the address from the first line of the file.
+               my $address = <FILE>;
+
+               # Close filehandle
+               close(FILE);
+
+               # Remove newlines.
+               chomp $address;
+
+               # Check if the grabbed address is valid.
+               if (&General::validip($address)) {
+                       # Return the address.
+                       return $address;
+               }
+       }
+
+       # Return nothing.
+       return;
+}
+
+#
+## Function to write the lock file for locking the WUI, while
+## the autoupdate script runs.
+#
+sub lock_ids_page() {
+       # Call subfunction to create the file.
+       &create_empty_file($ids_page_lock_file);
+}
+
+#
+## Function to release the lock of the WUI, again.
+#
+sub unlock_ids_page() {
+       # Delete lock file.
+       unlink($ids_page_lock_file);
+}
+
+1;
index aea72fc..e336a9d 100644 (file)
@@ -71,7 +71,6 @@ include "/etc/collectd.precache"
        Process "squid"
        Process "squidguard"
        Process "charon"
-       Process "snort"
        Process "openvpn"
        Process "qemu"
        Process "rtorrent"
index 5b84eca..4855214 100644 (file)
@@ -26,7 +26,7 @@ pcap:x:77:
 wbpriv:x:88:squid
 nobody:x:99:
 users:x:100:
-snort:x:101:
+suricata:x:101:
 logwatch:x:102:
 cron:x:104:
 syslogd:x:105:
index d38570d..f15ee92 100644 (file)
@@ -28,16 +28,16 @@ include /etc/logrotate.d
     endscript
 }
 
-/var/log/snort/alert  {
+/var/log/suricata/*.log {
     weekly
     copytruncate
     compress
     ifempty
     missingok
     postrotate
-       /bin/find /var/log/snort -path '/var/log/snort/[0-9]*' -prune -exec /bin/rm -rf {} \;
-       /bin/find /var/log/snort -name 'snort.log.*' -mtime +28 -exec /bin/rm -rf {} \;
-       /etc/init.d/snort restart
+       /bin/find /var/log/suricata -path '/var/log/suricata/[0-9]*' -prune -exec /bin/rm -rf {} \;
+       /bin/find /var/log/suricata -name 'fast.log.*' -mtime +28 -exec /bin/rm -rf {} \;
+       /bin/kill -HUP `cat /var/run/suricata.pid 2> /dev/null` 2> /dev/null || true
     endscript
 }
 
index 7c0f7df..7893b43 100644 (file)
@@ -10,7 +10,7 @@ stunnel:x:51:51:stunnel Daemon:/var/lib/stunnel:/bin/false
 sshd:x:74:74:sshd:/var/empty:/bin/false
 nobody:x:99:99:Nobody:/home/nobody:/bin/false
 postfix:x:100:100::/var/spool/postfix:/bin/false
-snort:x:101:101:ftp:/var/log/snort:/bin/false
+suricata:x:101:101:Suricata:/var/log/suricata:/bin/false
 logwatch:x:102:102::/var/log/logwatch:/bin/false
 cron:x:104:104::/:/bin/false
 syslogd:x:105:105:/var/empty:/bin/false
index d5f525a..b2b5489 100644 (file)
@@ -5,7 +5,7 @@
 # Log anything (except mail) of level info or higher.
 # Don't log private authentication messages!
 # local0.* any dhcpcd log (even debug) in messages
-cron.none;daemon.*;local0.*;local2.*;*.info;mail.none;authpriv.*       -/var/log/messages
+cron.none;daemon.*;local0.*;local2.*;local5.*;*.info;mail.none;authpriv.*      -/var/log/messages
 
 # Log crons
 #cron.*                                                                                -/var/log/cron.log
index 2f4d96e..83ce3bc 100644 (file)
                                'title' => "Quality of Service",
                                'enabled' => 1,
                                };
-    $subservices->{'60.ids'} = {'caption' => $Lang::tr{'intrusion detection'},
-                               'enabled' => 1,
-                               'uri' => '/cgi-bin/ids.cgi',
-                               'title' => "$Lang::tr{'intrusion detection system'}",
-                               };
     $subservices->{'70.extrahd'} = {'caption' => "ExtraHD",
                                'enabled' => 1,
                                'uri' => '/cgi-bin/extrahd.cgi',
index 7271b32..77642b0 100644 (file)
                                'title' => "Universal Plug and Play",
                                'enabled' => 0,
                                };
+     $subfirewall->{'80.ids'} = {'caption' => $Lang::tr{'intrusion detection'},
+                                'uri' => '/cgi-bin/ids.cgi',
+                                'title' => "$Lang::tr{'intrusion detection system'}",
+                               'enabled' => 1,
+                                };
        $subfirewall->{'90.iptables'} = {
                                'caption' => $Lang::tr{'ipts'},
                                'uri' => '/cgi-bin/iptables.cgi',
diff --git a/config/oinkmaster/oinkmaster.conf b/config/oinkmaster/oinkmaster.conf
new file mode 100644 (file)
index 0000000..a04e329
--- /dev/null
@@ -0,0 +1,432 @@
+# $Id: oinkmaster.conf,v 1.132 2006/02/02 12:05:08 andreas_o Exp $ #
+
+# This file is pretty big by default, but don't worry. 
+# The only things required are "path" and "update_files". You must also 
+# set "url" to point to the correct rules archive for your version of 
+# Snort, unless you prefer to specify this on the command line.
+# The rest in here is just a few recommended defaults, and examples
+# how to use all the other optional features and give some ideas how they 
+# could be used.
+
+# Remember not to let untrusted users edit Oinkmaster configuration
+# files, as things like the PATH to use during execution is defined
+# in here.
+
+
+# Use "url = <url>" to specify the location of the rules archive to 
+# download. The url must begin with http://, https://, ftp://, file:// 
+# or scp:// and end with .tar.gz or .tgz, and the file must be a 
+# gzipped tarball what contains a directory named "rules".
+# You can also point to a local directory with dir://<directory>.
+# Multiple "url = <url>" lines can be specified to grab multiple rules
+# archives from different locations.
+#
+# Note: if URL is specified on the command line, it overrides all 
+#       possible URLs specified in the configuration file(s).
+#
+# The location of the official Snort rules you should use depends
+# on which Snort version you run. Basically, you should go to
+# http://www.snort.org/rules/ and follow the instructions
+# there to pick the right URL for your version of Snort
+# (and remember to update the URL when upgrading Snort in the
+# future). You can of course also specify locations to third party 
+# rules.
+#
+# As of March 2005, you must register on the Snort site to get access 
+# to the official Snort rules. This will get you an "oinkcode".
+# You then specify the URL as
+# http://www.snort.org/pub-bin/oinkmaster.cgi/<oinkcode>/<filename>
+# For example, if your code is 5a081649c06a277e1022e1284b and
+# you use Snort 2.4, the url to use would be (without the wrap):
+# http://www.snort.org/pub-bin/oinkmaster.cgi/
+# 5a081649c06a277e1022e1284bdc8fabda70e2a4/snortrules-snapshot-2.4.tar.gz
+# See the Oinkmaster FAQ Q1 and http://www.snort.org/rules/ for
+# more information.
+
+
+# URL examples follows. Replace <oinkcode> with the code you get on the 
+# Snort site in your registered user profile.
+
+# Example for Snort 2.4
+# url = http://www.snort.org/pub-bin/oinkmaster.cgi/<oinkcode>/snortrules-snapshot-2.4.tar.gz
+# url = http://www.snort.org/pub-bin/oinkmaster.cgi/<oinkcode>/snortrules-snapshot-2.4.tar.gz
+
+# Example for Snort-current ("current" means cvs snapshots).
+#url = http://www.snort.org/pub-bin/oinkmaster.cgi/<oinkcode>/snortrules-snapshot-CURRENT.tar.gz
+
+# Example for Community rules
+# url = http://www.snort.org/pub-bin/downloads.cgi/Download/comm_rules/Community-Rules.tar.gz
+
+# Example for rules from the Bleeding Snort project
+# url = http://www.bleedingsnort.com/bleeding.rules.tar.gz
+
+# If you prefer to download the rules archive from outside Oinkmaster,
+# you can then point to the file on your local filesystem by using
+# file://<filename>, for example:
+# url = file:///tmp/snortrules.tar.gz
+
+# In rare cases you may want to grab the rules directly from a
+# local directory (don't confuse this with the output directory).
+# url = dir:///etc/snort/src/rules
+
+# Example to use scp to copy the rules archive from another host.
+# Only OpenSSH is tested. See the FAQ for more information.
+# url = scp://user@somehost.example.com:/somedir/snortrules.tar.gz
+
+# If you use -u scp://... and need to specify a private ssh key (passed 
+# as -i <key> to the scp command) you can specify it here or add an 
+# entry in ~/.ssh/config for the Oinkmaster user as described in the 
+# OpenSSH manual. 
+# scp_key = /home/oinkmaster/oinkmaster_privkey
+
+
+# The PATH to use during execution. If you prefer to use external 
+# binaries (i.e. use_external_bins=1, see below), tar and gzip must be 
+# found, and also wget if downloading via ftp, http or https. All with 
+# optional .exe suffix. If you're on Cygwin, make sure that the path 
+# contains the Cygwin binaries and not the native Win32 binaries or 
+# you will get problems.
+# Assume UNIX style by default:
+path = /bin:/usr/bin:/usr/local/bin
+
+# Example if running native Win32 or standalone Cygwin:
+# path = c:\oinkmaster;c:\oinkmaster\bin
+
+# Example if running standalone Cygwin and you prefer Cygwin style path:
+# path = /cygdrive/c/oinkmaster:/cygdrive/c/oinkmaster/bin
+
+
+# We normally use external binaries (wget, tar and gzip) since they're 
+# already available on most systems and do a good job. If you have the 
+# Perl modules Archive::Tar, IO::Zlib and LWP::UserAgent, you can use
+# those instead if you like. You can set use_external_bins below to 
+# choose which method you prefer. It's set to 0 by default on Win32 
+# (i.e. use Perl modules), and 1 on other systems (i.e. use external 
+# binaries). The reason for that is that the required Perl modules
+# are included on Windows/ActivePerl 5.8.1+, so it's easier to use 
+# those than to install the ported Unix tools. (Note that if you're 
+# using scp to download the archive, external scp  binary is still 
+# used.) 
+# use_external_bins = 0
+
+
+# Temporary directory to use. This directory must exist when starting and
+# Oinkmaster will then create a temporary sub directory in here.
+# Keep it as a #comment if you want to use the default.
+# The default will be checked for in the environment variables TMP,
+# TMPDIR or TEMPDIR, or otherwise use "/tmp" if none of them was set.
+
+# Example for UNIX.
+# tmpdir = /home/oinkmaster/tmp/
+
+# Example if running native Win32 or Cygwin.
+# tmpdir = c:\tmp
+
+# Example if running Cygwin and you prefer Cygwin style path.
+# tmpdir = /cygdrive/c/tmp
+
+
+# The umask to use during execution if you want it to be something
+# else than the current value when starting Oinkmaster.
+# This will affect the mode bits when writing new files.
+# Keep it commented out to keep your system's current umask.
+# umask = 0027
+
+
+# Files in the archive(s) matching this regular expression will be 
+# checked for changes, and then updated or added if needed.
+# All other files will be ignored. You can then choose to skip
+# individual files by specifying the "skipfile" keyword below.
+# Normally you shouldn't need to change this one.
+update_files = \.rules$|\.config$|\.conf$|\.txt$|\.map$
+
+
+# Regexp of keywords that starts a Snort rule.
+# May be useful if you create your own ruletypes and want those
+# lines to be regarded as rules as well.
+# rule_actions = alert|drop|log|pass|reject|sdrop|activate|dynamic
+
+
+# If the number of rules files in the downloaded archive matching the
+# 'update_files' regexp is below min_files, or if the number
+# of rules is below min_rules, the rules are regarded as broken
+# and the update is aborted with an error message.
+# Both are set to 1 by default (i.e. the archive is only regarded as
+# broken if it's totally empty).
+# If you download from multiple URLs, the count is the total number
+# of files/rules across all archives.
+# min_files = 1
+# min_rules = 1
+
+
+# By default, a basic sanity check is performed on most paths/filenames 
+# to see if they contain illegal characters that may screw things up. 
+# If this check is too strict for your system (e.g. you get bogus 
+# "illegal characters in filename" errors because of your local language 
+# etc) and you're sure you want to disable the checks completely,
+# set use_path_checks to 0.
+# use_path_checks = 1
+
+
+# If you want Oinkmaster to send a User-Agent HTTP header string
+# other than the default one for wget/LWP, set this variable.
+# user_agent = Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
+
+
+# You can include other files anywhere in here by using
+# "include <file>". <file> will be parsed just like a regular 
+# oinkmaster.conf as soon as the include statement is seen, and then 
+# return and continue parsing the rest of the original file. If an 
+# option is redefined, it will override the previous value. You can use 
+# as many "include" statements as you wish, and also include even more 
+# 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 which defines the runmode of suricata.
+include /var/ipfire/suricata/oinkmaster-modify-sids.conf
+
+#######################################################################
+# Files to totally skip (i.e. never update or check for changes)      #
+#                                                                     #
+# Syntax: skipfile filename                                           #
+# or:     skipfile filename1, filename2, filename3, ...               #
+#######################################################################
+
+# Ignore local.rules from the rules archive by default since we might 
+# have put some local rules in our own local.rules and we don't want it 
+# to get overwritten by the empty one from the archive after each 
+# update.
+skipfile local.rules
+
+# The file deleted.rules contains rules that have been deleted from 
+# other files, so there is usually no point in updating it.
+skipfile deleted.rules
+
+# Also skip snort.conf by default since we don't want to overwrite our 
+# own snort.conf if we have it in the same directory as the rules. If 
+# you have your own production copy of snort.conf in another directory, 
+# it may be really nice to check for changes in this file though, 
+# especially since variables are sometimes added or modified and 
+# new/old files are included/excluded.
+#skipfile snort.conf
+
+# You may want to consider ignoring threshold.conf for the same reasons 
+# as for snort.conf, i.e. if you customize it locally and don't want it 
+# to become overwritten by the default one. It may be better to put 
+# local thresholding/suppressing in some local file and still update 
+# and use the official one though, in case important stuff is added to 
+# it some day. We do update it by default, but it's your call.
+# skipfile threshold.conf
+
+# If you update from multiple URLs at the same time you may need to 
+# ignore the sid-msg.map (and generate it yourself if you need one) as 
+# it's usually included in each rules tarball. See the FAQ for more info.
+# skipfile sid-msg.map
+
+
+
+##########################################################################
+# SIDs to modify after each update (only for the skilled/stupid/brave).  #
+# Don't use it unless you have to. There is nothing that stops you from  #
+# modifying rules in such ways that they become invalid or generally     #
+# break things. You have been warned.                                    #
+# If you just want to disable SIDs, please skip this section and have a  #
+# look at the "disablesid" keyword below.                                #
+#                                                                        #
+# You may specify multiple modifysid directives for the same SID (they   #
+# will be processed in order of appearance), and you may also specify a  #
+# list of SIDs on which the substitution should be applied.              #
+# If the argument is in the form something.something it's regarded       #
+# as a filename and the substitution will apply on all rules in that     #
+# file. The wildcard ("*") can be used to apply the substitution on all  #
+# rules regardless of the SID or file. Please avoid using #comments      #
+# at the end of modifysid lines, they may confuse the parser in some     #
+# situations.                                                            #
+#                                                                        #
+# Syntax:                                                                #
+#   modifysid SID "replacethis" | "withthis"                             #    
+# or:                                                                    #
+#   modifysid SID1, SID2, SID3, ... "replacethis" | "withthis"           #
+# or:                                                                    #
+#   modifysid file "replacethis" | "withthis"                            #    
+# or:                                                                    #
+#   modifysid * "replacethis" | "withthis"                               #
+#                                                                        #
+# The strings within the quotes will basically be passed to a            #
+# s/replacethis/withthis/ statement in Perl, so they must be valid       #
+# regular expressions. The strings are case-insensitive and only the     #
+# first occurrence will be replaced. If there are multiple occurrences   #
+# you want to replace, simply repeat the same modifysid line.            #
+# As the strings are regular expressions, you MUST escape special        #
+# characters like $ \ / ( ) | by prepending a "\" to them.               #
+#                                                                        #
+# If you specify a modifysid statement for a multi-line rule, Oinkmaster #
+# will first translate the rule into a single-line version and then      #
+# perform the substitution, so you don't have to care about the trailing #
+# backslashes and newlines.                                              #
+#                                                                        #
+# If you use backreference variables in the substitution expression,     #
+# it's strongly recommended to specify them as ${1} instead of $1 and so #
+# on, to avoid parsing confusion with unexpected results in some         #
+# situations. Note that modifysid statements will process both active    #
+# and inactive (disabled) rules.                                         #
+#                                                                        #
+# You may want to check out README.templates and template-examples.conf  #
+# to find how you can simplify the modifysid usage by using templates.   #
+##########################################################################
+
+# Example to enable a rule (in this case SID 1325) that is disabled by
+# default, by simply replacing leading "#alert" with "alert".
+# (You should really use 'enablesid' for this though.)
+# Oinkmaster removes whitespaces next to the leading "#" so you don't
+# have to worry about that, but be careful about possible whitespace in
+# other places when writing the regexps.
+# modifysid 1325 "^#alert" | "alert"
+
+# You could also do this to enable it no matter what type of rule it is
+# (alert, log, pass, etc).
+# modifysid 1325 "^#" | ""
+
+# Example to add "tag" stuff to SID 1325.
+# modifysid 1325 "sid:1325;" | "sid:1325; tag: host, src, 300, seconds;"
+
+# Example to make SID 1378 a 'drop' rule (valid if you're running 
+# Snort_inline).
+# modifysid 1378 "^alert" | "drop"
+
+# Example to replace first occurrence of $EXTERNAL_NET with $HOME_NET 
+# in SID 302.
+# modifysid 302 "\$EXTERNAL_NET" | "\$HOME_NET"
+
+# You can also specify that a substitution should apply on multiple SIDs.
+# modifysid 302,429,1821 "\$EXTERNAL_NET" | "\$HOME_NET"
+
+# You can take advantage of the fact that it's regular expressions and
+# do more complex stuff. This example (for Snort_inline) adds a 'replace'
+# statement to SID 1324 that replaces "/bin/sh" with "/foo/sh".
+# modifysid 1324 "(content\s*:\s*"\/bin\/sh"\s*;)" | \
+#                "${1} replace:"\/foo\/sh";"
+
+# If you for some reason would like to add a comment inside the actual 
+# rules file, like the reason why you disabled this rule, you can do 
+# like this (you would normally add such comments in oinkmaster.conf 
+# though).
+# modifysid 1324 "(.+)" | "# 20020101: disabled this rule just for fun:\n#${1}"
+
+# Here is an example that is actually useful. Let's say you don't care 
+# about incoming welchia pings (detected by SID 483 at the time of 
+# writing) but you want to know when infected hosts on your network 
+# scans hosts on the outside. (Remember that watching for outgoing 
+# malicious packets is often just as important as watching for incoming 
+# ones, especially in this case.) The rule currently looks like
+# "alert icmp $EXTERNAL_NET any -> $HOME_NET any ..."
+# but we want to switch that so it becomes
+# "alert icmp $HOME_NET any -> $EXTERNAL_NET any ...".
+# Here is how it could be done.
+# modifysid 483 \
+# "(.+) \$EXTERNAL_NET (.+) \$HOME_NET (.+)" | \
+# "${1} \$HOME_NET ${2} \$EXTERNAL_NET ${3}"
+
+# The wildcard (modifysid * ...) can be used to do all kinds of 
+# interesting things. The substitution expression will be applied on all 
+# matching rules. First, a silly example to replace "foo" with "bar" in 
+# all rules (that have the string "foo" in them, that is.) 
+# modifysid * "foo" | "bar"
+
+# If you for some reason don't want to use the stream preprocessor to 
+# match established streams, you may want to replace the 'flow' 
+# statement with 'flags:A+;' in all those rules.
+# modifysid * "flow:[a-z,_ ]+;" | "flags:A+;"
+
+# Example to convert all rules of classtype attempted-admin to 'drop' 
+# rules (for Snort_inline only, obviously).
+# modifysid * "^alert (.*classtype\s*:\s*attempted-admin)" | "drop ${1}"
+
+# This one will append some text to the 'msg' string for all rules that 
+# have the 'tag' keyword in them.
+# modifysid * "(.*msg:\s*".+?)"(\s*;.+;\s*tag:.*)" | \
+#             "${1}, going to tag this baby"${2}"
+
+# There may be times when you want to replace multiple occurrences of a 
+# certain keyword/string in a rule and not just the first one. To 
+# replace the first two occurrences of "foo" with "bar" in SID 100, 
+# simply repeat the modifysid statement:
+# modifysid 100 "foo" | "bar"
+# modifysid 100 "foo" | "bar"
+# Or you can even specify a SID list but repeat the same SID as many 
+# times as required, like:
+# modifysid 100,100,100 "foo" | "bar"
+
+# Enable all rules in the file exploit.rules.
+# modifysid exploit.rules "^#" | ""
+
+# Enable all rules in exploit.rules, icmp-info.rules and also SID 1171.
+# modifysid exploit.rules, snmp.rules, 1171 "^#" | ""
+
+
+
+########################################################################
+# SIDs that we don't want to update.                                   #
+# If you for some reason don't want a specific rule to be updated      #
+# (e.g. you made local modifications to it and you never want to       #
+# update it and don't care about changes in the official version), you #
+# can specify a "localsid" statement for it. This means that the old   #
+# version of the rule (i.e. the one in the rules file on your          #
+# harddrive) is always kept, regardless if the official version has    #
+# been updated. Please do not use this feature unless in special       #
+# cases as it's easy to end up with many signatures that aren't        #
+# maintained anymore. See the FAQ for details about this and hints     #
+# about better solutions regarding customization of rules.             #
+#                                                                      #
+# Syntax:  localsid SID                                                #
+# or:      localsid SID1, SID2, SID3, ...                              #
+########################################################################
+
+# Example to never update SID 1325.
+# localsid 1325
+
+
+
+########################################################################
+# SIDs to enable after each update.                                    #
+# Will simply remove all the leading '#' for a specified SID (if it's  #
+# a multi-line rule, the leading '#' for all lines are removed.)       #
+# These will be processed after all the modifysid and disablesid       #
+# statements. Using 'enablesid' on a rule that is not disabled is a    #
+# NOOP.                                                                #
+#                                                                      #
+# Syntax:  enablesid SID                                               #
+# or:      enablesid SID1, SID2, SID3, ...                             #
+########################################################################
+
+# Example to enable SID 1325.
+# enablesid 1325
+
+
+
+########################################################################
+# SIDs to comment out, i.e. disable, after each update by placing a    #
+# '#' in front of the rule (if it's a multi-line rule, it will be put  #
+# in front of all lines).                                              #
+#                                                                      #
+# Syntax:  disablesid SID                                              #
+# or:      disablesid SID1, SID2, SID3, ...                            #
+########################################################################
+
+# You can specify one SID per line.
+# disablesid 1
+# disablesid 2
+# disablesid 3
+
+# And also as comma-separated lists.
+# disablesid 4,5,6
+
+# It's a good idea to also add comment about why you disable the sid:
+# disablesid 1324    # 20020101: disabled this SID just because I can
index 367a0a7..ed4f727 100644 (file)
@@ -53,7 +53,7 @@ etc/rc.d/init.d/networking/red.up/10-miniupnpd
 etc/rc.d/init.d/networking/red.up/10-multicast
 etc/rc.d/init.d/networking/red.up/10-static-routes
 etc/rc.d/init.d/networking/red.up/20-firewall
-etc/rc.d/init.d/networking/red.up/23-RS-snort
+etc/rc.d/init.d/networking/red.up/23-suricata
 etc/rc.d/init.d/networking/red.up/24-RS-qos
 etc/rc.d/init.d/networking/red.up/27-RS-squid
 etc/rc.d/init.d/networking/red.up/30-ddns
@@ -75,10 +75,10 @@ etc/rc.d/init.d/rngd
 etc/rc.d/init.d/sendsignals
 etc/rc.d/init.d/setclock
 etc/rc.d/init.d/smartenabler
-etc/rc.d/init.d/snort
 etc/rc.d/init.d/squid
 etc/rc.d/init.d/sshd
 etc/rc.d/init.d/static-routes
+etc/rc.d/init.d/suricata
 etc/rc.d/init.d/swap
 etc/rc.d/init.d/swconfig
 etc/rc.d/init.d/sysctl
@@ -105,7 +105,7 @@ etc/rc.d/rc0.d/K47setclock
 etc/rc.d/rc0.d/K49cyrus-sasl
 etc/rc.d/rc0.d/K51vnstat
 etc/rc.d/rc0.d/K77conntrackd
-etc/rc.d/rc0.d/K78snort
+etc/rc.d/rc0.d/K78suricata
 etc/rc.d/rc0.d/K79leds
 etc/rc.d/rc0.d/K79unbound
 etc/rc.d/rc0.d/K80network
@@ -158,7 +158,7 @@ etc/rc.d/rc6.d/K47setclock
 etc/rc.d/rc6.d/K49cyrus-sasl
 etc/rc.d/rc6.d/K51vnstat
 etc/rc.d/rc6.d/K77conntrackd
-etc/rc.d/rc6.d/K78snort
+etc/rc.d/rc6.d/K78suricata
 etc/rc.d/rc6.d/K79leds
 etc/rc.d/rc6.d/K79unbound
 etc/rc.d/rc6.d/K80network
index c6d19a5..576d3f7 100644 (file)
@@ -104,6 +104,7 @@ usr/local/bin/scanhd
 usr/local/bin/settime
 usr/local/bin/timecheck
 usr/local/bin/timezone-transition
+usr/local/bin/update-ids-ruleset
 usr/local/bin/update-lang-cache
 usr/local/bin/xt_geoip_build
 usr/local/bin/xt_geoip_update
index 367a0a7..ed4f727 100644 (file)
@@ -53,7 +53,7 @@ etc/rc.d/init.d/networking/red.up/10-miniupnpd
 etc/rc.d/init.d/networking/red.up/10-multicast
 etc/rc.d/init.d/networking/red.up/10-static-routes
 etc/rc.d/init.d/networking/red.up/20-firewall
-etc/rc.d/init.d/networking/red.up/23-RS-snort
+etc/rc.d/init.d/networking/red.up/23-suricata
 etc/rc.d/init.d/networking/red.up/24-RS-qos
 etc/rc.d/init.d/networking/red.up/27-RS-squid
 etc/rc.d/init.d/networking/red.up/30-ddns
@@ -75,10 +75,10 @@ etc/rc.d/init.d/rngd
 etc/rc.d/init.d/sendsignals
 etc/rc.d/init.d/setclock
 etc/rc.d/init.d/smartenabler
-etc/rc.d/init.d/snort
 etc/rc.d/init.d/squid
 etc/rc.d/init.d/sshd
 etc/rc.d/init.d/static-routes
+etc/rc.d/init.d/suricata
 etc/rc.d/init.d/swap
 etc/rc.d/init.d/swconfig
 etc/rc.d/init.d/sysctl
@@ -105,7 +105,7 @@ etc/rc.d/rc0.d/K47setclock
 etc/rc.d/rc0.d/K49cyrus-sasl
 etc/rc.d/rc0.d/K51vnstat
 etc/rc.d/rc0.d/K77conntrackd
-etc/rc.d/rc0.d/K78snort
+etc/rc.d/rc0.d/K78suricata
 etc/rc.d/rc0.d/K79leds
 etc/rc.d/rc0.d/K79unbound
 etc/rc.d/rc0.d/K80network
@@ -158,7 +158,7 @@ etc/rc.d/rc6.d/K47setclock
 etc/rc.d/rc6.d/K49cyrus-sasl
 etc/rc.d/rc6.d/K51vnstat
 etc/rc.d/rc6.d/K77conntrackd
-etc/rc.d/rc6.d/K78snort
+etc/rc.d/rc6.d/K78suricata
 etc/rc.d/rc6.d/K79leds
 etc/rc.d/rc6.d/K79unbound
 etc/rc.d/rc6.d/K80network
index fa18a05..4c9f6fb 100644 (file)
@@ -1,6 +1,7 @@
 usr/sbin/convert-dmz
 usr/sbin/convert-outgoingfw
 usr/sbin/convert-portfw
+usr/sbin/convert-snort
 usr/sbin/convert-xtaccess
 usr/sbin/firewall-policy
 #var/ipfire
@@ -78,6 +79,7 @@ var/ipfire/general-functions.pl
 var/ipfire/geoip-functions.pl
 var/ipfire/graphs.pl
 var/ipfire/header.pl
+var/ipfire/ids-functions.pl
 var/ipfire/isdn
 #var/ipfire/isdn/settings
 var/ipfire/key
@@ -173,8 +175,8 @@ var/ipfire/remote
 #var/ipfire/remote/settings
 var/ipfire/sensors
 #var/ipfire/sensors/settings
-var/ipfire/snort
-#var/ipfire/snort/settings
+var/ipfire/suricata
+#var/ipfire/suricata/settings
 var/ipfire/time
 #var/ipfire/time/settings
 var/ipfire/updatexlrator
diff --git a/config/rootfiles/common/daq b/config/rootfiles/common/daq
deleted file mode 100644 (file)
index 6c156e3..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#usr/bin/daq-modules-config
-#usr/include/daq.h
-#usr/include/daq_api.h
-#usr/include/daq_common.h
-#usr/include/sfbpf.h
-#usr/include/sfbpf_dlt.h
-usr/lib/daq
-#usr/lib/daq/daq_afpacket.la
-#usr/lib/daq/daq_afpacket.so
-#usr/lib/daq/daq_dump.la
-#usr/lib/daq/daq_dump.so
-#usr/lib/daq/daq_ipfw.la
-#usr/lib/daq/daq_ipfw.so
-#usr/lib/daq/daq_ipq.la
-#usr/lib/daq/daq_ipq.so
-#usr/lib/daq/daq_nfq.la
-#usr/lib/daq/daq_nfq.so
-#usr/lib/daq/daq_pcap.la
-#usr/lib/daq/daq_pcap.so
-#usr/lib/libdaq.a
-#usr/lib/libdaq.la
-#usr/lib/libdaq.so
-usr/lib/libdaq.so.2
-usr/lib/libdaq.so.2.0.4
-#usr/lib/libdaq_static.a
-#usr/lib/libdaq_static.la
-#usr/lib/libdaq_static_modules.a
-#usr/lib/libdaq_static_modules.la
-#usr/lib/libsfbpf.a
-#usr/lib/libsfbpf.la
-#usr/lib/libsfbpf.so
-usr/lib/libsfbpf.so.0
-usr/lib/libsfbpf.so.0.0.1
index 6f9868e..07a123a 100644 (file)
@@ -53,7 +53,7 @@ etc/rc.d/init.d/networking/red.up/10-miniupnpd
 etc/rc.d/init.d/networking/red.up/10-multicast
 etc/rc.d/init.d/networking/red.up/10-static-routes
 etc/rc.d/init.d/networking/red.up/20-firewall
-etc/rc.d/init.d/networking/red.up/23-RS-snort
+etc/rc.d/init.d/networking/red.up/23-suricata
 etc/rc.d/init.d/networking/red.up/24-RS-qos
 etc/rc.d/init.d/networking/red.up/27-RS-squid
 etc/rc.d/init.d/networking/red.up/30-ddns
@@ -75,10 +75,10 @@ etc/rc.d/init.d/rngd
 etc/rc.d/init.d/sendsignals
 etc/rc.d/init.d/setclock
 etc/rc.d/init.d/smartenabler
-etc/rc.d/init.d/snort
 etc/rc.d/init.d/squid
 etc/rc.d/init.d/sshd
 etc/rc.d/init.d/static-routes
+etc/rc.d/init.d/suricata
 etc/rc.d/init.d/swap
 etc/rc.d/init.d/sysctl
 etc/rc.d/init.d/sysklogd
@@ -104,7 +104,7 @@ etc/rc.d/rc0.d/K47setclock
 etc/rc.d/rc0.d/K49cyrus-sasl
 etc/rc.d/rc0.d/K51vnstat
 etc/rc.d/rc0.d/K77conntrackd
-etc/rc.d/rc0.d/K78snort
+etc/rc.d/rc0.d/K78suricata
 etc/rc.d/rc0.d/K79leds
 etc/rc.d/rc0.d/K79unbound
 etc/rc.d/rc0.d/K80network
@@ -157,7 +157,7 @@ etc/rc.d/rc6.d/K47setclock
 etc/rc.d/rc6.d/K49cyrus-sasl
 etc/rc.d/rc6.d/K51vnstat
 etc/rc.d/rc6.d/K77conntrackd
-etc/rc.d/rc6.d/K78snort
+etc/rc.d/rc6.d/K78suricata
 etc/rc.d/rc6.d/K79leds
 etc/rc.d/rc6.d/K79unbound
 etc/rc.d/rc6.d/K80network
diff --git a/config/rootfiles/common/ids-ruleset-sources b/config/rootfiles/common/ids-ruleset-sources
new file mode 100644 (file)
index 0000000..698fd12
--- /dev/null
@@ -0,0 +1 @@
+var/ipfire/suricata/ruleset-sources
diff --git a/config/rootfiles/common/libcap-ng b/config/rootfiles/common/libcap-ng
new file mode 100644 (file)
index 0000000..9c0b5e1
--- /dev/null
@@ -0,0 +1,44 @@
+#usr/bin/captest
+#usr/bin/filecap
+#usr/bin/netcap
+#usr/bin/pscap
+#usr/include/cap-ng.h
+#usr/lib/libcap-ng.la
+#usr/lib/libcap-ng.so
+usr/lib/libcap-ng.so.0
+usr/lib/libcap-ng.so.0.0.0
+#usr/lib/pkgconfig/libcap-ng.pc
+#usr/lib/python2.7/site-packages/_capng.la
+#usr/lib/python2.7/site-packages/_capng.so
+#usr/lib/python2.7/site-packages/capng.py
+#usr/lib/python2.7/site-packages/capng.pyc
+#usr/lib/python2.7/site-packages/capng.pyo
+#usr/lib/python3.6/site-packages/__pycache__/capng.cpython-36.opt-1.pyc
+#usr/lib/python3.6/site-packages/__pycache__/capng.cpython-36.pyc
+#usr/lib/python3.6/site-packages/_capng.la
+#usr/lib/python3.6/site-packages/_capng.so
+#usr/lib/python3.6/site-packages/capng.py
+#usr/share/aclocal/cap-ng.m4
+#usr/share/man/man3/capng_apply.3
+#usr/share/man/man3/capng_capability_to_name.3
+#usr/share/man/man3/capng_change_id.3
+#usr/share/man/man3/capng_clear.3
+#usr/share/man/man3/capng_fill.3
+#usr/share/man/man3/capng_get_caps_fd.3
+#usr/share/man/man3/capng_get_caps_process.3
+#usr/share/man/man3/capng_have_capabilities.3
+#usr/share/man/man3/capng_have_capability.3
+#usr/share/man/man3/capng_lock.3
+#usr/share/man/man3/capng_name_to_capability.3
+#usr/share/man/man3/capng_print_caps_numeric.3
+#usr/share/man/man3/capng_print_caps_text.3
+#usr/share/man/man3/capng_restore_state.3
+#usr/share/man/man3/capng_save_state.3
+#usr/share/man/man3/capng_set_caps_fd.3
+#usr/share/man/man3/capng_setpid.3
+#usr/share/man/man3/capng_update.3
+#usr/share/man/man3/capng_updatev.3
+#usr/share/man/man8/captest.8
+#usr/share/man/man8/filecap.8
+#usr/share/man/man8/netcap.8
+#usr/share/man/man8/pscap.8
diff --git a/config/rootfiles/common/libhtp b/config/rootfiles/common/libhtp
new file mode 100644 (file)
index 0000000..9211ea7
--- /dev/null
@@ -0,0 +1,22 @@
+#usr/include/htp
+#usr/include/htp/bstr.h
+#usr/include/htp/bstr_builder.h
+#usr/include/htp/htp.h
+#usr/include/htp/htp_base64.h
+#usr/include/htp/htp_config.h
+#usr/include/htp/htp_connection_parser.h
+#usr/include/htp/htp_core.h
+#usr/include/htp/htp_decompressors.h
+#usr/include/htp/htp_hooks.h
+#usr/include/htp/htp_list.h
+#usr/include/htp/htp_multipart.h
+#usr/include/htp/htp_table.h
+#usr/include/htp/htp_transaction.h
+#usr/include/htp/htp_urlencoded.h
+#usr/include/htp/htp_utf8_decoder.h
+#usr/include/htp/htp_version.h
+#usr/lib/libhtp.la
+#usr/lib/libhtp.so
+usr/lib/libhtp.so.2
+usr/lib/libhtp.so.2.0.0
+#usr/lib/pkgconfig/htp.pc
index 7891795..c48a474 100644 (file)
@@ -26,8 +26,8 @@ usr/local/bin/redctrl
 #usr/local/bin/sambactrl
 usr/local/bin/setaliases
 usr/local/bin/smartctrl
-usr/local/bin/snortctrl
 usr/local/bin/squidctrl
+usr/local/bin/suricatactrl
 usr/local/bin/sshctrl
 usr/local/bin/syslogdctrl
 usr/local/bin/timectrl
index be14b54..2557353 100644 (file)
@@ -1,2 +1,2 @@
 usr/local/bin/oinkmaster.pl
-var/ipfire/snort/oinkmaster.conf
+var/ipfire/suricata/oinkmaster.conf
diff --git a/config/rootfiles/common/snort b/config/rootfiles/common/snort
deleted file mode 100644 (file)
index c83b156..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-#etc/snort
-etc/snort/rules
-#etc/snort/rules/classification.config
-#etc/snort/rules/reference.config
-etc/snort/snort.conf
-etc/snort/snort.conf.template
-etc/snort/unicode.map
-usr/bin/u2boat
-usr/bin/u2spewfoo
-#usr/include/snort
-#usr/include/snort/dynamic_output
-#usr/include/snort/dynamic_output/bitop.h
-#usr/include/snort/dynamic_output/ipv6_port.h
-#usr/include/snort/dynamic_output/obfuscation.h
-#usr/include/snort/dynamic_output/output_api.h
-#usr/include/snort/dynamic_output/output_common.h
-#usr/include/snort/dynamic_output/output_lib.h
-#usr/include/snort/dynamic_output/preprocids.h
-#usr/include/snort/dynamic_output/sfPolicy.h
-#usr/include/snort/dynamic_output/sf_dynamic_common.h
-#usr/include/snort/dynamic_output/sf_ip.h
-#usr/include/snort/dynamic_output/sf_protocols.h
-#usr/include/snort/dynamic_output/sf_snort_packet.h
-#usr/include/snort/dynamic_output/sfrt.h
-#usr/include/snort/dynamic_output/sfrt_dir.h
-#usr/include/snort/dynamic_output/sfrt_trie.h
-#usr/include/snort/dynamic_output/snort_debug.h
-#usr/include/snort/dynamic_output/stream_api.h
-#usr/include/snort/dynamic_preproc
-#usr/include/snort/dynamic_preproc/appdata_adjuster.h
-#usr/include/snort/dynamic_preproc/bitop.h
-#usr/include/snort/dynamic_preproc/cpuclock.h
-#usr/include/snort/dynamic_preproc/file_api.h
-#usr/include/snort/dynamic_preproc/idle_processing.h
-#usr/include/snort/dynamic_preproc/ipv6_port.h
-#usr/include/snort/dynamic_preproc/mempool.h
-#usr/include/snort/dynamic_preproc/mpse_methods.h
-#usr/include/snort/dynamic_preproc/obfuscation.h
-#usr/include/snort/dynamic_preproc/packet_time.h
-#usr/include/snort/dynamic_preproc/perf_indicators.h
-#usr/include/snort/dynamic_preproc/preprocids.h
-#usr/include/snort/dynamic_preproc/profiler.h
-#usr/include/snort/dynamic_preproc/reg_test.h
-#usr/include/snort/dynamic_preproc/reload_api.h
-#usr/include/snort/dynamic_preproc/segment_mem.h
-#usr/include/snort/dynamic_preproc/session_api.h
-#usr/include/snort/dynamic_preproc/sfPolicy.h
-#usr/include/snort/dynamic_preproc/sfPolicyUserData.h
-#usr/include/snort/dynamic_preproc/sf_decompression.h
-#usr/include/snort/dynamic_preproc/sf_dynamic_common.h
-#usr/include/snort/dynamic_preproc/sf_dynamic_define.h
-#usr/include/snort/dynamic_preproc/sf_dynamic_engine.h
-#usr/include/snort/dynamic_preproc/sf_dynamic_meta.h
-#usr/include/snort/dynamic_preproc/sf_dynamic_preproc_lib.h
-#usr/include/snort/dynamic_preproc/sf_dynamic_preprocessor.h
-#usr/include/snort/dynamic_preproc/sf_ip.h
-#usr/include/snort/dynamic_preproc/sf_preproc_info.h
-#usr/include/snort/dynamic_preproc/sf_protocols.h
-#usr/include/snort/dynamic_preproc/sf_sdlist_types.h
-#usr/include/snort/dynamic_preproc/sf_seqnums.h
-#usr/include/snort/dynamic_preproc/sf_snort_packet.h
-#usr/include/snort/dynamic_preproc/sf_snort_plugin_api.h
-#usr/include/snort/dynamic_preproc/sfcommon.h
-#usr/include/snort/dynamic_preproc/sfcontrol.h
-#usr/include/snort/dynamic_preproc/sfrt.h
-#usr/include/snort/dynamic_preproc/sfrt_dir.h
-#usr/include/snort/dynamic_preproc/sfrt_flat.h
-#usr/include/snort/dynamic_preproc/sfrt_flat_dir.h
-#usr/include/snort/dynamic_preproc/sfrt_trie.h
-#usr/include/snort/dynamic_preproc/sidechannel_define.h
-#usr/include/snort/dynamic_preproc/snort_bounds.h
-#usr/include/snort/dynamic_preproc/snort_debug.h
-#usr/include/snort/dynamic_preproc/ssl.h
-#usr/include/snort/dynamic_preproc/ssl_config.h
-#usr/include/snort/dynamic_preproc/ssl_ha.h
-#usr/include/snort/dynamic_preproc/ssl_include.h
-#usr/include/snort/dynamic_preproc/ssl_inspect.h
-#usr/include/snort/dynamic_preproc/ssl_session.h
-#usr/include/snort/dynamic_preproc/str_search.h
-#usr/include/snort/dynamic_preproc/stream_api.h
-#usr/lib/pkgconfig/snort.pc
-#usr/lib/pkgconfig/snort_output.pc
-#usr/lib/pkgconfig/snort_preproc.pc
-#usr/lib/snort
-usr/lib/snort/dynamic_output
-#usr/lib/snort/dynamic_output/libsf_dynamic_output.a
-#usr/lib/snort/dynamic_output/libsf_dynamic_output.la
-usr/lib/snort/dynamic_preproc
-#usr/lib/snort/dynamic_preproc/libsf_dynamic_preproc.a
-#usr/lib/snort/dynamic_preproc/libsf_dynamic_preproc.la
-#usr/lib/snort/dynamic_preproc/libsf_dynamic_utils.a
-#usr/lib/snort/dynamic_preproc/libsf_dynamic_utils.la
-usr/lib/snort_dynamicengine
-#usr/lib/snort_dynamicengine/libsf_engine.a
-#usr/lib/snort_dynamicengine/libsf_engine.la
-#usr/lib/snort_dynamicengine/libsf_engine.so
-#usr/lib/snort_dynamicengine/libsf_engine.so.0
-#usr/lib/snort_dynamicengine/libsf_engine.so.0.0.0
-usr/lib/snort_dynamicpreprocessor
-#usr/lib/snort_dynamicpreprocessor/libsf_dce2_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_dce2_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_dce2_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_dce2_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_dce2_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_dnp3_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_dnp3_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_dnp3_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_dnp3_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_dnp3_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_dns_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_dns_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_dns_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_dns_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_dns_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_ftptelnet_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_ftptelnet_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_ftptelnet_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_ftptelnet_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_ftptelnet_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_gtp_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_gtp_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_gtp_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_gtp_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_gtp_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_imap_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_imap_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_imap_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_imap_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_imap_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_modbus_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_modbus_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_modbus_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_modbus_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_modbus_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_pop_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_pop_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_pop_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_pop_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_pop_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_reputation_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_reputation_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_reputation_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_reputation_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_reputation_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_sdf_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_sdf_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_sdf_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_sdf_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_sdf_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_sip_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_sip_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_sip_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_sip_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_sip_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_smtp_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_smtp_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_smtp_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_smtp_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_smtp_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_ssh_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_ssh_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_ssh_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_ssh_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_ssh_preproc.so.0.0.0
-#usr/lib/snort_dynamicpreprocessor/libsf_ssl_preproc.a
-#usr/lib/snort_dynamicpreprocessor/libsf_ssl_preproc.la
-#usr/lib/snort_dynamicpreprocessor/libsf_ssl_preproc.so
-#usr/lib/snort_dynamicpreprocessor/libsf_ssl_preproc.so.0
-#usr/lib/snort_dynamicpreprocessor/libsf_ssl_preproc.so.0.0.0
-usr/sbin/snort
-#usr/share/doc/snort
-#usr/share/doc/snort/AUTHORS
-#usr/share/doc/snort/BUGS
-#usr/share/doc/snort/CREDITS
-#usr/share/doc/snort/INSTALL
-#usr/share/doc/snort/NEWS
-#usr/share/doc/snort/OpenDetectorDeveloperGuide.pdf
-#usr/share/doc/snort/PROBLEMS
-#usr/share/doc/snort/README
-#usr/share/doc/snort/README.GTP
-#usr/share/doc/snort/README.PLUGINS
-#usr/share/doc/snort/README.PerfProfiling
-#usr/share/doc/snort/README.SMTP
-#usr/share/doc/snort/README.UNSOCK
-#usr/share/doc/snort/README.WIN32
-#usr/share/doc/snort/README.active
-#usr/share/doc/snort/README.alert_order
-#usr/share/doc/snort/README.appid
-#usr/share/doc/snort/README.asn1
-#usr/share/doc/snort/README.counts
-#usr/share/doc/snort/README.csv
-#usr/share/doc/snort/README.daq
-#usr/share/doc/snort/README.dcerpc2
-#usr/share/doc/snort/README.decode
-#usr/share/doc/snort/README.decoder_preproc_rules
-#usr/share/doc/snort/README.dnp3
-#usr/share/doc/snort/README.dns
-#usr/share/doc/snort/README.event_queue
-#usr/share/doc/snort/README.file
-#usr/share/doc/snort/README.file_ips
-#usr/share/doc/snort/README.filters
-#usr/share/doc/snort/README.flowbits
-#usr/share/doc/snort/README.frag3
-#usr/share/doc/snort/README.ftptelnet
-#usr/share/doc/snort/README.gre
-#usr/share/doc/snort/README.ha
-#usr/share/doc/snort/README.http_inspect
-#usr/share/doc/snort/README.imap
-#usr/share/doc/snort/README.ipip
-#usr/share/doc/snort/README.ipv6
-#usr/share/doc/snort/README.modbus
-#usr/share/doc/snort/README.multipleconfigs
-#usr/share/doc/snort/README.normalize
-#usr/share/doc/snort/README.pcap_readmode
-#usr/share/doc/snort/README.pop
-#usr/share/doc/snort/README.ppm
-#usr/share/doc/snort/README.reload
-#usr/share/doc/snort/README.reputation
-#usr/share/doc/snort/README.sensitive_data
-#usr/share/doc/snort/README.sfportscan
-#usr/share/doc/snort/README.sip
-#usr/share/doc/snort/README.ssh
-#usr/share/doc/snort/README.ssl
-#usr/share/doc/snort/README.stream5
-#usr/share/doc/snort/README.tag
-#usr/share/doc/snort/README.thresholding
-#usr/share/doc/snort/README.u2boat
-#usr/share/doc/snort/README.unified2
-#usr/share/doc/snort/README.variables
-#usr/share/doc/snort/TODO
-#usr/share/doc/snort/USAGE
-#usr/share/doc/snort/WISHLIST
-#usr/share/doc/snort/generators
-#usr/share/man/man8/snort.8
-var/log/snort
index ea941cd..5999609 100644 (file)
@@ -103,6 +103,7 @@ usr/local/bin/settime
 usr/local/bin/timecheck
 usr/local/bin/timezone-transition
 usr/local/bin/update-lang-cache
+usr/local/bin/update-ids-ruleset
 usr/local/bin/xt_geoip_build
 usr/local/bin/xt_geoip_update
 #usr/local/include
diff --git a/config/rootfiles/common/suricata b/config/rootfiles/common/suricata
new file mode 100644 (file)
index 0000000..ac48dbc
--- /dev/null
@@ -0,0 +1,23 @@
+etc/suricata
+etc/suricata/suricata.yaml
+usr/bin/suricata
+#usr/share/doc/suricata
+#usr/share/doc/suricata/AUTHORS
+#usr/share/doc/suricata/Basic_Setup.txt
+#usr/share/doc/suricata/GITGUIDE
+#usr/share/doc/suricata/INSTALL
+#usr/share/doc/suricata/INSTALL.PF_RING
+#usr/share/doc/suricata/INSTALL.WINDOWS
+#usr/share/doc/suricata/NEWS
+#usr/share/doc/suricata/README
+#usr/share/doc/suricata/Setting_up_IPSinline_for_Linux.txt
+#usr/share/doc/suricata/TODO
+#usr/share/doc/suricata/Third_Party_Installation_Guides.txt
+#usr/share/man/man1/suricata.1
+var/lib/suricata
+var/lib/suricata/classification.config
+var/lib/suricata/reference.config
+var/lib/suricata/threshold.config
+var/log/suricata
+#var/log/suricata/certs
+#var/log/suricata/files
index 6f9868e..07a123a 100644 (file)
@@ -53,7 +53,7 @@ etc/rc.d/init.d/networking/red.up/10-miniupnpd
 etc/rc.d/init.d/networking/red.up/10-multicast
 etc/rc.d/init.d/networking/red.up/10-static-routes
 etc/rc.d/init.d/networking/red.up/20-firewall
-etc/rc.d/init.d/networking/red.up/23-RS-snort
+etc/rc.d/init.d/networking/red.up/23-suricata
 etc/rc.d/init.d/networking/red.up/24-RS-qos
 etc/rc.d/init.d/networking/red.up/27-RS-squid
 etc/rc.d/init.d/networking/red.up/30-ddns
@@ -75,10 +75,10 @@ etc/rc.d/init.d/rngd
 etc/rc.d/init.d/sendsignals
 etc/rc.d/init.d/setclock
 etc/rc.d/init.d/smartenabler
-etc/rc.d/init.d/snort
 etc/rc.d/init.d/squid
 etc/rc.d/init.d/sshd
 etc/rc.d/init.d/static-routes
+etc/rc.d/init.d/suricata
 etc/rc.d/init.d/swap
 etc/rc.d/init.d/sysctl
 etc/rc.d/init.d/sysklogd
@@ -104,7 +104,7 @@ etc/rc.d/rc0.d/K47setclock
 etc/rc.d/rc0.d/K49cyrus-sasl
 etc/rc.d/rc0.d/K51vnstat
 etc/rc.d/rc0.d/K77conntrackd
-etc/rc.d/rc0.d/K78snort
+etc/rc.d/rc0.d/K78suricata
 etc/rc.d/rc0.d/K79leds
 etc/rc.d/rc0.d/K79unbound
 etc/rc.d/rc0.d/K80network
@@ -157,7 +157,7 @@ etc/rc.d/rc6.d/K47setclock
 etc/rc.d/rc6.d/K49cyrus-sasl
 etc/rc.d/rc6.d/K51vnstat
 etc/rc.d/rc6.d/K77conntrackd
-etc/rc.d/rc6.d/K78snort
+etc/rc.d/rc6.d/K78suricata
 etc/rc.d/rc6.d/K79leds
 etc/rc.d/rc6.d/K79unbound
 etc/rc.d/rc6.d/K80network
index c6d19a5..576d3f7 100644 (file)
@@ -104,6 +104,7 @@ usr/local/bin/scanhd
 usr/local/bin/settime
 usr/local/bin/timecheck
 usr/local/bin/timezone-transition
+usr/local/bin/update-ids-ruleset
 usr/local/bin/update-lang-cache
 usr/local/bin/xt_geoip_build
 usr/local/bin/xt_geoip_update
diff --git a/config/rootfiles/common/yaml b/config/rootfiles/common/yaml
new file mode 100644 (file)
index 0000000..565fa37
--- /dev/null
@@ -0,0 +1,6 @@
+#usr/include/yaml.h
+usr/lib/libyaml-0.so.2
+usr/lib/libyaml-0.so.2.0.5
+#usr/lib/libyaml.la
+#usr/lib/libyaml.so
+#usr/lib/pkgconfig/yaml-0.1.pc
diff --git a/config/snort/snort.conf b/config/snort/snort.conf
deleted file mode 100644 (file)
index 950ae3e..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-###################################################
-# IPFire snort.conf 
-#
-# some parts of this file are changed/updated by the webif
-###################################################
-# VERSIONS : 2.9.5.0
-
-include /etc/snort/vars
-
-###################################################
-# Step #1: Set the network variables.  For more information, see README.variables
-###################################################
-
-# taken from /etc/snort vars
-#ipvar HOME_NET any
-
-# Set up the external network addresses. Leave as "any" in most situations
-ipvar EXTERNAL_NET any
-
-# List of DNS servers on your network 
-#ipvar DNS_SERVERS $HOME_NET
-
-# List of SMTP servers on your network
-ipvar SMTP_SERVERS $HOME_NET
-
-# List of web servers on your network
-ipvar HTTP_SERVERS $HOME_NET
-
-# List of sql servers on your network 
-ipvar SQL_SERVERS $HOME_NET
-
-# List of telnet servers on your network
-ipvar TELNET_SERVERS $HOME_NET
-
-# List of ssh servers on your network
-ipvar SSH_SERVERS $HOME_NET
-
-# List of ftp servers on your network
-ipvar FTP_SERVERS $HOME_NET
-
-# List of sip servers on your network
-ipvar SIP_SERVERS $HOME_NET
-
-# List of ports you run web servers on
-portvar HTTP_PORTS [80,81,82,83,84,85,86,87,88,89,311,383,444,591,593,631,901,1220,1414,1741,1830,2301,2381,2809,3037,3057,3128,3702,4343,4848,5250,6080,6988,7000,7001,7144,7145,7510,7777,7779,8000,8008,8014,8028,8080,8085,8088,8090,8118,8123,8180,8181,8222,8243,8280,8300,8500,8800,8888,8899,9000,9060,9080,9090,9091,9443,9999,11371,34443,34444,41080,50002,55555]
-
-# List of ports you want to look for SHELLCODE on.
-portvar SHELLCODE_PORTS !80
-
-# List of ports you might see oracle attacks on
-portvar ORACLE_PORTS 1024:
-
-# List of ports you want to look for SSH connections on:
-portvar SSH_PORTS [22,222]
-
-# List of ports you run ftp servers on
-portvar FTP_PORTS [21,2100,3535]
-
-# List of ports you run SIP servers on
-portvar SIP_PORTS [5060,5061,5600]
-
-# List of file data ports for file inspection
-portvar FILE_DATA_PORTS [$HTTP_PORTS,110,143]
-
-# List of GTP ports for GTP preprocessor
-portvar GTP_PORTS [2123,2152,3386]
-
-# other variables, these should not be modified
-ipvar AIM_SERVERS [64.12.24.0/23,64.12.28.0/23,64.12.161.0/24,64.12.163.0/24,64.12.200.0/24,205.188.3.0/24,205.188.5.0/24,205.188.7.0/24,205.188.9.0/24,205.188.153.0/24,205.188.179.0/24,205.188.248.0/24]
-
-# Path to your rules files (this can be a relative path)
-# Note for Windows users:  You are advised to make this an absolute path,
-# such as:  c:\snort\rules
-var RULE_PATH /etc/snort/rules
-var SO_RULE_PATH /etc/snort/so_rules
-var PREPROC_RULE_PATH /etc/snort/preproc_rules
-
-# If you are using reputation preprocessor set these
-# Currently there is a bug with relative paths, they are relative to where snort is
-# not relative to snort.conf like the above variables
-# This is completely inconsistent with how other vars work, BUG 89986
-# Set the absolute path appropriately
-var WHITE_LIST_PATH /etc/snort/rules
-var BLACK_LIST_PATH /etc/snort/rules
-
-
-###################################################
-# Step #2: Configure the decoder.  For more information, see README.decode
-###################################################
-
-# Stop generic decode events:
-config disable_decode_alerts
-
-# Stop Alerts on experimental TCP options
-config disable_tcpopt_experimental_alerts
-
-# Stop Alerts on obsolete TCP options
-config disable_tcpopt_obsolete_alerts
-
-# Stop Alerts on T/TCP alerts
-# config disable_tcpopt_ttcp_alerts
-
-# Stop Alerts on all other TCPOption type events:
-config disable_tcpopt_alerts
-
-# Stop Alerts on invalid ip options
-# config disable_ipopt_alerts
-
-# Alert if value in length field (IP, TCP, UDP) is greater th elength of the packet
-# config enable_decode_oversized_alerts
-
-# Same as above, but drop packet if in Inline mode (requires enable_decode_oversized_alerts)
-# config enable_decode_oversized_drops
-
-# Configure IP / TCP checksum mode
-config checksum_mode: all
-
-# Configure maximum number of flowbit references.  For more information, see README.flowbits
-# config flowbits_size: 64
-
-# Configure ports to ignore 
-# config ignore_ports: tcp 21 6667:6671 1356
-# config ignore_ports: udp 1:17 53
-
-# Configure active response for non inline operation. For more information, see REAMDE.active
-# config response: eth0 attempts 2
-
-# Configure DAQ related options for inline operation. For more information, see README.daq
-#
-# config daq: <type>
-# config daq_dir: <dir>
-# config daq_mode: <mode>
-# config daq_var: <var>
-#
-# <type> ::= pcap | afpacket | dump | nfq | ipq | ipfw
-# <mode> ::= read-file | passive | inline
-# <var> ::= arbitrary <name>=<value passed to DAQ
-# <dir> ::= path as to where to look for DAQ module so's
-
-# Configure specific UID and GID to run snort as after dropping privs. For more information see snort -h command line options
-#
-# config set_gid:
-# config set_uid:
-
-# Configure default snaplen. Snort defaults to MTU of in use interface. For more information see README
-#
-# config snaplen:
-#
-
-# Configure default bpf_file to use for filtering what traffic reaches snort. For more information see snort -h command line options (-F)
-#
-# config bpf_file:
-#
-
-# Configure default log directory for snort to log to.  For more information see snort -h command line options (-l)
-#
-# config logdir:
-
-
-###################################################
-# Step #3: Configure the base detection engine.  For more information, see  README.decode
-###################################################
-
-# Configure PCRE match limitations
-config pcre_match_limit: 3500
-config pcre_match_limit_recursion: 1500
-
-# Configure the detection engine  See the Snort Manual, Configuring Snort - Includes - Config
-config detection: search-method ac-split search-optimize max-pattern-len 20
-
-# Configure the event queue.  For more information, see README.event_queue
-config event_queue: max_queue 8 log 5 order_events content_length
-
-###################################################
-## Configure GTP if it is to be used.
-## For more information, see README.GTP
-####################################################
-
-# config enable_gtp
-
-###################################################
-# Per packet and rule latency enforcement
-# For more information see README.ppm
-###################################################
-
-# Per Packet latency configuration
-#config ppm: max-pkt-time 250, \
-#   fastpath-expensive-packets, \
-#   pkt-log
-
-# Per Rule latency configuration
-#config ppm: max-rule-time 200, \
-#   threshold 3, \
-#   suspend-expensive-rules, \
-#   suspend-timeout 20, \
-#   rule-log alert
-
-###################################################
-# Configure Perf Profiling for debugging
-# For more information see README.PerfProfiling
-###################################################
-
-#config profile_rules: print all, sort avg_ticks
-#config profile_preprocs: print all, sort avg_ticks
-
-###################################################
-# Configure protocol aware flushing
-# For more information see README.stream5
-###################################################
-config paf_max: 16000
-
-###################################################
-# Step #4: Configure dynamic loaded libraries.  
-# For more information, see Snort Manual, Configuring Snort - Dynamic Modules
-###################################################
-
-# path to dynamic preprocessor libraries
-dynamicpreprocessor directory /usr/lib/snort_dynamicpreprocessor/
-
-# path to base preprocessor engine
-dynamicengine /usr/lib/snort_dynamicengine/libsf_engine.so
-
-# path to dynamic rules libraries
-# dynamicdetection directory /usr/local/lib/snort_dynamicrules
-
-
-###################################################
-# Step #5: Configure preprocessors
-# For more information, see the Snort Manual, Configuring Snort - Preprocessors
-###################################################
-
-# GTP Control Channle Preprocessor. For more information, see README.GTP
-# preprocessor gtp: ports { 2123 3386 2152 }
-
-# Inline packet normalization. For more information, see README.normalize
-# Does nothing in IDS mode
-preprocessor normalize_ip4
-preprocessor normalize_tcp: ips ecn stream
-preprocessor normalize_icmp4
-preprocessor normalize_ip6
-preprocessor normalize_icmp6
-
-# Target-based IP defragmentation.  For more inforation, see README.frag3
-preprocessor frag3_global: max_frags 65536
-preprocessor frag3_engine: policy windows detect_anomalies overlap_limit 10 min_fragment_length 100 timeout 180
-
-# Target-Based stateful inspection/stream reassembly.  For more inforation, see README.stream5
-preprocessor stream5_global: track_tcp yes, \
-   track_udp yes, \
-   track_icmp no, \ 
-   max_tcp 262144, \
-   max_udp 131072, \
-   max_active_responses 2, \
-   min_response_seconds 5
-preprocessor stream5_tcp: policy windows, detect_anomalies, require_3whs 180, \
-   overlap_limit 10, small_segments 3 bytes 150, timeout 180, \
-    ports client 21 22 23 25 42 53 70 79 109 110 111 113 119 135 136 137 139 143 \
-        161 222 445 513 514 587 593 691 1433 1521 1741 2100 3306 6070 6665 6666 6667 6668 6669 \
-        7000 8181 32770 32771 32772 32773 32774 32775 32776 32777 32778 32779, \
-    ports both 80 81 82 83 84 85 86 87 88 89 110 311 383 443 444 465 563 591 593 631 636 901 989 992 993 994 995 1220 1414 1830 2301 2381 2809 3037 3057 3128 3702 4343 4848 5250 6080 6988 7907 7000 7001 7144 7145 7510 7802 7777 7779 \
-        7801 7900 7901 7902 7903 7904 7905 7906 7908 7909 7910 7911 7912 7913 7914 7915 7916 \
-        7917 7918 7919 7920 8000 8008 8014 8028 8080 8085 8088 8090 8118 8123 8180 8222 8243 8280 8300 8500 8800 8888 8899 9000 9060 9080 9090 9091 9443 9999 11371 34443 34444 41080 50002 55555
-preprocessor stream5_udp: timeout 180
-
-# performance statistics.  For more information, see the Snort Manual, Configuring Snort - Preprocessors - Performance Monitor
-# preprocessor perfmonitor: time 300 file /var/snort/snort.stats pktcnt 10000
-
-# HTTP normalization and anomaly detection.  For more information, see README.http_inspect
-preprocessor http_inspect: global iis_unicode_map unicode.map 1252 compress_depth 65535 decompress_depth 65535
-preprocessor http_inspect_server: server default \
-    http_methods { GET POST PUT SEARCH MKCOL COPY MOVE LOCK UNLOCK NOTIFY POLL BCOPY BDELETE BMOVE LINK UNLINK OPTIONS HEAD DELETE TRACE TRACK CONNECT SOURCE SUBSCRIBE UNSUBSCRIBE PROPFIND PROPPATCH BPROPFIND BPROPPATCH RPC_CONNECT PROXY_SUCCESS BITS_POST CCM_POST SMS_POST RPC_IN_DATA RPC_OUT_DATA RPC_ECHO_DATA } \
-    chunk_length 500000 \
-    server_flow_depth 0 \
-    client_flow_depth 0 \
-    post_depth 65495 \
-    oversize_dir_length 500 \
-    max_header_length 750 \
-    max_headers 100 \
-    max_spaces 200 \
-    small_chunk_length { 10 5 } \
-    ports { 80 81 82 83 84 85 86 87 88 89 311 383 444 591 593 631 901 1220 1414 1741 1830 2301 2381 2809 3037 3057 3128 3702 4343 4848 5250 6080 6988 7000 7001 7144 7145 7510 7777 7779 8000 8008 8014 8028 8080 8085 8088 8090 8118 8123 8180 8181 8222 8243 8280 8300 8500 8800 8888 8899 9000 9060 9080 9090 9091 9443 9999 11371 34443 34444 41080 50002 55555 } \
-    non_rfc_char { 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 } \
-    enable_cookie \
-    extended_response_inspection \
-    inspect_gzip \
-    normalize_utf \
-    unlimited_decompress \
-    normalize_javascript \
-    apache_whitespace no \
-    ascii no \
-    bare_byte no \
-    directory no \
-    double_decode no \
-    iis_backslash no \
-    iis_delimiter no \
-    iis_unicode no \
-    multi_slash no \
-    utf_8 no \
-    u_encode yes \
-    webroot no
-
-# ONC-RPC normalization and anomaly detection.  For more information, see the Snort Manual, Configuring Snort - Preprocessors - RPC Decode
-preprocessor rpc_decode: 111 32770 32771 32772 32773 32774 32775 32776 32777 32778 32779 no_alert_multiple_requests no_alert_large_fragments no_alert_incomplete
-
-# Back Orifice detection.
-preprocessor bo
-
-# FTP / Telnet normalization and anomaly detection.  For more information, see README.ftptelnet
-preprocessor ftp_telnet: global inspection_type stateful encrypted_traffic no check_encrypted
-preprocessor ftp_telnet_protocol: telnet \
-    ayt_attack_thresh 20 \
-    normalize ports { 23 } \
-    detect_anomalies
-preprocessor ftp_telnet_protocol: ftp server default \
-    def_max_param_len 100 \
-    ports { 21 2100 3535 } \
-    telnet_cmds yes \
-    ignore_telnet_erase_cmds yes \
-    ftp_cmds { ABOR ACCT ADAT ALLO APPE AUTH CCC CDUP } \
-    ftp_cmds { CEL CLNT CMD CONF CWD DELE ENC EPRT } \
-    ftp_cmds { EPSV ESTA ESTP FEAT HELP LANG LIST LPRT } \
-    ftp_cmds { LPSV MACB MAIL MDTM MIC MKD MLSD MLST } \
-    ftp_cmds { MODE NLST NOOP OPTS PASS PASV PBSZ PORT } \
-    ftp_cmds { PROT PWD QUIT REIN REST RETR RMD RNFR } \
-    ftp_cmds { RNTO SDUP SITE SIZE SMNT STAT STOR STOU } \
-    ftp_cmds { STRU SYST TEST TYPE USER XCUP XCRC XCWD } \
-    ftp_cmds { XMAS XMD5 XMKD XPWD XRCP XRMD XRSQ XSEM } \
-    ftp_cmds { XSEN XSHA1 XSHA256 } \
-    alt_max_param_len 0 { ABOR CCC CDUP ESTA FEAT LPSV NOOP PASV PWD QUIT REIN STOU SYST XCUP XPWD } \
-    alt_max_param_len 200 { ALLO APPE CMD HELP NLST RETR RNFR STOR STOU XMKD } \
-    alt_max_param_len 256 { CWD RNTO } \
-    alt_max_param_len 400 { PORT } \
-    alt_max_param_len 512 { SIZE } \
-    chk_str_fmt { ACCT ADAT ALLO APPE AUTH CEL CLNT CMD } \
-    chk_str_fmt { CONF CWD DELE ENC EPRT EPSV ESTP HELP } \
-    chk_str_fmt { LANG LIST LPRT MACB MAIL MDTM MIC MKD } \
-    chk_str_fmt { MLSD MLST MODE NLST OPTS PASS PBSZ PORT } \
-    chk_str_fmt { PROT REST RETR RMD RNFR RNTO SDUP SITE } \
-    chk_str_fmt { SIZE SMNT STAT STOR STRU TEST TYPE USER } \
-    chk_str_fmt { XCRC XCWD XMAS XMD5 XMKD XRCP XRMD XRSQ } \ 
-    chk_str_fmt { XSEM XSEN XSHA1 XSHA256 } \
-    cmd_validity ALLO < int [ char R int ] > \    
-    cmd_validity EPSV < [ { char 12 | char A char L char L } ] > \
-    cmd_validity MACB < string > \
-    cmd_validity MDTM < [ date nnnnnnnnnnnnnn[.n[n[n]]] ] string > \
-    cmd_validity MODE < char ASBCZ > \
-    cmd_validity PORT < host_port > \
-    cmd_validity PROT < char CSEP > \
-    cmd_validity STRU < char FRPO [ string ] > \    
-    cmd_validity TYPE < { char AE [ char NTC ] | char I | char L [ number ] } >
-preprocessor ftp_telnet_protocol: ftp client default \
-    max_resp_len 256 \
-    bounce yes \
-    ignore_telnet_erase_cmds yes \
-    telnet_cmds yes
-
-
-# SMTP normalization and anomaly detection.  For more information, see README.SMTP
-preprocessor smtp: ports { 25 465 587 691 } \
-    inspection_type stateful \
-    b64_decode_depth 0 \
-    qp_decode_depth 0 \
-    bitenc_decode_depth 0 \
-    uu_decode_depth 0 \
-    log_mailfrom \
-    log_rcptto \
-    log_filename \
-    log_email_hdrs \
-    normalize cmds \
-    normalize_cmds { ATRN AUTH BDAT CHUNKING DATA DEBUG EHLO EMAL ESAM ESND ESOM ETRN EVFY } \
-    normalize_cmds { EXPN HELO HELP IDENT MAIL NOOP ONEX QUEU QUIT RCPT RSET SAML SEND SOML } \
-    normalize_cmds { STARTTLS TICK TIME TURN TURNME VERB VRFY X-ADAT X-DRCP X-ERCP X-EXCH50 } \
-    normalize_cmds { X-EXPS X-LINK2STATE XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUE XSTA XTRN XUSR } \
-    max_command_line_len 512 \
-    max_header_line_len 1000 \
-    max_response_line_len 512 \
-    alt_max_command_line_len 260 { MAIL } \
-    alt_max_command_line_len 300 { RCPT } \
-    alt_max_command_line_len 500 { HELP HELO ETRN EHLO } \
-    alt_max_command_line_len 255 { EXPN VRFY ATRN SIZE BDAT DEBUG EMAL ESAM ESND ESOM EVFY IDENT NOOP RSET } \
-    alt_max_command_line_len 246 { SEND SAML SOML AUTH TURN ETRN DATA RSET QUIT ONEX QUEU STARTTLS TICK TIME TURNME VERB X-EXPS X-LINK2STATE XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUE XSTA XTRN XUSR } \
-    valid_cmds { ATRN AUTH BDAT CHUNKING DATA DEBUG EHLO EMAL ESAM ESND ESOM ETRN EVFY } \ 
-    valid_cmds { EXPN HELO HELP IDENT MAIL NOOP ONEX QUEU QUIT RCPT RSET SAML SEND SOML } \
-    valid_cmds { STARTTLS TICK TIME TURN TURNME VERB VRFY X-ADAT X-DRCP X-ERCP X-EXCH50 } \
-    valid_cmds { X-EXPS X-LINK2STATE XADR XAUTH XCIR XEXCH50 XGEN XLICENSE XQUE XSTA XTRN XUSR } \
-    xlink2state { enabled }
-
-# Portscan detection.  For more information, see README.sfportscan
-preprocessor sfportscan: proto  { all } memcap { 10000000 } sense_level { medium }
-
-# ARP spoof detection.  For more information, see the Snort Manual - Configuring Snort - Preprocessors - ARP Spoof Preprocessor
-# preprocessor arpspoof
-# preprocessor arpspoof_detect_host: 192.168.40.1 f0:0f:00:f0:0f:00
-
-# SSH anomaly detection.  For more information, see README.ssh
-preprocessor ssh: server_ports { 22 222 } \
-                  autodetect \
-                  max_client_bytes 19600 \
-                  max_encrypted_packets 20 \
-                  max_server_version_len 100 \
-                  enable_respoverflow enable_ssh1crc32 \
-                  enable_srvoverflow enable_protomismatch
-
-# SMB / DCE-RPC normalization and anomaly detection.  For more information, see README.dcerpc2
-preprocessor dcerpc2: memcap 102400, events [co ]
-preprocessor dcerpc2_server: default, policy WinXP, \
-    detect [smb [139,445], tcp 135, udp 135, rpc-over-http-server 593], \
-    autodetect [tcp 1025:, udp 1025:, rpc-over-http-server 1025:], \
-    smb_max_chain 3, smb_invalid_shares ["C$", "D$", "ADMIN$"]
-
-# DNS anomaly detection.  For more information, see README.dns
-preprocessor dns: ports { 53 } enable_rdata_overflow
-
-# SSL anomaly detection and traffic bypass.  For more information, see README.ssl
-preprocessor ssl: ports { 443 444 465 563 636 989 992 993 994 995 7801 7802 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 }, trustservers, noinspect_encrypted
-
-# SDF sensitive data preprocessor.  For more information see README.sensitive_data
-preprocessor sensitive_data: alert_threshold 25
-
-# SIP Session Initiation Protocol preprocessor.  For more information see README.sip
-preprocessor sip: max_sessions 40000, \
-   ports { 5060 5061 5600 }, \
-   methods { invite \
-             cancel \
-             ack \
-             bye \
-             register \
-             options \
-             refer \
-             subscribe \
-             update \
-             join \
-             info \
-             message \
-             notify \
-             benotify \
-             do \
-             qauth \
-             sprack \
-             publish \
-             service \
-             unsubscribe \
-             prack }, \
-   max_uri_len 512, \
-   max_call_id_len 80, \
-   max_requestName_len 20, \
-   max_from_len 256, \
-   max_to_len 256, \
-   max_via_len 1024, \
-   max_contact_len 512, \
-   max_content_len 2048 
-
-# IMAP preprocessor.  For more information see README.imap
-preprocessor imap: \
-   ports { 143 } \
-   b64_decode_depth 0 \
-   qp_decode_depth 0 \
-   bitenc_decode_depth 0 \
-   uu_decode_depth 0
-
-# POP preprocessor. For more information see README.pop
-preprocessor pop: \
-   ports { 110 } \
-   b64_decode_depth 0 \
-   qp_decode_depth 0 \
-   bitenc_decode_depth 0 \
-   uu_decode_depth 0
-
-# Modbus preprocessor. For more information see README.modbus
-preprocessor modbus: ports { 502 }
-
-# DNP3 preprocessor. For more information see README.dnp3
-preprocessor dnp3: ports { 20000 } \
-   memcap 262144 \
-   check_crc
-
-# Reputation preprocessor. For more information see README.reputation
-#preprocessor reputation: \
-#   memcap 500, \
-#   priority whitelist, \
-#   nested_ip inner, \
-#   whitelist $WHITE_LIST_PATH/white_list.rules, \
-#   blacklist $BLACK_LIST_PATH/black_list.rules 
-
-
-###################################################
-# Step #6: Configure output plugins
-# For more information, see Snort Manual, Configuring Snort - Output Modules
-###################################################
-
-# unified2 
-# Recommended for most installs
-# output unified2: filename merged.log, limit 128, nostamp, mpls_event_types, vlan_event_types
-
-# Additional configuration for specific types of installs
-# output alert_unified2: filename snort.alert, limit 128, nostamp
-# output log_unified2: filename snort.log, limit 128, nostamp 
-
-# syslog
-# output alert_syslog: LOG_AUTH LOG_ALERT
-
-# pcap
-# output log_tcpdump: tcpdump.log
-
-# database
-# output database: alert, <db_type>, user=<username> password=<password> test dbname=<name> host=<hostname>
-# output database: log, <db_type>, user=<username> password=<password> test dbname=<name> host=<hostname>
-
-# prelude
-# output alert_prelude
-
-# metadata reference data.  do not modify these lines
-include /etc/snort/rules/classification.config
-include /etc/snort/rules/reference.config
-
-
-###################################################
-# Step #7: Customize your rule set
-# For more information, see Snort Manual, Writing Snort Rules
-###################################################
-
-#
-# site specific rules
-#
diff --git a/config/suricata/convert-snort b/config/suricata/convert-snort
new file mode 100644 (file)
index 0000000..ca650b1
--- /dev/null
@@ -0,0 +1,323 @@
+#!/usr/bin/perl
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2019 IPFire Development Team <info@ipfire.org>                #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+use strict;
+
+require '/var/ipfire/general-functions.pl';
+require "${General::swroot}/ids-functions.pl";
+
+# Snort settings file, which contains the settings from the WUI.
+my $snort_settings_file = "${General::swroot}/snort/settings";
+
+# Main snort config file.
+my $snort_config_file = "/etc/snort/snort.conf";
+
+# Snort rules tarball.
+my $snort_rules_tarball = "/var/tmp/snortrules.tar.gz";
+
+#
+## Step 1: Setup directory and file layout, if not present and set correct
+##         ownership. The converter runs as a privileged user, but the files
+##         needs to be full access-able by the WUI user and group (nobody:nobody).
+#
+
+# Check if the settings directory exists.
+unless (-d $IDS::settingsdir) {
+       # Create the directory.
+       mkdir($IDS::settingsdir);
+}
+
+# Check if the rules directory exists.
+unless (-d $IDS::rulespath) {
+       # Create the directory.
+       mkdir($IDS::rulespath);
+}
+
+# Create file layout, if not exists yet.
+&IDS::check_and_create_filelayout();
+
+# Set correct ownership for settingsdir and rulespath.
+&IDS::set_ownership("$IDS::settingsdir");
+&IDS::set_ownership("$IDS::rulespath");
+
+# Check if a snort settings file exists.
+unless( -f "$snort_settings_file") {
+       print "$snort_settings_file not found - Nothing to do. Exiting!\n";
+       exit(0);
+}
+
+# Check if the snort settings file is empty.
+if (-z "$snort_settings_file") {
+       print "$snort_settings_file is empty - Nothing to do. Exiting!\n";
+       exit(0);
+}
+
+#
+## Step 2: Import snort settings and convert to the required format for the new IDS
+##         (suricata).
+#
+
+# Hash which contains the "old" snort settings.
+my %snortsettings;
+
+# Hash which contains the IDS (suricata) settings.
+#
+# Add default value for MONITOR_TRAFFIC_ONLY which will be "on"
+# when migrating from snort to the new IDS.
+my %idssettings = (
+       "MONITOR_TRAFFIC_ONLY" => "on",
+);
+
+# Hash which contains the RULES settings.
+#
+# Set default value for UPDATE_INTERVAL to weekly.
+my %rulessettings = (
+       "AUTOUPDATE_INTERVAL" => "weekly",
+);
+
+# Get all available network zones.
+my @network_zones = &IDS::get_available_network_zones();
+
+# Read-in snort settings file.
+&General::readhash("$snort_settings_file", \%snortsettings);
+
+# Loop through the array of network zones.
+foreach my $zone (@network_zones) {
+       # Convert current zone into upper case.
+       my $zone_upper = uc($zone);
+
+       # Check if the current network zone is "red".
+       if($zone eq "red") {
+               # Check if snort was enabled and enabled on red.
+               if ($snortsettings{"ENABLE_SNORT"} eq "on") {
+                       # Enable the IDS.
+                       $idssettings{"ENABLE_IDS"} = "on";
+
+                       # Enable the IDS on RED.
+                       $idssettings{"ENABLE_IDS_$zone_upper"} = "on";
+               }
+       } else {
+               # Check if snort was enabled on the current zone.
+               if ($snortsettings{"ENABLE_SNORT_$zone_upper"} eq "on") {
+                       # Enable the IDS on this zone too.
+                       $idssettings{"ENABLE_IDS_$zone_upper"} = "on";
+               }
+       }
+}
+
+# Grab the choosen ruleset from snort settings hash and store it in the rules
+# settings hash.
+$rulessettings{"RULES"} = $snortsettings{"RULES"};
+
+# Check if an oinkcode has been provided.
+if($snortsettings{"OINKCODE"}) {
+       # Take the oinkcode from snort settings hash and store it in the rules
+       # settings hash.
+       $rulessettings{"OINKCODE"} = $snortsettings{"OINKCODE"};
+}
+
+#
+## Step 3: Import guardian settings and whitelist if the addon is installed.
+#
+
+# Pakfire meta file for owncloud.
+# (File exists when the addon is installed.)
+my $guardian_meta = "/opt/pakfire/db/installed/meta-guardian";
+
+# Check if the guardian addon is installed.
+if (-f $guardian_meta) {
+       # File which contains the taken setting for guardian.
+       my $guardian_settings_file = "${General::swroot}/guardian/settings";
+
+       # File which contains the white-listed hosts.
+       my $guardian_ignored_file = "${General::swroot}/guardian/ignored";
+
+       # Hash which will contain the settings of guardian.
+       my %guardiansettings;
+
+       # Check if the settings file of guardian is empty.
+       unless (-z $guardian_settings_file) {
+               # Read-in settings.
+               &General::readhash("$guardian_settings_file", \%guardiansettings);
+       }
+
+       # Check if guardian is not configured to take actions on snort events.
+       if ($guardiansettings{"GUARDIAN_MONITOR_SNORT"} eq "on") {
+               # Change the IDS into MONITOR_TRAFFIC_ONLY mode.
+               $idssettings{"MONITOR_TRAFFIC_ONLY"} = "off";
+       }
+
+       # Check if guardian has any white-listed hosts configured.
+       unless (-z $guardian_ignored_file) {
+               # Temporary hash to store the ignored hosts.
+               my %ignored_hosts;
+
+               # Read-in white-listed hosts and store them in the hash.
+               &General::readhasharray($guardian_ignored_file, \%ignored_hosts);
+
+               # Write-out the white-listed hosts for the IDS system.
+               &General::writehasharray($IDS::ignored_file, \%ignored_hosts);
+
+               # Call subfunction to generate the file for white-listing the hosts.
+               &IDS::generate_ignored_file();
+       }
+
+}
+
+#
+## Step 4: Save IDS and rules settings.
+#
+
+# Write IDS settings.
+&General::writehash("$IDS::ids_settings_file", \%idssettings);
+
+# Write rules settings.
+&General::writehash("$IDS::rules_settings_file", \%rulessettings);
+
+#
+## Step 5: Generate and write the file to modify the ruleset.
+#
+
+# Converters default is to only monitor the traffic, so set the IDS action to
+# "alert".
+my $IDS_action = "alert";
+
+# Check if the traffic only should be monitored.
+if ($idssettings{"MONITOR_TRAFFIC_ONLY"} eq "off") {
+       # Swith IDS action to alert only.
+       $IDS_action = "drop";
+}
+
+# Call subfunction and pass the desired IDS action.
+&IDS::write_modify_sids_file($IDS_action);
+
+# Set correct ownership.
+&IDS::set_ownership("$IDS::modify_sids_file");
+
+#
+## Step 6: Move rulestarball to its new location.
+#
+
+# Check if a rulestarball has been downloaded yet.
+if (-f $snort_rules_tarball) {
+       # Load perl module which contains the move command.
+       use File::Copy;
+
+       # Move the rulestarball to the new location.
+       move($snort_rules_tarball, $IDS::rulestarball);
+
+       # Set correct ownership.
+       &IDS::set_ownership("$IDS::rulestarball");
+
+# In case no tarball is present, try to download the ruleset.
+} else {
+       # Check if enought disk space is available.
+       if(&IDS::checkdiskspace()) {
+               # Call the download function and grab the new ruleset.
+               &IDS::downloadruleset();
+       }
+}
+
+#
+## Step 7: Call oinkmaster to extract and setup the rules structures.
+#
+
+# Check if a rulestarball is present.
+if (-f $IDS::rulestarball) {
+       # Launch oinkmaster by calling the subfunction.
+       &IDS::oinkmaster();
+
+       # Set correct ownership for the rulesdir and files.
+       &IDS::set_ownership("$IDS::rulespath");
+}
+
+#
+## Step 8: Grab used ruleset files from snort config file and convert
+##         them into the new format.
+#
+
+# Check if the snort config file exists.
+unless (-f $snort_config_file) {
+       print "$snort_config_file does not exist - Nothing to do. Exiting!\n";
+       exit(0);
+}
+
+# Array to store the enabled rules files.
+my @enabled_rule_files;
+
+# Open snort config file.
+open(SNORTCONF, $snort_config_file) or die "Could not open $snort_config_file. $!\n";
+
+# Loop through the file content.
+while (my $line = <SNORTCONF>) {
+       # Skip comments.
+       next if ($line =~ /\#/);
+
+       # Skip blank  lines.
+       next if ($line =~ /^\s*$/);
+
+       # Remove newlines.
+       chomp($line);
+
+       # Check for a line with .rules
+       if ($line =~ /\.rules$/) {
+               # Parse out rule file name
+               my $rulefile = $line;
+               $rulefile =~ s/\$RULE_PATH\///i;
+               $rulefile =~ s/ ?include ?//i;
+
+               # Add the enabled rulefile to the array of enabled rule files.
+               push(@enabled_rule_files, $rulefile);
+       }
+}
+
+# Close filehandle.
+close(SNORTCONF);
+
+# Pass the array of enabled rule files to the subfunction and write the file.
+&IDS::write_used_rulefiles_file(@enabled_rule_files);
+
+#
+## Step 9: Generate file for the HOME Net.
+#
+
+# Call subfunction to generate the file.
+&IDS::generate_home_net_file();
+
+#
+## Step 10: Setup automatic ruleset updates.
+#
+
+# Check if a ruleset is configured.
+if($rulessettings{"RULES"}) {
+       # Call suricatactrl and setup the periodic update mechanism.
+       &IDS::call_suricatactrl("cron", $rulessettings{'AUTOUPDATE_INTERVAL'});
+}
+
+#
+## Step 11: Start the IDS if enabled.
+#
+
+# Check if the IDS should be started.
+if($idssettings{"ENABLE_IDS"} eq "on") {
+       # Call suricatactrl and launch the IDS.
+       &IDS::call_suricatactrl("start");
+}
diff --git a/config/suricata/ruleset-sources b/config/suricata/ruleset-sources
new file mode 100644 (file)
index 0000000..cf6baa1
--- /dev/null
@@ -0,0 +1,15 @@
+# Ruleset for registered sourcefire users.
+registered = https://www.snort.org/rules/snortrules-snapshot-29120.tar.gz?oinkcode=<oinkcode>
+
+# Ruleset for registered sourcefire users with valid subscription.
+subscripted = https://www.snort.org/rules/snortrules-snapshot-29120.tar.gz?oinkcode=<oinkcode>
+
+# Community rules from sourcefire.
+community = https://www.snort.org/rules/community
+
+# Emerging threads community rules.
+emerging = https://rules.emergingthreats.net/open/suricata-4.0/emerging.rules.tar.gz
+
+# Emerging threads pro rules.
+emerging_pro = https://rules.emergingthreatspro.com/<oinkcode>/suricata-4.0/etpro.rules.tar.gz
+
diff --git a/config/suricata/suricata.yaml b/config/suricata/suricata.yaml
new file mode 100644 (file)
index 0000000..3b50157
--- /dev/null
@@ -0,0 +1,741 @@
+%YAML 1.1
+---
+
+##
+## IPFire specific configuration file - an untouched example configuration
+## can be found in suricata-example.yaml.
+##
+
+vars:
+  address-groups:
+    # Include HOME_NET declaration from external file.
+    include: /var/ipfire/suricata/suricata-homenet.yaml
+
+    EXTERNAL_NET: "!$HOME_NET"
+    #EXTERNAL_NET: "any"
+
+    HTTP_SERVERS: "$HOME_NET"
+    SMTP_SERVERS: "$HOME_NET"
+    SQL_SERVERS: "$HOME_NET"
+    DNS_SERVERS: "$HOME_NET"
+    TELNET_SERVERS: "$HOME_NET"
+    AIM_SERVERS: "$EXTERNAL_NET"
+    DC_SERVERS: "$HOME_NET"
+    DNP3_SERVER: "$HOME_NET"
+    DNP3_CLIENT: "$HOME_NET"
+    MODBUS_CLIENT: "$HOME_NET"
+    MODBUS_SERVER: "$HOME_NET"
+    ENIP_CLIENT: "$HOME_NET"
+    ENIP_SERVER: "$HOME_NET"
+
+  port-groups:
+    HTTP_PORTS: "80"
+    SHELLCODE_PORTS: "!80"
+    ORACLE_PORTS: 1521
+    SSH_PORTS: "[22,222]"
+    DNP3_PORTS: 20000
+    MODBUS_PORTS: 502
+    FILE_DATA_PORTS: "[$HTTP_PORTS,110,143]"
+    FTP_PORTS: 21
+
+##
+## Ruleset specific options.
+##
+default-rule-path: /var/lib/suricata
+rule-files:
+    # Include enabled ruleset files from external file.
+    include: /var/ipfire/suricata/suricata-used-rulefiles.yaml
+
+classification-file: /var/lib/suricata/classification.config
+reference-config-file: /var/lib/suricata/reference.config
+threshold-file: /var/lib/suricata/threshold.config
+
+
+##
+## Logging options.
+##
+default-log-dir: /var/log/suricata/
+
+# global stats configuration
+stats:
+  enabled: yes
+  # The interval field (in seconds) controls at what interval
+  # the loggers are invoked.
+  interval: 8
+
+  # Add decode events as stats.
+  #decoder-events: true
+  # Decoder event prefix in stats. Has been 'decoder' before, but that leads
+  # to missing events in the eve.stats records. See issue #2225.
+  decoder-events-prefix: "decoder.event"
+  # Add stream events as stats.
+  #stream-events: false
+
+# Configure the type of alert (and other) logging you would like.
+outputs:
+  # a line based alerts log similar to Snort's fast.log
+  - fast:
+      enabled: yes
+      filename: fast.log
+      append: yes
+      #filetype: regular # 'regular', 'unix_stream' or 'unix_dgram'
+
+  # Stats.log contains data from various counters of the suricata engine.
+  - stats:
+      enabled: yes
+      filename: stats.log
+      append: no       # append to file (yes) or overwrite it (no)
+      totals: yes       # stats for all threads merged together
+      threads: no       # per thread stats
+      #null-values: yes  # print counters that have value 0
+
+logging:
+  # The default log level, can be overridden in an output section.
+  # Note that debug level logging will only be emitted if Suricata was
+  # compiled with the --enable-debug configure option.
+  #
+  # This value is overriden by the SC_LOG_LEVEL env var.
+  default-log-level: notice
+
+  # A regex to filter output.  Can be overridden in an output section.
+  # Defaults to empty (no filter).
+  #
+  # This value is overriden by the SC_LOG_OP_FILTER env var.
+  default-output-filter:
+
+  # Define your logging outputs.  If none are defined, or they are all
+  # disabled you will get the default - console output.
+  outputs:
+  - console:
+      enabled: no
+      # type: json
+  - file:
+      enabled: no
+      level: info
+      filename: /var/log/suricata/suricata.log
+      # type: json
+  - syslog:
+      enabled: yes
+      facility: local5
+      format: ""
+      # type: json
+
+##
+## Netfilter configuration
+##
+
+nfq:
+   mode: repeat
+   repeat-mark: 1879048192
+   repeat-mask: 1879048192
+#   bypass-mark: 1
+#   bypass-mask: 1
+#  route-queue: 2
+#  batchcount: 20
+   fail-open: yes
+
+##
+## Step 5: App Layer Protocol Configuration
+##
+
+# Configure the app-layer parsers. The protocols section details each
+# protocol.
+#
+# The option "enabled" takes 3 values - "yes", "no", "detection-only".
+# "yes" enables both detection and the parser, "no" disables both, and
+# "detection-only" enables protocol detection only (parser disabled).
+app-layer:
+  protocols:
+    krb5:
+      enabled: no # Requires rust
+    ikev2:
+      enabled: yes
+    tls:
+      enabled: yes
+      detection-ports:
+        dp: "[443,444,465,853,993,995]"
+
+      # Completely stop processing TLS/SSL session after the handshake
+      # completed. If bypass is enabled this will also trigger flow
+      # bypass. If disabled (the default), TLS/SSL session is still
+      # tracked for Heartbleed and other anomalies.
+      #no-reassemble: yes
+    dcerpc:
+      enabled: yes
+    ftp:
+      enabled: yes
+    ssh:
+      enabled: yes
+    smtp:
+      enabled: yes
+      # Configure SMTP-MIME Decoder
+      mime:
+        # Decode MIME messages from SMTP transactions
+        # (may be resource intensive)
+        # This field supercedes all others because it turns the entire
+        # process on or off
+        decode-mime: yes
+
+        # Decode MIME entity bodies (ie. base64, quoted-printable, etc.)
+        decode-base64: yes
+        decode-quoted-printable: yes
+
+        # Maximum bytes per header data value stored in the data structure
+        # (default is 2000)
+        header-value-depth: 2000
+
+        # Extract URLs and save in state data structure
+        extract-urls: yes
+        # Set to yes to compute the md5 of the mail body. You will then
+        # be able to journalize it.
+        body-md5: no
+      # Configure inspected-tracker for file_data keyword
+      inspected-tracker:
+        content-limit: 100000
+        content-inspect-min-size: 32768
+        content-inspect-window: 4096
+    imap:
+      enabled: yes
+    msn:
+      enabled: yes
+    smb:
+      enabled: yes
+      detection-ports:
+        dp: 139, 445
+    # smb2 detection is disabled internally inside the engine.
+    #smb2:
+    #  enabled: yes
+    dns:
+      # memcaps. Globally and per flow/state.
+      global-memcap: 32mb
+      state-memcap: 512kb
+
+      # How many unreplied DNS requests are considered a flood.
+      # If the limit is reached, app-layer-event:dns.flooded; will match.
+      request-flood: 512
+
+      tcp:
+        enabled: yes
+        detection-ports:
+          dp: 53
+      udp:
+        enabled: yes
+        detection-ports:
+          dp: 53
+    http:
+      enabled: yes
+      memcap: 256mb
+
+      # default-config:           Used when no server-config matches
+      #   personality:            List of personalities used by default
+      #   request-body-limit:     Limit reassembly of request body for inspection
+      #                           by http_client_body & pcre /P option.
+      #   response-body-limit:    Limit reassembly of response body for inspection
+      #                           by file_data, http_server_body & pcre /Q option.
+      #   double-decode-path:     Double decode path section of the URI
+      #   double-decode-query:    Double decode query section of the URI
+      #   response-body-decompress-layer-limit:
+      #                           Limit to how many layers of compression will be
+      #                           decompressed. Defaults to 2.
+      #
+      # Currently Available Personalities:
+      #   Minimal, Generic, IDS (default), IIS_4_0, IIS_5_0, IIS_5_1, IIS_6_0,
+      #   IIS_7_0, IIS_7_5, Apache_2
+      libhtp:
+         default-config:
+           personality: IDS
+
+           # Can be specified in kb, mb, gb.  Just a number indicates
+           # it's in bytes.
+           request-body-limit: 0
+           response-body-limit: 0
+
+           # response body decompression (0 disables)
+           response-body-decompress-layer-limit: 2
+
+           # auto will use http-body-inline mode in IPS mode, yes or no set it statically
+           http-body-inline: auto
+
+           # Take a random value for inspection sizes around the specified value.
+           # This lower the risk of some evasion technics but could lead
+           # detection change between runs. It is set to 'yes' by default.
+           randomize-inspection-sizes: yes
+           # If randomize-inspection-sizes is active, the value of various
+           # inspection size will be choosen in the [1 - range%, 1 + range%]
+           # range
+           # Default value of randomize-inspection-range is 10.
+           randomize-inspection-range: 10
+
+           # decoding
+           double-decode-path: no
+           double-decode-query: no
+
+
+# Limit for the maximum number of asn1 frames to decode (default 256)
+asn1-max-frames: 256
+
+
+##############################################################################
+##
+## Advanced settings below
+##
+##############################################################################
+
+##
+## Run Options
+##
+
+# Run suricata as user and group.
+run-as:
+  user: suricata
+  group: suricata
+
+# Suricata core dump configuration. Limits the size of the core dump file to
+# approximately max-dump. The actual core dump size will be a multiple of the
+# page size. Core dumps that would be larger than max-dump are truncated. On
+# Linux, the actual core dump size may be a few pages larger than max-dump.
+# Setting max-dump to 0 disables core dumping.
+# Setting max-dump to 'unlimited' will give the full core dump file.
+# On 32-bit Linux, a max-dump value >= ULONG_MAX may cause the core dump size
+# to be 'unlimited'.
+
+coredump:
+  max-dump: unlimited
+
+# If suricata box is a router for the sniffed networks, set it to 'router'. If
+# it is a pure sniffing setup, set it to 'sniffer-only'.
+# If set to auto, the variable is internally switch to 'router' in IPS mode
+# and 'sniffer-only' in IDS mode.
+# This feature is currently only used by the reject* keywords.
+host-mode: auto
+
+# Number of packets preallocated per thread. The default is 1024. A higher number 
+# will make sure each CPU will be more easily kept busy, but may negatively 
+# impact caching.
+max-pending-packets: 1024
+
+# Runmode the engine should use. Please check --list-runmodes to get the available
+# runmodes for each packet acquisition method. Defaults to "autofp" (auto flow pinned
+# load balancing).
+#runmode: autofp
+
+# Specifies the kind of flow load balancer used by the flow pinned autofp mode.
+#
+# Supported schedulers are:
+#
+# round-robin       - Flows assigned to threads in a round robin fashion.
+# active-packets    - Flows assigned to threads that have the lowest number of
+#                     unprocessed packets (default).
+# hash              - Flow alloted usihng the address hash. More of a random
+#                     technique. Was the default in Suricata 1.2.1 and older.
+#
+#autofp-scheduler: active-packets
+
+# Preallocated size for packet. Default is 1514 which is the classical
+# size for pcap on ethernet. You should adjust this value to the highest
+# packet size (MTU + hardware header) on your system.
+default-packet-size: 1514
+
+# Unix command socket can be used to pass commands to suricata.
+# An external tool can then connect to get information from suricata
+# or trigger some modifications of the engine. Set enabled to yes
+# to activate the feature. In auto mode, the feature will only be
+# activated in live capture mode. You can use the filename variable to set
+# the file name of the socket.
+unix-command:
+  enabled: no
+  #filename: custom.socket
+
+# Magic file
+magic-file: /usr/share/misc/magic.mgc
+
+legacy:
+  uricontent: enabled
+
+##
+## Detection settings
+##
+
+# Set the order of alerts bassed on actions
+# The default order is pass, drop, reject, alert
+# action-order:
+#   - pass
+#   - drop
+#   - reject
+#   - alert
+
+# When run with the option --engine-analysis, the engine will read each of
+# the parameters below, and print reports for each of the enabled sections
+# and exit.  The reports are printed to a file in the default log dir
+# given by the parameter "default-log-dir", with engine reporting
+# subsection below printing reports in its own report file.
+engine-analysis:
+  # enables printing reports for fast-pattern for every rule.
+  rules-fast-pattern: yes
+  # enables printing reports for each rule
+  rules: yes
+
+#recursion and match limits for PCRE where supported
+pcre:
+  match-limit: 3500
+  match-limit-recursion: 1500
+
+##
+## Advanced Traffic Tracking and Reconstruction Settings
+##
+
+# Host specific policies for defragmentation and TCP stream
+# reassembly. The host OS lookup is done using a radix tree, just
+# like a routing table so the most specific entry matches.
+host-os-policy:
+  # Make the default policy windows.
+  windows: [0.0.0.0/0]
+  bsd: []
+  bsd-right: []
+  old-linux: []
+  linux: []
+  old-solaris: []
+  solaris: []
+  hpux10: []
+  hpux11: []
+  irix: []
+  macos: []
+  vista: []
+  windows2k3: []
+
+# Defrag settings:
+
+defrag:
+  memcap: 64mb
+  hash-size: 65536
+  trackers: 65535 # number of defragmented flows to follow
+  max-frags: 65535 # number of fragments to keep (higher than trackers)
+  prealloc: yes
+  timeout: 60
+
+# Flow settings:
+# By default, the reserved memory (memcap) for flows is 32MB. This is the limit
+# for flow allocation inside the engine. You can change this value to allow
+# more memory usage for flows.
+# The hash-size determine the size of the hash used to identify flows inside
+# the engine, and by default the value is 65536.
+# At the startup, the engine can preallocate a number of flows, to get a better
+# performance. The number of flows preallocated is 10000 by default.
+# emergency-recovery is the percentage of flows that the engine need to
+# prune before unsetting the emergency state. The emergency state is activated
+# when the memcap limit is reached, allowing to create new flows, but
+# prunning them with the emergency timeouts (they are defined below).
+# If the memcap is reached, the engine will try to prune flows
+# with the default timeouts. If it doens't find a flow to prune, it will set
+# the emergency bit and it will try again with more agressive timeouts.
+# If that doesn't work, then it will try to kill the last time seen flows
+# not in use.
+# The memcap can be specified in kb, mb, gb.  Just a number indicates it's
+# in bytes.
+
+flow:
+  memcap: 256mb
+  hash-size: 65536
+  prealloc: 10000
+  emergency-recovery: 30
+  managers: 1
+  recyclers: 1
+
+# This option controls the use of vlan ids in the flow (and defrag)
+# hashing. Normally this should be enabled, but in some (broken)
+# setups where both sides of a flow are not tagged with the same vlan
+# tag, we can ignore the vlan id's in the flow hashing.
+vlan:
+  use-for-tracking: true
+
+# Specific timeouts for flows. Here you can specify the timeouts that the
+# active flows will wait to transit from the current state to another, on each
+# protocol. The value of "new" determine the seconds to wait after a hanshake or
+# stream startup before the engine free the data of that flow it doesn't
+# change the state to established (usually if we don't receive more packets
+# of that flow). The value of "established" is the amount of
+# seconds that the engine will wait to free the flow if it spend that amount
+# without receiving new packets or closing the connection. "closed" is the
+# amount of time to wait after a flow is closed (usually zero). "bypassed"
+# timeout controls locally bypassed flows. For these flows we don't do any other
+# tracking. If no packets have been seen after this timeout, the flow is discarded.
+#
+# There's an emergency mode that will become active under attack circumstances,
+# making the engine to check flow status faster. This configuration variables
+# use the prefix "emergency-" and work similar as the normal ones.
+# Some timeouts doesn't apply to all the protocols, like "closed", for udp and
+# icmp.
+
+flow-timeouts:
+
+  default:
+    new: 30
+    established: 300
+    closed: 0
+    bypassed: 100
+    emergency-new: 10
+    emergency-established: 100
+    emergency-closed: 0
+    emergency-bypassed: 50
+  tcp:
+    new: 60
+    established: 600
+    closed: 60
+    bypassed: 100
+    emergency-new: 5
+    emergency-established: 100
+    emergency-closed: 10
+    emergency-bypassed: 50
+  udp:
+    new: 30
+    established: 300
+    bypassed: 100
+    emergency-new: 10
+    emergency-established: 100
+    emergency-bypassed: 50
+  icmp:
+    new: 30
+    established: 300
+    bypassed: 100
+    emergency-new: 10
+    emergency-established: 100
+    emergency-bypassed: 50
+
+# Stream engine settings. Here the TCP stream tracking and reassembly
+# engine is configured.
+#
+# stream:
+#   memcap: 32mb                # Can be specified in kb, mb, gb.  Just a
+#                               # number indicates it's in bytes.
+#   checksum-validation: yes    # To validate the checksum of received
+#                               # packet. If csum validation is specified as
+#                               # "yes", then packet with invalid csum will not
+#                               # be processed by the engine stream/app layer.
+#                               # Warning: locally generated trafic can be
+#                               # generated without checksum due to hardware offload
+#                               # of checksum. You can control the handling of checksum
+#                               # on a per-interface basis via the 'checksum-checks'
+#                               # option
+#   prealloc-sessions: 2k       # 2k sessions prealloc'd per stream thread
+#   midstream: false            # don't allow midstream session pickups
+#   async-oneside: false        # don't enable async stream handling
+#   inline: no                  # stream inline mode
+#   drop-invalid: yes           # in inline mode, drop packets that are invalid with regards to streaming engine
+#   max-synack-queued: 5        # Max different SYN/ACKs to queue
+#   bypass: no                  # Bypass packets when stream.depth is reached
+#
+#   reassembly:
+#     memcap: 64mb              # Can be specified in kb, mb, gb.  Just a number
+#                               # indicates it's in bytes.
+#     depth: 1mb                # Can be specified in kb, mb, gb.  Just a number
+#                               # indicates it's in bytes.
+#     toserver-chunk-size: 2560 # inspect raw stream in chunks of at least
+#                               # this size.  Can be specified in kb, mb,
+#                               # gb.  Just a number indicates it's in bytes.
+#     toclient-chunk-size: 2560 # inspect raw stream in chunks of at least
+#                               # this size.  Can be specified in kb, mb,
+#                               # gb.  Just a number indicates it's in bytes.
+#     randomize-chunk-size: yes # Take a random value for chunk size around the specified value.
+#                               # This lower the risk of some evasion technics but could lead
+#                               # detection change between runs. It is set to 'yes' by default.
+#     randomize-chunk-range: 10 # If randomize-chunk-size is active, the value of chunk-size is
+#                               # a random value between (1 - randomize-chunk-range/100)*toserver-chunk-size
+#                               # and (1 + randomize-chunk-range/100)*toserver-chunk-size and the same
+#                               # calculation for toclient-chunk-size.
+#                               # Default value of randomize-chunk-range is 10.
+#
+#     raw: yes                  # 'Raw' reassembly enabled or disabled.
+#                               # raw is for content inspection by detection
+#                               # engine.
+#
+#     segment-prealloc: 2048    # number of segments preallocated per thread
+#
+#     check-overlap-different-data: true|false
+#                               # check if a segment contains different data
+#                               # than what we've already seen for that
+#                               # position in the stream.
+#                               # This is enabled automatically if inline mode
+#                               # is used or when stream-event:reassembly_overlap_different_data;
+#                               # is used in a rule.
+#
+stream:
+  memcap: 256mb
+  prealloc-sessions: 4096
+  checksum-validation: yes      # reject wrong csums
+  inline: auto                  # auto will use inline mode in IPS mode, yes or no set it statically
+  reassembly:
+    memcap: 256mb
+    depth: 1mb                  # reassemble 1mb into a stream
+    toserver-chunk-size: 2560
+    toclient-chunk-size: 2560
+    randomize-chunk-size: yes
+    raw: yes
+    segment-prealloc: 2048
+    check-overlap-different-data: true
+
+# Host table:
+#
+# Host table is used by tagging and per host thresholding subsystems.
+#
+host:
+  hash-size: 4096
+  prealloc: 1000
+  memcap: 32mb
+
+# IP Pair table:
+#
+# Used by xbits 'ippair' tracking.
+#
+#ippair:
+#  hash-size: 4096
+#  prealloc: 1000
+#  memcap: 32mb
+
+# Decoder settings
+
+decoder:
+  # Teredo decoder is known to not be completely accurate
+  # it will sometimes detect non-teredo as teredo.
+  teredo:
+    enabled: false
+
+
+##
+## Performance tuning and profiling
+##
+
+# The detection engine builds internal groups of signatures. The engine
+# allow us to specify the profile to use for them, to manage memory on an
+# efficient way keeping a good performance. For the profile keyword you
+# can use the words "low", "medium", "high" or "custom". If you use custom
+# make sure to define the values at "- custom-values" as your convenience.
+# Usually you would prefer medium/high/low.
+#
+# "sgh mpm-context", indicates how the staging should allot mpm contexts for
+# the signature groups.  "single" indicates the use of a single context for
+# all the signature group heads.  "full" indicates a mpm-context for each
+# group head.  "auto" lets the engine decide the distribution of contexts
+# based on the information the engine gathers on the patterns from each
+# group head.
+#
+# The option inspection-recursion-limit is used to limit the recursive calls
+# in the content inspection code.  For certain payload-sig combinations, we
+# might end up taking too much time in the content inspection code.
+# If the argument specified is 0, the engine uses an internally defined
+# default limit.  On not specifying a value, we use no limits on the recursion.
+detect:
+  profile: high
+  custom-values:
+    toclient-groups: 3
+    toserver-groups: 25
+  sgh-mpm-context: auto
+  inspection-recursion-limit: 3000
+
+  # If set to yes, the loading of signatures will be made after the capture
+  # is started. This will limit the downtime in IPS mode.
+  delayed-detect: yes
+
+  prefilter:
+    # default prefiltering setting. "mpm" only creates MPM/fast_pattern
+    # engines. "auto" also sets up prefilter engines for other keywords.
+    # Use --list-keywords=all to see which keywords support prefiltering.
+    default: mpm
+
+  # the grouping values above control how many groups are created per
+  # direction. Port whitelisting forces that port to get it's own group.
+  # Very common ports will benefit, as well as ports with many expensive
+  # rules.
+  grouping:
+    #tcp-whitelist: 53, 80, 139, 443, 445, 1433, 3306, 3389, 6666, 6667, 8080
+    #udp-whitelist: 53, 135, 5060
+
+  profiling:
+    # Log the rules that made it past the prefilter stage, per packet
+    # default is off. The threshold setting determines how many rules
+    # must have made it past pre-filter for that rule to trigger the
+    # logging.
+    #inspect-logging-threshold: 200
+    grouping:
+      dump-to-disk: false
+      include-rules: false      # very verbose
+      include-mpm-stats: false
+
+# Select the multi pattern algorithm you want to run for scan/search the
+# in the engine.
+#
+# The supported algorithms are:
+# "ac"      - Aho-Corasick, default implementation
+# "ac-bs"   - Aho-Corasick, reduced memory implementation
+# "ac-cuda" - Aho-Corasick, CUDA implementation
+# "ac-ks"   - Aho-Corasick, "Ken Steele" variant
+# "hs"      - Hyperscan, available when built with Hyperscan support
+#
+# The default mpm-algo value of "auto" will use "hs" if Hyperscan is
+# available, "ac" otherwise.
+#
+# The mpm you choose also decides the distribution of mpm contexts for
+# signature groups, specified by the conf - "detect.sgh-mpm-context".
+# Selecting "ac" as the mpm would require "detect.sgh-mpm-context"
+# to be set to "single", because of ac's memory requirements, unless the
+# ruleset is small enough to fit in one's memory, in which case one can
+# use "full" with "ac".  Rest of the mpms can be run in "full" mode.
+#
+# There is also a CUDA pattern matcher (only available if Suricata was
+# compiled with --enable-cuda: b2g_cuda. Make sure to update your
+# max-pending-packets setting above as well if you use b2g_cuda.
+
+mpm-algo: auto
+
+# Select the matching algorithm you want to use for single-pattern searches.
+#
+# Supported algorithms are "bm" (Boyer-Moore) and "hs" (Hyperscan, only
+# available if Suricata has been built with Hyperscan support).
+#
+# The default of "auto" will use "hs" if available, otherwise "bm".
+
+spm-algo: auto
+
+# Suricata is multi-threaded. Here the threading can be influenced.
+threading:
+  set-cpu-affinity: no
+  # Tune cpu affinity of threads. Each family of threads can be bound
+  # on specific CPUs.
+  #
+  # These 2 apply to the all runmodes:
+  # management-cpu-set is used for flow timeout handling, counters
+  # worker-cpu-set is used for 'worker' threads
+  #
+  # Additionally, for autofp these apply:
+  # receive-cpu-set is used for capture threads
+  # verdict-cpu-set is used for IPS verdict threads
+  #
+  cpu-affinity:
+    - management-cpu-set:
+        cpu: [ 0 ]  # include only these cpus in affinity settings
+    - receive-cpu-set:
+        cpu: [ 0 ]  # include only these cpus in affinity settings
+    - worker-cpu-set:
+        cpu: [ "all" ]
+        mode: "exclusive"
+        # Use explicitely 3 threads and don't compute number by using
+        # detect-thread-ratio variable:
+        # threads: 3
+        prio:
+          low: [ 0 ]
+          medium: [ "1-2" ]
+          high: [ 3 ]
+          default: "medium"
+    #- verdict-cpu-set:
+    #    cpu: [ 0 ]
+    #    prio:
+    #      default: "high"
+  #
+  # By default Suricata creates one "detect" thread per available CPU/CPU core.
+  # This setting allows controlling this behaviour. A ratio setting of 2 will
+  # create 2 detect threads for each CPU/CPU core. So for a dual core CPU this
+  # will result in 4 detect threads. If values below 1 are used, less threads
+  # are created. So on a dual core CPU a setting of 0.5 results in 1 detect
+  # thread being created. Regardless of the setting at a minimum 1 detect
+  # thread will always be created.
+  #
+  detect-thread-ratio: 1.0
index 7c3ba91..4e61eb6 100644 (file)
@@ -33,6 +33,7 @@ use strict;
 require '/var/ipfire/general-functions.pl';    # replace /var/ipcop with /var/ipcop in case of manual install
 require "${General::swroot}/lang.pl";
 require "${General::swroot}/header.pl";
+require "${General::swroot}/ids-functions.pl";
 
 my $configfwdfw                = "${General::swroot}/firewall/config";
 my $configinput                = "${General::swroot}/firewall/input";
@@ -105,6 +106,9 @@ if ($settings{'ACTION'} eq $Lang::tr{'save'}) {
        
        # Rebuild configuration file if needed
        &BuildConfiguration;
+
+       # Handle suricata related actions.
+       &HandleSuricata();
     }
 
     ERROR:                                             # Leave the faulty field untouched
@@ -139,6 +143,9 @@ if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {
        
     # Rebuild configuration file
     &BuildConfiguration;
+
+    # Handle Suricata related actions.
+    &HandleSuricata();
 }
 
 if ($settings{'ACTION'} eq $Lang::tr{'add'}) {
@@ -220,6 +227,9 @@ if ($settings{'ACTION'} eq $Lang::tr{'add'}) {
        &SortDataFile;                          # sort newly added/modified entry
 
        &BuildConfiguration;                    # then re-build conf which use new data
+
+       # Handle Suricata related actions.
+       &HandleSuricata();
        
 ##
 ## if entering data line is repetitive, choose here to not erase fields between each addition
@@ -251,6 +261,9 @@ if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {
     &General::log($Lang::tr{'ip alias removed'});
 
     &BuildConfiguration;                               # then re-build conf which use new data
+
+    # Handle Suricata related actions.
+    &HandleSuricata();
 }
 
 
@@ -557,3 +570,16 @@ sub BuildConfiguration {
     system '/usr/local/bin/setaliases';
 }
 
+#
+## Handle Suricata related actions.
+#
+sub HandleSuricata() {
+       # Check if suricata is running.
+       if(&IDS::ids_is_running()) {
+               # Re-generate file which contains the HOME_NET declaration.
+               &IDS::generate_home_net_file();
+
+               # Call suricatactrl to perform a restart of suricata.
+               &IDS::call_suricatactrl("restart");
+       }
+}
index 5a3f4c3..98c6f57 100644 (file)
@@ -2,7 +2,7 @@
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2007-2015  IPFire Team  <info@ipfire.org>                     #
+# Copyright (C) 2007-2018  IPFire Team  <info@ipfire.org>                     #
 #                                                                             #
 # This program is free software: you can redistribute it and/or modify        #
 # it under the terms of the GNU General Public License as published by        #
@@ -24,390 +24,707 @@ use strict;
 # enable only the following on debugging purpose
 #use warnings;
 #use CGI::Carp 'fatalsToBrowser';
-use File::Copy;
 
 require '/var/ipfire/general-functions.pl';
 require "${General::swroot}/lang.pl";
 require "${General::swroot}/header.pl";
-
-sub refreshpage{&Header::openbox( 'Waiting', 1, "<meta http-equiv='refresh' content='1;'>" );print "<center><img src='/images/clock.gif' alt='' /><br/><font color='red'>$Lang::tr{'pagerefresh'}</font></center>";&Header::closebox();}
-
-$a = new CGI;
+require "${General::swroot}/ids-functions.pl";
 
 my %color = ();
 my %mainsettings = ();
+my %idsrules = ();
+my %idssettings=();
+my %rulessettings=();
+my %rulesetsources = ();
+my %cgiparams=();
+my %checked=();
+my %selected=();
+my %ignored=();
+
+# Read-in main settings, for language, theme and colors.
 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
 &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
 
-my %snortsettings=();
-my %checked=();
-my %selected=();
-my %netsettings=();
-our $errormessage = '';
-our $results = '';
-our $tempdir = '';
-our $url='';
-&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
+# Get the available network zones, based on the config type of the system and store
+# the list of zones in an array.
+my @network_zones = &IDS::get_available_network_zones();
+
+my $errormessage;
+
+# Create files if they does not exist yet.
+&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();
 
-$snortsettings{'ENABLE_SNORT'} = 'off';
-$snortsettings{'ENABLE_SNORT_GREEN'} = 'off';
-$snortsettings{'ENABLE_SNORT_BLUE'} = 'off';
-$snortsettings{'ENABLE_SNORT_ORANGE'} = 'off';
-$snortsettings{'ACTION'} = '';
-$snortsettings{'RULES'} = '';
-$snortsettings{'OINKCODE'} = '';
-$snortsettings{'INSTALLDATE'} = '';
-$snortsettings{'FILE'} = '';
-$snortsettings{'UPLOAD'} = '';
-
-&Header::getcgihash(\%snortsettings, {'wantfile' => 1, 'filevar' => 'FH'});
-
-####################### Added for snort rules control #################################
-my $snortrulepath; # change to "/etc/snort/rules" - maniac
-my @snortconfig;
-my $restartsnortrequired = 0;
-my %snortrules;
-my $rule = '';
-my $table1colour = '';
-my $table2colour = '';
-my $var = '';
-my $value = '';
-my $tmp = '';
-my $linkedrulefile = '';
-my $border = '';
-my $checkboxname = '';
-
-if (-e "/etc/snort/snort.conf") {
-
-
-       # Open snort.conf file, read it in, close it, and re-open for writing
-       open(FILE, "/etc/snort/snort.conf") or die 'Unable to read snort config file.';
-       @snortconfig = <FILE>;
-       close(FILE);
-       open(FILE, ">/etc/snort/snort.conf") or die 'Unable to write snort config file.';
-
-    my @rules = `cd /etc/snort/rules/ && ls *.rules 2>/dev/null`;    # With this loop the rule might be display with correct rulepath set
-       foreach (@rules) {
-       chomp $_;
-       my $temp = join(";",@snortconfig);
-    if ( $temp =~ /$_/ ){next;}
-    else { push(@snortconfig,"#include \$RULE_PATH/".$_);}
-       }
-
-       # Loop over each line
-       foreach my $line (@snortconfig) {
-               # Trim the line
-               chomp $line;
+#Get GUI values
+&Header::getcgihash(\%cgiparams);
 
-               # Check for a line with .rules
-               if ($line =~ /\.rules$/) {
-                       # Parse out rule file name
-                       $rule = $line;
-                       $rule =~ s/\$RULE_PATH\///i;
-                       $rule =~ s/ ?include ?//i;
-                       $rule =~ s/\#//i;
-                       my $snortrulepathrule = "$snortrulepath/$rule";
-
-                       # Open rule file and read in contents
-                       open(RULEFILE, "$snortrulepath/$rule") or die "Unable to read snort rule file for reading => $snortrulepath/$rule.";
-                       my @snortrulefile = <RULEFILE>;
-                       close(RULEFILE);
-                       open(RULEFILE, ">$snortrulepath/$rule") or die "Unable to write snort rule file for writing $snortrulepath/$rule";
+## Add/edit an entry to the ignore file.
+#
+if (($cgiparams{'WHITELIST'} eq $Lang::tr{'add'}) || ($cgiparams{'WHITELIST'} eq $Lang::tr{'update'})) {
 
-                       # Local vars
-                       my $dashlinecnt = 0;
-                       my $desclook = 1;
-                       my $snortruledesc = '';
-                       my %snortruledef = ();
-                       my $rulecnt = 1;
-
-                       # Loop over rule file contents
-                       foreach my $ruleline (@snortrulefile) {
-                               chomp $ruleline;
-
-                               # If still looking for a description
-                               if ($desclook) {
-                                       # If line does not start with a # anymore, then done looking for a description
-                                       if ($ruleline !~ /^\#/) {
-                                               $desclook = 0;
-                                       }
+       # Check if any input has been performed.
+       if ($cgiparams{'IGNORE_ENTRY_ADDRESS'} ne '') {
 
-                                       # If see more than one dashed line, (start to) create rule file description
-                                       if ($dashlinecnt > 1) {
-                                               # Check for a line starting with a #
-                                               if ($ruleline =~ /^\#/ and $ruleline !~ /^\#alert/) {
-                                                       # Create tempruleline
-                                                       my $tempruleline = $ruleline;
-
-                                                       # Strip off # and clean up line
-                                                       $tempruleline =~ s/\# ?//i;
-
-                                                       # Check for part of a description
-                                                       if ($snortruledesc eq '') {
-                                                               $snortruledesc = $tempruleline;
-                                                       } else {
-                                                               $snortruledesc .= " $tempruleline";
-                                                       }
-                                               } else {
-                                                       # Must be done
-                                                       $desclook = 0;
-                                               }
-                                       }
+               # Check if the given input is no valid IP-address or IP-address with subnet, display an error message.
+               if ((!&General::validip($cgiparams{'IGNORE_ENTRY_ADDRESS'})) && (!&General::validipandmask($cgiparams{'IGNORE_ENTRY_ADDRESS'}))) {
+                       $errormessage = "$Lang::tr{'guardian invalid address or subnet'}";
+               }
+       } else {
+               $errormessage = "$Lang::tr{'guardian empty input'}";
+       }
 
-                                       # If have a dashed line, increment count
-                                       if ($ruleline =~ /\# ?\-+/) {
-                                               $dashlinecnt++;
-                                       }
-                               } else {
-                                       # Parse out rule file rule's message for display
-                                       if ($ruleline =~ /(msg\:\"[^\"]+\";)/) {
-                                               my $msg = '';
-                                               $msg = $1;
-                                               $msg =~ s/msg\:\"//i;
-                                               $msg =~ s/\";//i;
-                                               $snortruledef{$rulecnt}{'Description'} = $msg;
-
-                                               # Check for 'Save' and rule file displayed in query string
-                                               if (($snortsettings{'ACTION'} eq $Lang::tr{'update'}) && ($ENV{'QUERY_STRING'} =~ /$rule/i)) {
-                                                       # Check for a disable rule which is now enabled, or an enabled rule which is now disabled
-                                                       if ((($ruleline =~ /^\#/) && (exists $snortsettings{"SNORT_RULE_$rule\_$rulecnt"})) || (($ruleline !~ /^\#/) && (!exists $snortsettings{"SNORT_RULE_$rule\_$rulecnt"}))) {
-                                                               $restartsnortrequired = 1;
-                                                       }
-
-                                                       # Strip out leading # from rule line
-                                                       $ruleline =~ s/\# ?//i;
-
-                                                       # Check if it does not exists (which means it is disabled), append a #
-                                                       if (!exists $snortsettings{"SNORT_RULE_$rule\_$rulecnt"}) {
-                                                               $ruleline = "#"." $ruleline";
-                                                       }
-                                               }
-
-                                               # Check if ruleline does not begin with a #, so it is enabled
-                                               if ($ruleline !~ /^\#/) {
-                                                       $snortruledef{$rulecnt++}{'State'} = 'Enabled';
-                                               } else {
-                                                       # Otherwise it is disabled
-                                                       $snortruledef{$rulecnt++}{'State'} = 'Disabled';
-                                               }
-                                       }
-                               }
+       # Go further if there was no error.
+       if ($errormessage eq '') {
+               my %ignored = ();
+               my $id;
+               my $status;
 
-                               # Print ruleline to RULEFILE
-                               print RULEFILE "$ruleline\n";
-                       }
+               # Assign hash values.
+               my $new_entry_address = $cgiparams{'IGNORE_ENTRY_ADDRESS'};
+               my $new_entry_remark = $cgiparams{'IGNORE_ENTRY_REMARK'};
 
-                       # Close RULEFILE
-                       close(RULEFILE);
+               # Read-in ignoredfile.
+               &General::readhasharray($IDS::ignored_file, \%ignored);
 
-                       # Check for 'Save'
-                       if ($snortsettings{'ACTION'} eq $Lang::tr{'update'}) {
-                               # Check for a disable rule which is now enabled, or an enabled rule which is now disabled
-                               if ((($line =~ /^\#/) && (exists $snortsettings{"SNORT_RULE_$rule"})) || (($line !~ /^\#/) && (!exists $snortsettings{"SNORT_RULE_$rule"}))) {
-                                       $restartsnortrequired = 1;
-                               }
+               # Check if we should edit an existing entry and got an ID.
+               if (($cgiparams{'WHITELIST'} eq $Lang::tr{'update'}) && ($cgiparams{'ID'})) {
+                       # Assin the provided id.
+                       $id = $cgiparams{'ID'};
 
-                               # Strip out leading # from rule line
-                               $line =~ s/\# ?//i;
+                       # Undef the given ID.
+                       undef($cgiparams{'ID'});
 
-                               # Check if it does not exists (which means it is disabled), append a #
-                               if (!exists $snortsettings{"SNORT_RULE_$rule"}) {
-                                       $line = "# $line";
-                               }
+                       # Grab the configured status of the corresponding entry.
+                       $status = $ignored{$id}[2];
+               } else {
+                       # Each newly added entry automatically should be enabled.
+                       $status = "enabled";
 
-                       }
+                       # Generate the ID for the new entry.
+                       #
+                       # Sort the keys by their ID and store them in an array.
+                       my @keys = sort { $a <=> $b } keys %ignored;
 
-                       # Check for rule state
-                       if ($line =~ /^\#/) {
-                               $snortrules{$rule}{"State"} = "Disabled";
-                       } else {
-                               $snortrules{$rule}{"State"} = "Enabled";
-                       }
+                       # Reverse the key array.
+                       my @reversed = reverse(@keys);
 
-                       # Set rule description
-                       $snortrules{$rule}{"Description"} = $snortruledesc;
+                       # Obtain the last used id.
+                       my $last_id = @reversed[0];
 
-                       # Loop over sorted rules
-                       foreach my $ruledef (sort {$a <=> $b} keys(%snortruledef)) {
-                               $snortrules{$rule}{"Definition"}{$ruledef}{'Description'} = $snortruledef{$ruledef}{'Description'};
-                               $snortrules{$rule}{"Definition"}{$ruledef}{'State'} = $snortruledef{$ruledef}{'State'};
-                       }
+                       # Increase the last id by one and use it as id for the new entry.
+                       $id = ++$last_id;
+               }
+
+               # Add/Modify the entry to/in the ignored hash.
+               $ignored{$id} = ["$new_entry_address", "$new_entry_remark", "$status"];
+
+               # Write the changed ignored hash to the ignored file.
+               &General::writehasharray($IDS::ignored_file, \%ignored);
+
+               # Regenerate the ignore file.
+               &IDS::generate_ignore_file();
+       }
 
-                       $snortruledesc = '';
-                       print FILE "$line\n";
-               } elsif ($line =~ /var RULE_PATH/) {
-                       ($tmp, $tmp, $snortrulepath) = split(' ', $line);
-                       print FILE "$line\n";
+       # Check if the IDS is running.
+       if(&IDS::ids_is_running()) {
+               # Call suricatactrl to perform a reload.
+               &IDS::call_suricatactrl("reload");
+       }
+
+## Toggle Enabled/Disabled for an existing entry on the ignore list.
+#
+
+} elsif ($cgiparams{'WHITELIST'} eq $Lang::tr{'toggle enable disable'}) {
+       my %ignored = ();
+
+       # Only go further, if an ID has been passed.
+       if ($cgiparams{'ID'}) {
+               # Assign the given ID.
+               my $id = $cgiparams{'ID'};
+
+               # Undef the given ID.
+               undef($cgiparams{'ID'});
+
+               # Read-in ignoredfile.
+               &General::readhasharray($IDS::ignored_file, \%ignored);
+
+               # Grab the configured status of the corresponding entry.
+               my $status = $ignored{$id}[2];
+
+               # Switch the status.
+               if ($status eq "disabled") {
+                       $status = "enabled";
                } else {
-                       print FILE "$line\n";
+                       $status = "disabled";
+               }
+
+               # Modify the status of the existing entry.
+               $ignored{$id} = ["$ignored{$id}[0]", "$ignored{$id}[1]", "$status"];
+
+               # Write the changed ignored hash to the ignored file.
+               &General::writehasharray($IDS::ignored_file, \%ignored);
+
+               # Regenerate the ignore file.
+               &IDS::generate_ignore_file();
+
+               # Check if the IDS is running.
+               if(&IDS::ids_is_running()) {
+                       # Call suricatactrl to perform a reload.
+                       &IDS::call_suricatactrl("reload");
                }
        }
-       close(FILE);
 
-       if ($restartsnortrequired) {
-               system('/usr/local/bin/snortctrl restart >/dev/null');
+## Remove entry from ignore list.
+#
+} elsif ($cgiparams{'WHITELIST'} eq $Lang::tr{'remove'}) {
+       my %ignored = ();
+
+       # Read-in ignoredfile.
+       &General::readhasharray($IDS::ignored_file, \%ignored);
+
+       # Drop entry from the hash.
+       delete($ignored{$cgiparams{'ID'}});
+
+       # Undef the given ID.
+       undef($cgiparams{'ID'});
+
+       # Write the changed ignored hash to the ignored file.
+       &General::writehasharray($IDS::ignored_file, \%ignored);
+
+       # Regenerate the ignore file.
+       &IDS::generate_ignore_file();
+
+       # Check if the IDS is running.
+       if(&IDS::ids_is_running()) {
+               # Call suricatactrl to perform a reload.
+               &IDS::call_suricatactrl("reload");
        }
 }
 
-#######################  End added for snort rules control  #################################
+# 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'}");
 
-if ($snortsettings{'OINKCODE'} ne "") {
-       $errormessage = $Lang::tr{'invalid input for oink code'} unless ($snortsettings{'OINKCODE'} =~ /^[a-z0-9]+$/);
+       # 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();
 }
 
-if (!$errormessage) {
-       if ($snortsettings{'RULES'} eq 'subscripted') {
-               $url=" https://www.snort.org/rules/snortrules-snapshot-29120.tar.gz?oinkcode=$snortsettings{'OINKCODE'}";
-       } elsif ($snortsettings{'RULES'} eq 'registered') {
-               $url=" https://www.snort.org/rules/snortrules-snapshot-29120.tar.gz?oinkcode=$snortsettings{'OINKCODE'}";
-       } elsif ($snortsettings{'RULES'} eq 'community') {
-               $url=" https://www.snort.org/rules/community";
-       } else {
-               $url="https://rules.emergingthreats.net/open/snort-2.9.0/emerging.rules.tar.gz";
+# Check if any error has been stored.
+if (-e $IDS::storederrorfile) {
+        # Open file to read in the stored error message.
+        open(FILE, "<$IDS::storederrorfile") or die "Could not open $IDS::storederrorfile. $!\n";
+
+        # Read the stored error message.
+        $errormessage = <FILE>;
+
+        # Close file.
+        close (FILE);
+
+        # Delete the file, which is now not longer required.
+        unlink($IDS::storederrorfile);
+}
+
+## Grab all available rules and store them in the idsrules hash.
+#
+# Open rules directory and do a directory listing.
+opendir(DIR, $IDS::rulespath) or die $!;
+       # Loop through the direcory.
+       while (my $file = readdir(DIR)) {
+
+               # We only want files.
+               next unless (-f "$IDS::rulespath/$file");
+
+               # Ignore empty files.
+               next if (-z "$IDS::rulespath/$file");
+
+               # Use a regular expression to find files ending in .rules
+               next unless ($file =~ m/\.rules$/);
+
+               # Ignore files which are not read-able.
+               next unless (-R "$IDS::rulespath/$file");
+
+               # Skip whitelist rules file.
+               next if( $file eq "whitelist.rules");
+
+               # Call subfunction to read-in rulefile and add rules to
+               # the idsrules hash.
+               &readrulesfile("$file");
        }
 
-       if ($snortsettings{'ACTION'} eq $Lang::tr{'save'} && $snortsettings{'ACTION2'} eq "snort" ) {
-               &General::writehash("${General::swroot}/snort/settings", \%snortsettings);
-               if ($snortsettings{'ENABLE_SNORT'} eq 'on')
-               {
-                       system ('/usr/bin/touch', "${General::swroot}/snort/enable");
-               } else {
-                       unlink "${General::swroot}/snort/enable";
-               }
-               if ($snortsettings{'ENABLE_SNORT_GREEN'} eq 'on')
-               {
-                       system ('/usr/bin/touch', "${General::swroot}/snort/enable_green");
-               } else {
-                       unlink "${General::swroot}/snort/enable_green";
-               }
-               if ($snortsettings{'ENABLE_SNORT_BLUE'} eq 'on')
-               {
-                       system ('/usr/bin/touch', "${General::swroot}/snort/enable_blue");
-               } else {
-                       unlink "${General::swroot}/snort/enable_blue";
+closedir(DIR);
+
+# Gather used rulefiles.
+#
+# Check if the file for activated rulefiles is not empty.
+if(-f $IDS::used_rulefiles_file) {
+       # Open the file for used rulefile and read-in content.
+       open(FILE, $IDS::used_rulefiles_file) or die "Could not open $IDS::used_rulefiles_file. $!\n";
+
+       # Read-in content.
+       my @lines = <FILE>;
+
+       # Close file.
+       close(FILE);
+
+       # Loop through the array.
+       foreach my $line (@lines) {
+               # Remove newlines.
+               chomp($line);
+
+               # Skip comments.
+               next if ($line =~ /\#/);
+
+               # Skip blank  lines.
+               next if ($line =~ /^\s*$/);
+
+               # Gather rule sid and message from the ruleline.
+               if ($line =~ /.*- (.*)/) {
+                       my $rulefile = $1;
+
+                       # Check if the current rulefile exists in the %idsrules hash.
+                       # If not, the file probably does not exist anymore or contains
+                       # no rules.
+                       if($idsrules{$rulefile}) {
+                               # Add the rulefile state to the %idsrules hash.
+                               $idsrules{$rulefile}{'Rulefile'}{'State'} = "on";
+                       }
                }
-               if ($snortsettings{'ENABLE_SNORT_ORANGE'} eq 'on')
-               {
-                       system ('/usr/bin/touch', "${General::swroot}/snort/enable_orange");
+       }
+}
+
+# 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 =~ /\<oinkcode\>/ ) {
+               # 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 {
-                       unlink "${General::swroot}/snort/enable_orange";
+                       # Print an error message, that an subsription/oinkcode is required for this
+                       # vendor.
+                       $errormessage = $Lang::tr{'ids oinkcode required'};
                }
-               if ($snortsettings{'ENABLE_PREPROCESSOR_HTTP_INSPECT'} eq 'on')
-               {
-                       system ('/usr/bin/touch', "${General::swroot}/snort/enable_preprocessor_http_inspect");
-               } else {
-                       unlink "${General::swroot}/snort/enable_preprocessor_http_inspect";
+       }
+
+       # 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'});
                }
 
-               system('/usr/local/bin/snortctrl restart >/dev/null');
-       }
+               # 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'}";
+                       }
 
-       # INSTALLMD5 is not in the form, so not retrieved by getcgihash
-       &General::readhash("${General::swroot}/snort/settings", \%snortsettings);
+                       # Check if any errors happend.
+                       unless ($errormessage) {
+                               # Lock the webpage and print notice about downloading
+                               # a new ruleset.
+                               &working_notice("$Lang::tr{'ids working'}");
 
-       if ($snortsettings{'ACTION'} eq $Lang::tr{'download new ruleset'} || $snortsettings{'ACTION'} eq $Lang::tr{'upload new ruleset'}) {
-               my @df = `/bin/df -B M /var`;
-               foreach my $line (@df) {
-                       next if $line =~ m/^Filesystem/;
-                       my $return;
+                               # Call subfunction to download the ruleset.
+                               if(&IDS::downloadruleset()) {
+                                       $errormessage = $Lang::tr{'could not download latest updates'};
 
-                       if ($line =~ m/dev/ ) {
-                               $line =~ m/^.* (\d+)M.*$/;
-                               my @temp = split(/ +/,$line);
-                               if ($1<300) {
-                                       $errormessage = "$Lang::tr{'not enough disk space'} < 300MB, /var $1MB";
+                                       # Call function to store the errormessage.
+                                       &IDS::_store_error_message($errormessage);
                                } else {
-                                       if ( $snortsettings{'ACTION'} eq $Lang::tr{'download new ruleset'}) {
-                                               &downloadrulesfile();
-                                               sleep(3);
-                                               $return = `cat /var/tmp/log 2>/dev/null`;
-
-                                       } elsif ( $snortsettings{'ACTION'} eq $Lang::tr{'upload new ruleset'}) {
-                                               my $upload = $a->param("UPLOAD");
-                                               open UPLOADFILE, ">/var/tmp/snortrules.tar.gz";
-                                               binmode $upload;
-                                               while ( <$upload> ) {
-                                                       print UPLOADFILE;
-                                               }
-                                               close UPLOADFILE;
-                                       }
+                                       # Call subfunction to launch oinkmaster.
+                                       &IDS::oinkmaster();
+                               }
 
-                                       if ($return =~ "ERROR") {
-                                               $errormessage = "<br /><pre>".$return."</pre>";
-                                       } else {
-                                               system("/usr/local/bin/oinkmaster.pl -v -s -u file:///var/tmp/snortrules.tar.gz -C /var/ipfire/snort/oinkmaster.conf -o /etc/snort/rules >>/var/tmp/log 2>&1 &");
-                                               sleep(2);
+                               # 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.
+} elsif ($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;
+
+       # Loop through the hash of idsrules.
+       foreach my $rulefile(keys %idsrules) {
+               # Check if the rulefile is enabled.
+               if ($cgiparams{$rulefile} eq "on") {
+                       # Add rulefile to the array of enabled rulefiles.
+                       push(@enabled_rulefiles, $rulefile);
+
+                       # Drop item from cgiparams hash.
+                       delete $cgiparams{$rulefile};
+               }
+       }
+
+       # 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));
+
+       # 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+/ );
+
+                       # 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};
+                               }
+                       }
+               }
+       }
+
+       # 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);
+
+       # 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{'ids apply ruleset changes'}");
+
+       # Call oinkmaster to alter the ruleset.
+       &IDS::oinkmaster();
+
+       # Check if the IDS is running.
+       if(&IDS::ids_is_running()) {
+               # Call suricatactrl to perform a reload.
+               &IDS::call_suricatactrl("reload");
+       }
+
+       # Reload page.
+       &reload();
+
+# 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'} - $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 download new ruleset'}");
+
+               # 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);
+
+                       # Preform a reload of the page.
+                       &reload();
+               } else {
+                       # Call subfunction to launch oinkmaster.
+                       &IDS::oinkmaster();
+
+                       # Check if the IDS is running.
+                       if(&IDS::ids_is_running()) {
+                               # Call suricatactrl to perform a reload.
+                               &IDS::call_suricatactrl("reload");
                        }
+
+                       # Perform a reload of the page.
+                       &reload();
                }
        }
+# 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::ids_settings_file", \%oldidssettings);
+
+       # Prevent form name from been stored in conf file.
+       delete $cgiparams{'IDS'};
+
+       # 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::ids_settings_file", \%cgiparams);
+       }
+
+       # Generate file to store the home net.
+       &IDS::generate_home_net_file();
+
+       # Temporary variable to set the ruleaction.
+       # Default is "drop" to use suricata as IPS.
+       my $ruleaction="drop";
+
+       # 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";
+       }
+
+       # 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{'ids working'}");
+
+                       # Call oinkmaster to alter the ruleset.
+                       &IDS::oinkmaster();
+
+                       # Set reload_page to "True".
+                       $reload_page="True";
+               }
+       }
+
+       # Check if the IDS currently is running.
+       if(&IDS::ids_is_running()) {
+               # Check if ENABLE_IDS is set to on.
+               if($cgiparams{'ENABLE_IDS'} eq "on") {
+                       # Call suricatactrl to perform a reload of suricata.
+                       &IDS::call_suricatactrl("reload");
+               } else {
+                       # Call suricatactrl to stop suricata.
+                       &IDS::call_suricatactrl("stop");
+               }
+       } else {
+               # Call suricatactrl to start suricata.
+               &IDS::call_suricatactrl("start");
+       }
+
+       # Check if the page should be reloaded.
+       if ($reload_page) {
+               # Perform a reload of the page.
+               &reload();
+       }
+}
+
+# Read-in idssettings and rulesetsettings
+&General::readhash("$IDS::ids_settings_file", \%idssettings);
+&General::readhash("$IDS::rules_settings_file", \%rulessettings);
+
+# If no autoupdate intervall has been configured yet, set default value.
+unless(exists($rulessettings{'AUTOUPDATE_INTERVAL'})) {
+       # Set default to "weekly".
+       $rulessettings{'AUTOUPDATE_INTERVAL'} = 'weekly';
 }
 
-$checked{'ENABLE_SNORT'}{'off'} = '';
-$checked{'ENABLE_SNORT'}{'on'} = '';
-$checked{'ENABLE_SNORT'}{$snortsettings{'ENABLE_SNORT'}} = "checked='checked'";
-$checked{'ENABLE_SNORT_GREEN'}{'off'} = '';
-$checked{'ENABLE_SNORT_GREEN'}{'on'} = '';
-$checked{'ENABLE_SNORT_GREEN'}{$snortsettings{'ENABLE_SNORT_GREEN'}} = "checked='checked'";
-$checked{'ENABLE_SNORT_BLUE'}{'off'} = '';
-$checked{'ENABLE_SNORT_BLUE'}{'on'} = '';
-$checked{'ENABLE_SNORT_BLUE'}{$snortsettings{'ENABLE_SNORT_BLUE'}} = "checked='checked'";
-$checked{'ENABLE_SNORT_ORANGE'}{'off'} = '';
-$checked{'ENABLE_SNORT_ORANGE'}{'on'} = '';
-$checked{'ENABLE_SNORT_ORANGE'}{$snortsettings{'ENABLE_SNORT_ORANGE'}} = "checked='checked'";
+# Read-in ignored hosts.
+&General::readhasharray("$IDS::settingsdir/ignored", \%ignored);
+
+$checked{'ENABLE_IDS'}{'off'} = '';
+$checked{'ENABLE_IDS'}{'on'} = '';
+$checked{'ENABLE_IDS'}{$idssettings{'ENABLE_IDS'}} = "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'}{$snortsettings{'RULES'}} = "selected='selected'";
+$selected{'RULES'}{$rulessettings{'RULES'}} = "selected='selected'";
+$selected{'AUTOUPDATE_INTERVAL'}{'off'} = '';
+$selected{'AUTOUPDATE_INTERVAL'}{'daily'} = '';
+$selected{'AUTOUPDATE_INTERVAL'}{'weekly'} = '';
+$selected{'AUTOUPDATE_INTERVAL'}{$rulessettings{'AUTOUPDATE_INTERVAL'}} = "selected='selected'";
 
 &Header::openpage($Lang::tr{'intrusion detection system'}, 1, '');
 
-####################### Added for snort rules control #################################
-print "<script type='text/javascript' src='/include/snortupdateutility.js'></script>";
+### Java Script ###
+print"<script>\n";
+
+# Java script variable declaration for show and hide.
+print"var show = \"$Lang::tr{'ids show'}\"\;\n";
+print"var hide = \"$Lang::tr{'ids hide'}\"\;\n";
+
 print <<END
-<style type="text/css">
-<!--
-.section {
-       border: groove;
-}
-.row1color {
-       border: ridge;
-       background-color: $color{'color22'};
-}
-.row2color {
-       border: ridge;
-       background-color: $color{'color20'};
-}
-.rowselected {
-       border: double #FF0000;
-       background-color: #DCDCDC;
-}
--->
-</style>
+       // JQuery function to show/hide the text input field for
+       // Oinkcode/Subscription code.
+       \$(function() {
+               \$('#RULES').change(function(){
+                       if(\$('#RULES').val() == 'registered') {
+                               \$('#code').show();
+                       } else if(\$('#RULES').val() == 'subscripted') {
+                               \$('#code').show();
+                       } else if(\$('#RULES').val() == 'emerging_pro') {
+                               \$('#code').show();
+                       } else {
+                               \$('#code').hide();
+                       }
+               });
+       });
+
+       // Tiny java script function to show/hide the rules
+       // of a given category.
+       function showhide(tblname) {
+               \$("#" + tblname).toggle();
+
+               // Get current content of the span element.
+               var content = document.getElementById("span_" + tblname);
+
+               if (content.innerHTML === show) {
+                       content.innerHTML = hide;
+               } else {
+                       content.innerHTML = show;
+               }
+       }
+</script>
 END
 ;
-#######################  End added for snort rules control  #################################
 
 &Header::openbigbox('100%', 'left', '', $errormessage);
 
-###############
-# DEBUG DEBUG
-# &Header::openbox('100%', 'left', 'DEBUG');
-# my $debugCount = 0;
-# foreach my $line (sort keys %snortsettings) {
-# print "$line = $snortsettings{$line}<br />\n";
-# $debugCount++;
-# }
-# print "&nbsp;Count: $debugCount\n";
-# &Header::closebox();
-# DEBUG DEBUG
-###############
-
 if ($errormessage) {
        &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
        print "<class name='base'>$errormessage\n";
@@ -415,252 +732,441 @@ if ($errormessage) {
        &Header::closebox();
 }
 
-my $return = `pidof oinkmaster.pl -x`;
-chomp($return);
-if ($return) {
-       &Header::openbox( 'Waiting', 1, "<meta http-equiv='refresh' content='10;'>" );
+# Draw current state of the IDS
+&Header::openbox('100%', 'left', $Lang::tr{'intrusion detection system'});
+
+# Check if the IDS is running and obtain the process-id.
+my $pid = &IDS::ids_is_running();
+
+# Display some useful information, if suricata daemon is running.
+if ($pid) {
+       # Gather used memory.
+       my $memory = &get_memory_usage($pid);
+
        print <<END;
-       <table>
-               <tr><td>
-                               <img src='/images/indicator.gif' alt='$Lang::tr{'aktiv'}' />&nbsp;
-                       <td>
-                               $Lang::tr{'snort working'}
-               <tr><td colspan='2' align='center'>
-                       <form method='post' action='$ENV{'SCRIPT_NAME'}'>
-                               <input type='image' alt='$Lang::tr{'reload'}' title='$Lang::tr{'reload'}' src='/images/view-refresh.png' />
-                       </form>
-               <tr><td colspan='2' align='left'><pre>
+               <table width='95%' cellspacing='0' class='tbl'>
+                       <tr>
+                               <th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'intrusion detection'}</strong></th>
+                       </tr>
+
+                       <tr>
+                               <td class='base'>$Lang::tr{'guardian daemon'}</td>
+                               <td align='center' colspan='2' width='75%' bgcolor='${Header::colourgreen}'><font color='white'><strong>$Lang::tr{'running'}</strong></font></td>
+                       </tr>
+
+                       <tr>
+                               <td class='base'></td>
+                               <td bgcolor='$color{'color20'}' align='center'><strong>PID</strong></td>
+                               <td bgcolor='$color{'color20'}' align='center'><strong>$Lang::tr{'memory'}</strong></td>
+                       </tr>
+
+                       <tr>
+                               <td class='base'></td>
+                               <td bgcolor='$color{'color22'}' align='center'>$pid</td>
+                               <td bgcolor='$color{'color22'}' align='center'>$memory KB</td>
+                       </tr>
+               </table>
 END
-       my @output = `tail -20 /var/tmp/log`;
-       foreach (@output) {
-               print "$_";
-       }
+} else {
+       # Otherwise display a hint that the service is not launched.
        print <<END;
-                       </pre>
+               <table width='95%' cellspacing='0' class='tbl'>
+                       <tr>
+                               <th bgcolor='$color{'color20'}' colspan='3' align='left'><strong>$Lang::tr{'intrusion detection'}</strong></th>
+                       </tr>
+
+                       <tr>
+                               <td class='base'>$Lang::tr{'guardian daemon'}</td>
+                               <td align='center' width='75%' bgcolor='${Header::colourred}'><font color='white'><strong>$Lang::tr{'stopped'}</strong></font></td>
+                       </tr>
                </table>
 END
-       &Header::closebox();
-       &Header::closebigbox();
-       &Header::closepage();
-       exit;
-       refreshpage();
 }
 
-&Header::openbox('100%', 'left', $Lang::tr{'intrusion detection system'});
+# Only show this area, if a ruleset is present.
+if (%idsrules) {
+
+       print <<END
+
+       <br><br><h2>$Lang::tr{'settings'}</h2>
+
+       <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+               <table width='100%' border='0'>
+                       <tr>
+                               <td class='base' colspan='2'>
+                                       <input type='checkbox' name='ENABLE_IDS' $checked{'ENABLE_IDS'}{'on'}>&nbsp;$Lang::tr{'ids enable'}
+                               </td>
+
+                               <td class='base' colspan='2'>
+                                       <input type='checkbox' name='MONITOR_TRAFFIC_ONLY' $checked{'MONITOR_TRAFFIC_ONLY'}{'on'}>&nbsp;$Lang::tr{'ids monitor traffic only'}
+                       </td>
+                       </tr>
+
+                       <tr>
+                               <td><br><br></td>
+                               <td><br><br></td>
+                               <td><br><br></td>
+                               <td><br><br></td>
+                       </tr>
+
+                       <tr>
+                               <td colspan='4'><b>$Lang::tr{'ids monitored interfaces'}</b><br></td>
+                       </tr>
+
+                       <tr>
+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);
+
+               # Set zone name.
+               my $zone_name = $zone;
+
+               # Dirty hack to get the correct language string for the red zone.
+               if ($zone eq "red") {
+                       $zone_name = "red1";
+               }
+
+               # Grab checkbox status from settings hash.
+               if ($idssettings{"ENABLE_IDS_$zone_upper"} eq "on") {
+                       $checked_input = "checked = 'checked'";
+               }
+
+               print "<td class='base' width='25%'>\n";
+               print "<input type='checkbox' name='ENABLE_IDS_$zone_upper' $checked_input>\n";
+               print "&nbsp;$Lang::tr{'enabled on'}<font color='$colourhash{$zone}'> $Lang::tr{$zone_name}</font>\n";
+               print "</td>\n";
+       }
+
 print <<END
-<form method='post' action='$ENV{'SCRIPT_NAME'}'><table width='100%'>
-<tr><td class='base'><input type='checkbox' name='ENABLE_SNORT_GREEN' $checked{'ENABLE_SNORT_GREEN'}{'on'} />GREEN Snort
+                       </tr>
+               </table>
+
+               <br><br>
+
+               <table width='100%'>
+                       <tr>
+                               <td align='right'><input type='submit' name='IDS' value='$Lang::tr{'save'}' /></td>
+                       </tr>
+               </table>
+       </form>
 END
 ;
-if ($netsettings{'BLUE_DEV'} ne '') {
-  print "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='checkbox' name='ENABLE_SNORT_BLUE' $checked{'ENABLE_SNORT_BLUE'}{'on'} />   BLUE Snort";
-}
-if ($netsettings{'ORANGE_DEV'} ne '') {
-  print "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='checkbox' name='ENABLE_SNORT_ORANGE' $checked{'ENABLE_SNORT_ORANGE'}{'on'} />   ORANGE Snort";
+
 }
-  print "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type='checkbox' name='ENABLE_SNORT' $checked{'ENABLE_SNORT'}{'on'} />   RED Snort";
+
+&Header::closebox();
+
+# Draw elements for ruleset configuration.
+&Header::openbox('100%', 'center', $Lang::tr{'ids ruleset settings'});
 
 print <<END
-</td></tr>
-<tr>
-       <td><br><br></td>
-</tr>
-<tr>
-       <td><b>$Lang::tr{'ids rules update'}</b></td>
-</tr>
-<tr>
-       <td><select name='RULES'>
-                               <option value='nothing' $selected{'RULES'}{'nothing'} >$Lang::tr{'no'}</option>
+<form method='post' action='$ENV{'SCRIPT_NAME'}'>
+        <table width='100%' border='0'>
+               <tr>
+                       <td><b>$Lang::tr{'ids rules update'}</b></td>
+                       <td><b>$Lang::tr{'ids automatic rules update'}</b></td>
+               </tr>
+
+               <tr>
+                       <td><select name='RULES' id='RULES'>
                                <option value='emerging' $selected{'RULES'}{'emerging'} >$Lang::tr{'emerging rules'}</option>
+                               <option value='emerging_pro' $selected{'RULES'}{'emerging_pro'} >$Lang::tr{'emerging pro rules'}</option>
                                <option value='community' $selected{'RULES'}{'community'} >$Lang::tr{'community rules'}</option>
                                <option value='registered' $selected{'RULES'}{'registered'} >$Lang::tr{'registered user rules'}</option>
                                <option value='subscripted' $selected{'RULES'}{'subscripted'} >$Lang::tr{'subscripted user rules'}</option>
                        </select>
-       </td>
-</tr>
-<tr>
-       <td><br />
-               $Lang::tr{'ids rules license'} <a href='https://www.snort.org/subscribe' target='_blank'>www.snort.org</a>$Lang::tr{'ids rules license1'}<br /><br />
-               $Lang::tr{'ids rules license2'} <a href='https://www.snort.org/account/oinkcode' target='_blank'>Get an Oinkcode</a>, $Lang::tr{'ids rules license3'}
-       </td>
-</tr>
-<tr>
-       <td nowrap='nowrap'>Oinkcode:&nbsp;<input type='text' size='40' name='OINKCODE' value='$snortsettings{'OINKCODE'}' /></td>
-</tr>
-<tr>
-       <td width='30%' align='left'><br><input type='submit' name='ACTION' value='$Lang::tr{'download new ruleset'}' />
+                       </td>
+
+                       <td>
+                               <select name='AUTOUPDATE_INTERVAL'>
+                                       <option value='off' $selected{'AUTOUPDATE_INTERVAL'}{'off'} >- $Lang::tr{'Disabled'} -</option>
+                                       <option value='daily' $selected{'AUTOUPDATE_INTERVAL'}{'daily'} >$Lang::tr{'Daily'}</option>
+                                       <option value='weekly' $selected{'AUTOUPDATE_INTERVAL'}{'weekly'} >$Lang::tr{'Weekly'}</option>
+                               </select>
+                       </td>
+               </tr>
+
+               <tr>
+                       <td colspan='2'><br><br></td>
+               </tr>
+
+               <tr style='display:none' id='code'>
+                       <td colspan='2'>Oinkcode:&nbsp;<input type='text' size='40' name='OINKCODE' value='$rulessettings{'OINKCODE'}'></td>
+               </tr>
+
+               <tr>
+                       <td>&nbsp;</td>
+
+                       <td align='right'>
 END
 ;
-if ( -e "/var/tmp/snortrules.tar.gz"){
-       my @Info = stat("/var/tmp/snortrules.tar.gz");
-       $snortsettings{'INSTALLDATE'} = localtime($Info[9]);
-}
-print "&nbsp;$Lang::tr{'updates installed'}: $snortsettings{'INSTALLDATE'}</td>";
+                       # 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"<input type='submit' name='RULESET' value='$Lang::tr{'update ruleset'}'>\n";
+               }
+print <<END;
+                               <input type='submit' name='RULESET' value='$Lang::tr{'save'}'>
+                       </td>
 
-print <<END
-</tr>
-</table>
-<br><br>
-<table width='100%'>
-<tr>
-       <td align='right'><input type='hidden' name='ACTION2' value='snort' /><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>
-</tr>
-</table>
+               </tr>
+       </table>
 </form>
 END
 ;
 
-if ($results ne '') {
-       print "$results";
-}
+&Header::closebox();
+
+#
+# Whitelist / Ignorelist
+#
+&Header::openbox('100%', 'center', $Lang::tr{'ids ignored hosts'});
+
+print <<END;
+       <table width='100%'>
+               <tr>
+                       <td class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'ip address'}</b></td>
+                       <td class='base' bgcolor='$color{'color20'}'><b>$Lang::tr{'remark'}</b></td>
+                       <td class='base' colspan='3' bgcolor='$color{'color20'}'></td>
+               </tr>
+END
+               # Check if some hosts have been added to be ignored.
+               if (keys (%ignored)) {
+                       my $col = "";
+
+                       # Loop through all entries of the hash.
+                       while( (my $key) = each %ignored)  {
+                               # Assign data array positions to some nice variable names.
+                               my $address = $ignored{$key}[0];
+                               my $remark = $ignored{$key}[1];
+                               my $status  = $ignored{$key}[2];
+
+                               # Check if the key (id) number is even or not.
+                               if ($cgiparams{'ID'} eq $key) {
+                                       $col="bgcolor='${Header::colouryellow}'";
+                               } elsif ($key % 2) {
+                                       $col="bgcolor='$color{'color22'}'";
+                               } else {
+                                       $col="bgcolor='$color{'color20'}'";
+                               }
+
+                               # Choose icon for the checkbox.
+                               my $gif;
+                               my $gdesc;
+
+                               # Check if the status is enabled and select the correct image and description.
+                               if ($status eq 'enabled' ) {
+                                       $gif = 'on.gif';
+                                       $gdesc = $Lang::tr{'click to disable'};
+                               } else {
+                                       $gif = 'off.gif';
+                                       $gdesc = $Lang::tr{'click to enable'};
+                               }
+
+print <<END;
+                               <tr>
+                                       <td width='20%' class='base' $col>$address</td>
+                                       <td width='65%' class='base' $col>$remark</td>
+
+                                       <td align='center' $col>
+                                               <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+                                                       <input type='hidden' name='WHITELIST' value='$Lang::tr{'toggle enable disable'}' />
+                                                       <input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc' />
+                                                       <input type='hidden' name='ID' value='$key' />
+                                               </form>
+                                       </td>
+
+                                       <td align='center' $col>
+                                               <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+                                                       <input type='hidden' name='WHITELIST' value='$Lang::tr{'edit'}' />
+                                                       <input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />
+                                                       <input type='hidden' name='ID' value='$key' />
+                                               </form>
+                                       </td>
+
+                                       <td align='center' $col>
+                                               <form method='post' name='$key' action='$ENV{'SCRIPT_NAME'}'>
+                                                       <input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' title='$Lang::tr{'remove'}' alt='$Lang::tr{'remove'}'>
+                                                       <input type='hidden' name='ID' value='$key'>
+                                                       <input type='hidden' name='WHITELIST' value='$Lang::tr{'remove'}'>
+                                               </form>
+                                       </td>
+                               </tr>
+END
+                       }
+               } else {
+                       # Print notice that currently no hosts are ignored.
+                       print "<tr>\n";
+                       print "<td class='base' colspan='2'>$Lang::tr{'guardian no entries'}</td>\n";
+                       print "</tr>\n";
+               }
+
+       print "</table>\n";
+
+       # Section to add new elements or edit existing ones.
+print <<END;
+       <br>
+       <hr>
+       <br>
+
+       <div align='center'>
+               <table width='100%'>
+END
+
+       # Assign correct headline and button text.
+       my $buttontext;
+       my $entry_address;
+       my $entry_remark;
+
+       # Check if an ID (key) has been given, in this case an existing entry should be edited.
+       if ($cgiparams{'ID'} ne '') {
+               $buttontext = $Lang::tr{'update'};
+                       print "<tr><td class='boldbase' colspan='3'><b>$Lang::tr{'update'}</b></td></tr>\n";
+
+                       # Grab address and remark for the given key.
+                       $entry_address = $ignored{$cgiparams{'ID'}}[0];
+                       $entry_remark = $ignored{$cgiparams{'ID'}}[1];
+               } else {
+                       $buttontext = $Lang::tr{'add'};
+                       print "<tr><td class='boldbase' colspan='3'><b>$Lang::tr{'dnsforward add a new entry'}</b></td></tr>\n";
+               }
+
+print <<END;
+                       <form method='post' action='$ENV{'SCRIPT_NAME'}'>
+                       <input type='hidden' name='ID' value='$cgiparams{'ID'}'>
+                       <tr>
+                               <td width='30%'>$Lang::tr{'ip address'}: </td>
+                               <td width='50%'><input type='text' name='IGNORE_ENTRY_ADDRESS' value='$entry_address' size='24' /></td>
+
+                               <td width='30%'>$Lang::tr{'remark'}: </td>
+                               <td wicth='50%'><input type='text' name=IGNORE_ENTRY_REMARK value='$entry_remark' size='24' /></td>
+                               <td align='center' width='20%'><input type='submit' name='WHITELIST' value='$buttontext' /></td>
+                       </tr>
+                       </form>
+               </table>
+       </div>
+END
 
 &Header::closebox();
 
-####################### Added for snort rules control #################################
-if ( -e "${General::swroot}/snort/enable" || -e "${General::swroot}/snort/enable_green" || -e "${General::swroot}/snort/enable_blue" || -e "${General::swroot}/snort/enable_orange" ) {
-       &Header::openbox('100%', 'LEFT', $Lang::tr{'intrusion detection system rules'});
-               # Output display table for rule files
-               print "<table width='100%'><tr><td valign='top'><table>";
+# Only show the section for configuring the ruleset if one is present.
+if (%idsrules) {
+       # Load neccessary perl modules for file stat and to format the timestamp.
+       use File::stat;
+       use POSIX qw( strftime );
 
-               print "<form method='post'>";
+       # Call stat on the rulestarball.
+       my $stat = stat("$IDS::rulestarball");
 
-               # Local vars
-               my $ruledisplaycnt = 1;
-               my $rulecnt = keys %snortrules;
-               $rulecnt++;
-               $rulecnt = $rulecnt / 2;
+       # Get timestamp the file creation.
+       my $mtime = $stat->mtime;
 
-               # Loop over each rule file
-               foreach my $rulefile (sort keys(%snortrules)) {
-                       my $rulechecked = '';
+       # Convert into human read-able format.
+       my $rulesdate = strftime('%Y-%m-%d %H:%M:%S', localtime($mtime));
 
-                       # Hide inkompatible Block rules
-                       if ($rulefile =~'-BLOCK.rules') {
-                               next;
-                       }
+       &Header::openbox('100%', 'LEFT', "$Lang::tr{'intrusion detection system rules'} ($rulesdate)" );
 
-                       # Check if reached half-way through rule file rules to start new column
-               if ($ruledisplaycnt > $rulecnt) {
-                               print "</table></td><td valign='top'><table>";
-                               $ruledisplaycnt = 0;
-                       }
+               print"<form method='POST' action='$ENV{'SCRIPT_NAME'}'>\n";
+
+               # Output display table for rule files
+               print "<table width='100%'>\n";
+
+               # Loop over each rule file
+               foreach my $rulefile (sort keys(%idsrules)) {
+                       my $rulechecked = '';
 
                        # Check if rule file is enabled
-                       if ($snortrules{$rulefile}{"State"} eq 'Enabled') {
+                       if ($idsrules{$rulefile}{'Rulefile'}{'State'} eq 'on') {
                                $rulechecked = 'CHECKED';
                        }
 
-                       # Create rule file link, vars array, and display flag
-                       my $rulefilelink = "?RULEFILE=$rulefile";
-                       my $rulefiletoclose = '';
-                       my @queryvars = ();
-                       my $displayrulefilerules = 0;
-
-                       # Check for passed in query string
-                       if ($ENV{'QUERY_STRING'}) {
-                               # Split out vars
-                               @queryvars = split(/\&/, $ENV{'QUERY_STRING'});
-
-                               # Loop over values
-                               foreach $value (@queryvars) {
-                                       # Split out var pairs
-                                       ($var, $linkedrulefile) = split(/=/, $value);
-
-                                       # Check if var is 'RULEFILE'
-                                       if ($var eq 'RULEFILE') {
-                                               # Check if rulefile equals linkedrulefile
-                                               if ($rulefile eq $linkedrulefile) {
-                                                       # Set display flag
-                                                       $displayrulefilerules = 1;
-
-                                                       # Strip out rulefile from rulefilelink
-                                                       $rulefilelink =~ s/RULEFILE=$linkedrulefile//g;
-                                               } else {
-                                                       # Add linked rule file to rulefilelink
-                                                       $rulefilelink .= "&RULEFILE=$linkedrulefile";
-                                               }
-                                       }
-                               }
-                       }
+                       # Convert rulefile name into category name.
+                       my $categoryname = &_rulefile_to_category($rulefile);
 
-                       # Strip out extra & & ? from rulefilelink
-                       $rulefilelink =~ s/^\?\&/\?/i;
+                       # Table and rows for the rule files.
+                       print"<tr>\n";
+                       print"<td class='base' width='5%'>\n";
+                       print"<input type='checkbox' name='$rulefile' $rulechecked>\n";
+                       print"</td>\n";
+                       print"<td class='base' width='90%'><b>$rulefile</b></td>\n";
+                       print"<td class='base' width='5%' align='right'>\n";
+                       print"<a href=\"javascript:showhide('$categoryname')\"><span id='span_$categoryname'>$Lang::tr{'ids show'}</span></a>\n";
+                       print"</td>\n";
+                       print"</tr>\n";
 
-                       # Check for a single '?' and replace with page for proper link display
-                       if ($rulefilelink eq '?') {
-                               $rulefilelink = "ids.cgi";
-                       }
-
-                       # Output rule file name and checkbox
-                       print "<tr><td class='base' valign='top'><input type='checkbox' NAME='SNORT_RULE_$rulefile' $rulechecked> <a href='$rulefilelink'>$rulefile</a></td></tr>";
-                       print "<tr><td class='base' valign='top'>";
+                       # Rows which will be hidden per default and will contain the single rules.
+                       print"<tr  style='display:none' id='$categoryname'>\n";
+                       print"<td colspan='3'>\n";
 
-                       # Check for empty 'Description'
-                       if ($snortrules{$rulefile}{'Description'} eq '') {
-                               print "<table width='100%'><tr><td class='base'>No description available</td></tr>";
-                       } else {
-                               # Output rule file 'Description'
-                               print "<table width='100%'><tr><td class='base'>$snortrules{$rulefile}{'Description'}</td></tr>";
-                       }
+                       # Local vars
+                       my $lines;
+                       my $rows;
+                       my $col;
 
-                       # Check for display flag
-                       if ($displayrulefilerules) {
-                               # Rule file definition rule display
-                               print "<tr><td class='base' valign='top'><table border='0'><tr>";
+                       # New table for the single rules.
+                       print "<table width='100%'>\n";
 
+                       # Loop over rule file rules
+                       foreach my $sid (sort {$a <=> $b} keys(%{$idsrules{$rulefile}})) {
                                # Local vars
-                               my $ruledefdisplaycnt = 0;
-                               my $ruledefcnt = keys %{$snortrules{$rulefile}{"Definition"}};
-                               $ruledefcnt++;
-                               $ruledefcnt = $ruledefcnt / 2;
-
-                               # Loop over rule file rules
-                               foreach my $ruledef (sort {$a <=> $b} keys(%{$snortrules{$rulefile}{"Definition"}})) {
-                                       # Local vars
-                                       my $ruledefchecked = '';
-
-                                       # If have display 2 rules, start new row
-                                       if (($ruledefdisplaycnt % 2) == 0) {
-                                               print "</tr><tr>";
-                                               $ruledefdisplaycnt = 0;
-                                       }
+                               my $ruledefchecked = '';
 
-                                       # Check for rules state
-                                       if ($snortrules{$rulefile}{'Definition'}{$ruledef}{'State'} eq 'Enabled') {
-                                               $ruledefchecked = 'CHECKED';
-                                       }
+                               # Skip rulefile itself.
+                               next if ($sid eq "Rulefile");
 
-                                       # Create rule file rule's checkbox
-                                       $checkboxname = "SNORT_RULE_$rulefile";
-                                       $checkboxname .= "_$ruledef";
-                                       print "<td class='base'><input type='checkbox' NAME='$checkboxname' $ruledefchecked> $snortrules{$rulefile}{'Definition'}{$ruledef}{'Description'}</td>";
+                               # If 2 rules have been displayed, start a new row
+                               if (($lines % 2) == 0) {
+                                       print "</tr><tr>\n";
 
-                                       # Increment count
-                                       $ruledefdisplaycnt++;
+                                       # Increase rows by once.
+                                       $rows++;
                                }
 
-                               # If do not have second rule for row, create empty cell
-                               if (($ruledefdisplaycnt % 2) != 0) {
-                                       print "<td class='base'></td>";
+                               # Colour lines.
+                               if ($rows % 2) {
+                                       $col="bgcolor='$color{'color20'}'";
+                               } else {
+                                       $col="bgcolor='$color{'color22'}'";
                                }
 
-                               # Close display table
-                               print "</tr></table></td></tr>";
-               }
+                               # Set rule state
+                               if ($idsrules{$rulefile}{$sid}{'State'} eq 'on') {
+                                       $ruledefchecked = 'CHECKED';
+                               }
 
-                       # Close display table
-                       print "</table>";
+                               # Create rule checkbox and display rule description
+                               print "<td class='base' width='5%' align='right' $col>\n";
+                               print "<input type='checkbox' NAME='$sid' $ruledefchecked>\n";
+                               print "</td>\n";
+                               print "<td class='base' width='45%' $col>$idsrules{$rulefile}{$sid}{'Description'}</td>";
 
-                       # Increment ruledisplaycnt
-               $ruledisplaycnt++;
+                               # Increment rule count
+                               $lines++;
+                       }
+
+                       # If do not have a second rule for row, create empty cell
+                       if (($lines % 2) != 0) {
+                               print "<td class='base'></td>";
+                       }
+
+                       # Close display table
+                       print "</tr></table></td></tr>";
                }
-       print "</td></tr></table></td></tr></table>";
-       print <<END
+
+               # Close display table
+               print "</table>";
+
+print <<END
 <table width='100%'>
 <tr>
-       <td width='100%' align='right'><input type='submit' name='ACTION' value='$Lang::tr{'update'}' /></td>
-               &nbsp; <!-- space for future online help link -->
-       </td>
+       <td width='100%' align='right'><input type='submit' name='RULESET' value='$Lang::tr{'ids apply'}'></td>
 </tr>
 </table>
 </form>
@@ -669,31 +1175,205 @@ END
        &Header::closebox();
 }
 
-#######################  End added for snort rules control  #################################
 &Header::closebigbox();
 &Header::closepage();
 
-sub downloadrulesfile {
-       my $peer;
-       my $peerport;
+#
+## A function to display a notice, to lock the webpage and
+## tell the user which action currently will be performed.
+#
+sub working_notice ($) {
+       my ($message) = @_;
+
+       &Header::openpage($Lang::tr{'intrusion detection system'}, 1, '');
+       &Header::openbigbox('100%', 'left', '', $errormessage);
+       &Header::openbox( 'Waiting', 1,);
+               print <<END;
+                       <table>
+                               <tr>
+                                       <td><img src='/images/indicator.gif' alt='$Lang::tr{'aktiv'}' /></td>
+                                       <td>$message</td>
+                               </tr>
+                       </table>
+END
+       &Header::closebox();
+       &Header::closebigbox();
+       &Header::closepage();
+}
 
-       unlink("/var/tmp/log");
+#
+## A tiny function to perform a reload of the webpage after one second.
+#
+sub reload () {
+       print "<meta http-equiv='refresh' content='1'>\n";
 
-       unless (-e "${General::swroot}/red/active") {
-               $errormessage = $Lang::tr{'could not download latest updates'};
-               return undef;
+       # Stop the script.
+       exit;
+}
+
+#
+## Private function to read-in and parse rules of a given rulefile.
+#
+## The given file will be read, parsed and all valid rules will be stored by ID,
+## message/description and it's state in the idsrules hash.
+#
+sub readrulesfile ($) {
+       my $rulefile = shift;
+
+       # Open rule file and read in contents
+       open(RULEFILE, "$IDS::rulespath/$rulefile") or die "Unable to read $rulefile!";
+
+       # Store file content in an array.
+       my @lines = <RULEFILE>;
+
+       # Close file.
+       close(RULEFILE);
+
+       # Loop over rule file contents
+       foreach my $line (@lines) {
+               # Remove whitespaces.
+               chomp $line;
+
+               # Skip blank  lines.
+               next if ($line =~ /^\s*$/);
+
+               # Local vars.
+               my $sid;
+               my $msg;
+
+               # Gather rule sid and message from the ruleline.
+               if ($line =~ m/.*msg:\"(.*?)\"\; .* sid:(.*?); /) {
+                       $msg = $1;
+                       $sid = $2;
+
+                       # Check if a rule has been found.
+                       if ($sid && $msg) {
+                               # Add rule to the idsrules hash.
+                               $idsrules{$rulefile}{$sid}{'Description'} = $msg;
+
+                               # Grab status of the rule. Check if ruleline starts with a "dash".
+                               if ($line =~ /^\#/) {
+                                       # If yes, the rule is disabled.
+                                       $idsrules{$rulefile}{$sid}{'State'} = "off";
+                               } else {
+                                       # Otherwise the rule is enabled.
+                                       $idsrules{$rulefile}{$sid}{'State'} = "on";
+                               }
+                       }
+               }
        }
+}
 
-       my %proxysettings=();
-       &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
+#
+## Function to get the used memory of a given process-id.
+#
+sub get_memory_usage($) {
+       my ($pid) = @_;
+
+       my $memory = 0;
+
+       # Try to open the status file for the given process-id on the pseudo
+       # file system proc.
+       if (open(FILE, "/proc/$pid/status")) {
+               # Loop through the entire file.
+               while (<FILE>) {
+                       # Splitt current line content and store them into variables.
+                       my ($key, $value) = split(":", $_, 2);
+
+                       # Check if the current key is the one which contains the memory usage.
+                       # The wanted one is VmRSS which contains the Real-memory (resident set)
+                       # of the entire process.
+                       if ($key eq "VmRSS") {
+                               # Found the memory usage add it to the memory variable.
+                               $memory += $value;
+
+                               # Break the loop.
+                               last;
+                       }
+               }
+
+               # Close file handle.
+               close(FILE);
 
-       if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
-               ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
+               # Return memory usage.
+               return $memory;
        }
 
-       if ($peer) {
-               system("wget -r --proxy=on --proxy-user=$proxysettings{'UPSTREAM_USER'} --proxy-passwd=$proxysettings{'UPSTREAM_PASSWORD'} -e http_proxy=http://$peer:$peerport/ -e https_proxy=http://$peer:$peerport/ -o /var/tmp/log --output-document=/var/tmp/snortrules.tar.gz $url");
-       } else {
-               system("wget -r -o /var/tmp/log --output-document=/var/tmp/snortrules.tar.gz $url");
+       # If the file could not be open, return nothing.
+       return;
+}
+
+#
+## Function to read-in the given enabled or disables sids file.
+#
+sub read_enabled_disabled_sids_file($) {
+       my ($file) = @_;
+
+       # Temporary hash to store the sids and their state. It will be
+       # returned at the end of this function.
+       my %temphash;
+
+       # Open the given filename.
+       open(FILE, "$file") or die "Could not open $file. $!\n";
+
+       # Loop through the file.
+       while(<FILE>) {
+               # Remove newlines.
+               chomp $_;
+
+               # Skip blank lines.
+               next if ($_ =~ /^\s*$/);
+
+               # Skip coments.
+               next if ($_ =~ /^\#/);
+
+               # Splitt line into sid and state part.
+               my ($state, $sid) = split(" ", $_);
+
+               # Skip line if the sid is not numeric.
+               next unless ($sid =~ /\d+/ );
+
+               # Check if the sid was enabled.
+               if ($state eq "enablesid") {
+                       # Add the sid and its state as enabled to the temporary hash.
+                       $temphash{$sid} = "enabled";
+               # Check if the sid was disabled.
+               } elsif ($state eq "disablesid") {
+                       # Add the sid and its state as disabled to the temporary hash.
+                       $temphash{$sid} = "disabled";
+               # Invalid state - skip the current sid and state.
+               } else {
+                       next;
+               }
        }
+
+       # Close filehandle.
+       close(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;
 }
index 030fd4b..e374f57 100644 (file)
@@ -157,7 +157,7 @@ if ($multifile) {
 if ($cgiparams{'ACTION'} eq $Lang::tr{'export'})
 {
        print "Content-type: text/plain\n\n";
-       print "IPFire IDS snort log\r\n";
+       print "IPFire IPS log\r\n";
        print "Date: $cgiparams{'DAY'} $longmonths[$cgiparams{'MONTH'}]\r\n"; 
        print "\r\n";
 
@@ -167,6 +167,10 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'export'})
        {
                my ($datetime,$title,$priority,$classification,$srcip,$srcport,$destip,$destport,$sid,$refs) = split(/\|/);
                $refs =~ s/,$//;
+
+               # Skip event if no datetime and title are available.
+               next unless (($datetime) && ($title));
+
                print "Date: $datetime\n";
                print "Name: $title\n";
                print "Priority: $priority\n";
@@ -250,7 +254,7 @@ END
 &Header::closebox();
 
 &Header::openbox('100%', 'left', $Lang::tr{'log'});
-print "<p><b>$Lang::tr{'snort hits'} $longmonthstr $daystr: $lines</b></p>";
+print "<p><b>$Lang::tr{'ids log hits'} $longmonthstr $daystr: $lines</b></p>";
 
 if ($start == -1) {
         $start = $lines - ${Header::viewsize}; }
@@ -285,6 +289,10 @@ foreach $_ (@slice)
        else {
                print "<tr bgcolor='$color{'color22'}'><td>\n"; }
        my ($datetime,$title,$priority,$classification,$srcip,$srcport,$destip,$destport,$sid,$refs) = split(/\|/);
+
+       # Only show the current event if at least datetime and title are available.
+       next unless (($datetime) && ($title));
+
        print <<END
 <table width='100%'>
 <tr>
@@ -351,7 +359,7 @@ END
        }
 print <<END
 </tr>
-</table>
+</table><br>
 </td></tr>
 END
        ;
@@ -375,11 +383,26 @@ sub processevent
        our ($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport, $sid, @refs);
 
        my $filestr='';
+       my $readmode='';
        if ($datediff==0) {
-               $filestr="/var/log/snort/alert";
+               # If there is no datediff, directly assign the suricata fast.log.
+               $filestr="/var/log/suricata/fast.log";
        } else {
-               $filestr="/var/log/snort/alert.$datediff";
-               $filestr = "$filestr.gz" if -f "$filestr.gz";
+               # If there is a datediff, assign the datediff to the filestring.
+               $filestr="/var/log/suricata/fast.log.$datediff";
+
+               # The files are compressed add the extension to the filestring.
+               $filestr="$filestr.gz";
+
+               # If the file does not exist, try to fallback to legacy snort alert file.
+               unless (-f $filestr) {
+                       # Assign snort alert file, the datediff and extension for compressed file.
+                       $filestr = "/var/log/snort/alert.$datediff";
+                       $filestr = "$filestr.gz";
+
+                       # Assign "snort" as readmode.
+                       $readmode="snort";
+               }
        }
        if (!(open (LOG,($filestr =~ /.gz$/ ? "gzip -dc $filestr |" : $filestr)))) {
                $errormessage="$errormessage$Lang::tr{'date not in logs'}: $filestr $Lang::tr{'could not be opened'}";
@@ -388,15 +411,26 @@ sub processevent
 
                while(<LOG>) {
                        $line++;
-                       if ($_ =~ m/\[\*\*\]/) {
+                       if (($_ =~ m/\[\*\*\]/) && ($readmode eq "snort")) {
                                unless ($line == 1 || $date ne "$monthstr/$daystr") {
                                        &append;
                                        $line = 1;
                                }
-                               ($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport, $sid) = ("n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a", "n/a");
+                               ($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport,$sid) = ("n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a", "n/a");
                                @refs = ();
                                $_ =~ m/:([0-9]{1,5})\] (.*) \[\*\*\]/;
                                $title = &Header::cleanhtml($2,"y");
+                       } else {
+                               &append;
+                               $line = 1;
+
+                               # Assign default values.
+                               ($title,$classification,$priority,$date,$time,$srcip,$srcport,$destip,$destport,$sid) = ("n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a", "n/a");
+                               @refs = ();
+
+                               # Gather title details from line.
+                               $_ =~ m/:([0-9]{1,5})\] (.*) \[\*\*\]/;
+                               $title = &Header::cleanhtml($2,"y");
                        }
                        if ($_ =~ m/Classification: (.*)\] \[Priority: (\d)\]/) {
                                $classification = &Header::cleanhtml($1,"y");
@@ -413,7 +447,7 @@ sub processevent
                                $destport = $10;
                        }
 
-                       if ($_  =~ m/^([0-9\/]{3,5})\-([0-9\:]{5,8})\.([0-9]{1,14})/) {
+                       if ($_  =~ m/^([0-9\/]{3,10})\-([0-9\:]{5,8})\.([0-9]{1,14})/) {
                                ($date,$time) = ($1,$2);
                        }
                        if ($_ =~ m/\[Xref \=\>.*\]/) {
index 153ffb5..136fed7 100644 (file)
@@ -63,10 +63,11 @@ my %sections = (
         'ipsec' => '(ipsec_[\w_]+: |pluto\[.*\]: |charon: |vpnwatch: )',
         'kernel' => '(kernel: (?!DROP_))',
         'ntp' => '(ntpd(?:ate)?\[.*\]: )',
+       'oinkmaster' => '(oinkmaster\[.*\]: )',
         'openvpn' => '(openvpnserver\[.*\]: |.*n2n\[.*\]: )',
         'pakfire' => '(pakfire:)',
         'red' => '(red:|pppd\[.*\]: |chat\[.*\]|pppoe\[.*\]|pptp\[.*\]|pppoa\[.*\]|pppoa3\[.*\]|pppoeci\[.*\]|ipppd|ipppd\[.*\]|kernel: ippp\d|kernel: isdn.*|ibod\[.*\]|dhcpcd\[.*\]|modem_run\[.*\])',
-        'snort' => '(snort\[.*\]: )',
+        'suricata' => '(suricata\[.*\]: )',
         'squid' => '(squid\[.*\]: |squid: )',
         'ssh' => '(sshd(?:\(.*\))?\[.*\]: )',
         'unbound' => '(unbound: \[.*:.*\])(.*:.*$)',
@@ -90,10 +91,11 @@ my %trsections = (
         'ipsec' => 'IPSec',
         'kernel' => "$Lang::tr{'kernel'}",
         'ntp' => 'NTP',
+       'oinkmaster' => 'Oinkmaster',
         'openvpn' => 'OpenVPN',
         'pakfire' => 'Pakfire',
         'red' => 'RED',
-        'snort' => "$Lang::tr{'intrusion detection'}",
+        'suricata' => "$Lang::tr{'intrusion detection'}",
         'squid' => "$Lang::tr{'web proxy'}",
         'ssh' => 'SSH',
         'unbound' => 'DNS: Unbound',
index 64fdbba..26ab4f3 100644 (file)
@@ -56,6 +56,7 @@ my %servicenames =(
        $Lang::tr{'secure shell server'} => 'sshd',
        $Lang::tr{'vpn'} => 'charon',
        $Lang::tr{'web proxy'} => 'squid',
+       $Lang::tr{'intrusion detection system'} => 'suricata',
        'OpenVPN' => 'openvpn'
 );
 
@@ -71,30 +72,15 @@ my %link =(
        $Lang::tr{'vpn'} => "<a href=\'vpnmain.cgi\'>$Lang::tr{'vpn'}</a>",
        $Lang::tr{'web proxy'} => "<a href=\'proxy.cgi\'>$Lang::tr{'web proxy'}</a>",
        'OpenVPN' => "<a href=\'ovpnmain.cgi\'>OpenVPN</a>",
-       "$Lang::tr{'intrusion detection system'} (GREEN)" => "<a href=\'ids.cgi\'>$Lang::tr{'intrusion detection system'} (GREEN)</a>",
-       "$Lang::tr{'intrusion detection system'} (RED)" => "<a href=\'ids.cgi\'>$Lang::tr{'intrusion detection system'} (RED)</a>",
-       "$Lang::tr{'intrusion detection system'} (ORANGE)" => "<a href=\'ids.cgi\'>$Lang::tr{'intrusion detection system'} (ORANGE)</a>",
-       "$Lang::tr{'intrusion detection system'} (BLUE)" => "<a href=\'ids.cgi\'>$Lang::tr{'intrusion detection system'} (BLUE)</a>"
+       "$Lang::tr{'intrusion detection system'}" => "<a href=\'ids.cgi\'>$Lang::tr{'intrusion detection system'}</a>",
 );
 
-my $lines=0; # Used to count the outputlines to make different bgcolor
-
-my $iface = '';
-if (open(FILE, "${General::swroot}/red/iface")){
-       $iface = <FILE>;
-       close FILE;
-       chomp $iface;
-}
-
-$servicenames{"$Lang::tr{'intrusion detection system'} (RED)"}   = "snort_${iface}";
-$servicenames{"$Lang::tr{'intrusion detection system'} (GREEN)"} = "snort_$netsettings{'GREEN_DEV'}";
+# Hash to overwrite the process name of a process if it differs fromt the launch command.
+my %overwrite_exename_hash = (
+       "suricata" => "Suricata-Main"
+);
 
-if ($netsettings{'ORANGE_DEV'} ne ''){
-       $servicenames{"$Lang::tr{'intrusion detection system'} (ORANGE)"} = "snort_$netsettings{'ORANGE_DEV'}";
-}
-if ($netsettings{'BLUE_DEV'} ne ''){
-       $servicenames{"$Lang::tr{'intrusion detection system'} (BLUE)"} = "snort_$netsettings{'BLUE_DEV'}";
-}
+my $lines=0; # Used to count the outputlines to make different bgcolor
 
 my @querry = split(/\?/,$ENV{'QUERY_STRING'});
 $querry[0] = '' unless defined $querry[0];
@@ -258,7 +244,20 @@ sub isrunning{
        my $memory;
 
        $cmd =~ /(^[a-z]+)/;
-       $exename = $1;
+
+       # Check if the exename needs to be overwritten.
+       # This happens if the expected process name string
+       # differs from the real one. This may happened if
+       # a service uses multiple processes or threads.
+       if (exists($overwrite_exename_hash{$1})) {
+               # Grab the string which will be reported by
+               # the process from the corresponding hash.
+               $exename = $overwrite_exename_hash{$1};
+       } else {
+               # Directly expect the launched command as
+               # process name.
+               $exename = $1;
+       }
 
        if (open(FILE, "/var/run/${cmd}.pid")){
                $pid = <FILE>; chomp $pid;
index ce7090c..4d5466a 100644 (file)
@@ -83,6 +83,8 @@
 'ConnSched time' => 'Zeit:',
 'ConnSched up' => 'Herauf',
 'ConnSched weekdays' => 'Wochentage:',
+'Daily' => 'Täglich',
+'Disabled' => 'Deaktiviert',
 'Edit an existing route' => 'Eine existierende Route editieren',
 'Enter TOS' => 'Aktivieren oder deaktivieren Sie die TOS-Bits <br /> und klicken Sie danach auf <i>Speichern</i>.',
 'Existing Files' => 'Dateien in der Datenbank',
 'Utilization on' => 'Auslastung auf',
 'Verbose' => 'Verbose',
 'WakeOnLan' => 'Wake On LAN',
+'Weekly' => 'Wöchentlich',
 'a ca certificate with this name already exists' => 'Ein CA-Zertifikat mit diesem Namen existiert bereits.',
 'a connection with this common name already exists' => 'Eine Verbindung mit diesem gemeinsamen Namen existiert bereits.',
 'a connection with this name already exists' => 'Eine Verbindung mit diesem Namen existiert bereits.',
 'idle' => 'Leerlauf',
 'idle timeout' => 'Leerlauf-Wartezeit in Min. (0 zum Deaktivieren):',
 'idle timeout not set' => 'Leerlauf-Wartezeit nicht angegeben.',
-'ids log viewer' => 'Ansicht IDS-Protokoll',
-'ids logs' => 'IDS-Protokolldateien',
-'ids preprocessor' => 'IDS-Präprozessor',
-'ids rules license' => 'Um  Sourcefire VRT Zertifizierte Regeln zu nutzen, müssen Sie sich unter',
-'ids rules license1' => ' registrieren.',
-'ids rules license2' => 'Bestätigen Sie die Lizenz; aktivieren Sie Ihren Account, indem Sie auf den Link, den Sie per Mail erhalten haben, klicken. Gehen Sie dann zu',
-'ids rules license3' => 'klicken Sie den "Generate code"-Knopf und kopieren Sie den 40-Zeichen Oinkcode in das untere Feld.',
-'ids rules update' => 'Snort Regeln Update',
+'ids apply' => 'Übernehmen',
+'ids apply ruleset changes' => 'Regel-Änderungen werden übernommen ... Bitte warten Sie, bis dieser Vorgang erfolgreich beendet wurde.',
+'ids automatic rules update' => 'Automatische Regeln-Aktualisierung',
+'ids traffic analyze' => 'Packet-Analyse',
+'ids active on' => 'Aktiv auf',
+'ids enable' => 'Intrusion-Prevention-System aktivieren',
+'ids download new ruleset' => 'Das neue Regelset wird heruntergeladen und entpackt ... Bitte warten Sie, bis dieser Vorgang erfolgreich beendet wurde.',
+'ids ignored hosts' => 'Ignorierte Hosts',
+'ids log viewer' => 'Ansicht IPS-Protokoll',
+'ids log hits' => 'Gesamtanzahl der aktivierten Regeln für',
+'ids logs' => 'IPS-Protokolldateien',
+'ids monitored interfaces' => 'Überwachte Netzwerkzonen',
+'ids monitor traffic only' => 'Netzwerk-Pakete nur überpfrüfen',
+'ids no network zone' => 'Mindestends eine Netzwerk-Zone muss überwacht werden!',
+'ids no ruleset available' => 'Kein Regelset verfügbar, bitte downloaden Sie eines!',
+'ids oinkcode required' => 'Für das ausgewählte Regelset wird ein Abonnement oder ein Oinkcode benötigt',
+'ids ruleset settings' => 'Regelset-Einstellungen',
+'ids ruleset autoupdate in progress' => 'Das Regelset wird gerade aktualisiert ... Bitte warten Sie, bis dieser Vorgang erfolgreich beendet wurde.',
+'ids working' => 'Änderungen werden übernommen ... Bitte warten Sie, bis dieser Vorgang erfolgreich beendet wurde.',
 'iface' => 'Iface',
 'ignore filter' => '&quot;Ignorieren&quot;-Filter',
 'ike encryption' => 'IKE Verschlüsselung:',
 'interface' => 'Schnittstelle',
 'interfaces' => 'Interfaces',
 'internet' => 'INTERNET',
-'intrusion detection' => 'Einbruchdetektierung',
-'intrusion detection system' => 'Einbruchsdetektierung',
-'intrusion detection system log viewer' => 'Betrachter der IDS-Protokolldateien',
-'intrusion detection system rules' => 'Regeln für die Einbruchsdetektierung',
-'intrusion detection system2' => 'Intrusion Detection System:',
+'intrusion detection' => 'Intrusion-Prevention',
+'intrusion detection system' => 'Intrusion-Prevention-System',
+'intrusion detection system log viewer' => 'Betrachter der IPS-Protokolldateien',
+'intrusion detection system rules' => 'Regelset',
+'intrusion detection system2' => 'Intrusion-Prevention-System',
+'intrusion prevention system' => 'Intrusion-Prevention-System',
 'invalid broadcast ip' => 'Ungültige Broadcast-IP',
 'invalid cache size' => 'Ungültige Cache-Größe.',
 'invalid characters found in pre-shared key' => 'Ungültige Zeichen im Pre-Shared Schlüssel gefunden.',
 'rsvd dst port overlap' => 'Dieser Zielportbereich überlappt mit einem Port, der für die ausschließliche Benutzung durch IPFire reserviert ist:',
 'rsvd src port overlap' => 'Dieser Quellportbereich überlappt mit einem Port, der für die ausschließliche Benutzung durch IPFire reserviert ist:',
 'rules already up to date' => 'Regeln sind schon aktuell',
+'runmode' => 'Runmode',
 'running' => 'LÄUFT',
 'safe removal of umounted device' => 'Sie können gefahrlos das abgemeldete Gerät entfernen',
 'samba' => 'Samba',
 'smtphost' => 'Smtp Host',
 'smtpport' => 'Smtp Port',
 'snat new source ip address' => 'Neue Quell-IP-Adresse',
-'snort hits' => 'Gesamtanzahl der aktivierten Intrusion-Regeln für',
-'snort working' => 'Snort führt gerade eine Aufgabe aus... Bitte warten Sie, bis diese erfolgreich beendet wurde.',
 'socket options' => 'Socket Options',
 'software version' => 'Software-Version',
 'sort ascending' => 'Sortiere aufsteigend',
 'system has hwrng' => 'Dieses System hat einen Hardware-Zufallszahlengenerator.',
 'system has rdrand' => 'Dieses System unterstützt Intel(R) RDRAND.',
 'system information' => 'Systeminformationen',
+'system is offline' => 'Das System ist offline.',
 'system log viewer' => 'Betrachter der Systemprotokolldateien',
 'system logs' => 'Systemprotokolldateien',
 'system status information' => 'System-Statusinformationen',
 'unnamed' => 'Unbenannt',
 'update' => 'Aktualisieren',
 'update accelerator' => 'Update-Accelerator',
+'update ruleset' => 'Regelsatz aktualisieren',
 'update time' => 'Aktualisiere die Uhrzeit:',
 'update transcript' => 'Aktualisieren',
 'updatedatabase' => 'Datenbank auf Stand der letzten Reports setzen',
index 7697dc2..5998204 100644 (file)
@@ -83,6 +83,8 @@
 'ConnSched time' => 'Time:',
 'ConnSched up' => 'Up',
 'ConnSched weekdays' => 'Days of the week:',
+'Daily' => 'Daily',
+'Disabled' => 'Disabled',
 'Edit an existing route' => 'Edit an existing route',
 'Enter TOS' => 'Activate or deactivate TOS-bits <br /> and then press <i>Save</i>.',
 'Existing Files' => 'Files in database',
 'Utilization on' => 'Utilization on',
 'Verbose' => 'Verbose:',
 'WakeOnLan' => 'Wake On Lan',
+'Weekly' => 'Weekly',
 'a ca certificate with this name already exists' => 'A CA certificate with this name already exists.',
 'a connection with this common name already exists' => 'A connection with this common name already exists.',
 'a connection with this name already exists' => 'A connection with this name already exists.',
 'email usemail' => 'Activate Mail Service',
 'emailreportlevel' => 'E-mailreportlevel',
 'emerging rules' => 'Emergingthreats.net Community Rules',
+'emerging pro rules' => 'Emergingthreats.net Pro Rules',
 'empty' => 'This field may be left blank',
 'empty profile' => 'empty',
 'enable ignore filter' => 'Enable ignore filter',
 'idle' => 'Idle',
 'idle timeout' => 'Idle timeout (mins; 0 to disable):',
 'idle timeout not set' => 'Idle timeout not set.',
-'ids log viewer' => 'IDS log viewer',
-'ids logs' => 'IDS Logs',
-'ids preprocessor' => 'IDS preprocessor',
-'ids rules license' => 'To utilize Sourcefire VRT Certified Rules, you need to register on',
-'ids rules license1' => '.',
-'ids rules license2' => 'Acknowledge the license, activate your account by visiting the url you got via mail. Then go to',
-'ids rules license3' => 'press the "Generate code"-button and copy the 40 character Oinkcode into the field below.',
-'ids rules update' => 'Snort rules update',
+'ids apply' => 'Apply',
+'ids apply ruleset changes' => 'The ruleset changes will be applied ... Please wait until all operations have completed successfully.',
+'ids automatic rules update' => 'Automatic rules update',
+'ids traffic analyze' => 'Traffic analyzing',
+'ids active on' => 'Active on',
+'ids download new ruleset' => 'Downloading and unpacking new ruleset ... Please wait until all operations have completed successfully.',
+'ids enable' => 'Enable Intrusion Prevention System',
+'ids hide' => 'Hide',
+'ids ignored hosts' => 'Ignored hosts',
+'ids log hits' => 'Total of number of activated rules for',
+'ids log viewer' => 'IPS log viewer',
+'ids logs' => 'IPS Logs',
+'ids monitored interfaces' => 'Monitored interfaces',
+'ids monitor traffic only' => 'Monitor traffic only',
+'ids no network zone' => 'At least one network zone has to be monitored!',
+'ids no ruleset available' => 'No ruleset available, please download one!',
+'ids oinkcode required' => 'The selected ruleset requires a subscription or an oinkcode',
+'ids ruleset settings' => 'Ruleset settings',
+'ids rules update' => 'IPS rules',
+'ids ruleset autoupdate in progress' => 'Ruleset update in progress ... Please wait until all operations have completed successfully.',
+'ids show' => 'Show',
+'ids working' => 'Changes will be applied ... Please wait until all operations have completed successfully.',
 'iface' => 'Iface',
 'ignore filter' => 'Ignore filter',
 'ike encryption' => 'IKE Encryption:',
 'interface mode' => 'Interface',
 'interfaces' => 'Interfaces',
 'internet' => 'INTERNET',
-'intrusion detection' => 'Intrusion Detection',
-'intrusion detection system' => 'Intrusion Detection System',
-'intrusion detection system log viewer' => 'Intrusion Detection System Log Viewer',
-'intrusion detection system rules' => 'intrusion detection system rules',
-'intrusion detection system2' => 'Intrusion Detection System:',
+'intrusion detection' => 'Intrusion Prevention',
+'intrusion detection system' => 'Intrusion Prevention System',
+'intrusion detection system log viewer' => 'Intrusion Prevention System Log Viewer',
+'intrusion detection system rules' => 'Ruleset',
+'intrusion detection system2' => 'Intrusion Prevention System',
+'intrusion prevention system' => 'Intrusion Prevention System',
 'invalid broadcast ip' => 'Invalid broadcast IP',
 'invalid cache size' => 'Invalid cache size.',
 'invalid characters found in pre-shared key' => 'Invalid characters found in pre-shared key.',
 'rsvd dst port overlap' => 'Destination Port Range overlaps a port reserved for IPFire:',
 'rsvd src port overlap' => 'Source Port Range overlaps a port reserved for IPFire:',
 'rules already up to date' => 'Rules already up to date',
+'runmode' => 'Runmode',
 'running' => 'RUNNING',
 'safe removal of umounted device' => 'You can safely remove the unmounted device',
 'samba' => 'Samba',
 'smtphost' => 'SMTP host',
 'smtpport' => 'SMTP port',
 'snat new source ip address' => 'New source IP address',
-'snort hits' => 'Total of number of Intrusion rules activated for',
-'snort working' => 'Snort is working ... Please wait until all operations have completed successfully.',
 'socket options' => 'Socket options',
 'software version' => 'Software Version',
 'sort ascending' => 'Sort ascending',
 'system has hwrng' => 'This system has a hardware random number generator.',
 'system has rdrand' => 'This system has support for Intel(R) RDRAND.',
 'system information' => 'System Information',
+'system is offline' => 'The system is offline.',
 'system log viewer' => 'System Log Viewer',
 'system logs' => 'System Logs',
 'system status information' => 'System Status Information',
 'unnamed' => 'Unnamed',
 'update' => 'Update',
 'update accelerator' => 'Update Accelerator',
+'update ruleset' => 'Update ruleset',
 'update time' => 'Update the time:',
 'update transcript' => 'Update transcript',
 'updatedatabase' => 'Update Database with last report',
index 4e6751e..33e89e0 100644 (file)
@@ -54,7 +54,7 @@ $(TARGET) :
                        ethernet extrahd/bin fwlogs fwhosts firewall isdn key langs logging mac main \
                        menu.d modem optionsfw \
                        ovpn patches pakfire portfw ppp private proxy/advanced/cre \
-                       proxy/calamaris/bin qos/bin red remote sensors snort time \
+                       proxy/calamaris/bin qos/bin red remote sensors suricata time \
                        updatexlrator/bin updatexlrator/autocheck urlfilter/autoupdate urlfilter/bin upnp vpn \
                        wakeonlan wireless ; do \
                mkdir -p $(CONFIG_ROOT)/$$i; \
@@ -69,7 +69,7 @@ $(TARGET) :
            isdn/settings mac/settings main/hosts main/routing main/settings optionsfw/settings \
            ovpn/ccd.conf ovpn/ccdroute ovpn/ccdroute2 pakfire/settings portfw/config ppp/settings-1 ppp/settings-2 ppp/settings-3 ppp/settings-4 \
            ppp/settings-5 ppp/settings proxy/settings proxy/squid.conf proxy/advanced/settings proxy/advanced/cre/enable remote/settings qos/settings qos/classes qos/subclasses qos/level7config qos/portconfig \
-           qos/tosconfig snort/settings upnp/settings vpn/config vpn/settings vpn/ipsec.conf \
+           qos/tosconfig suricata/settings upnp/settings vpn/config vpn/settings vpn/ipsec.conf \
            vpn/ipsec.secrets vpn/caconfig wakeonlan/clients.conf wireless/config wireless/settings; do \
            touch $(CONFIG_ROOT)/$$i; \
        done
@@ -80,6 +80,7 @@ $(TARGET) :
        cp $(DIR_SRC)/config/cfgroot/network-functions.pl       $(CONFIG_ROOT)/
        cp $(DIR_SRC)/config/cfgroot/geoip-functions.pl         $(CONFIG_ROOT)/
        cp $(DIR_SRC)/config/cfgroot/aws-functions.pl           $(CONFIG_ROOT)/
+       cp $(DIR_SRC)/config/cfgroot/ids-functions.pl           $(CONFIG_ROOT)/
        cp $(DIR_SRC)/config/cfgroot/lang.pl                    $(CONFIG_ROOT)/
        cp $(DIR_SRC)/config/cfgroot/countries.pl               $(CONFIG_ROOT)/
        cp $(DIR_SRC)/config/cfgroot/graphs.pl                  $(CONFIG_ROOT)/
@@ -132,6 +133,9 @@ $(TARGET) :
        echo  "POLICY=MODE2"            >> $(CONFIG_ROOT)/firewall/settings
        echo  "POLICY1=MODE2"           >> $(CONFIG_ROOT)/firewall/settings
 
+       # Install snort to suricata converter.
+       cp $(DIR_SRC)/config/suricata/convert-snort     /usr/sbin/convert-snort
+
        # Add conntrack helper default settings
        for proto in FTP H323 IRC SIP TFTP; do \
                echo "CONNTRACK_$${proto}=on" >> $(CONFIG_ROOT)/optionsfw/settings; \
diff --git a/lfs/ids-ruleset-sources b/lfs/ids-ruleset-sources
new file mode 100644 (file)
index 0000000..d55b1a0
--- /dev/null
@@ -0,0 +1,53 @@
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007  Michael Tremer & Christian Schmidt                      #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER        = ipfire
+
+THISAPP    = ids-ruleset-sources
+TARGET     = $(DIR_INFO)/$(THISAPP)
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+install : $(TARGET)
+
+check :
+
+download :
+
+md5 :
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) :
+       @$(PREBUILD)
+       # Simple install the ruleset sources file.
+       install -m 644 $(DIR_SRC)/config/suricata/ruleset-sources \
+               /var/ipfire/suricata/
+       @$(POSTBUILD)
index c053b71..055e106 100644 (file)
@@ -121,8 +121,8 @@ $(TARGET) :
        ln -sf ../init.d/fcron       /etc/rc.d/rc0.d/K08fcron
        ln -sf ../init.d/fcron       /etc/rc.d/rc3.d/S40fcron
        ln -sf ../init.d/fcron       /etc/rc.d/rc6.d/K08fcron
-       ln -sf ../init.d/snort       /etc/rc.d/rc0.d/K78snort
-       ln -sf ../init.d/snort       /etc/rc.d/rc6.d/K78snort
+       ln -sf ../init.d/suricata    /etc/rc.d/rc0.d/K78suricata
+       ln -sf ../init.d/suricata    /etc/rc.d/rc6.d/K78suricata
        ln -sf ../init.d/network     /etc/rc.d/rc0.d/K80network
        ln -sf ../init.d/network     /etc/rc.d/rc3.d/S20network
        ln -sf ../init.d/network     /etc/rc.d/rc6.d/K80network
@@ -188,8 +188,6 @@ $(TARGET) :
        ln -sf ../init.d/wlanclient  /etc/rc.d/rc3.d/S19wlanclient
        ln -sf ../init.d/wlanclient  /etc/rc.d/rc6.d/K82wlanclient
 
-       ln -sf ../../../../../usr/local/bin/snortctrl \
-               /etc/rc.d/init.d/networking/red.up/23-RS-snort
        ln -sf ../../../../../usr/local/bin/qosctrl \
                /etc/rc.d/init.d/networking/red.up/24-RS-qos
        ln -sf ../../squid /etc/rc.d/init.d/networking/red.up/27-RS-squid
similarity index 74%
rename from lfs/snort
rename to lfs/libcap-ng
index c66a0dd..0cbe3e6 100644 (file)
--- a/lfs/snort
@@ -24,9 +24,9 @@
 
 include Config
 
-VER        = 2.9.12
+VER        = 0.7.9
 
-THISAPP    = snort-$(VER)
+THISAPP    = libcap-ng-$(VER)
 DL_FILE    = $(THISAPP).tar.gz
 DL_FROM    = $(URL_IPFIRE)
 DIR_APP    = $(DIR_SRC)/$(THISAPP)
@@ -40,7 +40,7 @@ objects = $(DL_FILE)
 
 $(DL_FILE) = $(DL_FROM)/$(DL_FILE)
 
-$(DL_FILE)_MD5 = 3a305d9c44bd0319aa50783a60c8947f
+$(DL_FILE)_MD5 = 2398d695508fab9ce33668c53a89b0e9
 
 install : $(TARGET)
 
@@ -69,37 +69,12 @@ $(subst %,%_MD5,$(objects)) :
 
 $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @$(PREBUILD)
-       @rm -rf $(DIR_APP) $(DIR_SRC)/snort* && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+       @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
        cd $(DIR_APP) && ./configure \
                --prefix=/usr \
-               --sysconfdir=/etc/snort \
-               --target=i586 \
-               --enable-linux-smp-stats \
-               --disable-open-appid \
-               --enable-gre \
-               --enable-mpls \
-               --enable-targetbased \
-               --enable-ppm \
-               --enable-non-ether-decoders \
-               --enable-perfprofiling \
-               --enable-active-response \
-               --enable-normalizer \
-               --enable-reload \
-               --enable-react \
-               --enable-flexresp3
+               --disable-static
 
        cd $(DIR_APP) && make $(MAKETUNING)
        cd $(DIR_APP) && make install
-       mv /usr/bin/snort /usr/sbin/
-       -mkdir -p /etc/snort/rules
-
-       cd $(DIR_APP) && install -m 0644  \
-               etc/reference.config etc/classification.config /etc/snort/rules
-       cd $(DIR_APP) && install -m 0644 etc/unicode.map /etc/snort
-       install -m 0644 $(DIR_SRC)/config/snort/snort.conf /etc/snort
-       cp /etc/snort/snort.conf /etc/snort/snort.conf.template
-       chown -R nobody:nobody /etc/snort
-       -mkdir -p /var/log/snort
-       chown -R snort:snort /var/log/snort
-       @rm -rf $(DIR_APP) $(DIR_SRC)/snort*
+       @rm -rf $(DIR_APP)
        @$(POSTBUILD)
diff --git a/lfs/libhtp b/lfs/libhtp
new file mode 100644 (file)
index 0000000..212514d
--- /dev/null
@@ -0,0 +1,80 @@
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2015  Michael Tremer & Christian Schmidt                      #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER        = 0.5.29
+
+THISAPP    = libhtp-$(VER)
+DL_FILE    = $(THISAPP).tar.gz
+DL_FROM    = $(URL_IPFIRE)
+DIR_APP    = $(DIR_SRC)/$(THISAPP)
+TARGET     = $(DIR_INFO)/$(THISAPP)
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+objects = $(DL_FILE)
+
+$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
+
+$(DL_FILE)_MD5 = 5feb73647723db5b458d00faddb30954
+
+install : $(TARGET)
+
+check : $(patsubst %,$(DIR_CHK)/%,$(objects))
+
+download :$(patsubst %,$(DIR_DL)/%,$(objects))
+
+md5 : $(subst %,%_MD5,$(objects))
+
+###############################################################################
+# Downloading, checking, md5sum
+###############################################################################
+
+$(patsubst %,$(DIR_CHK)/%,$(objects)) :
+       @$(CHECK)
+
+$(patsubst %,$(DIR_DL)/%,$(objects)) :
+       @$(LOAD)
+
+$(subst %,%_MD5,$(objects)) :
+       @$(MD5)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+       @$(PREBUILD)
+       @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+       cd $(DIR_APP) && ./autogen.sh
+       cd $(DIR_APP) && ./configure \
+               --prefix=/usr \
+               --disable-static
+       cd $(DIR_APP) && make $(MAKETUNING)
+       cd $(DIR_APP) && make install
+       @rm -rf $(DIR_APP)
+       @$(POSTBUILD)
index 3403eb8..51b99ec 100644 (file)
@@ -71,8 +71,9 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf  $(DIR_DL)/$(DL_FILE)
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/oinkmaster-2.0-add_community_rules.patch
        cd $(DIR_APP) && chown nobody:nobody oinkmaster.pl
-       cd $(DIR_APP) && cp -f oinkmaster.conf /var/ipfire/snort/
-       cd /var/ipfire/snort && patch -Np1 < $(DIR_SRC)/src/patches/oinkmaster-tmp.patch
+       cd $(DIR_APP) && install -m 0644 $(DIR_SRC)/config/oinkmaster/oinkmaster.conf \
+               /var/ipfire/suricata/
+       cd /var/ipfire/suricata && patch -Np1 < $(DIR_SRC)/src/patches/oinkmaster-tmp.patch
        cd $(DIR_APP) && install -m 0755 oinkmaster.pl /usr/local/bin/
        @rm -rf $(DIR_APP)
        @$(POSTBUILD)
diff --git a/lfs/suricata b/lfs/suricata
new file mode 100644 (file)
index 0000000..0a561ef
--- /dev/null
@@ -0,0 +1,114 @@
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2007-2018  IPFire Team  <info@ipfire.org>                     #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER        = 4.1.3
+
+THISAPP    = suricata-$(VER)
+DL_FILE    = $(THISAPP).tar.gz
+DL_FROM    = $(URL_IPFIRE)
+DIR_APP    = $(DIR_SRC)/$(THISAPP)
+TARGET     = $(DIR_INFO)/$(THISAPP)
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+objects = $(DL_FILE)
+
+$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
+
+$(DL_FILE)_MD5 = 35c4a8e6be3910831649a073950195df
+
+install : $(TARGET)
+
+check : $(patsubst %,$(DIR_CHK)/%,$(objects))
+
+download :$(patsubst %,$(DIR_DL)/%,$(objects))
+
+md5 : $(subst %,%_MD5,$(objects))
+
+###############################################################################
+# Downloading, checking, md5sum
+###############################################################################
+
+$(patsubst %,$(DIR_CHK)/%,$(objects)) :
+       @$(CHECK)
+
+$(patsubst %,$(DIR_DL)/%,$(objects)) :
+       @$(LOAD)
+
+$(subst %,%_MD5,$(objects)) :
+       @$(MD5)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+       @$(PREBUILD)
+       @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+       cd $(DIR_APP) && ./configure \
+               --prefix=/usr \
+               --sysconfdir=/etc \
+               --localstatedir=/var \
+               --enable-gccprotect \
+               --disable-gccmarch-native \
+               --enable-non-bundled-htp \
+               --enable-nfqueue \
+               --disable-static \
+               --disable-python \
+               --disable-suricata-update
+       cd $(DIR_APP) && make $(MAKETUNING)
+       cd $(DIR_APP) && make install
+       cd $(DIR_APP) && make install-conf
+
+       # Remove default suricata config file.
+       rm -rvf /etc/suricata/suricata.yaml
+
+       # Install IPFire related config file.
+       install -m 0644 $(DIR_SRC)/config/suricata/suricata.yaml /etc/suricata
+
+       # Remove shipped rules.
+       rm -rvf /usr/share/suricata
+
+       # Create emtpy rules directory.
+       -mkdir -p /var/lib/suricata
+
+       # Move config files for references, threshold and classification
+       # to the rules directory.
+       mv /etc/suricata/*.config /var/lib/suricata
+
+       # Set correct ownership for /var/lib/suricata
+       chown nobody:nobody /var/lib/suricata
+
+       # Create logging directory.
+       -mkdir -p /var/log/suricata
+
+       # Set correct ownership for /var/log/suricata.
+       chown suricata:suricata /var/log/suricata
+
+       @rm -rf $(DIR_APP)
+       @$(POSTBUILD)
similarity index 93%
rename from lfs/daq
rename to lfs/yaml
index 4e9e1c9..81cdd4f 100644 (file)
--- a/lfs/daq
+++ b/lfs/yaml
@@ -24,9 +24,9 @@
 
 include Config
 
-VER        = 2.0.6
+VER        = 0.2.1
 
-THISAPP    = daq-$(VER)
+THISAPP    = yaml-$(VER)
 DL_FILE    = $(THISAPP).tar.gz
 DL_FROM    = $(URL_IPFIRE)
 DIR_APP    = $(DIR_SRC)/$(THISAPP)
@@ -40,7 +40,7 @@ objects = $(DL_FILE)
 
 $(DL_FILE) = $(DL_FROM)/$(DL_FILE)
 
-$(DL_FILE)_MD5 = 2cd6da422a72c129c685fc4bb848c24c
+$(DL_FILE)_MD5 = 72724b9736923c517e5a8fc6757ef03d
 
 install : $(TARGET)
 
@@ -70,8 +70,10 @@ $(subst %,%_MD5,$(objects)) :
 $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @$(PREBUILD)
        @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
-       cd $(DIR_APP) && ./configure --prefix=/usr
-       cd $(DIR_APP) && make
+       cd $(DIR_APP) && ./configure \
+               --prefix=/usr \
+               --disable-static
+       cd $(DIR_APP) && make $(MAKETUNING)
        cd $(DIR_APP) && make install
        @rm -rf $(DIR_APP)
        @$(POSTBUILD)
diff --git a/make.sh b/make.sh
index 079f02e..bb4269d 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -1216,6 +1216,7 @@ buildipfire() {
   lfsmake2 attr
   lfsmake2 acl
   lfsmake2 libcap
+  lfsmake2 libcap-ng
   lfsmake2 pciutils
   lfsmake2 usbutils
   lfsmake2 libxml2
@@ -1314,9 +1315,11 @@ buildipfire() {
   lfsmake2 setserial
   lfsmake2 setup
   lfsmake2 libdnet
-  lfsmake2 daq
-  lfsmake2 snort
+  lfsmake2 yaml
+  lfsmake2 libhtp
+  lfsmake2 suricata
   lfsmake2 oinkmaster
+  lfsmake2 ids-ruleset-sources
   lfsmake2 squid
   lfsmake2 squidguard
   lfsmake2 calamaris
diff --git a/src/initscripts/networking/red.up/23-suricata b/src/initscripts/networking/red.up/23-suricata
new file mode 100644 (file)
index 0000000..1514909
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/perl
+#
+# Helper script to regenerate the file which contains the HOME_NET declaration
+# including the assigned IP-address of red and any configured aliases.
+
+use strict;
+
+require '/var/ipfire/general-functions.pl';
+require "${General::swroot}/ids-functions.pl";
+
+# Hash to store the IDS settings.
+my %ids_settings = ();
+
+# Read-in IDS settings.
+&General::readhash("$IDS::ids_settings_file", \%ids_settings);
+
+# Check if suricata is enabled.
+if($ids_settings{'ENABLE_IDS'} eq "on") {
+       # Regenerate the file with HOME_NET details.
+       &IDS::generate_home_net_file();
+
+       # Set correct ownership.
+       &IDS::set_ownership("$IDS::homenet_file");
+
+       # Check if suricata is running.
+       if(&IDS::ids_is_running()) {
+               # Call suricatactrl to perform a restart of suricata.
+               &IDS::call_suricatactrl("restart");
+       } else {
+               # Call suricatactrl to start suricata.
+               &IDS::call_suricatactrl("start");
+       }
+}
index cb533cc..be6c916 100644 (file)
@@ -185,6 +185,12 @@ iptables_init() {
        iptables -A INPUT -j GUARDIAN
        iptables -A FORWARD -j GUARDIAN
 
+       # IPS (suricata) chains
+       iptables -N IPS
+       iptables -A INPUT -j IPS
+       iptables -A FORWARD -j IPS
+       iptables -A OUTPUT -j IPS
+
        # Block non-established IPsec networks
        iptables -N IPSECBLOCK
        iptables -A FORWARD -m policy --dir out --pol none -j IPSECBLOCK
diff --git a/src/initscripts/system/snort b/src/initscripts/system/snort
deleted file mode 100644 (file)
index 5c43042..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/bin/sh
-########################################################################
-# Begin $rc_base/init.d/snort
-#
-# Description : Snort Initscript
-#
-# Authors     : Michael Tremer for ipfire.org - mitch@ipfire.org
-#
-# Version     : 01.00
-#
-# Notes       :
-#
-########################################################################
-
-. /etc/sysconfig/rc
-. ${rc_functions}
-
-PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin; export PATH
-
-eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
-eval $(/usr/local/bin/readhash /var/ipfire/snort/settings)
-
-ALIASFILE="/var/ipfire/ethernet/aliases"
-
-case "$1" in
-        start)
-               if [ "$BLUE_NETADDRESS" ]; then
-                       BLUE_NET="$BLUE_NETADDRESS/$BLUE_NETMASK,"
-                       BLUE_IP="$BLUE_ADDRESS,"
-               fi
-
-               if [ "$ORANGE_NETADDRESS" ]; then
-                       ORANGE_NET="$ORANGE_NETADDRESS/$ORANGE_NETMASK,"
-                       ORANGE_IP="$ORANGE_ADDRESS,"
-               fi
-
-               if [ "$ENABLE_SNORT_ORANGE" == "on" ]; then
-                       DEVICES+="$ORANGE_DEV "
-                       HOMENET+="$ORANGE_IP"
-               else
-                       HOMENET+="$ORANGE_NET"
-               fi
-
-               if [ "$ENABLE_SNORT_BLUE" == "on" ]; then
-                       DEVICES+="$BLUE_DEV "
-                       HOMENET+="$BLUE_IP"
-               else
-                       HOMENET+="$BLUE_NET"
-               fi
-
-               if [ "$ENABLE_SNORT_GREEN" == "on" ]; then
-                       DEVICES+="$GREEN_DEV "
-                       HOMENET+="$GREEN_ADDRESS,"
-               else
-                       HOMENET+="$GREEN_NETADDRESS/$GREEN_NETMASK,"
-               fi
-
-               if [ "$ENABLE_SNORT" == "on" ]; then
-                       DEVICES+=`cat /var/ipfire/red/iface 2>/dev/null`
-                       LOCAL_IP=`cat /var/ipfire/red/local-ipaddress 2>/dev/null`
-                       if [ "$LOCAL_IP" ]; then
-                               HOMENET+="$LOCAL_IP,"
-                       fi
-
-                       # Check if the red device is set to static and
-                       # any aliases have been configured.
-                       if [ "${RED_TYPE}" == "STATIC" ] && [ -s "${ALIASFILE}" ]; then
-                               # Read in aliases file.
-                               while IFS="," read -r address mode remark; do
-                                       # Check if the alias is enabled.
-                                       [ "${mode}" = "on" ] || continue
-
-                                       # Add alias to the list of HOMENET addresses.
-                                       HOMENET+="${address},"
-                               done < "${ALIASFILE}"
-                       fi
-               fi
-               HOMENET+="127.0.0.1"
-               echo "ipvar HOME_NET [$HOMENET]" > /etc/snort/vars
-
-               DNS1=`cat /var/ipfire/red/dns1 2>/dev/null`
-               DNS2=`cat /var/ipfire/red/dns2 2>/dev/null`
-
-               if [ "$DNS2" ]; then
-                       echo "ipvar DNS_SERVERS [$DNS1,$DNS2]" >> /etc/snort/vars
-               else
-                       echo "ipvar DNS_SERVERS $DNS1" >> /etc/snort/vars
-               fi
-
-                for DEVICE in $DEVICES; do
-                        boot_mesg "Starting Intrusion Detection System on $DEVICE..."
-                        /usr/sbin/snort -c /etc/snort/snort.conf -i $DEVICE -D -l /var/log/snort --create-pidfile --nolock-pidfile --pid-path /var/run
-                        evaluate_retval
-                       sleep 1
-                        chmod 644 /var/run/snort_$DEVICE.pid
-                done
-       ;;
-
-        stop)
-               DEVICES=""
-               if [ -r /var/run/snort_$BLUE_DEV.pid ]; then
-                 DEVICES+="$BLUE_DEV "
-               fi
-               
-               if [ -r /var/run/snort_$GREEN_DEV.pid ]; then
-                 DEVICES+="$GREEN_DEV "
-              fi
-             
-              if [ -r /var/run/snort_$ORANGE_DEV.pid ]; then
-                 DEVICES+="$ORANGE_DEV "
-              fi
-      
-              RED=`cat /var/ipfire/red/iface 2>/dev/null`
-              if [ -r /var/run/snort_$RED.pid ]; then
-                 DEVICES+=`cat /var/ipfire/red/iface 2>/dev/null`
-              fi
-       
-              for DEVICE in $DEVICES; do
-                 boot_mesg "Stopping Intrusion Detection System on $DEVICE..."
-                 killproc -p /var/run/snort_$DEVICE.pid /var/run
-              done
-              
-              rm /var/run/snort_* >/dev/null 2>/dev/null
-
-               # Don't report returncode of rm if snort was not started
-               exit 0
-        ;;
-                
-        status)
-                statusproc /usr/sbin/snort
-                ;;
-                
-        restart)
-                $0 stop
-                $0 start
-                ;;
-                
-        *)
-                echo "Usage: $0 {start|stop|restart|status}"
-                exit 1
-                ;;
-esac
-
-chmod 644 /var/log/snort/* 2>/dev/null
-
-# End $rc_base/init.d/snort
diff --git a/src/initscripts/system/suricata b/src/initscripts/system/suricata
new file mode 100644 (file)
index 0000000..ae434df
--- /dev/null
@@ -0,0 +1,174 @@
+#!/bin/sh
+########################################################################
+# Begin $rc_base/init.d/suricata
+#
+# Description : Suricata Initscript
+#
+# Author      : Stefan Schantl <stefan.schantl@ipfire.org>
+#
+# Version     : 01.00
+#
+# Notes       :
+#
+########################################################################
+
+. /etc/sysconfig/rc
+. ${rc_functions}
+
+PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin; export PATH
+
+eval $(/usr/local/bin/readhash /var/ipfire/suricata/settings)
+
+# Name of the firewall chain.
+FW_CHAIN="IPS"
+
+# Optional options for the Netfilter queue.
+NFQ_OPTS="--queue-bypass "
+
+# Array containing the 4 possible network zones.
+network_zones=( red green blue orange )
+
+# Mark and Mask options.
+MARK="0x70000000"
+MASK="0x70000000"
+
+# PID file of suricata.
+PID_FILE="/var/run/suricata.pid"
+
+# Function to get the amount of CPU cores of the system.
+function get_cpu_count {
+       CPUCOUNT=0
+
+       # Loop through "/proc/cpuinfo" and count the amount of CPU cores.
+       while read line; do
+               [ "$line" ] && [ -z "${line%processor*}" ]  && ((CPUCOUNT++))
+       done </proc/cpuinfo
+
+       echo $CPUCOUNT
+}
+
+# Function to create the firewall rules to pass the traffic to suricata.
+function generate_fw_rules {
+       cpu_count=$(get_cpu_count)
+
+       # Flush the firewall chain.
+       iptables -F "$FW_CHAIN"
+
+       # Loop through the array of network zones.
+       for zone in "${network_zones[@]}"; do
+               # Convert zone into upper case.
+               zone_upper=${zone^^}
+
+               # Generate variable name for checking if the IDS is
+               # enabled on the zone.
+               enable_ids_zone="ENABLE_IDS_$zone_upper"
+
+               # Check if the IDS is enabled for this network zone.
+               if [ "${!enable_ids_zone}" == "on" ]; then
+                       # Generate name of the network interface.
+                       network_device=$zone
+                       network_device+="0"
+
+                       # Assign NFQ_OPTS
+                       NFQ_OPTIONS=$NFQ_OPTS
+
+                       # Check if there are multiple cpu cores available.
+                       if [ "$cpu_count" -gt "1" ]; then
+                               # Balance beetween all queues.
+                               NFQ_OPTIONS+="--queue-balance 0:"
+                               NFQ_OPTIONS+=$(($cpu_count-1))
+                       else
+                               # Send all packets to queue 0.
+                               NFQ_OPTIONS+="--queue-num 0"
+                       fi
+
+                       # Create firewall rules to queue the traffic and pass to
+                       # the IDS.
+                       iptables -I "$FW_CHAIN" -i "$network_device" -m mark ! --mark "$MARK"/"$MASK" -j NFQUEUE $NFQ_OPTIONS
+                       iptables -I "$FW_CHAIN" -o "$network_device" -m mark ! --mark "$MARK"/"$MASK" -j NFQUEUE $NFQ_OPTIONS
+               fi
+       done
+
+       # Clear repeat bit, so that it does not confuse IPsec or QoS
+       iptables -A "${FW_CHAIN}" -j MARK --set-xmark "0x0/${MASK}"
+}
+
+# Function to flush the firewall chain.
+function flush_fw_chain {
+       # Call iptables and flush the chain
+       iptables -F "$FW_CHAIN"
+}
+
+case "$1" in
+        start)
+               # Get amount of CPU cores.
+               cpu_count=$(get_cpu_count)
+
+               # Numer of NFQUES.
+               NFQUEUES=
+
+               for i in $(seq 0 $((cpu_count-1)) ); do
+                       NFQUEUES+="-q $i "
+               done
+
+               # Check if the IDS should be started.
+               if [ "$ENABLE_IDS" == "on" ]; then
+                       # Start the IDS.
+