From patchwork Fri Apr 3 14:25:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Schantl X-Patchwork-Id: 2881 Return-Path: Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web04.haj.ipfire.org (Postfix) with ESMTPS id 48v2Jm3WLsz3wdp for ; Fri, 3 Apr 2020 14:25:12 +0000 (UTC) Received: from mail02.haj.ipfire.org (mail02.haj.ipfire.org [172.28.1.201]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) client-signature ECDSA (P-384)) (Client CN "mail02.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail01.ipfire.org (Postfix) with ESMTPS id 48v2Jk3j0Qz23Z; Fri, 3 Apr 2020 14:25:10 +0000 (UTC) Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 48v2Jk0VJnz2yjX; Fri, 3 Apr 2020 14:25:10 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384 client-signature ECDSA (P-384) client-digest SHA384) (Client CN "mail01.haj.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 48v2Jg5fp6z2xJ9 for ; Fri, 3 Apr 2020 14:25:07 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPSA id 48v2Jf3XMCz1YK; Fri, 3 Apr 2020 14:25:06 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1585923906; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=ObR5LqlIFoqHS5sPascc3PC1b1JRiN1+5YB6s7WPnlk=; b=WlTgkz0B3rIJhui8mfO/XTJkEsO6Ks3EFr79RnbKg9N5RRqJTFzHlSgqpNC/y6wwNC8HY4 k687Ny0lwIeUxfDw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1585923906; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=ObR5LqlIFoqHS5sPascc3PC1b1JRiN1+5YB6s7WPnlk=; b=rmmCwzxUbq12c0p/zinSrjtH0rDhjmOYQg1l22/WjtHYYZ7F0QGZ8eiIBHRYZhGepXWlUO tfYKPyaYYPWse1YprIIc1fbhm6ZLp7BY9TszUGfJk7Ujl/vcFMptm2M+ts/c91O19mJAON cWo2YIOESCM1BtX+TOFaBOye+Ek7+eCZZci6Q2J03bmX4vJJobRM6ppBIGMkI+Vb8duXMe oi1Vki6iFD1XU/xGhV1KL1e1h+6M15dVtfGeWzj0Q8cHpfpt+AboxZh5hJQTUmdPC57bS1 wpyUc9q2EW6Uef0/QJ8wg7y5lNHuN/ISEXYlhKuFJX3M+jlAIwZYxNMUJVuwaA== From: Stefan Schantl To: development@lists.ipfire.org Subject: [PATCH] IDS: Dynamically generate and import the HTTP ports. Date: Fri, 3 Apr 2020 16:25:01 +0200 Message-Id: <20200403142501.8604-1-stefan.schantl@ipfire.org> MIME-Version: 1.0 Authentication-Results: mail01.ipfire.org; auth=pass smtp.mailfrom=stefan.schantl@ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.29 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" With this commit suricata reads the HTTP port declarations from a newly introduced external file (/var/ipfire/suricata/suricata-http-ports.yaml). This file dynamically will be generated. HTTP ports always are the default port "80" and "81" for update Accelerator and HTTP access to the WUI. In case the Web-proxy is used, the configured proxy port and/or Transparent Proxy port also will be declared as a HTTP port and written to that file. In case one of the proxy ports will be changed, the HTTP port file will be re-generated and suricate restarted if launched. Also if an old backup with snort will be restored the convert script handles the generation of the HTTP ports file. Finally the suricata-generate-http-ports-file as a tiny script which simply generates the http ports file and needs to be launched during the installation of a core update. (The script will no be required anymore, so it could be deleted afterwards.) Fixes #12308. Signed-off-by: Stefan Schantl --- config/cfgroot/ids-functions.pl | 51 +++++++++++++++++++ config/suricata/convert-snort | 18 +++++-- .../suricata-generate-http-ports-file | 47 +++++++++++++++++ config/suricata/suricata.yaml | 4 +- html/cgi-bin/ids.cgi | 5 +- html/cgi-bin/proxy.cgi | 36 ++++++++++++- 6 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 config/suricata/suricata-generate-http-ports-file diff --git a/config/cfgroot/ids-functions.pl b/config/cfgroot/ids-functions.pl index af8a927e0..5bc3e77ec 100644 --- a/config/cfgroot/ids-functions.pl +++ b/config/cfgroot/ids-functions.pl @@ -37,6 +37,9 @@ our $homenet_file = "$settingsdir/suricata-homenet.yaml"; # File where the addresses of the used DNS servers are stored. our $dns_servers_file = "$settingsdir/suricata-dns-servers.yaml"; +# File where the HTTP ports definition is stored. +our $http_ports_file = "$settingsdir/suricata-http-ports.yaml"; + # File which contains the enabled sids. our $enabled_sids_file = "$settingsdir/oinkmaster-enabled-sids.conf"; @@ -89,6 +92,10 @@ my @suricatactrl_cmds = ( 'start', 'stop', 'restart', 'reload', 'fix-rules-dir', # Array with supported cron intervals. my @cron_intervals = ('off', 'daily', 'weekly' ); +# Array which contains the HTTP ports, which statically will be declared as HTTP_PORTS in the +# http_ports_file. +my @http_ports = ('80', '81'); + # ## Function to check and create all IDS related files, if the does not exist. # @@ -738,6 +745,50 @@ sub generate_dns_servers_file() { close(FILE); } +# +# Function to generate and write the file which contains the HTTP_PORTS definition. +# +sub generate_http_ports_file() { + my %proxysettings; + + # Read-in proxy settings + &General::readhash("${General::swroot}/proxy/advanced/settings", \%proxysettings); + + # Check if the proxy is enabled. + if (( -e "${General::swroot}/proxy/enable") || (-e "${General::swroot}/proxy/enable_blue")) { + # Add the proxy port to the array of HTTP ports. + push(@http_ports, $proxysettings{'PROXY_PORT'}); + } + + # Check if the transparent mode of the proxy is enabled. + if ((-e "${General::swroot}/proxy/transparent") || (-e "${General::swroot}/proxy/transparent_blue")) { + # Add the transparent proxy port to the array of HTTP ports. + push(@http_ports, $proxysettings{'TRANSPARENT_PORT'}); + } + + # Format HTTP_PORTS declaration. + my $line = ""; + + # Generate line which will be written to the http ports file. + $line = join(",", @http_ports); + + # Open file to store the HTTP_PORTS. + open(FILE, ">$http_ports_file") or die "Could not open $http_ports_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 HTTP_PORTS declaration to the file. + print FILE "HTTP_PORTS:\t\"[$line]\"\n"; + + # Close file handle. + close(FILE); +} + # ## Function to generate and write the file for used rulefiles. # diff --git a/config/suricata/convert-snort b/config/suricata/convert-snort index ee52548e9..3e938137e 100644 --- a/config/suricata/convert-snort +++ b/config/suricata/convert-snort @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2019 IPFire Development Team # +# Copyright (C) 2020 IPFire Development Team # # # # 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 # @@ -298,7 +298,17 @@ if (-f $IDS::rulestarball) { &IDS::set_ownership("$IDS::dns_servers_file"); # -## Step 11: Setup automatic ruleset updates. +## Step 11: Generate file which contains the HTTP ports. +# + +# Call subfunction to generate the file. +&IDS::generate_http_ports_file(); + +# Set correct ownership for the http_ports_file. +&IDS::set_ownership("$IDS::http_ports_file"); + +# +## Step 12: Setup automatic ruleset updates. # # Check if a ruleset is configured. @@ -308,7 +318,7 @@ if($rulessettings{"RULES"}) { } # -## Step 12: Grab used ruleset files from snort config file and convert +## Step 13: Grab used ruleset files from snort config file and convert ## them into the new format. # @@ -354,7 +364,7 @@ close(SNORTCONF); &IDS::write_used_rulefiles_file(@enabled_rule_files); # -## Step 13: Start the IDS if enabled. +## Step 14: Start the IDS if enabled. # # Check if the IDS should be started. diff --git a/config/suricata/suricata-generate-http-ports-file b/config/suricata/suricata-generate-http-ports-file new file mode 100644 index 000000000..f0d6bb823 --- /dev/null +++ b/config/suricata/suricata-generate-http-ports-file @@ -0,0 +1,47 @@ +#!/usr/bin/perl +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2012 IPFire Development Team # +# # +# 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"; + +exit unless(-f $IDS::ids_settings_file and -f $IDS::rules_settings_file); + +# +## Step 1: Generate and write the HTTP ports file. +# + +# Call subfunction to generate the HTTP ports file. +&IDS::generate_http_ports_file(); + +# Set correct ownership. +&IDS::set_ownership("$IDS::http_ports_file"); + +# +## Step 2: Restart suricata if necessary. +# + +# Check if the IDS should be started. +if(&IDS::ids_is_running()) { + # Call suricatactrl and reload the rules. + &IDS::call_suricatactrl("restart"); +} diff --git a/config/suricata/suricata.yaml b/config/suricata/suricata.yaml index 54016a887..973b2686c 100644 --- a/config/suricata/suricata.yaml +++ b/config/suricata/suricata.yaml @@ -30,7 +30,9 @@ vars: ENIP_SERVER: "$HOME_NET" port-groups: - HTTP_PORTS: "[80,81]" + # Incluse HTTP_PORTS declaration from external file. + include: /var/ipfire/suricata/suricata-http-ports.yaml + SHELLCODE_PORTS: "!80" ORACLE_PORTS: 1521 SSH_PORTS: "[22,222]" diff --git a/html/cgi-bin/ids.cgi b/html/cgi-bin/ids.cgi index c3e5eefdb..df7138e08 100644 --- a/html/cgi-bin/ids.cgi +++ b/html/cgi-bin/ids.cgi @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2018 IPFire Team # +# Copyright (C) 2007-2020 IPFire Team # # # # 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 # @@ -625,6 +625,9 @@ if ($cgiparams{'RULESET'} eq $Lang::tr{'save'}) { # Generate file to the store the DNS servers. &IDS::generate_dns_servers_file(); + # Generate file to store the HTTP ports. + &IDS::generate_http_ports_file(); + # Write the modify sid's file and pass the taken ruleaction. &IDS::write_modify_sids_file(); diff --git a/html/cgi-bin/proxy.cgi b/html/cgi-bin/proxy.cgi index 06aca579b..73646a5ae 100644 --- a/html/cgi-bin/proxy.cgi +++ b/html/cgi-bin/proxy.cgi @@ -2,7 +2,7 @@ ############################################################################### # # # IPFire.org - A linux based firewall # -# Copyright (C) 2007-2013 IPFire Team # +# Copyright (C) 2007-2020 IPFire Team # # # # 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 # @@ -37,6 +37,8 @@ require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; +require "${General::swroot}/ids-functions.pl"; + my @squidversion = `/usr/sbin/squid -v`; my $http_port='81'; my $https_port='444'; @@ -550,6 +552,29 @@ ERROR: if ($proxysettings{'VALID'} eq 'yes') { + # Determine if suricata may needs to be restarted. + my $suricata_proxy_ports_changed; + + # Check if the IDS is running + if(&IDS::ids_is_running()) { + my %oldproxysettings; + + # Read-in current proxy settings and store them as oldsettings hash. + &General::readhash("${General::swroot}/proxy/advanced/settings", \%oldproxysettings); + + # Check if the proxy port has been changed. + unless ($proxysettings{'PROXY_PORT'} eq $oldproxysettings{'PROXY_PORT'}) { + # Port has changed, suricata needs to be adjusted. + $suricata_proxy_ports_changed = 1; + } + + # Check if the transparent port has been changed. + unless ($proxysettings{'TRANSPARENT_PORT'} eq $oldproxysettings{'TRANSPARENT_PORT'}) { + # Transparent port has changed, suricata needs to be adjusted. + $suricata_proxy_ports_changed = 1; + } + } + &write_acls; delete $proxysettings{'SRC_SUBNETS'}; @@ -627,6 +652,15 @@ ERROR: if ($proxysettings{'ACTION'} eq $Lang::tr{'advproxy save and restart'}) { system('/usr/local/bin/squidctrl restart >/dev/null 2>&1'); } if ($proxysettings{'ACTION'} eq $Lang::tr{'proxy reconfigure'}) { system('/usr/local/bin/squidctrl reconfigure >/dev/null 2>&1'); } + + # Check if the suricata_proxy_ports_changed flag has been set. + if ($suricata_proxy_ports_changed) { + # Re-generate HTTP ports file. + &IDS::generate_http_ports_file(); + + # Restart suricata. + &IDS::call_suricatactrl("restart"); + } } }