Allow saving a specified list of ipsets

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2014-09-28 11:19:41 -07:00
parent 38a18ac9ac
commit 3858683e94
7 changed files with 175 additions and 66 deletions

View File

@ -428,45 +428,47 @@ do_save() {
;;
esac
case ${SAVE_IPSETS:=No} in
[Yy]es)
case ${IPSET:=ipset} in
*/*)
if [ ! -x "$IPSET" ]; then
error_message "ERROR: IPSET=$IPSET does not exist or is not executable - ipsets are not saved"
IPSET=
if ! run_it ${VARDIR}/firewall savesets ${g_restorepath}-ipsets; then
case ${SAVE_IPSETS:=No} in
[Yy]es)
case ${IPSET:=ipset} in
*/*)
if [ ! -x "$IPSET" ]; then
error_message "ERROR: IPSET=$IPSET does not exist or is not executable - ipsets are not saved"
IPSET=
fi
;;
*)
IPSET="$(mywhich $IPSET)"
[ -n "$IPSET" ] || error_message "ERROR: The ipset utility cannot be located - ipsets are not saved"
;;
esac
if [ -n "$IPSET" ]; then
if [ -f /etc/debian_version ] && [ $(cat /etc/debian_version) = 5.0.3 ]; then
#
# The 'grep -v' is a hack for a bug in ipset's nethash implementation when xtables-addons is applied to Lenny
#
hack='| grep -v /31'
else
hack=
fi
;;
*)
IPSET="$(mywhich $IPSET)"
[ -n "$IPSET" ] || error_message "ERROR: The ipset utility cannot be located - ipsets are not saved"
;;
esac
if [ -n "$IPSET" ]; then
if [ -f /etc/debian_version ] && [ $(cat /etc/debian_version) = 5.0.3 ]; then
#
# The 'grep -v' is a hack for a bug in ipset's nethash implementation when xtables-addons is applied to Lenny
#
hack='| grep -v /31'
else
hack=
if eval $IPSET -S $hack > ${VARDIR}/ipsets.tmp; then
#
# Don't save an 'empty' file
#
grep -qE -- '^(-N|create )' ${VARDIR}/ipsets.tmp && mv -f ${VARDIR}/ipsets.tmp ${g_restorepath}-ipsets
fi
fi
if eval $IPSET -S $hack > ${VARDIR}/ipsets.tmp; then
#
# Don't save an 'empty' file
#
grep -qE -- '^(-N|create )' ${VARDIR}/ipsets.tmp && mv -f ${VARDIR}/ipsets.tmp ${g_restorepath}-ipsets
fi
fi
;;
[Nn]o)
;;
*)
error_message "WARNING: Invalid value ($SAVE_IPSETS) for SAVE_IPSETS"
;;
esac
;;
[Nn]o)
;;
*)
error_message "WARNING: Invalid value ($SAVE_IPSETS) for SAVE_IPSETS"
;;
esac
fi
return $status
}

View File

