#!/bin/sh # # The Shoreline Firewall (Shorewall) Packet Filtering Firewall - V3.2 # # This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] # # (c) 1999,2000,2001,2002,2003,2004,2005,2006 - Tom Eastep (teastep@shorewall.net) # # tcstart from tc4shorewall Version 0.5 # (c) 2005 Arne Bernin # Modified by Tom Eastep for integration into the Shorewall distribution # published under GPL Version 2# # # Complete documentation is available at http://shorewall.net # # This program is free software; you can redistribute it and/or modify # it under the terms of Version 2 of the GNU General Public License # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA # # If an error occurs while starting or restarting the firewall, the # firewall is automatically stopped. # # Commands are: # # shorewall start Starts the firewall # shorewall restart Restarts the firewall # shorewall stop Stops the firewall # shorewall reset Resets iptables packet and # byte counts # shorewall clear Remove all Shorewall chains # and rules/policies. # # Mutual exclusion -- These functions are jackets for the mutual exclusion # routines in $FUNCTIONS. They invoke # the corresponding function in that file if the user did # not specify "nolock" on the runline. # my_mutex_on() { [ -n "$NOLOCK" ] || { mutex_on; HAVE_MUTEX=Yes; } } my_mutex_off() { [ -n "$HAVE_MUTEX" ] && { mutex_off; HAVE_MUTEX=; } } # # Fatal error -- stops the firewall after issuing the error message # fatal_error() # $* = Error Message { echo " ERROR: $@" >&2 stop_firewall exit 2 } # # Fatal error during startup -- generate an error message and abend without # altering the state of the firewall # startup_error() # $* = Error Message { echo " ERROR: $@" >&2 my_mutex_off [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR [ -n "$RESTOREBASE" ] && rm -f $RESTOREBASE kill $$ exit 2 } # # Send a message to STDOUT and the System Log # report () { # $* = message progress_message3 "$@" logger "$@" } # # Run iptables and if an error occurs, stop the firewall and quit # run_iptables() { if [ -z "$KLUDGEFREE" ]; then # # Purge the temporary files that we use to prevent duplicate '-m' specifications # [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev [ -n "$IPRANGE_MATCH" ] && [ -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange fi if ! $IPTABLES $@ ; then if [ -z "$STOPPING" ]; then error_message "ERROR: Command \"$IPTABLES $@\" Failed" stop_firewall exit 2 fi fi } # # Version of 'run_iptables' that inserts white space after "!" in the arg list # run_iptables2() { case "$@" in *!*) run_iptables $(fix_bang $@) ;; *) run_iptables $@ ;; esac } # # Quietly run iptables # qt_iptables() { if [ -z "$KLUDGEFREE" ]; then # # Purge the temporary files that we use to prevent duplicate '-m' specifications # [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev [ -n "$IPRANGE_MATCH" ] && [ -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange fi qt $IPTABLES $@ } # # Run ip and if an error occurs, stop the firewall and quit # run_ip() { if ! ip $@ ; then if [ -z "$STOPPING" ]; then error_message "ERROR: Command \"ip $@\" Failed" stop_firewall exit 2 fi fi } # # Run tc and if an error occurs, stop the firewall and quit # run_tc() { if ! tc $@ ; then if [ -z "$STOPPING" ]; then error_message "ERROR: Command \"tc $@\" Failed" stop_firewall exit 2 fi fi } # # Delete a chain if it exists # deletechain() # $1 = name of chain { qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1 } # # Find broadcast addresses -- if we are compiling a script and 'detect' is specified for an interface # the function returns nothing for that interface # find_broadcasts() { for interface in $ALL_INTERFACES; do eval bcast=\$$(chain_base $interface)_broadcast if [ "x$bcast" = "xdetect" ]; then ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u elif [ "x${bcast}" != "x-" ]; then echo $(separate_list $bcast) fi done } # # For each entry in the CRITICALHOSTS global list, add INPUT and OUTPUT rules to # enable traffic to/from those hosts. # enable_critical_hosts() { for host in $CRITICALHOSTS; do interface=${host%:*} networks=${host#*:} $IPTABLES -A INPUT -i $interface $(source_ip_range $networks) -j ACCEPT $IPTABLES -A OUTPUT -o $interface $(dest_ip_range $networks) -j ACCEPT done } # # For each entry in the CRITICALHOSTS global list, delete the INPUT and OUTPUT rules that # enable traffic to/from those hosts. # disable_critical_hosts() { for host in $CRITICALHOSTS; do interface=${host%:*} networks=${host#*:} $IPTABLES -D INPUT -i $interface $(source_ip_range $networks) -j ACCEPT $IPTABLES -D OUTPUT -o $interface $(dest_ip_range $networks) -j ACCEPT done } # # Stop the Firewall # stop_firewall() { # # Turn off trace unless we were tracing "stop" or "clear" # [ -n "$RESTOREBASE" ] && rm -f $RESTOREBASE case $COMMAND in stop|clear) ;; *) set +x [ -n "${RESTOREFILE:=restore}" ] RESTOREPATH=${VARDIR}/$RESTOREFILE if [ -x $RESTOREPATH ]; then 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 ${RESTOREPATH}-ipsets fi echo Restoring Shorewall... if $RESTOREPATH restore; then echo "Shorewall restored from $RESTOREPATH" set_state "Started" else set_state "Unknown" fi my_mutex_off kill $$ exit 2 fi ;; esac set_state "Stopping" STOPPING="Yes" TERMINATOR= deletechain shorewall run_user_exit stop if [ -n "$MANGLE_ENABLED" ]; then run_iptables -t mangle -F run_iptables -t mangle -X for chain in PREROUTING INPUT FORWARD POSTROUTING; do qt $IPTABLES -t mangle -P $chain ACCEPT done fi if [ -n "$RAW_TABLE" ]; then run_iptables -t raw -F run_iptables -t raw -X for chain in PREROUTING OUTPUT; do qt $IPTABLES -t raw -P $chain ACCEPT done fi if [ -n "$NAT_ENABLED" ]; then delete_nat for chain in PREROUTING POSTROUTING OUTPUT; do qt $IPTABLES -t nat -P $chain ACCEPT done fi delete_proxy_arp [ -n "$CLEAR_TC" ] && delete_tc1 [ -n "$DISABLE_IPV6" ] && disable_ipv6 process_criticalhosts if [ -n "$CRITICALHOSTS" ]; then if [ -z "$ADMINISABSENTMINDED" ]; then for chain in INPUT OUTPUT; do setpolicy $chain ACCEPT done setpolicy FORWARD DROP deleteallchains enable_critical_hosts for chain in INPUT OUTPUT; do setpolicy $chain DROP done else for chain in INPUT OUTPUT; do setpolicy $chain ACCEPT done setpolicy FORWARD DROP deleteallchains enable_critical_hosts setpolicy INPUT DROP for chain in INPUT FORWARD; do setcontinue $chain done fi elif [ -z "$ADMINISABSENTMINDED" ]; then for chain in INPUT OUTPUT FORWARD; do setpolicy $chain DROP done deleteallchains else for chain in INPUT FORWARD; do setpolicy $chain DROP done setpolicy OUTPUT ACCEPT deleteallchains for chain in INPUT FORWARD; do setcontinue $chain done fi process_routestopped -A $IPTABLES -A INPUT -i lo -j ACCEPT [ -z "$ADMINISABSENTMINDED" ] && \ $IPTABLES -A OUTPUT -o lo -j ACCEPT for interface in $(find_interfaces_by_option dhcp); do $IPTABLES -A INPUT -p udp -i $interface --dport 67:68 -j ACCEPT [ -z "$ADMINISABSENTMINDED" ] && \ $IPTABLES -A OUTPUT -p udp -o $interface --dport 67:68 -j ACCEPT # # This might be a bridge # $IPTABLES -A FORWARD -p udp -i $interface -o $interface --dport 67:68 -j ACCEPT done case "$IP_FORWARDING" in [Oo][Nn]) echo 1 > /proc/sys/net/ipv4/ip_forward progress_message2 "IP Forwarding Enabled" ;; [Oo][Ff][Ff]) echo 0 > /proc/sys/net/ipv4/ip_forward progress_message2 "IP Forwarding Disabled!" ;; esac run_user_exit stopped set_state "Stopped" logger "Shorewall Stopped" rm -rf $TMP_DIR case $COMMAND in stop|clear) ;; *) # # The firewall is being stopped when we were trying to do something # else. Remove the lock file and Kill the shell in case we're in a # subshell # my_mutex_off kill $$ ;; esac } # # Remove all rules and remove all user-defined chains # 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" ] && qt mywhich ip6tables; then ip6tables -P INPUT ACCEPT 2> /dev/null ip6tables -P OUTPUT ACCEPT 2> /dev/null ip6tables -P FORWARD ACCEPT 2> /dev/null fi run_user_exit clear set_state "Cleared" logger "Shorewall Cleared" } # # Delete existing Proxy ARP # delete_proxy_arp() { if [ -f ${VARDIR}/proxyarp ]; then while read address interface external haveroute; do case $COMMAND in stop|clear) qt arp -i $external -d $address pub [ -z "${haveroute}${NOROUTES}" ] && qt ip route del $address dev $interface ;; *) if [ -n "$STOPPING" ]; then qt arp -i $external -d $address pub qt arp -i $external -d $address pub [ -z "${haveroute}${NOROUTES}" ] && qt ip route del $address dev $interface else qt arp -i $external -d $address pub if [ -z "$haveroute" ];then [ -n "$NOROUTE" ] || qt ip route del $address dev $interface fi fi ;; esac done < ${VARDIR}/proxyarp rm -f ${VARDIR}/proxyarp fi [ -d ${VARDIR} ] && touch ${VARDIR}/proxyarp case $COMMAND in stop|clear) for f in /proc/sys/net/ipv4/conf/*; do [ -f $f/proxy_arp ] && echo 0 > $f/proxy_arp done ;; *) if [ -n "$STOPPING" ]; then for f in /proc/sys/net/ipv4/conf/*; do [ -f $f/proxy_arp ] && echo 0 > $f/proxy_arp done else for f in /proc/sys/net/ipv4/conf/*; do [ -f $f/proxy_arp ] && echo 0 > $f/proxy_arp done fi ;; esac } # # Delete existing Static NAT # delete_nat() { run_iptables -t nat -F run_iptables -t nat -X if [ -f ${VARDIR}/nat ]; then while read external interface; do qt ip addr del $external dev $interface done < ${VARDIR}/nat rm -f ${VARDIR}/nat fi [ -d ${VARDIR} ] && touch ${VARDIR}/nat } # # Display elements of a list with leading white space # display_list() # $1 = List Title, rest of $* = list to display { [ $# -gt 1 ] && echo " $*" } # # Verify that kernel has netfilter support # verify_os_version() { osversion=$(uname -r) case $osversion in 2.4.*|2.5.*|2.6.*) ;; *) startup_error "Shorewall version $VERSION does not work with kernel version $osversion" ;; esac [ $COMMAND = start -a -n "$(lsmod 2> /dev/null | grep '^ipchains')" ] && \ startup_error "Shorewall can't start with the ipchains kernel module loaded - see FAQ #8" } # # Check for disabled startup # check_disabled_startup() { if [ -z "$STARTUP_ENABLED" ]; then echo " Shorewall Startup is disabled -- to enable startup" echo " after you have completed Shorewall configuration," echo " change the setting of STARTUP_ENABLED to Yes in" echo " ${CONFDIR}/shorewall.conf" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off exit 2 fi } # # Add a host or networks to a zone # add_to_zone() # $1...${n-1} = [:] $n = zone { local interface host zone z h z1 z2 chain local dhcp_interfaces blacklist_interfaces maclist_interfaces local tcpflags_interfaces newhostlist= local rulenum source_chain dest_hosts iface hosts hostlist= nat_chain_exists() # $1 = chain name { qt $IPTABLES -t nat -L $1 -n } do_iptables() # $@ = command { [ -n "$BRIDGING" ] && [ -f $TMP_DIR/physdev ] && rm -f $TMP_DIR/physdev [ -n "$IPRANGE_MATCH" ] && [ -f $TMP_DIR/iprange ] && rm -f $TMP_DIR/iprange if ! $IPTABLES $@ ; then error_message "ERROR: Can't add $newhost to zone $zone" fi } # # Load $zones # determine_zones # # Validate Interfaces File # validate_interfaces_file # # Validate Hosts File # validate_hosts_file # # Validate IPSec File # f=$(find_file $IPSECFILE) [ -f $f ] && setup_ipsec $f # # Normalize host list # while [ $# -gt 1 ]; do interface=${1%%:*} host=${1#*:} # # Be sure that the interface was dynamic at last [re]start # if ! chain_exists $(input_chain $interface) ; then startup_error "Unknown interface $interface" fi if ! chain_exists $(dynamic_in $interface) ; then startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf" fi if [ -z "$host" ]; then hostlist="$hostlist $interface:0.0.0.0/0" else for h in $(separate_list $host); do hostlist="$hostlist $interface:$h" done fi shift done # # Validate Zone # zone=$1 validate_zone $zone || startup_error "Unknown zone: $zone" [ "$zone" = $FW ] && startup_error "Can't add $1 to firewall zone" # # Be sure that Shorewall has been restarted using a DZ-aware version of the code # [ -f ${VARDIR}/chains ] || startup_error "${VARDIR}/chains -- file not found" [ -f ${VARDIR}/zones ] || startup_error "${VARDIR}/zones -- file not found" # # Check for duplicates and create a new zone state file # > ${VARDIR}/zones_$$ while read z type hosts; do if [ "$z" = "$zone" ]; then for h in $hostlist; do list_search $h $hosts if [ "$?" -gt 0 ]; then newhostlist="$newhostlist $h" else error_message "$h already in zone $zone" fi done [ -z "$hosts" ] && hosts=$newhostlist || hosts="$hosts $newhostlist" fi eval ${z}_hosts=\"$hosts\" echo "$z $type $hosts" >> ${VARDIR}/zones_$$ done < ${VARDIR}/zones mv -f ${VARDIR}/zones_$$ ${VARDIR}/zones TERMINATOR=fatal_error # # Create a new Zone state file # for newhost in $newhostlist; do # # Isolate interface and host parts # interface=${newhost%%:*} host=${newhost#*:} # # If the zone passed in the command has a dnat chain then insert a rule in # the nat table PREROUTING chain to jump to that chain when the source # matches the new host(s)# # chain=${zone}_dnat if nat_chain_exists $chain; then do_iptables -t nat -A $(dynamic_in $interface) $(source_ip_range $host) $(match_ipsec_in $zone $newhost) -j $chain fi # # Insert new rules into the filter table for the passed interface # while read z1 z2 chain; do [ "$z1" = "$z2" ] && op="-I" || op="-A" if [ "$z1" = "$zone" ]; then if [ "$z2" = "$FW" ]; then do_iptables $op $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j $chain else source_chain=$(dynamic_fwd $interface) if is_ipsec_host $z1 $newhost ; then do_iptables $op $source_chain $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j ${z1}_frwd else eval dest_hosts=\"\$${z2}_hosts\" for h in $dest_hosts; do iface=${h%%:*} hosts=${h#*:} if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then do_iptables $op $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $(match_ipsec_out $z2 $h) -j $chain fi done fi fi elif [ "$z2" = "$zone" ]; then if [ "$z1" = "$FW" ]; then # # Add a rule to the dynamic out chain for the interface # do_iptables $op $(dynamic_out $interface) $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain else eval source_hosts=\"\$${z1}_hosts\" for h in $source_hosts; do iface=${h%%:*} hosts=${h#*:} if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then if is_ipsec_host $z1 $h; then do_iptables $op ${z1}_dyn -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain else do_iptables $op $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $newhost) -j $chain fi fi done fi fi done < ${VARDIR}/chains progress_message "$newhost added to zone $zone" done rm -rf $TMP_DIR } # # Delete a host or networks from a zone # delete_from_zone() # $1 = [:] $2 = zone { local interface host zone z h z1 z2 chain delhost local dhcp_interfaces blacklist_interfaces maclist_interfaces tcpflags_interfaces local rulenum source_chain dest_hosts iface hosts hostlist= # # Load $zones # determine_zones # # Validate Interfaces File # validate_interfaces_file # # Validate Hosts File # validate_hosts_file # # Validate IPSec File # f=$(find_file ipsec) [ -f $f ] && setup_ipsec $f # # Normalize host list # while [ $# -gt 1 ]; do interface=${1%%:*} host=${1#*:} # # Be sure that the interface was dynamic at last [re]start # if ! chain_exists $(input_chain $interface) ; then startup_error "Unknown interface $interface" fi if ! chain_exists $(dynamic_in $interface) ; then startup_error "At last Shorewall [re]start, DYNAMIC_ZONES=No in shorewall.conf" fi if [ -z "$host" ]; then hostlist="$hostlist $interface:0.0.0.0/0" else for h in $(separate_list $host); do hostlist="$hostlist $interface:$h" done fi shift done # # Validate Zone # zone=$1 validate_zone $zone || startup_error "Unknown zone: $zone" [ "$zone" = $FW ] && startup_error "Can't delete from the firewall zone" # # Be sure that Shorewall has been restarted using a DZ-aware version of the code # [ -f ${VARDIR}/chains ] || startup_error "${VARDIR}/chains -- file not found" [ -f ${VARDIR}/zones ] || startup_error "${VARDIR}/zones -- file not found" # # Delete the passed hosts from the zone state file # > ${VARDIR}/zones_$$ while read z hosts; do if [ "$z" = "$zone" ]; then temp=$hosts hosts= for host in $hostlist; do found= for h in $temp; do if [ "$h" = "$host" ]; then found=Yes break fi done [ -n "$found" ] || error_message "WARNING: $host does not appear to be in zone $zone" done for h in $temp; do found= for host in $hostlist; do if [ "$h" = "$host" ]; then found=Yes break fi done [ -n "$found" ] || hosts="$hosts $h" done fi eval ${z}_hosts=\"$hosts\" echo "$z $hosts" >> ${VARDIR}/zones_$$ done < ${VARDIR}/zones mv -f ${VARDIR}/zones_$$ ${VARDIR}/zones TERMINATOR=fatal_error for delhost in $hostlist; do interface=${delhost%%:*} host=${delhost#*:} # # Delete any nat table entries for the host(s) # qt_iptables -t nat -D $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $zone $delhost) -j ${zone}_dnat # # Delete rules rules the input chains for the passed interface # while read z1 z2 chain; do if [ "$z1" = "$zone" ]; then if [ "$z2" = "$FW" ]; then qt_iptables -D $(dynamic_in $interface) $(match_source_hosts $host) $(match_ipsec_in $z1 $delhost) -j $chain else source_chain=$(dynamic_fwd $interface) if is_ipsec_host $z1 $delhost ; then qt_iptables -D $source_chain $(match_source_hosts $host) $(match_ipsec_in $z1 $newhost) -j ${z1}_frwd else eval dest_hosts=\"\$${z2}_hosts\" [ "$z2" = "$zone" ] && dest_hosts="$dest_hosts $hostlist" for h in $dest_hosts; do iface=${h%%:*} hosts=${h#*:} if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then qt_iptables -D $source_chain $(match_source_hosts $host) -o $iface $(match_dest_hosts $hosts) $(match_ipsec_out $z2 $h) -j $chain fi done fi fi elif [ "$z2" = "$zone" ]; then if [ "$z1" = "$FW" ]; then qt_iptables -D $(dynamic_out $interface) $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain else eval source_hosts=\"\$${z1}_hosts\" for h in $source_hosts; do iface=${h%%:*} hosts=${h#*:} if [ "$iface" != "$interface" -o "$hosts" != "$host" ]; then if is_ipsec_host $z1 $h; then qt_iptables -D ${z1}_dyn -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain else qt_iptables -D $(dynamic_fwd $iface) $(match_source_hosts $hosts) -o $interface $(match_dest_hosts $host) $(match_ipsec_out $z2 $delhost) -j $chain fi fi done fi fi done < ${VARDIR}/chains progress_message "$delhost removed from zone $zone" done rm -rf $TMP_DIR } # # Give Usage Information # usage() { echo "Usage: $0 [debug] {start|stop|reset|restart|clear}" 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" # [ $# -gt 1 ] && [ "$1" = "debug" ] && { set -x ; shift ; } NOLOCK= [ $# -gt 1 ] && [ "$1" = "nolock" ] && { NOLOCK=Yes; shift ; } trap "my_mutex_off; exit 2" 1 2 3 4 5 6 9 SHAREDIR=/usr/share/shorewall VARDIR=/var/lib/shorewall CONFDIR=/etc/shorewall FUNCTIONS=${SHAREDIR}/functions if [ -f $FUNCTIONS ]; then [ $VERBOSE -ge 2 ] && echo "Loading $FUNCTIONS..." . $FUNCTIONS else startup_error "$FUNCTIONS does not exist!" fi PROGRAM=firewall COMMAND="$1" case "$COMMAND" in stop) [ $# -ne 1 ] && usage do_initialize my_mutex_on # # Don't want to do a 'stop' when startup is disabled # check_disabled_startup progress_message3 "Stopping Shorewall..." stop_firewall [ -n "$SUBSYSLOCK" ] && rm -f $SUBSYSLOCK progress_message3 "done." my_mutex_off ;; reset) [ $# -ne 1 ] && usage do_initialize my_mutex_on if ! shorewall_is_started ; then echo "Shorewall Not Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off exit 2; fi $IPTABLES -Z $IPTABLES -t nat -Z $IPTABLES -t mangle -Z report "Shorewall Counters Reset" date > ${VARDIR}/restarted my_mutex_off ;; clear) [ $# -ne 1 ] && usage do_initialize my_mutex_on progress_message3 "Clearing Shorewall..." clear_firewall [ -n "$SUBSYSLOCK" ] && rm -f $SUBSYSLOCK progress_message3 "done." my_mutex_off ;; add) [ $# -lt 3 ] && usage do_initialize my_mutex_on if ! shorewall_is_started ; then echo "Shorewall Not Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off exit 2; fi shift add_to_zone $@ my_mutex_off ;; delete) [ $# -lt 3 ] && usage do_initialize my_mutex_on if ! shorewall_is_started ; then echo "Shorewall Not Started" [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR my_mutex_off exit 2; fi shift delete_from_zone $@ my_mutex_off ;; call) # # Undocumented way to call functions in ${SHAREDIR}/firewall directly # shift do_initialize EMPTY= $@ ;; *) usage ;; esac