############################################################################### # Code imported from /usr/share/shorewall/prog.footer ############################################################################### # # Clear Proxy Arp # delete_proxyarp() { if [ -f ${VARDIR}/proxyarp ]; then while read address interface external haveroute; do qt arp -i $external -d $address pub [ -z "${haveroute}${NOROUTES}" ] && qt $IP -4 route del $address dev $interface f=/proc/sys/net/ipv4/conf/$interface/proxy_arp [ -f $f ] && echo 0 > $f done < ${VARDIR}/proxyarp fi rm -f ${VARDIR}/proxyarp } # # Remove all Shorewall-added rules # clear_firewall() { stop_firewall setpolicy INPUT ACCEPT setpolicy FORWARD ACCEPT setpolicy OUTPUT ACCEPT run_iptables -F echo 1 > /proc/sys/net/ipv4/ip_forward if [ -n "$DISABLE_IPV6" ]; then if [ -x $IPTABLES ]; then $IP6TABLES -P INPUT ACCEPT 2> /dev/null $IP6TABLES -P OUTPUT ACCEPT 2> /dev/null $IP6TABLES -P FORWARD ACCEPT 2> /dev/null fi fi run_clear_exit set_state "Cleared" logger -p kern.info "$PRODUCT Cleared" } # # Issue a message and stop/restore the firewall # fatal_error() { echo " ERROR: $@" >&2 if [ $LOG_VERBOSE -gt 1 ]; then timestamp="$(date +'%_b %d %T') " echo "${timestamp} ERROR: $@" >> $STARTUP_LOG fi stop_firewall [ -n "$TEMPFILE" ] && rm -f $TEMPFILE exit 2 } # # Issue a message and stop # startup_error() # $* = Error Message { echo " ERROR: $@: Firewall state not changed" >&2 case $COMMAND in start) logger -p kern.err "ERROR:$PRODUCT start failed:Firewall state not changed" ;; restart) logger -p kern.err "ERROR:$PRODUCT restart failed:Firewall state not changed" ;; restore) logger -p kern.err "ERROR:$PRODUCT restore failed:Firewall state not changed" ;; esac if [ $LOG_VERBOSE -gt 1 ]; then timestamp="$(date +'%_b %d %T') " case $COMMAND in start) echo "${timestamp} ERROR:$PRODUCT start failed:Firewall state not changed" >> $STARTUP_LOG ;; restart) echo "${timestamp} ERROR:$PRODUCT restart failed:Firewall state not changed" >> $STARTUP_LOG ;; restore) echo "${timestamp} ERROR:$PRODUCT restore failed:Firewall state not changed" >> $STARTUP_LOG ;; esac fi kill $$ exit 2 } # # Run iptables and if an error occurs, stop/restore the firewall # run_iptables() { local status while [ 1 ]; do $IPTABLES $@ status=$? [ $status -ne 4 ] && break done if [ $status -ne 0 ]; then error_message "ERROR: Command \"$IPTABLES $@\" Failed" stop_firewall exit 2 fi } # # Run iptables retrying exit status 4 # do_iptables() { local status while [ 1 ]; do $IPTABLES $@ status=$? [ $status -ne 4 ] && return $status; done } # # Run iptables and if an error occurs, stop/restore the firewall # run_ip() { if ! $IP -4 $@; then error_message "ERROR: Command \"$IP -4 $@\" Failed" stop_firewall exit 2 fi } # # Run tc and if an error occurs, stop/restore the firewall # run_tc() { if ! $TC $@ ; then error_message "ERROR: Command \"$TC $@\" Failed" stop_firewall exit 2 fi } # # Restore the rules generated by 'drop','reject','logdrop', etc. # restore_dynamic_rules() { if [ -f ${VARDIR}/save ]; then progress_message2 "Setting up dynamic rules..." rangematch='source IP range' while read target ignore1 ignore2 address ignore3 rest; do case $target in DROP|reject|logdrop|logreject) case $rest in $rangematch*) run_iptables -A dynamic -m iprange --src-range ${rest#source IP range} -j $target ;; *) if [ -z "$rest" ]; then run_iptables -A dynamic -s $address -j $target else error_message "WARNING: Unable to restore dynamic rule \"$target $ignore1 $ignore2 $address $ignore3 $rest\"" fi ;; esac ;; esac done < ${VARDIR}/save fi } # # Get a list of all configured broadcast addresses on the system # get_all_bcasts() { $IP -f inet addr show 2> /dev/null | grep 'inet.*brd' | grep -v '/32 ' | sed 's/inet.*brd //; s/scope.*//;' | sort -u } # # Run the .iptables_restore_input as a set of discrete iptables commands # debug_restore_input() { local first second rest table chain # # Clear the ruleset # qt1 $IPTABLES -t mangle -F qt1 $IPTABLES -t mangle -X for chain in PREROUTING INPUT FORWARD POSTROUTING; do qt1 $IPTABLES -t mangle -P $chain ACCEPT done qt1 $IPTABLES -t raw -F qt1 $IPTABLES -t raw -X for chain in PREROUTING OUTPUT; do qt1 $IPTABLES -t raw -P $chain ACCEPT done run_iptables -t nat -F run_iptables -t nat -X for chain in PREROUTING POSTROUTING OUTPUT; do qt1 $IPTABLES -t nat -P $chain ACCEPT done qt1 $IPTABLES -t filter -F qt1 $IPTABLES -t filter -X for chain in INPUT FORWARD OUTPUT; do qt1 $IPTABLES -t filter -P $chain -P ACCEPT done while read first second rest; do case $first in -*) # # We can't call run_iptables() here because the rules may contain quoted strings # eval $IPTABLES -t $table $first $second $rest if [ $? -ne 0 ]; then error_message "ERROR: Command \"$IPTABLES $first $second $rest\" Failed" stop_firewall exit 2 fi ;; :*) chain=${first#:} if [ "x$second" = x- ]; then do_iptables -t $table -N $chain else do_iptables -t $table -P $chain $second fi if [ $? -ne 0 ]; then error_message "ERROR: Command \"$IPTABLES $first $second $rest\" Failed" stop_firewall exit 2 fi ;; # # This grotesque hack with the table names works around a bug/feature with ash # '*'raw) table=raw ;; '*'mangle) table=mangle ;; '*'nat) table=nat ;; '*'filter) table=filter ;; esac done } # # Give Usage Information # usage() { echo "Usage: $0 [ -q ] [ -v ] [ -n ] [ start|stop|clear|reset|refresh|restart|status|version ]" exit $1 } ################################################################################ # E X E C U T I O N B E G I N S H E R E # ################################################################################ # # Start trace if first arg is "debug" or "trace" # if [ $# -gt 1 ]; then if [ "x$1" = "xtrace" ]; then set -x shift elif [ "x$1" = "xdebug" ]; then DEBUG=Yes shift fi fi initialize if [ -n "$STARTUP_LOG" ]; then if [ ${SHOREWALL_INIT_SCRIPT:-0} -eq 1 ]; then # # We're being run by a startup script that isn't redirecting STDOUT # Redirect it to the log # exec 2>>$STARTUP_LOG fi fi finished=0 while [ $finished -eq 0 -a $# -gt 0 ]; do option=$1 case $option in -*) option=${option#-} [ -z "$option" ] && usage 1 while [ -n "$option" ]; do case $option in v*) VERBOSE=$(($VERBOSE + 1 )) option=${option#v} ;; q*) VERBOSE=$(($VERBOSE - 1 )) option=${option#q} ;; n*) NOROUTES=Yes option=${option#n} ;; *) usage 1 ;; esac done shift ;; *) finished=1 ;; esac done COMMAND="$1" [ -n "${PRODUCT:=Shorewall}" ] case "$COMMAND" in start) [ $# -ne 1 ] && usage 2 if shorewall_is_started; then error_message "$PRODUCT is already Running" status=0 else progress_message3 "Starting $PRODUCT...." define_firewall status=$? [ -n "$SUBSYSLOCK" -a $status -eq 0 ] && touch $SUBSYSLOCK progress_message3 "done." fi ;; stop) [ $# -ne 1 ] && usage 2 progress_message3 "Stopping $PRODUCT...." stop_firewall status=0 [ -n "$SUBSYSLOCK" ] && rm -f $SUBSYSLOCK progress_message3 "done." ;; reset) if ! shorewall_is_started ; then error_message "$PRODUCT is not running" status=2 elif [ $# -eq 1 ]; then $IPTABLES -Z $IPTABLES -t nat -Z $IPTABLES -t mangle -Z date > ${VARDIR}/restarted status=0 progress_message3 "$PRODUCT Counters Reset" else shift status=0 for chain in $@; do if chain_exists $chain; then if qt $IPTABLES -Z $chain; then progress_message3 "Filter $chain Counters Reset" else error_message "ERROR: Reset of chain $chain failed" status=2 break fi else error_message "WARNING: Filter Chain $chain does not exist" fi done fi ;; restart) [ $# -ne 1 ] && usage 2 if shorewall_is_started; then progress_message3 "Restarting $PRODUCT...." else error_message "$PRODUCT is not running" progress_message3 "Starting $PRODUCT...." fi define_firewall status=$? if [ -n "$SUBSYSLOCK" ]; then [ $status -eq 0 ] && touch $SUBSYSLOCK || rm -f $SUBSYSLOCK fi progress_message3 "done." ;; refresh) [ $# -ne 1 ] && usage 2 if shorewall_is_started; then progress_message3 "Refreshing $PRODUCT...." define_firewall status=$? progress_message3 "done." else echo "$PRODUCT is not running" >&2 status=2 fi ;; restore) [ $# -ne 1 ] && usage 2 define_firewall status=$? if [ -n "$SUBSYSLOCK" ]; then [ $status -eq 0 ] && touch $SUBSYSLOCK || rm -f $SUBSYSLOCK fi ;; clear) [ $# -ne 1 ] && usage 2 progress_message3 "Clearing $PRODUCT...." clear_firewall status=0 [ -n "$SUBSYSLOCK" ] && rm -f $SUBSYSLOCK progress_message3 "done." ;; status) [ $# -ne 1 ] && usage 2 echo "$PRODUCT-$VERSION Status at $HOSTNAME - $(date)" echo if shorewall_is_started; then echo "$PRODUCT is running" status=0 else echo "$PRODUCT is stopped" status=4 fi if [ -f ${VARDIR}/state ]; then state="$(cat ${VARDIR}/state)" case $state in Stopped*|Clear*) status=3 ;; esac else state=Unknown fi echo "State:$state" echo ;; version) [ $# -ne 1 ] && usage 2 echo $VERSION status=0 ;; help) [ $# -ne 1 ] && usage 2 usage 0 ;; *) usage 2 ;; esac exit $status