diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index a8ec48fea..33248ed77 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -16,6 +16,8 @@ Changes in 3.3.6 8) Make colon after system optional in the 'export' command. +9) Restore 'try' command and improve 'safe-' commands. + Changes in 3.3.5 1) Restore default route when there are no 'balance' providers. diff --git a/Shorewall/compiler b/Shorewall/compiler index fd76716ae..9a60cf08e 100755 --- a/Shorewall/compiler +++ b/Shorewall/compiler @@ -4483,36 +4483,45 @@ stop_firewall() { *) set +x - RESTOREPATH=\${VARDIR}/\$RESTOREFILE + if [ "\$RESTOREFILE" = NONE ]; then + COMMAND=clear + clear_firewall + echo "\$PRODUCT Cleared" - if [ -x \$RESTOREPATH ]; then + kill \$\$ + exit 2 + else + RESTOREPATH=\${VARDIR}/\$RESTOREFILE - if [ -x \${RESTOREPATH}-ipsets ]; then - progress_message2 Restoring Ipsets... - # - # We must purge iptables to be sure that there are no - # references to ipsets - # - for table in mangle nat filter; do - \$IPTABLES -t \$table -F - \$IPTABLES -t \$table -X - done + if [ -x \$RESTOREPATH ]; then - \${RESTOREPATH}-ipsets - fi + if [ -x \${RESTOREPATH}-ipsets ]; then + progress_message2 Restoring Ipsets... + # + # We must purge iptables to be sure that there are no + # references to ipsets + # + for table in mangle nat filter; do + \$IPTABLES -t \$table -F + \$IPTABLES -t \$table -X + done - echo Restoring \${PRODUCT:=Shorewall}... + \${RESTOREPATH}-ipsets + fi - if \$RESTOREPATH restore; then - echo "\$PRODUCT restored from \$RESTOREPATH" - set_state "Started" - else - set_state "Unknown" - fi + echo Restoring \${PRODUCT:=Shorewall}... - kill \$\$ - exit 2 - fi + if \$RESTOREPATH restore; then + echo "\$PRODUCT restored from \$RESTOREPATH" + set_state "Started" + else + set_state "Unknown" + fi + + kill \$\$ + exit 2 + fi + fi ;; esac @@ -4889,7 +4898,7 @@ __EOF__ set_state "Cleared" - logger "Shorewall Cleared" + logger "\$PRODUCT Cleared" } # diff --git a/Shorewall/lib.cli b/Shorewall/lib.cli index c2d1cbcaa..a5b8ff29c 100644 --- a/Shorewall/lib.cli +++ b/Shorewall/lib.cli @@ -93,9 +93,9 @@ validate_restorefile() # $* = label error_message "ERROR: $@ must specify a simple file name: $RESTOREFILE" exit 2 ;; - .safe) + .safe|.try) ;; - .*) + .*|NONE) error_message "ERROR: Reserved File Name: $RESTOREFILE" exit 2 ;; diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 562512582..42c6898ce 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -67,9 +67,16 @@ Other Changes in 3.3.6 Shorewall will use that support for the destination port when generating rules from entries in the /etc/shorewall/tcrules file. -5) The 'try' command has been removed. See the Migration - Considerations for information about how to accomplish the same - thing as 'try' in a better way. +5) The 'safe-start' and 'safe-restart' command have been + improved. Both now accept an optional directory name; if supplied, + Shorewall will look first in that directory for configuration + files. + + The commands have also been enhanced to only restore the + configuration once in the event of a failure. Previously, if there + was a current 'safe' command in effect, then that configuration + would be restored on a failure and then the last-running + configuration would be restored. 6) The syntax of the 'export' command has been made slightly friendlier. diff --git a/Shorewall/shorewall b/Shorewall/shorewall index fd43fd851..f170c8b90 100755 --- a/Shorewall/shorewall +++ b/Shorewall/shorewall @@ -64,6 +64,13 @@ # shorewall show capabilities Display iptables/kernel capabilities # shorewall version Display the installed version id # shorewall check [ -e ] [ ] Dry-run compilation. +# shorewall try [ ] Try a new configuration and if +# it doesn't work, revert to the +# standard one. If a timeout is supplied +# the command reverts back to the +# standard configuration after that many +# seconds have elapsed after successfully +# starting the new configuration. # shorewall logwatch [ refresh-interval ] Monitor the local log for Shorewall # messages. # shorewall drop
... Temporarily drop all packets from the @@ -97,11 +104,11 @@ # Displays the decimal equivalent of an IP # address and vice versa. # -# shorewall safe-start Starts the firewall and promtp for a c +# shorewall safe-start [ ] Starts the firewall and promtp for a c # confirmation to accept or reject the new # configuration # -# shorewall safe-restart Restarts the firewall and prompt for a +# shorewall safe-restart [ ] Restarts the firewall and prompt for a # confirmation to accept or reject the new # configuration # @@ -649,7 +656,27 @@ safe_commands() { esac done - [ $# -eq 0 ] || usage 2 + case $# in + 0) + ;; + 1) + [ -n "$SHOREWALL_DIR" ] && usage 2 + + if [ ! -d $1 ]; then + if [ -e $1 ]; then + echo "$1 is not a directory" >&2 && exit 2 + else + echo "Directory $1 does not exist" >&2 && exit 2 + fi + fi + + SHOREWALL_DIR=$1 + export SHOREWALL_DIR + ;; + *) + usage 1 + ;; + esac if [ -z "$STARTUP_ENABLED" ]; then error_message "ERROR: Startup is disabled" @@ -668,7 +695,7 @@ safe_commands() { # the command is safe-start but the firewall is already running error_message "Shorewall is already started" mutex_off - exit 1 + exit 0 fi if [ "$COMMAND" = "safe-start" -o -z "$running" ]; then @@ -687,41 +714,165 @@ safe_commands() { exit $status fi - RESTOREFILE=.safe - RESTOREPATH=${VARDIR}/.safe - - save_config - case $command in start) + export RESTOREFILE=NONE progress_message3 "Starting..." ;; restart) + export RESTOREFILE=.safe + RESTOREPATH=${VARDIR}/.safe + save_config progress_message3 "Restarting..." ;; esac - ${VARDIR}/.$command $command + if ${VARDIR}/.$command $command; then - echo -n "Do you want to accept the new firewall configuration? [y/n] " + echo -n "Do you want to accept the new firewall configuration? [y/n] " - if read_yesno_with_timeout; then - echo "New configuration has been accepted" - else - if [ "$command" = "restart" ]; then - ${VARDIR}/.safe restore + if read_yesno_with_timeout; then + echo "New configuration has been accepted" else - ${VARDIR}/.$command clear + if [ "$command" = "restart" ]; then + ${VARDIR}/.safe restore + else + ${VARDIR}/.$command clear + fi + + mutex_off + echo "New configuration has been rejected and the old one restored" + exit 2 fi - mutex_off - echo "New configuration has been rejected and the old one restored" - exit 2 fi mutex_off } +# +# 'try' Command Executor +# +try_command() { + local finished=0 timeout= + + handle_directory() { + [ -n "$SHOREWALL_DIR" ] && usage 2 + + if [ ! -d $1 ]; then + if [ -e $1 ]; then + echo "$1 is not a directory" >&2 && exit 2 + else + echo "Directory $1 does not exist" >&2 && exit 2 + fi + fi + + SHOREWALL_DIR=$1 + export SHOREWALL_DIR + } + + while [ $finished -eq 0 -a $# -gt 0 ]; do + option=$1 + case $option in + -*) + option=${option#-} + + while [ -n "$option" ]; do + case $option in + -) + finished=1 + option= + ;; + n*) + NOROUTES=Yes + option=${option#n} + ;; + *) + usage 1 + ;; + esac + done + shift + ;; + *) + finished=1 + ;; + esac + done + + case $# in + 0) + usage 1 + ;; + 1) + handle_directory $1 + ;; + 2) + handle_directory $1 + timeout=$2 + ;; + *) + usage 1 + ;; + esac + + if [ -z "$STARTUP_ENABLED" ]; then + error_message "ERROR: Startup is disabled" + exit 2 + fi + + mutex_on + + if shorewall_is_started; then + running=Yes + else + running= + fi + + if [ -z "$running" ]; then + # shorewall is not started yet + command="start" + else + # the firewall is already running + command="restart" + fi + + progress_message3 "Compiling..." + + if ! $SHOREWALL_SHELL ${SHAREDIR}/compiler $debugging nolock compile ${VARDIR}/.$command; then + status=$? + mutex_off + exit $status + fi + + case $command in + start) + export RESTOREFILE=NONE + progress_message3 "Starting..." + ;; + restart) + export RESTOREFILE=.try + RESTOREPATH=${VARDIR}/.try + save_config + progress_message3 "Restarting..." + ;; + esac + + if ${VARDIR}/.$command $command && [ -n "$timeout" ]; then + sleep $timeout + + if [ "$command" = "restart" ]; then + ${VARDIR}/.try restore + else + ${VARDIR}/.$command clear + fi + fi + + mutex_off + + return 0 +} + # # [Re]load command executor # @@ -915,9 +1066,10 @@ usage() # $1 = exit status echo " start [ -f ] [ -n ] [ ]" echo " stop" echo " status" + echo " try [ ]" echo " version" - echo " safe-start" - echo " safe-restart" + echo " safe-start [ ]" + echo " safe-restart [ ]" echo exit $1 } @@ -1191,6 +1343,10 @@ case "$COMMAND" in version) echo $version ;; + try) + shift + try_command $@ + ;; logwatch) logwatch_command $@ ;; @@ -1249,6 +1405,7 @@ case "$COMMAND" in esac RESTOREPATH=${VARDIR}/$RESTOREFILE + mutex_off [ "$nolock" ] || mutex_on