public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
* [PATCH 1/3] ids-functions.pl: Generate ipset based whitelist.
@ 2022-04-06 19:12 Stefan Schantl
  2022-04-06 19:12 ` [PATCH 2/3] suricata: Handle ipset based whitelist in initscript Stefan Schantl
  2022-04-06 19:12 ` [PATCH 3/3] rules.pl: Prevent from cleanup the IPSWHITELIST set Stefan Schantl
  0 siblings, 2 replies; 3+ messages in thread
From: Stefan Schantl @ 2022-04-06 19:12 UTC (permalink / raw)
  To: development

[-- Attachment #1: Type: text/plain, Size: 4312 bytes --]

Signed-off-by: Stefan Schantl <stefan.schantl(a)ipfire.org>
---
 config/cfgroot/ids-functions.pl | 68 ++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 35 deletions(-)

diff --git a/config/cfgroot/ids-functions.pl b/config/cfgroot/ids-functions.pl
index 94dccc8ae..d8ce5d0a0 100644
--- a/config/cfgroot/ids-functions.pl
+++ b/config/cfgroot/ids-functions.pl
@@ -90,7 +90,7 @@ our $sid_msg_file = "$rulespath/sid-msg.map";
 our $local_rules_file = "$rulespath/local.rules";
 
 # File which contains the rules to whitelist addresses on suricata.
-our $whitelist_file = "$rulespath/whitelist.rules";
+our $whitelist_file = "$settingsdir/whitelist.conf";
 
 # File which contains a list of all supported ruleset sources.
 # (Sourcefire, Emergingthreads, etc..)
@@ -125,7 +125,7 @@ my @cron_intervals = ('off', 'daily', 'weekly' );
 my @http_ports = ('80', '81');
 
 # Array which contains a list of rulefiles which always will be included if they exist.
-my @static_included_rulefiles = ('local.rules', 'whitelist.rules');
+my @static_included_rulefiles = ('local.rules');
 
 # Array which contains a list of allways enabled application layer protocols.
 my @static_enabled_app_layer_protos = ('app-layer', 'decoder', 'files', 'stream');
@@ -1199,9 +1199,6 @@ sub _cleanup_rulesdir() {
 		# We only want files.
 		next unless (-f "$rulespath/$file");
 
-		# Skip rules file for whitelisted hosts.
-		next if ("$rulespath/$file" eq $whitelist_file);
-
 		# Skip rules file with local rules.
 		next if ("$rulespath/$file" eq $local_rules_file);
 
@@ -1707,46 +1704,47 @@ sub get_suricata_enabled_app_layer_protos() {
 #
 sub generate_ignore_file() {
 	my %ignored = ();
+	my @ignored_addresses = ();
 
-	# SID range 1000000-1999999 Reserved for Local Use
-	# Put your custom rules in this range to avoid conflicts
-	my $sid = 1500000;
+	# Name of the ipset.
+	my $list = "IPSWHITELIST";
 
 	# 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";
+	# Loop through the entire hash and add the enabled addresses to
+	# the array of ignored addresses..
+	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))) {
+				# Add the address to the array of ignored addresses.
+				push(@ignored_addresses, $address);
+			}
+		}
+	}
 
-	# Config file header.
-	print FILE "# Autogenerated file.\n";
-	print FILE "# All user modifications will be overwritten.\n\n";
+	# Open the the whitelist file for writing.
+	open(FILE, ">", "$whitelist_file") or die "Could not write to $whitelist_file. $!\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\"\; bypass; sid:$sid\;)\n";
-
-					# Increment sid.
-					$sid++;
-				}
-			}
+	# Check if the array of ignored addresses contains any elements.
+	if(@ignored_addresses) {
+		# Write file header.
+		print FILE "create $list hash:net family inet -exist\n";
+		print FILE "flush $list\n";
+
+		# Loop through the array of ignored addresses.
+		foreach my $address (@ignored_addresses) {
+			print FILE "add $list $address\n";
 		}
 	}
 
+	# Close filehandle.
 	close(FILE);
 }
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 2/3] suricata: Handle ipset based whitelist in initscript.
  2022-04-06 19:12 [PATCH 1/3] ids-functions.pl: Generate ipset based whitelist Stefan Schantl
@ 2022-04-06 19:12 ` Stefan Schantl
  2022-04-06 19:12 ` [PATCH 3/3] rules.pl: Prevent from cleanup the IPSWHITELIST set Stefan Schantl
  1 sibling, 0 replies; 3+ messages in thread
From: Stefan Schantl @ 2022-04-06 19:12 UTC (permalink / raw)
  To: development

