forked from extern/shorewall_code
b66929a65e
1) Elimination of the "shorewall monitor" command. 2) The /etc/shorewall/ipsec and /etc/shorewall/zones file are combined into a single /etc/shorewall/zones file. This is done in an upwardly-compatible way so that current users can continue to use their existing files. 3) Support has been added for the arp_ignore interface option. 4) DROPINVALID has been removed from shorewall.conf. Behavior is as if DROPINVALID=No was specified. 5) The 'nobogons' option and BOGON_LOG_LEVEL are removed. 6) Error and warning messages have been made easier to spot by using capitalization (e.g., ERROR: and WARNING:). 7) The /etc/shorewall/policy file now contains a new connection policy and a policy for ESTABLISHED packets. Useful for users of snort-inline who want to pass all packets to the QUEUE target. 8) A new 'critical' option has been added to /etc/shorewall/routestopped. Shorewall insures communication between the firewall and 'critical' hosts throughout start, restart, stop and clear. Useful for diskless firewall's with NFS-mounted file systems, LDAP servers, Crossbow, etc. 9) Macros. Macros are very similar to actions but are easier to use, allow parameter substitution and are more efficient. Almost all of the standard actions have been converted to macros in the EXPERIMENTAL branch. 10) The default value of ADD_IP_ALIASES in shorewall.conf is changed to No. 11) If you have 'make' installed on your firewall, then when you use the '-f' option to 'shorewall start' (as happens when you reboot), if your /etc/shorewall/ directory contains files that were modified after Shorewall was last restarted then Shorewall is started using the config files rather than using the saved configuration. git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@2409 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
1305 lines
30 KiB
Bash
Executable File
1305 lines
30 KiB
Bash
Executable File
#!/bin/sh
|
||
#
|
||
# Shorewall Packet Filtering Firewall Control Program - V2.6
|
||
#
|
||
# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm]
|
||
#
|
||
# (c) 1999,2000,2001,2002,2003,2004,2005 - Tom Eastep (teastep@shorewall.net)
|
||
#
|
||
# This file should be placed in /sbin/shorewall.
|
||
#
|
||
# Shorewall documentation is available at http://shorewall.sourceforge.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.
|
||
#
|
||
# The firewall uses configuration files in /etc/shorewall/ - skeleton
|
||
# files is included with the firewall.
|
||
#
|
||
# Commands are:
|
||
#
|
||
# shorewall add <iface>[:<host>] zone Adds a host or subnet to a zone
|
||
# shorewall delete <iface>[:<host>] zone Deletes a host or subnet from a zone
|
||
# shorewall start Starts the firewall
|
||
# shorewall restart Restarts the firewall
|
||
# shorewall stop Stops the firewall
|
||
# shorewall monitor [ refresh-interval ] Repeatedly Displays firewall status
|
||
# plus the last 20 "interesting"
|
||
# packets
|
||
# shorewall status Displays firewall status
|
||
# shorewall reset Resets iptables packet and
|
||
# byte counts
|
||
# shorewall clear Open the floodgates by
|
||
# removing all iptables rules
|
||
# and setting the three permanent
|
||
# chain policies to ACCEPT
|
||
# shorewall refresh Rebuild the common chain to
|
||
# compensate for a change of
|
||
# broadcast address on any "detect"
|
||
# interface.
|
||
# shorewall show <chain> [ <chain> ... ] Display the rules in each <chain> listed
|
||
# shorewall show actions Displays the available actions
|
||
# shorewall show log Print the last 20 log messages
|
||
# shorewall show connections Show the kernel's connection
|
||
# tracking table
|
||
# shorewall show nat Display the rules in the nat table
|
||
# shorewall show {mangle|tos} Display the rules in the mangle table
|
||
# shorewall show tc Display traffic control info
|
||
# shorewall show classifiers Display classifiers
|
||
# shorewall show capabilities Display iptables/kernel capabilities
|
||
# shorewall version Display the installed version id
|
||
# shorewall check Verify the more heavily-used
|
||
# configuration files.
|
||
# shorewall try <directory> [ <timeout> ] 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 <address> ... Temporarily drop all packets from the
|
||
# listed address(es)
|
||
# shorewall reject <address> ... Temporarily reject all packets from the
|
||
# listed address(es)
|
||
# shorewall allow <address> ... Reenable address(es) previously
|
||
# disabled with "drop" or "reject"
|
||
# shorewall save [ <file> ] Save the list of "rejected" and
|
||
# "dropped" addresses so that it will
|
||
# be automatically reinstated the
|
||
# next time that Shorewall starts.
|
||
# Save the current state so that 'shorewall
|
||
# restore' can be used.
|
||
#
|
||
# shorewall forget [ <file> ] Discard the data saved by 'shorewall save'
|
||
#
|
||
# shorewall restore [ <file> ] Restore the state of the firewall from
|
||
# previously saved information.
|
||
#
|
||
# shorewall ipaddr [ <address>/<cidr> | <address> <netmask> ]
|
||
#
|
||
# Displays information about the network
|
||
# defined by the argument[s]
|
||
#
|
||
# shorewall iprange <address>-<address> Decomposes a range of IP addresses into
|
||
# a list of network/host addresses.
|
||
#
|
||
# 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
|
||
# confirmation to accept or reject the new
|
||
# configuration
|
||
#
|
||
# Fatal Error
|
||
#
|
||
fatal_error() # $@ = Message
|
||
{
|
||
echo " $@" >&2
|
||
exit 2
|
||
}
|
||
|
||
# Display a chain if it exists
|
||
#
|
||
|
||
showfirstchain() # $1 = name of chain
|
||
{
|
||
awk \
|
||
'BEGIN {prnt=0; rslt=1; }; \
|
||
/^$/ { next; };\
|
||
/^Chain/ {if ( prnt == 1 ) { rslt=0; exit 0; }; };\
|
||
/Chain '$1'/ { prnt=1; }; \
|
||
{ if (prnt == 1) print; };\
|
||
END { exit rslt; }' $TMPFILE
|
||
}
|
||
|
||
showchain() # $1 = name of chain
|
||
{
|
||
if [ "$firstchain" = "Yes" ]; then
|
||
if showfirstchain $1; then
|
||
firstchain=
|
||
fi
|
||
else
|
||
awk \
|
||
'BEGIN {prnt=0;};\
|
||
/^$|^ pkts/ { next; };\
|
||
/^Chain/ {if ( prnt == 1 ) exit; };\
|
||
/Chain '$1'/ { prnt=1; };\
|
||
{ if (prnt == 1) print; }' $TMPFILE
|
||
fi
|
||
}
|
||
|
||
#
|
||
# The 'awk' hack that compensates for bugs in iptables-save (or rather in the extension modules).
|
||
#
|
||
|
||
iptablesbug()
|
||
{
|
||
if qt which awk ; then
|
||
awk 'BEGIN {sline=""; };\
|
||
/^-j/ { print sline $0; next };\
|
||
/-m policy.*-j/ { print $0; next };\
|
||
/-m policy/ { sline=$0; next };\
|
||
/--mask ff/ { sub( /--mask ff/, "--mask 0xff" ) };\
|
||
{print ; sline="" }'
|
||
else
|
||
echo " WARNING: You don't have 'awk' on this system so the output of the save command may be unusable" >&2
|
||
cat
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Validate the value of RESTOREFILE
|
||
#
|
||
validate_restorefile() # $* = label
|
||
{
|
||
case $RESTOREFILE in
|
||
*/*)
|
||
echo " ERROR: $@ must specify a simple file name: $RESTOREFILE" >&2
|
||
exit 2
|
||
;;
|
||
esac
|
||
}
|
||
|
||
#
|
||
# Set the configuration variables from shorewall.conf
|
||
#
|
||
get_config() {
|
||
|
||
[ -z "$LOGFILE" ] && LOGFILE=/var/log/messages
|
||
|
||
if [ ! -f $LOGFILE ]; then
|
||
echo "LOGFILE ($LOGFILE) does not exist!" >&2
|
||
exit 2
|
||
fi
|
||
#
|
||
# See if we have a real version of "tail" -- use separate redirection so
|
||
# that ash (aka /bin/sh on LRP) doesn't crap
|
||
#
|
||
if ( tail -n5 $LOGFILE > /dev/null 2> /dev/null ) ; then
|
||
realtail="Yes"
|
||
else
|
||
realtail=""
|
||
fi
|
||
|
||
[ -n "$FW" ] || FW=fw
|
||
|
||
[ -n "LOGFORMAT" ] && LOGFORMAT="${LOGFORMAT%%%*}"
|
||
|
||
[ -n "$LOGFORMAT" ] || LOGFORMAT="Shorewall:"
|
||
|
||
if [ -n "$IPTABLES" ]; then
|
||
if [ ! -e "$IPTABLES" ]; then
|
||
echo " ERROR: The program specified in IPTABLES does not exist or is not executable" >&2
|
||
exit 2
|
||
fi
|
||
else
|
||
IPTABLES=$(which iptables 2> /dev/null)
|
||
if [ -z "$IPTABLES" ] ; then
|
||
echo " ERROR: Can't find iptables executable" >&2
|
||
exit 2
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$SHOREWALL_SHELL" ]; then
|
||
if [ ! -e "$SHOREWALL_SHELL" ]; then
|
||
echo " ERROR: The program specified in SHOREWALL_SHELL does not exist or is not executable" >&2
|
||
exit 2
|
||
fi
|
||
fi
|
||
|
||
[ -n "$RESTOREFILE" ] || RESTOREFILE=restore
|
||
|
||
validate_restorefile RESTOREFILE
|
||
|
||
export RESTOREFILE
|
||
|
||
case $STARTUP_ENABLED in
|
||
[Nn][Oo])
|
||
echo " WARNING: Shorewall startup is disabled. To enable startup, set STARTUP_ENABLED=Yes in /etc/shorewall/shorewall.conf" >&2
|
||
;;
|
||
esac
|
||
|
||
}
|
||
|
||
#
|
||
# Clear descriptor 1 if it is a terminal
|
||
#
|
||
clear_term() {
|
||
[ -t 1 ] && clear
|
||
}
|
||
|
||
#
|
||
# Delay $timeout seconds -- if we're running on a recent bash2 then allow
|
||
# <enter> to terminate the delay
|
||
#
|
||
timed_read ()
|
||
{
|
||
read -t $timeout foo 2> /dev/null
|
||
|
||
test $? -eq 2 && sleep $timeout
|
||
}
|
||
|
||
#
|
||
# Display the last $1 packets logged
|
||
#
|
||
packet_log() # $1 = number of messages
|
||
{
|
||
local options
|
||
|
||
[ -n "$realtail" ] && options="-n$1"
|
||
|
||
if [ -n "$VERBOSE" ]; then
|
||
grep "${LOGFORMAT}" $LOGFILE | \
|
||
sed s/" kernel:"// | \
|
||
sed s/" $host $LOGFORMAT"/" "/ | \
|
||
tail $options
|
||
else
|
||
grep "${LOGFORMAT}" $LOGFILE | \
|
||
sed s/" kernel:"// | \
|
||
sed s/" $host $LOGFORMAT"/" "/ | \
|
||
sed 's/MAC=.* SRC=/SRC=/' | \
|
||
tail $options
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Show traffic control information
|
||
#
|
||
show_tc() {
|
||
|
||
show_one_tc() {
|
||
local device=${1%@*}
|
||
qdisc=$(tc qdisc list dev $device)
|
||
|
||
if [ -n "$qdisc" ]; then
|
||
echo Device $device:
|
||
tc -s -d qdisc show dev $device
|
||
tc -s -d class show dev $device
|
||
echo
|
||
fi
|
||
}
|
||
|
||
ip link list | \
|
||
while read inx interface details; do
|
||
case $inx in
|
||
[0-9]*)
|
||
show_one_tc ${interface%:}
|
||
;;
|
||
*)
|
||
;;
|
||
esac
|
||
done
|
||
|
||
}
|
||
|
||
#
|
||
# Show classifier information
|
||
#
|
||
show_classifiers() {
|
||
|
||
show_one_classifier() {
|
||
local device=${1%@*}
|
||
qdisc=$(tc qdisc list dev $device)
|
||
|
||
if [ -n "$qdisc" ]; then
|
||
echo Device $device:
|
||
tc -s filter ls dev $device
|
||
echo
|
||
fi
|
||
}
|
||
|
||
ip link list | \
|
||
while read inx interface details; do
|
||
case $inx in
|
||
[0-9]*)
|
||
show_one_classifier ${interface%:}
|
||
;;
|
||
*)
|
||
;;
|
||
esac
|
||
done
|
||
|
||
}
|
||
|
||
#
|
||
# Watch the Firewall Log
|
||
#
|
||
logwatch() # $1 = timeout -- if negative, prompt each time that
|
||
# an 'interesting' packet count changes
|
||
{
|
||
|
||
host=$(echo $HOSTNAME | sed 's/\..*$//')
|
||
oldrejects=$($IPTABLES -L -v -n | grep 'LOG')
|
||
|
||
if [ $1 -lt 0 ]; then
|
||
timeout=$((- $1))
|
||
pause="Yes"
|
||
else
|
||
pause="No"
|
||
timeout=$1
|
||
fi
|
||
|
||
qt which awk && haveawk=Yes || haveawk=
|
||
|
||
while true; do
|
||
clear_term
|
||
echo "$banner $(date)"
|
||
echo
|
||
|
||
echo "Dropped/Rejected Packet Log"
|
||
echo
|
||
|
||
show_reset
|
||
|
||
rejects=$($IPTABLES -L -v -n | grep 'LOG')
|
||
|
||
if [ "$rejects" != "$oldrejects" ]; then
|
||
oldrejects="$rejects"
|
||
|
||
$RING_BELL
|
||
|
||
packet_log 40
|
||
|
||
if [ "$pause" = "Yes" ]; then
|
||
echo
|
||
echo $ECHO_N 'Enter any character to continue: '
|
||
read foo
|
||
else
|
||
timed_read
|
||
fi
|
||
else
|
||
echo
|
||
packet_log 40
|
||
timed_read
|
||
fi
|
||
done
|
||
}
|
||
|
||
#
|
||
# Save currently running configuration
|
||
#
|
||
save_config() {
|
||
[ "$nolock" ] || mutex_on
|
||
|
||
if qt $IPTABLES -L shorewall -n; then
|
||
[ -d /var/lib/shorewall ] || mkdir -p /var/lib/shorewall
|
||
|
||
if [ -f $RESTOREPATH -a ! -x $RESTOREPATH ]; then
|
||
echo " ERROR: $RESTOREPATH exists and is not a saved Shorewall configuration"
|
||
else
|
||
case $RESTOREFILE in
|
||
save|restore-base)
|
||
echo " ERROR: Reserved file name: $RESTOREFILE"
|
||
;;
|
||
*)
|
||
if $IPTABLES -L dynamic -n > /var/lib/shorewall/save; then
|
||
echo " Dynamic Rules Saved"
|
||
if [ -f /var/lib/shorewall/restore-base ]; then
|
||
cp -f /var/lib/shorewall/restore-base /var/lib/shorewall/restore-$$
|
||
if iptables-save | iptablesbug >> /var/lib/shorewall/restore-$$ ; then
|
||
echo __EOF__ >> /var/lib/shorewall/restore-$$
|
||
[ -f /var/lib/shorewall/restore-tail ] && \
|
||
cat /var/lib/shorewall/restore-tail >> /var/lib/shorewall/restore-$$
|
||
mv -f /var/lib/shorewall/restore-$$ $RESTOREPATH
|
||
chmod +x $RESTOREPATH
|
||
echo " Currently-running Configuration Saved to $RESTOREPATH"
|
||
|
||
rm -f ${RESTOREPATH}-ipsets
|
||
|
||
case ${SAVE_IPSETS:-No} in
|
||
[Yy][Ee][Ss])
|
||
RESTOREPATH=${RESTOREPATH}-ipsets
|
||
|
||
f=/var/lib/shorewall/restore-$$
|
||
|
||
echo "#!/bin/sh" > $f
|
||
echo "#This ipset restore file generated $(date) by Shorewall $version" >> $f
|
||
echo >> $f
|
||
echo ". /usr/share/shorewall/functions" >> $f
|
||
echo >> $f
|
||
grep '^MODULE' /var/lib/shorewall/restore-base >> $f
|
||
echo "reload_kernel_modules << __EOF__" >> $f
|
||
grep 'loadmodule ip_set' /var/lib/shorewall/restore-base >> $f
|
||
echo "__EOF__" >> $f
|
||
echo >> $f
|
||
echo "ipset -U :all: :all:" >> $f
|
||
echo "ipset -F" >> $f
|
||
echo "ipset -X" >> $f
|
||
echo "ipset -R << __EOF__" >> $f
|
||
ipset -S >> $f
|
||
echo "__EOF__" >> $f
|
||
mv -f $f $RESTOREPATH
|
||
chmod +x $RESTOREPATH
|
||
echo " Current Ipset Contents Saved to $RESTOREPATH"
|
||
;;
|
||
[Nn][Oo])
|
||
;;
|
||
*)
|
||
echo " WARNING: Invalid value ($SAVE_IPSETS) for SAVE_IPSETS. Ipset contents not saved"
|
||
;;
|
||
esac
|
||
else
|
||
rm -f /var/lib/shorewall/restore-$$
|
||
echo " ERROR: Currently-running Configuration Not Saved"
|
||
fi
|
||
else
|
||
echo " ERROR: /var/lib/shorewall/restore-base does not exist"
|
||
fi
|
||
else
|
||
echo "Error Saving the Dynamic Rules"
|
||
fi
|
||
;;
|
||
esac
|
||
fi
|
||
else
|
||
echo "Shorewall isn't started"
|
||
fi
|
||
|
||
[ "$nolock" ] || mutex_off
|
||
}
|
||
#
|
||
# Help information
|
||
#
|
||
help()
|
||
{
|
||
[ -x $HELP ] && { export version; exec $HELP $*; }
|
||
echo "Help subsystem is not installed at $HELP"
|
||
}
|
||
|
||
#
|
||
# Give Usage Information
|
||
#
|
||
usage() # $1 = exit status
|
||
{
|
||
echo "Usage: $(basename $0) [debug|trace] [nolock] [ -x ] [ -q ] [ -f ] [ -v ] <command>"
|
||
echo "where <command> is one of:"
|
||
echo " add <interface>[:{<bridge-port>[:<host>]|<host>}[,...]] ... <zone>"
|
||
echo " allow <address> ..."
|
||
echo " check [ <directory> ]"
|
||
echo " clear"
|
||
echo " delete <interface>[:{<bridge-port>[:<host>]|<host>}[,...]] ... <zone>"
|
||
echo " drop <address> ..."
|
||
echo " forget [ <file name> ]"
|
||
echo " help [ <command > | host | address ]"
|
||
echo " hits"
|
||
echo " ipcalc [ <address>/<vlsm> | <address> <netmask> ]"
|
||
echo " iprange <address>-<address>"
|
||
echo " logwatch [<refresh interval>]"
|
||
echo " refresh"
|
||
echo " reject <address> ..."
|
||
echo " reset"
|
||
echo " restart [ <directory> ]"
|
||
echo " restore [ <file name> ]"
|
||
echo " save [ <file name> ]"
|
||
echo " show [<chain> [ <chain> ... ]|actions|capabilities|classifiers|connections|log|nat|tc|tos|zones]"
|
||
echo " start [ <directory> ]"
|
||
echo " stop"
|
||
echo " status"
|
||
echo " try <directory> [ <timeout> ]"
|
||
echo " version"
|
||
echo " safe-start"
|
||
echo " safe-restart"
|
||
echo
|
||
exit $1
|
||
}
|
||
|
||
#
|
||
# Display the time that the counters were last reset
|
||
#
|
||
show_reset() {
|
||
[ -f /var/lib/shorewall/restarted ] && \
|
||
echo "Counters reset $(cat /var/lib/shorewall/restarted)" && \
|
||
echo
|
||
}
|
||
|
||
#
|
||
# Display's the passed file name followed by "=" and the file's contents.
|
||
#
|
||
show_proc() # $1 = name of a file
|
||
{
|
||
[ -f $1 ] && echo " $1 = $(cat $1)"
|
||
}
|
||
|
||
read_yesno_with_timeout() {
|
||
read -t 60 yn 2> /dev/null
|
||
if [ $? -eq 2 ]
|
||
then
|
||
# read doesn't support timeout
|
||
test -x /bin/bash || return 2 # bash is not installed so the feature is not available
|
||
/bin/bash -c 'read -t 60 yn ; if [ "$yn" == "y" ] ; then exit 0 ; else exit 1 ; fi' # invoke bash and use its version of read
|
||
return $?
|
||
else
|
||
# read supports timeout
|
||
case "$yn" in
|
||
y|Y)
|
||
return 0
|
||
;;
|
||
*)
|
||
return 1
|
||
;;
|
||
esac
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Execution begins here
|
||
#
|
||
debugging=
|
||
|
||
if [ $# -gt 0 ] && [ "$1" = "debug" -o "$1" = "trace" ]; then
|
||
debugging=debug
|
||
shift
|
||
fi
|
||
|
||
nolock=
|
||
|
||
if [ $# -gt 0 ] && [ "$1" = "nolock" ]; then
|
||
nolock=nolock
|
||
shift
|
||
fi
|
||
|
||
SHOREWALL_DIR=
|
||
QUIET=
|
||
IPT_OPTIONS="-nv"
|
||
FAST=
|
||
VERBOSE=
|
||
|
||
done=0
|
||
|
||
while [ $done -eq 0 ]; do
|
||
[ $# -eq 0 ] && usage 1
|
||
option=$1
|
||
case $option in
|
||
-*)
|
||
option=${option#-}
|
||
|
||
[ -z "$option" ] && usage 1
|
||
|
||
while [ -n "$option" ]; do
|
||
case $option in
|
||
c)
|
||
[ $# -eq 1 ] && usage 1
|
||
|
||
if [ ! -d $2 ]; then
|
||
if [ -e $2 ]; then
|
||
echo "$2 is not a directory" >&2 && exit 2
|
||
else
|
||
echo "Directory $2 does not exist" >&2 && exit 2
|
||
fi
|
||
fi
|
||
|
||
SHOREWALL_DIR=$2
|
||
option=
|
||
shift
|
||
;;
|
||
x*)
|
||
IPT_OPTIONS="-xnv"
|
||
option=${option#x}
|
||
;;
|
||
q*)
|
||
QUIET=Yes
|
||
option=${option#q}
|
||
;;
|
||
f*)
|
||
FAST=Yes
|
||
option=${option#f}
|
||
;;
|
||
v*)
|
||
VERBOSE=Yes
|
||
option=${option#v}
|
||
;;
|
||
*)
|
||
usage 1
|
||
;;
|
||
esac
|
||
done
|
||
shift
|
||
;;
|
||
*)
|
||
done=1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
if [ $# -eq 0 ]; then
|
||
usage 1
|
||
fi
|
||
|
||
[ -n "$SHOREWALL_DIR" ] && export SHOREWALL_DIR
|
||
[ -n "$QUIET" ] && export QUIET
|
||
|
||
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
|
||
MUTEX_TIMEOUT=
|
||
|
||
SHARED_DIR=/usr/share/shorewall
|
||
FIREWALL=$SHARED_DIR/firewall
|
||
FUNCTIONS=$SHARED_DIR/functions
|
||
VERSION_FILE=$SHARED_DIR/version
|
||
HELP=$SHARED_DIR/help
|
||
|
||
if [ -f $FUNCTIONS ]; then
|
||
. $FUNCTIONS
|
||
else
|
||
echo "$FUNCTIONS does not exist!" >&2
|
||
exit 2
|
||
fi
|
||
|
||
ensure_config_path
|
||
|
||
config=$(find_file shorewall.conf)
|
||
|
||
if [ -f $config ]; then
|
||
if [ -r $config ]; then
|
||
. $config
|
||
else
|
||
echo "Cannot read $config! (Hint: Are you root?)" >&2
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "$config does not exist!" >&2
|
||
exit 2
|
||
fi
|
||
|
||
ensure_config_path
|
||
|
||
export CONFIG_PATH
|
||
|
||
get_config
|
||
|
||
if [ ! -f $FIREWALL ]; then
|
||
echo "ERROR: Shorewall is not properly installed"
|
||
if [ -L $FIREWALL ]; then
|
||
echo " $FIREWALL is a symbolic link to a"
|
||
echo " non-existant file"
|
||
else
|
||
echo " The file $FIREWALL does not exist"
|
||
fi
|
||
|
||
exit 2
|
||
fi
|
||
|
||
if [ -f $VERSION_FILE ]; then
|
||
version=$(cat $VERSION_FILE)
|
||
else
|
||
echo "ERROR: Shorewall is not properly installed"
|
||
echo " The file $VERSION_FILE does not exist"
|
||
exit 1
|
||
fi
|
||
|
||
banner="Shorewall-$version Status at $HOSTNAME -"
|
||
|
||
case $(echo -e) in
|
||
-e*)
|
||
RING_BELL="echo \a"
|
||
;;
|
||
*)
|
||
RING_BELL="echo -e \a"
|
||
;;
|
||
esac
|
||
|
||
case $(echo -n "Testing") in
|
||
-n*)
|
||
ECHO_N=
|
||
;;
|
||
*)
|
||
ECHO_N=-n
|
||
;;
|
||
esac
|
||
|
||
case "$1" in
|
||
start)
|
||
case $# in
|
||
1)
|
||
;;
|
||
2)
|
||
[ -n "$SHOREWALL_DIR" -o -n "$FAST" ] && usage 2
|
||
|
||
if [ ! -d $2 ]; then
|
||
if [ -e $2 ]; then
|
||
echo "$2 is not a directory" >&2 && exit 2
|
||
else
|
||
echo "Directory $2 does not exist" >&2 && exit 2
|
||
fi
|
||
fi
|
||
|
||
SHOREWALL_DIR=$2
|
||
export SHOREWALL_DIR
|
||
;;
|
||
*)
|
||
usage 1
|
||
;;
|
||
esac
|
||
|
||
if [ -n "$FAST" ]; then
|
||
if qt which make; then
|
||
make -qf /etc/shorewall/Makefile || FAST=
|
||
fi
|
||
|
||
if [ -n "$FAST" ]; then
|
||
|
||
RESTOREPATH=/var/lib/shorewall/$RESTOREFILE
|
||
|
||
if [ -x $RESTOREPATH ]; then
|
||
if [ -x ${RESTOREPATH}-ipsets ]; then
|
||
echo Restoring Ipsets...
|
||
#
|
||
# We must purge iptables to be sure that there are no
|
||
# references to ipsets
|
||
#
|
||
iptables -F
|
||
iptables -X
|
||
${RESTOREPATH}-ipsets
|
||
fi
|
||
|
||
echo Restoring Shorewall...
|
||
$RESTOREPATH
|
||
date > /var/lib/shorewall/restarted
|
||
echo Shorewall restored from $RESTOREPATH
|
||
else
|
||
exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock start
|
||
fi
|
||
else
|
||
exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock start
|
||
fi
|
||
else
|
||
exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock start
|
||
fi
|
||
;;
|
||
stop|reset|clear|refresh)
|
||
[ $# -ne 1 ] && usage 1
|
||
exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $1
|
||
;;
|
||
check|restart)
|
||
case $# in
|
||
1)
|
||
;;
|
||
2)
|
||
[ -n "$SHOREWALL_DIR" ] && usage 2
|
||
|
||
if [ ! -d $2 ]; then
|
||
if [ -e $2 ]; then
|
||
echo "$2 is not a directory" >&2 && exit 2
|
||
else
|
||
echo "Directory $2 does not exist" >&2 && exit 2
|
||
fi
|
||
fi
|
||
|
||
SHOREWALL_DIR=$2
|
||
export SHOREWALL_DIR
|
||
;;
|
||
*)
|
||
usage 1
|
||
;;
|
||
esac
|
||
exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $1
|
||
;;
|
||
add|delete)
|
||
[ $# -lt 3 ] && usage 1
|
||
exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock $@
|
||
;;
|
||
show|list)
|
||
[ -n "$debugging" ] && set -x
|
||
case "$2" in
|
||
connections)
|
||
[ $# -gt 2 ] && usage 1
|
||
echo "Shorewall-$version Connections at $HOSTNAME - $(date)"
|
||
echo
|
||
cat /proc/net/ip_conntrack
|
||
;;
|
||
nat)
|
||
[ $# -gt 2 ] && usage 1
|
||
echo "Shorewall-$version NAT at $HOSTNAME - $(date)"
|
||
echo
|
||
show_reset
|
||
$IPTABLES -t nat -L $IPT_OPTIONS
|
||
;;
|
||
tos|mangle)
|
||
[ $# -gt 2 ] && usage 1
|
||
echo "Shorewall-$version TOS at $HOSTNAME - $(date)"
|
||
echo
|
||
show_reset
|
||
$IPTABLES -t mangle -L $IPT_OPTIONS
|
||
;;
|
||
log)
|
||
[ $# -gt 2 ] && usage 1
|
||
echo "Shorewall-$version Log at $HOSTNAME - $(date)"
|
||
echo
|
||
show_reset
|
||
host=$(echo $HOSTNAME | sed 's/\..*$//')
|
||
packet_log 20
|
||
;;
|
||
tc)
|
||
[ $# -gt 2 ] && usage 1
|
||
echo "Shorewall-$version Traffic Control at $HOSTNAME - $(date)"
|
||
echo
|
||
show_tc
|
||
;;
|
||
classifiers)
|
||
[ $# -gt 2 ] && usage 1
|
||
echo "Shorewall-$version Clasifiers at $HOSTNAME - $(date)"
|
||
echo
|
||
show_classifiers
|
||
;;
|
||
zones)
|
||
[ $# -gt 2 ] && usage 1
|
||
if [ -f /var/lib/shorewall/zones ]; then
|
||
echo "Shorewall-$version Zones at $HOSTNAME - $(date)"
|
||
echo
|
||
while read zone hosts; do
|
||
echo $zone
|
||
for host in $hosts; do
|
||
echo " $host"
|
||
done
|
||
done < /var/lib/shorewall/zones
|
||
echo
|
||
else
|
||
echo " ERROR: /var/lib/shorewall/zones does not exist" >&2
|
||
exit 1
|
||
fi
|
||
;;
|
||
capabilities)
|
||
exec $SHOREWALL_SHELL $FIREWALL $debugging $nolock capabilities
|
||
;;
|
||
actions)
|
||
echo "allowBcast #Silently Allow Broadcast/multicast"
|
||
echo "dropBcast #Silently Drop Broadcast/multicast"
|
||
echo "dropNotSyn #Silently Drop Non-syn TCP packets"
|
||
echo "rejNotSyn #Silently Reject Non-syn TCP packets"
|
||
echo "dropInvalid #Silently Drop packets that are in the INVALID conntrack state"
|
||
echo "allowInvalid #Accept packets that are in the INVALID conntrack state."
|
||
echo "allowoutUPnP #Allow traffic from local command 'upnpd'"
|
||
echo "allowinUPnP #Allow UPnP inbound (to firewall) traffic"
|
||
echo "forwardUPnP #Allow traffic that upnpd has redirected from"
|
||
cat /usr/share/shorewall/actions.std /etc/shorewall/actions | grep -Ev '^\#|^$'
|
||
;;
|
||
*)
|
||
shift
|
||
|
||
echo "Shorewall-$version $([ $# -gt 1 ] && echo Chains || echo Chain) $* at $HOSTNAME - $(date)"
|
||
echo
|
||
show_reset
|
||
if [ $# -gt 0 ]; then
|
||
for chain in $*; do
|
||
$IPTABLES -L $chain $IPT_OPTIONS
|
||
done
|
||
else
|
||
$IPTABLES -L $IPT_OPTIONS
|
||
fi
|
||
;;
|
||
esac
|
||
;;
|
||
status)
|
||
[ -n "$debugging" ] && set -x
|
||
[ $# -eq 1 ] || usage 1
|
||
clear_term
|
||
echo "Shorewall-$version Status at $HOSTNAME - $(date)"
|
||
echo
|
||
show_reset
|
||
host=$(echo $HOSTNAME | sed 's/\..*$//')
|
||
$IPTABLES -L $IPT_OPTIONS
|
||
echo
|
||
packet_log 20
|
||
echo
|
||
echo "NAT Table"
|
||
echo
|
||
$IPTABLES -t nat -L $IPT_OPTIONS
|
||
echo
|
||
echo "Mangle Table"
|
||
echo
|
||
$IPTABLES -t mangle -L $IPT_OPTIONS
|
||
echo
|
||
cat /proc/net/ip_conntrack
|
||
echo
|
||
echo "IP Configuration"
|
||
echo
|
||
ip addr ls
|
||
echo
|
||
echo "IP Stats"
|
||
echo
|
||
ip -stat link ls
|
||
|
||
if qt which brctl; then
|
||
echo
|
||
echo "Bridges"
|
||
echo
|
||
brctl show
|
||
fi
|
||
|
||
echo
|
||
echo "/proc"
|
||
echo
|
||
|
||
show_proc /proc/sys/net/ipv4/ip_forward
|
||
show_proc /proc/sys/net/ipv4/icmp_echo_ignore_all
|
||
|
||
for directory in /proc/sys/net/ipv4/conf/*; do
|
||
for file in proxy_arp arp_filter arp_ignore rp_filter log_martians; do
|
||
show_proc $directory/$file
|
||
done
|
||
done
|
||
|
||
if [ -n "$(ip rule ls)" ]; then
|
||
echo
|
||
echo "Routing Rules"
|
||
echo
|
||
ip rule ls
|
||
ip rule ls | while read rule; do
|
||
echo ${rule##* }
|
||
done | sort -u | while read table; do
|
||
echo
|
||
echo "Table $table:"
|
||
echo
|
||
ip route ls table $table
|
||
done
|
||
else
|
||
echo
|
||
echo "Routing Table"
|
||
echo
|
||
ip route ls
|
||
fi
|
||
|
||
echo
|
||
echo "ARP"
|
||
echo
|
||
arp -na
|
||
|
||
if qt which lsmod; then
|
||
echo
|
||
echo "Modules"
|
||
echo
|
||
lsmod | grep -E '^ip_|^ipt_'
|
||
fi
|
||
;;
|
||
hits)
|
||
[ -n "$debugging" ] && set -x
|
||
[ $# -eq 1 ] || usage 1
|
||
clear_term
|
||
echo "Shorewall-$version Hits at $HOSTNAME - $(date)"
|
||
echo
|
||
|
||
timeout=30
|
||
|
||
if [ $(grep -c "$LOGFORMAT" $LOGFILE ) -gt 0 ] ; then
|
||
echo " HITS IP DATE"
|
||
echo " ---- --------------- ------"
|
||
grep "$LOGFORMAT" $LOGFILE | sed 's/\(.\{6\}\)\(.*SRC=\)\(.*\)\( DST=.*\)/\3 \1/' | sort | uniq -c | sort -rn
|
||
echo ""
|
||
|
||
echo " HITS IP PORT"
|
||
echo " ---- --------------- -----"
|
||
grep "$LOGFORMAT" $LOGFILE | sed 's/\(.*SRC=\)\(.*\)\( DST=.*DPT=\)\([0-9]\{1,5\}\)\(.*\)/\2 \4/
|
||
t
|
||
s/\(.*SRC=\)\(.*\)\( DST=.*\)/\2/' | sort | uniq -c | sort -rn
|
||
echo ""
|
||
|
||
echo " HITS DATE"
|
||
echo " ---- ------"
|
||
grep "$LOGFORMAT" $LOGFILE | sed 's/\(.\{6\}\)\(.*\)/\1/' | sort | uniq -c | sort -rn
|
||
echo ""
|
||
|
||
echo " HITS PORT SERVICE(S)"
|
||
echo " ---- ----- ----------"
|
||
grep "$LOGFORMAT.*DPT" $LOGFILE | sed 's/\(.*DPT=\)\([0-9]\{1,5\}\)\(.*\)/\2/' | sort | uniq -c | sort -rn | \
|
||
while read count port ; do
|
||
# List all services defined for the given port
|
||
srv=$(grep "^[^#].*\\b$port/" /etc/services | cut -f 1 | sort -u)
|
||
srv=$(echo $srv | sed 's/ /,/g')
|
||
|
||
if [ -n "$srv" ] ; then
|
||
printf '%7d %5d %s\n' $count $port $srv
|
||
else
|
||
printf '%7d %5d\n' $count $port
|
||
fi
|
||
done
|
||
fi
|
||
;;
|
||
version)
|
||
echo $version
|
||
;;
|
||
try)
|
||
[ -n "$SHOREWALL_DIR" ] && startup_error "ERROR: -c option may not be used with \"try\""
|
||
[ $# -lt 2 -o $# -gt 3 ] && usage 1
|
||
if ! $0 $debugging -c $2 restart; then
|
||
if ! $IPTABLES -L shorewall > /dev/null 2> /dev/null; then
|
||
$0 start
|
||
fi
|
||
elif ! $IPTABLES -L shorewall > /dev/null 2> /dev/null; then
|
||
$0 start
|
||
elif [ $# -eq 3 ]; then
|
||
sleep $3
|
||
$0 restart
|
||
fi
|
||
;;
|
||
logwatch)
|
||
[ -n "$debugging" ] && set -x
|
||
if [ $# -eq 2 ]; then
|
||
logwatch $2
|
||
elif [ $# -eq 1 ]; then
|
||
logwatch 30
|
||
else
|
||
usage 1
|
||
fi
|
||
;;
|
||
drop)
|
||
[ -n "$debugging" ] && set -x
|
||
[ $# -eq 1 ] && usage 1
|
||
mutex_on
|
||
while [ $# -gt 1 ]; do
|
||
shift
|
||
qt $IPTABLES -D dynamic -s $1 -j reject
|
||
qt $IPTABLES -D dynamic -s $1 -j DROP
|
||
$IPTABLES -A dynamic -s $1 -j DROP || break 1
|
||
echo "$1 Dropped"
|
||
done
|
||
mutex_off
|
||
;;
|
||
reject)
|
||
[ -n "$debugging" ] && set -x
|
||
[ $# -eq 1 ] && usage 1
|
||
mutex_on
|
||
while [ $# -gt 1 ]; do
|
||
shift
|
||
qt $IPTABLES -D dynamic -s $1 -j reject
|
||
qt $IPTABLES -D dynamic -s $1 -j DROP
|
||
$IPTABLES -A dynamic -s $1 -j reject || break 1
|
||
echo "$1 Rejected"
|
||
done
|
||
mutex_off
|
||
;;
|
||
allow)
|
||
[ -n "$debugging" ] && set -x
|
||
[ $# -eq 1 ] && usage 1
|
||
mutex_on
|
||
while [ $# -gt 1 ]; do
|
||
shift
|
||
if qt $IPTABLES -D dynamic -s $1 -j reject || qt $IPTABLES -D dynamic -s $1 -j DROP; then
|
||
echo "$1 Allowed"
|
||
else
|
||
echo "$1 Not Dropped or Rejected"
|
||
fi
|
||
done
|
||
mutex_off
|
||
;;
|
||
save)
|
||
[ -n "$debugging" ] && set -x
|
||
|
||
case $# in
|
||
1)
|
||
;;
|
||
2)
|
||
RESTOREFILE="$2"
|
||
validate_restorefile '<restore file>'
|
||
;;
|
||
*)
|
||
usage 1
|
||
;;
|
||
esac
|
||
|
||
RESTOREPATH=/var/lib/shorewall/$RESTOREFILE
|
||
|
||
save_config
|
||
|
||
;;
|
||
forget)
|
||
case $# in
|
||
1)
|
||
;;
|
||
2)
|
||
RESTOREFILE="$2"
|
||
validate_restorefile '<restore file>'
|
||
;;
|
||
*)
|
||
usage 1
|
||
;;
|
||
esac
|
||
|
||
|
||
RESTOREPATH=/var/lib/shorewall/$RESTOREFILE
|
||
|
||
if [ -x $RESTOREPATH ]; then
|
||
|
||
if [ -x ${RESTOREPATH}-ipsets ]; then
|
||
rm -f ${RESTOREPATH}-ipsets
|
||
echo " ${RESTOREPATH}-ipsets removed"
|
||
fi
|
||
|
||
rm -f $RESTOREPATH
|
||
echo " $RESTOREPATH removed"
|
||
elif [ -f $RESTOREPATH ]; then
|
||
echo " $RESTOREPATH exists and is not a saved Shorewall configuration"
|
||
fi
|
||
;;
|
||
ipcalc)
|
||
[ -n "$debugging" ] && set -x
|
||
if [ $# -eq 2 ]; then
|
||
address=${2%/*}
|
||
vlsm=${2#*/}
|
||
elif [ $# -eq 3 ]; then
|
||
address=$2
|
||
vlsm=$(ip_vlsm $3)
|
||
else
|
||
usage 1
|
||
fi
|
||
|
||
[ -z "$vlsm" ] && exit 2
|
||
[ "x$address" = "x$vlsm" ] && usage 2
|
||
[ $vlsm -gt 32 ] && echo "Invalid VLSM: /$vlsm" >&2 && exit 2
|
||
|
||
address=$address/$vlsm
|
||
|
||
echo " CIDR=$address"
|
||
temp=$(ip_netmask $address); echo " NETMASK=$(encodeaddr $temp)"
|
||
temp=$(ip_network $address); echo " NETWORK=$temp"
|
||
temp=$(broadcastaddress $address); echo " BROADCAST=$temp"
|
||
;;
|
||
|
||
iprange)
|
||
[ -n "$debugging" ] && set -x
|
||
case $2 in
|
||
*.*.*.*-*.*.*.*)
|
||
ip_range $2
|
||
;;
|
||
*)
|
||
usage 1
|
||
;;
|
||
esac
|
||
;;
|
||
restore)
|
||
case $# in
|
||
1)
|
||
;;
|
||
2)
|
||
RESTOREFILE="$2"
|
||
validate_restorefile '<restore file>'
|
||
;;
|
||
*)
|
||
usage 1
|
||
;;
|
||
esac
|
||
|
||
RESTOREPATH=/var/lib/shorewall/$RESTOREFILE
|
||
|
||
[ -n "$nolock" ] || mutex_on
|
||
|
||
if [ -x $RESTOREPATH ]; then
|
||
if [ -x ${RESTOREPATH}-ipsets ] ; then
|
||
echo Restoring Ipsets...
|
||
iptables -F
|
||
iptables -X
|
||
${RESTOREPATH}-ipsets
|
||
fi
|
||
|
||
echo Restoring Shorewall...
|
||
$RESTOREPATH && echo "Shorewall restored from /var/lib/shorewall/$RESTOREFILE"
|
||
[ -n "$nolock" ] || mutex_off
|
||
else
|
||
echo "File /var/lib/shorewall/$RESTOREFILE: file not found"
|
||
[ -n "$nolock" ] || mutex_off
|
||
exit 2
|
||
fi
|
||
;;
|
||
call)
|
||
[ -n "$debugging" ] && set -x
|
||
#
|
||
# Undocumented way to call functions in /usr/share/shorewall/functions directly
|
||
#
|
||
shift;
|
||
$@
|
||
;;
|
||
help)
|
||
shift
|
||
[ $# -ne 1 ] && usage 1
|
||
help $@
|
||
;;
|
||
safe-restart|safe-start)
|
||
# test is the shell supports timed read
|
||
read -t 0 junk 2> /dev/null
|
||
if [ $? -eq 2 -a ! -x /bin/bash ]
|
||
then
|
||
echo "Your shell does not support a feature required to execute this command".
|
||
exit 2
|
||
fi
|
||
|
||
mutex_on
|
||
|
||
if qt $IPTABLES -L shorewall -n
|
||
then
|
||
running=0
|
||
else
|
||
running=1
|
||
fi
|
||
|
||
if [ "$1" = "safe-start" -a $running -eq 0 ]
|
||
then
|
||
# the command is safe-start but the firewall is already running
|
||
$0 nolock $debugging start
|
||
ret=$?
|
||
exit 0
|
||
fi
|
||
|
||
if [ "$1" = "safe-start" -o $running -ne 0 ]
|
||
then
|
||
# the command is safe-start or shorewall is not started yet
|
||
command="start"
|
||
else
|
||
# the command is safe-restart and the firewall is already running |