From patchwork Sun Jun 2 02:08:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tim FitzGeorge X-Patchwork-Id: 2276 Return-Path: Received: from mail01.ipfire.org (mail01.i.ipfire.org [172.28.1.200]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mail01.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web07.i.ipfire.org (Postfix) with ESMTPS id 29AC68C9E74 for ; Sat, 1 Jun 2019 17:08:53 +0100 (BST) Received: from mail01.i.ipfire.org (localhost [IPv6:::1]) by mail01.ipfire.org (Postfix) with ESMTP id 45GR841z22z57csf; Sat, 1 Jun 2019 17:08:52 +0100 (BST) Received: from smtp.hosts.co.uk (smtp.hosts.co.uk [85.233.160.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPS id 45GR805Z7Jz57csf for ; Sat, 1 Jun 2019 17:08:48 +0100 (BST) Received: from [95.150.182.208] (helo=aragorn.tfitzgeorge.me.uk) by smtp.hosts.co.uk with esmtpa (Exim) (envelope-from ) id 1hX6Yi-00036r-5l; Sat, 01 Jun 2019 17:08:42 +0100 From: Tim FitzGeorge To: development@lists.ipfire.org Subject: [PATCH] suricata: correct rule actions in IPS mode Date: Sat, 1 Jun 2019 17:08:17 +0100 Message-Id: <20190601160817.16358-1-ipfr@tfitzgeorge.me.uk> X-Mailer: git-send-email 2.16.4 Authentication-Results: mail01.ipfire.org; dkim=none; dmarc=none; spf=pass (mail01.ipfire.org: domain of ipfr@tfitzgeorge.me.uk designates 85.233.160.19 as permitted sender) smtp.mailfrom=ipfr@tfitzgeorge.me.uk X-Rspamd-Queue-Id: 45GR805Z7Jz57csf X-Spamd-Result: default: False [-5.38 / 11.00]; ARC_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RECEIVED_SPAMHAUS_PBL(0.00)[208.182.150.95.zen.spamhaus.org : 127.0.0.11]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; R_SPF_ALLOW(-0.20)[+ip4:85.233.160.0/27]; MIME_GOOD(-0.10)[text/plain]; RCVD_TLS_LAST(0.00)[]; DMARC_NA(0.00)[tfitzgeorge.me.uk]; TO_MATCH_ENVRCPT_SOME(0.00)[]; MX_GOOD(-0.01)[mx1.ukservers.net]; RCPT_COUNT_TWO(0.00)[2]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM(-2.96)[-0.985,0]; IP_SCORE(-0.02)[country: GB(-0.08)]; FROM_EQ_ENVFROM(0.00)[]; R_DKIM_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:8622, ipnet:85.233.160.0/19, country:GB]; RCVD_COUNT_TWO(0.00)[2]; BAYES_HAM(-3.00)[100.00%]; RCVD_IN_DNSWL_LOW(-0.10)[19.160.233.85.list.dnswl.org : 127.0.5.1] X-Rspamd-Server: mail01.i.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" In IPS mode rule actions need to be have the action 'drop' for the protection to work, however this is not appropriate for all rules. Modify the generator for oinkmaster-modify-sids.conf to leave rules with the action 'alert' here this is appropriate. Also add a script to be run on update to correct existing downloaded rules. Fixes #12086 Signed-off-by: Tim FitzGeorge Tested-by: Peter Müller --- config/cfgroot/ids-functions.pl | 44 +++++++++++++-- config/rootfiles/common/configroot | 1 + config/rootfiles/core/133/update.sh | 3 ++ config/suricata/convert-ids-modifysids-file | 84 +++++++++++++++++++++++++++++ html/cgi-bin/ids.cgi | 22 +++++++- lfs/configroot | 1 + 6 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 config/suricata/convert-ids-modifysids-file diff --git a/config/cfgroot/ids-functions.pl b/config/cfgroot/ids-functions.pl index 88734a3ca..d7f659d69 100644 --- a/config/cfgroot/ids-functions.pl +++ b/config/cfgroot/ids-functions.pl @@ -243,7 +243,7 @@ sub downloadruleset { # 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". + # Generate temporary 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(); @@ -293,6 +293,9 @@ sub downloadruleset { # Overwrite existing rules tarball with the new downloaded one. move("$tmpfile", "$rulestarball"); + # Set correct ownership for the rulesdir and files. + set_ownership("$rulestarball"); + # If we got here, everything worked fine. Return nothing. return; } @@ -726,8 +729,8 @@ sub write_used_rulefiles_file(@) { # ## Function to generate and write the file for modify the ruleset. # -sub write_modify_sids_file($) { - my ($ruleaction) = @_; +sub write_modify_sids_file($$) { + my ($ruleaction,$rulefile) = @_; # Open modify sid's file for writing. open(FILE, ">$modify_sids_file") or die "Could not write to $modify_sids_file. $!\n"; @@ -737,8 +740,39 @@ sub write_modify_sids_file($) { # 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"; + # Suricata is in IPS mode, which means that the rule actions have to be changed + # from 'alert' to 'drop', however not all rules should be changed. Some rules + # exist purely to set a flowbit which is used to convey other information, such + # as a specific type of file being downloaded, to other rulewhich then check for + # malware in that file. Rules which fall into the first category should stay as + # alert since not all flows of that type contain malware. + + if($rulefile eq 'registered' or $rulefile eq 'subscripted' or $rulefile eq 'community') { + # These types of rulesfiles contain meta-data which gives the action that should + # be used when in IPS mode. Do the following: + # + # 1. Disable all rules and set the action to 'drop' + # 2. Set the action back to 'alert' if the rule contains 'flowbits:noalert;' + # This should give rules not in the policy a reasonable default if the user + # manually enables them. + # 3. Enable rules and set actions according to the meta-data strings. + + my $policy = 'balanced'; # Placeholder to allow policy to be changed. + + print FILE < # +# # +# 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 . # +# # +############################################################################### + +use strict; + +require '/var/ipfire/general-functions.pl'; +require "${General::swroot}/ids-functions.pl"; + +# Hash which contains the IDS (suricata) settings. +my %idssettings; + +# Hash which contains the RULES settings. +my %rulessettings; + +# +## Step 1: Read IDS and rules settings. +# + +exit unless(-f $IDS::ids_settings_file and -f $IDS::rules_settings_file); + +# Read IDS settings. +&General::readhash("$IDS::ids_settings_file", \%idssettings); + +# Read rules settings. +&General::readhash("$IDS::rules_settings_file", \%rulessettings); + +# +## Step 2: Generate and write the file to modify the ruleset. +# + +my $IDS_action = "drop"; + +# Check if the traffic only should be monitored. +if ($idssettings{"MONITOR_TRAFFIC_ONLY"} eq "on") { + # Switch IDS action to alert only. + $IDS_action = "alert"; +} + +# Call subfunction and pass the desired IDS action. +&IDS::write_modify_sids_file($IDS_action, $rulessettings{RULES}); + +# Set correct ownership. +&IDS::set_ownership("$IDS::modify_sids_file"); + +# +## Step 3: 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 4: Start the IDS if enabled. +# + +# Check if the IDS should be started. +if($idssettings{"ENABLE_IDS"} eq "on") { + # Call suricatactrl and reload the rules. + &IDS::call_suricatactrl("reload"); +} diff --git a/html/cgi-bin/ids.cgi b/html/cgi-bin/ids.cgi index 00db6a0c3..1791e9beb 100644 --- a/html/cgi-bin/ids.cgi +++ b/html/cgi-bin/ids.cgi @@ -359,7 +359,7 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'save'}) { $errormessage = "$Lang::tr{'could not download latest updates'} - $Lang::tr{'system is offline'}"; } - # Check if enought free disk space is availabe. + # Check if enough free disk space is availabe. if(&IDS::checkdiskspace()) { $errormessage = "$Lang::tr{'not enough disk space'}"; } @@ -370,6 +370,22 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'save'}) { # a new ruleset. &working_notice("$Lang::tr{'ids working'}"); + &General::readhash("$IDS::ids_settings_file", \%idssettings); + + # 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($idssettings{'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, $cgiparams{'RULES'}); + # Call subfunction to download the ruleset. if(&IDS::downloadruleset()) { $errormessage = $Lang::tr{'could not download latest updates'}; @@ -609,8 +625,10 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'save'}) { $ruleaction="alert"; } + &General::readhash("$IDS::rules_settings_file", \%rulessettings); + # Write the modify sid's file and pass the taken ruleaction. - &IDS::write_modify_sids_file($ruleaction); + &IDS::write_modify_sids_file($ruleaction, $rulessettings{'RULES'}); # Check if "MONITOR_TRAFFIC_ONLY" has been changed. if($cgiparams{'MONITOR_TRAFFIC_ONLY'} ne $oldidssettings{'MONITOR_TRAFFIC_ONLY'}) { diff --git a/lfs/configroot b/lfs/configroot index d4eb545f0..227d09239 100644 --- a/lfs/configroot +++ b/lfs/configroot @@ -135,6 +135,7 @@ $(TARGET) : # Install snort to suricata converter. cp $(DIR_SRC)/config/suricata/convert-snort /usr/sbin/convert-snort + cp $(DIR_SRC)/config/suricata/convert-ids-modifysids-file /usr/sbin/convert-ids-modifysids-file # Add conntrack helper default settings for proto in FTP H323 IRC SIP TFTP; do \