From 88a799b860783bab7263d123c0f667bccced0321 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 18 Apr 2020 11:27:15 -0700 Subject: [PATCH 01/12] Allow IFUPDOWN=1 to work on Debian Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Providers.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index 4f4ad59bb..34b6ff37e 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -2064,12 +2064,12 @@ sub compile_updown() { push_indent; emit( q(if [ "$state" = started ]; then) , - q( if [ "$COMMAND" = up ]; then) , + q( if [ "$COMMAND" = up ]; then) , q( progress_message3 "Attempting enable on interface $1") , q( COMMAND=enable) , q( detect_configuration $1), q( enable_provider $1), - q( elif [ "$PHASE" != post-down ]; then # pre-down or not Debian) , + q( elif [ "$PHASE" != pre-down ]; then # post-down or not Debian) , q( progress_message3 "Attempting disable on interface $1") , q( COMMAND=disable) , q( detect_configuration $1), From 32ca53706cb17dd547f0a4f44b70ccac6201438c Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 18 Apr 2020 12:43:27 -0700 Subject: [PATCH 02/12] Don't run the 'up' command twice when an dual-stack interface comes up Signed-off-by: Tom Eastep --- Shorewall-init/ifupdown.debian.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Shorewall-init/ifupdown.debian.sh b/Shorewall-init/ifupdown.debian.sh index 65390c5db..36077f70c 100644 --- a/Shorewall-init/ifupdown.debian.sh +++ b/Shorewall-init/ifupdown.debian.sh @@ -127,6 +127,17 @@ esac [ -n "$LOGFILE" ] || LOGFILE=/dev/null for PRODUCT in $PRODUCTS; do + if [ -n "$ADDRFAM" -a ${COMMAND} = up ]; then + case $PRODUCT in + *6*) + [ ${ADDRFAM} = inet6 ] || continue + ;; + *) + [ ${ADDRFAM} = inet ] || continue + ;; + esac + fi + setstatedir if [ -x $VARLIB/$PRODUCT/firewall ]; then From 7d4d409799668d39e849baaecc5a2c4e45738a91 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 19 Apr 2020 12:18:44 -0700 Subject: [PATCH 03/12] Don't install ifupdown script in if-down.d on Debian - Proper location for the script is if-post-down Signed-off-by: Tom Eastep --- Shorewall-init/install.sh | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Shorewall-init/install.sh b/Shorewall-init/install.sh index d24d98c43..3162fab2a 100755 --- a/Shorewall-init/install.sh +++ b/Shorewall-init/install.sh @@ -357,11 +357,9 @@ fi if [ $HOST = debian ]; then if [ -n "${DESTDIR}" ]; then make_parent_directory ${DESTDIR}${ETC}/network/if-up.d 0755 - make_parent_directory ${DESTDIR}${ETC}/network/if-down.d 0755 make_parent_directory ${DESTDIR}${ETC}/network/if-post-down.d 0755 elif [ $configure -eq 0 ]; then make_parent_directory ${DESTDIR}${CONFDIR}/network/if-up.d 0755 - make_parent_directory ${DESTDIR}${CONFDIR}/network/if-down.d 0755 make_parent_directory ${DESTDIR}${CONFDIR}/network/if-post-down.d 0755 fi @@ -425,11 +423,10 @@ case $HOST in debian) if [ $configure -eq 1 ]; then install_file ifupdown ${DESTDIR}/etc/network/if-up.d/shorewall 0544 - install_file ifupdown ${DESTDIR}/etc/network/if-down.d/shorewall 0544 install_file ifupdown ${DESTDIR}/etc/network/if-post-down.d/shorewall 0544 + rm -f ${DESTDIR}/etc/network/if-down.d/shorewall else install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-up.d/shorewall 0544 - install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-down.d/shorewall 0544 install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-post-down.d/shorewall 0544 fi ;; From 3c06be28bee20d4c5c6ee06365738ddf462746d0 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 19 Apr 2020 12:28:16 -0700 Subject: [PATCH 04/12] Delete unnecessary check if IPv6 interface_is_usable() Signed-off-by: Tom Eastep --- Shorewall/Perl/lib.runtime | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Shorewall/Perl/lib.runtime b/Shorewall/Perl/lib.runtime index d8bd65b1d..f654be373 100644 --- a/Shorewall/Perl/lib.runtime +++ b/Shorewall/Perl/lib.runtime @@ -1113,7 +1113,7 @@ interface_is_usable() # $1 = interface status=0 if [ "$1" != lo ]; then - if interface_is_up $1 && [ "$(find_first_interface_address_if_any $1)" != :: ] && [ -z "$($IP -$g_family link list dev $1 2> /dev/null | fgrep 'state DOWN')" ]; then + if interface_is_up $1 && [ "$(find_first_interface_address_if_any $1)" != :: ]; then if [ "$COMMAND" != enable ]; then [ ! -f ${VARDIR}/${1}_disabled ] && run_isusable_exit $1 status=$? From cabadd4846366e75809d050f8dcb195f9eddfeba Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 19 Apr 2020 14:31:12 -0700 Subject: [PATCH 05/12] Honor 'wait= when enabling an interface. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Zones.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index 29e870606..fe949b0fa 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -2028,7 +2028,7 @@ sub verify_required_interfaces( $ ) { push_indent; - emit( 'start|reload|restore)' ); + emit( 'start|reload|restore|enable)' ); push_indent; From 16af9ee2ded92f8f308ee62eece969a6ee1c0744 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 19 Apr 2020 15:19:13 -0700 Subject: [PATCH 06/12] Revert "Don't install ifupdown script in if-down.d on Debian" This reverts commit 7d4d409799668d39e849baaecc5a2c4e45738a91. --- Shorewall-init/install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Shorewall-init/install.sh b/Shorewall-init/install.sh index 3162fab2a..d24d98c43 100755 --- a/Shorewall-init/install.sh +++ b/Shorewall-init/install.sh @@ -357,9 +357,11 @@ fi if [ $HOST = debian ]; then if [ -n "${DESTDIR}" ]; then make_parent_directory ${DESTDIR}${ETC}/network/if-up.d 0755 + make_parent_directory ${DESTDIR}${ETC}/network/if-down.d 0755 make_parent_directory ${DESTDIR}${ETC}/network/if-post-down.d 0755 elif [ $configure -eq 0 ]; then make_parent_directory ${DESTDIR}${CONFDIR}/network/if-up.d 0755 + make_parent_directory ${DESTDIR}${CONFDIR}/network/if-down.d 0755 make_parent_directory ${DESTDIR}${CONFDIR}/network/if-post-down.d 0755 fi @@ -423,10 +425,11 @@ case $HOST in debian) if [ $configure -eq 1 ]; then install_file ifupdown ${DESTDIR}/etc/network/if-up.d/shorewall 0544 + install_file ifupdown ${DESTDIR}/etc/network/if-down.d/shorewall 0544 install_file ifupdown ${DESTDIR}/etc/network/if-post-down.d/shorewall 0544 - rm -f ${DESTDIR}/etc/network/if-down.d/shorewall else install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-up.d/shorewall 0544 + install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-down.d/shorewall 0544 install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-post-down.d/shorewall 0544 fi ;; From 057a2dec704a58e4f6a8442ada486522032bc624 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 19 Apr 2020 18:44:19 -0700 Subject: [PATCH 07/12] Correct typo with bad consequences Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 215f418c0..7b25e94dd 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -8875,7 +8875,7 @@ sub ensure_ipsets( @ ) { if ( $globals{DBL_TIMEOUT} ne '' && $_[0] eq $globals{DBL_IPSET} ) { shift; - emit( qq( if ! qt \$IPSET list $globals{DBL_IPSET}; then)); + emit( qq( if qt \$IPSET list $globals{DBL_IPSET}; then)); push_indent; From 086f7a0e6d0ab8861b53dcdd4a2127089ea8633d Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Mon, 20 Apr 2020 09:11:03 -0700 Subject: [PATCH 08/12] Only destroy ipsets that will be restored Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 7b25e94dd..3b2906eb8 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -9065,10 +9065,14 @@ sub create_load_ipsets() { # Requires V5 or later # emit( '' , - " for set in \$(\$IPSET save | grep '$select' | cut -d' ' -f2); do" , - ' $IPSET flush $set' , - ' $IPSET destroy $set' , - " done" , + ' if [ -f ${VARDIR}/ipsets.save ]; then' , + ' while read ${VARDIR}/ipsets.save verb set; do' , + ' if [ $verb = create ]; then' , + ' $IPSET flush $set' , + ' $IPSET destroy $set' , + ' fi' , + ' done' , + ' fi', ); } else { # From 18360471ab305555c6b0cae0e76d487b184b1a72 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Mon, 20 Apr 2020 09:23:34 -0700 Subject: [PATCH 09/12] Have Shorewall-init restore ipsets before stopping the firewalls Signed-off-by: Tom Eastep --- Shorewall-init/shorewall-init | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Shorewall-init/shorewall-init b/Shorewall-init/shorewall-init index 89ecdeee9..b3e0bad6f 100644 --- a/Shorewall-init/shorewall-init +++ b/Shorewall-init/shorewall-init @@ -65,6 +65,11 @@ shorewall_start () { local STATEDIR printf "Initializing \"Shorewall-based firewalls\": " + + if [ -n "$SAVE_IPSETS" -a -f "$SAVE_IPSETS" ]; then + ipset -R < "$SAVE_IPSETS" + fi + for PRODUCT in $PRODUCTS; do if setstatedir; then # @@ -78,10 +83,6 @@ shorewall_start () { fi done - if [ -n "$SAVE_IPSETS" -a -f "$SAVE_IPSETS" ]; then - ipset -R < "$SAVE_IPSETS" - fi - return 0 } From e14798b4a25879b400197ad6c4ad6b478f3367c8 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Mon, 20 Apr 2020 10:29:36 -0700 Subject: [PATCH 10/12] Make OPTIMIZE=16 an order of magnitude faster Signed-off-by: Tom Eastep --- Shorewall-init/shorewall-init | 16 +++-- Shorewall/Perl/Shorewall/Chains.pm | 99 ++++++++++++++++++------------ 2 files changed, 69 insertions(+), 46 deletions(-) diff --git a/Shorewall-init/shorewall-init b/Shorewall-init/shorewall-init index b3e0bad6f..4e8e8c1dc 100644 --- a/Shorewall-init/shorewall-init +++ b/Shorewall-init/shorewall-init @@ -25,6 +25,7 @@ # ############################################################################### # set the STATEDIR variable + setstatedir() { local statedir if [ -f ${CONFDIR}/${PRODUCT}/vardir ]; then @@ -59,8 +60,9 @@ else exit 1 fi -# Initialize the firewall -shorewall_start () { +# Initialize the firewalls + +shorewall_init_start () { local PRODUCT local STATEDIR @@ -86,12 +88,14 @@ shorewall_start () { return 0 } -# Clear the firewall -shorewall_stop () { +# Clear the firewalls + +shorewall_init_stop () { local PRODUCT local STATEDIR printf "Clearing \"Shorewall-based firewalls\": " + for PRODUCT in $PRODUCTS; do if setstatedir; then # @@ -119,10 +123,10 @@ shorewall_stop () { case "$1" in start) - shorewall_start + shorewall_init_start ;; stop) - shorewall_stop + shorewall_init_stop ;; *) echo "Usage: $0 {start|stop}" diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 3b2906eb8..8c45ce7f9 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -726,6 +726,7 @@ our %opttype = ( rule => CONTROL, 'icmpv6-type' => UNIQUE, comment => CONTROL, + digest => CONTROL, policy => MATCH, state => EXCLUSIVE, @@ -3521,6 +3522,33 @@ sub irule_to_string( $ ) { $string; } +# +# This one omits the comment +# +sub irule_to_string1( $ ) { + my ( $ruleref ) = @_; + + return $ruleref->{cmd} if exists $ruleref->{cmd}; + + my $string = ''; + + for ( grep ! ( get_opttype( $_, 0 ) & ( CONTROL | TARGET ) ), @{$ruleref->{matches}}) { + my $value = $ruleref->{$_}; + if ( reftype $value ) { + $string .= "$_=" . join( ',', @$value ) . ' '; + } else { + $string .= "$_=$value "; + } + } + + if ( $ruleref->{target} ) { + $string .= join( ' ', " -$ruleref->{jump}", $ruleref->{target} ); + $string .= join( '', ' ', $ruleref->{targetopts} ) if $ruleref->{targetopts}; + } + + $string; +} + sub calculate_digest( $ ) { my $chainref = shift; my $rules = ''; @@ -4193,7 +4221,7 @@ sub get_multi_sports( $ ) { # Return an array of keys for the passed rule. 'dport', 'comment', and 'origin' are omitted; # sub get_keys( $ ) { - my %skip = ( dport => 1, comment => 1, origin => 1 ); + my %skip = ( dport => 1, comment => 1, origin => 1, digest => 1 ); sort grep ! $skip{$_}, keys %{$_[0]}; } @@ -4374,64 +4402,55 @@ sub delete_duplicates { my @rules; my $chainref = shift; my $lastrule = @_; - my $baseref = pop; my $ruleref; my %skip = ( comment => 1, origin => 1 ); + for ( @_ ) { + $_->{digest} = sha1_hex irule_to_string1( $_ ); + } + + my $baseref = pop; + while ( @_ ) { my $docheck; my $duplicate = 0; if ( $baseref->{mode} == CAT_MODE && $baseref->{target} ) { my $ports1; - my @keys1 = sort( grep ! $skip{$_}, keys( %$baseref ) ); + my $bad_key; my $rulenum = @_; my $adjacent = 1; - - { - RULE: + my $digest = $baseref->{digest}; - while ( --$rulenum >= 0 ) { - $ruleref = $_[$rulenum]; + for ( grep ! $skip{$_}, keys( %$baseref ) ) { + $bad_key = 1, last if $bad_match{$_}; + } - last unless $ruleref->{mode} == CAT_MODE; + while ( --$rulenum >= 0 ) { + $ruleref = $_[$rulenum]; - my @keys2 = sort(grep ! $skip{$_}, keys( %$ruleref ) ); - - next unless @keys1 == @keys2 ; + last unless $ruleref->{mode} == CAT_MODE; + next unless $digest eq $ruleref->{digest}; my $keynum = 0; - if ( $adjacent > 0 ) { - # - # There are no non-duplicate rules between this rule and the base rule - # - for my $key ( @keys1 ) { - next RULE unless $key eq $keys2[$keynum++]; - next RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} ); - } - } else { - # - # There are non-duplicate rules between this rule and the base rule - # - for my $key ( @keys1 ) { - next RULE unless $key eq $keys2[$keynum++]; - next RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} ); - last RULE if $bad_match{$key}; - } - } + unless ( $adjacent > 0 ) { # - # This rule is a duplicate + # There are non-duplicate rules between this rule and the base rule # - $duplicate = 1; - # - # Increment $adjacent so that the continue block won't set it to zero - # - $adjacent++; - - } continue { - $adjacent--; + last if $bad_key; } + # + # This rule is a duplicate + # + $duplicate = 1; + # + # Increment $adjacent so that the continue block won't set it to zero + # + $adjacent++; + + } continue { + $adjacent--; } } @@ -4471,7 +4490,7 @@ sub get_conntrack( $ ) { # Return an array of keys for the passed rule. 'conntrack', 'comment' & 'origin' are omitted; # sub get_keys1( $ ) { - my %skip = ( comment => 1, origin => 1 , 'conntrack --ctstate' => 1 ); + my %skip = ( comment => 1, origin => 1 , digest => 1, 'conntrack --ctstate' => 1 ); sort grep ! $skip{$_}, keys %{$_[0]}; } From 39de88563f25beef45cd9548550c73775006cba0 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Tue, 21 Apr 2020 13:02:56 -0700 Subject: [PATCH 11/12] Cleanup of Optimize 16 change Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 8c45ce7f9..0e98f69a5 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -4218,7 +4218,7 @@ sub get_multi_sports( $ ) { } # -# Return an array of keys for the passed rule. 'dport', 'comment', and 'origin' are omitted; +# Return an array of keys for the passed rule. 'dport', 'comment', 'origin' and 'digest' are omitted; # sub get_keys( $ ) { my %skip = ( dport => 1, comment => 1, origin => 1, digest => 1 ); @@ -4432,7 +4432,6 @@ sub delete_duplicates { last unless $ruleref->{mode} == CAT_MODE; next unless $digest eq $ruleref->{digest}; - my $keynum = 0; unless ( $adjacent > 0 ) { # @@ -4487,7 +4486,7 @@ sub get_conntrack( $ ) { } # -# Return an array of keys for the passed rule. 'conntrack', 'comment' & 'origin' are omitted; +# Return an array of keys for the passed rule. 'conntrack', 'comment', 'origin' and 'digest' are omitted; # sub get_keys1( $ ) { my %skip = ( comment => 1, origin => 1 , digest => 1, 'conntrack --ctstate' => 1 ); From 0a9d2d9a3358241a805cb41046b7a19cea81d8c2 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Tue, 21 Apr 2020 13:02:56 -0700 Subject: [PATCH 12/12] Don't install script in if_down.d on Debian - Eliminates need for Debian-specific code in generated script Signed-off-by: Tom Eastep --- Shorewall-init/install.sh | 5 +---- Shorewall/Perl/Shorewall/Providers.pm | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Shorewall-init/install.sh b/Shorewall-init/install.sh index d24d98c43..3162fab2a 100755 --- a/Shorewall-init/install.sh +++ b/Shorewall-init/install.sh @@ -357,11 +357,9 @@ fi if [ $HOST = debian ]; then if [ -n "${DESTDIR}" ]; then make_parent_directory ${DESTDIR}${ETC}/network/if-up.d 0755 - make_parent_directory ${DESTDIR}${ETC}/network/if-down.d 0755 make_parent_directory ${DESTDIR}${ETC}/network/if-post-down.d 0755 elif [ $configure -eq 0 ]; then make_parent_directory ${DESTDIR}${CONFDIR}/network/if-up.d 0755 - make_parent_directory ${DESTDIR}${CONFDIR}/network/if-down.d 0755 make_parent_directory ${DESTDIR}${CONFDIR}/network/if-post-down.d 0755 fi @@ -425,11 +423,10 @@ case $HOST in debian) if [ $configure -eq 1 ]; then install_file ifupdown ${DESTDIR}/etc/network/if-up.d/shorewall 0544 - install_file ifupdown ${DESTDIR}/etc/network/if-down.d/shorewall 0544 install_file ifupdown ${DESTDIR}/etc/network/if-post-down.d/shorewall 0544 + rm -f ${DESTDIR}/etc/network/if-down.d/shorewall else install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-up.d/shorewall 0544 - install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-down.d/shorewall 0544 install_file ifupdown ${DESTDIR}${CONFDIR}/network/if-post-down.d/shorewall 0544 fi ;; diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index 34b6ff37e..3f17e2d3d 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -2069,7 +2069,7 @@ sub compile_updown() { q( COMMAND=enable) , q( detect_configuration $1), q( enable_provider $1), - q( elif [ "$PHASE" != pre-down ]; then # post-down or not Debian) , + q( else) , q( progress_message3 "Attempting disable on interface $1") , q( COMMAND=disable) , q( detect_configuration $1),