diff --git a/Shorewall-lite/shorecap b/Shorewall-lite/shorecap index af46729ef..3bd7a7534 100755 --- a/Shorewall-lite/shorecap +++ b/Shorewall-lite/shorecap @@ -51,6 +51,7 @@ CONFDIR=/etc/shorewall-lite g_product="Shorewall Lite" . /usr/share/shorewall-lite/lib.base +. /usr/share/shorewall-lite/lib.cli . /usr/share/shorewall-lite/configpath [ -n "$PATH" ] || PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin diff --git a/Shorewall/Perl/prog.header6 b/Shorewall/Perl/prog.header6 index 411af581a..6b2ec084e 100644 --- a/Shorewall/Perl/prog.header6 +++ b/Shorewall/Perl/prog.header6 @@ -1,3 +1,5 @@ +#!/bin/sh +# # This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt] # # (c) 1999-2009 - Tom Eastep (teastep@shorewall.net) @@ -22,14 +24,6 @@ ################################################################################ # Functions imported from /usr/share/shorewall/prog.header6 ################################################################################ -# -# Message to stderr -# -error_message() # $* = Error Message -{ - echo " $@" >&2 -} - # # Conditionally produce message # @@ -81,66 +75,6 @@ progress_message3() # $* = Message fi } -# -# Split a colon-separated list into a space-separated list -# -split() { - local ifs - ifs=$IFS - IFS=: - echo $* - IFS=$ifs -} - -# -# Undo the effect of 'split()' -# -join() -{ - local f - local o - o= - - for f in $* ; do - o="${o:+$o:}$f" - done - - echo $o -} - -# -# Return the number of elements in a list -# -list_count() # $* = list -{ - return $# -} - -# -# Search a list looking for a match -- returns zero if a match found -# 1 otherwise -# -list_search() # $1 = element to search for , $2-$n = list -{ - local e - e=$1 - - while [ $# -gt 1 ]; do - shift - [ "x$e" = "x$1" ] && return 0 - done - - return 1 -} - -# -# Suppress all output for a command -# -qt() -{ - "$@" >/dev/null 2>&1 -} - qt1() { local status @@ -152,35 +86,6 @@ qt1() done } -# -# Determine if Shorewall is "running" -# -shorewall6_is_started() { - qt1 $IP6TABLES -L shorewall -n -} - -# -# Echos the fully-qualified name of the calling shell program -# -my_pathname() { - cd $(dirname $0) - echo $PWD/$(basename $0) -} - -# -# Source a user exit file if it exists -# -run_user_exit() # $1 = file name -{ - local user_exit - user_exit=$(find_file $1) - - if [ -f $user_exit ]; then - progress_message "Processing $user_exit ..." - . $user_exit - fi -} - # # Set a standard chain's policy # @@ -213,131 +118,6 @@ deleteallchains() { run_iptables -X } -# -# Load a Kernel Module -- assumes that the variable 'moduledirectories' contains -# a space-separated list of directories to search for -# the module and that 'moduleloader' contains the -# module loader command. -# -loadmodule() # $1 = module name, $2 - * arguments -{ - local modulename - modulename=$1 - local modulefile - local suffix - - if ! list_search $modulename $DONT_LOAD $MODULES; then - shift - - for suffix in $MODULE_SUFFIX ; do - for directory in $moduledirectories; do - modulefile=$directory/${modulename}.${suffix} - - if [ -f $modulefile ]; then - case $moduleloader in - insmod) - insmod $modulefile $* - ;; - *) - modprobe $modulename $* - ;; - esac - break 2 - fi - done - done - fi -} - -# -# Reload the Modules -# -reload_kernel_modules() { - - local save_modules_dir - save_modules_dir=$MODULESDIR - local directory - local moduledirectories - moduledirectories= - local moduleloader - moduleloader=modprobe - - if ! qt mywhich modprobe; then - moduleloader=insmod - fi - - [ -n "${MODULE_SUFFIX:=o gz ko o.gz ko.gz}" ] - - [ -z "$MODULESDIR" ] && MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv6/netfilter:/lib/modules/$(uname -r)/kernel/net/netfilter:/lib/modules/$(uname -r)/kernel/net/sched/ - MODULES=$(lsmod | cut -d ' ' -f1) - - for directory in $(split $MODULESDIR); do - [ -d $directory ] && moduledirectories="$moduledirectories $directory" - done - - [ -n "$moduledirectories" ] && while read command; do - eval $command - done - - MODULESDIR=$save_modules_dir -} - -# -# Load kernel modules required for Shorewall6 -# -load_kernel_modules() # $1 = Yes, if we are to save moduleinfo in $VARDIR -{ - local save_modules_dir - save_modules_dir=$MODULESDIR - local directory - local moduledirectories - moduledirectories= - local moduleloader - moduleloader=modprobe - local savemoduleinfo - savemoduleinfo=${1:-Yes} # So old compiled scripts still work - - if ! qt mywhich modprobe; then - moduleloader=insmod - fi - - [ -n "${MODULE_SUFFIX:=o gz ko o.gz ko.gz}" ] - - [ -z "$MODULESDIR" ] && \ - MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv6/netfilter:/lib/modules/$(uname -r)/kernel/net/netfilter:/lib/modules/$(uname -r)/kernel/net/sched/ - - for directory in $(split $MODULESDIR); do - [ -d $directory ] && moduledirectories="$moduledirectories $directory" - done - - [ -n "$LOAD_HELPERS_ONLY" ] && modules=$(find_file helpers) || modules=$(find_file modules) - - if [ -f $modules -a -n "$moduledirectories" ]; then - MODULES=$(lsmod | cut -d ' ' -f1) - progress_message "Loading Modules..." - . $modules - if [ $savemoduleinfo = Yes ]; then - [ -d ${VARDIR} ] || mkdir -p ${VARDIR} - echo MODULESDIR="$MODULESDIR" > ${VARDIR}/.modulesdir - cp -f $modules ${VARDIR}/.modules - fi - elif [ $savemoduleinfo = Yes ]; then - [ -d ${VARDIR} ] || mkdir -p ${VARDIR} - > ${VARDIR}/.modulesdir - > ${VARDIR}/.modules - fi - - MODULESDIR=$save_modules_dir -} - -# -# Query NetFilter about the existence of a filter chain -# -chain_exists() # $1 = chain name -{ - qt1 $IP6TABLES -L $1 -n -} - # # Find the value 'dev' in the passed arguments then echo the next value # @@ -400,32 +180,6 @@ find_default_interface() { done } -# -# Find the interface with the passed MAC address -# - -find_interface_by_mac() { - local mac - mac=$1 - local first - local second - local rest - local dev - - $IP link list | while read first second rest; do - case $first in - *:) - dev=$second - ;; - *) - if [ "$second" = $mac ]; then - echo ${dev%:} - return - fi - esac - done -} - # # Determine if Interface is up # @@ -433,40 +187,6 @@ interface_is_up() { [ -n "$($IP link list dev $1 2> /dev/null | grep -e '[<,]UP[,>]')" ] } -# -# Find interface address--returns the first IP address assigned to the passed -# device -# -find_first_interface_address() # $1 = interface -{ - # - # get the line of output containing the first IP address - # - addr=$($IP -f inet6 addr show $1 2> /dev/null | grep 'inet6 .* global' | head -n1) - # - # If there wasn't one, bail out now - # - [ -n "$addr" ] || startup_error "Can't determine the IPv6 address of $1" - # - # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) - # along with everything else on the line - # - echo $addr | sed 's/\s*inet6 //;s/\/.*//;s/ peer.*//' -} - -find_first_interface_address_if_any() # $1 = interface -{ - # - # get the line of output containing the first IP address - # - addr=$($IP -f inet6 addr show $1 2> /dev/null | grep 'inet6 2.* global' | head -n1) - # - # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) - # along with everything else on the line - # - [ -n "$addr" ] && echo $addr | sed 's/\s*inet6 //;s/\/.*//;s/ peer.*//' || echo :: -} - # # Determine if interface is usable from a Netfilter prespective # @@ -682,71 +402,6 @@ get_all_acasts() find_interface_full_addresses | convert_to_anycast | sort -u } -# -# Internal version of 'which' -# -mywhich() { - local dir - - for dir in $(split $PATH); do - if [ -x $dir/$1 ]; then - echo $dir/$1 - return 0 - fi - done - - return 2 -} - -# -# Find a File -- For relative file name, look in each ${CONFIG_PATH} then ${CONFDIR} -# -find_file() -{ - local saveifs - saveifs= - local directory - - case $1 in - /*) - echo $1 - ;; - *) - for directory in $(split $CONFIG_PATH); do - if [ -f $directory/$1 ]; then - echo $directory/$1 - return - fi - done - - echo ${CONFDIR}/$1 - ;; - esac -} - -# -# Set the Shorewall state -# -set_state () # $1 = state -{ - echo "$1 ($(date))" > ${VARDIR}/state -} - -# -# Perform variable substitution on the passed argument and echo the result -# -expand() # $@ = contents of variable which may be the name of another variable -{ - eval echo \"$@\" -} - -# -# Function for including one file into another -# -INCLUDE() { - . $(find_file $(expand $@)) -} - # # Detect the gateway through an interface # @@ -772,20 +427,6 @@ detect_gateway() # $1 = interface [ -n "$gateway" ] && echo $gateway } -# Function to truncate a string -- It uses 'cut -b -' -# rather than ${v:first:last} because light-weight shells like ash and -# dash do not support that form of expansion. -# - -truncate() # $1 = length -{ - cut -b -${1} -} - -# -# Clear the current traffic shaping configuration -# - delete_tc1() { clear_one_tc() { diff --git a/Shorewall6-lite/shorecap b/Shorewall6-lite/shorecap index b15b42325..d95df126a 100755 --- a/Shorewall6-lite/shorecap +++ b/Shorewall6-lite/shorecap @@ -51,6 +51,7 @@ CONFDIR=/etc/shorewall6-lite g_product="Shorewall Lite" . /usr/share/shorewall6-lite/lib.base +. /usr/share/shorewall6-lite/lib.cli . /usr/share/shorewall6-lite/configpath [ -n "$PATH" ] || PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin diff --git a/Shorewall6/lib.base b/Shorewall6/lib.base index 4b53c294e..bdf7f700f 100644 --- a/Shorewall6/lib.base +++ b/Shorewall6/lib.base @@ -40,14 +40,6 @@ SHOREWALL_CAPVERSION=40408 [ -n "${CONFDIR:=/etc/shorewall6}" ] [ -n "${PERLSHAREDIR:=/usr/share/shorewall}" ] -# -# Message to stderr -# -error_message() # $* = Error Message -{ - echo " $@" >&2 -} - # # Conditionally produce message # @@ -84,34 +76,6 @@ progress_message3() # $* = Message fi } -# -# Split a colon-separated list into a space-separated list -# -split() { - local ifs - ifs=$IFS - IFS=: - echo $* - IFS=$ifs -} - -# -# Search a list looking for a match -- returns zero if a match found -# 1 otherwise -# -list_search() # $1 = element to search for , $2-$n = list -{ - local e - e=$1 - - while [ $# -gt 1 ]; do - shift - [ "x$e" = "x$1" ] && return 0 - done - - return 1 -} - # # Undo the effect of 'separate_list()' # @@ -128,200 +92,6 @@ combine_list() echo $o } -# -# Suppress all output for a command -# -qt() -{ - "$@" >/dev/null 2>&1 -} - -# -# Determine if Shorewall is "running" -# -shorewall6_is_started() { - qt $IP6TABLES -L shorewall -n -} - -# -# Echos the fully-qualified name of the calling shell program -# -my_pathname() { - cd $(dirname $0) - echo $PWD/$(basename $0) -} - -# -# Source a user exit file if it exists -# -run_user_exit() # $1 = file name -{ - local user_exit - user_exit=$(find_file $1) - - if [ -f $user_exit ]; then - progress_message "Processing $user_exit ..." - . $user_exit - fi -} - -# -# Set a standard chain's policy -# -setpolicy() # $1 = name of chain, $2 = policy -{ - run_iptables -P $1 $2 -} - -# -# Set a standard chain to enable established and related connections -# -setcontinue() # $1 = name of chain -{ - run_iptables -A $1 -m state --state ESTABLISHED,RELATED -j ACCEPT -} - -# -# Flush one of the NAT table chains -# -flushnat() # $1 = name of chain -{ - run_iptables -t nat -F $1 -} - -# -# Flush one of the Mangle table chains -# -flushmangle() # $1 = name of chain -{ - run_iptables -t mangle -F $1 -} - -# -# Flush and delete all user-defined chains in the filter table -# -deleteallchains() { - run_iptables -F - run_iptables -X -} - -# -# Load a Kernel Module -- assumes that the variable 'moduledirectories' contains -# a space-separated list of directories to search for -# the module and that 'moduleloader' contains the -# module loader command. -# -loadmodule() # $1 = module name, $2 - * arguments -{ - local modulename - modulename=$1 - local modulefile - local suffix - - if ! list_search $modulename $MODULES $DONT_LOAD ; then - shift - - for suffix in $MODULE_SUFFIX ; do - for directory in $moduledirectories; do - modulefile=$directory/${modulename}.${suffix} - - if [ -f $modulefile ]; then - case $moduleloader in - insmod) - insmod $modulefile $* - ;; - *) - modprobe $modulename $* - ;; - esac - break 2 - fi - done - done - fi -} - -# -# Reload the Modules -# -reload_kernel_modules() { - - local save_modules_dir - save_modules_dir=$MODULESDIR - local directory - local moduledirectories - moduledirectories= - local moduleloader - moduleloader=modprobe - - if ! qt mywhich modprobe; then - moduleloader=insmod - fi - - [ -n "${MODULE_SUFFIX:=o gz ko o.gz ko.gz}" ] - - [ -z "$MODULESDIR" ] && MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv6/netfilter:/lib/modules/$(uname -r)/kernel/net/netfilter:/lib/modules/$(uname -r)/kernel/net/sched - MODULES=$(lsmod | cut -d ' ' -f1) - - for directory in $(split $MODULESDIR); do - [ -d $directory ] && moduledirectories="$moduledirectories $directory" - done - - [ -n "$moduledirectories" ] && while read command; do - eval $command - done - - MODULESDIR=$save_modules_dir -} - -# -# Load kernel modules required for Shorewall -# -load_kernel_modules() # $1 = Yes, if we are to save moduleinfo in $VARDIR -{ - local save_modules_dir - save_modules_dir=$MODULESDIR - local directory - local moduledirectories - moduledirectories= - local moduleloader - moduleloader=modprobe - local savemoduleinfo - savemoduleinfo=${1:-Yes} # So old compiled scripts still work - - if ! qt mywhich modprobe; then - moduleloader=insmod - fi - - [ -n "${MODULE_SUFFIX:=o gz ko o.gz ko.gz}" ] - - [ -z "$MODULESDIR" ] && \ - MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv6/netfilter:/lib/modules/$(uname -r)/kernel/net/netfilter:/lib/modules/$(uname -r)/kernel/net/sched - - for directory in $(split $MODULESDIR); do - [ -d $directory ] && moduledirectories="$moduledirectories $directory" - done - - [ -n "$LOAD_HELPERS_ONLY" ] && modules=$(find_file helpers) || modules=$(find_file modules) - - if [ -f $modules -a -n "$moduledirectories" ]; then - MODULES=$(lsmod | cut -d ' ' -f1) - progress_message "Loading Modules..." - . $modules - if [ $savemoduleinfo = Yes ]; then - [ -d ${VARDIR} ] || mkdir -p ${VARDIR} - echo MODULESDIR="$MODULESDIR" > ${VARDIR}/.modulesdir - cp -f $modules ${VARDIR}/.modules - fi - elif [ $savemoduleinfo = Yes ]; then - [ -d ${VARDIR} ] || mkdir -p ${VARDIR} - > ${VARDIR}/.modulesdir - > ${VARDIR}/.modules - fi - - MODULESDIR=$save_modules_dir -} - # # Call this function to assert mutual exclusion with Shorewall. If you invoke the # /sbin/shorewall program while holding mutual exclusion, you should pass "nolock" as @@ -370,30 +140,6 @@ mutex_off() rm -f ${LOCKFILE:=${VARDIR}/lock} } -# -# Load an optional library -# -lib_load() # $1 = Name of the Library, $2 = Error Message heading if the library cannot be found -{ - local lib - lib=${SHAREDIR}/lib.$1 - local loaded - - eval loaded=\$LIB_${1}_LOADED - - if [ -z "$loaded" ]; then - [ -f $lib ] || lib=${SHELLSHAREDIR}/lib.$1 - - if [ -f $lib ]; then - progress_message "Loading library $lib..." - . $lib - eval LIB_${1}_LOADED=Yes - else - startup_error "$2 requires the Shorewall library $1 ($lib) which is not installed" - fi - fi -} - # # Query NetFilter about the existence of a filter chain # @@ -402,68 +148,6 @@ chain_exists() # $1 = chain name qt $IP6TABLES -L $1 -n } -# -# Find the value 'dev' in the passed arguments then echo the next value -# - -find_device() { - while [ $# -gt 1 ]; do - [ "x$1" = xdev ] && echo $2 && return - shift - done -} - -# -# Find the value 'via' in the passed arguments then echo the next value -# - -find_gateway() { - while [ $# -gt 1 ]; do - [ "x$1" = xvia ] && echo $2 && return - shift - done -} - -# -# Find the value 'mtu' in the passed arguments then echo the next value -# - -find_mtu() { - while [ $# -gt 1 ]; do - [ "x$1" = xmtu ] && echo $2 && return - shift - done -} - -# -# Find the value 'peer' in the passed arguments then echo the next value up to -# "/" -# - -find_peer() { - while [ $# -gt 1 ]; do - [ "x$1" = xpeer ] && echo ${2%/*} && return - shift - done -} - -# -# Try to find the gateway through an interface looking for 'nexthop' - -find_nexthop() # $1 = interface -{ - echo $(find_gateway `ip -6 route list | grep "[[:space:]]nexthop.* $1"`) -} - -# -# Find the default route's interface -# -find_default_interface() { - ip -6 route list | while read first rest; do - [ "$first" = default ] && echo $(find_device $rest) && return - done -} - # # Find the interface with the passed MAC address # @@ -490,109 +174,6 @@ find_interface_by_mac() { done } -# -# Determine if Interface is up -# -interface_is_up() { - [ -n "$(ip link list dev $1 2> /dev/null | grep -e '[<,]UP[,>]')" ] -} - -# -# Find interface address--returns the first IP address assigned to the passed -# device -# -find_first_interface_address() # $1 = interface -{ - # - # get the line of output containing the first IP address - # - addr=$(ip -f inet6 addr show $1 2> /dev/null | grep 'inet6 .* global' | head -n1) - # - # If there wasn't one, bail out now - # - [ -n "$addr" ] || fatal_error "Can't determine the IPv6 address of $1" - # - # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) - # along with everything else on the line - # - echo $addr | sed 's/\s*inet6 //;s/\/.*//;s/ peer.*//' -} - -find_first_interface_address_if_any() # $1 = interface -{ - # - # get the line of output containing the first IP address - # - addr=$(ip -f inet6 addr show $1 2> /dev/null | grep 'inet6 .* global' | head -n1) - # - # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) - # along with everything else on the line - # - [ -n "$addr" ] && echo $addr | sed 's/\s*inet6 //;s/\/.*//;s/ peer.*//' || echo :: -} - -# -# Determine if interface is usable from a Netfilter prespective -# -interface_is_usable() # $1 = interface -{ - interface_is_up $1 && [ "$(find_first_interface_address_if_any $1)" != :: ] -} - -# -# Find interface addresses--returns the set of addresses assigned to the passed -# device -# -find_interface_addresses() # $1 = interface -{ - ip -f inet6 addr show $1 2> /dev/null | grep inet\ | sed 's/\s*inet6 //;s/\/.*//;s/ peer.*//' -} - -# -# echo the list of networks routed out of a given interface -# -get_routed_networks() # $1 = interface name, $2-n = Fatal error message -{ - local address - local rest - - ip -6 route show dev $1 2> /dev/null | - while read address rest; do - case "$address" in - default) - if [ $# -gt 1 ]; then - shift - fatal_error "$@" - else - echo "WARNING: default route ignored on interface $1" >&2 - fi - ;; - multicast|broadcast|prohibit|nat|throw|nexthop) - ;; - *) - [ "$address" = "${address%/*}" ] && address="${address}/128" - echo $address - ;; - esac - done -} - -# -# Internal version of 'which' -# -mywhich() { - local dir - - for dir in $(split $PATH); do - if [ -x $dir/$1 ]; then - echo $dir/$1 - return 0 - fi - done - - return 2 -} - # # Set default config path # @@ -609,32 +190,6 @@ ensure_config_path() { fi } -# -# Find a File -- For relative file name, look in each ${CONFIG_PATH} then ${CONFDIR} -# -find_file() -{ - local saveifs - saveifs= - local directory - - case $1 in - /*) - echo $1 - ;; - *) - for directory in $(split $CONFIG_PATH); do - if [ -f $directory/$1 ]; then - echo $directory/$1 - return - fi - done - - echo ${CONFDIR}/$1 - ;; - esac -} - # # Get fully-qualified name of file # @@ -669,346 +224,6 @@ resolve_file() # $1 = file name esac } -# -# Perform variable substitution on the passed argument and echo the result -# -expand() # $@ = contents of variable which may be the name of another variable -{ - eval echo \"$@\" -} - -# -# Function for including one file into another -# -INCLUDE() { - . $(find_file $(expand $@)) -} - -# -# Set the Shorewall state -# -set_state () # $1 = state -{ - echo "$1 ($(date))" > ${VARDIR}/state -} - -# -# Determine which optional facilities are supported by iptables/netfilter -# -determine_capabilities() { - CONNTRACK_MATCH= - NEW_CONNTRACK_MATCH= - OLD_CONNTRACK_MATCH= - MULTIPORT= - XMULTIPORT= - POLICY_MATCH= - PHYSDEV_MATCH= - PHYSDEV_BRIDGE= - IPRANGE_MATCH= - RECENT_MATCH= - OWNER_MATCH= - IPSET_MATCH= - CONNMARK= - XCONNMARK= - CONNMARK_MATCH= - XCONNMARK_MATCH= - RAW_TABLE= - IPP2P_MATCH= - OLD_IPP2P_MATCH= - LENGTH_MATCH= - CLASSIFY_TARGET= - ENHANCED_REJECT= - USEPKTTYPE= - KLUDGEFREE= - MARK= - XMARK= - EXMARK= - TPROXY_TARGET= - MANGLE_FORWARD= - COMMENTS= - ADDRTYPE= - TCPMSS_MATCH= - HASHLIMIT_MATCH= - NFQUEUE_TARGET= - REALM_MATCH= - HELPER_MATCH= - CONNLIMIT_MATCH= - TIME_MATCH= - GOTO_TARGET= - IPMARK_TARGET= - LOG_TARGET=Yes - FLOW_FILTER= - - chain=fooX$$ - - [ -n "$IP6TABLES" ] || IP6TABLES=$(mywhich ip6tables) - - if [ -z "$IP6TABLES" ]; then - echo " ERROR: No executable iptables binary can be found on your PATH" >&2 - exit 1 - fi - - [ -n "$IP" ] || IP=$(which ip) - - [ -n "$IP" -a -x "$IP" ] || IP= - - qt $IP6TABLES -t mangle -L -n && MANGLE_ENABLED=Yes || MANGLE_ENABLED= - - qt $IP6TABLES -F $chain - qt $IP6TABLES -X $chain - if ! $IP6TABLES -N $chain; then - echo " ERROR: The command \"$IP6TABLES -N $chain\" failed" >&2 - exit 1 - fi - - chain1=${chain}1 - - qt $IP6TABLES -F $chain1 - qt $IP6TABLES -X $chain1 - if ! $IP6TABLES -N $chain1; then - echo " ERROR: The command \"$IP6TABLES -N $chain1\" failed" >&2 - exit 1 - fi - - if ! qt $IP6TABLES -A $chain -m state --state ESTABLISHED,RELATED -j ACCEPT; then - echo " ERROR: Your kernel lacks connection tracking and/or state matching -- Shorewall will not run on this system" >&2 - exit 1 - fi - - qt $IP6TABLES -A $chain -m conntrack --ctorigdst ::1 -j ACCEPT && CONNTRACK_MATCH=Yes - - if [ -n "$CONNTRACK_MATCH" ]; then - qt $IP6TABLES -A $chain -m conntrack -p tcp --ctorigdstport 22 -j ACCEPT && NEW_CONNTRACK_MATCH=Yes - qt $IP6TABLES -A $chain -m conntrack ! --ctorigdst ::1 || OLD_CONNTRACK_MATCH=Yes - fi - - if qt $IP6TABLES -A $chain -p tcp -m multiport --dports 21,22 -j ACCEPT; then - MULTIPORT=Yes - qt $IP6TABLES -A $chain -p tcp -m multiport --sports 60 -m multiport --dports 99 -j ACCEPT && KLUDEFREE=Yes - fi - - qt $IP6TABLES -A $chain -p tcp -m multiport --dports 21:22 -j ACCEPT && XMULTIPORT=Yes - qt $IP6TABLES -A $chain -m policy --pol ipsec --mode tunnel --dir in -j ACCEPT && POLICY_MATCH=Yes - - if qt $IP6TABLES -A $chain -m physdev --physdev-out eth0 -j ACCEPT; then - PHYSDEV_MATCH=Yes - qt $IP6TABLES -A $chain -m physdev --physdev-is-bridged --physdev-in eth0 --physdev-out eth0 -j ACCEPT && PHYSDEV_BRIDGE=Yes - if [ -z "${KLUDGEFREE}" ]; then - qt $IP6TABLES -A $chain -m physdev --physdev-in eth0 -m physdev --physdev-out eth0 -j ACCEPT && KLUDGEFREE=Yes - fi - fi - - if qt $IP6TABLES -A $chain -m iprange --src-range ::1-::2 -j ACCEPT; then - IPRANGE_MATCH=Yes - if [ -z "${KLUDGEFREE}" ]; then - qt $IP6TABLES -A $chain -m iprange --src-range ::1-::2 -m iprange --dst-range ::1-::2 -j ACCEPT && KLUDGEFREE=Yes - fi - fi - - qt $IP6TABLES -A $chain -m recent --update -j ACCEPT && RECENT_MATCH=Yes - qt $IP6TABLES -A $chain -m owner --uid-owner 0 -j ACCEPT && OWNER_MATCH=Yes - - if qt $IP6TABLES -A $chain -m connmark --mark 2 -j ACCEPT; then - CONNMARK_MATCH=Yes - qt $IP6TABLES -A $chain -m connmark --mark 2/0xFF -j ACCEPT && XCONNMARK_MATCH=Yes - fi - - qt $IP6TABLES -A $chain -p tcp -m ipp2p --edk -j ACCEPT && IPP2P_MATCH=Yes - if [ -n "$IPP2P_MATCH" ]; then - qt $IP6TABLES -A $chain -p tcp -m ipp2p --ipp2p -j ACCEPT && OLD_IPP2P_MATCH=Yes - fi - - qt $IP6TABLES -A $chain -m length --length 10:20 -j ACCEPT && LENGTH_MATCH=Yes - qt $IP6TABLES -A $chain -j REJECT --reject-with icmp6-adm-prohibited && ENHANCED_REJECT=Yes - - qt $IP6TABLES -A $chain -j ACCEPT -m comment --comment "This is a comment" && COMMENTS=Yes - - if [ -n "$MANGLE_ENABLED" ]; then - qt $IP6TABLES -t mangle -N $chain - - if qt $IP6TABLES -t mangle -A $chain -j MARK --set-mark 1; then - MARK=Yes - qt $IP6TABLES -t mangle -A $chain -j MARK --and-mark 0xFF && XMARK=Yes - qt $IP6TABLES -t mangle -A $chain -j MARK --set-mark 1/0xFF && EXMARK=Yes - fi - - if qt $IP6TABLES -t mangle -A $chain -j CONNMARK --save-mark; then - CONNMARK=Yes - qt $IP6TABLES -t mangle -A $chain -j CONNMARK --save-mark --mask 0xFF && XCONNMARK=Yes - fi - - qt $IP6TABLES -t mangle -A $chain -j CLASSIFY --set-class 1:1 && CLASSIFY_TARGET=Yes - qt $IP6TABLES -t mangle -A $chain -j IPMARK --addr src && IPMARK_TARGET=Yes - qt $IP6TABLES -t mangle -A $chain -p tcp -j TPROXY --on-port 0 --tproxy-mark 1 && TPROXY_TARGET=Yes - qt $IP6TABLES -t mangle -F $chain - qt $IP6TABLES -t mangle -X $chain - qt $IP6TABLES -t mangle -L FORWARD -n && MANGLE_FORWARD=Yes - fi - - qt $IP6TABLES -t raw -L -n && RAW_TABLE=Yes - - if qt mywhich ipset; then - qt ipset -X $chain # Just in case something went wrong the last time - - if qt ipset -N $chain iphash ; then - if qt $IP6TABLES -A $chain -m set --set $chain src -j ACCEPT; then - qt $IP6TABLES -D $chain -m set --set $chain src -j ACCEPT - IPSET_MATCH=Yes - fi - qt ipset -X $chain - fi - fi - - qt $IP6TABLES -A $chain -m pkttype --pkt-type broadcast -j ACCEPT && USEPKTTYPE=Yes - qt $IP6TABLES -A $chain -m addrtype --src-type BROADCAST -j ACCEPT && ADDRTYPE=Yes - qt $IP6TABLES -A $chain -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1000:1500 -j ACCEPT && TCPMSS_MATCH=Yes - qt $IP6TABLES -A $chain -m hashlimit --hashlimit-upto 4 --hashlimit-burst 5 --hashlimit-name $chain --hashlimit-mode dstip -j ACCEPT && HASHLIMIT_MATCH=Yes - if [ -z "$HASHLIMIT_MATCH" ]; then - qt $IP6TABLES -A $chain -m hashlimit --hashlimit 4 --hashlimit-burst 5 --hashlimit-name $chain --hashlimit-mode dstip -j ACCEPT && OLD_HL_MATCH=Yes - HASHLIMIT_MATCH=$OLD_HL_MATCH - fi - qt $IP6TABLES -A $chain -j NFQUEUE --queue-num 4 && NFQUEUE_TARGET=Yes - qt $IP6TABLES -A $chain -m realm --realm 4 && REALM_MATCH=Yes - qt $IP6TABLES -A $chain -m helper --helper "ftp" && HELPER_MATCH=Yes - qt $IP6TABLES -A $chain -m connlimit --connlimit-above 8 -j DROP && CONNLIMIT_MATCH=Yes - qt $IP6TABLES -A $chain -m time --timestart 23:00 -j DROP && TIME_MATCH=Yes - qt $IP6TABLES -A $chain -g $chain1 && GOTO_TARGET=Yes - qt $IP6TABLES -A $chain -j LOG || LOG_TARGET= - - qt $IP6TABLES -F $chain - qt $IP6TABLES -X $chain - qt $IP6TABLES -F $chain1 - qt $IP6TABLES -X $chain1 - - [ -n "$IP" ] && $IP filter add flow help 2>&1 | grep -q ^Usage && FLOW_FILTER=Yes - - CAPVERSION=$SHOREWALL_CAPVERSION - KERNELVERSION=$(printf "%d%02d%02d" $(uname -r 2> /dev/null | sed -e 's/-.*//' -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/\1 \2 \3/g')) -} - -report_capabilities() { - report_capability() # $1 = Capability Description , $2 Capability Setting (if any) - { - local setting - setting= - - [ "x$2" = "xYes" ] && setting="Available" || setting="Not available" - - echo " " $1: $setting - } - - if [ $VERBOSITY -gt 1 ]; then - echo "Shorewall6 has detected the following ip6tables/netfilter capabilities:" - report_capability "Packet Mangling" $MANGLE_ENABLED - report_capability "Multi-port Match" $MULTIPORT - [ -n "$MULTIPORT" ] && report_capability "Extended Multi-port Match" $XMULTIPORT - report_capability "Connection Tracking Match" $CONNTRACK_MATCH - if [ -n "$CONNTRACK_MATCH" ]; then - report_capability "Extended Connection Tracking Match Support" $NEW_CONNTRACK_MATCH - [ -n "$OLD_CONNTRACK_MATCH" ] && report_capability "Old Connection Tracking Match Syntax" $OLD_CONNTRACK_MATCH - fi - report_capability "Packet Type Match" $USEPKTTYPE - report_capability "Policy Match" $POLICY_MATCH - report_capability "Physdev Match" $PHYSDEV_MATCH - report_capability "Physdev-is-bridged Support" $PHYSDEV_BRIDGE - report_capability "Packet length Match" $LENGTH_MATCH - report_capability "IP range Match" $IPRANGE_MATCH - report_capability "Recent Match" $RECENT_MATCH - report_capability "Owner Match" $OWNER_MATCH - report_capability "Ipset Match" $IPSET_MATCH - report_capability "CONNMARK Target" $CONNMARK - [ -n "$CONNMARK" ] && report_capability "Extended CONNMARK Target" $XCONNMARK - report_capability "Connmark Match" $CONNMARK_MATCH - [ -n "$CONNMARK_MATCH" ] && report_capability "Extended Connmark Match" $XCONNMARK_MATCH - report_capability "Raw Table" $RAW_TABLE - report_capability "IPP2P Match" $IPP2P_MATCH - [ -n "$OLD_IPP2P_MATCH" ] && report_capability "Old IPP2P Match Syntax" $OLD_IPP2P_MATCH - report_capability "CLASSIFY Target" $CLASSIFY_TARGET - report_capability "Extended REJECT" $ENHANCED_REJECT - report_capability "Repeat match" $KLUDGEFREE - report_capability "MARK Target" $MARK - [ -n "$MARK" ] && report_capability "Extended MARK Target" $XMARK - [ -n "$XMARK" ] && report_capability "Extended MARK Target 2" $EXMARK - report_capability "Mangle FORWARD Chain" $MANGLE_FORWARD - report_capability "Comments" $COMMENTS - report_capability "Address Type Match" $ADDRTYPE - report_capability "TCPMSS Match" $TCPMSS_MATCH - report_capability "Hashlimit Match" $HASHLIMIT_MATCH - [ -n "$OLD_HL_MATCH" ] && report_capability "Old Hashlimit Match" $OLD_HL_MATCH - report_capability "NFQUEUE Target" $NFQUEUE_TARGET - report_capability "Realm Match" $REALM_MATCH - report_capability "Helper Match" $HELPER_MATCH - report_capability "Connlimit Match" $CONNLIMIT_MATCH - report_capability "Time Match" $TIME_MATCH - report_capability "Goto Support" $GOTO_TARGET - report_capability "IPMARK Target" $IPMARK_TARGET - report_capability "LOG Target" $LOG_TARGET - report_capability "TPROXY Target" $TPROXY_TARGET - report_capability "FLOW Classifier" $FLOW_FILTER - fi - - [ -n "$PKTTYPE" ] || USEPKTTYPE= - -} - -report_capabilities1() { - report_capability1() # $1 = Capability - { - eval echo $1=\$$1 - } - - echo "#" - echo "# Shorewall6 $SHOREWALL_VERSION detected the following ip6tables/netfilter capabilities - $(date)" - echo "#" - report_capability1 MANGLE_ENABLED - report_capability1 MULTIPORT - report_capability1 XMULTIPORT - report_capability1 CONNTRACK_MATCH - report_capability1 NEW_CONNTRACK_MATCH - report_capability1 OLD_CONNTRACK_MATCH - report_capability1 USEPKTTYPE - report_capability1 POLICY_MATCH - report_capability1 PHYSDEV_MATCH - report_capability1 PHYSDEV_BRIDGE - report_capability1 LENGTH_MATCH - report_capability1 IPRANGE_MATCH - report_capability1 RECENT_MATCH - report_capability1 OWNER_MATCH - report_capability1 IPSET_MATCH - report_capability1 CONNMARK - report_capability1 XCONNMARK - report_capability1 CONNMARK_MATCH - report_capability1 XCONNMARK_MATCH - report_capability1 RAW_TABLE - report_capability1 IPP2P_MATCH - report_capability1 OLD_IPP2P_MATCH - report_capability1 CLASSIFY_TARGET - report_capability1 ENHANCED_REJECT - report_capability1 KLUDGEFREE - report_capability1 MARK - report_capability1 XMARK - report_capability1 EXMARK - report_capability1 MANGLE_FORWARD - report_capability1 COMMENTS - report_capability1 ADDRTYPE - report_capability1 TCPMSS_MATCH - report_capability1 HASHLIMIT_MATCH - report_capability1 OLD_HL_MATCH - report_capability1 NFQUEUE_TARGET - report_capability1 REALM_MATCH - report_capability1 HELPER_MATCH - report_capability1 CONNLIMIT_MATCH - report_capability1 TIME_MATCH - report_capability1 GOTO_TARGET - report_capability1 IPMARK_TARGET - report_capability1 LOG_TARGET - report_capability1 TPROXY_TARGET - report_capability1 FLOW_FILTER - - echo CAPVERSION=$SHOREWALL_CAPVERSION - echo KERNELVERSION=$KERNELVERSION -} - detect_gateway() # $1 = interface { local interface @@ -1031,136 +246,6 @@ detect_gateway() # $1 = interface [ -n "$gateway" ] && echo $gateway } -# Function to truncate a string -- It uses 'cut -b -' -# rather than ${v:first:last} because light-weight shells like ash and -# dash do not support that form of expansion. -# - -truncate() # $1 = length -{ - cut -b -${1} -} - -delete_tc1() -{ - clear_one_tc() { - tc qdisc del dev $1 root 2> /dev/null - tc qdisc del dev $1 ingress 2> /dev/null - - } - - run_user_exit tcclear - - run_ip link list | \ - while read inx interface details; do - case $inx in - [0-9]*) - clear_one_tc ${interface%:} - ;; - *) - ;; - esac - done -} - -# -# Detect a device's MTU -- echos the passed device's MTU -# -get_device_mtu() # $1 = device -{ - local output - output="$(ip link list dev $1 2> /dev/null)" # quotes required for /bin/ash - - if [ -n "$output" ]; then - echo $(find_mtu $output) - else - echo 1500 - fi -} - -# -# Version of the above that doesn't generate any output for MTU 1500. -# Generates 'mtu ' otherwise, where is the device's MTU + 100 -# -get_device_mtu1() # $1 = device -{ - local output - output="$(ip link list dev $1 2> /dev/null)" # quotes required for /bin/ash - local mtu - - if [ -n "$output" ]; then - mtu=$(find_mtu $output) - if [ -n "$mtu" ]; then - [ $mtu = 1500 ] || echo mtu $(($mtu + 100)) - fi - fi - -} - -# -# Undo changes to routing -# -undo_routing() { - - if [ -z "$g_noroutes" ]; then - # - # Restore rt_tables database - # - if [ -f ${VARDIR}/rt_tables ]; then - [ -w /etc/iproute2/rt_table -a -z "$KEEP_RT_TABLES" ] && cp -f ${VARDIR}/rt_tables /etc/iproute2/ && progress_message "/etc/iproute2/rt_tables database restored" - rm -f ${VARDIR}/rt_tables - fi - # - # Restore the rest of the routing table - # - if [ -f ${VARDIR}/undo_routing ]; then - . ${VARDIR}/undo_routing - progress_message "Shorewall6-generated routing tables and routing rules removed" - rm -f ${VARDIR}/undo_routing - fi - fi - -} - -restore_default_route() { - if [ -z "$g_noroutes" -a -f ${VARDIR}/default_route ]; then - local default_route - default_route= - local route - - while read route ; do - case $route in - default*) - if [ -n "$default_route" ]; then - case "$default_route" in - *metric*) - # - # Don't restore a route with a metric -- we only replace the one with metric == 0 - # - qt ip -6 route delete default metric 0 && \ - progress_message "Default Route with metric 0 deleted" - ;; - *) - qt ip -6 route replace $default_route && \ - progress_message "Default Route (${default_route# }) restored" - ;; - esac - - break - fi - - default_route="$default_route $route" - ;; - *) - default_route="$default_route $route" - ;; - esac - done < ${VARDIR}/default_route - - rm -f ${VARDIR}/default_route - fi -} - # # Determine how to do "echo -e" # diff --git a/Shorewall6/lib.cli b/Shorewall6/lib.cli index 5440c8574..887df582d 100644 --- a/Shorewall6/lib.cli +++ b/Shorewall6/lib.cli @@ -1125,3 +1125,320 @@ logwatch_command() { usage 1 fi } + +# +# Determine which optional facilities are supported by iptables/netfilter +# +determine_capabilities() { + CONNTRACK_MATCH= + NEW_CONNTRACK_MATCH= + OLD_CONNTRACK_MATCH= + MULTIPORT= + XMULTIPORT= + POLICY_MATCH= + PHYSDEV_MATCH= + PHYSDEV_BRIDGE= + IPRANGE_MATCH= + RECENT_MATCH= + OWNER_MATCH= + IPSET_MATCH= + CONNMARK= + XCONNMARK= + CONNMARK_MATCH= + XCONNMARK_MATCH= + RAW_TABLE= + IPP2P_MATCH= + OLD_IPP2P_MATCH= + LENGTH_MATCH= + CLASSIFY_TARGET= + ENHANCED_REJECT= + USEPKTTYPE= + KLUDGEFREE= + MARK= + XMARK= + EXMARK= + TPROXY_TARGET= + MANGLE_FORWARD= + COMMENTS= + ADDRTYPE= + TCPMSS_MATCH= + HASHLIMIT_MATCH= + NFQUEUE_TARGET= + REALM_MATCH= + HELPER_MATCH= + CONNLIMIT_MATCH= + TIME_MATCH= + GOTO_TARGET= + IPMARK_TARGET= + LOG_TARGET=Yes + FLOW_FILTER= + + chain=fooX$$ + + [ -n "$IP6TABLES" ] || IP6TABLES=$(mywhich ip6tables) + + if [ -z "$IP6TABLES" ]; then + echo " ERROR: No executable iptables binary can be found on your PATH" >&2 + exit 1 + fi + + [ -n "$IP" ] || IP=$(which ip) + + [ -n "$IP" -a -x "$IP" ] || IP= + + qt $IP6TABLES -t mangle -L -n && MANGLE_ENABLED=Yes || MANGLE_ENABLED= + + qt $IP6TABLES -F $chain + qt $IP6TABLES -X $chain + if ! $IP6TABLES -N $chain; then + echo " ERROR: The command \"$IP6TABLES -N $chain\" failed" >&2 + exit 1 + fi + + chain1=${chain}1 + + qt $IP6TABLES -F $chain1 + qt $IP6TABLES -X $chain1 + if ! $IP6TABLES -N $chain1; then + echo " ERROR: The command \"$IP6TABLES -N $chain1\" failed" >&2 + exit 1 + fi + + if ! qt $IP6TABLES -A $chain -m state --state ESTABLISHED,RELATED -j ACCEPT; then + echo " ERROR: Your kernel lacks connection tracking and/or state matching -- Shorewall will not run on this system" >&2 + exit 1 + fi + + qt $IP6TABLES -A $chain -m conntrack --ctorigdst ::1 -j ACCEPT && CONNTRACK_MATCH=Yes + + if [ -n "$CONNTRACK_MATCH" ]; then + qt $IP6TABLES -A $chain -m conntrack -p tcp --ctorigdstport 22 -j ACCEPT && NEW_CONNTRACK_MATCH=Yes + qt $IP6TABLES -A $chain -m conntrack ! --ctorigdst ::1 || OLD_CONNTRACK_MATCH=Yes + fi + + if qt $IP6TABLES -A $chain -p tcp -m multiport --dports 21,22 -j ACCEPT; then + MULTIPORT=Yes + qt $IP6TABLES -A $chain -p tcp -m multiport --sports 60 -m multiport --dports 99 -j ACCEPT && KLUDEFREE=Yes + fi + + qt $IP6TABLES -A $chain -p tcp -m multiport --dports 21:22 -j ACCEPT && XMULTIPORT=Yes + qt $IP6TABLES -A $chain -m policy --pol ipsec --mode tunnel --dir in -j ACCEPT && POLICY_MATCH=Yes + + if qt $IP6TABLES -A $chain -m physdev --physdev-out eth0 -j ACCEPT; then + PHYSDEV_MATCH=Yes + qt $IP6TABLES -A $chain -m physdev --physdev-is-bridged --physdev-in eth0 --physdev-out eth0 -j ACCEPT && PHYSDEV_BRIDGE=Yes + if [ -z "${KLUDGEFREE}" ]; then + qt $IP6TABLES -A $chain -m physdev --physdev-in eth0 -m physdev --physdev-out eth0 -j ACCEPT && KLUDGEFREE=Yes + fi + fi + + if qt $IP6TABLES -A $chain -m iprange --src-range ::1-::2 -j ACCEPT; then + IPRANGE_MATCH=Yes + if [ -z "${KLUDGEFREE}" ]; then + qt $IP6TABLES -A $chain -m iprange --src-range ::1-::2 -m iprange --dst-range ::1-::2 -j ACCEPT && KLUDGEFREE=Yes + fi + fi + + qt $IP6TABLES -A $chain -m recent --update -j ACCEPT && RECENT_MATCH=Yes + qt $IP6TABLES -A $chain -m owner --uid-owner 0 -j ACCEPT && OWNER_MATCH=Yes + + if qt $IP6TABLES -A $chain -m connmark --mark 2 -j ACCEPT; then + CONNMARK_MATCH=Yes + qt $IP6TABLES -A $chain -m connmark --mark 2/0xFF -j ACCEPT && XCONNMARK_MATCH=Yes + fi + + qt $IP6TABLES -A $chain -p tcp -m ipp2p --edk -j ACCEPT && IPP2P_MATCH=Yes + if [ -n "$IPP2P_MATCH" ]; then + qt $IP6TABLES -A $chain -p tcp -m ipp2p --ipp2p -j ACCEPT && OLD_IPP2P_MATCH=Yes + fi + + qt $IP6TABLES -A $chain -m length --length 10:20 -j ACCEPT && LENGTH_MATCH=Yes + qt $IP6TABLES -A $chain -j REJECT --reject-with icmp6-adm-prohibited && ENHANCED_REJECT=Yes + + qt $IP6TABLES -A $chain -j ACCEPT -m comment --comment "This is a comment" && COMMENTS=Yes + + if [ -n "$MANGLE_ENABLED" ]; then + qt $IP6TABLES -t mangle -N $chain + + if qt $IP6TABLES -t mangle -A $chain -j MARK --set-mark 1; then + MARK=Yes + qt $IP6TABLES -t mangle -A $chain -j MARK --and-mark 0xFF && XMARK=Yes + qt $IP6TABLES -t mangle -A $chain -j MARK --set-mark 1/0xFF && EXMARK=Yes + fi + + if qt $IP6TABLES -t mangle -A $chain -j CONNMARK --save-mark; then + CONNMARK=Yes + qt $IP6TABLES -t mangle -A $chain -j CONNMARK --save-mark --mask 0xFF && XCONNMARK=Yes + fi + + qt $IP6TABLES -t mangle -A $chain -j CLASSIFY --set-class 1:1 && CLASSIFY_TARGET=Yes + qt $IP6TABLES -t mangle -A $chain -j IPMARK --addr src && IPMARK_TARGET=Yes + qt $IP6TABLES -t mangle -A $chain -p tcp -j TPROXY --on-port 0 --tproxy-mark 1 && TPROXY_TARGET=Yes + qt $IP6TABLES -t mangle -F $chain + qt $IP6TABLES -t mangle -X $chain + qt $IP6TABLES -t mangle -L FORWARD -n && MANGLE_FORWARD=Yes + fi + + qt $IP6TABLES -t raw -L -n && RAW_TABLE=Yes + + if qt mywhich ipset; then + qt ipset -X $chain # Just in case something went wrong the last time + + if qt ipset -N $chain iphash ; then + if qt $IP6TABLES -A $chain -m set --set $chain src -j ACCEPT; then + qt $IP6TABLES -D $chain -m set --set $chain src -j ACCEPT + IPSET_MATCH=Yes + fi + qt ipset -X $chain + fi + fi + + qt $IP6TABLES -A $chain -m pkttype --pkt-type broadcast -j ACCEPT && USEPKTTYPE=Yes + qt $IP6TABLES -A $chain -m addrtype --src-type BROADCAST -j ACCEPT && ADDRTYPE=Yes + qt $IP6TABLES -A $chain -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1000:1500 -j ACCEPT && TCPMSS_MATCH=Yes + qt $IP6TABLES -A $chain -m hashlimit --hashlimit-upto 4 --hashlimit-burst 5 --hashlimit-name $chain --hashlimit-mode dstip -j ACCEPT && HASHLIMIT_MATCH=Yes + if [ -z "$HASHLIMIT_MATCH" ]; then + qt $IP6TABLES -A $chain -m hashlimit --hashlimit 4 --hashlimit-burst 5 --hashlimit-name $chain --hashlimit-mode dstip -j ACCEPT && OLD_HL_MATCH=Yes + HASHLIMIT_MATCH=$OLD_HL_MATCH + fi + qt $IP6TABLES -A $chain -j NFQUEUE --queue-num 4 && NFQUEUE_TARGET=Yes + qt $IP6TABLES -A $chain -m realm --realm 4 && REALM_MATCH=Yes + qt $IP6TABLES -A $chain -m helper --helper "ftp" && HELPER_MATCH=Yes + qt $IP6TABLES -A $chain -m connlimit --connlimit-above 8 -j DROP && CONNLIMIT_MATCH=Yes + qt $IP6TABLES -A $chain -m time --timestart 23:00 -j DROP && TIME_MATCH=Yes + qt $IP6TABLES -A $chain -g $chain1 && GOTO_TARGET=Yes + qt $IP6TABLES -A $chain -j LOG || LOG_TARGET= + + qt $IP6TABLES -F $chain + qt $IP6TABLES -X $chain + qt $IP6TABLES -F $chain1 + qt $IP6TABLES -X $chain1 + + [ -n "$IP" ] && $IP filter add flow help 2>&1 | grep -q ^Usage && FLOW_FILTER=Yes + + CAPVERSION=$SHOREWALL_CAPVERSION + KERNELVERSION=$(printf "%d%02d%02d" $(uname -r 2> /dev/null | sed -e 's/-.*//' -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\).*$/\1 \2 \3/g')) +} + +report_capabilities() { + report_capability() # $1 = Capability Description , $2 Capability Setting (if any) + { + local setting + setting= + + [ "x$2" = "xYes" ] && setting="Available" || setting="Not available" + + echo " " $1: $setting + } + + if [ $VERBOSITY -gt 1 ]; then + echo "Shorewall6 has detected the following ip6tables/netfilter capabilities:" + report_capability "Packet Mangling" $MANGLE_ENABLED + report_capability "Multi-port Match" $MULTIPORT + [ -n "$MULTIPORT" ] && report_capability "Extended Multi-port Match" $XMULTIPORT + report_capability "Connection Tracking Match" $CONNTRACK_MATCH + if [ -n "$CONNTRACK_MATCH" ]; then + report_capability "Extended Connection Tracking Match Support" $NEW_CONNTRACK_MATCH + [ -n "$OLD_CONNTRACK_MATCH" ] && report_capability "Old Connection Tracking Match Syntax" $OLD_CONNTRACK_MATCH + fi + report_capability "Packet Type Match" $USEPKTTYPE + report_capability "Policy Match" $POLICY_MATCH + report_capability "Physdev Match" $PHYSDEV_MATCH + report_capability "Physdev-is-bridged Support" $PHYSDEV_BRIDGE + report_capability "Packet length Match" $LENGTH_MATCH + report_capability "IP range Match" $IPRANGE_MATCH + report_capability "Recent Match" $RECENT_MATCH + report_capability "Owner Match" $OWNER_MATCH + report_capability "Ipset Match" $IPSET_MATCH + report_capability "CONNMARK Target" $CONNMARK + [ -n "$CONNMARK" ] && report_capability "Extended CONNMARK Target" $XCONNMARK + report_capability "Connmark Match" $CONNMARK_MATCH + [ -n "$CONNMARK_MATCH" ] && report_capability "Extended Connmark Match" $XCONNMARK_MATCH + report_capability "Raw Table" $RAW_TABLE + report_capability "IPP2P Match" $IPP2P_MATCH + [ -n "$OLD_IPP2P_MATCH" ] && report_capability "Old IPP2P Match Syntax" $OLD_IPP2P_MATCH + report_capability "CLASSIFY Target" $CLASSIFY_TARGET + report_capability "Extended REJECT" $ENHANCED_REJECT + report_capability "Repeat match" $KLUDGEFREE + report_capability "MARK Target" $MARK + [ -n "$MARK" ] && report_capability "Extended MARK Target" $XMARK + [ -n "$XMARK" ] && report_capability "Extended MARK Target 2" $EXMARK + report_capability "Mangle FORWARD Chain" $MANGLE_FORWARD + report_capability "Comments" $COMMENTS + report_capability "Address Type Match" $ADDRTYPE + report_capability "TCPMSS Match" $TCPMSS_MATCH + report_capability "Hashlimit Match" $HASHLIMIT_MATCH + [ -n "$OLD_HL_MATCH" ] && report_capability "Old Hashlimit Match" $OLD_HL_MATCH + report_capability "NFQUEUE Target" $NFQUEUE_TARGET + report_capability "Realm Match" $REALM_MATCH + report_capability "Helper Match" $HELPER_MATCH + report_capability "Connlimit Match" $CONNLIMIT_MATCH + report_capability "Time Match" $TIME_MATCH + report_capability "Goto Support" $GOTO_TARGET + report_capability "IPMARK Target" $IPMARK_TARGET + report_capability "LOG Target" $LOG_TARGET + report_capability "TPROXY Target" $TPROXY_TARGET + report_capability "FLOW Classifier" $FLOW_FILTER + fi + + [ -n "$PKTTYPE" ] || USEPKTTYPE= + +} + +report_capabilities1() { + report_capability1() # $1 = Capability + { + eval echo $1=\$$1 + } + + echo "#" + echo "# Shorewall6 $SHOREWALL_VERSION detected the following ip6tables/netfilter capabilities - $(date)" + echo "#" + report_capability1 MANGLE_ENABLED + report_capability1 MULTIPORT + report_capability1 XMULTIPORT + report_capability1 CONNTRACK_MATCH + report_capability1 NEW_CONNTRACK_MATCH + report_capability1 OLD_CONNTRACK_MATCH + report_capability1 USEPKTTYPE + report_capability1 POLICY_MATCH + report_capability1 PHYSDEV_MATCH + report_capability1 PHYSDEV_BRIDGE + report_capability1 LENGTH_MATCH + report_capability1 IPRANGE_MATCH + report_capability1 RECENT_MATCH + report_capability1 OWNER_MATCH + report_capability1 IPSET_MATCH + report_capability1 CONNMARK + report_capability1 XCONNMARK + report_capability1 CONNMARK_MATCH + report_capability1 XCONNMARK_MATCH + report_capability1 RAW_TABLE + report_capability1 IPP2P_MATCH + report_capability1 OLD_IPP2P_MATCH + report_capability1 CLASSIFY_TARGET + report_capability1 ENHANCED_REJECT + report_capability1 KLUDGEFREE + report_capability1 MARK + report_capability1 XMARK + report_capability1 EXMARK + report_capability1 MANGLE_FORWARD + report_capability1 COMMENTS + report_capability1 ADDRTYPE + report_capability1 TCPMSS_MATCH + report_capability1 HASHLIMIT_MATCH + report_capability1 OLD_HL_MATCH + report_capability1 NFQUEUE_TARGET + report_capability1 REALM_MATCH + report_capability1 HELPER_MATCH + report_capability1 CONNLIMIT_MATCH + report_capability1 TIME_MATCH + report_capability1 GOTO_TARGET + report_capability1 IPMARK_TARGET + report_capability1 LOG_TARGET + report_capability1 TPROXY_TARGET + report_capability1 FLOW_FILTER + + echo CAPVERSION=$SHOREWALL_CAPVERSION + echo KERNELVERSION=$KERNELVERSION +} diff --git a/Shorewall6/lib.common b/Shorewall6/lib.common index ddc63c6ec..b19441e61 100644 --- a/Shorewall6/lib.common +++ b/Shorewall6/lib.common @@ -105,6 +105,251 @@ run_it() { $SHOREWALL_SHELL $script $options $@ } + +# +# Message to stderr +# +error_message() # $* = Error Message +{ + echo " $@" >&2 +} + +# +# Split a colon-separated list into a space-separated list +# +split() { + local ifs + ifs=$IFS + IFS=: + echo $* + IFS=$ifs +} + +# +# Undo the effect of 'split()' +# +join() +{ + local f + local o + o= + + for f in $* ; do + o="${o:+$o:}$f" + done + + echo $o +} + +# +# Return the number of elements in a list +# +list_count() # $* = list +{ + return $# +} + +# +# Search a list looking for a match -- returns zero if a match found +# 1 otherwise +# +list_search() # $1 = element to search for , $2-$n = list +{ + local e + e=$1 + + while [ $# -gt 1 ]; do + shift + [ "x$e" = "x$1" ] && return 0 + done + + return 1 +} + +# +# Suppress all output for a command +# +qt() +{ + "$@" >/dev/null 2>&1 +} + +# +# Determine if Shorewall is "running" +# +shorewall6_is_started() { + qt1 $IP6TABLES -L shorewall -n +} + +# +# Echos the fully-qualified name of the calling shell program +# +my_pathname() { + cd $(dirname $0) + echo $PWD/$(basename $0) +} + +# +# Source a user exit file if it exists +# +run_user_exit() # $1 = file name +{ + local user_exit + user_exit=$(find_file $1) + + if [ -f $user_exit ]; then + progress_message "Processing $user_exit ..." + . $user_exit + fi +} + +# +# Query NetFilter about the existence of a filter chain +# +chain_exists() # $1 = chain name +{ + qt1 $IP6TABLES -L $1 -n +} + +# +# Find the interface with the passed MAC address +# + +find_interface_by_mac() { + local mac + mac=$1 + local first + local second + local rest + local dev + + $IP link list | while read first second rest; do + case $first in + *:) + dev=$second + ;; + *) + if [ "$second" = $mac ]; then + echo ${dev%:} + return + fi + esac + done +} + +# +# Find interface address--returns the first IP address assigned to the passed +# device +# +find_first_interface_address() # $1 = interface +{ + # + # get the line of output containing the first IP address + # + addr=$($IP -f inet6 addr show $1 2> /dev/null | grep 'inet6 .* global' | head -n1) + # + # If there wasn't one, bail out now + # + [ -n "$addr" ] || startup_error "Can't determine the IPv6 address of $1" + # + # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) + # along with everything else on the line + # + echo $addr | sed 's/\s*inet6 //;s/\/.*//;s/ peer.*//' +} + +find_first_interface_address_if_any() # $1 = interface +{ + # + # get the line of output containing the first IP address + # + addr=$($IP -f inet6 addr show $1 2> /dev/null | grep 'inet6 2.* global' | head -n1) + # + # Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link) + # along with everything else on the line + # + [ -n "$addr" ] && echo $addr | sed 's/\s*inet6 //;s/\/.*//;s/ peer.*//' || echo :: +} + +# +# Internal version of 'which' +# +mywhich() { + local dir + + for dir in $(split $PATH); do + if [ -x $dir/$1 ]; then + echo $dir/$1 + return 0 + fi + done + + return 2 +} + +# +# Find a File -- For relative file name, look in each ${CONFIG_PATH} then ${CONFDIR} +# +find_file() +{ + local saveifs + saveifs= + local directory + + case $1 in + /*) + echo $1 + ;; + *) + for directory in $(split $CONFIG_PATH); do + if [ -f $directory/$1 ]; then + echo $directory/$1 + return + fi + done + + echo ${CONFDIR}/$1 + ;; + esac +} + +# +# Set the Shorewall state +# +set_state () # $1 = state +{ + echo "$1 ($(date))" > ${VARDIR}/state +} + +# +# Perform variable substitution on the passed argument and echo the result +# +expand() # $@ = contents of variable which may be the name of another variable +{ + eval echo \"$@\" +} + +# +# Function for including one file into another +# +INCLUDE() { + . $(find_file $(expand $@)) +} + +# Function to truncate a string -- It uses 'cut -b -' +# rather than ${v:first:last} because light-weight shells like ash and +# dash do not support that form of expansion. +# + +truncate() # $1 = length +{ + cut -b -${1} +} + +# +# Clear the current traffic shaping configuration +# + ################################################################################# # End of lib.common #################################################################################