public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
From: Michael Tremer <michael.tremer@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH 1/2] rules.pl: Allow dynamic destory of loaded but unused ipset sets.
Date: Tue, 01 Mar 2022 13:23:22 +0000	[thread overview]
Message-ID: <EE7A19D9-9C87-41DB-B364-0EB5178514B2@ipfire.org> (raw)
In-Reply-To: <20220227134903.1828-1-stefan.schantl@ipfire.org>

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

Hello,

> On 27 Feb 2022, at 13:49, Stefan Schantl <stefan.schantl(a)ipfire.org> wrote:
> 
> Instead of stupidly destroying all ipsets, we now grab the already loaded sets
> and compare them with the loaded sets during runtime of the script.
> 
> So we are now able to determine which sets are not longer required and
> safely can destroy (unload) at a later time.
> 
> This saves us from taking care about dropping/flushing rules which are
> based on ipset before we can destroy them - because only unused sets are
> affected.
> 
> Signed-off-by: Stefan Schantl <stefan.schantl(a)ipfire.org>
> Inspired-by: Tim FitzGeorge <ipfr(a)tfitzgeorge.me.uk>

LOL. This isn’t an official tag :)

But nevertheless:

Reviewed-by: Michael Tremer <michael.tremer(a)ipfire.org>

> ---
> config/firewall/rules.pl | 68 ++++++++++++++++++++++++++++++----------
> 1 file changed, 52 insertions(+), 16 deletions(-)
> 
> diff --git a/config/firewall/rules.pl b/config/firewall/rules.pl
> index 927c1f2ba..7a7c8ed31 100644
> --- a/config/firewall/rules.pl
> +++ b/config/firewall/rules.pl
> @@ -70,7 +70,8 @@ my %confignatfw=();
> my %locationsettings = (
> 	"LOCATIONBLOCK_ENABLED" => "off"
> );
> -my %loaded_ipset_lists=();
> +my %ipset_loaded_sets = ();
> +my @ipset_used_sets = ();
> 
> my $configfwdfw		= "${General::swroot}/firewall/config";
> my $configinput	    = "${General::swroot}/firewall/input";
> @@ -114,12 +115,12 @@ undef (@dummy);
> &main();
> 
> sub main {
> +	# Get currently used ipset sets.
> +	&ipset_get_sets();
> +
> 	# Flush all chains.
> 	&flush();
> 
> -	# Destroy all existing ipsets.
> -	run("$IPSET destroy");
> -
> 	# Prepare firewall rules.
> 	if (! -z  "${General::swroot}/firewall/input"){
> 		&buildrules(\%configinputfw);
> @@ -137,6 +138,9 @@ sub main {
> 	# Reload firewall policy.
> 	run("/usr/sbin/firewall-policy");
> 
> +	# Cleanup not longer needed ipset sets.
> +	&ipset_cleanup();
> +
> 	#Reload firewall.local if present
> 	if ( -f '/etc/sysconfig/firewall.local'){
> 		run("/etc/sysconfig/firewall.local reload");
> @@ -189,9 +193,6 @@ sub flush {
> 	run("$IPTABLES -t nat -F $CHAIN_NAT_SOURCE");
> 	run("$IPTABLES -t nat -F $CHAIN_NAT_DESTINATION");
> 	run("$IPTABLES -t mangle -F $CHAIN_MANGLE_NAT_DESTINATION_FIX");
> -
> -	# Flush LOCATIONBLOCK chain.
> -	run("$IPTABLES -F LOCATIONBLOCK");
> }
> 
> sub buildrules {
> @@ -639,7 +640,8 @@ sub time_convert_to_minutes {
> }
> 
> sub locationblock {
> -	# The LOCATIONBLOCK chain now gets flushed by the flush() function.
> +	# Flush LOCATIONBLOCK chain.
> +	run("$IPTABLES -F LOCATIONBLOCK");
> 
> 	# If location blocking is not enabled, we are finished here.
> 	if ($locationsettings{'LOCATIONBLOCK_ENABLED'} ne "on") {
> @@ -669,7 +671,7 @@ sub locationblock {
> 			&ipset_restore($location);
> 
> 			# Call iptables and create rule to use the loaded ipset list.
> -			run("$IPTABLES -A LOCATIONBLOCK -m set --match-set CC_$location src -j DROP");
> +			run("$IPTABLES -A LOCATIONBLOCK -m set --match-set $location src -j DROP");
> 		}
> 	}
> }
> @@ -887,24 +889,58 @@ sub firewall_is_in_subnet {
> 	return 0;
> }
> 
> +sub ipset_get_sets () {
> +	# Get all currently used ipset lists and store them in an array.
> +	my @output = `$IPSET -n list`;
> +
> +	# Loop through the temporary array.
> +	foreach my $set (@output) {
> +		# Remove any newlines.
> +		chomp($set);
> +
> +		# Add the set the array of used sets.
> +		push(@ipset_used_sets, $set);
> +	}
> +
> +	# Display used sets in debug mode.
> +	if($DEBUG) {
> +		print "Used ipset sets:\n";
> +		print "@ipset_used_sets\n\n";
> +	}
> +}
> +
> sub ipset_restore ($) {
> -	my ($list) = @_;
> +	my ($set) = @_;
> 
> 	my $file_prefix = "ipset4";
> -	my $db_file = "$Location::Functions::ipset_db_directory/$list.$file_prefix";
> +	my $db_file = "$Location::Functions::ipset_db_directory/$set.$file_prefix";
> 
> -	# Check if the network list already has been loaded.
> -	if($loaded_ipset_lists{$list}) {
> +	# Check if the set already has been loaded.
> +	if($ipset_loaded_sets{$set}) {
> 		# It already has been loaded - so there is nothing to do.
> 		return;
> 	}
> 
> 	# Check if the generated file exists.
> 	if (-f $db_file) {
> -		# Run ipset and restore the list of the given country code.
> +		# Run ipset and restore the given set.
> 		run("$IPSET restore < $db_file");
> 
> -		# Store the restored list name to the hash to prevent from loading it again.
> -		$loaded_ipset_lists{$list} = "1";
> +		# Store the restored set to the hash to prevent from loading it again.
> +		$ipset_loaded_sets{$set} = "1";
> +	}
> +}
> +
> +sub ipset_cleanup () {
> +	# Loop through the array of used sets.
> +	foreach my $set (@ipset_used_sets) {
> +		# Check if this set is still in use.
> +		#
> +		# In this case an entry in the loaded sets hash exists.
> +		unless($ipset_loaded_sets{$set}) {
> +			# Entry does not exist, so this set is not longer
> +			# used and can be destroyed.
> +			run("$IPSET destroy $set");
> +		}
> 	}
> }
> -- 
> 2.30.2
> 


      parent reply	other threads:[~2022-03-01 13:23 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-27 13:49 Stefan Schantl
2022-02-27 13:49 ` [PATCH 2/2] firewall: Move dropping hostile networks to rules.pl Stefan Schantl
2022-03-01 13:23   ` Michael Tremer
2022-03-01 13:23 ` Michael Tremer [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=EE7A19D9-9C87-41DB-B364-0EB5178514B2@ipfire.org \
    --to=michael.tremer@ipfire.org \
    --cc=development@lists.ipfire.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox