diff --git a/Shorewall/firewall b/Shorewall/firewall index 21109418e..d682cb9a2 100755 --- a/Shorewall/firewall +++ b/Shorewall/firewall @@ -502,6 +502,11 @@ dynamic_chains() #$1 = interface echo ${c}_dyni ${c}_dynf ${c}_dyno } +macrecent_target() # $1 - interface +{ + [ -n "$MACLIST_TTL" ] && echo $(chain_base $1)_rec || echo RETURN +} + # # DNAT Chain from a zone # @@ -2322,6 +2327,15 @@ setup_mac_lists() { for interface in $maclist_interfaces; do chain=$(mac_chain $interface) createchain $chain no + + if [ -n "$MACLIST_TTL" ]; then + chain1=$(macrecent_target $interface) + createchain $chain1 no + run_iptables -A $chain -m recent --rcheck --seconds $MACLIST_TTL --name $chain -j RETURN + run_iptables -A $chain -j $chain1 + run_iptables -A $chain -m recent --update --name $chain -j RETURN + run_iptables -A $chain -m recent --set --name $chain + fi done # # Process the maclist file producing the verification rules @@ -2340,8 +2354,7 @@ setup_mac_lists() { esac fi - chain=$(mac_chain $interface) - chain1=$(macrecent_target $interface) + [ -n "$MACLIST_TTL" ] && chain=$(macrecent_target $interface) || chain=$(mac_chain $interface) if ! havechain $chain ; then fatal_error "No hosts on $interface have the maclist option specified" @@ -2350,10 +2363,10 @@ setup_mac_lists() { macpart=$(mac_match $mac) if [ -z "$addresses" ]; then - run_iptables -A $chain $macpart $physdev_part -j $chain1 + run_iptables -A $chain $macpart $physdev_part -j RETURN else for address in $(separate_list $addresses) ; do - run_iptables2 -A $chain $macpart -s $address $physdev_part -j $chain1 + run_iptables2 -A $chain $macpart -s $address $physdev_part -j RETURN done fi done < $TMP_DIR/maclist @@ -2362,8 +2375,7 @@ setup_mac_lists() { # chains # for interface in $maclist_interfaces; do - chain=$(mac_chain $interface) - chain1=$(macrecent_target $interface) + [ -n "$MACLIST_TTL" ] && chain=$(macrecent_target $interface) || chain=$(mac_chain $interface) blob=$(ip link show $interface 2> /dev/null) @@ -2373,15 +2385,15 @@ setup_mac_lists() { ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | sed 's/inet //; s/brd //; s/scope.*//;' | while read address broadcast; do address=${address%/*} if [ -n "$broadcast" ]; then - run_iptables -A $chain -s $address -d $broadcast -j $chain1 + run_iptables -A $chain -s $address -d $broadcast -j RETURN fi - run_iptables -A $chain -s $address -d 255.255.255.255 -j $chain1 - run_iptables -A $chain -s $address -d 224.0.0.0/4 -j $chain1 + run_iptables -A $chain -s $address -d 255.255.255.255 -j RETURN + run_iptables -A $chain -s $address -d 224.0.0.0/4 -j RETURN done if [ -n "$MACLIST_LOG_LEVEL" ]; then - log_rule $MACLIST_LOG_LEVEL $chain $MACLIST_DISPOSITION + log_rule_limit $MACLIST_LOG_LEVEL $chain $(mac_chain $interface) $MACLIST_DISPOSITION "$LOGLIMIT" "" -A fi run_iptables -A $chain -j $maclist_target @@ -3180,8 +3192,8 @@ check_config() { [ "$MACLIST_TTL" = "0" ] && MACLIST_TTL= - if [ -n "$MACLIST_TTL" ]; then - error_message "WARNING: MACLIST_TTL has been disabled until further notice" + if [ -n "$MACLIST_TTL" -a -z "$RECENT_MATCH" ]; then + startup_error "MACLIST_TTL requires the Recent Match capability which is not present in your Kernel and/or iptables" fi echo "Determining Zones..." @@ -6389,8 +6401,8 @@ initialize_netfilter () { [ "$MACLIST_TTL" = "0" ] && MACLIST_TTL= - if [ -n "$MACLIST_TTL" ]; then - error_message "WARNING: MACLIST_TTL has been disabled until further notice" + if [ -n "$MACLIST_TTL" -a -z "$RECENT_MATCH" ]; then + startup_error "MACLIST_TTL requires the Recent Match capability which is not present in your Kernel and/or iptables" fi [ -n "$RFC1918_STRICT" -a -z "$CONNTRACK_MATCH" ] && \ @@ -8178,8 +8190,11 @@ do_initialize() { case $MACLIST_DISPOSITION in REJECT) ;; - ACCEPT|DROP) - maclist_target=$MACLIST_DISPOSITION + DROP) + maclist_target=DROP + ;; + ACCEPT) + maclist_target=RETURN ;; *) startup_error "Invalid value ($MACLIST_DISPOSITION) for MACLIST_DISPOSITION" diff --git a/Shorewall/shorewall.conf b/Shorewall/shorewall.conf index f596c7bb3..7df925578 100755 --- a/Shorewall/shorewall.conf +++ b/Shorewall/shorewall.conf @@ -779,6 +779,29 @@ DROPINVALID=No RFC1918_STRICT=No +# +# MACLIST caching +# +# If your iptables and kernel support the "Recent Match" (see the output of +# "shorewall check" near the top), you can cache the results of a 'maclist' +# file lookup and thus reduce the overhead associated with MAC Verification +# (/etc/shorewall/maclist). +# +# When a new connection arrives from a 'maclist' interface, the packet passes +# through then list of entries for that interface in /etc/shorewall/maclist. If +# there is a match then the source IP address is added to the 'Recent' set for +# that interface. Subsequent connection attempts from that IP address occuring +# within $MACLIST_TTL seconds will be accepted without having to scan all of +# the entries. After $MACLIST_TTL from the first accepted connection request, +# the next connection request from that IP address will be checked against +# the entire list. +# +# If MACLIST_TTL is not specified or is specified as empty (e.g, +# MACLIST_TTL="" or is specified as zero then 'maclist' lookups will not +# be cached. + +MACLIST_TTL= + # # Save/Restore IPSETS #