2006-08-27 22:22:03 +02:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
2007-07-09 16:01:07 +02:00
|
|
|
# Shorewall 4.0 -- /usr/share/shorewall/lib.accounting
|
2006-08-27 22:22:03 +02:00
|
|
|
#
|
2007-09-08 18:09:51 +02:00
|
|
|
# This program is under GPL [http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt]
|
2006-08-27 22:22:03 +02:00
|
|
|
#
|
2007-01-12 23:06:29 +01:00
|
|
|
# (c) 1999,2000,2001,2002,2003,2004,2005,2006,2007 - Tom Eastep (teastep@shorewall.net)
|
2006-08-27 22:22:03 +02:00
|
|
|
#
|
|
|
|
# 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
|
2007-09-08 18:09:51 +02:00
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2006-09-09 17:03:44 +02:00
|
|
|
#
|
|
|
|
# This library is loaded by /usr/share/shorewall/compiler when the accounting file is
|
|
|
|
# non-empty.
|
|
|
|
#
|
2006-08-27 22:22:03 +02:00
|
|
|
|
|
|
|
#
|
|
|
|
# Process a record from the accounting file
|
|
|
|
#
|
|
|
|
process_accounting_rule() {
|
|
|
|
rule=
|
|
|
|
rule2=
|
|
|
|
jumpchain=
|
|
|
|
user1=
|
|
|
|
|
|
|
|
accounting_error() {
|
2007-05-01 23:08:33 +02:00
|
|
|
error_message "WARNING: Invalid Accounting rule" $action $chain $source $dest $proto $port $sport $user $mark
|
2006-08-27 22:22:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
accounting_interface_error() {
|
2007-05-01 23:08:33 +02:00
|
|
|
error_message "WARNING: Unknown interface $1 in " $action $chain $source $dest $proto $port $sport $user $mark
|
2006-08-27 22:22:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
accounting_interface_verify() {
|
|
|
|
verify_interface $1 || accounting_interface_error $1
|
|
|
|
}
|
|
|
|
|
|
|
|
jump_to_chain() {
|
|
|
|
if ! havechain $jumpchain; then
|
|
|
|
if ! createchain2 $jumpchain No; then
|
|
|
|
accounting_error
|
|
|
|
return 2
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
rule="$rule -j $jumpchain"
|
|
|
|
}
|
|
|
|
|
|
|
|
do_ipp2p() {
|
|
|
|
[ -n "$IPP2P_MATCH" ] || fatal_error "Your kernel and/or iptables does not have IPP2P match support"
|
|
|
|
case $proto in
|
|
|
|
*:*)
|
|
|
|
proto=${proto#*:}
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
proto=tcp
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
rule="$rule -p $proto -m ipp2p --${port:-ipp2p}"
|
|
|
|
}
|
|
|
|
|
|
|
|
case $source in
|
|
|
|
*:*)
|
|
|
|
accounting_interface_verify ${source%:*}
|
|
|
|
rule="$(source_ip_range ${source#*:}) $(match_source_dev ${source%:*})"
|
|
|
|
;;
|
|
|
|
*.*.*.*|+*|!+*)
|
|
|
|
rule="$(source_ip_range $source)"
|
|
|
|
;;
|
|
|
|
-|all|any)
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
if [ -n "$source" ]; then
|
|
|
|
accounting_interface_verify $source
|
|
|
|
rule="$(match_source_dev $source)"
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
[ -n "$dest" ] && case $dest in
|
|
|
|
*:*)
|
|
|
|
accounting_interface_verify ${dest%:*}
|
|
|
|
rule="$rule $(dest_ip_range ${dest#*:}) $(match_dest_dev ${dest%:*})"
|
|
|
|
;;
|
|
|
|
*.*.*.*|+*|!*)
|
|
|
|
rule="$rule $(dest_ip_range $dest)"
|
|
|
|
;;
|
|
|
|
-|all|any)
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
accounting_interface_verify $dest
|
|
|
|
rule="$rule $(match_dest_dev $dest)"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
[ -n "$proto" ] && case $proto in
|
|
|
|
-|any|all)
|
|
|
|
;;
|
|
|
|
ipp2p|IPP2P|ipp2p:*|IPP2P:*)
|
|
|
|
do_ipp2p
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
rule="$rule -p $proto"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
multiport=
|
|
|
|
|
|
|
|
[ -n "$port" ] && case $port in
|
|
|
|
-|any|all)
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
if [ -n "$MULTIPORT" ]; then
|
|
|
|
rule="$rule -m multiport --dports $port"
|
|
|
|
multiport=Yes
|
|
|
|
else
|
|
|
|
rule="$rule --dport $port"
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
[ -n "$sport" ] && case $sport in
|
|
|
|
-|any|all)
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
if [ -n "$MULTIPORT" ]; then
|
|
|
|
[ -n "$multiport" ] && rule="$rule --sports $sport" || rule="$rule -m multiport --sports $sport"
|
|
|
|
else
|
|
|
|
rule="$rule --sport $sport"
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
[ -n "$user" ] && case $user in
|
|
|
|
-|any|all)
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
[ "$chain" != OUTPUT ] && \
|
|
|
|
fatal_error "Invalid use of a user/group: chain is not OUTPUT but $chain"
|
|
|
|
rule="$rule -m owner"
|
|
|
|
user1="$user"
|
|
|
|
|
|
|
|
case "$user" in
|
|
|
|
!*+*)
|
|
|
|
if [ -n "${user#*+}" ]; then
|
|
|
|
rule="$rule ! --cmd-owner ${user#*+} "
|
|
|
|
fi
|
|
|
|
user1=${user%+*}
|
|
|
|
;;
|
|
|
|
*+*)
|
|
|
|
if [ -n "${user#*+}" ]; then
|
|
|
|
rule="$rule --cmd-owner ${user#*+} "
|
|
|
|
fi
|
|
|
|
user1=${user%+*}
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
case "$user1" in
|
|
|
|
!*:*)
|
|
|
|
if [ "$user1" != "!:" ]; then
|
|
|
|
temp="${user1#!}"
|
|
|
|
temp="${temp%:*}"
|
|
|
|
[ -n "$temp" ] && rule="$rule ! --uid-owner $temp "
|
|
|
|
temp="${user1#*:}"
|
|
|
|
[ -n "$temp" ] && rule="$rule ! --gid-owner $temp "
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
*:*)
|
|
|
|
if [ "$user1" != ":" ]; then
|
|
|
|
temp="${user1%:*}"
|
|
|
|
[ -n "$temp" ] && rule="$rule --uid-owner $temp "
|
|
|
|
temp="${user1#*:}"
|
|
|
|
[ -n "$temp" ] && rule="$rule --gid-owner $temp "
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
!*)
|
|
|
|
[ "$user1" != "!" ] && rule="$rule ! --uid-owner ${user1#!} "
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
[ -n "$user1" ] && rule="$rule --uid-owner $user1 "
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2007-05-01 23:08:33 +02:00
|
|
|
[ -n "$mark" ] && case $mark in
|
|
|
|
-|any|all)
|
|
|
|
mark=
|
|
|
|
;;
|
|
|
|
!*)
|
|
|
|
rule="$rule -m mark ! --mark ${mark#*!}"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
rule="$rule -m mark --mark $mark"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2006-08-27 22:22:03 +02:00
|
|
|
case $action in
|
|
|
|
COUNT)
|
|
|
|
;;
|
|
|
|
DONE)
|
|
|
|
rule="$rule -j RETURN"
|
|
|
|
;;
|
|
|
|
*:COUNT)
|
|
|
|
rule2="$rule"
|
|
|
|
jumpchain=${action%:*}
|
|
|
|
jump_to_chain || return
|
|
|
|
;;
|
|
|
|
JUMP:*)
|
|
|
|
jumpchain=${action#*:}
|
|
|
|
jump_to_chain || return
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
jumpchain=$action
|
|
|
|
jump_to_chain || return
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
[ "x${chain:=accounting}" = "x-" ] && chain=accounting
|
|
|
|
|
|
|
|
ensurechain1 $chain
|
|
|
|
|
|
|
|
if do_iptables -A $chain $(fix_bang $rule) ; then
|
|
|
|
[ -n "$rule2" ] && run_iptables2 -A $jumpchain $rule2
|
|
|
|
progress_message " Accounting rule \"$action $chain $source $dest $proto $port $sport $user\" $DONE"
|
|
|
|
save_progress_message_short " Accounting rule \\\"$action $chain $source $dest $proto $port $sport $user\\\" Added"
|
|
|
|
else
|
|
|
|
accounting_error
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Set up Accounting
|
|
|
|
#
|
|
|
|
setup_accounting() # $1 = Name of accounting file
|
|
|
|
{
|
|
|
|
|
|
|
|
progress_message2 "$DOING Accounting..."
|
|
|
|
|
|
|
|
save_progress_message "Setting up Accounting..."
|
|
|
|
|
2007-05-01 23:08:33 +02:00
|
|
|
while read action chain source dest proto port sport user mark ; do
|
2006-08-27 22:22:03 +02:00
|
|
|
process_accounting_rule
|
|
|
|
done < $TMP_DIR/accounting
|
|
|
|
|
|
|
|
if havechain accounting; then
|
|
|
|
for chain in INPUT FORWARD OUTPUT; do
|
|
|
|
run_iptables -I $chain -j accounting
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
}
|
|
|
|
|