ACC SHELL
Path : /sbin/ |
|
Current File : //sbin/SuSEfirewall2 |
#!/bin/bash
#
# SuSEfirewall2 - stateful packetfilter rules generator
# Copyright (C) 2000-2002 Marc Heuse <marc@suse.de>
# Copyright (C) 2003,2004 SUSE Linux AG
# Copyright (C) 2005-2008 SUSE LINUX Products GmbH
#
# Author: Marc Heuse
# Maintainer: Ludwig Nussel
#
# Please send feedback via http://www.suse.de/feedback
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# For all those fellow experts out there: yes I know that this is NOT a
# firewall setup but a simple (no, not simple, it tries actually to be
# clever) packet filter. But if we would call this "SuSEpacketfilter",
# only a few user would install it, hence general security would be bad.
#
###########################################################################
# #
# The configuration file for this firewall script is #
# /etc/sysconfig/SuSEfirewall2 #
# #
# Please make only modifications to this script if you know what you #
# are doing! A small explanation of the setup can be found in #
# /usr/share/doc/packages/SuSEfirewall2/README #
# #
# For new-user help concerning configuring this firewall, take a look at #
# the configuration file /etc/sysconfig/SuSEfirewall2 - it tells #
# you all #
# (if not: sorry, but configuring a packet filter/screening router is NOT #
# trivial - you must know what you are doing and what it actually does!) #
# #
###########################################################################
help() {
cat <<EOF
SuSEfirewall2 3.6, Copyright (C) 2005 SUSE LINUX Products GmbH
stateful packet filter rules generator for iptables.
$0 start|test|debug [file FILENAME]
$0 basic|stop|close|status|help
$0 open ZONE TYPE services...
$0 on|off
Options:
start generate and load the firewall filter rules from
/etc/sysconfig/SuSEfirewall2
stop unload all filter rules
close no incoming network traffic except bootp+ping (for boot security)
basic set basic filter rules that drop all incoming access
test generate and load the filter rules but do not drop any packet but log
to syslog anything which *would* be denied
status print the output of "iptables -nvL"
debug print the iptables command to stdout instead of executing them
log show SuSEfirewall2 related syslog messages in a better readable format
help this output
open open the specified services in the specified zone. You need to
restart SuSEfirewall2 for changes to take effect.
on add SuSEfirwall2 initscripts to boot process and start
off remove SuSEfirwall2 initscripts from boot process and stop
file FILENAME same as "start" but load alternate config file FILENAME
Calling $0 without any option is the same as the "start" option.
The "file FILENAME" option may be used with the start, test and debug options.
EOF
exit 0
}
removefiles=()
declare -a removefiles
removeonexit()
{
removefiles[${#removefiles[@]}]="$1"
}
cleanup()
{
local file
for file in "${removefiles[@]}"; do
rm -f "$file"
done
}
trap cleanup EXIT
quiet=''
syslog()
{
local pri="-p auth.err"
local dashs='-s'
if [ "$1" = '0' ]; then
pri="-p auth.info"
if [ -n "$quiet" ]; then
dashs=''
fi
elif [ "$1" = '-1' ]; then
pri="-p auth.warn"
fi
shift
/bin/logger $dashs $pri -t SuSEfirewall2 "$*"
}
message()
{
syslog 0 "$*"
}
warning()
{
syslog -1 "Warning:" "$*"
}
deprecated()
{
warning "$@ is deprecated and will likely be removed in the future."
warning "If you think it should be kept please report your use case at"
warning "http://forge.novell.com/modules/xfmod/project/?susefirewall2"
}
error()
{
syslog -2 "Error:" "$*"
}
die()
{
local ret=1
trap EXIT
cleanup
case "$1" in
[0-9]) ret="$1"; shift ;;
esac
[ -n "$*" ] && syslog "$ret" "$*"
exit $ret
}
need()
{
. "$SCRIPTSDIR/SuSEfirewall2-$1"
}
CONFIGURATIONSDIR_0="/etc/sysconfig/SuSEfirewall2.d/services"
CONFIGURATIONSDIR_1="/usr/share/SuSEfirewall2/services"
SCRIPTSDIR="/etc/sysconfig/scripts"
FWCONFIG="/etc/sysconfig/SuSEfirewall2"
LOCKFILE="/var/lock/SuSEfirewall2.pid"
BOOTLOCKFILE="/var/lock/SuSEfirewall2.booting"
STATUSDIR="/var/run/SuSEfirewall2"
FW_CUSTOMRULES=""
FW_ZONE_DEFAULT=""
USE_IPTABLES_BATCH=''
# whether ip6tables supports state matching
IP6TABLES_HAVE_STATE=1
# whether ip6tables support REJECT
IP6TABLES_HAVE_REJECT=1
ACTION="start"
MODE="standard"
INITSCRIPTS="" # on|off
needconfig=
needlock=1
create_bootlock=0
remove_bootlock=0
# prevent double log entries when called from ip-up
if test -x /usr/bin/tty && ! /usr/bin/tty -s; then
quiet=1
fi
getopttmp=`/usr/bin/getopt -o hq --long help,scriptsdir:,batch,nobatch,file:,debug,test,bootlock,bootunlock,quiet \
-n 'SuSEfirewall2' -- "$@"`
[ $? != 0 ] && die 1 "getopt error"
eval set -- "$getopttmp"
while true ; do
case "$1" in
--file) FWCONFIG="$2"; shift 2 ;;
--batch) USE_IPTABLES_BATCH='yes'; shift ;;
--nobatch) USE_IPTABLES_BATCH='no'; shift ;;
--scriptsdir) SCRIPTSDIR="$2" ; shift 2 ;;
--test) MODE="test" ; shift ;;
--debug) MODE="debug"; needlock=0 ; shift ;;
--bootlock) create_bootlock=1 ; shift ;;
--bootunlock) remove_bootlock=1 ; shift ;;
-h|--help) help ; shift ;;
-q|--quiet) quiet=1 ; shift ;;
--) shift ; break ;;
*) die 1 "getopt error"; ;;
esac
done
case "$1" in
start|"") needconfig=1 ;;
test) MODE="test" ;;
debug) MODE="debug"; needlock=0 ;;
easy|novice|basic) ACTION="basic" ;;
stop|halt|down|shutdown) ACTION="stop"; needconfig=1 ;;
close) ACTION="close" ;;
status) ACTION="status"; USE_IPTABLES_BATCH='no'; needlock=0 ;;
open) ACTION="open"; USE_IPTABLES_BATCH='no'; needlock=0 ;;
log) ACTION="showlog"; USE_IPTABLES_BATCH='no' ;;
bootlock) ACTION="bootlock"; create_bootlock=1; needlock=0 ;;
bootunlock) ACTION="bootunlock"; remove_bootlock=1; needlock=0 ;;
help) help ;;
off) ACTION="stop"; needconfig=1; INITSCRIPTS="off" ;;
on) ACTION="start"; needconfig=1; INITSCRIPTS="on" ;;
*) help ;;
esac
shift
case "$ACTION" in
start|stop)
while [ $# -gt 0 ]; do
case "$1" in
file) FWCONFIG="$2"; shift 2 ;;
force|batch) shift ;; # unused, for compatability
*) echo "invalid option: $1"; exit 1 ;;
esac
done
;;
esac
test -e /etc/sysconfig/network/config && . /etc/sysconfig/network/config
if [ -r "$FWCONFIG" ]; then
. "$FWCONFIG"
elif [ -n "$needconfig" ]; then
die 6 " Can not read $FWCONFIG"
fi
if [ -z "$USE_IPTABLES_BATCH" ]; then
case "$FW_USE_IPTABLES_BATCH" in
no) USE_IPTABLES_BATCH='' ;;
yes) USE_IPTABLES_BATCH='yes' ;;
''|auto) USE_IPTABLES_BATCH='auto' ;;
esac
fi
if [ "$FW_ZONE_DEFAULT" = 'yes' -o "$FW_ZONE_DEFAULT" = 'auto' ]; then
FW_ZONE_DEFAULT=''
fi
if [ -n "$USE_IPTABLES_BATCH" -a "$USE_IPTABLES_BATCH" != 'no' ]; then
need batch
check_iptables_batch
fi
[ "$USE_IPTABLES_BATCH" = 'no' ] && USE_IPTABLES_BATCH=''
### Definitions - fixed
unset ${!LC_*} ${!RC_LC_*} LANGUAGE RC_LANG
export LANG=en_US
export PATH="/sbin:/bin:/usr/sbin:/usr/bin"
hwdesc2iface=/etc/sysconfig/network/scripts/hwdesc2iface
modinfo="/sbin/modinfo"
TC="/usr/sbin/tc"
IPTABLES_BIN="/usr/sbin/iptables"
IP6TABLES_BIN="/usr/sbin/ip6tables"
if [ "$MODE" = debug ]; then
IPTABLES="iptables"
iptables()
{
echo iptables "$@"
}
IP6TABLES="ip6tables"
ip6tables()
{
echo ip6tables "$@"
}
TC="tc"
tc()
{
echo tc "$@"
}
modprobe()
{
echo modprobe "$@"
}
else
IPTABLES="$IPTABLES_BIN"
IP6TABLES="$IP6TABLES_BIN"
### ipv6 checks
case "$FW_IPv6" in
drop|reject) IP6TABLES_HAVE_STATE=0 ;;
no) IP6TABLES=":" ;;
*) FW_IPv6="" ;;
esac
####
if [ -n "$USE_IPTABLES_BATCH" ]; then
IPTABLES=iptables
[ "$IP6TABLES" != ":" ] && IP6TABLES=ip6tables
fi
fi
### jump targets
ACCEPT="ACCEPT"
DROP="DROP"
REJECT="reject_func"
[ "$FW_REJECT" = yes ] && DROP="reject_func"
# fwmarks
mark_redir=1
# ipsec
ipsec_chain=""
IPSEC_INPUT_MATCH="-m policy --dir in --pol ipsec --proto esp"
IPSEC_OUTPUT_MATCH="-m policy --dir out --pol ipsec --proto esp"
### zones
all_zones="int ext dmz"
forward_zones=
input_zones=
#### constants
safe_icmp_replies="echo-reply destination-unreachable time-exceeded parameter-problem timestamp-reply address-mask-reply protocol-unreachable redirect"
safe_icmpv6_replies="echo-reply destination-unreachable packet-too-big time-exceeded parameter-problem"
stateless_icmpv6_types="router-solicitation router-advertisement neighbour-solicitation neighbour-advertisement redirect"
###############
check_ip6tables_support()
{
[ "$IP6TABLES" != ':' ] || return
# Do we have a kernel with IPv6 enabled?
$IP6TABLES_BIN -nvL >/dev/null 2>&1 || IP6TABLES=:
if ! $IP6TABLES_BIN -m state --help >/dev/null 2>&1 || \
( ! $modinfo ip6t_state >/dev/null 2>&1 && ! $modinfo xt_state >/dev/null 2>&1); then
warning "ip6tables does not support state matching. Extended IPv6 support disabled."
IP6TABLES_HAVE_STATE=0
# reject incoming packets if not specified otherwise
[ "$FW_IPv6" != 'no' -a "$FW_IPv6" != 'drop' ] && FW_IPv6='reject'
fi
$modinfo ip6t_REJECT >/dev/null 2>&1 || IP6TABLES_HAVE_REJECT=0
if [ \( "$FW_REJECT" = "yes" -o "$FW_IPv6" = "reject" \) \
-a "$IP6TABLES_HAVE_REJECT" != 1 ]; then
warning "Kernel lacks support for IPv6 REJECT target! Using DROP for IPv6 instead."
fi
}
is_running()
{
test -e /proc/net/ip_tables_names && $IPTABLES_BIN -nL reject_func >/dev/null 2>&1
}
parse_logging()
{
if [ -z "$FW_LOG_LIMIT" ]; then
FW_LOG_LIMIT="-m limit --limit 3/minute"
elif [ "$FW_LOG_LIMIT" = 'no' ]; then
FW_LOG_LIMIT=''
else
FW_LOG_LIMIT="-m limit --limit $FW_LOG_LIMIT"
fi
### logging setup
if [ -z "$FW_LOG" ]; then
LOG='--log-level warning --log-tcp-options --log-ip-options --log-prefix SFW2'
else
LOG="$FW_LOG"
fi
case "$LOG" in
-j\ *) ;;
*) LOG="-j LOG $LOG" ;;
esac
LDC='' # log drop critical
LDA='' # log drop all
LDAC='' # log drop all or critical
LAC='' # log accept critical
LAA='' # log accept all
LAAC='' # log accept all or critical
# 'critical' will be unset if 'all' is set since 'critical' might be a special case of 'all'.
if [ "$FW_LOG_DROP_ALL" != yes ]; then
LDA=":"
if [ "$FW_LOG_DROP_CRIT" = no ]; then
LDC=":"
LDAC=":"
fi
else
LDC=':'
fi
if [ "$FW_LOG_ACCEPT_ALL" != yes ]; then
LAA=":"
if [ "$FW_LOG_ACCEPT_CRIT" = no ]; then
LAC=":"
LAAC=":"
fi
else
LAC=':'
fi
[ "$LAA" = ':' ] && LOG="$FW_LOG_LIMIT $LOG"
}
### Functions
function setproc()
{
[ -z "$2" -o ! -w "$2" ] && return
if [ "$MODE" != "debug" ]; then
echo "$1" > "$2"
else
echo "echo \"$1\" > \"$2\""
fi
}
# parameters: protocol port variable
# check whether $1 and $2/$3 are a valid protocol/port combination and sets global
# variables $proto, $port ($rport) and $sport ($rsport) in iptables syntax
# $4 is used for logging
# returns 1 on error, the content of $proto and $port is undefined then
check_proto_port()
{
proto="$1"
port="$2"
sport="$3"
local var="$4"
case "$proto" in
'')
if [ -z "$proto" -a -z "$port" -a -z "$sport" ]; then
proto=''
port=''
rport=''
sport=''
rsport=''
else
error "proto must not be empty in ${var}"
return 1
fi
;;
_rpc_) # cannot check ports here
;;
tcp|udp)
if [ -n "$port" ]; then
rport="--sport $port"
port="--dport $port"
else
port=''
rport=''
fi
if [ -n "$sport" ]; then
rsport="--dport $sport"
sport="--sport $sport"
else
sport=''
rsport=''
fi
;;
icmp)
if [ -n "$port" ]; then
port="--icmp-type $port"
rport="$port"
else
port=''
rport=''
fi
if [ -n "$sport" ]; then
sport="--icmp-type $sport"
rsport="$sport"
else
sport=''
rsport=''
fi
;;
*)
if [ -n "$port" ]; then
error "port is only valid with tcp, udp or icmp in ${var}"
return 1
fi
;;
esac
[ -z "$proto" ] || proto="-p $proto"
return 0
}
reset_rules() {
local policy_input policy_output policy_forward
policy_input=${1:-ACCEPT}
policy_output=${2:-ACCEPT}
policy_forward=${3:-ACCEPT}
$IPTABLES -P INPUT $policy_input
$IPTABLES -P OUTPUT $policy_output
$IPTABLES -P FORWARD $policy_forward
# yes we need cat for /proc
for i in `sort < /proc/net/ip_tables_names`; do
$IPTABLES -t $i -F
$IPTABLES -t $i -X
done
if [ "$IP6TABLES" != ":" ]; then
$IP6TABLES -P INPUT $policy_input
$IP6TABLES -P OUTPUT $policy_output
$IP6TABLES -P FORWARD $policy_forward
for i in `sort /proc/net/ip6_tables_names`; do
$IP6TABLES -t $i -F
$IP6TABLES -t $i -X
done
fi
}
clear_qdisc_settings() {
local data
local dev
local bandwidth
for data in $FW_HTB_TUNE_DEV; do
IFS="," read dev bandwidth < <(echo "$data")
$TC qdisc del dev $dev root 2> /dev/null
done
}
function load_modules()
{
local i
for i in "$@"; do
modprobe "$i"
done
}
function rulelog()
{
rule=$1
case $rule in
input_*)
echo IN${rule#input_}
;;
forward_*)
echo FWD${rule#forward_}
;;
esac
}
function allow_basic_established()
{
# needed for dhcp and dns replies
local iptables
for iptables in "$IPTABLES" "$IP6TABLES"; do
$LAA $iptables -A INPUT ${LOG}"-IN-ACC-EST " -m state --state ESTABLISHED
$iptables -A INPUT -j "$ACCEPT" -m state --state ESTABLISHED
# if two hosts have a tcp connection on fixed ports and
# one of the hosts crashes it will send a SYN to the
# peer if it comes back up. The peer sends back ACK as
# it thinks there is already a connection established.
# This ACK is INVALID and must be answered with RST
# otherwise long timeouts may occur (#46818).
# $LDA $iptables -A INPUT ${LOG}"-IN-REJECT-ACK " -m state --state INVALID -p tcp --tcp-flags SYN,RST,ACK ACK
# $iptables -A INPUT -j "$REJECT" -m state --state INVALID -p tcp --tcp-flags SYN,RST,ACK ACK
done
# need to accept icmp RELATED packets (bnc#382004)
$LAA $IPTABLES -A INPUT ${LOG}"-IN-ACC-REL " -p icmp -m state --state RELATED
$IPTABLES -A INPUT -j "$ACCEPT" -p icmp -m state --state RELATED
$LAA $IP6TABLES -A INPUT ${LOG}"-IN-ACC-REL " -p icmpv6 -m state --state RELATED
$IP6TABLES -A INPUT -j "$ACCEPT" -p icmpv6 -m state --state RELATED
}
have_bridgeinterfaces()
{
local i
for i in /sys/class/net/*/bridge; do
[ -e "$i" ] && return 0
done
return 1
}
allow_bridgetraffic()
{
local iptables
case "$FW_FORWARD_ALLOW_BRIDGING" in
yes) ;;
no)
return
;;
auto|'')
have_bridgeinterfaces || return
;;
esac
for iptables in "$IPTABLES" "$IP6TABLES"; do
$iptables -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT
done
}
xen_forward_hack()
{
local dev iptables
if [ -n "$FW_FORWARD_ALWAYS_INOUT_DEV" ]; then
warning "FW_FORWARD_ALWAYS_INOUT_DEV is deprecated and most likely not needed at all anymore"
fi
for iptables in "$IPTABLES" "$IP6TABLES"; do
for dev in $FW_FORWARD_ALWAYS_INOUT_DEV; do
$iptables -A FORWARD -i $dev -o $dev -j ACCEPT
done
done
}
function set_basic_rules()
{
local itype
check_ip6tables_support
load_modules ip_tables ip_conntrack $FW_LOAD_MODULES
if [ "$IP6TABLES" != ':' ]; then
load_modules ip6table_filter ip6table_mangle
fi
# determine policy
local DROP_JUMP
if [ "$DROP" = "ACCEPT" ]; then
DROP_JUMP="ACCEPT"
else
DROP_JUMP="DROP"
fi
reset_rules "$DROP_JUMP" ACCEPT "$DROP_JUMP"
# loopback is always allowed
for iptables in "$IPTABLES" "$IP6TABLES"; do
$iptables -A INPUT -j "$ACCEPT" -i lo
$iptables -A OUTPUT -j "$ACCEPT" -o lo
if [ "$FW_LO_NOTRACK" != 'no' ]; then
$iptables -t raw -A PREROUTING -j NOTRACK -i lo
$iptables -t raw -A OUTPUT -j NOTRACK -o lo
fi
done
# Special REJECT function #
$IPTABLES -N reject_func
$IPTABLES -A reject_func -p tcp -j REJECT --reject-with tcp-reset
$IPTABLES -A reject_func -p udp -j REJECT --reject-with icmp-port-unreachable
$IPTABLES -A reject_func -j REJECT --reject-with icmp-proto-unreachable
$IP6TABLES -N reject_func
if [ "$IP6TABLES_HAVE_REJECT" = 1 ]; then
$IP6TABLES -A reject_func -p tcp -j REJECT --reject-with tcp-reset
$IP6TABLES -A reject_func -p udp -j REJECT --reject-with port-unreach
$IP6TABLES -A reject_func -j REJECT --reject-with addr-unreach # know anything better?
fi
# sometimes the above lines do not work despite prior checks, so add drop
# always to be on the safe side
$IP6TABLES -A reject_func -j DROP
allow_bridgetraffic
xen_forward_hack
# workaround for ip6tables without state matching
if [ "$IP6TABLES_HAVE_STATE" != 1 ]; then
for itype in $stateless_icmpv6_types $safe_icmpv6_replies; do
$LAA $IP6TABLES -A INPUT ${LOG}"-IN-ACC-ICMP " -p icmpv6 --icmpv6-type $itype
$IP6TABLES -A INPUT -j "$ACCEPT" -p icmpv6 --icmpv6-type $itype
done
if [ "$FW_ALLOW_PING_FW" = yes ]; then
$LAA $IP6TABLES -A INPUT ${LOG}"-`rulelog $chain`-ACC-PING " -p icmpv6 --icmpv6-type echo-request
$IP6TABLES -A INPUT -j "$ACCEPT" -p icmpv6 --icmpv6-type echo-request
fi
$LAA $IP6TABLES -A INPUT -p tcp --tcp-flags ACK ACK ${LOG}"-IN-ACC-TCP "
$IP6TABLES -A INPUT -p tcp --tcp-flags ACK ACK -j "$ACCEPT"
# Drop all until IPv6 is really supported
$LDA $IP6TABLES -A INPUT ${LOG}"-IN-IPv6_PROHIB "
if [ "$FW_IPv6" = "drop" -o "$IP6TABLES_HAVE_REJECT" != 1 ]; then
$IP6TABLES -A INPUT -j "$DROP"
else
$IP6TABLES -A INPUT -j "$REJECT"
fi
$IP6TABLES -A OUTPUT -p icmpv6 -j "$ACCEPT"
$IP6TABLES -A OUTPUT -p tcp -j "$ACCEPT"
if [ "$IP6TABLES_HAVE_REJECT" != 1 -o "$FW_IPv6_REJECT_OUTGOING" = "no" ]; then
$IP6TABLES -A OUTPUT -j "$DROP"
else
$IP6TABLES -A OUTPUT -j "$REJECT"
fi
IP6TABLES=":" # disable further rules
fi
allow_basic_established
# make sure basic rules get committed even if there are errors later
[ -n "$USE_IPTABLES_BATCH" ] && iptables_batch_commitpoint
}
handle_initscripts()
{
local i
case "$INITSCRIPTS" in
on)
for i in SuSEfirewall2_init SuSEfirewall2_setup; do
/sbin/insserv -f $i
done
;;
off)
for i in SuSEfirewall2_setup SuSEfirewall2_init; do
/sbin/insserv -r -f $i
done
;;
esac
}
# set $dev to actual name of device $1
getdevinfo()
{
local dev=
local d="$1"
local var="$2"
if [ -d /sys/class/net/"$d" ]; then
dev="$d"
else
local deprecatediface=
if [ -x /sbin/getcfg-interface ]; then
dev=`/sbin/getcfg-interface "$d"`
elif [ -x "$hwdesc2iface" ]; then
case "$d" in
*-id-*) dev=`$hwdesc2iface id ${d#*-id-}`; deprecatediface=1 ;;
*-bus-*) dev=`$hwdesc2iface bus ${d#*-bus-}`; deprecatediface=1 ;;
esac
fi
if [ -z "$dev" -o ! -d /sys/class/net/"$dev" ]; then
return 1
fi
if [ -n "$deprecatediface" ]; then
warning "$var: the notation '$d' is deprecated. Please use '$dev' instead"
fi
fi
echo "$dev"
return 0
}
setlock()
{
if [ "$remove_bootlock" -ne 0 ]; then
rm -f "$BOOTLOCKFILE"
fi
### Locking mechanism
if [ "$needlock" -ne 0 ]; then
if [ -e "$BOOTLOCKFILE" ]; then
die 0 "$BOOTLOCKFILE exists which means system boot in progress, exit."
fi
if [ -e "$LOCKFILE" ]; then
read PID < $LOCKFILE
message "Another SuSEfirewall2 with PID $PID found, waiting ..."
i=0
while [ -e "$LOCKFILE" -a "$i" -lt 15 ]; do
sleep 2
i=$(( i + 1 ))
done
if [ -e "$LOCKFILE" ]; then
message "Lockfile is still there, ignoring it ..."
kill -TERM $PID
sleep 2
kill -KILL $PID
rm -f "$LOCKFILE"
fi
fi
removeonexit "$LOCKFILE"
set -o noclobber
echo "$$" > $LOCKFILE || exit 1
set +o noclobber
fi
if [ "$create_bootlock" -eq 1 ]; then
touch "$BOOTLOCKFILE"
fi
}
##
## function definitions for full featured mode
##
# Provide empty functions for transparent hook support for customised rules
fw_custom_after_chain_creation() { true; }
fw_custom_before_antispoofing() { true; }
fw_custom_after_antispoofing() { true; }
fw_custom_before_port_handling() { true; }
fw_custom_before_masq() { true; }
fw_custom_before_denyall() { true; }
evaluateinterfaces()
{
local devs=""
local var dev
local zone="$1"
var="FW_DEV_`cibiz $zone`"
eval set -- \$$var
for dev in "$@" ; do
if [ "$dev" = 'any' ]; then
if [ -n "$FW_ZONE_DEFAULT" ]; then
error "zone '$FW_ZONE_DEFAULT' is already default, ignoring 'any' in '$var'"
else
FW_ZONE_DEFAULT="$zone"
fi
continue
elif [ "$dev" = 'auto' ]; then
warning "ignoring deprecated interface 'auto' in $var"
continue
fi
dev=`getdevinfo "$dev" "$var"` || continue
case "$dev" in *:*) continue; ;; esac
devs="$devs $dev"
done
set -- $devs
eval FW_DEV_$zone="\$*"
}
#sets iface_$name=$zone
check_interfaces_unique()
{
local zone devs d z
for zone in $all_zones; do
eval devs="\$FW_DEV_$zone"
for d in $devs; do
[ -z "$d" ] && continue
d=${d//[^A-Za-z0-9]/_}
eval z=\${iface_$d}
if [ -z "$z" ]; then
eval iface_$d=$zone
else
error "$d already in zone '$z' but also configured for '$zone'"
fi
done
done
}
source_config_for_iface()
{
local iface="$1"
local dir=/etc/sysconfig/network
if [ -x /sbin/getcfg ] ; then
eval `/sbin/getcfg -d $dir -f ifcfg- -- $iface 2>/dev/null`
cfg="$HWD_CONFIG_0"
fi
if [ -z "$cfg" ]; then
cfg=$iface
fi
. $dir/ifcfg-$cfg 2>/dev/null
}
check_iface_override()
{
local iface="$1"
local f="$STATUSDIR/override/interfaces/$iface/zone"
local z dummy
test -e "$f" || return 0
read z dummy < "$f" || return 0
echo "$z"
}
autodetect_interfaces()
{
local d z
local have_override=''
set -- /sys/class/net/*
for d in "$@"; do
test -d "$d" || continue
d="${d#/sys/class/net/}"
[ -z "$d" -o "$d" = 'lo' -o "$d" = 'sit0' ] && continue
d=${d//[^A-Za-z0-9]/_}
unset z
if [ "$FW_RUNTIME_OVERRIDE" != 'no' ]; then
z=`check_iface_override $d`
if [ -n "$z" ]; then
eval iface_$d=$z
if eval [ -n "\"\$zone_$z\"" ]; then
message "runtime zone override '$z' for interface '$d'"
have_override=1
continue
else
error "invalid zone '$z' as override for interface '$d'"
fi
fi
fi
eval z=\${iface_$d}
[ -n "$z" ] && continue
eval [ -n "\"\$seen_$d\"" ] && continue
eval local seen_$d=1
z=`source_config_for_iface $d && echo $FW_ZONE`
if [ -n "$z" ]; then
if eval [ -n "\"\$zone_$z\"" ]; then
eval FW_DEV_$z="\"\$FW_DEV_$z \$d\""
#" fix vim syntax
eval iface_$d=$z
else
error "invalid zone '$z' specified for interface '$d'"
fi
elif [ -n "$FW_ZONE_DEFAULT" -a "$FW_ZONE_DEFAULT" != 'no' ]; then
message "using default zone '$FW_ZONE_DEFAULT' for interface $d"
z="$FW_ZONE_DEFAULT"
eval FW_DEV_$z="\"\$FW_DEV_$z \$d\""
#" fix vim syntax
eval iface_$d=$z
else
warning "no firewall zone defined for interface $d"
fi
done
# runtime override, we have to reconstruct FW_DEV_*
if [ -n "$have_override" ]; then
for z in $all_zones; do
eval "FW_DEV_$z=''"
done
for d in ${!iface_*}; do
eval z="\$$d"
eval "FW_DEV_$z=\"\$FW_DEV_$z ${d#iface_}\""
done
fi
}
write_interface_status()
{
local d z
mkdir -p "$STATUSDIR"/status/interfaces
for d in "$STATUSDIR/status/interfaces/"*; do
d=${d##*/}
[ "$d" != '*' ] || break
d=${d//[^A-Za-z0-9]/_}
eval z="\$iface_$d"
if [ -z "$z" ]; then
rm -rf "$STATUSDIR/status/interfaces/$d"
else
eval local seen_$d=1
echo $z > "$STATUSDIR/status/interfaces/$d/zone"
fi
done
for d in ${!iface_*}; do
eval z="\$$d"
d=${d#iface_}
eval [ -n "\"\$seen_$d\"" ] && continue
mkdir "$STATUSDIR/status/interfaces/$d"
echo $z > "$STATUSDIR/status/interfaces/$d/zone"
done
}
write_zone_status()
{
local v z
mkdir -p "$STATUSDIR/status/zones"
for z in "$STATUSDIR/status/zones/"*; do
z=${z##*/}
[ "$z" != '*' ] || break
z=${z//[^A-Za-z0-9]/_}
eval v="\$zone_$d"
if [ -z "$v" ]; then
rm -rf "$STATUSDIR/status/zones/$z"
else
eval local seen_$z=1
fi
done
for z in $all_zones; do
eval [ -n "\"\$seen_$z\"" ] && continue
mkdir "$STATUSDIR/status/zones/$z"
done
}
write_status()
{
[ "$MODE" != "debug" ] || return
[ "$FW_WRITE_STATUS" != "no" ] || return
write_interface_status
write_zone_status
}
parse_interfaces()
{
local zone devs var
for zone in $all_zones; do
evaluateinterfaces $zone
done
if [ -z "$FW_ZONE_DEFAULT" ]; then
FW_ZONE_DEFAULT='ext'
warning "no default firewall zone defined, assuming 'ext'"
fi
}
process_masq_dev()
{
local devs=""
local dev
set -- $FW_MASQ_DEV
for dev in "$@" ; do
if [ "$dev" = 'auto' ]; then
warning "ignoring deprecated interface 'auto' in FW_MASQ_DEV"
continue
fi
# zone specified?
if [ "$dev" != "${dev#zone:}" ]; then
dev=${dev#zone:}
if eval [ -n "\"\$zone_$dev\"" ]; then
eval devs="\"\$devs \$FW_DEV_$dev\""
continue
fi
fi
dev=`getdevinfo "$dev" FW_MASQ_DEV` || continue
case "$dev" in *:*) continue; ;; esac
devs="$devs $dev"
done
FW_MASQ_DEV="$devs"
}
load_customrules()
{
### Load custom rules
if [ -n "$FW_CUSTOMRULES" ]; then
if [ ! -r "$FW_CUSTOMRULES" ]; then
die 1 "Firewall customary rules file can not be read from $FW_CUSTOMRULES"
fi
. "$FW_CUSTOMRULES"
message "Firewall customary rules loaded from $FW_CUSTOMRULES"
fi
}
check_interfaces()
{
local v
for zone in $all_zones; do
eval v="\$FW_DEV_$zone"
[ -n "$v" ] && return
done
warning 'no interface active'
}
verify_parameters()
{
if [ "$FW_ROUTE" = no ]; then
if [ "$FW_MASQUERADE" = yes ]; then
warning 'FW_ROUTE needs to be set to yes for masquerading to work!'
fi
if [ "$FW_ALLOW_CLASS_ROUTING" = yes ]; then
warning 'FW_ROUTE needs to be set to yes for FW_ALLOW_CLASS_ROUTING to work!'
fi
if [ "$FW_ALLOW_PING_DMZ" = yes -o "$FW_ALLOW_PING_EXT" = yes ]; then
warning 'FW_ROUTE needs to be set to yes for FW_ALLOW_PING_EXT and/or FW_ALLOW_PING_DMZ to work!'
fi
fi
if [ "$FW_MASQUERADE" = no ]; then
[ -n "$FW_MASQ_NETS" -a "$FW_MASQ_NETS" != "0/0" ] && warning 'FW_MASQ_NETS needs FW_MASQUERADE set to yes to work!'
[ -n "$FW_FORWARD_MASQ" ] && warning 'FW_FORWARD_MASQ needs FW_MASQUERADE set to yes to work!'
fi
}
# Turn ip forwarding on if configured
switch_on_ip_forwarding()
{
if [ "$FW_ROUTE" = yes ]; then
setproc 1 /proc/sys/net/ipv4/ip_forward
else
setproc 0 /proc/sys/net/ipv4/ip_forward
fi
}
# warn user if device to masquerade is from a non private network
# 0/0 has to be skipped here, otherwise the spoof rules would block
# anything
verify_masq_nets()
{
local nets net1
for nets in $FW_MASQ_NETS ; do
IFS=, eval set -- \$nets
net1="$1"
# skip 0/0
test "$net1" = "0/0" && continue
IFS=/ eval set -- \$net1
[ -z "$2" ] && continue
case "$1" in
10.*|172.1[6789].*|172.2[0-9].*|172.3[01].*|192.168.*) ;;
*) warning "The network $net1 you want to masquerade is not from a private network " \
'like 10.0.0.0/8, 172.16.0.0/12 or 192.168.0.0/16'
esac
done
}
#################################
# Configuring more kernel stuff #
#################################
set_proc_stuff()
{
if [ "$FW_KERNEL_SECURITY" != no ]; then
setproc 1 /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# test "$FW_ALLOW_PING_FW" = yes || setproc 1 /proc/sys/net/ipv4/icmp_echo_ignore_all # XXX
setproc 1 /proc/sys/net/ipv4/ip_always_defrag # XXX not there?
setproc 1 /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
setproc 5 /proc/sys/net/ipv4/icmp_echoreply_rate
setproc 5 /proc/sys/net/ipv4/icmp_destunreach_rate
setproc 5 /proc/sys/net/ipv4/icmp_paramprob_rate
setproc 6 /proc/sys/net/ipv4/icmp_timeexceed_rate
setproc 20 /proc/sys/net/ipv4/ipfrag_time
for i in /proc/sys/net/ipv4/conf/*; do
setproc 1 $i/log_martians
setproc 0 $i/bootp_relay
[ "$FW_ROUTE" != yes ] && setproc 0 $i/forwarding
setproc 0 $i/proxy_arp
setproc 1 $i/secure_redirects
#setproc 0 $i/accept_redirects # let kernel decide this
setproc 0 $i/accept_source_route
setproc 1 $i/rp_filter
done
setproc 1 /proc/sys/net/ipv4/route/flush
fi
}
# Make input/forward chains
create_chains()
{
local iptables
for iptables in "$IPTABLES" "$IP6TABLES"; do
for TARGET in input forward; do
for CHAIN in $all_zones; do
$iptables -N ${TARGET}_${CHAIN}
done
done
done
}
### configurations ###
parse_configurations()
{
local var zone configurations config
for zone in $input_zones; do
var="FW_CONFIGURATIONS_`cibiz $zone`"
eval configurations="\"\$$var\""
for config in $configurations; do
local TCP=''
local UDP=''
local RPC=''
local IP=''
local BROADCAST=''
local RELATED=''
local MODULES=''
# XXX: could use a sub shell in order to enforce use of known variables only
if [ ! -r $CONFIGURATIONSDIR_0/$config ] || ! . $CONFIGURATIONSDIR_0/$config; then
if [ ! -r $CONFIGURATIONSDIR_1/$config ] || ! . $CONFIGURATIONSDIR_1/$config; then
warning "config '$config' not available"
continue
fi
fi
for var in TCP UDP RPC IP; do
eval [ -n \"\$$var\" ] \&\& FW_SERVICES_`cibiz $zone`_$var="\"\$FW_SERVICES_`cibiz $zone`_$var \$$var\""
done
if [ -n "$BROADCAST" ]; then
var=FW_ALLOW_FW_BROADCAST_`cibiz $zone`
eval allow="\"\$$var\""
if [ "$allow" != 'yes' ]; then
# 'no' is ignored later anyways
eval $var="\"\$$var \$BROADCAST\""
fi
fi
if [ -n "$RELATED" ]; then
eval FW_SERVICES_ACCEPT_RELATED_`cibiz $zone`="\"\$FW_SERVICES_ACCEPT_RELATED_`cibiz $zone` \$RELATED\""
fi
if [ -n "$MODULES" ]; then
eval FW_LOAD_MODULES="\"\$FW_LOAD_MODULES \$MODULES\""
fi
done
done
}
### handling of broadcasts ###
check_convert_old_broadcast()
{
if [ -n "$FW_ALLOW_FW_BROADCAST" -o -n "$FW_IGNORE_FW_BROADCAST" ]; then
need oldbroadcast
convert_old_broadcast
fi
}
drop_broadcast()
{
local allow ignore port zone
for zone in $input_zones; do
eval allow="\$FW_ALLOW_FW_BROADCAST_`cibiz $zone`"
eval ignore="\$FW_IGNORE_FW_BROADCAST_`cibiz $zone`"
local match="-A input_$zone -m pkttype --pkt-type broadcast"
for port in $allow; do
[ $port = no -o $port = yes ] && continue
$LAA $IPTABLES $match -p udp --dport $port ${LOG}"-ACC-BCAST${zone:0:1} "
$IPTABLES $match -p udp --dport $port -j "$ACCEPT"
done
if [ "$ignore" != yes ]; then
for port in $ignore; do
[ $port = no ] && continue
$IPTABLES $match -p udp --dport $port -j DROP
done
if [ "$allow" != 'yes' ]; then
$LDA $IPTABLES $match ${LOG}"-DROP-BCAST${zone:0:1} "
fi
fi
if [ "$allow" != 'yes' ]; then
$IPTABLES $match -j DROP # no need to send icmp for broadcasts
fi
done
}
### zones ###
parse_zones()
{
local zone
for zone in $FW_ZONES; do
case $zone in
[Ii][Nn][Tt]|[Ee][Xx][Tt]|[Dd][Mm][Zz])
error "FW_ZONES=$zone ignored" ;;
*)
if [ "$zone" != "${zone//[^A-Za-z0-9]/_}" ]; then
error "ignoring invalid zone name $zone in FW_ZONES"
else
all_zones="$all_zones $zone"
fi
;;
esac
done
for zone in $all_zones; do
eval "zone_$zone=0"
done
}
remove_unused_zones()
{
local zone zones devs
for zone in $all_zones; do
eval devs="\$FW_DEV_$zone"
if [ -n "$devs" -o "$ipsec_chain" = $zone -o "$FW_ZONE_DEFAULT" = "$zone" ]; then
if [ -z "$zones" ]; then
zones=$zone
else
zones="$zones $zone"
fi
fi
done
[ "$all_zones" != "$zones" ] && all_zones="$zones"
}
# convert if built in zone, eg ext -> EXT
cibiz()
{
case $1 in
int) echo INT ;;
ext) echo EXT ;;
dmz) echo DMZ ;;
*) echo "$1" ;;
esac
}
### IPsec ###
parse_ipsec()
{
if [ "$FW_IPSEC_TRUST" = yes ]; then
ipsec_chain="int"
elif [ "$FW_IPSEC_TRUST" = no ]; then
:
elif [ -n "$FW_IPSEC_TRUST" ]; then
for zone in $all_zones; do
if [ "$FW_IPSEC_TRUST" = "$zone" ]; then
ipsec_chain="$zone"
break;
fi
done
if [ -z "$ipsec_chain" ]; then
warning "FW_IPSEC_TRUST: $FW_IPSEC_TRUST is no valid zone"
fi
fi
}
allow_ipsec()
{
if [ -n "$ipsec_chain" ]; then
$IPTABLES -A INPUT -j "input_$ipsec_chain" $IPSEC_INPUT_MATCH
$IPTABLES -A FORWARD -j "forward_$ipsec_chain" $IPSEC_INPUT_MATCH
$IPTABLES -A FORWARD -j "forward_$ipsec_chain" $IPSEC_OUTPUT_MATCH
fi
}
#####################################
# Rule split up - forking to chains #
#####################################
# ipv4 and ipv6
fork_to_chains()
{
local iptables
local zone
local dev
local devs
local var val
for iptables in "$IPTABLES" "$IP6TABLES"; do
for zone in $saved_input_zones; do
var="FW_PROTECT_FROM_`cibiz $zone`"
eval val="\"\$$var\""
if [ "$val" = 'notrack' ]; then
# already have rules for that
continue
fi
eval devs="\$FW_DEV_$zone"
for dev in $devs; do
$iptables -A INPUT -j input_$zone -i $dev
done
done
if [ -n "$FW_ZONE_DEFAULT" -a "$FW_ZONE_DEFAULT" != 'no' ]; then
$iptables -A INPUT -j "input_$FW_ZONE_DEFAULT"
fi
if [ "$FW_ROUTE" = yes ]; then
for zone in $forward_zones; do
eval devs="\$FW_DEV_$zone"
for dev in $devs; do
$iptables -A FORWARD -j forward_$zone -i $dev
done
done
fi
done
}
# ipv4 and ipv6
finish_chains()
{
local iptables
for iptables in "$IPTABLES" "$IP6TABLES"; do
# anything which is now not in the input_* chains is evil
$LDAC $iptables -A INPUT ${LOG}"-IN-ILL-TARGET "
$iptables -A INPUT -j "$DROP"
$LDAC $iptables -A FORWARD ${LOG}"-FWD-ILL-ROUTING "
if [ "$FW_ROUTE" = yes ]; then
$iptables -A FORWARD -j "$DROP" # this is an unneeded rule, but looks nice :)
fi
$iptables -A OUTPUT -j ACCEPT -m state --state NEW,ESTABLISHED,RELATED
$LDAC $iptables -A OUTPUT ${LOG}"-OUT-ERROR "
# we want to let locally generated packets out since our task is not
# to protect the world from us, but protect us from the world ;)
# policy is ACCEPT $iptables -A OUTPUT -j ACCEPT
done
# MSS stuff needs this?
if [ "$FW_ROUTE" = yes ]; then
$IPTABLES -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
fi
}
# Protect the firewall from the internal network? #
protect_from_internal()
{
local iptables zone devs dev chain
local newzones=
for zone in $input_zones; do
if [ "$zone" = "int" -a "$FW_PROTECT_FROM_INTERNAL" = "no" ]; then
val="no"
warning "FW_PROTECT_FROM_INTERNAL is deprecated, use FW_PROTECT_FROM_INT instead"
else
var="FW_PROTECT_FROM_`cibiz $zone`"
eval val="\"\$$var\""
fi
if [ "$val" = notrack ]; then
eval devs="\$FW_DEV_$zone"
for dev in $devs; do
for iptables in "$IPTABLES" "$IP6TABLES"; do
$iptables -t raw -i $dev -I PREROUTING -j NOTRACK
$iptables -t raw -o $dev -I OUTPUT -j NOTRACK
$iptables -i $dev -I INPUT -j ACCEPT
$iptables -o $dev -I OUTPUT -j ACCEPT
done
done
elif [ "$val" = no ]; then
chain=input_$zone
for iptables in "$IPTABLES" "$IP6TABLES"; do
$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-ALL "
$iptables -A $chain -j "$ACCEPT"
done
else
if [ -z "$newzones" ]; then
newzones="$zone"
else
newzones="$newzones $zone"
fi
fi
done
if [ "$input_zones" != "$newzones" ]; then
saved_input_zones="$input_zones" # need that for fork_to_chains
input_zones="$newzones"
fi
}
allow_related()
{
local var
local services target service proto net
local iptables zone chain
for zone in $input_zones; do
chain=input_$zone
var="FW_SERVICES_ACCEPT_RELATED_`cibiz $zone`"
eval services="\"\$$var\""
for service in $services; do
IFS=, eval set -- \$service
net="${1:-0/0}"
proto="$2"
port="$3"
sport="$4"
iptables="$IPTABLES $IP6TABLES"
case "$net" in
*:*) iptables="$IP6TABLES" ;;
[0-9]*.*.*.*) iptables="$IPTABLES" ;;
esac
if check_proto_port "$proto" "$port" "$sport" "$var"; then
for iptables in $iptables; do
$LAA $iptables -A $chain -s $net $proto $rport $rsport -m state --state RELATED ${LOG}"-`rulelog $chain`-REL "
$iptables -A $chain -s $net $proto $rport $rsport -j ACCEPT -m state --state RELATED
done
fi
done
done
}
# ICMP stuff
allow_icmp()
{
local chain dev itype zone devs
# INPUT ICMP rules
if [ "$FW_ALLOW_FW_SOURCEQUENCH" != "no" ]; then
for chain in $input_zones; do
chain=input_$chain
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-SOURCEQUENCH " -p icmp --icmp-type source-quench
$IPTABLES -A $chain -j "$ACCEPT" -p icmp --icmp-type source-quench
done
fi
if [ "$FW_ALLOW_PING_FW" = yes ]; then
for chain in $input_zones; do
chain=input_$chain
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING " -p icmp --icmp-type echo-request
$IPTABLES -A $chain -j "$ACCEPT" -p icmp --icmp-type echo-request
$LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING " -p icmpv6 --icmpv6-type echo-request
$IP6TABLES -A $chain -j "$ACCEPT" -p icmpv6 --icmpv6-type echo-request
done
fi
# not needed as there is a generic accept rule for ICMP RELATED packets
# local icmp_types="$safe_icmp_replies"
# for itype in $icmp_types; do
# for chain in $input_zones; do
# chain=input_$chain
# $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-ICMP " -m state --state ESTABLISHED,RELATED -p icmp --icmp-type $itype
# $IPTABLES -A $chain -j "$ACCEPT" -m state --state ESTABLISHED,RELATED -p icmp --icmp-type $itype
# done
# done
# icmp_types="$safe_icmpv6_replies"
# for itype in $icmp_types; do
# for chain in $input_zones; do
# chain=input_$chain
# $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-ICMP " -m state --state ESTABLISHED,RELATED -p icmpv6 --icmpv6-type $itype
# $IP6TABLES -A $chain -j "$ACCEPT" -m state --state ESTABLISHED,RELATED -p icmpv6 --icmpv6-type $itype
# done
# done
# DROP rules for input ICMP are after trusted handling (see below)
# state matching for these does not work
icmp_types="$stateless_icmpv6_types"
for itype in $icmp_types; do
for chain in $input_zones; do
chain=input_$chain
$LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-ICMP " -p icmpv6 --icmpv6-type $itype
$IP6TABLES -A $chain -j "$ACCEPT" -p icmpv6 --icmpv6-type $itype
done
done
$IP6TABLES -A OUTPUT -j "$ACCEPT" -p icmpv6 # XXX: some are not catched by conntrack, should be fixed in kernel
}
allow_forward_icmp_echo()
{
[ "$FW_ROUTE" != "yes" ] && return
local zone chain var val
# FORWARD ICMP rules
for zone in $forward_zones; do
var="FW_ALLOW_PING_`cibiz $zone`"
eval val="\"\$$var\""
[ "$val" != yes ] && continue
eval devs="\$FW_DEV_$zone"
for dev in $devs; do
for chain in $forward_zones; do
[ "$chain" = "$zone" ] && continue
chain=forward_$chain
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING " -p icmp --icmp-type echo-request -o $dev
$IPTABLES -A $chain -j "$ACCEPT" -m state --state NEW -p icmp --icmp-type echo-request -o $dev
$LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING " -p icmpv6 --icmpv6-type echo-request -o $dev
$IP6TABLES -A $chain -j "$ACCEPT" -m state --state NEW -p icmpv6 --icmpv6-type echo-request -o $dev
done
done
chain=forward_$zone
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING " -p icmp --icmp-type echo-reply
$IPTABLES -A $chain -j "$ACCEPT" -m state --state ESTABLISHED -p icmp --icmp-type echo-reply
$LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-PING " -p icmpv6 --icmpv6-type echo-reply
$IP6TABLES -A $chain -j "$ACCEPT" -m state --state ESTABLISHED -p icmpv6 --icmpv6-type echo-reply
done
# drop rule for forwarding chains are at the end of the forwarding rules
}
#############################
# Trusted Networks Handling #
#############################
process_trusted_nets()
{
local nets net chain
for nets in $FW_TRUSTED_NETS; do
IFS=, eval set -- \$nets
net="$1"
proto="$2"
port="$3"
if [ -n "$4" ]; then
error "Too many arguments in FW_TRUSTED_NETS -> $nets"
elif [ -z "$net" ]; then
error "network parameter of FW_TRUSTED_NETS is empty -> $nets"
elif [ -z "$proto" -a -n "$port" ]; then
error "need to specify protocol for port $port in FW_TRUSTED_NETS"
elif check_proto_port "$proto" "$port" "" 'FW_TRUSTED_NETS'; then
for chain in $input_zones; do # trusted networks can be on any interface ...
chain=input_$chain
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-TRUST " -m state --state NEW -s $net $proto $port
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-TRUST " -s $net $proto $port
$IPTABLES -A $chain -j "$ACCEPT" -m state --state NEW,ESTABLISHED,RELATED -s $net $proto $port
done
fi
done
}
# determine port numbers of rpc services and generate a suitable iptables
# parameter fragment
#
# parameters: names of rpc services, e.g. ypbind mountd
rpcservicerules()
{
perl "$SCRIPTSDIR/SuSEfirewall2-rpcinfo" "$@" 2>/dev/null
}
# parameters: REJECT|DROP
reject_or_drop_services()
{
local action="$1"
local var
local services target service proto net port
local iptables zone chain
eval target=\$$action
for zone in $input_zones; do
chain=input_$zone
var="FW_SERVICES_${action}_`cibiz $zone`"
eval services="\"\$$var\""
for service in $services; do
IFS=, eval set -- \$service
net="${1:-0/0}"
proto="$2"
port="$3"
sport="$4"
iptables="$IPTABLES $IP6TABLES"
case "$net" in
*:*) iptables="$IP6TABLES" ;;
[0-9]*.*.*.*) iptables="$IPTABLES" ;;
esac
if [ "$proto" = "_rpc_" ]; then
rpcservicerules $service | while read ARG; do
$LDC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-$action " -m state --state NEW $ARG
$IPTABLES -A $chain -j "$target" $ARG
done
elif check_proto_port "$proto" "$port" "$sport" "$var"; then
for iptables in $iptables; do
$LDA $iptables -A $chain -s $net $proto $port $sport -m state --state NEW ${LOG}"-`rulelog $chain`-$action "
$iptables -A $chain -s $net $proto $port $sport -m state --state NEW -j "$target"
done
fi
done
done
}
accept_services()
{
local var
local services target service proto net
local iptables zone chain
local ipt_recent_update ipt_recent_set ipt_recent_rcheck
for zone in $input_zones; do
chain=input_$zone
var="FW_SERVICES_ACCEPT_`cibiz $zone`"
eval services="\"\$$var\""
for service in $services; do
ipt_recent_update=''
ipt_recent_set=''
ipt_recent_rcheck=''
IFS=, eval set -- \$service
if [ "$#" -lt 1 ]; then
error "too few parameters in $var -> $service"
continue
fi
net="${1:-0/0}"
proto="$2"
port="$3"
sport="$4"
while [ "$#" -gt 4 ]; do
case "$5" in
hitcount=*) ipt_recent_update="$ipt_recent_update --hitcount ${5#*=}"; shift ;;
blockseconds=*) ipt_recent_update="$ipt_recent_update --seconds ${5#*=}"; shift ;;
recentname=*)
ipt_recent_update="$ipt_recent_update --name ${5#*=}"
ipt_recent_set="$ipt_recent_set --name ${5#*=}"
shift
;;
*) error "unknown parameter $5 in $var -> $service"; continue 2 ;;
esac
done
if [ -n "$ipt_recent_update" ]; then
ipt_recent_rcheck="-m recent --rcheck$ipt_recent_update"
ipt_recent_update="-m recent --update$ipt_recent_update --rttl"
ipt_recent_set="-m recent --set$ipt_recent_set"
fi
iptables="$IPTABLES $IP6TABLES"
case "$net" in
*:*) iptables="$IP6TABLES" ;;
[0-9]*.*.*.*) iptables="$IPTABLES" ;;
esac
if [ "$proto" = "_rpc_" ]; then
rpcservicerules $service | while read ARG; do
if [ -n "$ipt_recent_set" ]; then
$LDC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-DROPr " $ARG -m state --state NEW $ipt_recent_rcheck
$IPTABLES -A $chain -j "$DROP" $ARG -m state --state NEW $ipt_recent_update
fi
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC " -m state --state NEW $ARG
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC " $ARG
[ -n "$ipt_recent_set" ] && $IPTABLES -A $chain -j ACCEPT $ARG -m state --state NEW $ipt_recent_set
$IPTABLES -A $chain -j ACCEPT $ARG
done
elif check_proto_port "$proto" "$port" "$sport" "$var"; then
for iptables in $iptables; do
if [ -n "$ipt_recent_set" ]; then
$LDC $iptables -A $chain ${LOG}"-`rulelog $chain`-DROPr " -s $net $proto $port $sport -m state --state NEW $ipt_recent_rcheck
$iptables -A $chain -j "$DROP" -s $net $proto $port $sport -m state --state NEW $ipt_recent_update
fi
$LAC $iptables -A $chain -s $net $proto $port $sport -m state --state NEW ${LOG}"-`rulelog $chain`-ACC "
$LAA $iptables -A $chain -s $net $proto $port $sport ${LOG}"-`rulelog $chain`-ACC "
[ -n "$ipt_recent_set" ] && $iptables -A $chain -s $net $proto $port $sport -j ACCEPT -m state --state NEW $ipt_recent_set
$iptables -A $chain -s $net $proto $port $sport -j ACCEPT
done
fi
done
done
}
allow_tcp_highports()
{
local j chain
for j in $FW_ALLOW_INCOMING_HIGHPORTS_TCP; do
case "$j" in
[Dd][Nn][Ss]) warning "FW_ALLOW_INCOMING_HIGHPORTS_TCP=DNS is no longer supported" ;;
no) ;;
yes)
deprecated 'FW_ALLOW_INCOMING_HIGHPORTS_TCP'
for chain in $input_zones; do
chain=input_$chain
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HiTCP " -p tcp --dport 1024: --syn
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HiTCP " -p tcp --dport 1024:
$IPTABLES -A $chain -j "$ACCEPT" -p tcp --dport 1024:
done
break;
;;
*)
deprecated 'FW_ALLOW_INCOMING_HIGHPORTS_TCP'
for chain in $input_zones; do
chain=input_$chain
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HIGH " -p tcp --sport $j --dport 1024: --syn
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HIGH " -p tcp --sport $j --dport 1024:
$IPTABLES -A $chain -j "$ACCEPT" -p tcp --sport $j --dport 1024:
done
;;
esac
done
}
allow_rpc_services()
{
local zone chain ports
for zone in $input_zones; do
chain=input_$zone
eval ports="\$FW_SERVICES_`cibiz $zone`_RPC"
rpcservicerules $ports | while read ARG; do
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-RPC " -m state --state NEW $ARG
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-RPC " $ARG
$IPTABLES -A $chain -j "$ACCEPT" $ARG
done
done
}
allow_ip_services()
{
local proto zone iptables protos
for zone in $input_zones; do
chain=input_$zone
eval protos="\$FW_SERVICES_`cibiz $zone`_IP"
for iptables in "$IPTABLES" "$IP6TABLES"; do
for proto in $protos; do
$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-IP " -p $proto
$iptables -A $chain -j "$ACCEPT" -p $proto
done
done
done
}
allow_tcp_services()
{
local port zone iptables ports
for zone in $input_zones; do
chain=input_$zone
eval ports="\$FW_SERVICES_`cibiz $zone`_TCP"
for iptables in "$IPTABLES" "$IP6TABLES"; do
for port in $ports; do
$LAC $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-TCP " -p tcp --dport $port --syn
$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-TCP " -p tcp --dport $port
$iptables -A $chain -j "$ACCEPT" -p tcp --dport $port
done
done
done
}
# UDP Stuff
allow_udp_services()
{
local port zone iptables ports
for zone in $input_zones; do
chain=input_$zone
eval ports="\$FW_SERVICES_`cibiz $zone`_UDP"
for iptables in "$IPTABLES" "$IP6TABLES"; do
for port in $ports; do
$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-ACC-UDP " -p udp --dport $port
$iptables -A $chain -j "$ACCEPT" -p udp --dport $port
done
done
done
}
allow_highports_udp()
{
local j chain
# checking "yes" in the loop allows you to log individual services plus
# allowing all
for j in $FW_ALLOW_INCOMING_HIGHPORTS_UDP; do
case "$j" in
[Dd][Nn][Ss])
warning "FW_ALLOW_INCOMING_HIGHPORTS_UDP=DNS is no longer supported"
;;
no) ;;
yes)
deprecated 'FW_ALLOW_INCOMING_HIGHPORTS_UDP'
for chain in $input_zones; do
chain=input_$chain
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HiUDP " -m state --state NEW -p udp --dport 1024:
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HiUDP " -p udp --dport 1024:
$IPTABLES -A $chain -j "$ACCEPT" -m state --state NEW -p udp --dport 1024:
done
break;
;;
*)
deprecated 'FW_ALLOW_INCOMING_HIGHPORTS_UDP'
for chain in $input_zones; do
chain=input_$chain
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HiUDP " -m state --state NEW -p udp --sport $j --dport 1024:
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-HiUDP " -p udp --sport $j --dport 1024:
$IPTABLES -A $chain -j "$ACCEPT" -m state --state NEW -p udp --sport $j --dport 1024:
done
;;
esac
done
}
# redirect packets from one port to another, opens ports in input_*
redirect_rules()
{
local chain nets net1 net2 proto port1 port2
local redirectinstalled
for nets in $FW_REDIRECT; do
IFS=, eval set -- \$nets
net1="$1"
net2="$2"
proto="$3"
port1="$4"
port2="$5"
if [ -n "$6" ]; then
error "Too many arguments in FW_REDIRECT -> $nets"
elif [ -z "$net1" -o -z "$net2" -o -z "$proto" -o -z "$port1" -o -z "$port2" ]; then
error "Missing parameter in FW_REDIRECT -> $nets"
elif [ "$proto" != tcp -a "$proto" != udp ]; then
error "FW_REDIRECT supports only tcp and udp -> $nets"
else
net1=${net1/\!/\! }
net2=${net2/\!/\! }
$IPTABLES -A PREROUTING -t mangle -j MARK -p $proto -s $net1 -d $net2 --dport $port1 --set-mark $mark_redir
$IPTABLES -A PREROUTING -t nat -j REDIRECT -p $proto -s $net1 -d $net2 --dport $port1 --to-ports $port2
redirectinstalled=1
fi
done
if [ -n "$redirectinstalled" ]; then
for chain in $input_zones; do
chain=input_$chain
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REDIR " -m mark --mark $mark_redir -m state --state NEW
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REDIR " -m mark --mark $mark_redir -m state --state NEW,ESTABLISHED,RELATED
$IPTABLES -A $chain -j "$ACCEPT" -m state --state NEW,ESTABLISHED,RELATED -m mark --mark $mark_redir
done
fi
}
allow_class_routing()
{
local chain iface devs zone iptables
if [ "$FW_ALLOW_CLASS_ROUTING" = 'yes' ]; then
FW_ALLOW_CLASS_ROUTING="$forward_zones"
elif [ "$FW_ALLOW_CLASS_ROUTING" = 'no' ]; then
return
fi
# assuming that only traffic from $zone interface enter the
# forward_$zone chain anyways, we don't need the -i parameter
for zone in $FW_ALLOW_CLASS_ROUTING; do
eval devs="\$FW_DEV_$zone"
chain=forward_$zone
for iface in $devs; do
for iptables in "$IPTABLES" "$IP6TABLES"; do
$LAA $iptables -A $chain $LOG"-`rulelog $chain`-ACC-CLASS " -o $iface
$iptables -A $chain -j "$ACCEPT" -o $iface
done
done
done
}
allow_related_forward_icmp()
{
local chain itype
for chain in $forward_zones; do
chain=forward_$chain
for itype in $safe_icmp_replies; do
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-FWD-RELA" -m state --state ESTABLISHED,RELATED -p icmp --icmp-type $itype
$IPTABLES -A $chain -j "$ACCEPT" -m state --state ESTABLISHED,RELATED -p icmp --icmp-type $itype
done
for itype in $safe_icmpv6_replies; do
$LAA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-FWD-RELA " -m state --state ESTABLISHED,RELATED -p icmpv6 --icmpv6-type $itype
$IP6TABLES -A $chain -j "$ACCEPT" -m state --state ESTABLISHED,RELATED -p icmpv6 --icmpv6-type $itype
done
done
}
# <source network>,<destination network>[,protocol[,port[,flags]]]
forwarding_rules()
{
local nets net1 net2 flags more_args_in more_args_out chain iptables var services
local target="$1"
if [ "$target" = ACCEPT ]; then
var="FW_FORWARD"
else
var="FW_FORWARD_${target}"
fi
eval services="\"\$$var\""
for nets in $services; do
IFS=, eval set -- \$nets
net1="$1"
net2="$2"
proto="$3"
port="$4"
flags="$5"
rport=""
more_args_in=
more_args_out=
case "$flags" in
"") ;;
ipsec)
more_args_in="$IPSEC_INPUT_MATCH"
more_args_out="$IPSEC_OUTPUT_MATCH"
;;
*)
echo "Error: unsupported flag in FW_FORWARD: $flags"
net1=""
;;
esac
if ! check_proto_port "$proto" "$port" '' "FW_FORWARD"; then
continue
fi
if [ -n "$net1" -a -n "$net2" ]; then
if [ "${net1//:/_}" != "$net1" -o "${net2//:/_}" != "$net2" ]; then
iptables=$IP6TABLES
else
iptables=$IPTABLES
fi
for chain in $forward_zones; do
chain=forward_$chain
$LAC $iptables -A $chain ${LOG}"-`rulelog $chain`-${target:0:3}-FORW " -s $net1 -d $net2 $proto $port -m state --state NEW $more_args_in
$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-${target:0:3}-FORW " -s $net1 -d $net2 $proto $port $more_args_in
$iptables -A $chain -j "$target" -m state --state NEW,ESTABLISHED,RELATED -s $net1 -d $net2 $proto $port $more_args_in
$iptables -A $chain -j "$target" -m state --state ESTABLISHED,RELATED -s $net2 -d $net1 $proto $rport $more_args_in
if [ -n "$more_args_out" ]; then
$LAC $iptables -A $chain ${LOG}"-`rulelog $chain`-${target:0:3}-FORW " -s $net1 -d $net2 $proto $port -m state --state NEW $more_args_out
$LAA $iptables -A $chain ${LOG}"-`rulelog $chain`-${target:0:3}-FORW " -s $net1 -d $net2 $proto $port $more_args_out
$iptables -A $chain -j "$target" -m state --state NEW,ESTABLISHED,RELATED -s $net1 -d $net2 $proto $port $more_args_out
$iptables -A $chain -j "$target" -m state --state ESTABLISHED,RELATED -s $net2 -d $net1 $proto $rport $more_args_out
fi
done
else
error "too few parameters in $var -> $nets"
fi
done
}
masquerading_rules()
{
local nets net1 net2 proto port dev snet2 sport
local szone dzone sdev sdevs
local z d
local var='FW_NOMASQ_NETS'
for nets in $FW_NOMASQ_NETS -- $FW_MASQ_NETS; do
if [ "$nets" = '--' ]; then # cheap hack
var='FW_MASQ_NETS'
continue
fi
IFS=, eval set -- \$nets
net1="$1"
net2="$2"
proto="$3"
port="$4"
rport=""
if [ -n "$5" ]; then
error "Too many arguments in $var -> $nets"
elif [ -z "$net1" ]; then
error "source network must not be empty in $var -> $nets"
elif check_proto_port "$proto" "$port" '' "$var"; then
net1=${net1/\!/\! }
net2=${net2/\!/\! }
snet2=""
if [ -n "$net2" ]; then
snet2="-s $net2"
net2="-d $net2"
fi
for dev in $FW_MASQ_DEV; do
d=${dev//[^A-Za-z0-9]/_}
eval z=\${iface_$d}
if [ "$var" = "FW_NOMASQ_NETS" ]; then # cheap hack
$IPTABLES -A POSTROUTING -j ACCEPT -t nat -s $net1 $net2 $proto $port -o $dev
continue
fi
for dzone in $forward_zones; do
dzone=forward_$dzone
for szone in $forward_zones; do
[ "$z" = "$szone" ] && continue
eval sdevs="\$FW_DEV_$szone"
for sdev in $sdevs; do
[ "$sdev" = "$dev" ] && continue
if [ "forward_$z" != "$dzone" ]; then
#echo "$dzone: $sdev ($szone) -> $dev ($z)"
$LAA $IPTABLES -A $dzone ${LOG}"-`rulelog $dzone`-ACC-MASQ " -s $net1 $net2 $proto $port -i $sdev -o $dev
$IPTABLES -A $dzone -j "$ACCEPT" -m state --state NEW,ESTABLISHED,RELATED -s $net1 $net2 $proto $port -i $sdev -o $dev
else
#echo "$dzone: $sdev ($szone) <- $dev ($z)"
# we need to allow the replies as well
$LAA $IPTABLES -A $dzone -d $net1 $snet2 $proto $rport -i $dev -o $sdev ${LOG}"-`rulelog $dzone`-ACC-MASQ " -m state --state ESTABLISHED,RELATED
$IPTABLES -A $dzone -d $net1 $snet2 $proto $rport -i $dev -o $sdev -j "$ACCEPT" -m state --state ESTABLISHED,RELATED
fi
done
done
done
$IPTABLES -A POSTROUTING -j MASQUERADE -t nat -s $net1 $net2 $proto $port -o $dev
done
fi
done
}
# <source network>,<ip to forward to>,<protocol>,<port>[,redirect port,[destination ip]]
forward_masquerading_rules()
{
local nets net1 net2 proto port1 port2 lip
for nets in $FW_FORWARD_MASQ; do
IFS=, eval set -- \$nets
net1="$1"
net2="$2"
proto="$3"
port1="$4"
port2="$5"
lip="$6"
case "$net2" in
*/*|'')
error "target must be a single host in FW_FORWARD_MASQ -> $nets"
continue
;;
esac
if [ -n "$7" ]; then
error "too many arguments in FW_FORWARD_MASQ -> $nets"
elif [ -z "$net1" ]; then
error "source network must not be empty in FW_FORWARD_MASQ -> $nets"
elif [ "$proto" != tcp -a "$proto" != udp ]; then
error "The protocol with FW_FORWARD_MASQ must be tcp or udp -> $nets"
elif [ -z "$port1" ]; then
error "Port missing in FW_FORWARD_MASQ -> $nets"
else
net1=${net1/\!/\! }
net2=${net2/\!/\! }
proto="-p $proto"
test -z "$port2" && port2="$port1"
port1="--dport $port1"
dport2="--dport $port2"
port2=":${port2/:/-}"
test -n "$lip" && lip="-d $lip"
for dev in $FW_MASQ_DEV; do
$IPTABLES -A PREROUTING -j DNAT -t nat $proto -s $net1 $lip $port1 --to-destination ${net2}${port2} -i $dev
# to install minimal rule set we'd need to check if
# $net1 is covered by $FW_MASQ_NETS. Not feasible in
# bash code so just check for 0/0
if [ "$FW_MASQ_NETS" != "0/0" ]; then
$IPTABLES -A POSTROUTING -j MASQUERADE -t nat -s $net1 -d $net2 $proto $dport2 -o $dev
fi
done
for chain in $forward_zones; do
chain=forward_$chain
$LAC $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REVMASQ " $proto -s $net1 -d $net2 $dport2 -m state --state NEW
$LAA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-ACC-REVMASQ " $proto -s $net1 -d $net2 $dport2
$IPTABLES -A $chain -j "$ACCEPT" $proto -s $net1 -d $net2 $dport2
$IPTABLES -A $chain -j "$ACCEPT" $proto -d $net1 -s $net2 -m state --state ESTABLISHED,RELATED
done
fi
done
}
# Special Logging + Deny #
drop_all()
{
local chain
local zone
local drop
local chainprefix='input_'
for zone in $input_zones '--' $forward_zones; do
if [ "$zone" = '--' ]; then
[ "$FW_ROUTE" != 'yes' ] && break
chainprefix='forward_'
continue
fi
chain="$chainprefix$zone"
eval drop="\$FW_REJECT_`cibiz $zone`"
if [ "$drop" = "yes" ]; then
drop="$REJECT"
else
drop="$DROP"
fi
# log and drop multicast packets separately to not flood
# other log targets (#155326, #538053)
$LDA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-DROP-DEFLT " -m pkttype --pkt-type multicast
$IPTABLES -A $chain -j "$DROP" -m pkttype --pkt-type multicast
eval local ignore="\$FW_IGNORE_FW_BROADCAST_`cibiz $zone`"
if [ "$ignore" != 'yes' ]; then
$LDA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-DROP-DEFLT " -m pkttype --pkt-type broadcast
fi
$IPTABLES -A $chain -j "$DROP" -m pkttype --pkt-type broadcast
# some packet types are considered critical
if [ -z "$LDC" ]; then
local log=${LOG}"-`rulelog $chain`-DROP-DEFLT"
$IPTABLES -A $chain $log" " -p tcp --syn
$IP6TABLES -A $chain $log" " -p tcp --syn
$IPTABLES -A $chain $log" " -p icmp
$IP6TABLES -A $chain $log" " -p icmpv6
$IPTABLES -A $chain $log" " -p udp -m state --state NEW
$IP6TABLES -A $chain $log" " -p udp -m state --state NEW
fi
# log anything else
$LDA $IPTABLES -A $chain ${LOG}"-`rulelog $chain`-DROP-DEFLT "
$IPTABLES -A $chain -j "$drop"
$LDA $IP6TABLES -A $chain ${LOG}"-`rulelog $chain`-DROP-DEFLT "
$IP6TABLES -A $chain -j "$drop"
done
}
############################################
# #
# Now we begin to set the filter rules ... #
# #
############################################
if [ "$ACTION" = "showlog" ]; then
exec perl "$SCRIPTSDIR/SuSEfirewall2-showlog" "$@"
die 1 "failed to execute $SCRIPTSDIR/SuSEfirewall2-showlog"
fi
###############
parse_logging
setlock
if [ "$ACTION" = "bootlock" -o "$ACTION" = "bootunlock" ]; then
# lock file already set in setlock
die 0
fi
if [ "$ACTION" = "basic" ]; then
# Reset the filter rules
set_basic_rules
$IPTABLES -A INPUT -j "$ACCEPT" -p icmp --icmp-type echo-request
# log incoming tcp connection requests. also logging udp etc would just flood the log
$IPTABLES -A INPUT -p tcp -m state --state NEW $LOG"-IN-DROP-NEW-CONNECT "
# reject anything else
$IPTABLES -A INPUT -j "$DROP"
[ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch
die 0 "Firewall rules successfully set in simple mode"
fi
if [ "$MODE" = "test" ]; then
DROP="ACCEPT"
REJECT="ACCEPT"
FW_LOG_DROP_ALL=yes
FW_LOG_DROP_CRIT=yes
FW_LOG_ACCEPT_ALL=no
FW_LOG_ACCEPT_CRIT=no
warning "SuSEfirewall2 is running in TEST MODE, no packet filtering is done!"
fi
if [ "$ACTION" = "stop" ]; then
if [ "$FW_STOP_KEEP_ROUTING_STATE" != "yes" ]; then
setproc 0 /proc/sys/net/ipv4/ip_forward
fi
# Do we have a kernel with IPv6 enabled?
$IP6TABLES_BIN -nvL >/dev/null 2>&1 || IP6TABLES=:
reset_rules
clear_qdisc_settings
handle_initscripts
[ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch
die 0 "Firewall rules unloaded."
fi
if [ "$ACTION" = "close" ]; then
set_basic_rules
setproc 0 /proc/sys/net/ipv4/ip_forward
[ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch
die 0 "Firewall rules set to CLOSE."
fi
if [ "$ACTION" = "status" ]; then
if [ "$UID" != 0 ]; then
die 2 "You need to be root to check the status"
fi
if ! is_running; then
die 1 "SuSEfirewall2 not active"
fi
[ -z "$quiet" ] || die 0
# yes we need cat here, while read ... does no work :-(
for i in `sort < /proc/net/ip_tables_names`; do
echo "### iptables $i ###"
$IPTABLES -t $i -vnL
echo ""
done
if [ "$IP6TABLES" != ":" ]; then
for i in `sort /proc/net/ip6_tables_names`; do
echo "### ip6tables $i ###"
$IP6TABLES -t $i -vnL
echo ""
done
fi
die 0
fi
if [ "$ACTION" = "open" ]; then
OPENHELPER="$SCRIPTSDIR/SuSEfirewall2-open"
exec perl -w $OPENHELPER "$@"
die 1 "failed to execute $OPENHELPER"
fi
### main mode ###
message "Setting up rules from $FWCONFIG ..."
parse_zones
parse_interfaces
check_interfaces_unique
autodetect_interfaces
write_status
process_masq_dev
load_customrules
check_interfaces
verify_parameters
#verify_masq_nets
parse_ipsec
remove_unused_zones
[ "$FW_ROUTE" = 'yes' ] && forward_zones="$all_zones"
input_zones="$all_zones"
saved_input_zones="$input_zones" # need that for fork_to_chains
parse_configurations
# Set default rules + flush
set_basic_rules
switch_on_ip_forwarding
set_proc_stuff
create_chains
# HOOK
fw_custom_after_chain_creation
# HOOK, deprecated
fw_custom_before_antispoofing
# HOOK, deprecated
fw_custom_after_antispoofing
protect_from_internal
check_convert_old_broadcast
drop_broadcast
allow_ipsec
allow_icmp
allow_forward_icmp_echo
# HOOK
fw_custom_before_port_handling
process_trusted_nets
allow_related
allow_ip_services
allow_tcp_services
allow_udp_services
allow_rpc_services
accept_services
reject_or_drop_services DROP
reject_or_drop_services REJECT
allow_tcp_highports
allow_highports_udp
# HOOK
fw_custom_before_masq
redirect_rules
if [ "$FW_ROUTE" = yes ]; then
allow_related_forward_icmp
allow_class_routing
forwarding_rules DROP
forwarding_rules REJECT
forwarding_rules ACCEPT
if [ "$FW_MASQUERADE" = yes ]; then
masquerading_rules
forward_masquerading_rules
fi
fi
# HOOK
fw_custom_before_denyall
drop_all
fork_to_chains
finish_chains
# HTB settings
if [ -n "$FW_HTB_TUNE_DEV" ]; then
need qdisc
do_qdisc_settings
fi
[ -n "$USE_IPTABLES_BATCH" ] && commit_iptables_batch
handle_initscripts
# END #
die 0 "Firewall rules successfully set"
# vim: sw=4
ACC SHELL 2018