diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index ed8f7bf06..113dc2712 100755 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -1,15 +1,13 @@ -Changes since 1.4.3a +Changes since 1.4.4b + +1) The command "shorewall debug try " now correctly traces + the attempt. + +2) The ORIGINAL DEST column in a DNAT[-] or REDIRECT[-] rule may now + contain a list of addresses. If the list begins with "!' then the + rule will take effect only if the original destination address in + the connection request does not match any of the addresses listed. -1. Implement REDIRECT-. -2. Change LOGMARKER to a printf mask and allow embedded spaces. Renamed - it LOGFORMAT to avoid confusion. - -3. DNAT and REDIRECT logging is moved from the filter table to the nat - table. - -4. Don't include log rule number when LOGFORMAT doesn't include "%d". - -5. Add --log-level to LOG rules. diff --git a/Shorewall/firewall b/Shorewall/firewall index d9cb5dd97..b5cccf86b 100755 --- a/Shorewall/firewall +++ b/Shorewall/firewall @@ -1793,19 +1793,13 @@ refresh_tc() { # add_nat_rule() { local chain + local excludedests= # Be sure we should and can NAT - case $logtarget in - DNAT|REDIRECT) - if [ -z "$NAT_ENABLED" ]; then - fatal_error "Rule \"$rule\" requires NAT which is disabled" - fi - ;; - *) - fatal_error "Only DNAT and REDIRECT rules may specify port mapping; rule \"$rule\"" - ;; - esac + if [ -z "$NAT_ENABLED" ]; then + fatal_error "Rule \"$rule\" requires NAT which is disabled" + fi # Parse SNAT address if any @@ -1823,14 +1817,20 @@ add_nat_rule() { addr= ;; detect) - addr= - if [ -n "$DETECT_DNAT_IPADDRS" -a "$source" != "$FW" ]; then - eval interfaces=\$${source}_interfaces - for interface in $interfaces; do - addr="`find_interface_address $interface` $addr" - done - fi - ;; + addr= + if [ -n "$DETECT_DNAT_IPADDRS" -a "$source" != "$FW" ]; then + eval interfaces=\$${source}_interfaces + for interface in $interfaces; do + addr="`find_interface_address $interface` $addr" + done + fi + ;; + !*) + if [ `list_count $addr` -gt 1 ]; then + excludedests="`separate_list ${addr#\!}`" + addr= + fi + ;; esac addr=${addr:-0.0.0.0/0} @@ -1853,36 +1853,51 @@ add_nat_rule() { else chain=`dnat_chain $source` - if [ -n "$excludezones" ]; then + if [ -n "${excludezones}${excludedests}" ]; then chain=nonat${nonat_seq} nonat_seq=$(($nonat_seq + 1)) createnatchain $chain - addnatrule `dnat_chain $source` -j $chain + addnatrule `dnat_chain $source` $cli $proto $multiport $sports $dports -j $chain for z in $excludezones; do eval hosts=\$${z}_hosts for host in $hosts; do - for adr in $addr; do - addnatrule $chain $proto -s ${host#*:} \ - $multiport $sports -d $adr $dports -j RETURN + for adr in `separate_list $addr`; do + addnatrule $chain -s ${host#*:} -d $adr -j RETURN done done done + + for adr in $excludedests; do + addnatrule $chain -d $adr -j RETURN + done + + for adr in `separate_list $addr`; do + if [ -n "$loglevel" ]; then + ensurenatchain $chain + log_rule $loglevel $chain $logtarget -t nat -d `fix_bang $adr` + fi + + addnatrule $chain -j $target1 + done + else + for adr in `separate_list $addr`; do + if [ -n "$loglevel" ]; then + ensurenatchain $chain + log_rule $loglevel $chain $logtarget -t nat \ + `fix_bang $proto $cli $sports -d $adr $multiport $dports` + fi + + addnatrule $chain $proto $cli $sports \ + -d $adr $multiport $dports -j $target1 + done fi - - for adr in $addr; do - if [ -n "$loglevel" ]; then - ensurenatchain $chain - log_rule $loglevel $chain $logtarget -t nat \ - `fix_bang $proto $cli $sports -d $adr $multiport $dports` - loglevel= - fi - - addnatrule $chain $proto $cli $sports \ - -d $adr $multiport $dports -j $target1 - done fi fi + # We do all logging here rather than in the filter table + + loglevel= + # Replace destination port by the new destination port if [ -n "$servport" ]; then @@ -1930,6 +1945,11 @@ add_nat_rule() { # add_a_rule() { + + rule_error() { + fatal_error "Only DNAT and REDIRECT rules may specify port mapping; rule \"$rule\"" + } + # Set source variables cli= @@ -2054,11 +2074,19 @@ add_a_rule() # A specific server or server port given - if [ -n "$addr" -a "$addr" != "$serv" ]; then - add_nat_rule - elif [ -n "$servport" -a "$servport" != "$port" ]; then - add_nat_rule - fi + case "$logtarget" in + REDIRECT|DNAT) + add_nat_rule + ;; + *) + if [ -n "$addr" -a "$addr" != "$serv" ]; then + rule_error + elif [ -n "$servport" -a "$servport" != "$port" ]; then + rule_error + fi + + ;; + esac if [ -z "$dnat_only" -a $chain != ${FW}2${FW} ]; then serv="${serv:+-d $serv}" diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index efa8ced70..65bf2b673 100755 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -2,32 +2,13 @@ This is a minor release of Shorewall. Problems Corrected: +1) The command "shorewall debug try " now correctly traces + the attempt. + New Features: -1) A REDIRECT- rule target has been added. This target behaves for - REDIRECT in the same was as DNAT- does for DNAT in that the - Netfilter nat table REDIRECT rule is added but not the companion - filter table ACCEPT rule. - -2) The LOGMARKER variable has been renamed LOGFORMAT and has been - changed to a 'printf' formatting template which accepts three - arguments (the chain name, logging rule number (optional) and the - disposition). The logging rule number is included if the LOGFORMAT - value contains '%d'. For example, to use LOGFORMAT with fireparse, - set it as: - - LOGFORMAT="fp=%s:%d a=%s " - - - CAUTION: /sbin/shorewall uses the leading part of the LOGFORMAT - string (up to but not including the first '%') to find log messages - in the 'show log', 'status' and 'hits' commands. This part should - not be omitted (the LOGFORMAT should not begin with "%") and the - leading part should be sufficiently unique for /sbin/shorewall to - identify Shorewall messages. - -3) When logging is specified on a DNAT[-] or REDIRECT[-] rule, the - logging now takes place in the nat table rather than in the filter - table. This way, only those connections that actually undergo DNAT - or redirection will be logged. +1) The ORIGINAL DEST column in a DNAT[-] or REDIRECT[-] rule may now + contain a list of addresses. If the list begins with "!' then the + rule will take effect only if the original destination address in + the connection request does not match any of the addresses listed. diff --git a/Shorewall/rules b/Shorewall/rules index 2ff32024f..fae892632 100755 --- a/Shorewall/rules +++ b/Shorewall/rules @@ -162,13 +162,20 @@ # Otherwise, a separate rule will be generated for each # port. # -# ORIGINAL DEST (0ptional -- only allowed if ACTION is DNAT or -# REDIRECT) If included and different from the IP +# ORIGINAL DEST (0ptional -- only allowed if ACTION is DNAT[-] or +# REDIRECT[-]) If included and different from the IP # address given in the SERVER column, this is an address # on some interface on the firewall and connections to # that address will be forwarded to the IP and port # specified in the DEST column. # +# A comma-separated list of addresses may also be used. +# This is usually most useful with the REDIRECT target. +# Finally, if the list of addresses begins with "!" then +# the rule will be followed only if the original +# destination address in the connection request does not +# match any of the addresses listed. +# # The address may optionally be followed by # a colon (":") and a second IP address. This causes # Shorewall to use the second IP address as the source diff --git a/Shorewall/shorewall b/Shorewall/shorewall index 44c9cc5db..44f0f2e8b 100755 --- a/Shorewall/shorewall +++ b/Shorewall/shorewall @@ -776,7 +776,7 @@ case "$1" in try) [ -n "$SHOREWALL_DIR" ] && startup_error "Error: -c option may not be used with \"try\"" [ $# -lt 2 -o $# -gt 3 ] && usage 1 - if ! $0 -c $2 restart; then + if ! $0 $debugging -c $2 restart; then if ! iptables -L shorewall > /dev/null 2> /dev/null; then $0 start fi