From f08803e29326abdfcbfc313b7da426c666afa08f Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 30 Oct 2014 18:38:45 -0700 Subject: [PATCH] Preserve counts on 'restart' without compilation. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 56 ++++++++++++++++++++-------- Shorewall/Perl/Shorewall/Compiler.pm | 43 +++++++++++---------- Shorewall/Perl/Shorewall/Config.pm | 20 ++++++++++ Shorewall/Perl/prog.footer | 1 + Shorewall/install.sh | 1 + 5 files changed, 84 insertions(+), 37 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 2f435d828..3dfbcdd4a 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -7909,14 +7909,21 @@ sub emitr1( $$ ) { sub save_dynamic_chains() { - my $tool; + my $tool = $family == F_IPV4 ? '${IPTABLES}' : '${IP6TABLES}'; emit ( 'if [ "$COMMAND" = restart -o "$COMMAND" = refresh ]; then' ); push_indent; - if ( have_capability 'IPTABLES_S' ) { - $tool = $family == F_IPV4 ? '${IPTABLES}' : '${IP6TABLES}'; + if ( $config{SAVE_COUNTERS} ) { + my $utility = $family == F_IPV4 ? 'iptables-restore' : 'ip6tables-restore'; + emit( 'if [ "$COMMAND" = restart; then', + " ${tool}-save --counters > \${VARDIR}/.$utility}-input", + "fi\n" ); + + } + + if ( have_capability 'IPTABLES_S' ) { emit <<"EOF"; if chain_exists 'UPnP -t nat'; then $tool -t nat -S UPnP | tail -n +2 > \${VARDIR}/.UPnP @@ -7936,6 +7943,7 @@ else rm -f \${VARDIR}/.dynamic fi EOF + } else { $tool = $family == F_IPV4 ? '${IPTABLES}-save' : '${IP6TABLES}-save'; @@ -8240,14 +8248,24 @@ sub create_netfilter_load( $ ) { '# Create the input to iptables-restore/ip6tables-restore and pass that input to the utility', '#', 'setup_netfilter()', - '{' - ); + '{' ); + + emit( ' local option' ) if $config{SAVE_COUNTERS}; push_indent; my $utility = $family == F_IPV4 ? 'iptables-restore' : 'ip6tables-restore'; my $UTILITY = $family == F_IPV4 ? 'IPTABLES_RESTORE' : 'IP6TABLES_RESTORE'; + if ( $config{SAVE_COUNTERS} ) { + emit( '', + 'if [ "$COMMAND" = restart -a -n "$g_sha1sum" -a -f ${VARDIR}/.sha1sum -a $g_sha1sum = $(cat ${VARDIR}/.sha1sum) ]; then', + ' option="--counters"', + 'else' + ); + push_indent; + } + save_progress_message "Preparing $utility input..."; emit ''; @@ -8304,20 +8322,28 @@ sub create_netfilter_load( $ ) { } enter_cmd_mode; + + pop_indent, emit "fi\n" if $config{SAVE_COUNTERS}; # # Now generate the actual ip[6]tables-restore command # emit( 'exec 3>&-', - '', - '[ -n "$g_debug_iptables" ] && command=debug_restore_input || command=$' . $UTILITY, - '', - 'progress_message2 "Running $command..."', - '', - "cat \${VARDIR}/.${utility}-input | \$command # Use this nonsensical form to appease SELinux", - 'if [ $? != 0 ]; then', - qq( fatal_error "iptables-restore Failed. Input is in \${VARDIR}/.${utility}-input"), - "fi\n" - ); + '' ); + + if ( $config{SAVE_COUNTERS} ) { + emit( '[ -n "$g_debug_iptables" ] && command=debug_restore_input || command=$' . $UTILITY . ' $option' ); + } else { + emit( '[ -n "$g_debug_iptables" ] && command=debug_restore_input || command=$' . $UTILITY ); + } + + emit( '', + 'progress_message2 "Running $command..."', + '', + "cat \${VARDIR}/.${utility}-input | \$command # Use this nonsensical form to appease SELinux", + 'if [ $? != 0 ]; then', + qq( fatal_error "iptables-restore Failed. Input is in \${VARDIR}/.${utility}-input"), + "fi\n" + ); pop_indent; diff --git a/Shorewall/Perl/Shorewall/Compiler.pm b/Shorewall/Perl/Shorewall/Compiler.pm index 2951b148f..dd9e8f1d2 100644 --- a/Shorewall/Perl/Shorewall/Compiler.pm +++ b/Shorewall/Perl/Shorewall/Compiler.pm @@ -512,45 +512,44 @@ EOF # # Use a parameter list rather than 'here documents' to avoid an extra blank line # - emit( -' run_refreshed_exit', -' do_iptables -N shorewall' ); + emit( ' run_refreshed_exit', + ' do_iptables -N shorewall' ); emit ( ' do_iptables -A shorewall -m recent --set --name %CURRENTTIME' ) if have_capability 'RECENT_MATCH'; emit( -" set_state Started $config_dir", -' [ $0 = ${VARDIR}/firewall ] || cp -f $(my_pathname) ${VARDIR}/firewall', -'else', -' setup_netfilter' + " set_state Started $config_dir", + ' [ $0 = ${VARDIR}/firewall ] || cp -f $(my_pathname) ${VARDIR}/firewall'); + emit( ' [ -n "$g_sha1sum" ] && echo "$g_sha1sum" > ${VARDIR}/.sha1sum || rm -f ${VARDIR}/.sha1sum' ) if $config{SAVE_COUNTERS}; + + emit( 'else', + ' setup_netfilter' ); push_indent; emit 'setup_arptables' if $have_arptables; setup_load_distribution; pop_indent; - emit<<'EOF'; - conditionally_flush_conntrack -EOF + emit( " conditionally_flush_conntrack\n" ); + push_indent; initialize_switches; setup_forwarding( $family , 0 ); pop_indent; - emit<<"EOF"; - run_start_exit - do_iptables -N shorewall -EOF + emit( ' run_start_exit', + ' do_iptables -N shorewall', + '' ); - emit ( ' do_iptables -A shorewall -m recent --set --name %CURRENTTIME' ) if have_capability 'RECENT_MATCH'; + emit( ' do_iptables -A shorewall -m recent --set --name %CURRENTTIME' ) if have_capability 'RECENT_MATCH'; - emit<<"EOF"; - set_state Started $config_dir - my_pathname=\$(my_pathname) - [ \$my_pathname = \${VARDIR}/firewall ] || cp -f \$my_pathname \${VARDIR}/firewall - run_started_exit -fi -EOF + emit( " set_state Started $config_dir", + ' my_pathname=$(my_pathname)', + ' [ $my_pathname = ${VARDIR}/firewall ] || cp -f $my_pathname ${VARDIR}/firewall' ); + + emit( ' [ -n "$g_sha1sum" ] && echo "$g_sha1sum" > ${VARDIR}/.sha1sum || rm -f ${VARDIR}/.sha1sum' ) if $config{SAVE_COUNTERS}; + emit( ' run_started_exit', + "fi\n" ); emit<<'EOF'; date > ${VARDIR}/restarted diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 88a510561..79744ba6b 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -40,6 +40,7 @@ use Cwd qw(abs_path getcwd); use autouse 'Carp' => qw(longmess confess); use Scalar::Util 'reftype'; use FindBin; +use Digest::SHA qw(sha1_hex); our @ISA = qw(Exporter); # @@ -88,6 +89,7 @@ our @EXPORT = qw( our @EXPORT_OK = qw( $shorewall_dir initialize shorewall); our %EXPORT_TAGS = ( internal => [ qw( create_temp_script + generate_sha1 finalize_script enable_script disable_script @@ -1761,6 +1763,13 @@ sub create_temp_script( $$ ) { } +# Generate the SHA1 digest of the (incomplete script) +# +sub generate_sha1() { + my $data = `cat $tempfile`; + sha1_hex $data; +} + # # Finalize the script file # @@ -1770,6 +1779,17 @@ sub finalize_script( $ ) { $script = 0; if ( $file ne '-' ) { + if ( $config{SAVE_COUNTERS} ) { + my $sha1sum = generate_sha1; + @ARGV = ( $tempfile ); + $^I = ''; + + while ( <> ) { + s/g_sha1sum=/g_sha1sum=$sha1sum/; + print; + } + } + rename $tempfile, $file or fatal_error "Cannot Rename $tempfile to $file: $!"; chmod 0700, $file or fatal_error "Cannot secure $file for execute access"; progress_message3 "Shorewall configuration compiled to $file" unless $export; diff --git a/Shorewall/Perl/prog.footer b/Shorewall/Perl/prog.footer index 0c44dd420..772a2661a 100644 --- a/Shorewall/Perl/prog.footer +++ b/Shorewall/Perl/prog.footer @@ -86,6 +86,7 @@ g_purge=$PURGE g_noroutes=$NOROUTES g_timestamp=$TIMESTAMP g_recovering=$RECOVERING +g_sha1sum= initialize diff --git a/Shorewall/install.sh b/Shorewall/install.sh index 088206304..c1176d668 100755 --- a/Shorewall/install.sh +++ b/Shorewall/install.sh @@ -332,6 +332,7 @@ if [ $PRODUCT = shorewall ]; then if ! perl -e 'use Digest::SHA;' 2> /dev/null ; then if perl -e 'use Digest::SHA1;' 2> /dev/null ; then sed -i 's/Digest::SHA/Digest::SHA1/' Perl/Shorewall/Chains.pm + sed -i 's/Digest::SHA/Digest::SHA1/' Perl/Shorewall/Config.pm DIGEST=SHA1 else echo "ERROR: Shorewall $VERSION requires either Digest::SHA or Digest::SHA1" >&2