Rate Limiting in Rules - Part 1

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@705 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2003-08-13 17:07:05 +00:00
parent 552d738579
commit 88dbd252af
2 changed files with 83 additions and 49 deletions

View File

@ -2042,6 +2042,7 @@ refresh_tc() {
# by this function # by this function
# cport = Source Port Specification # cport = Source Port Specification
# multiport = String to invoke multiport match if appropriate # multiport = String to invoke multiport match if appropriate
# ratelimit = Optional rate limiting clause
# #
add_nat_rule() { add_nat_rule() {
local chain local chain
@ -2125,7 +2126,7 @@ add_nat_rule() {
log_rule $loglevel $chain $logtarget -t nat log_rule $loglevel $chain $logtarget -t nat
fi fi
addnatrule $chain $proto -j $target1 # Protocol is necessary for port redirection addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection
else else
for adr in `separate_list $addr`; do for adr in `separate_list $addr`; do
if [ -n "$loglevel" ]; then if [ -n "$loglevel" ]; then
@ -2133,7 +2134,7 @@ add_nat_rule() {
`fix_bang $proto $cli $sports -d $adr $multiport $dports` `fix_bang $proto $cli $sports -d $adr $multiport $dports`
fi fi
run_iptables2 -t nat -A OUTPUT $proto $sports -d $adr $multiport $dports -j $target1 run_iptables2 -t nat -A OUTPUT $ratelimit $proto $sports -d $adr $multiport $dports -j $target1
done done
fi fi
else else
@ -2160,19 +2161,19 @@ add_nat_rule() {
done done
if [ -n "$loglevel" ]; then if [ -n "$loglevel" ]; then
log_rule $loglevel $chain $logtarget -t nat log_rule $loglevel $chain $logtarget $ratelimit -t nat
fi fi
addnatrule $chain $proto -j $target1 # Protocol is necessary for port redirection addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection
else else
for adr in `separate_list $addr`; do for adr in `separate_list $addr`; do
if [ -n "$loglevel" ]; then if [ -n "$loglevel" ]; then
ensurenatchain $chain ensurenatchain $chain
log_rule $loglevel $chain $logtarget -t nat \ log_rule $loglevel $chain $logtarget $ratelimit -t nat \
`fix_bang $proto $cli $sports -d $adr $multiport $dports` `fix_bang $proto $cli $sports -d $adr $multiport $dports`
fi fi
addnatrule $chain $proto $cli $sports \ addnatrule $chain $proto $ratelimit $cli $sports \
-d $adr $multiport $dports -j $target1 -d $adr $multiport $dports -j $target1
done done
fi fi
@ -2207,7 +2208,8 @@ add_nat_rule() {
fi fi
fi fi
[ "x$addr" = "x0.0.0.0/0" ] && addr= [ "x$addr" = "x0.0.0.0/0" ] && addr=
ratelimit=
} }
# #
@ -2225,6 +2227,7 @@ add_nat_rule() {
# multioption = String to invoke multiport match if appropriate # multioption = String to invoke multiport match if appropriate
# servport = Port the server listens on # servport = Port the server listens on
# chain = The canonical chain for this rule # chain = The canonical chain for this rule
# ratelimit = Optional rate limiting clause
# #
add_a_rule() add_a_rule()
{ {
@ -2371,32 +2374,32 @@ add_a_rule()
if [ -n "$addr" -a -n "$CONNTRACK_MATCH" ]; then if [ -n "$addr" -a -n "$CONNTRACK_MATCH" ]; then
for adr in `separate_list $addr`; do for adr in `separate_list $addr`; do
if [ -n "$loglevel" -a -z "$natrule" ]; then if [ -n "$loglevel" -a -z "$natrule" ]; then
log_rule $loglevel $chain $logtarget -m conntrack --ctorigdst $adr \ log_rule $loglevel $chain $logtarget $ratelimit -m conntrack --ctorigdst $adr \
`fix_bang $proto $sports $multiport $state $cli -d $srv $dports` `fix_bang $proto $sports $multiport $state $cli -d $srv $dports`
fi fi
run_iptables2 -A $chain $proto $multiport $state $cli $sports \ run_iptables2 -A $chain $proto $ratelimit $multiport $state $cli $sports \
-d $srv $dports -m conntrack --ctorigdst $adr -j $target -d $srv $dports -m conntrack --ctorigdst $adr -j $target
done done
else else
if [ -n "$loglevel" -a -z "$natrule" ]; then if [ -n "$loglevel" -a -z "$natrule" ]; then
log_rule $loglevel $chain $logtarget \ log_rule $loglevel $chain $logtarget $ratelimit \
`fix_bang $proto $sports $multiport $state $cli -d $srv $dports` `fix_bang $proto $sports $multiport $state $cli -d $srv $dports`
fi fi
run_iptables2 -A $chain $proto $multiport $state $cli $sports \ run_iptables2 -A $chain $proto $multiport $state $cli $sports \
-d $srv $dports -j $target -d $srv $dports $ratelimit -j $target
fi fi
done done
done done
else else
if [ -n "$loglevel" -a -z "$natrule" ]; then if [ -n "$loglevel" -a -z "$natrule" ]; then
log_rule $loglevel $chain $logtarget \ log_rule $loglevel $chain $logtarget $ratelimit \
`fix_bang $proto $sports $multiport $state $cli $dports` `fix_bang $proto $sports $multiport $state $cli $dports`
fi fi
run_iptables2 -A $chain $proto $multiport $state $cli $sports \ run_iptables2 -A $chain $proto $multiport $state $cli $sports \
$dports -j $target $dports $ratelimit -j $target
fi fi
fi fi
fi fi
@ -2410,13 +2413,13 @@ add_a_rule()
if [ $command != check ]; then if [ $command != check ]; then
if [ -n "$loglevel" ]; then if [ -n "$loglevel" ]; then
log_rule $loglevel $chain $logtarget \ log_rule $loglevel $chain $logtarget $ratelimit \
`fix_bang $proto $multiport $dest_interface $state $cli $sports $dports` `fix_bang $proto $multiport $dest_interface $state $cli $sports $dports`
fi fi
if [ $logtarget != LOG ]; then if [ $logtarget != LOG ]; then
run_iptables2 -A $chain $proto $multiport $dest_interface $state \ run_iptables2 -A $chain $proto $multiport $dest_interface $state \
$cli $sports $dports -j $target $cli $sports $dports $ratelimit -j $target
fi fi
fi fi
fi fi
@ -2442,7 +2445,19 @@ process_rule() # $1 = target
local address="$7" local address="$7"
local rule="`echo $target $clients $servers $protocol $ports $cports $address`" local rule="`echo $target $clients $servers $protocol $ports $cports $address`"
# Function Body -- isolate log level # Function Body - isolate rate limit
if [ "$target" = "${target%<*}" ]; then
ratelimit=
else
ratelimit="${target#*<}"
ratelimit="${ratelimit%>*}"
target="${target%<*}${target#*>}"
expandv ratelimit
ratelimit="-m limit --limit ${ratelimit%:*} --limit-burst ${ratelimit#*:}"
fi
# Isolate log level
if [ "$target" = "${target%:*}" ]; then if [ "$target" = "${target%:*}" ]; then
loglevel= loglevel=
@ -2451,7 +2466,7 @@ process_rule() # $1 = target
target="${target%:*}" target="${target%:*}"
expandv loglevel expandv loglevel
fi fi
logtarget="$target" logtarget="$target"
dnat_only= dnat_only=
@ -2465,36 +2480,42 @@ process_rule() # $1 = target
[ "x$address" = "x-" ] && address= [ "x$address" = "x-" ] && address=
case $target in case $target in
DNAT) DNAT)
target=ACCEPT target=ACCEPT
address=${address:=detect} address=${address:=detect}
;; ;;
DNAT-) DNAT-)
target=ACCEPT target=ACCEPT
address=${address:=detect} address=${address:=detect}
dnat_only=Yes dnat_only=Yes
logtarget=DNAT logtarget=DNAT
;; ;;
REDIRECT) REDIRECT)
target=ACCEPT target=ACCEPT
address=${address:=all} address=${address:=all}
if [ "x-" = "x$servers" ]; then if [ "x-" = "x$servers" ]; then
servers=$FW servers=$FW
else else
servers="$FW::$servers" servers="$FW::$servers"
fi fi
;; ;;
REDIRECT-) REDIRECT-)
target=ACCEPT target=ACCEPT
logtarget=REDIRECT logtarget=REDIRECT
dnat_only=Yes dnat_only=Yes
address=${address:=all} address=${address:=all}
if [ "x-" = "x$servers" ]; then if [ "x-" = "x$servers" ]; then
servers=$FW servers=$FW
else else
servers="$FW::$servers" servers="$FW::$servers"
fi fi
;; ;;
ACCEPT)
;;
*)
[ -n "$ratelimit" ] && fatal_error \
"Rate Limiting only available with ACCEPT, DNAT[-] and REDIRECT[-]"
;;
esac esac
# Parse and validate source # Parse and validate source
@ -2690,8 +2711,8 @@ process_rules() # $1 = name of rules file
} }
while read xtarget xclients xservers xprotocol xports xcports xaddress; do while read xtarget xclients xservers xprotocol xports xcports xaddress; do
case "${xtarget%:*}" in temp="${xtarget%:*}"
case "${temp%<*}" in
ACCEPT|DROP|REJECT|DNAT|DNAT-|REDIRECT|REDIRECT-|LOG|CONTINUE) ACCEPT|DROP|REJECT|DNAT|DNAT-|REDIRECT|REDIRECT-|LOG|CONTINUE)
expandv xclients xservers xprotocol xports xcports xaddress expandv xclients xservers xprotocol xports xcports xaddress

View File

@ -56,6 +56,19 @@
# to a separate log through use of ulogd # to a separate log through use of ulogd
# (http://www.gnumonks.org/projects/ulogd). # (http://www.gnumonks.org/projects/ulogd).
# #
# Finally, you may rate-limit the rule by optionally
# ending the ACTION with
#
# < <rate>/<interval>:<burst> >
#
# where <rate> is the number of connections per
# <interval> ("sec" or "min") and <burst> is the
# largest burst permitted. Rate limiting may only be
# used with ACCEPT, DNAT and REDIRECT and there may be
# no whitespace embedded in the specification.
#
# Example: <10/sec:20>
#
# SOURCE Source hosts to which the rule applies. May be a zone # SOURCE Source hosts to which the rule applies. May be a zone
# defined in /etc/shorewall/zones, $FW to indicate the # defined in /etc/shorewall/zones, $FW to indicate the
# firewall itself, or "all" If the ACTION is DNAT or # firewall itself, or "all" If the ACTION is DNAT or