diff --git a/New/compiler b/New/compiler deleted file mode 100755 index f351967d0..000000000 --- a/New/compiler +++ /dev/null @@ -1,106 +0,0 @@ -#!/bin/sh -# -# The Shoreline Firewall (Shorewall) Packet Filtering Firewall Compiler wrapper - V3.9 -# -# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] -# -# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007 - Tom Eastep (teastep@shorewall.net) -# -# 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 -# -# Commands are: -# -# compile check Verify the configuration files. -# compile compile Compile into -# -# Environmental Variables: -# -# EXPORT=Yes -e option specified to /sbin/shorewall -# SHOREWALL_DIR A directory name was passed to /sbin/shorewall -# VERBOSE Standard Shorewall verbosity control. -# - -# -# Fatal error -- stops the compiler after issuing the error message -# -fatal_error() # $* = Error Message -{ - echo " ERROR: $@" >&2 - [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR - [ -n "$OUTPUT" ] && rm -f $OUTPUT - kill $$ - exit 2 -} - -# -# We include this for compatibility with the 'firewall' script. That script distinguishes between -# Fatal Errors (stop or restore required) and Startup Errors (errors detected before the firewall -# state has been changed. This allows us to use common parsing routines in both programs. -# -startup_error() -{ - echo " ERROR: $@" >&2 - [ -n "$TMP_DIR" ] && rm -rf $TMP_DIR - [ -n "$OUTPUT" ] && rm -f $OUTPUT - kill $$ - exit 2 -} - -# -# Debug the compiler if first arg is "debug" -# -debug="-w" - -[ $# -gt 1 ] && [ "$1" = "debug" ] && { debug="-dw"; shift ; } - -SHAREDIR=/usr/share/shorewall -VARDIR=/var/lib/shorewall -[ -z "$EXPORT" ] && CONFDIR=/etc/shorewall || CONFDIR=${SHAREDIR}/configfiles - -[ -n "${VERBOSE:=2}" ] - -for library in lib.base lib.config; do - FUNCTIONS=${SHAREDIR}/${library} - - if [ -f $FUNCTIONS ]; then - [ $VERBOSE -ge 2 ] && echo "Loading $FUNCTIONS..." - . $FUNCTIONS - else - fatal_error "Installation Error: $FUNCTIONS does not exist!" - fi -done - -PROGRAM=compiler - -COMMAND="$1" - -case "$COMMAND" in - - check) - [ $# -ne 1 ] && usage - do_initialize - exec perl $debug /usr/share/shorewall/compiler.pl - ;; - compile) - [ $# -ne 2 ] && usage - do_initialize - exec perl $debug /usr/share/shorewall/compiler.pl $(resolve_file $2) - ;; - *) - usage - ;; - -esac diff --git a/New/lib.base b/New/lib.base deleted file mode 100644 index 1bfd02088..000000000 --- a/New/lib.base +++ /dev/null @@ -1,1421 +0,0 @@ -#!/bin/sh -# -# Shorewall 3.4 -- /usr/share/shorewall/lib.base -# -# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] -# -# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007 - Tom Eastep (teastep@shorewall.net) -# -# 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 -# -# This library contains the code common to all Shorewall components. It is copied into -# the compiled script with the -e compiler flag is specified and is loaded by -# /sbin/shorewall, /usr/share/shorewall/compiler and /usr/share/shorewall/firewall. It -# is also released as part of Shorewall Lite where it is used by /sbin/shorewall-lite -# and /usr/share/shorewall-lite/shorecap. -# - -SHOREWALL_LIBVERSION=30303 - -[ -n "${VARDIR:=/var/lib/shorewall}" ] -[ -n "${SHAREDIR:=/usr/share/shorewall}" ] -[ -n "${CONFDIR:=/etc/shorewall}" ] - -# -# Message to stderr -# -error_message() # $* = Error Message -{ - echo " $@" >&2 -} - -# -# Conditionally produce message -# -progress_message() # $* = Message -{ - local timestamp= - - if [ $VERBOSE -gt 1 ]; then - [ -n "$TIMESTAMP" ] && timestamp="$(date +%H:%M:%S) " - echo "${timestamp}$@" - fi -} - -progress_message2() # $* = Message -{ - local timestamp= - - if [ $VERBOSE -gt 0 ]; then - [ -n "$TIMESTAMP" ] && timestamp="$(date +%H:%M:%S) " - echo "${timestamp}$@" - fi -} - -progress_message3() # $* = Message -{ - local timestamp= - - if [ $VERBOSE -ge 0 ]; then - [ -n "$TIMESTAMP" ] && timestamp="$(date +%H:%M:%S) " - echo "${timestamp}$@" - fi -} - -# -# Split a colon-separated list into a space-separated list -# -split() { - local 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=$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" -# -shorewall_is_started() { - qt $IPTABLES -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=$(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=$1 - local modulefile - local suffix - - if ! list_search $modulename $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=$MODULESDIR - local directory - local moduledirectories= - local moduleloader=modprobe - - if ! qt mywhich modprobe; then - moduleloader=insmod - fi - - [ -z "$MODULESDIR" ] && MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter:/lib/modules/$(uname -r)/kernel/net/netfilter - 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=$MODULESDIR - local directory - local moduledirectories= - local moduleloader=modprobe - local savemoduleinfo=${1:-Yes} # So old compiled scripts still work - - if ! qt mywhich modprobe; then - moduleloader=insmod - fi - - [ -z "$MODULESDIR" ] && \ - MODULESDIR=/lib/modules/$(uname -r)/kernel/net/ipv4/netfilter:/lib/modules/$(uname -r)/kernel/net/netfilter - - for directory in $(split $MODULESDIR); do - [ -d $directory ] && moduledirectories="$moduledirectories $directory" - done - - 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 -# the first argument. Example "shorewall nolock refresh" -# -# This function uses the lockfile utility from procmail if it exists. -# Otherwise, it uses a somewhat race-prone algorithm to attempt to simulate the -# behavior of lockfile. -# -mutex_on() -{ - local try=0 - local lockf=${VARDIR}/lock - - MUTEX_TIMEOUT=${MUTEX_TIMEOUT:-60} - - if [ $MUTEX_TIMEOUT -gt 0 ]; then - - [ -d ${VARDIR} ] || mkdir -p ${VARDIR} - - if qt mywhich lockfile; then - lockfile -${MUTEX_TIMEOUT} -r1 ${lockf} - else - while [ -f ${lockf} -a ${try} -lt ${MUTEX_TIMEOUT} ] ; do - sleep 1 - try=$((${try} + 1)) - done - - if [ ${try} -lt ${MUTEX_TIMEOUT} ] ; then - # Create the lockfile - echo $$ > ${lockf} - else - echo "Giving up on lock file ${lockf}" >&2 - fi - fi - fi -} - -# -# Call this function to release mutual exclusion -# -mutex_off() -{ - rm -f ${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=${SHAREDIR}/lib.$1 - local loaded - - eval loaded=\$LIB_${1}_LOADED - - if [ -z "$loaded" ]; then - if [ -n "$EXPERIMENTAL" ]; then - eval LIB_${1}_LOADED=Yes - return - fi - - 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 -} - -# -# Determine if an optional library is available -# -lib_avail() # $1 = Name of the Library -{ - [ -f ${SHAREDIR}/lib.$1 ] -} - -# -# Note: The following set of IP address manipulation functions have anomalous -# behavior when the shell only supports 32-bit signed arithmatic and -# the IP address is 128.0.0.0 or 128.0.0.1. -# - -LEFTSHIFT='<<' - -# -# Validate an IP address -# -valid_address() { - local x y - local ifs=$IFS - - IFS=. - - for x in $1; do - case $x in - [0-9]|[0-9][0-9]|[1-2][0-9][0-9]) - [ $x -lt 256 ] || { IFS=$ifs; return 2; } - ;; - *) - IFS=$ifs - return 2 - ;; - esac - done - - IFS=$ifs - - return 0 -} - -# -# Convert an IP address in dot quad format to an integer -# -decodeaddr() { - local x - local temp=0 - local ifs=$IFS - - IFS=. - - for x in $1; do - temp=$(( $(( $temp $LEFTSHIFT 8 )) | $x )) - done - - echo $temp - - IFS=$ifs -} - -# -# convert an integer to dot quad format -# -encodeaddr() { - addr=$1 - local x - local y=$(($addr & 255)) - - for x in 1 2 3 ; do - addr=$(($addr >> 8)) - y=$(($addr & 255)).$y - done - - echo $y -} - -# -# Enumerate the members of an IP range -- When using a shell supporting only -# 32-bit signed arithmetic, the range cannot span 128.0.0.0. -# -# Comes in two flavors: -# -# ip_range() - produces a mimimal list of network/host addresses that spans -# the range. -# -# ip_range_explicit() - explicitly enumerates the range. -# -ip_range() { - local first last l x y z vlsm - - case $1 in - !*) - # - # Let iptables complain if it's a range - # - echo $1 - return - ;; - [0-9]*.*.*.*-*.*.*.*) - ;; - *) - echo $1 - return - ;; - esac - - first=$(decodeaddr ${1%-*}) - last=$(decodeaddr ${1#*-}) - - if [ $first -gt $last ]; then - fatal_error "Invalid IP address range: $1" - fi - - l=$(( $last + 1 )) - - while [ $first -le $last ]; do - vlsm= - x=31 - y=2 - z=1 - - while [ $(( $first % $y )) -eq 0 -a $(( $first + $y )) -le $l ]; do - vlsm=/$x - x=$(( $x - 1 )) - z=$y - y=$(( $y * 2 )) - done - - echo $(encodeaddr $first)$vlsm - first=$(($first + $z)) - done -} - -ip_range_explicit() { - local first last - - case $1 in - [0-9]*.*.*.*-*.*.*.*) - ;; - *) - echo $1 - return - ;; - esac - - first=$(decodeaddr ${1%-*}) - last=$(decodeaddr ${1#*-}) - - if [ $first -gt $last ]; then - fatal_error "Invalid IP address range: $1" - fi - - while [ $first -le $last ]; do - echo $(encodeaddr $first) - first=$(($first + 1)) - done -} - -# -# Netmask from CIDR -# -ip_netmask() { - local vlsm=${1#*/} - - [ $vlsm -eq 0 ] && echo 0 || echo $(( -1 $LEFTSHIFT $(( 32 - $vlsm )) )) -} - -# -# Network address from CIDR -# -ip_network() { - local decodedaddr=$(decodeaddr ${1%/*}) - local netmask=$(ip_netmask $1) - - echo $(encodeaddr $(($decodedaddr & $netmask))) -} - -# -# The following hack is supplied to compensate for the fact that many of -# the popular light-weight Bourne shell derivatives don't support XOR ("^"). -# -ip_broadcast() { - local x=$(( 32 - ${1#*/} )) - - [ $x -eq 32 ] && echo -1 || echo $(( $(( 1 $LEFTSHIFT $x )) - 1 )) -} - -# -# Calculate broadcast address from CIDR -# -broadcastaddress() { - local decodedaddr=$(decodeaddr ${1%/*}) - local netmask=$(ip_netmask $1) - local broadcast=$(ip_broadcast $1) - - echo $(encodeaddr $(( $(($decodedaddr & $netmask)) | $broadcast ))) -} - -# -# Test for network membership -# -in_network() # $1 = IP address, $2 = CIDR network -{ - local netmask=$(ip_netmask $2) - - test $(( $(decodeaddr $1) & $netmask)) -eq $(( $(decodeaddr ${2%/*}) & $netmask )) -} - -# -# Netmask to VLSM -# -ip_vlsm() { - local mask=$(decodeaddr $1) - local vlsm=0 - local x=$(( 128 << 24 )) # 0x80000000 - - while [ $(( $x & $mask )) -ne 0 ]; do - [ $mask -eq $x ] && mask=0 || mask=$(( $mask $LEFTSHIFT 1 )) # Not all shells shift 0x80000000 left properly. - vlsm=$(($vlsm + 1)) - done - - if [ $(( $mask & 2147483647 )) -ne 0 ]; then # 2147483647 = 0x7fffffff - echo "Invalid net mask: $1" >&2 - else - echo $vlsm - fi -} - - -# -# Chain name base for an interface -- replace all periods with underscores in the passed name. -# The result is echoed (less trailing "+"). -# -chain_base() #$1 = interface -{ - local c=${1%%+} - - while true; do - case $c in - @*) - c=at_${c#@} - ;; - *.*) - c="${c%.*}_${c##*.}" - ;; - *-*) - c="${c%-*}_${c##*-}" - ;; - *%*) - c="${c%\%*}_${c##*%}" - ;; - *@*) - c="${c%@*}_${c##*@}" - ;; - *) - echo ${c:=common} - return - ;; - esac - done -} - -# -# Query NetFilter about the existence of a filter chain -# -chain_exists() # $1 = chain name -{ - qt $IPTABLES -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 -} - -# -# Find the interfaces that have a route to the passed address - the default -# route is not used. -# - -find_rt_interface() { - ip route ls | while read addr rest; do - case $addr in - */*) - in_network ${1%/*} $addr && echo $(find_device $rest) - ;; - default) - ;; - *) - if [ "$addr" = "$1" -o "$addr/32" = "$1" ]; then - echo $(find_device $rest) - fi - ;; - esac - done -} - -# -# Try to find the gateway through an interface looking for 'nexthop' - -find_nexthop() # $1 = interface -{ - echo $(find_gateway `ip route ls | grep "[[:space:]]nexthop.* $1"`) -} - -# -# Find the default route's interface -# -find_default_interface() { - ip route ls | while read first rest; do - [ "$first" = default ] && echo $(find_device $rest) && return - done -} - -# -# Echo the name of the interface(s) that will be used to send to the -# passed address -# - -find_interface_by_address() { - local dev="$(find_rt_interface $1)" - local first rest - - [ -z "$dev" ] && dev=$(find_default_interface) - - [ -n "$dev" ] && echo $dev -} - -# -# Find the interface with the passed MAC address -# - -find_interface_by_mac() { - local mac=$1 first second rest dev - - ip link ls | 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 -# -interface_is_up() { - [ -n "$(ip link ls dev $1 | 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 inet addr show $1 2> /dev/null | grep 'inet .* global' | head -n1) - # - # If there wasn't one, bail out now - # - [ -n "$addr" ] || fatal_error "Can't determine the IP 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*inet //;s/\/.*//;s/ peer.*//' -} - -find_first_interface_address_if_any() # $1 = interface -{ - # - # get the line of output containing the first IP address - # - addr=$(ip -f inet addr show $1 2> /dev/null | grep 'inet .* 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*inet //;s/\/.*//;s/ peer.*//' || echo 0.0.0.0 -} - -# -# 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)" != 0.0.0.0 ] -} - -# -# Find interface addresses--returns the set of addresses assigned to the passed -# device -# -find_interface_addresses() # $1 = interface -{ - ip -f inet addr show $1 | grep inet\ | sed 's/\s*inet //;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 route show dev $1 2> /dev/null | - while read address rest; do - if [ "x$address" = xdefault ]; then - if [ $# -gt 1 ]; then - shift - fatal_error "$@" - else - "WARNING: default route ignored on interface $1" - fi - else - [ "$address" = "${address%/*}" ] && address="${address}/32" - echo $address - fi - 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 -# -ensure_config_path() { - local F=${SHAREDIR}/configpath - if [ -z "$CONFIG_PATH" ]; then - [ -f $F ] || { echo " ERROR: $F does not exist"; exit 2; } - . $F - fi - - if [ -n "$SHOREWALL_DIR" ]; then - [ "${CONFIG_PATH%%:*}" = "$SHOREWALL_DIR" ] || CONFIG_PATH=$SHOREWALL_DIR:$CONFIG_PATH - fi -} - -# -# Find a File -- For relative file name, look in each ${CONFIG_PATH} then ${CONFDIR} -# -find_file() -{ - local saveifs= 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 -# -resolve_file() # $1 = file name -{ - local pwd=$PWD - - case $1 in - /*) - echo $1 - ;; - .) - echo $pwd - ;; - ./*) - echo ${pwd}${1#.} - ;; - ..) - cd .. - echo $PWD - cd $pwd - ;; - ../*) - cd .. - resolve_file ${1#../} - cd $pwd - ;; - *) - echo $pwd/$1 - ;; - 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() { - qt $IPTABLES -t nat -L -n && NAT_ENABLED=Yes || NAT_ENABLED= - qt $IPTABLES -t mangle -L -n && MANGLE_ENABLED=Yes || MANGLE_ENABLED= - - CONNTRACK_MATCH= - MULTIPORT= - XMULTIPORT= - POLICY_MATCH= - PHYSDEV_MATCH= - IPRANGE_MATCH= - RECENT_MATCH= - OWNER_MATCH= - IPSET_MATCH= - CONNMARK= - XCONNMARK= - CONNMARK_MATCH= - XCONNMARK_MATCH= - RAW_TABLE= - IPP2P_MATCH= - LENGTH_MATCH= - CLASSIFY_TARGET= - ENHANCED_REJECT= - USEPKTTYPE= - KLUDGEFREE= - MARK= - XMARK= - MANGLE_FORWARD= - ADDRTYPE= - COMMENTS= - - qt $IPTABLES -N fooX1234 - qt $IPTABLES -A fooX1234 -m conntrack --ctorigdst 192.168.1.1 -j ACCEPT && CONNTRACK_MATCH=Yes - qt $IPTABLES -A fooX1234 -p tcp -m multiport --dports 21,22 -j ACCEPT && MULTIPORT=Yes - qt $IPTABLES -A fooX1234 -p tcp -m multiport --dports 21:22 -j ACCEPT && XMULTIPORT=Yes - qt $IPTABLES -A fooX1234 -m policy --pol ipsec --mode tunnel --dir in -j ACCEPT && POLICY_MATCH=Yes - - if qt $IPTABLES -A fooX1234 -m physdev --physdev-in eth0 -j ACCEPT; then - PHYSDEV_MATCH=Yes - fi - - if qt $IPTABLES -A fooX1234 -m iprange --src-range 192.168.1.5-192.168.1.124 -j ACCEPT; then - IPRANGE_MATCH=Yes - if [ -z "${KLUDGEFREE}" ]; then - qt $IPTABLES -A fooX1234 -m iprange --src-range 192.168.1.5-192.168.1.124 -m iprange --dst-range 192.168.1.5-192.168.1.124 -j ACCEPT && KLUDGEFREE=Yes - fi - fi - - qt $IPTABLES -A fooX1234 -m recent --update -j ACCEPT && RECENT_MATCH=Yes - qt $IPTABLES -A fooX1234 -m owner --uid-owner 0 -j ACCEPT && OWNER_MATCH=Yes - - if qt $IPTABLES -A fooX1234 -m connmark --mark 2 -j ACCEPT; then - CONNMARK_MATCH=Yes - qt $IPTABLES -A fooX1234 -m connmark --mark 2/0xFF -j ACCEPT && XCONNMARK_MATCH=Yes - fi - - qt $IPTABLES -A fooX1234 -p tcp -m ipp2p --ipp2p -j ACCEPT && IPP2P_MATCH=Yes - qt $IPTABLES -A fooX1234 -m length --length 10:20 -j ACCEPT && LENGTH_MATCH=Yes - qt $IPTABLES -A fooX1234 -j REJECT --reject-with icmp-host-prohibited && ENHANCED_REJECT=Yes - - qt $IPTABLES -A fooX1234 -j ACCEPT -m comment --comment "This is a comment" && COMMENTS=Yes - - if [ -n "$MANGLE_ENABLED" ]; then - qt $IPTABLES -t mangle -N fooX1234 - - if qt $IPTABLES -t mangle -A fooX1234 -j MARK --set-mark 1; then - MARK=Yes - qt $IPTABLES -t mangle -A fooX1234 -j MARK --and-mark 0xFF && XMARK=Yes - fi - - if qt $IPTABLES -t mangle -A fooX1234 -j CONNMARK --save-mark; then - CONNMARK=Yes - qt $IPTABLES -t mangle -A fooX1234 -j CONNMARK --save-mark --mask 0xFF && XCONNMARK=Yes - fi - - qt $IPTABLES -t mangle -A fooX1234 -j CLASSIFY --set-class 1:1 && CLASSIFY_TARGET=Yes - qt $IPTABLES -t mangle -F fooX1234 - qt $IPTABLES -t mangle -X fooX1234 - qt $IPTABLES -t mangle -L FORWARD -n && MANGLE_FORWARD=Yes - fi - - qt $IPTABLES -t raw -L -n && RAW_TABLE=Yes - - if qt mywhich ipset; then - qt ipset -X fooX1234 # Just in case something went wrong the last time - - if qt ipset -N fooX1234 iphash ; then - if qt $IPTABLES -A fooX1234 -m set --set fooX1234 src -j ACCEPT; then - qt $IPTABLES -D fooX1234 -m set --set fooX1234 src -j ACCEPT - IPSET_MATCH=Yes - fi - qt ipset -X fooX1234 - fi - fi - - qt $IPTABLES -A fooX1234 -m pkttype --pkt-type broadcast -j ACCEPT && USEPKTTYPE=Yes - qt $IPTABLES -A fooX1234 -m addrtype --src-type BROADCAST -j ACCEPT && ADDRTYPE=Yes - - qt $IPTABLES -F fooX1234 - qt $IPTABLES -X fooX1234 -} - -report_capabilities() { - report_capability() # $1 = Capability Description , $2 Capability Setting (if any) - { - local setting= - - [ "x$2" = "xYes" ] && setting="Available" || setting="Not available" - - echo " " $1: $setting - } - - if [ $VERBOSE -gt 1 ]; then - echo "Shorewall has detected the following iptables/netfilter capabilities:" - report_capability "NAT" $NAT_ENABLED - 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 - report_capability "Packet Type Match" $USEPKTTYPE - report_capability "Policy Match" $POLICY_MATCH - report_capability "Physdev Match" $PHYSDEV_MATCH - 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 - 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 - report_capability "Mangle FORWARD Chain" $MANGLE_FORWARD - report_capability "Comments" $COMMENTS - report_capability "Address Type Match" $ADDRTYPE - fi - - [ -n "$PKTTYPE" ] || USEPKTTYPE= - -} - -report_capabilities1() { - report_capability1() # $1 = Capability - { - eval echo $1=\$$1 - } - - echo "#" - echo "# Shorewall $VERSION detected the following iptables/netfilter capabilities - $(date)" - echo "#" - report_capability1 NAT_ENABLED - report_capability1 MANGLE_ENABLED - report_capability1 MULTIPORT - report_capability1 XMULTIPORT - report_capability1 CONNTRACK_MATCH - report_capability1 USEPKTTYPE - report_capability1 POLICY_MATCH - report_capability1 PHYSDEV_MATCH - 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 CLASSIFY_TARGET - report_capability1 ENHANCED_REJECT - report_capability1 KLUDGEFREE - report_capability1 MARK - report_capability1 XMARK - report_capability1 MANGLE_FORWARD - report_capability1 COMMENTS - report_capability1 ADDRTYPE -} - -# -# Delete IP address -# -del_ip_addr() # $1 = address, $2 = interface -{ - [ $(find_first_interface_address_if_any $2) = $1 ] || qt ip addr del $1 dev $2 -} - -# Add IP Aliases -# -add_ip_aliases() # $* = List of addresses -{ - local addresses external interface inet cidr rest val arping=$(mywhich arping) - - address_details() - { - # - # Folks feel uneasy if they don't see all of the same - # decoration on these IP addresses that they see when their - # distro's net config tool adds them. In an attempt to reduce - # the anxiety level, we have the following code which sets - # the VLSM and BRD from an existing address in the same networks - # - # Get all of the lines that contain inet addresses with broadcast - # - ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | while read inet cidr rest ; do - case $cidr in - */*) - if in_network $external $cidr; then - echo "/${cidr#*/} brd $(broadcastaddress $cidr)" - break - fi - ;; - esac - done - } - - do_one() - { - val=$(address_details) - - ip addr add ${external}${val} dev $interface $label - [ -n "$arping" ] && qt $arping -U -c 2 -I $interface $external - echo "$external $interface" >> $STATEDIR/nat - [ -n "$label" ] && label="with $label" - progress_message " IP Address $external added to interface $interface $label" - } - - progress_message "Adding IP Addresses..." - - while [ $# -gt 0 ]; do - external=$1 - interface=$2 - label= - - if [ "$interface" != "${interface%:*}" ]; then - label="${interface#*:}" - interface="${interface%:*}" - label="label $interface:$label" - fi - - shift 2 - - list_search $external $(find_interface_addresses $interface) || do_one - done -} - -detect_gateway() # $1 = interface -{ - local interface=$1 - # - # First assume that this is some sort of point-to-point interface - # - gateway=$( find_peer $(ip addr ls $interface ) ) - # - # Maybe there's a default route through this gateway already - # - [ -n "$gateway" ] || gateway=$(find_gateway $(ip route ls dev $interface)) - # - # Last hope -- is there a load-balancing route through the interface? - # - [ -n "$gateway" ] || gateway=$(find_nexthop $interface) - # - # Be sure we found one - # - [ -n "$gateway" ] && echo $gateway -} - -# -# Disable IPV6 -# -disable_ipv6() { - local foo="$(ip -f inet6 addr ls 2> /dev/null)" - - if [ -n "$foo" ]; then - if qt mywhich ip6tables; then - ip6tables -P FORWARD DROP - ip6tables -P INPUT DROP - ip6tables -P OUTPUT DROP - ip6tables -F - ip6tables -X - ip6tables -A OUTPUT -o lo -j ACCEPT - ip6tables -A INPUT -i lo -j ACCEPT - else - error_message "WARNING: DISABLE_IPV6=Yes in shorewall.conf but this system does not appear to have ip6tables" - fi - fi -} - -# -# Add a logging rule. -# -do_log_rule_limit() # $1 = log level, $2 = chain, $3 = display Chain $4 = disposition , $5 = rate limit $6=log tag $7=command $... = predicates for the rule -{ - local level=$1 - local chain=$2 - local displayChain=$3 - local disposition=$4 - local rulenum= - local limit= - local tag= - local command= - local prefix - local base=$(chain_base $displayChain) - local pf - - limit="${5:-$LOGLIMIT}" # Do this here rather than in the declaration above to appease /bin/ash. - tag=${6:+$6 } - command=${7:--A} - - shift 7 - - if [ -n "$tag" -a -n "$LOGTAGONLY" ]; then - displayChain=$tag - tag= - fi - - if [ -n "$LOGRULENUMBERS" ]; then - # - # Hack for broken printf on some lightweight shells - # - [ $(printf "%d" 1) = "1" ] && pf=printf || pf=$(mywhich printf) - - eval rulenum=\$${base}_logrules - - rulenum=${rulenum:-1} - - prefix="$($pf "$LOGFORMAT" $displayChain $rulenum $disposition)${tag}" - - rulenum=$(($rulenum + 1)) - eval ${base}_logrules=$rulenum - else - prefix="$(printf "$LOGFORMAT" $displayChain $disposition)${tag}" - fi - - if [ ${#prefix} -gt 29 ]; then - prefix="$(echo $prefix | truncate 29)" - error_message "WARNING: Log Prefix shortened to \"$prefix\"" - fi - - case $level in - ULOG) - $IPTABLES $command $chain $@ $limit -j ULOG $LOGPARMS --ulog-prefix "$prefix" - ;; - *) - $IPTABLES $command $chain $@ $limit -j LOG $LOGPARMS --log-level $level --log-prefix "$prefix" - ;; - esac - - if [ $? -ne 0 ] ; then - [ -z "$STOPPING" ] && { stop_firewall; exit 2; } - fi -} - -do_log_rule() # $1 = log level, $2 = chain, $3 = disposition , $... = predicates for the rule -{ - local level=$1 - local chain=$2 - local disposition=$3 - - shift 3 - - do_log_rule_limit $level $chain $chain $disposition "$LOGLIMIT" "" -A $@ -} - -delete_tc1() -{ - run_tcclear_exit; - - 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 -# -get_device_mtu() # $1 = device -{ - local output="$(ip link ls dev $1 2> /dev/null)" # quotes required for /bin/ash - - if [ -n "$output" ]; then - echo $(find_mtu $output) - else - echo 1500 - fi -} - -# -# Undo changes to routing -# -undo_routing() { - - if [ -z "$NOROUTES" ]; then - # - # Restore rt_tables database - # - if [ -f ${VARDIR}/rt_tables ]; then - 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 "Shorewall-generated routing tables and routing rules removed" - rm -f ${VARDIR}/undo_routing - fi - fi - -} - -restore_default_route() { - if [ -z "$NOROUTES" -a -f ${VARDIR}/default_route ]; then - local default_route= 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 route delete default metric 0 && \ - progress_message "Default Route with metric 0 deleted" - ;; - *) - qt ip 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" -# - -find_echo() { - local result - - result=$(echo "a\tb") - [ ${#result} -eq 3 ] && { echo echo; return; } - - result=$(echo -e "a\tb") - [ ${#result} -eq 3 ] && { echo "echo -e"; return; } - - result=$(which echo) - [ -n "$result" ] && { echo "$result -e"; return; } - - echo echo -} diff --git a/New/lib.config b/New/lib.config deleted file mode 100644 index 0260c0ed9..000000000 --- a/New/lib.config +++ /dev/null @@ -1,2191 +0,0 @@ -#!/bin/sh -# -# Shorewall 3.4 -- /usr/share/shorewall/lib.config -# -# This program is under GPL [http://www.gnu.org/copyleft/gpl.htm] -# -# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007 - Tom Eastep (teastep@shorewall.net) -# -# 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 -# -# This library contains the configuration file parsing code common to -# /usr/share/shorewall/compiler and /usr/share/shorewall/firewall -# - -# -# Replace commas with spaces and echo the result -# -separate_list() { - local list="$@" - local part - local newlist - local firstpart - local lastpart - local enclosure - - case "$list" in - *,|,*|*,,*|*[[:space:]]*) - # - # There's been whining about us not catching embedded white space in - # comma-separated lists. This is an attempt to snag some of the cases. - # - # The 'TERMINATOR' function will be set by the 'firewall' script to - # either 'startup_error' or 'fatal_error' depending on the command and - # command phase - # - [ -n "$TERMINATOR" ] && \ - $TERMINATOR "Invalid comma-separated list \"$@\"" - echo "WARNING -- invalid comma-separated list \"$@\"" >&2 - ;; - *\[*\]*) - # - # Where we need to embed comma-separated lists within lists, we enclose them - # within square brackets. - # - firstpart=${list%%\[*} - lastpart=${list#*\[} - enclosure=${lastpart%%\]*} - lastpart=${lastpart#*\]} - case $lastpart in - \,*) - case $firstpart in - *\,) - echo "$(separate_list ${firstpart%,}) [$enclosure] $(separate_list ${lastpart#,})" - ;; - *) - echo "$(separate_list $firstpart)[$enclosure] $(separate_list ${lastpart#,})" - ;; - esac - ;; - *) - case $firstpart in - *\,) - echo "$(separate_list ${firstpart%,}) [$enclosure]$(separate_list $lastpart)" - ;; - *) - echo "$(separate_list $firstpart)[$enclosure]$(separate_list $lastpart)" - ;; - esac - ;; - esac - return - ;; - esac - - list="$@" - part="${list%%,*}" - newlist="$part" - - while [ "x$part" != "x$list" ]; do - list="${list#*,}"; - part="${list%%,*}"; - newlist="$newlist $part"; - done - - echo "$newlist" -} - -# -# Undo the effect of 'separate_list()' -# -combine_list() -{ - local f o= - - for f in $* ; do - o="${o:+$o,}$f" - done - - echo $o -} - -# -# Display elements of a list with leading white space -# -display_list() # $1 = List Title, rest of $* = list to display -{ - [ $# -gt 1 ] && echo " $*" -} - -# -# Determine if a chain is a policy chain -# -is_policy_chain() # $1 = name of chain -{ - eval test \"\$${1}_is_policy\" = Yes -} - -# 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} -} - -# -# Return a space separated list of values matching -# -list_walk() # $1 = element to search for, $2-$n = list -{ - local e=$1 result= - - while [ $# -gt 1 ]; do - shift - case $1 in - $e*) - result="$result ${1##$e}" - ;; - esac - done - echo $result -} - -# -# Functions to count list elements -# - - - - - - - - - - - - - - - - -# Whitespace-separated list -# -list_count1() { - echo $# -} -# -# Comma-separated list -# -list_count() { - list_count1 $(separate_list $1) -} - -# -# Filter that expands variables -# -expand_line() { - local line - - while read line; do - echo $(expand $line) - done -} - -# -# Add whitespace after leading "!" -# -fix_bang() -{ - local result= - - while [ $# -gt 0 ]; do - case $1 in - !*) - result="$result ! ${1#!}" - ;; - *) - result="$result $1" - ;; - esac - shift - done - - echo $result -} - -# -# Read the zones file and find the firewall zone -# -get_firewall_zone() { - local zone type rest comment='#*' f=$(find_file zones) - - [ -f $f ] || startup_error "Unable to find zones file" - - while read zone type rest; do - case $zone in - $comment) - ;; - *) - if [ "x$type" = xfirewall ]; then - FW=$zone - return - fi - ;; - esac - done < $f - - startup_error "No firewall zone defined in $f" -} - -# -# This function assumes that the TMP_DIR variable is set and that -# its value names an existing directory. -# -determine_zones() -{ - local zone parent parents rest new_zone_file= r - - merge_zone() - { - local z zones="$ZONES" merged= - - if [ -n "$parents" ]; then - ZONES= - for z in $zones; do - if [ -z "$merged" ] && list_search $z $parents; then - ZONES="$ZONES $zone" - merged=Yes - fi - ZONES="$ZONES $z" - done - else - ZONES="$ZONES $zone" - fi - } - - ZONES= - IPV4_ZONES= - IPSEC_ZONES= - - [ "$IPSECFILE" = zones ] && new_zone_file=Yes || test -n "${FW:=fw}" - - while read zone type rest; do - case $zone in - *:*) - parents=${zone#*:} - zone=${zone%:*} - [ -n "$zone" ] || startup_error "Invalid nested zone syntax: :$parents" - parents=$(separate_list $parents) - eval ${zone}_parents=\"$parents\" - ;; - *) - parents= - eval ${zone}_parents= - ;; - esac - - for parent in $parents; do - [ "$parent" = "$FW" ] && startup_error "Sub-zones of the firewall zone are not allowed" - list_search $parent $ZONES || startup_error "Parent zone not defined: $parent" - done - - [ ${#zone} -gt $MAXZONENAMELENGTH ] && startup_error "Zone name longer than $MAXZONENAMELENGTH characters: $zone" - - case "$zone" in - [0-9*]) - startup_error "Illegal zone name \"$zone\" in zones file" - ;; - all|none) - startup_error "Reserved zone name \"$zone\" in zones file" - ;; - esac - - if [ -n "$new_zone_file" ]; then - case ${type:=ipv4} in - ipv4|IPv4|IPV4|plain|-) - list_search $zone $ZONES $FW && startup_error "Zone $zone is defined more than once" - merge_zone - IPV4_ZONES="$IPV4_ZONES $zone" - ;; - ipsec|IPSEC|ipsec4|IPSEC4) - list_search $zone $ZONES $FW && startup_error "Zone $zone is defined more than once" - [ -n "$POLICY_MATCH" ] || startup_error "Your kernel and/or iptables does not support policy match" - eval ${zone}_is_ipsec=Yes - eval ${zone}_is_complex=Yes - merge_zone - IPSEC_ZONES="$IPSEC_ZONES $zone" - ;; - firewall) - [ -n "$FW" ] && startup_error "Only one firewall zone may be defined" - list_search $zone $ZONES && startup_error "Zone $zone is defined more than once" - [ -n "$parents" ] && startup_error "The firewall zone may not be nested" - for r in $rest; do - [ "x$r" = x- ] || startup_error "OPTIONS not allowed on the firewall zone" - done - FW=$zone - ;; - *) - startup_error "Invalid Zone Type: $type" - ;; - esac - - eval ${zone}_type=$type - else - list_search $zone $ZONES $FW && startup_error "Zone $zone is defined more than once" - ZONES="$ZONES $zone" - IPV4_ZONES="$IPV4_ZONES $zone" - eval ${zone}_type=ipv4 - fi - done < $TMP_DIR/zones - - [ -z "$ZONES" ] && startup_error "No ipv4 or ipsec Zones Defined" - - [ -z "$FW" ] && startup_error "No Firewall Zone Defined" -} - -# -# Validate the zone names and options in the interfaces file -# -validate_interfaces_file() { - local wildcard - local found_obsolete_option= - local z interface networks options r iface option - - while read z interface networks options; do - r="$z $interface $networks $options" - - [ "x$z" = "x-" ] && z= - - if [ -n "$z" ]; then - validate_zone $z || startup_error "Invalid zone ($z) in record \"$r\"" - fi - - list_search $interface $ALL_INTERFACES && \ - startup_error "Duplicate Interface $interface" - - wildcard= - - case $interface in - *:*|+) - startup_error "Invalid Interface Name: $interface" - ;; - *+) - wildcard=Yes - ;; - esac - - ALL_INTERFACES="$ALL_INTERFACES $interface" - options=$(separate_list $options) - iface=$(chain_base $interface) - - eval ${iface}_broadcast="$networks" - eval ${iface}_zone="$z" - eval ${iface}_options=\"$options\" - - for option in $options; do - case $option in - -) - ;; - dhcp|tcpflags|arp_filter|routefilter|logmartians|sourceroute|blacklist|nosmurfs|upnp|-) - ;; - proxyarp) - lib_load proxyarp "The 'proxyarp' option on interface $interface" - ;; - maclist) - lib_load maclist "The 'maclist' option" - ;; - norfc1918) - if [ "$PROGRAM" != compiler ]; then - addr=$(ip -f inet addr show $interface 2> /dev/null | grep inet | head -n1) - if [ -n "$addr" ]; then - addr=$(echo $addr | sed 's/inet //;s/\/.*//;s/ peer.*//') - for network in 10.0.0.0/8 176.16.0.0/12 192.168.0.0/16; do - if in_network $addr $network; then - startup_error "The 'norfc1918' option may not be specified on an interface with an RFC 1918 address. Interface:$interface" - fi - done - fi - fi - ;; - arp_ignore=*) - eval ${iface}_arp_ignore=${option#*=} - ;; - arp_ignore) - eval ${iface}_arp_ignore=1 - ;; - detectnets) - [ -n "$wildcard" ] && \ - startup_error "The \"detectnets\" option may not be used with a wild-card interface" - [ -n "$EXPORT" ] && \ - startup_error "'detectnets' not permitted with the -e run-line option" - ;; - routeback) - [ -n "$z" ] || startup_error "The routeback option may not be specified on a multi-zone interface" - ;; - *) - error_message "WARNING: Invalid option ($option) in record \"$r\"" - ;; - esac - done - done < $TMP_DIR/interfaces - - [ -z "$ALL_INTERFACES" ] && startup_error "No Interfaces Defined" -} - -# -# Process the ipsec information in the zones file -# -setup_ipsec() { - local zone using_ipsec= - # - # Add a --set-mss rule to the passed chain - # - set_mss1() # $1 = chain, $2 = MSS - { - eval local policy=\$${1}_policy - - if [ "$policy" != NONE ]; then - ensurechain $1 - run_iptables -I $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss $2 - fi - } - # - # Set up rules to set MSS to and/or from zone "$zone" - # - set_mss() # $1 = MSS value, $2 = _in, _out or "" - { - for z in $ZONES $FW; do - case $2 in - _in) - set_mss1 ${zone}2${z} $1 - ;; - _out) - set_mss1 ${z}2${zone} $1 - ;; - *) - set_mss1 ${z}2${zone} $1 - set_mss1 ${zone}2${z} $1 - ;; - esac - done - } - - do_options() # $1 = _in, _out or "" - $2 = option list - { - local option newoptions= val - - [ x${2} = x- ] && return - - for option in $(separate_list $2); do - val=${option#*=} - - case $option in - mss=[0-9]*) [ "$PROGRAM" = compiler ] && set_mss $val $1 ;; - strict) newoptions="$newoptions --strict" ;; - next) newoptions="$newoptions --next" ;; - reqid=*) newoptions="$newoptions --reqid $val" ;; - spi=*) newoptions="$newoptions --spi $val" ;; - proto=*) newoptions="$newoptions --proto $val" ;; - mode=*) newoptions="$newoptions --mode $val" ;; - tunnel-src=*) newoptions="$newoptions --tunnel-src $val" ;; - tunnel-dst=*) newoptions="$newoptions --tunnel-dst $val" ;; - reqid!=*) newoptions="$newoptions ! --reqid $val" ;; - spi!=*) newoptions="$newoptions ! --spi $val" ;; - proto!=*) newoptions="$newoptions ! --proto $val" ;; - mode!=*) newoptions="$newoptions ! --mode $val" ;; - tunnel-src!=*) newoptions="$newoptions ! --tunnel-src $val" ;; - tunnel-dst!=*) newoptions="$newoptions ! --tunnel-dst $val" ;; - *) fatal_error "Invalid option \"$option\" for zone $zone" ;; - esac - done - - if [ -n "$newoptions" ]; then - [ -n "$POLICY_MATCH" ] || fatal_error "Your kernel and/or iptables does not support policy match" - eval ${zone}_is_complex=Yes - eval ${zone}_ipsec${1}_options=\"${newoptions# }\" - fi - } - - case $IPSECFILE in - zones) - f=zones - progress_message "$DOING IPSEC..." - [ $PROGRAM = compiler -a -n "$IPSEC_ZONES" ] && save_progress_message "Setting up IPSEC management..." - ;; - ipsec) - using_ipsec=Yes - if [ -s ${TMP_DIR}/ipsec ]; then - progress_message "$DOING ipsec..." - [ $PROGRAM = compiler ] && save_progress_message "Setting up IPSEC management..." - fi - ;; - esac - - while read zone type options in_options out_options mss; do - if [ -n "$using_ipsec" ]; then - validate_zone1 $zone || fatal_error "Unknown zone: $zone" - fi - - if [ -n "$type" ]; then - if [ -n "$using_ipsec" ]; then - case $type in - No|no) - ;; - Yes|yes) - [ -n "$POLICY_MATCH" ] || fatal_error "Your kernel and/or iptables does not support policy match" - eval ${zone}_is_ipsec=Yes - eval ${zone}_is_complex=Yes - eval ${zone}_type=ipsec4 - ;; - *) - fatal_error "Invalid IPSEC column contents" - ;; - esac - fi - - do_options "" $options - do_options "_in" $in_options - do_options "_out" $out_options - fi - - done < $TMP_DIR/$f -} - -# -# Validate the zone names and options in the hosts file -# -validate_hosts_file() { - local z hosts options r interface host option zports ipsec= - - check_bridge_port() - { - list_search ${interface}:${1} $zports || zports="$zports ${interface}:${1}" - list_search $1 $ALL_PORTS || ALL_PORTS="$ALL_PORTS $1" - } - - while read z hosts options; do - r="$z $hosts $options" - validate_zone1 $z || startup_error "Invalid zone ($z) in record \"$r\"" - - case $hosts in - *:*) - - interface=${hosts%%:*} - iface=$(chain_base $interface) - - list_search $interface $ALL_INTERFACES || \ - startup_error "Unknown interface ($interface) in record \"$r\"" - - hosts=${hosts#*:} - ;; - *) - startup_error "Invalid HOST(S) column contents: $hosts" - ;; - esac - - eval zports=\$${z}_ports - - if [ -z "$BRIDGING" ]; then - case $hosts in - *!*!*) - startup_error "Invalid hosts file entry: \"$r\"" - ;; - !*) - hosts=0.0.0.0/0 - eval ${z}_is_complex=Yes - ;; - *!*) - hosts=${hosts%%!*} - eval ${z}_is_complex=Yes - ;; - esac - fi - - for host in $(separate_list $hosts); do - if [ -n "$BRIDGING" ]; then - case $host in - *:*) - known_interface ${host%:*} && \ - startup_error "Bridged interfaces may not be defined in ${CONFDIR}/interfaces: $host" - check_bridge_port ${host%%:*} - ;; - *.*.*) - ;; - *+|+*|*!*) - eval ${z}_is_complex=Yes - ;; - *) - known_interface $host && \ - startup_error "Bridged interfaces may not be defined in ${CONFDIR}/interfaces: $host" - check_bridge_port $host - ;; - esac - else - case $host in - *.*.*) - ;; - +*) - eval ${z}_is_complex=Yes - ;; - *) - startup_error "BRIDGING=Yes is needed for this zone definition: $r" - ;; - esac - fi - - for option in $(separate_list $options) ; do - case $option in - norfc1918|blacklist|tcpflags|nosmurfs|-) - ;; - maclist) - lib_load maclist "The 'maclist' option" - ;; - ipsec) - [ -n "$POLICY_MATCH" ] || \ - startup_error "Your kernel and/or iptables does not support policy match: ipsec" - eval ${z}_ipsec_hosts=\"\$${z}_ipsec_hosts $interface:$host\" - eval ${z}_is_complex=Yes - ipsec=Yes - ;; - routeback) - eval ${z}_routeback=\"$interface:$host \$${z}_routeback\" - ;; - *) - error_message "WARNING: Invalid option ($option) in record \"$r\"" - ;; - esac - done - done - - [ -n "$zports" ] && eval ${z}_ports=\"$zports\" - - done < $TMP_DIR/hosts - - [ -n "$ALL_PORTS" ] && progress_message2 " Bridge ports are: $ALL_PORTS" - - [ -n "${IPSEC_ZONES}${ipsec}" ] || POLICY_MATCH= -} - -# -# Find interfaces to a given zone -# -# Search the variables representing the contents of the interfaces file and -# for each record matching the passed ZONE, echo the expanded contents of -# the "INTERFACE" column -# -find_interfaces() # $1 = interface zone -{ - local zne=$1 - local z - local interface - - for interface in $ALL_INTERFACES; do - eval z=\$$(chain_base $interface)_zone - [ "x${z}" = x${zne} ] && echo $interface - done -} - -# -# Forward Chain for an interface -# -forward_chain() # $1 = interface -{ - echo $(chain_base $1)_fwd -} - -# -# Input Chain for an interface -# -input_chain() # $1 = interface -{ - echo $(chain_base $1)_in -} - -# -# Output Chain for an interface -# -output_chain() # $1 = interface -{ - echo $(chain_base $1)_out -} - -# -# Masquerade Chain for an interface -# -masq_chain() # $1 = interface -{ - echo $(chain_base $1)_masq -} - -# -# MAC Verification Chain for an interface -# -mac_chain() # $1 = interface -{ - echo $(chain_base $1)_mac -} - -macrecent_target() # $1 - interface -{ - [ -n "$MACLIST_TTL" ] && echo $(chain_base $1)_rec || echo RETURN -} - -# -# Functions for creating dynamic zone rules -# -dynamic_fwd() # $1 = interface -{ - echo $(chain_base $1)_dynf -} - -dynamic_in() # $1 = interface -{ - echo $(chain_base $1)_dyni -} - -dynamic_out() # $1 = interface -{ - echo $(chain_base $1)_dyno -} - -dynamic_chains() #$1 = interface -{ - local c=$(chain_base $1) - - echo ${c}_dyni ${c}_dynf ${c}_dyno -} - -# -# DNAT Chain from a zone -# -dnat_chain() # $1 = zone -{ - echo ${1}_dnat -} - -# -# SNAT Chain to an interface -# -snat_chain() # $1 = interface -{ - echo $(chain_base $1)_snat -} - -# -# ECN Chain to an interface -# -ecn_chain() # $1 = interface -{ - echo $(chain_base $1)_ecn -} - -# -# First chains for an interface -# -first_chains() #$1 = interface -{ - local c=$(chain_base $1) - - echo ${c}_fwd ${c}_in -} - -# -# Out Chain to an interface -# -out_chain() # $1 = interface -{ - echo $(chain_base $1)_out -} - -# -# Horrible hack to work around an iptables limitation -# -iprange_echo() -{ - if [ -n "$KLUDGEFREE" ]; then - echo "-m iprange $@" - elif [ -f $TMP_DIR/iprange ]; then - echo $@ - else - echo "-m iprange $@" - > $TMP_DIR/iprange - fi -} - -# -# Get set flags (ipsets). -# -get_set_flags() # $1 = set name and optional [levels], $2 = src or dst -{ - local temp setname=$1 options=$2 - - [ -n "$IPSET_MATCH" ] || fatal_error "Your kernel and/or iptables does not include ipset match: $1" - - case $1 in - *\[[1-6]\]) - temp=${1#*\[} - temp=${temp%\]} - setname=${1%\[*} - while [ $temp -gt 1 ]; do - options="$options,$2" - temp=$(($temp - 1)) - done - ;; - *\[*\]) - options=${1#*\[} - options=${options%\]} - setname=${1%\[*} - ;; - *) - ;; - esac - - echo "--set ${setname#+} $options" -} - -# -# Horrible hack to work around an iptables limitation -# -physdev_echo() -{ - if [ -n "$KLUDGEFREE" ]; then - echo -m physdev $@ - elif [ -f $TMP_DIR/physdev ]; then - echo $@ - else - echo -m physdev $@ - > $TMP_DIR/physdev - fi -} - -# -# Source IP range -# -source_ip_range() # $1 = Address or Address Range -{ - [ $# -gt 0 ] && case $1 in - *.*.*.*-*.*.*.*) - case $1 in - !*) - iprange_echo "! --src-range ${1#!}" - ;; - *) - iprange_echo "--src-range $1" - ;; - esac - ;; - !+*) - echo "-m set ! $(get_set_flags ${1#!} src)" - ;; - +*) - echo "-m set $(get_set_flags $1 src)" - ;; - *) - echo "-s $1" - ;; - esac -} - -# -# Destination IP range -# -dest_ip_range() # $1 = Address or Address Range -{ - [ $# -gt 0 ] && case $1 in - *.*.*.*-*.*.*.*) - case $1 in - !*) - iprange_echo "! --dst-range ${1#!}" - ;; - *) - iprange_echo "--dst-range $1" - ;; - esac - ;; - !+*) - echo "-m set ! $(get_set_flags ${1#!} dst)" - ;; - +*) - echo "-m set $(get_set_flags $1 dst)" - ;; - *) - echo "-d $1" - ;; - esac -} - -both_ip_ranges() # $1 = Source address or range, $2 = dest address or range -{ - local rangeprefix= setprefix= rangematch= setmatch= - - case $1 in - *.*.*.*-*.*.*.*) - rangeprefix="-m iprange" - rangematch="--src-range $1" - ;; - !+*) - setprefix="-m set" - setmatch="! $(get_set_flags ${1#!} src)" - ;; - +*) - setprefix="-m set" - setmatch="$(get_set_flags $1 src)" - ;; - *) - rangematch="-s $1" - ;; - esac - - case $2 in - *.*.*.*-*.*.*.*) - rangeprefix="-m iprange" - rangematch="$rangematch --dst-range $2" - ;; - !+*) - setprefix="-m set" - match="$setmatch ! $(get_set_flags ${2#!} dst)" - ;; - +*) - setprefix="-m set" - setmatch="$setmatch $(get_set_flags $2 dst)" - ;; - *) - rangematch="$rangematch -d $2" - ;; - esac - - echo "$rangeprefix $rangematch $setprefix $setmatch" -} - -# -# Loosly Match the name of an interface -# - -if_match() # $1 = Name in interfaces file - may end in "+" - # $2 = Full interface name - may also end in "+" -{ - local pattern=${1%+} - - case $1 in - *+) - test "x$(echo $2 | truncate ${#pattern} )" = "x${pattern}" - ;; - *) - test "x$1" = "x$2" - ;; - esac -} - -# -# We allow hosts to be specified by IP address or by physdev. These two functions -# are used to produce the proper match in a netfilter rule. -# -match_source_hosts() -{ - if [ -n "$BRIDGING" ]; then - case $1 in - *:*) - physdev_echo "--physdev-in ${1%:*} $(source_ip_range ${1#*:})" - ;; - *.*.*.*|+*|!+*) - echo $(source_ip_range $1) - ;; - *) - physdev_echo "--physdev-in $1" - ;; - esac - else - echo $(source_ip_range $1) - fi -} - -match_dest_hosts() -{ - if [ -n "$BRIDGING" ]; then - case $1 in - *:*) - physdev_echo "--physdev-out ${1%:*} $(dest_ip_range ${1#*:})" - ;; - *.*.*.*|+*|!+*) - echo $(dest_ip_range $1) - ;; - *) - physdev_echo "--physdev-out $1" - ;; - esac - else - echo $(dest_ip_range $1) - fi -} -# -# Matches for either or :
-# -match_source() -{ - case "$1" in - *:*) - echo "-i ${1%%:*} $(match_source_hosts ${1#*:})" - ;; - *) - echo $(dest_ip_range $1) - ;; - esac -} - -match_dest() -{ - case "$1" in - *:*) - echo "-o ${1%%:*} $(match_dest_hosts ${1#*:})" - ;; - *) - echo $(dest_ip_range $1) - ;; - esac -} - -# -# Similarly, the source or destination in a rule can be qualified by a device name. If -# the device is defined in ${CONFDIR}/interfaces then a normal interface match is -# generated (-i or -o); otherwise, a physdev match is generated. -#------------------------------------------------------------------------------------- -# -# loosely match the passed interface with those in ${CONFDIR}/interfaces. -# -known_interface() # $1 = interface name -{ - local iface - - for iface in $ALL_INTERFACES ; do - if if_match $iface $1 ; then - return 0 - fi - done - - return 1 -} - -known_port() # $1 = port name -{ - local port - - for port in $ALL_PORTS ; do - if if_match $port $1 ; then - return 0 - fi - done - - return 1 -} - -match_source_dev() -{ - if [ -n "$BRIDGING" ]; then - known_port $1 && physdev_echo "--physdev-in $1" || echo -i $1 - elif known_interface $1; then - echo -i $1 - elif [ -n "$PHYSDEV_MATCH" ]; then - physdev_echo "--physdev-in $1" - else - echo -i $1 - fi -} - -match_dest_dev() -{ - if [ -n "$BRIDGING" ]; then - known_port $1 && physdev_echo "--physdev-out $1" || echo -o $1 - elif known_interface $1; then - echo -o $1 - elif [ -n "$PHYSDEV_MATCH" ]; then - physdev_echo "--physdev-out $1" - else - echo -o $1 - fi -} - -verify_interface() -{ - known_interface $1 || { [ -n "$BRIDGING" ] && known_port $1 ; } -} - -# -# Determine if communication to/from a host is encrypted using IPSEC -# -is_ipsec_host() # $1 = zone, $2 = host -{ - eval local is_ipsec=\$${1}_is_ipsec - eval local hosts=\"\$${1}_ipsec_hosts\" - - test -n "$is_ipsec" || list_search $2 $hosts -} - -# -# Generate a match for decrypted packets -# -match_ipsec_in() # $1 = zone, $2 = host -{ - if is_ipsec_host $1 $2 ; then - eval local options=\"\$${1}_ipsec_options \$${1}_ipsec_in_options\" - echo "-m policy --pol ipsec --dir in $options" - elif [ -n "$POLICY_MATCH" ]; then - echo "-m policy --pol none --dir in" - fi -} - -# -# Generate a match for packets that will be encrypted -# -match_ipsec_out() # $1 = zone, $2 = host -{ - if is_ipsec_host $1 $2 ; then - eval local options=\"\$${1}_ipsec_options \$${1}_ipsec_out_options\" - echo "-m policy --pol ipsec --dir out $options" - elif [ -n "$POLICY_MATCH" ]; then - echo "-m policy --pol none --dir out" - fi -} - -# -# Jacket for ip_range() that takes care of iprange match -# - -firewall_ip_range() # $1 = IP address or range -{ - [ -n "$IPRANGE_MATCH" ] && echo $1 || ip_range $1 -} - -# -# -# Find hosts in a given zone -# -# Read hosts file and for each record matching the passed ZONE, -# echo the expanded contents of the "HOST(S)" column -# -find_hosts() # $1 = host zone -{ - local hosts interface address addresses - - while read z hosts options; do - if [ "x$(expand $z)" = "x$1" ]; then - interface=${hosts%%:*} - addresses=${hosts#*:} - case $addresses in - !*) - echo $interface:0.0.0.0/0 - ;; - *) - for address in $(separate_list ${addresses%%!*}); do - echo $interface:$address - done - ;; - esac - fi - done < $TMP_DIR/hosts -} - -# -# -# Find exclusions in a given zone -# -# Read hosts file and for each record matching the passed ZONE, -# echo any exclusions -# -find_exclusions() # $1 = host zone -{ - local hosts interface address addresses - - while read z hosts options; do - if [ "x$z" = "x$1" ]; then - interface=${hosts%%:*} - addresses=${hosts#*:} - case $addresses in - *!*) - for address in $(separate_list ${addresses#*!}); do - echo $interface:$address - done - ;; - esac - fi - done < $TMP_DIR/hosts -} - -# -# Determine the interfaces on the firewall -# -# For each zone, create a variable called ${zone}_interfaces. This -# variable contains a space-separated list of interfaces to the zone -# -determine_interfaces() { - for zone in $ZONES; do - interfaces=$(find_interfaces $zone) - interfaces=$(echo $interfaces) # Remove extra trash - eval ${zone}_interfaces=\"\$interfaces\" - done -} - -# -# Determine if an interface has a given option -# -interface_has_option() # $1 = interface, #2 = option -{ - local options - - eval options=\$$(chain_base $1)_options - - list_search $2 $options -} - -# -# Determine the defined hosts in each zone -# -determine_hosts() { - for zone in $ZONES; do - hosts=$(find_hosts $zone) - hosts=$(echo $hosts) # Remove extra trash - exclusions=$(find_exclusions $zone) - exclusions=$(echo $exclusions) # Remove extra trash - - eval interfaces=\$${zone}_interfaces - - for interface in $interfaces; do - if interface_has_option $interface detectnets; then - networks=$(get_routed_networks $interface "detectnets not allowed on interface with default route - $interface" ) - else - networks=0.0.0.0/0 - fi - - for network in $networks; do - if [ -z "$hosts" ]; then - hosts=$interface:$network - else - hosts="$hosts $interface:$network" - fi - - if interface_has_option $interface routeback; then - eval ${zone}_routeback=\"$interface:$network \$${zone}_routeback\" - fi - done - done - - interfaces= - - for host in $hosts; do - interface=${host%:*} - if list_search $interface $interfaces; then - list_search $interface:0.0.0.0/0 $hosts && \ - startup_error "Invalid zone definition for zone $zone" - list_search $interface:0/0 $hosts && \ - startup_error "Invalid zone definition for zone $zone" - eval ${zone}_is_complex=Yes - else - if [ -z "$interfaces" ]; then - interfaces=$interface - else - interfaces="$interfaces $interface" - fi - fi - done - - eval ${zone}_exclusions="\$exclusions" - eval ${zone}_interfaces="\$interfaces" - eval ${zone}_hosts="\$hosts" - - if [ -n "$hosts" ]; then - if [ $VERBOSE -ge 1 ]; then - [ -n "$exclusions" ] && display_list "$zone Zone:" $hosts minus "($exclusions)" || display_list "$zone Zone:" $hosts - fi - else - error_message "WARNING: Zone $zone is empty" - fi - done -} - -# -# Ensure that the passed zone is defined in the zones file or is the firewall -# -validate_zone() # $1 = zone -{ - list_search $1 $ZONES $FW -} -# -# Ensure that the passed zone is defined in the zones file. -# -validate_zone1() # $1 = zone -{ - list_search $1 $ZONES -} - -# -# Format a match by the passed MAC address -# The passed address begins with "~" and uses "-" as a separator between bytes -# Example: ~01-02-03-04-05-06 -# -mac_match() # $1 = MAC address formated as described above -{ - echo "--match mac --mac-source $(echo $1 | sed 's/~//;s/-/:/g')" -} - -# -# Find interfaces that have the passed option specified -# -find_interfaces_by_option() # $1 = option -{ - for interface in $ALL_INTERFACES; do - eval options=\$$(chain_base $interface)_options - list_search $1 $options && echo $interface - done -} - -# -# This slightly slower version is used to find both the option and option followed -# by equal sign ("=") and a value -# -find_interfaces_by_option1() # $1 = option -{ - local options option - - for interface in $ALL_INTERFACES; do - eval options=\$$(chain_base $interface)_options - for option in $options; do - if [ "${option%=*}" = "$1" ]; then - echo $interface - break - fi - done - done -} - -# -# Find hosts with the passed option -# -find_hosts_by_option() # $1 = option -{ - local ignore hosts interface address addresses options ipsec= list - - while read ignore hosts options; do - list=$(separate_list $options) - if list_search $1 $list; then - list_search ipsec $list && ipsec=ipsec || ipsec=none - interface=${hosts%%:*} - addresses=${hosts#*:} - for address in $(separate_list $addresses); do - echo ${ipsec}^$interface:$address - done - fi - done < $TMP_DIR/hosts - - for interface in $ALL_INTERFACES; do - interface_has_option $interface $1 && \ - echo none^${interface}:0.0.0.0/0 - done -} - -# -# Process the routestopped file either adding or deleting rules -# -process_routestopped() # $1 = command -{ - local hosts= interface host host1 options networks source= dest= matched - - while read interface host options; do - [ "x$host" = "x-" -o -z "$host" ] && host=0.0.0.0/0 - for h in $(separate_list $host); do - hosts="$hosts $interface:$h" - done - - routeback= - - if [ -n "$options" ]; then - for option in $(separate_list $options); do - case $option in - routeback) - if [ -n "$routeback" ]; then - error_message "WARNING: Duplicate routestopped option ignored: routeback" - else - routeback=Yes - for h in $(separate_list $host); do - run_iptables $1 FORWARD -i $interface -o $interface $(both_ip_ranges $h $h) -j ACCEPT - done - fi - ;; - source) - for h in $(separate_list $host); do - source="$source $interface:$h" - done - ;; - dest) - for h in $(separate_list $host); do - dest="$dest $interface:$h" - done - ;; - critical) - ;; - *) - error_message "WARNING: Unknown routestopped option ignored: $option" - ;; - esac - done - fi - - done < $TMP_DIR/routestopped - - - for host in $hosts; do - interface=${host%:*} - networks=${host#*:} - source_range=$(source_ip_range $networks) - dest_range=$(dest_ip_range $networks) - run_iptables $1 INPUT -i $interface $source_range -j ACCEPT - [ -z "$ADMINISABSENTMINDED" ] && \ - run_iptables $1 OUTPUT -o $interface $dest_range -j ACCEPT - - matched= - - if list_search $host $source ; then - run_iptables $1 FORWARD -i $interface $source_range -j ACCEPT - matched=Yes - fi - - if list_search $host $dest ; then - run_iptables $1 FORWARD -o $interface $dest_range -j ACCEPT - matched=Yes - fi - - if [ -z "$matched" ]; then - for host1 in $hosts; do - [ "$host" != "$host1" ] && run_iptables $1 FORWARD -i $interface -o ${host1%:*} $(both_ip_ranges $networks ${host1#*:}) -j ACCEPT - done - fi - done -} - -process_criticalhosts() -{ - local hosts= interface host h options networks criticalhosts= - - while read interface host options; do - [ "x$host" = "x-" -o -z "$host" ] && host=0.0.0.0/0 || host=$(separate_list $host) - - if [ -n "$options" ]; then - for option in $(separate_list $options); do - case $option in - routeback|source|dest) - ;; - critical) - for h in $host; do - criticalhosts="$criticalhosts $interface:$h" - done - ;; - *) - error_message "WARNING: Unknown routestopped option ignored: $option" - ;; - esac - done - fi - done < $TMP_DIR/routestopped - - if [ -n "$criticalhosts" ]; then - CRITICALHOSTS=$criticalhosts - progress_message "Critical Hosts are:$CRITICALHOSTS" - fi - -} - -# -# Determine which version of mktemp is present (if any) and set MKTEMP accortingly: -# -# None - No mktemp -# BSD - BSD mktemp (Mandrake) -# STD - mktemp.org mktemp -# -find_mktemp() { - local mktemp=`mywhich mktemp 2> /dev/null` - - if [ -n "$mktemp" ]; then - if qt mktemp -V ; then - MKTEMP=STD - else - MKTEMP=BSD - fi - else - MKTEMP=None - fi -} - -# -# create a temporary file. If a directory name is passed, the file will be created in -# that directory. Otherwise, it will be created in a temporary directory. -# -mktempfile() { - - [ -z "$MKTEMP" ] && find_mktemp - - if [ $# -gt 0 ]; then - case "$MKTEMP" in - BSD) - mktemp $1/shorewall.XXXXXX - ;; - STD) - mktemp -p $1 shorewall.XXXXXX - ;; - None) - > $1/shorewall-$$ && echo $1/shorewall-$$ - ;; - *) - error_message "ERROR:Internal error in mktempfile" - ;; - esac - else - case "$MKTEMP" in - BSD) - mktemp /tmp/shorewall.XXXXXX - ;; - STD) - mktemp -t shorewall.XXXXXX - ;; - None) - rm -f /tmp/shorewall-$$ - > /tmp/shorewall-$$ && echo /tmp/shorewall-$$ - ;; - *) - error_message "ERROR:Internal error in mktempfile" - ;; - esac - fi -} - -# -# create a temporary directory -# -mktempdir() { - - [ -z "$MKTEMP" ] && find_mktemp - - case "$MKTEMP" in - STD) - mktemp -td shorewall.XXXXXX - ;; - None|BSD) - # - # Not all versions of the BSD mktemp support the -d option under Linux - # - qt rm -rf /tmp/shorewall-$$ - mkdir -p /tmp/shorewall-$$ && chmod 700 /tmp/shorewall-$$ && echo /tmp/shorewall-$$ - ;; - *) - error_message "ERROR:Internal error in mktempdir" - ;; - esac -} - -# -# Read a file and handle "INCLUDE" directives -# - -read_file() # $1 = file name, $2 = nest count -{ - local first rest - - if [ -f $1 ]; then - while read first rest; do - if [ "x$first" = "xINCLUDE" ]; then - if [ $2 -lt 4 ]; then - read_file $(find_file $(expand ${rest%#*})) $(($2 + 1)) - else - error_message "WARNING: INCLUDE in $1 ignored (nested too deeply)" - fi - else - echo "$first $rest" - fi - done < $1 - else - [ -n "$TERMINATOR" ] && $TERMINATOR "No such file: $1" - echo "WARNING -- No such file: $1" - fi -} - -# -# Strip comments and blank lines from a file and place the result in the -# temporary directory -# -strip_file() # $1 = Base Name of the file, $2 = Full Name of File (optional) -{ - local fname - - if [ ! -f $TMP_DIR/$1 ]; then - [ $# = 1 ] && fname=$(find_file $1) || fname=$2 - - if [ -f $fname ]; then - read_file $fname 0 | cut -d'#' -f1 | grep -v '^[[:space:]]*$' | expand_line > $TMP_DIR/$1 - else - > $TMP_DIR/$1 - fi - fi -} - -# -# Strip the passed file. -# -# Return success if -# a) the stripped file is non-empty and the library was successfully loaded; or -# b) the stripped file is empty but the library had been loaded previously -# -strip_file_and_lib_load() # $1 = logical file name, $2 = library to load if the stripped file is non-empty -{ - local f=$(find_file $1) - - strip_file $1 $f - - if [ -s $TMP_DIR/$1 ]; then - lib_load $2 "A non-empty $1 file ($f)" - return 0 - fi - - eval test -n \"\$LIB_${2}_LOADED\" -} - -# -# Check that a mark value or mask is less that 256 or that it is less than 65536 and -# that it's lower 8 bits are zero. -# -verify_mark() # $1 = value to test -{ - verify_mark2() - { - case $1 in - 0*) - [ $(($1)) -lt 256 ] && return 0 - [ -n "$HIGH_ROUTE_MARKS" ] || return 1 - [ $(($1)) -gt 65535 ] && return 1 - return $(($1 & 0xFF)) - ;; - [1-9]*) - [ $1 -lt 256 ] && return 0 - [ -n "$HIGH_ROUTE_MARKS" ] || return 1 - [ $1 -gt 65535 ] && return 1 - return $(($1 & 0xFF)) - ;; - *) - return 2 - ;; - esac - } - - verify_mark2 $1 || fatal_error "Invalid Mark or Mask value: $1" -} - -# -# Determine the value for a parameter that defaults to Yes -# -added_param_value_yes() # $1 = Parameter Name, $2 = Parameter value -{ - local val="$2" - - if [ -z "$val" ]; then - echo "Yes" - else case $val in - [Yy][Ee][Ss]) - echo "Yes" - ;; - [Nn][Oo]) - echo "" - ;; - *) - startup_error "Invalid value ($val) for $1" - ;; - esac - fi -} - -# -# Determine the value for a parameter that defaults to No -# -added_param_value_no() # $1 = Parameter Name, $2 = Parameter value -{ - local val="$2" - - if [ -z "$val" ]; then - echo "" - else case $val in - [Yy][Ee][Ss]) - echo "Yes" - ;; - [Nn][Oo]) - echo "" - ;; - *) - startup_error "Invalid value ($val) for $1" - ;; - esac - fi -} - -# -# Initialize this program -# -do_initialize() { - - # Run all utility programs using the C locale - # - # Thanks to Vincent Planchenault for this tip # - - export LC_ALL=C - - # Make sure umask is sane - umask 077 - - PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin - # - # Establish termination function - # - TERMINATOR=fatal_error - # - # Clear all configuration variables (shorewall.conf) - # - STARTUP_ENABLED= - # - #VERBOSE is inherited -- VERBOSITY is only used in the CIs - # - # - # Logging - # - LOGFILE= - LOGFORMAT= - LOGTAGONLY= - LOGRATE= - LOGBURST= - LOGALLNEW= - BLACKLIST_LOGLEVEL= - MACLIST_LOG_LEVEL= - TCP_FLAGS_LOG_LEVEL= - RFC1918_LOG_LEVEL= - SMURF_LOG_LEVEL= - LOG_MARTIANS= - # - # Location of files - # - IPTABLES= - #PATH is inherited - SHOREWALL_SHELL= - SUBSYSLOCK= - MODULESDIR= - #CONFIG_PATH is inherited - RESTOREFILE= - IPSECFILE= - # - # Default Actions/Macros - # - DROP_DEFAULT= - REJECT_DEFAULT= - ACCEPT_DEFAULT= - QUEUE_DEFAULT= - # - # Firewall Options - # - IP_FORWARDING= - ADD_IP_ALIASES= - ADD_SNAT_ALIASES= - RETAIN_ALIASES= - TC_ENABLED= - TC_EXPERT= - CLEAR_TC= - MARK_IN_FORWARD_CHAIN= - CLAMPMSS= - ROUTE_FILTER= - DETECT_DNAT_IPADDRS= - MUTEX_TIMEOUT= - ADMINISABSENTMINDED= - BLACKLISTNEWONLY= - DELAYBLACKLISTLOAD= - MODULE_SUFFIX= - DISABLE_IPV6= - BRIDGING= - DYNAMIC_ZONES= - PKTTYPE= - RFC1918_STRICT= - MACLIST_TABLE= - MACLIST_TTL= - SAVE_IPSETS= - MAPOLDACTIONS= - FASTACCEPT= - IMPLICIT_CONTINUE= - HIGH_ROUTE_MARKS= - USE_ACTIONS= - OPTIMIZE= - EXPORTPARAMS= - # - # Packet Disposition - # - MACLIST_DISPOSITION= - TCP_FLAGS_DISPOSITION= - BLACKLIST_DISPOSITION= - # - # Other Globals - # - VERSION= - FW= - USEPKTYPE= - LOGLIMIT= - LOGPARMS= - OUTPUT= - ALL_INTERFACES= - ROUTEMARK_INTERFACES= - PROVIDERS= - CRITICALHOSTS= - EXCLUSION_SEQ=1 - STOPPING= - HAVE_MUTEX= - ALIASES_TO_ADD= - SECTION=ESTABLISHED - SECTIONS= - ALL_PORTS= - ACTIONS= - USEDACTIONS= - DEFAULT_MACROS= - COMMENT= - VERSION_FILE= - LOGRULENUMBERS= - ORIGINAL_POLICY_MATCH= - TMP_DIR=$(mktempdir) - - [ -n "$TMP_DIR" ] && chmod 700 $TMP_DIR || \ - startup_error "Can't create a temporary directory" - - case $PROGRAM in - compiler) - trap "[ -n "$OUTPUT" ] && rm -f $OUTPUT;rm -rf $TMP_DIR; exit 2" 1 2 3 4 5 6 9 - ;; - firewall) - trap "[ -n "$RESTOREBASE" ] && rm -f $RESTOREBASE;rm -rf $TMP_DIR; my_mutex_off; exit 2" 1 2 3 4 5 6 9 - ;; - esac - - ensure_config_path - - VERSION_FILE=$SHAREDIR/version - - [ -f $VERSION_FILE ] && VERSION=$(cat $VERSION_FILE) - - set -a - - run_user_exit params - - set +a - - config=$(find_file shorewall.conf) - - if [ -f $config ]; then - if [ -r $config ]; then - progress_message "Processing $config..." - . $config - else - startup_error "Cannot read $config (Hint: Are you root?)" - fi - else - startup_error "$config does not exist!" - fi - - # - # Restore CONFIG_PATH if the shorewall.conf file cleared it - # - ensure_config_path - # - # Determine the capabilities of the installed iptables/netfilter - # We load the kernel modules here to accurately determine - # capabilities when module autoloading isn't enabled. - # - PKTTYPE=$(added_param_value_no PKTTYPE $PKTTYPE) - - [ -n "${MODULE_SUFFIX:=o gz ko o.gz ko.gz}" ] - - if [ -z "$EXPORT" -a $(id -u) -eq 0 ]; then - - load_kernel_modules Yes - - if [ -z "$IPTABLES" ]; then - IPTABLES=$(mywhich iptables 2> /dev/null) - [ -z "$IPTABLES" ] && startup_error "Can't find iptables executable" - else - [ -e "$IPTABLES" ] || startup_error "\$IPTABLES=$IPTABLES does not exist or is not executable" - fi - - f=$(find_file capabilities) - - [ -f $f ] && . $f || determine_capabilities - - else - f=$(find_file capabilities) - [ -f $f ] && . $f || startup_error "The -e flag requires a capabilities file" - fi - - ORIGINAL_POLICY_MATCH=$POLICY_MATCH - - ADD_IP_ALIASES="$(added_param_value_yes ADD_IP_ALIASES $ADD_IP_ALIASES)" - - if [ -n "${LOGRATE}${LOGBURST}" ]; then - LOGLIMIT="--match limit" - [ -n "$LOGRATE" ] && LOGLIMIT="$LOGLIMIT --limit $LOGRATE" - [ -n "$LOGBURST" ] && LOGLIMIT="$LOGLIMIT --limit-burst $LOGBURST" - fi - - if [ -n "$IP_FORWARDING" ]; then - case "$IP_FORWARDING" in - On|Off|Keep|on|off|keep|ON|OFF|KEEP) - ;; - *) - startup_error "Invalid value ($IP_FORWARDING) for IP_FORWARDING" - ;; - esac - else - IP_FORWARDING=On - fi - - [ -n "${BLACKLIST_DISPOSITION:=DROP}" ] - - case "$CLAMPMSS" in - [0-9]*) - ;; - *) - CLAMPMSS=$(added_param_value_no CLAMPMSS $CLAMPMSS) - ;; - esac - - ADD_SNAT_ALIASES=$(added_param_value_no ADD_SNAT_ALIASES $ADD_SNAT_ALIASES) - ROUTE_FILTER=$(added_param_value_no ROUTE_FILTER $ROUTE_FILTER) - LOG_MARTIANS=$(added_param_value_no LOG_MARTIANS $LOG_MARTIANS) - DETECT_DNAT_IPADDRS=$(added_param_value_no DETECT_DNAT_IPADDRS $DETECT_DNAT_IPADDRS) - - MACLIST_TARGET=reject - - if [ -n "$MACLIST_DISPOSITION" ] ; then - case $MACLIST_DISPOSITION in - REJECT) - ;; - DROP) - MACLIST_TARGET=DROP - ;; - ACCEPT) - MACLIST_TARGET=RETURN - ;; - *) - startup_error "Invalid value ($MACLIST_DISPOSITION) for MACLIST_DISPOSITION" - ;; - esac - else - MACLIST_DISPOSITION=REJECT - fi - - if [ -n "$TCP_FLAGS_DISPOSITION" ] ; then - case $TCP_FLAGS_DISPOSITION in - REJECT|ACCEPT|DROP) - ;; - *) - startup_error "Invalid value ($TCP_FLAGS_DISPOSITION) for TCP_FLAGS_DISPOSITION" - ;; - esac - else - TCP_FLAGS_DISPOSITION=DROP - fi - - [ -n "${RFC1918_LOG_LEVEL:=info}" ] - - MARK_IN_FORWARD_CHAIN=$(added_param_value_no MARK_IN_FORWARD_CHAIN $MARK_IN_FORWARD_CHAIN) - [ -n "$MARK_IN_FORWARD_CHAIN" ] && MARKING_CHAIN=tcfor || MARKING_CHAIN=tcpre - CLEAR_TC=$(added_param_value_yes CLEAR_TC $CLEAR_TC) - - if [ -n "$LOGFORMAT" ]; then - if [ -n "$(echo $LOGFORMAT | grep '%d')" ]; then - LOGRULENUMBERS=Yes - temp=$(printf "$LOGFORMAT" fooxx2barxx 1 ACCEPT 2> /dev/null) - if [ $? -ne 0 ]; then - startup_error "Invalid LOGFORMAT string: \"$LOGFORMAT\"" - fi - else - temp=$(printf "$LOGFORMAT" fooxx2barxx ACCEPT 2> /dev/null) - if [ $? -ne 0 ]; then - startup_error "Invalid LOGFORMAT string: \"$LOGFORMAT\"" - fi - fi - - [ ${#temp} -le 29 ] || startup_error "LOGFORMAT string is longer than 29 characters: \"$LOGFORMAT\"" - - MAXZONENAMELENGTH=$(( 5 + ( ( 29 - ${#temp}) / 2) )) - MAXZONENAMELENGTH=${MAXZONENAMELENGTH%.*} - else - LOGFORMAT="Shorewall:%s:%s:" - MAXZONENAMELENGTH=5 - fi - - ADMINISABSENTMINDED=$(added_param_value_no ADMINISABSENTMINDED $ADMINISABSENTMINDED) - BLACKLISTNEWONLY=$(added_param_value_no BLACKLISTNEWONLY $BLACKLISTNEWONLY) - DISABLE_IPV6=$(added_param_value_no DISABLE_IPV6 $DISABLE_IPV6) - BRIDGING=$(added_param_value_no BRIDGING $BRIDGING) - - DYNAMIC_ZONES=$(added_param_value_no DYNAMIC_ZONES $DYNAMIC_ZONES) - if [ -n "$DYNAMIC_ZONES" ]; then - [ -n "$EXPORT" ] && startup_error "DYNAMIC_ZONES=Yes is incompatible with the -e option" - lib_avail dynamiczones || error_message "WARNING: DYNAMIC_ZONES=Yes requires the Shorewall dynamiczones library (${SHAREDIR}/lib.dynamiczones) which is not installed" - fi - - STARTUP_ENABLED=$(added_param_value_yes STARTUP_ENABLED $STARTUP_ENABLED) - RETAIN_ALIASES=$(added_param_value_no RETAIN_ALIASES $RETAIN_ALIASES) - [ -n "${ADD_IP_ALIASES}${ADD_SNAT_ALIASES}" ] || RETAIN_ALIASES= - DELAYBLACKLISTLOAD=$(added_param_value_no DELAYBLACKLISTLOAD $DELAYBLACKLISTLOAD) - LOGTAGONLY=$(added_param_value_no LOGTAGONLY $LOGTAGONLY) - RFC1918_STRICT=$(added_param_value_no RFC1918_STRICT $RFC1918_STRICT) - SAVE_IPSETS=$(added_param_value_no SAVE_IPSETS $SAVE_IPSETS) - MAPOLDACTIONS=$(added_param_value_yes MAPOLDACTIONS $MAPOLDACTIONS) - FASTACCEPT=$(added_param_value_no FASTACCEPT $FASTACCEPT) - IMPLICIT_CONTINUE=$(added_param_value_no IMPLICIT_CONTINUE $IMPLICIT_CONTINUE) - HIGH_ROUTE_MARKS=$(added_param_value_no HIGH_ROUTE_MARKS $HIGH_ROUTE_MARKS) - TC_EXPERT=$(added_param_value_no TC_EXPERT $TC_EXPERT) - USE_ACTIONS=$(added_param_value_yes USE_ACTIONS $USE_ACTIONS) - EXPORTPARAMS=$(added_param_value_yes EXPORTPARAMS $EXPORTPARAMS) - [ -n "$USE_ACTIONS" ] && lib_load actions "USE_ACTIONS=Yes" - - [ -n "$XCONNMARK_MATCH" ] || XCONNMARK= - [ -n "$XMARK" ] || XCONNMARK= - - [ -n "$HIGH_ROUTE_MARKS" -a -z "$XCONNMARK" ] && startup_error "HIGH_ROUTE_MARKS=Yes requires extended CONNMARK target, extended CONNMARK match support and extended MARK support" - - case ${MACLIST_TABLE:=filter} in - filter) - ;; - mangle) - [ $MACLIST_DISPOSITION = reject ] && startup_error "MACLIST_DISPOSITION=REJECT is not allowed with MACLIST_TABLE=mangle" - ;; *) - startup_error "Invalid value ($MACLIST_TABLE) for MACLIST_TABLE option" - ;; - esac - - TC_SCRIPT= - - if [ -n "$TC_ENABLED" ] ; then - case "$TC_ENABLED" in - [Yy][Ee][Ss]) - TC_ENABLED=Yes - TC_SCRIPT=$(find_file tcstart) - [ -f $TC_SCRIPT ] || startup_error "Unable to find tcstart file" - ;; - [Ii][Nn][Tt][Ee][Rr][Nn][Aa][Ll]) - TC_ENABLED=Internal - ;; - [Nn][Oo]) - TC_ENABLED= - ;; - esac - else - TC_ENABLED=Yes - fi - - if [ -n "$TC_ENABLED" ];then - [ -n "$MANGLE_ENABLED" ] || startup_error "Traffic Shaping requires mangle support in your kernel and iptables" - fi - - [ "x${SHOREWALL_DIR}" = "x." ] && SHOREWALL_DIR="$PWD" - - [ -n "${RESTOREFILE:=restore}" ] - - case "${DROP_DEFAULT:=Drop}" in - None) - DROP_DEFAULT=none - ;; - esac - - case "${REJECT_DEFAULT:=Reject}" in - None) - REJECT_DEFAULT=none - ;; - esac - - case "${QUEUE_DEFAULT:=none}" in - None) - QUEUE_DEFAULT=none - ;; - esac - - case "${ACCEPT_DEFAULT:=none}" in - None) - ACCEPT_DEFAULT=none - ;; - esac - - case "${OPTIMIZE:=0}" in - 0|1) - ;; - *) - startup_error "Invalid OPTIMIZE value ($OPTIMIZE)" - ;; - esac - # - # Check out the user's shell - # - [ -n "${SHOREWALL_SHELL:=/bin/sh}" ] - - temp=$(decodeaddr 192.168.1.1) - if [ $(encodeaddr $temp) != 192.168.1.1 ]; then - startup_error "Shell $SHOREWALL_SHELL is broken and may not be used with Shorewall" - fi - - if [ -z "$KLUDGEFREE" ]; then - rm -f $TMP_DIR/physdev - rm -f $TMP_DIR/iprange - fi - - qt mywhich awk && HAVEAWK=Yes || HAVEAWK= - # - # Pre-process all of the standard files - # - # Because 'strip_file()' does shell variable expansion, we must first determine the - # setting of $FW - # - case ${IPSECFILE:=ipsec} in - ipsec) - [ -n "${FW:=fw}" ] - strip_file ipsec - ;; - zones) - get_firewall_zone - ;; - *) - startup_error "Invalid value ($IPSECFILE) for IPSECFILE option" - ;; - esac - - strip_file zones - strip_file routestopped - strip_file interfaces - strip_file hosts - - if [ $PROGRAM = compiler ]; then - strip_file_and_lib_load accounting accounting - - if [ -n "$USE_ACTIONS" ]; then - strip_file actions - strip_file actions.std ${SHAREDIR}/actions.std - fi - - strip_file blacklist - strip_file ecn - strip_file maclist - strip_file_and_lib_load masq nat - strip_file_and_lib_load nat nat - strip_file_and_lib_load netmap nat - strip_file policy - strip_file_and_lib_load providers providers && strip_file route_rules - strip_file_and_lib_load proxyarp proxyarp - strip_file rfc1918 - strip_file routestopped - strip_file rules - - if [ "$TC_ENABLED" = Internal ]; then - strip_file_and_lib_load tcdevices tc - strip_file_and_lib_load tcclasses tc - fi - - strip_file_and_lib_load tcrules tcrules - strip_file tos - strip_file_and_lib_load tunnels tunnels - report_capabilities1 > $TMP_DIR/capabilities - export TMP_DIR - export CONFIG_PATH - export VERSION - fi - # - # Clear $FW - # - FW= - -}