@ -262,6 +262,7 @@ our %EXPORT_TAGS = (
set_global_variables
save_dynamic_chains
load_ipsets
create_save_ipsets
validate_nfobject
create_nfobjects
create_netfilter_load
@ -7995,11 +7996,77 @@ sub ensure_ipset( $ ) {
}
}
#
# Generate the save_ipsets() function
#
sub create_save_ipsets() {
my @ipsets = all_ipsets;
emit( "#\n#Save the ipsets specified by the SAVE_IPSETS setting and by dynamic zones\n#",
'save_ipsets() {' );
if ( @ipsets || @{$globals{SAVED_IPSETS}} || ( $config{SAVE_IPSETS} && have_ipset_rules ) ) {
emit( ' local file' ,
'',
' file=$1',
''
);
if ( @ipsets ) {
ensure_ipset( $_ ) for @ipsets;
}
emit( '' ,
' rm -f ${VARDIR}/ipsets.save' ,
'' );
if ( $config{SAVE_IPSETS} ) {
if ( $family == F_IPV4 ) {
emit ( ' if [ -f /etc/debian_version ] && [ $(cat /etc/debian_version) = 5.0.3 ]; then' ,
' #',
' # The \'grep -v\' is a hack for a bug in ipset\'s nethash implementation when xtables-addons is applied to Lenny' ,
' #',
' hack=\'| grep -v /31\'' ,
' else' ,
' hack=' ,
' fi' ,
'',
' if eval $IPSET -S $hack > ${VARDIR}/ipsets.tmp; then' ,
" grep -qE -- \"^(-N|create )\" \${VARDIR}/ipsets.tmp && mv -f \${VARDIR}/ipsets.tmp \$file" ,
' fi' );
} else {
emit ( ' if eval $IPSET -S > ${VARDIR}/ipsets.tmp; then' ,
" grep -qE -- \"^(-N|create )\" \${VARDIR}/ipsets.tmp && mv -f \${VARDIR}/ipsets.tmp \$file" ,
' fi' );
}
} elsif ( @ipsets || $globals{SAVED_IPSETS} ) {
emit( ' rm -f ${VARDIR}/ipsets.tmp' ,
' touch ${VARDIR}/ipsets.tmp' ,
'' );
emit( " \$IPSET -S $_ >> >> \${VARDIR}/ipsets.tmp" ) for @ipsets;
emit( " if qt \$IPSET list $_; then" ,
" \$IPSET save $_ >> \${VARDIR}/ipsets.tmp" ,
' else' ,
" error_message 'ipset $_ not saved (not found)'" ,
" fi\n" ) for @{$globals{SAVED_IPSETS}};
emit( " grep -qE -- \"(-N|^create )\" \${VARDIR}/ipsets.tmp && cat \${VARDIR}/ipsets.tmp >> \$file\n" );
emit( '' ,
"}\n" );
}
} else {
emit( ' error_message "WARNING: No ipsets were saved"',
"}\n" );
}
}
sub load_ipsets() {
my @ipsets = all_ipsets;
if ( @ipsets || ( $config{SAVE_IPSETS} && have_ipset_rules ) ) {
if ( @ipsets || @{$globals{SAVED_IPSETS}} || ( $config{SAVE_IPSETS} && have_ipset_rules ) ) {
emit ( '',
'local hack',
'',
@ -8026,9 +8093,25 @@ sub load_ipsets() {
emit ( '' );
ensure_ipset( $_ ) for @ipsets;
emit ( '' );
emit ( ' if [ -f ${VARDIR}/ipsets.save ]; then' ,
' $IPSET flush' ,
' $IPSET destroy' ,
' $IPSET restore < ${VARDIR}/ipsets.save' ,
" fi\n" ) for @{$globals{SAVED_IPSETS}};
}
} else {
ensure_ipset( $_ ) for @ipsets;
if ( @{$globals{SAVED_IPSETS}} ) {
emit ( '' );
emit ( ' if [ -f ${VARDIR}/ipsets.save ]; then' ,
' $IPSET flush' ,
' $IPSET destroy' ,
' $IPSET restore < ${VARDIR}/ipsets.save' ,
" fi\n" ) for @{$globals{SAVED_IPSETS}};
}
}
emit ( 'elif [ "$COMMAND" = restore -a -z "$g_recovering" ]; then' );
@ -8052,6 +8135,12 @@ sub load_ipsets() {
}
} else {
ensure_ipset( $_ ) for @ipsets;
emit ( ' if [ -f ${VARDIR}/ipsets.save ]; then' ,
' $IPSET flush' ,
' $IPSET destroy' ,
' $IPSET restore < ${VARDIR}/ipsets.save' ,
" fi\n" ) for @{$globals{SAVED_IPSETS}};
}
if ( @ipsets ) {
@ -8059,36 +8148,14 @@ sub load_ipsets() {
ensure_ipset( $_ ) for @ipsets;
}
emit( 'elif [ "$COMMAND" = stop ]; then' );
if ( @ipsets ) {
ensure_ipset( $_ ) for @ipsets;
emit( '' );
}
if ( $family == F_IPV4 ) {
emit ( ' if [ -f /etc/debian_version ] && [ $(cat /etc/debian_version) = 5.0.3 ]; then' ,
' #',
' # The \'grep -v\' is a hack for a bug in ipset\'s nethash implementation when xtables-addons is applied to Lenny' ,
' #',
' hack=\'| grep -v /31\'' ,
' else' ,
' hack=' ,
' fi' ,
'',
' if eval $IPSET -S $hack > ${VARDIR}/ipsets.tmp; then' ,
' grep -qE -- "^(-N|create )" ${VARDIR}/ipsets.tmp && mv -f ${VARDIR}/ipsets.tmp ${VARDIR}/ipsets.save' ,
' fi' );
} else {
emit ( ' if eval $IPSET -S > ${VARDIR}/ipsets.tmp; then' ,
' grep -qE -- "^(-N|create )" ${VARDIR}/ipsets.tmp && mv -f ${VARDIR}/ipsets.tmp ${VARDIR}/ipsets.save' ,
' fi' );
}
emit( 'elif [ "$COMMAND" = stop ]; then' ,
' save_ipsets'
);
if ( @ipsets ) {
emit( 'elif [ "$COMMAND" = refresh ]; then' );
ensure_ipset( $_ ) for @ipsets;
}
};
emit ( 'fi' ,
'' );

View File

@ -348,6 +348,7 @@ sub generate_script_3($) {
create_netfilter_load( $test );
create_arptables_load( $test ) if $have_arptables;
create_chainlist_reload( $_[0] );
create_save_ipsets;
emit "#\n# Start/Restart the Firewall\n#";

View File

@ -1106,7 +1106,8 @@ sub initialize( $;$$) {
$family == F_IPV4 ? 'shorewall' : 'shorewall6'
) if defined $shorewallrc;
$globals{SHAREDIRPL} = "$shorewallrc{SHAREDIR}/shorewall/";
$globals{SHAREDIRPL} = "$shorewallrc{SHAREDIR}/shorewall/";
$globals{SAVED_IPSETS} = [];
if ( $family == F_IPV4 ) {
$globals{SHAREDIR} = "$shorewallrc{SHAREDIR}/shorewall";
@ -5570,7 +5571,13 @@ sub get_configuration( $$$$$ ) {
unsupported_yes_no 'BRIDGING';
unsupported_yes_no_warning 'RFC1918_STRICT';
default_yes_no 'SAVE_IPSETS' , '';
unless (default_yes_no 'SAVE_IPSETS', '', '*' ) {
my @sets = (split_list( $val= $config{SAVE_IPSETS}, 'ipset' ));
$globals{SAVED_IPSETS} = \@sets;
require_capability 'IPSET_V5', 'A saved ipset list', 's';
$config{SAVE_IPSETS} = '';
}
default_yes_no 'SAVE_ARPTABLES' , '';
default_yes_no 'STARTUP_ENABLED' , 'Yes';
default_yes_no 'DELAYBLACKLISTLOAD' , '';

View File

@ -20,6 +20,7 @@ usage() {
echo " run <command> [ <parameter> ... ]"
echo " status"
echo " up <interface>"
echo " savesets <file>"
echo " version"
echo
echo "Options are:"
@ -383,6 +384,13 @@ case "$COMMAND" in
error_message "ERROR: Missing command"
fi
;;
savesets)
if [ $# -eq 2 ]; then
save_ipsets $2
else
usage 2
fi
;;
version)
[ $# -ne 1 ] && usage 2
echo $SHOREWALL_VERSION

View File

@ -2469,7 +2469,8 @@ INLINE - - - ; -j REJECT
<varlistentry>
<term><emphasis role="bold">SAVE_IPSETS=</emphasis>{<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>}</term>
role="bold">Yes</emphasis>|<emphasis
role="bold">No|<replaceable>setlist</replaceable></emphasis>}</term>
<listitem>
<para>Re-enabled in Shorewall 4.4.6. If SAVE_IPSETS=Yes, then the
@ -2478,6 +2479,10 @@ INLINE - - - ; -j REJECT
role="bold">shorewall save</emphasis> commands and restored by the
<emphasis role="bold">shorewall start</emphasis> and <emphasis
role="bold">shorewall restore</emphasis> commands.</para>
<para>Beginning with Shorewall 4.6.4, you can restrict the set of
ipsets saved by specifying a setlist (a comma-separated list of ipv4
ipset names).</para>
</listitem>
</varlistentry>

View File

@ -2122,6 +2122,25 @@ INLINE - - - ; -j REJECT
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis role="bold">SAVE_IPSETS=</emphasis>{<emphasis
role="bold">Yes</emphasis>|<emphasis
role="bold">No|<replaceable>setlist</replaceable></emphasis>}</term>
<listitem>
<para>Re-enabled in Shorewall 4.4.6. If SAVE_IPSETS=Yes, then the
current contents of your ipsets will be saved by the <emphasis
role="bold">shorewall stop</emphasis> and <emphasis
role="bold">shorewall save</emphasis> commands and restored by the
<emphasis role="bold">shorewall start</emphasis> and <emphasis
role="bold">shorewall restore</emphasis> commands.</para>
<para>Beginning with Shorewall 4.6.4, you can restrict the set of
ipsets saved by specifying a setlist (a comma-separated list of ipv6
ipset names).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis
role="bold">SHOREWALL_SHELL=</emphasis>[<emphasis>pathname</emphasis>]</term>