Implement 'default' interface option

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@2129 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2005-05-17 15:09:05 +00:00
parent 955e8e683a
commit 1ca5bde7b5
5 changed files with 200 additions and 33 deletions

View File

@ -4,6 +4,8 @@ Changes in 2.3.2
2) Add TEST column to /etc/shorewall/routes 2) Add TEST column to /etc/shorewall/routes
3) Add support for 'default' interface option.
Changes in 2.3.1 Changes in 2.3.1
1) Change the behavior of SAVE_IPSETS and allow 'ipsets' files in 1) Change the behavior of SAVE_IPSETS and allow 'ipsets' files in

View File

@ -1019,11 +1019,20 @@ validate_interfaces_file() {
routeback) routeback)
[ -n "$z" ] || startup_error "The routeback option may not be specified on a multi-zone interface" [ -n "$z" ] || startup_error "The routeback option may not be specified on a multi-zone interface"
;; ;;
mark=*) default)
[ -n "$ROUTE_TARGET" ] || \ [ -n "$ROUTE_TARGET" ] || \
startup_error "Interface marks require ROUTE Target support in your kernel and iptables: $option" startup_error "Default route interfaces require ROUTE Target support in your kernel and iptables: $option"
eval ${iface}_mark=${option#*=} [ -n "$CONNMARK" ] || \
MARK_INTERFACES="$MARK_INTERFACES $interface" startup_error "Default route interfaces require CONNMARK Target support in your kernel and iptables: $option"
[ -n "$CONNMARK_MATCH" ] || \
startup_error "Default route interfaces require Connmark Match support in your kernel and iptables: $option"
[ -n "$XMARK" ] || \
startup_error "Default route interfaces require Extended MARK support in your kernel and iptables: $option"
[ $ROUTEMARK -lt 4096 ] || \
startup_error "Too many default route interfaces defined"
eval ${iface}_routemark=$ROUTEMARK
ROUTEMARK=$(($ROUTEMARK + 256))
ROUTEMARK_INTERFACES="$ROUTEMARK_INTERFACES $interface"
;; ;;
*) *)
error_message "Warning: Invalid option ($option) in record \"$r\"" error_message "Warning: Invalid option ($option) in record \"$r\""
@ -2460,6 +2469,24 @@ setup_ecn() # $1 = file name
fi fi
} }
#
# Check that a mark value or mask is less that 256
#
verify_mark() # $1 = value to test
{
verify_mark1()
{
[ $1 -lt 256 ]
}
verify_mark2()
{
verify_mark1 $1 2> /dev/null
}
verify_mark2 $1 || fatal_error "Invalid Mark or Mask value: $1"
}
# #
# Process a TC Rule - $MARKING_CHAIN is assumed to contain the name of the # Process a TC Rule - $MARKING_CHAIN is assumed to contain the name of the
# default marking chain # default marking chain
@ -2588,29 +2615,46 @@ process_tc_rule()
chain=tcpost chain=tcpost
;; ;;
esac esac
fi fi
case $mark in case $mark in
SAVE) SAVE)
target="CONNMARK --save-mark" target="CONNMARK --save-mark --mask 255"
mark= mark=
;; ;;
SAVE/*) SAVE/*)
target="CONNMARK --save-mark --mask" target="CONNMARK --save-mark --mask"
mark=${mark#*/} mark=${mark#*/}
verify_mark $mark
;; ;;
RESTORE) RESTORE)
target="CONNMARK --restore-mark" target="CONNMARK --restore-mark --mask 255"
mark= mark=
;; ;;
RESTORE/*) RESTORE/*)
target="CONNMARK --restore-mark --mask" target="CONNMARK --restore-mark --mask"
mark=${mark#*/} mark=${mark#*/}
verify_mark $mark
;; ;;
CONTINUE) CONTINUE)
target=RETURN target=RETURN
mark= mark=
;; ;;
*)
if [ "$chain" != tcpost ]; then
case $mark in
*/*)
verify_mark ${mark%/*}
verify_mark ${mark#*/}
;;
*)
verify_mark $mark
mark=$mark/255
;;
esac
fi
;;
esac esac
case $testval in case $testval in
@ -2634,6 +2678,19 @@ process_tc_rule()
;; ;;
esac esac
if [ -n "$marktest" ] ; then
case $testval in
*/*)
verify_mark ${testval%/*}
verify_mark ${testval#*/}
;;
*)
verify_mark $testval
testval=$testval/255
;;
esac
fi
for source in $(separate_list ${sources:=-}); do for source in $(separate_list ${sources:=-}); do
for dest in $(separate_list ${dests:=-}); do for dest in $(separate_list ${dests:=-}); do
for port in $(separate_list ${ports:=-}); do for port in $(separate_list ${ports:=-}); do
@ -5026,11 +5083,12 @@ process_tos() # $1 = name of tos file
{ {
echo "Processing $1..." echo "Processing $1..."
strip_file tos $1
if [ -s $TMP_DIR/tos ] ; then
run_iptables -t mangle -N pretos run_iptables -t mangle -N pretos
run_iptables -t mangle -N outtos run_iptables -t mangle -N outtos
strip_file tos $1
while read src dst protocol sport dport tos; do while read src dst protocol sport dport tos; do
expandv src dst protocol sport dport tos expandv src dst protocol sport dport tos
rule="$(echo $src $dst $protocol $sport $dport $tos)" rule="$(echo $src $dst $protocol $sport $dport $tos)"
@ -5039,6 +5097,7 @@ process_tos() # $1 = name of tos file
run_iptables -t mangle -A PREROUTING -j pretos run_iptables -t mangle -A PREROUTING -j pretos
run_iptables -t mangle -A OUTPUT -j outtos run_iptables -t mangle -A OUTPUT -j outtos
fi
} }
# #
@ -5323,6 +5382,7 @@ add_a_route()
case $testval in case $testval in
-) -)
testval=
;; ;;
!*:C) !*:C)
marktest="connmark ! " marktest="connmark ! "
@ -5342,6 +5402,19 @@ add_a_route()
;; ;;
esac esac
if [ -n "$testval" ] ; then
case $testval in
*/*)
verify_mark ${testval%/*}
verify_mark ${testval#*/}
;;
*)
verify_mark $testval
testval=$testval/255
;;
esac
fi
[ -n "$marktest" ] && r="${r}-m ${marktest}--mark $testval " [ -n "$marktest" ] && r="${r}-m ${marktest}--mark $testval "
r="${r}-j ROUTE " r="${r}-j ROUTE "
@ -5355,6 +5428,17 @@ add_a_route()
progress_message " Routing Rule \"$rule\" Added." progress_message " Routing Rule \"$rule\" Added."
} }
#
# Create routing chains
#
create_routing_chains()
{
run_iptables -t mangle -N routefwd
run_iptables -t mangle -A FORWARD -j routefwd
run_iptables -t mangle -N routeout
run_iptables -t mangle -A OUTPUT -j routeout
}
# #
# Set up Routing # Set up Routing
# #
@ -5366,10 +5450,7 @@ setup_routes() # $1 = file name
echo "Processing $1..." echo "Processing $1..."
[ -n "$ROUTE_TARGET" ] || \ [ -n "$ROUTE_TARGET" ] || \
fatal_error "Entries in /etc/shorewall/routes requires that your kernel and iptables have ROUTE target support" fatal_error "Entries in /etc/shorewall/routes requires that your kernel and iptables have ROUTE target support"
run_iptables -t mangle -N routefwd create_routing_chains
run_iptables -t mangle -A FORWARD -j routefwd
run_iptables -t mangle -N routeout
run_iptables -t mangle -A OUTPUT -j routeout
while read source dest proto port sport testval interface gateway; do while read source dest proto port sport testval interface gateway; do
@ -5377,6 +5458,8 @@ setup_routes() # $1 = file name
rule="$source $dest $proto $port $sport testval $interface $gateway" rule="$source $dest $proto $port $sport testval $interface $gateway"
add_a_route add_a_route
done < $TMP_DIR/routes done < $TMP_DIR/routes
elif [ -n "$ROUTEMARK_INTERFACES" ]; then
create_routing_chains
fi fi
} }
@ -6057,6 +6140,8 @@ determine_capabilities() {
IPSET_MATCH= IPSET_MATCH=
ROUTE_TARGET= ROUTE_TARGET=
XMARK= XMARK=
CONNMARK=
CONNMARK_MATCH=
qt $IPTABLES -N fooX1234 qt $IPTABLES -N fooX1234
qt $IPTABLES -A fooX1234 -m conntrack --ctorigdst 192.168.1.1 -j ACCEPT && CONNTRACK_MATCH=Yes qt $IPTABLES -A fooX1234 -m conntrack --ctorigdst 192.168.1.1 -j ACCEPT && CONNTRACK_MATCH=Yes
@ -6067,10 +6152,12 @@ determine_capabilities() {
qt $IPTABLES -A fooX1234 -m iprange --src-range 192.168.1.5-192.168.1.124 -j ACCEPT && IPRANGE_MATCH=Yes qt $IPTABLES -A fooX1234 -m iprange --src-range 192.168.1.5-192.168.1.124 -j ACCEPT && IPRANGE_MATCH=Yes
qt $IPTABLES -A fooX1234 -m recent --update -j ACCEPT && RECENT_MATCH=Yes qt $IPTABLES -A fooX1234 -m recent --update -j ACCEPT && RECENT_MATCH=Yes
qt $IPTABLES -A fooX1234 -m owner --cmd-owner foo -j ACCEPT && OWNER_MATCH=Yes qt $IPTABLES -A fooX1234 -m owner --cmd-owner foo -j ACCEPT && OWNER_MATCH=Yes
qt $IPTABLES -A fooX1234 -m connmark --mark 2 -j ACCEPT && CONNMARK_MATCH=Yes
qt $IPTABLES -t mangle -N fooX1234 qt $IPTABLES -t mangle -N fooX1234
qt $IPTABLES -t mangle -A fooX1234 -j ROUTE --oif eth0 && ROUTE_TARGET=Yes qt $IPTABLES -t mangle -A fooX1234 -j ROUTE --oif eth0 && ROUTE_TARGET=Yes
qt $IPTABLES -t mangle -A fooX1234 -j MARK --or-mark 2 && XMARK=Yes qt $IPTABLES -t mangle -A fooX1234 -j MARK --or-mark 2 && XMARK=Yes
qt $IPTABLES -t mangle -A fooX1234 -j CONNMARK --save-mark && CONNMARK=Yes
qt $IPTABLES -t mangle -F fooX1234 qt $IPTABLES -t mangle -F fooX1234
qt $IPTABLES -t mangle -X fooX1234 qt $IPTABLES -t mangle -X fooX1234
@ -6118,6 +6205,8 @@ report_capabilities() {
report_capability "Ipset Match" $IPSET_MATCH report_capability "Ipset Match" $IPSET_MATCH
report_capability "ROUTE Target" $ROUTE_TARGET report_capability "ROUTE Target" $ROUTE_TARGET
report_capability "Extended MARK Target" $XMARK report_capability "Extended MARK Target" $XMARK
report_capability "CONNMARK Target" $CONNMARK
report_capability "Connmark Match" $CONNMARK_MATCH
} }
# #
@ -7068,16 +7157,43 @@ activate_rules()
done done
done done
for interface in $MARK_INTERFACES ; do if [ -n "$CONNMARK" ]; then
run_iptables -t mangle -I PREROUTING -m connmark ! --mark 0 -j CONNMARK --restore-mark
fi
if [ -n "$ROUTEMARK_INTERFACES" ]; then
run_iptables -t mangle -N routemark
for interface in $ROUTEMARK_INTERFACES ; do
iface=$(chain_base $interface) iface=$(chain_base $interface)
chain=$(input_chain $interface) eval mark_value=\$${iface}_routemark
eval mark_value=\$${iface}_mark
run_iptables -t mangle -N $chain run_iptables -t mangle -A PREROUTING -i $interface -m mark --mark 0/3840 -j routemark
run_iptables -t mangle -A PREROUTING -i $interface -j $chain run_iptables -t mangle -A routemark -i $interface -j MARK --or-mark $mark_value
eval run_iptables -t mangle -A PREROUTING -i $interface -j MARK --set-mark ip route ls dev $interface 2> /dev/null | while read net rest; do
case $net in
default)
gateway=$(find_gateway $rest)
for chain in routefwd routeout; do
for interface1 in $ROUTEMARK_INTERFACES; do
run_iptables -t mangle -A $chain -o $interface1 -m mark --mark $mark_value/3840 -j ROUTE --oif $interface --gw $gateway --continue
done done
done
;;
*)
for chain in routefwd routeout; do
run_iptables -t mangle -A $chain -d $net -o $interface -j RETURN
done
;;
esac
done
done
run_iptables -t mangle -A routemark -m mark ! --mark 0/3840 -j CONNMARK --save-mark --mask 3840
run_iptables -t mangle -I POSTROUTING -j MARK --and-mark 255
fi
for interface in $ALL_INTERFACES ; do for interface in $ALL_INTERFACES ; do
run_iptables -A FORWARD -i $interface -j $(forward_chain $interface) run_iptables -A FORWARD -i $interface -j $(forward_chain $interface)
@ -7227,7 +7343,11 @@ define_firewall() # $1 = Command (Start or Restart)
[ -n "$TC_ENABLED" ] && setup_tc [ -n "$TC_ENABLED" ] && setup_tc
routes=$(find_file routes) routes=$(find_file routes)
[ -f $routes ] && setup_routes $routes if [ -f $routes ]; then
setup_routes $routes
elif [ -n "$ROUTEMARK_INTERFACES" ]; then
add_routing_chains
fi
echo "Activating Rules..."; activate_rules echo "Activating Rules..."; activate_rules
@ -7794,7 +7914,8 @@ do_initialize() {
RESTOREBASE= RESTOREBASE=
TMP_DIR= TMP_DIR=
ALL_INTERFACES= ALL_INTERFACES=
MARK_INTERFACES= ROUTEMARK_INTERFACES=
ROUTEMARK=256
stopping= stopping=
have_mutex= have_mutex=

View File

@ -778,6 +778,17 @@ find_device() {
done 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 interfaces that have a route to the passed address - the default # Find the interfaces that have a route to the passed address - the default
# route is not used. # route is not used.

View File

@ -167,9 +167,21 @@
# detectnets - Automatically taylors the zone named # detectnets - Automatically taylors the zone named
# in the ZONE column to include only those # in the ZONE column to include only those
# hosts routed through the interface. # hosts routed through the interface.
#
# upnp - Incoming requests from this interface may # upnp - Incoming requests from this interface may
# be remapped via UPNP (upnpd). # be remapped via UPNP (upnpd).
# #
# default - This interface is one of two or more on the
# the firewall that have a default route.
# You should specify 'default' on all such
# interfaces, the interfaces should be up when
# Shorewall starts and each interface must have
# a default route configured in the main routing
# table. There are many restrictions on the use
# of this feature; see
# http://shorewall.net/Shorewall_and_Routing.html
# for details.
#
# WARNING: DO NOT SET THE detectnets OPTION ON YOUR # WARNING: DO NOT SET THE detectnets OPTION ON YOUR
# INTERNET INTERFACE. # INTERNET INTERFACE.
# #

View File

@ -90,6 +90,27 @@ New Features in version 2.3.2
GATEWAY The gateway that the packet is to be forewarded GATEWAY The gateway that the packet is to be forewarded
through. through.
2) Shorewall 2.3.2 includes support for multiple internet interfaces to
different ISPs. This feature is enabled by setting the "default"
option for each internet interface in /etc/shorewall/interfaces.
This feature requires a number of extensions in your kernel and
iptables:
- Extended MARK support.
- ROUTE Target support.
- CONNMARK Target support and conntrack match support.
Each interface with the 'default' option given must have a default
gateway route in the main routing table and must be up when
Shorewall is [re]started.
When you specify 'default' on two or more entries in
/etc/shorewall/interfaces, replies to connections from these
interfaces are routed back out of the same interface and through the
correct gateway.
----------------------------------------------------------------------- -----------------------------------------------------------------------
Problems corrected in version 2.3.1 Problems corrected in version 2.3.1