[-- Attachment #1: Type: text/plain, Size: 3853 bytes --]

Signed-off-by: Stefan Schantl <stefan.schantl(a)ipfire.org>
---
 src/initscripts/system/suricata | 42 +++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/src/initscripts/system/suricata b/src/initscripts/system/suricata
index 938ea66de..5ede405ce 100644
--- a/src/initscripts/system/suricata
+++ b/src/initscripts/system/suricata
@@ -44,6 +44,15 @@ enabled_ips_zones=()
 # PID file of suricata.
 PID_FILE="/var/run/suricata.pid"
 
+# File which contains the ipset of whitelisted hosts.
+WHITELIST_FILE="/var/ipfire/suricata/whitelist.conf"
+
+# Name of the ipset set
+IPSET_SET="IPSWHITELIST"
+
+IPS_BYPASS_MARK="0x40000000"
+IPS_BYPASS_MASK="0x40000000"
+
 # Function to get the amount of CPU cores of the system.
 function get_cpu_count {
 	CPUCOUNT=0
@@ -135,16 +144,44 @@ function generate_fw_rules {
 	# Flush the firewall chains.
 	flush_fw_chain
 
+	if [ -s "$WHITELIST_FILE" ]; then
+		# Load the whitelist file.
+		ipset restore -f "$WHITELIST_FILE"
+	fi
+
 	# Check if the array of enabled_ips_zones contains any elements.
 	if [[ ${enabled_ips_zones[@]} ]]; then
 		# Loop through the array and create firewall rules.
 		for enabled_ips_zone in "${enabled_ips_zones[@]}"; do
+			# Check if the whitelist file is not empty.
+			if [ -s "$WHITELIST_FILE" ]; then
+				# Create rules to handle whitelisted hosts.
+				iptables -w -A "$IPS_INPUT_CHAIN" -i "$enabled_ips_zone" -m set --match-set $IPSET_SET src -j CONNMARK --set-xmark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK
+				iptables -w -A "$IPS_INPUT_CHAIN" -i "$enabled_ips_zone" -m set --match-set $IPSET_SET dst -j CONNMARK --set-xmark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK
+				iptables -w -A "$IPS_INPUT_CHAIN" -i "$enabled_ips_zone" -m connmark --mark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK -j RETURN
+
+				iptables -w -A "$IPS_OUTPUT_CHAIN" -o "$enabled_ips_zone" -m set --match-set $IPSET_SET src -j CONNMARK --set-xmark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK
+				iptables -w -A "$IPS_OUTPUT_CHAIN" -o "$enabled_ips_zone" -m set --match-set $IPSET_SET src -j CONNMARK --set-xmark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK
+				iptables -w -A "$IPS_OUTPUT_CHAIN" -o "$enabled_ips_zone" -m connmark --mark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK -j RETURN
+			fi
+
 			# Create rules queue input and output related traffic and pass it to the IPS.
 			iptables -w -A "$IPS_INPUT_CHAIN" -i "$enabled_ips_zone" -j NFQUEUE $NFQ_OPTIONS
 			iptables -w -A "$IPS_OUTPUT_CHAIN" -o "$enabled_ips_zone" -j NFQUEUE $NFQ_OPTIONS
 
 			# Create rules which are required to handle forwarded traffic.
 			for enabled_ips_zone_forward in "${enabled_ips_zones[@]}"; do
+				# Check if the whetelist file is not empty.
+				if [ -s "$WHITELIST_FILE" ]; then
+					# Create rules to handle whitelisted hosts.
+					iptables -w -A "$IPS_FORWARD_CHAIN" -i "$enabled_ips_zone" -o "$enabled_ips_zone_forward" \
+						-m set --match-set $IPSET_SET src -j CONNMARK --set-xmark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK
+					iptables -w -A "$IPS_FORWARD_CHAIN" -i "$enabled_ips_zone" -o "$enabled_ips_zone_forward" \
+						-m set --match-set $IPSET_SET dst -j CONNMARK --set-xmark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK
+					iptables -w -A "$IPS_FORWARD_CHAIN" -i "$enabled_ips_zone" -o "$enabled_ips_zone_forward" \
+						-m connmark --mark $IPS_BYPASS_MARK/$IPS_BYPASS_MASK
+				fi
+
 				iptables -w -A "$IPS_FORWARD_CHAIN" -i "$enabled_ips_zone" -o "$enabled_ips_zone_forward" -j NFQUEUE $NFQ_OPTIONS
 			done
 		done
@@ -188,6 +225,11 @@ case "$1" in
 		# Flush firewall chain.
 		flush_fw_chain
 
+		# Unload the ipset set.
+		if [ -s "$WHITELIST_FILE" ]; then
+			ipset destroy $IPSET_SET 2>/dev/null
+		fi
+
 		# Sometimes suricata not correct shutdown. So killall.
 		killall -KILL /usr/bin/suricata 2>/dev/null
 
-- 
2.30.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 3/3] rules.pl: Prevent from cleanup the IPSWHITELIST set.
  2022-04-06 19:12 [PATCH 1/3] ids-functions.pl: Generate ipset based whitelist Stefan Schantl
  2022-04-06 19:12 ` [PATCH 2/3] suricata: Handle ipset based whitelist in initscript Stefan Schantl
@ 2022-04-06 19:12 ` Stefan Schantl
  1 sibling, 0 replies; 3+ messages in thread
From: Stefan Schantl @ 2022-04-06 19:12 UTC (permalink / raw)
  To: development

[-- Attachment #1: Type: text/plain, Size: 680 bytes --]

Init the IPSWHITELIST set as loaded to prevent from destroying
during cleanup.

Signed-off-by: Stefan Schantl <stefan.schantl(a)ipfire.org>
---
 config/firewall/rules.pl | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl
index 19dc7a6d1..0591a47be 100644
--- a/config/firewall/rules.pl
+++ b/config/firewall/rules.pl
@@ -73,7 +73,10 @@ my %confignatfw=();
 my %locationsettings = (
 	"LOCATIONBLOCK_ENABLED" => "off"
 );
-my %ipset_loaded_sets = ();
+my %ipset_loaded_sets = (
+	"IPSWHITELIST" => "1",
+);
+
 my @ipset_used_sets = ();
 
 my $configfwdfw		= "${General::swroot}/firewall/config";
-- 
2.30.2


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-04-06 19:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-06 19:12 [PATCH 1/3] ids-functions.pl: Generate ipset based whitelist Stefan Schantl
2022-04-06 19:12 ` [PATCH 2/3] suricata: Handle ipset based whitelist in initscript Stefan Schantl
2022-04-06 19:12 ` [PATCH 3/3] rules.pl: Prevent from cleanup the IPSWHITELIST set Stefan Schantl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox