Reorganize rules file processing

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@84 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2002-06-19 21:51:36 +00:00
parent 98d57a3733
commit a9d40f34b3

View File

@ -1225,8 +1225,8 @@ setup_nat() {
# Folks feel uneasy if they don't see all of the same # Folks feel uneasy if they don't see all of the same
# decoration on these IP addresses that they see when their # decoration on these IP addresses that they see when their
# distro's net config tool adds them. In an attempt to reduce # distro's net config tool adds them. In an attempt to reduce
# the anxiety level, we'll introduce the following code to set # the anxiety level, we have the following code which sets
# the VLSM and BRD just like the primary address # the VLSM and BRD from the primary address
# #
# Get all of the lines that contain inet addresses with broadcast # Get all of the lines that contain inet addresses with broadcast
# #
@ -1374,36 +1374,37 @@ delete_tc()
} }
################################################################################ ################################################################################
# Process a record from the rules file # # Add a NAT rule - Helper function for the rules file processor #
# # #------------------------------------------------------------------------------#
# The caller has loaded the column contents from the record into the following # # The caller has established the following variables: #
# variables: # # cli = Source IP, interface or MAC Specification #
# # # serv = Destination IP Specification #
# target clients servers protocol ports cports address # # dest_interface = Destination Interface Specification #
# # # proto = Protocol Specification #
# and has loaded a space-separated list of their values in "rule". # # addr = Original Destination Address #
# # # dports = Destination Port Specification #
# The 'multioption' variable has also been loaded appropriately to reflect # # cport = Source Port Specification #
# the setting of the MULTIPORT option in /etc/shorewall/shorewall.conf # # multioption = String to invoke multiport match if appropriate #
################################################################################ ################################################################################
process_rule() { add_nat_rule() {
############################################################################
# Add a NAT rule
#
add_nat_rule() {
local chain local chain
# Be sure NAT is enabled
if [ -z "$NAT_ENABLED" ]; then if [ -z "$NAT_ENABLED" ]; then
fatal_error \ fatal_error \
"Error - Rule \"$rule\" requires NAT which is disabled" "Error - Rule \"$rule\" requires NAT which is disabled"
fi fi
# Onle ACCEPT (plus DNAT and REDIRECT) may result in NAT
if [ "$target" != "ACCEPT" ]; then if [ "$target" != "ACCEPT" ]; then
fatal_error "Error - Only DNAT and REDIRECT rules may specify " \ fatal_error "Error - Only DNAT and REDIRECT rules may specify " \
"port mapping; rule \"$rule\"" "port mapping; rule \"$rule\""
fi fi
# Parse SNAT address if any
if [ "$addr" != "${addr%:*}" ]; then if [ "$addr" != "${addr%:*}" ]; then
snat="${addr#*:}" snat="${addr#*:}"
addr="${addr%:*}" addr="${addr%:*}"
@ -1411,8 +1412,12 @@ process_rule() {
snat="" snat=""
fi fi
# Set original destination address
[ "$addr" = "all" ] && addr= || addr=${addr:+-d $addr} [ "$addr" = "all" ] && addr= || addr=${addr:+-d $addr}
# Select target
if [ -n "$serv" ]; then if [ -n "$serv" ]; then
servport="${servport:+:$servport}" servport="${servport:+:$servport}"
target1="DNAT --to-destination ${serv}${servport}" target1="DNAT --to-destination ${serv}${servport}"
@ -1420,6 +1425,8 @@ process_rule() {
target1="REDIRECT --to-port $servport" target1="REDIRECT --to-port $servport"
fi fi
# Generate nat table rules
if [ "$source" = "$FW" ]; then if [ "$source" = "$FW" ]; then
run_iptables -t nat -A OUTPUT $proto $sports $addr \ run_iptables -t nat -A OUTPUT $proto $sports $addr \
$dports -j $target1 $dports -j $target1
@ -1444,8 +1451,12 @@ process_rule() {
$addr $dports -j $target1 $addr $dports -j $target1
fi fi
# Replace destination port by the new destination port
[ -n "$servport" ] && dports="--dport ${servport#*:}" [ -n "$servport" ] && dports="--dport ${servport#*:}"
# Handle SNAT
if [ -n "$snat" ]; then if [ -n "$snat" ]; then
if [ -n "$cli" ]; then if [ -n "$cli" ]; then
run_iptables -t nat -A POSTROUTING $proto $cli \ run_iptables -t nat -A POSTROUTING $proto $cli \
@ -1458,38 +1469,44 @@ process_rule() {
done done
fi fi
fi fi
} }
############################################################################ ################################################################################
# Add one rule # Add one Filter Rule -- Helper function for the rules file processor #
# #------------------------------------------------------------------------------#
# The caller has established the following variables: #
# client = SOURCE IP or MAC #
# server = DESTINATION IP or interface #
# protocol = Protocol #
# address = Original Destination Address #
# port = Destination Port #
# cport = Source Port #
# multioption = String to invoke multiport match if appropriate #
# servport = Port the server listens on #
# chain = The canonical chain for this rule #
################################################################################
add_a_rule()
{
# Set source variables
add_a_rule() {
########################################################################
# Determine the format of the client
#
cli= cli=
[ -n "$client" ] && case "$client" in [ -n "$client" ] && case "$client" in
-) -)
;; ;;
[0-9]*|![0-9]*) [0-9]*|![0-9]*)
#
# IP Address or subnet
#
cli="-s $client" cli="-s $client"
;; ;;
~*) ~*)
cli=`mac_match $client` cli=`mac_match $client`
;; ;;
*) *)
#
# Assume that this is a device name
#
cli="-i $client" cli="-i $client"
;; ;;
esac esac
# Set destination variables
dest_interface= dest_interface=
[ -n "$server" ] && case "$server" in [ -n "$server" ] && case "$server" in
@ -1504,9 +1521,9 @@ process_rule() {
serv= serv=
;; ;;
esac esac
################################################################
# Setup PROTOCOL, PORT and STATE variables # Setup protocol and port variables
#
sports= sports=
dports= dports=
state="-m state --state NEW" state="-m state --state NEW"
@ -1556,6 +1573,8 @@ process_rule() {
proto="${proto:+-p $proto}" proto="${proto:+-p $proto}"
# Some misc. setup
case "$logtarget" in case "$logtarget" in
REJECT) REJECT)
target=reject target=reject
@ -1571,21 +1590,18 @@ process_rule() {
;; ;;
esac esac
# Complain if the rule is really a policy
if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" ]; then if [ -z "$proto" -a -z "$cli" -a -z "$serv" -a -z "$servport" ]; then
error_message "Warning -- Rule \"$rule\" is a POLICY" error_message "Warning -- Rule \"$rule\" is a POLICY"
error_message " -- and should be moved to the policy file" error_message " -- and should be moved to the policy file"
fi fi
if [ -n "${serv}${servport}" ]; then if [ -n "${serv}${servport}" ]; then
##################################################################
# Destination is a Specific Server or we're redirecting a port # A specific server or server port given
#
if [ -n "$addr" -a "$addr" != "$serv" ]; then [ -n "$addr" -a "$addr" != "$serv" ] && add_nat_rule
##############################################################
# Must use Prerouting DNAT or REDIRECT
#
add_nat_rule
fi
serv="${serv:+-d $serv}" serv="${serv:+-d $serv}"
@ -1596,9 +1612,9 @@ process_rule() {
run_iptables -A $chain $proto $multiport $state $cli $sports \ run_iptables -A $chain $proto $multiport $state $cli $sports \
$serv $dports -j $target $serv $dports -j $target
else else
####################################################################
# Destination is just a zone or an interface # Destination is a simple zone
#
[ -n "$addr" ] && fatal_error \ [ -n "$addr" ] && fatal_error \
"Error: An ADDRESS ($addr) is only allowed in" \ "Error: An ADDRESS ($addr) is only allowed in" \
" a DNAT or REDIRECT: \"$rule\"" " a DNAT or REDIRECT: \"$rule\""
@ -1611,11 +1627,24 @@ process_rule() {
run_iptables -A $chain $proto $multiport $dest_interface $state \ run_iptables -A $chain $proto $multiport $dest_interface $state \
$cli $sports $dports -j $target $cli $sports $dports -j $target
fi fi
} }
############################################################################ ################################################################################
# Return the number of elements in the passed comma-separated list # Process a record from the rules file #
# # #
# The caller has loaded the column contents from the record into the following #
# variables: #
# #
# target clients servers protocol ports cports address #
# #
# and has loaded a space-separated list of their values in "rule". #
# #
# The 'multioption' variable has also been loaded appropriately to reflect #
# the setting of the MULTIPORT option in /etc/shorewall/shorewall.conf #
################################################################################
process_rule() {
# Function to count list elements
list_count() { list_count() {
local temp=`separate_list $1` local temp=`separate_list $1`
@ -1623,11 +1652,8 @@ process_rule() {
echo $temp | wc -w echo $temp | wc -w
} }
############################################################################ # Function Body -- isolate log level
# P r o c e s s _ R u l e S t a r t s H e r e
############################################################################
# Parse the Target and Clients columns
#
if [ "$target" = "${target%:*}" ]; then if [ "$target" = "${target%:*}" ]; then
loglevel= loglevel=
else else
@ -1637,12 +1663,8 @@ process_rule() {
fi fi
logtarget="$target" logtarget="$target"
#
# DNAT and REDIRECT targets were implemented in version 1.3 to replace # Convert 1.3 Rule formats to 1.2 format
# an older syntax. We simply map the new syntax into the old and proceed;
# that way, people who have files with the old syntax don't need to
# convert right away.
#
case $target in case $target in
DNAT) DNAT)
@ -1660,6 +1682,8 @@ process_rule() {
;; ;;
esac esac
# Parse and validate source
if [ "$clients" = "${clients%:*}" ]; then if [ "$clients" = "${clients%:*}" ]; then
clientzone="$clients" clientzone="$clients"
clients= clients=
@ -1678,20 +1702,16 @@ process_rule() {
fatal_error "Error: Exclude list only allowed with DNAT or REDIRECT" fatal_error "Error: Exclude list only allowed with DNAT or REDIRECT"
fi fi
############################################################################
# Validate the Source Zone
if ! validate_zone $clientzone; then if ! validate_zone $clientzone; then
fatal_error "Error: Undefined Client Zone in rule \"$rule\"" fatal_error "Error: Undefined Client Zone in rule \"$rule\""
fi fi
# Parse and validate destination
source=$clientzone source=$clientzone
[ $source = $FW ] && source_hosts= || eval source_hosts=\"\$${source}_hosts\" [ $source = $FW ] && source_hosts= || eval source_hosts=\"\$${source}_hosts\"
############################################################################
# Parse the servers column
#
if [ "$servers" = "${servers%:*}" ] ; then if [ "$servers" = "${servers%:*}" ] ; then
serverzone="$servers" serverzone="$servers"
servers= servers=
@ -1706,22 +1726,20 @@ process_rule() {
serverport= serverport=
fi fi
fi fi
############################################################################
# Validate the destination zone
#
if ! validate_zone $serverzone; then if ! validate_zone $serverzone; then
fatal_error "Error: Undefined Server Zone in rule \"$rule\"" fatal_error "Error: Undefined Server Zone in rule \"$rule\""
fi fi
dest=$serverzone dest=$serverzone
############################################################################
# Create the canonical chain if it doesn't exist # Create canonical chain if necessary
#
chain=${source}2${dest} chain=${source}2${dest}
ensurechain $chain ensurechain $chain
############################################################################
# Iterate through the various lists creating individual rules # Generate Netfilter rule(s)
#
if [ -n "$MULTIPORT" -a \ if [ -n "$MULTIPORT" -a \
"$ports" = "${ports%:*}" -a \ "$ports" = "${ports%:*}" -a \
"$cports" = "${cports%:*}" -a \ "$cports" = "${cports%:*}" -a \
@ -2646,6 +2664,9 @@ add_common_rules() {
# #
drop_broadcasts `find_broadcasts` drop_broadcasts `find_broadcasts`
###########################################################################
# RFC 1918
#
norfc1918_interfaces="`find_interfaces_by_option norfc1918`" norfc1918_interfaces="`find_interfaces_by_option norfc1918`"
if [ -n "$norfc1918_interfaces" ]; then if [ -n "$norfc1918_interfaces" ]; then
@ -2710,7 +2731,9 @@ add_common_rules() {
# Enable icmp output # Enable icmp output
# #
run_iptables -A OUTPUT -m state --state ! INVALID -p icmp -j ACCEPT run_iptables -A OUTPUT -m state --state ! INVALID -p icmp -j ACCEPT
############################################################################
# Route Filtering
#
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 0 > $f echo 0 > $f
done done
@ -2736,7 +2759,9 @@ add_common_rules() {
done done
fi fi
fi fi
############################################################################
# IP Forwarding
#
case "$IP_FORWARDING" in case "$IP_FORWARDING" in
[Oo][Nn]) [Oo][Nn])
echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/ip_forward
@ -2754,7 +2779,9 @@ add_common_rules() {
# Add the appropriate policy rule(s) to the end of each canonical chain # # Add the appropriate policy rule(s) to the end of each canonical chain #
################################################################################ ################################################################################
apply_policy_rules() { apply_policy_rules() {
############################################################################
# Create policy chains
#
while read client server policy loglevel synparams; do while read client server policy loglevel synparams; do
expandv client server policy loglevel synparams expandv client server policy loglevel synparams
validate_zone $client validate_zone $client
@ -2788,7 +2815,9 @@ apply_policy_rules() {
fi fi
done < $TMP_DIR/policy done < $TMP_DIR/policy
############################################################################
# Add policy rules to canonical chains
#
for zone in $FW $zones; do for zone in $FW $zones; do
setup_intrazone $zone setup_intrazone $zone
for zone1 in $FW $zones; do for zone1 in $FW $zones; do