forked from extern/shorewall_code
Move DNAT/REDIRECT processing code to lib.nat
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@4817 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
71b29cfe99
commit
bad66d0f1a
@ -15,6 +15,8 @@ Changes in 3.3.4
|
|||||||
|
|
||||||
7) Fix whitespace in LOGFORMAT.
|
7) Fix whitespace in LOGFORMAT.
|
||||||
|
|
||||||
|
8) Move DNAT/REDIRECT code to lib.base.
|
||||||
|
|
||||||
Changes in 3.3.4
|
Changes in 3.3.4
|
||||||
|
|
||||||
1) Make exclusion work with "show zones"
|
1) Make exclusion work with "show zones"
|
||||||
|
@ -1596,195 +1596,6 @@ __EOF__
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Add a NAT rule - Helper function for the rules file processor
|
|
||||||
#
|
|
||||||
# The caller has established the following variables:
|
|
||||||
# cli = Source IP, interface or MAC Specification
|
|
||||||
# serv = Destination IP Specification
|
|
||||||
# servport = Port the server is listening on
|
|
||||||
# dest_interface = Destination Interface Specification
|
|
||||||
# proto = Protocol Specification
|
|
||||||
# addr = Original Destination Address
|
|
||||||
# dports = Destination Port Specification. 'dports' may be changed
|
|
||||||
# by this function
|
|
||||||
# cport = Source Port Specification
|
|
||||||
# multiport = String to invoke multiport match if appropriate
|
|
||||||
# ratelimit = Optional rate limiting clause
|
|
||||||
# userandgroup = -m owner match to limit the rule to a particular user and/or group
|
|
||||||
# logtag = Log tag
|
|
||||||
# excludesource = Source Exclusion List
|
|
||||||
#
|
|
||||||
add_nat_rule() {
|
|
||||||
local chain
|
|
||||||
local excludedests=
|
|
||||||
|
|
||||||
# Be sure we can NAT
|
|
||||||
|
|
||||||
if [ -z "$NAT_ENABLED" ]; then
|
|
||||||
fatal_error "Rule \"$rule\" requires NAT which is disabled"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse SNAT address if any
|
|
||||||
|
|
||||||
if [ "$addr" != "${addr%:*}" ]; then
|
|
||||||
fatal_error "SNAT may no longer be specified in a DNAT rule; use ${CONFDIR}/masq instead"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set original destination address
|
|
||||||
|
|
||||||
case $addr in
|
|
||||||
all)
|
|
||||||
addr=
|
|
||||||
;;
|
|
||||||
detect)
|
|
||||||
eval interfaces=\$${source}_interfaces
|
|
||||||
|
|
||||||
if [ -n "$DETECT_DNAT_IPADDRS" -a "$source" != "$FW" ]; then
|
|
||||||
|
|
||||||
save_command
|
|
||||||
if [ $(list_count1 $interfaces) -eq 1 ]; then
|
|
||||||
save_command "addr=\$(find_first_interface_address $interfaces)"
|
|
||||||
else
|
|
||||||
save_command "addr="
|
|
||||||
for interface in $interfaces; do
|
|
||||||
ident >&3 << __EOF__
|
|
||||||
addr="\$addr \$(find_first_interface_address $interface)"
|
|
||||||
__EOF__
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
addr=
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
!*)
|
|
||||||
if [ $(list_count $addr) -gt 1 ]; then
|
|
||||||
excludedests="${addr#\!}"
|
|
||||||
addr=
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
addr=${addr:-0.0.0.0/0}
|
|
||||||
|
|
||||||
# Select target
|
|
||||||
|
|
||||||
if [ "$logtarget" = SAME ]; then
|
|
||||||
[ -n "$servport" ] && fatal_error "Port mapping not allowed in SAME rules"
|
|
||||||
serv1=
|
|
||||||
for srv in $(separate_list $serv); do
|
|
||||||
serv1="$serv1 --to ${srv}"
|
|
||||||
done
|
|
||||||
target1="SAME $serv1"
|
|
||||||
elif [ -n "$serv" ]; then
|
|
||||||
servport="${servport:+:$servport}"
|
|
||||||
serv1=
|
|
||||||
for srv in $(separate_list $serv); do
|
|
||||||
serv1="$serv1 --to-destination ${srv}${servport}"
|
|
||||||
done
|
|
||||||
target1="DNAT $serv1"
|
|
||||||
else
|
|
||||||
target1="REDIRECT --to-port $servport"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Generate nat table rules
|
|
||||||
|
|
||||||
if [ "$source" = "$FW" ]; then
|
|
||||||
if [ -n "${excludesource}${excludedests}" ]; then
|
|
||||||
build_exclusion_chain chain nat "$excludesource" $excludedests
|
|
||||||
|
|
||||||
for adr in $(separate_list $addr); do
|
|
||||||
run_iptables2 -t nat -A OUTPUT $cli $proto $userandgroup $multiport $sports $dports $(dest_ip_range $adr) -j $chain
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -n "$loglevel" ]; then
|
|
||||||
log_rule_limit $loglevel $chain OUTPUT $logtarget "$ratelimit" "$logtag" -A -t nat
|
|
||||||
fi
|
|
||||||
|
|
||||||
addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection
|
|
||||||
else
|
|
||||||
for adr in $(separate_list $addr); do
|
|
||||||
if [ -n "$loglevel" ]; then
|
|
||||||
log_rule_limit $loglevel OUTPUT OUTPUT $logtarget "$ratelimit" "$logtag" -A -t nat \
|
|
||||||
$(fix_bang $proto $cli $sports $userandgroup $(dest_ip_range $adr) $multiport $dports)
|
|
||||||
fi
|
|
||||||
|
|
||||||
run_iptables2 -t nat -A OUTPUT $ratelimit $proto $sports $userandgroup $(dest_ip_range $adr) $multiport $dports -j $target1
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ -n "${excludesource}${excludedests}" ]; then
|
|
||||||
build_exclusion_chain chain nat "$excludesource" $excludedests
|
|
||||||
|
|
||||||
if [ $addr = detect ]; then
|
|
||||||
ensurenatchain $(dnat_chain $source)
|
|
||||||
#
|
|
||||||
# The 'for loops' begun below are completed in add_a_rule() whose declaration follows
|
|
||||||
#
|
|
||||||
indent >&3 << __EOF__
|
|
||||||
|
|
||||||
for adr in \$addr; do
|
|
||||||
run_iptables -t nat -A $(fix_bang $(dnat_chain $source) $cli $proto $multiport $sports $dports) -d \$adr -j $chain
|
|
||||||
__EOF__
|
|
||||||
else
|
|
||||||
for adr in $(separate_list $addr); do
|
|
||||||
addnatrule $(dnat_chain $source) $cli $proto $multiport $sports $dports $(dest_ip_range $adr) -j $chain
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$loglevel" ]; then
|
|
||||||
log_rule_limit $loglevel $chain $(dnat_chain $source) $logtarget "$ratelimit" "$logtag" -A -t nat
|
|
||||||
fi
|
|
||||||
|
|
||||||
addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection
|
|
||||||
else
|
|
||||||
chain=$(dnat_chain $source)
|
|
||||||
|
|
||||||
if [ $addr = detect ]; then
|
|
||||||
ensurenatchain $chain
|
|
||||||
|
|
||||||
indent >&3 << __EOF__
|
|
||||||
|
|
||||||
for adr in \$addr; do
|
|
||||||
__EOF__
|
|
||||||
if [ -n "$loglevel" ]; then
|
|
||||||
indent >&3 << __EOF__
|
|
||||||
log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A -t nat $(fix_bang $proto $cli $sports $multiport $dports) -d \$adr
|
|
||||||
__EOF__
|
|
||||||
fi
|
|
||||||
|
|
||||||
indent >&3 << __EOF__
|
|
||||||
run_iptables -t nat -A $chain $(fix_bang $proto $ratelimit $cli $sports $multiport $dports) -d \$adr -j $target1
|
|
||||||
__EOF__
|
|
||||||
else
|
|
||||||
for adr in $(separate_list $addr); do
|
|
||||||
if [ -n "$loglevel" ]; then
|
|
||||||
ensurenatchain $chain
|
|
||||||
log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A -t nat \
|
|
||||||
$(fix_bang $proto $cli $sports $(dest_ip_range $adr) $multiport $dports)
|
|
||||||
fi
|
|
||||||
|
|
||||||
addnatrule $chain $proto $ratelimit $cli $sports \
|
|
||||||
-d $adr $multiport $dports -j $target1
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Replace destination port by the new destination port
|
|
||||||
|
|
||||||
if [ -n "$servport" ]; then
|
|
||||||
if [ -z "$multiport" ]; then
|
|
||||||
dports="--dport ${servport#*:}"
|
|
||||||
else
|
|
||||||
dports="--dports ${servport#*:}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ "x$addr" = "x0.0.0.0/0" ] && addr=
|
|
||||||
ratelimit=
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Add one Filter Rule
|
# Add one Filter Rule
|
||||||
#
|
#
|
||||||
@ -2028,6 +1839,7 @@ add_a_rule() {
|
|||||||
# A specific server or server port given
|
# A specific server or server port given
|
||||||
|
|
||||||
if [ -n "$natrule" ]; then
|
if [ -n "$natrule" ]; then
|
||||||
|
lib_load nat "$logtarget Rules"
|
||||||
add_nat_rule
|
add_nat_rule
|
||||||
[ $policy = ACCEPT ] && return
|
[ $policy = ACCEPT ] && return
|
||||||
elif [ -n "$servport" -a "$servport" != "$port" ]; then
|
elif [ -n "$servport" -a "$servport" != "$port" ]; then
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
|
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
|
||||||
#
|
#
|
||||||
# This library is loaded by /usr/share/shorewall/compiler when any of the following
|
# This library is loaded by /usr/share/shorewall/compiler when any of the following
|
||||||
# configuration files are non-empty: masq, nat, netmap
|
# configuration files are non-empty: masq, nat, netmap; or when there are
|
||||||
|
# DNAT/REDIRECT rules in the /etc/shorewall/rules file.
|
||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -580,3 +581,192 @@ setup_netmap() {
|
|||||||
|
|
||||||
done < $TMP_DIR/netmap
|
done < $TMP_DIR/netmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add a NAT rule - Helper function for the rules file processor
|
||||||
|
#
|
||||||
|
# The caller has established the following variables:
|
||||||
|
# cli = Source IP, interface or MAC Specification
|
||||||
|
# serv = Destination IP Specification
|
||||||
|
# servport = Port the server is listening on
|
||||||
|
# dest_interface = Destination Interface Specification
|
||||||
|
# proto = Protocol Specification
|
||||||
|
# addr = Original Destination Address
|
||||||
|
# dports = Destination Port Specification. 'dports' may be changed
|
||||||
|
# by this function
|
||||||
|
# cport = Source Port Specification
|
||||||
|
# multiport = String to invoke multiport match if appropriate
|
||||||
|
# ratelimit = Optional rate limiting clause
|
||||||
|
# userandgroup = -m owner match to limit the rule to a particular user and/or group
|
||||||
|
# logtag = Log tag
|
||||||
|
# excludesource = Source Exclusion List
|
||||||
|
#
|
||||||
|
add_nat_rule() {
|
||||||
|
local chain
|
||||||
|
local excludedests=
|
||||||
|
|
||||||
|
# Be sure we can NAT
|
||||||
|
|
||||||
|
if [ -z "$NAT_ENABLED" ]; then
|
||||||
|
fatal_error "Rule \"$rule\" requires NAT which is disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse SNAT address if any
|
||||||
|
|
||||||
|
if [ "$addr" != "${addr%:*}" ]; then
|
||||||
|
fatal_error "SNAT may no longer be specified in a DNAT rule; use ${CONFDIR}/masq instead"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set original destination address
|
||||||
|
|
||||||
|
case $addr in
|
||||||
|
all)
|
||||||
|
addr=
|
||||||
|
;;
|
||||||
|
detect)
|
||||||
|
eval interfaces=\$${source}_interfaces
|
||||||
|
|
||||||
|
if [ -n "$DETECT_DNAT_IPADDRS" -a "$source" != "$FW" ]; then
|
||||||
|
|
||||||
|
save_command
|
||||||
|
if [ $(list_count1 $interfaces) -eq 1 ]; then
|
||||||
|
save_command "addr=\$(find_first_interface_address $interfaces)"
|
||||||
|
else
|
||||||
|
save_command "addr="
|
||||||
|
for interface in $interfaces; do
|
||||||
|
ident >&3 << __EOF__
|
||||||
|
addr="\$addr \$(find_first_interface_address $interface)"
|
||||||
|
__EOF__
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
addr=
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
!*)
|
||||||
|
if [ $(list_count $addr) -gt 1 ]; then
|
||||||
|
excludedests="${addr#\!}"
|
||||||
|
addr=
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
addr=${addr:-0.0.0.0/0}
|
||||||
|
|
||||||
|
# Select target
|
||||||
|
|
||||||
|
if [ "$logtarget" = SAME ]; then
|
||||||
|
[ -n "$servport" ] && fatal_error "Port mapping not allowed in SAME rules"
|
||||||
|
serv1=
|
||||||
|
for srv in $(separate_list $serv); do
|
||||||
|
serv1="$serv1 --to ${srv}"
|
||||||
|
done
|
||||||
|
target1="SAME $serv1"
|
||||||
|
elif [ -n "$serv" ]; then
|
||||||
|
servport="${servport:+:$servport}"
|
||||||
|
serv1=
|
||||||
|
for srv in $(separate_list $serv); do
|
||||||
|
serv1="$serv1 --to-destination ${srv}${servport}"
|
||||||
|
done
|
||||||
|
target1="DNAT $serv1"
|
||||||
|
else
|
||||||
|
target1="REDIRECT --to-port $servport"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate nat table rules
|
||||||
|
|
||||||
|
if [ "$source" = "$FW" ]; then
|
||||||
|
if [ -n "${excludesource}${excludedests}" ]; then
|
||||||
|
build_exclusion_chain chain nat "$excludesource" $excludedests
|
||||||
|
|
||||||
|
for adr in $(separate_list $addr); do
|
||||||
|
run_iptables2 -t nat -A OUTPUT $cli $proto $userandgroup $multiport $sports $dports $(dest_ip_range $adr) -j $chain
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$loglevel" ]; then
|
||||||
|
log_rule_limit $loglevel $chain OUTPUT $logtarget "$ratelimit" "$logtag" -A -t nat
|
||||||
|
fi
|
||||||
|
|
||||||
|
addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection
|
||||||
|
else
|
||||||
|
for adr in $(separate_list $addr); do
|
||||||
|
if [ -n "$loglevel" ]; then
|
||||||
|
log_rule_limit $loglevel OUTPUT OUTPUT $logtarget "$ratelimit" "$logtag" -A -t nat \
|
||||||
|
$(fix_bang $proto $cli $sports $userandgroup $(dest_ip_range $adr) $multiport $dports)
|
||||||
|
fi
|
||||||
|
|
||||||
|
run_iptables2 -t nat -A OUTPUT $ratelimit $proto $sports $userandgroup $(dest_ip_range $adr) $multiport $dports -j $target1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -n "${excludesource}${excludedests}" ]; then
|
||||||
|
build_exclusion_chain chain nat "$excludesource" $excludedests
|
||||||
|
|
||||||
|
if [ $addr = detect ]; then
|
||||||
|
ensurenatchain $(dnat_chain $source)
|
||||||
|
#
|
||||||
|
# The 'for loops' begun below are completed in add_a_rule() whose declaration follows
|
||||||
|
#
|
||||||
|
indent >&3 << __EOF__
|
||||||
|
|
||||||
|
for adr in \$addr; do
|
||||||
|
run_iptables -t nat -A $(fix_bang $(dnat_chain $source) $cli $proto $multiport $sports $dports) -d \$adr -j $chain
|
||||||
|
__EOF__
|
||||||
|
else
|
||||||
|
for adr in $(separate_list $addr); do
|
||||||
|
addnatrule $(dnat_chain $source) $cli $proto $multiport $sports $dports $(dest_ip_range $adr) -j $chain
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$loglevel" ]; then
|
||||||
|
log_rule_limit $loglevel $chain $(dnat_chain $source) $logtarget "$ratelimit" "$logtag" -A -t nat
|
||||||
|
fi
|
||||||
|
|
||||||
|
addnatrule $chain $ratelimit $proto -j $target1 # Protocol is necessary for port redirection
|
||||||
|
else
|
||||||
|
chain=$(dnat_chain $source)
|
||||||
|
|
||||||
|
if [ $addr = detect ]; then
|
||||||
|
ensurenatchain $chain
|
||||||
|
|
||||||
|
indent >&3 << __EOF__
|
||||||
|
|
||||||
|
for adr in \$addr; do
|
||||||
|
__EOF__
|
||||||
|
if [ -n "$loglevel" ]; then
|
||||||
|
indent >&3 << __EOF__
|
||||||
|
log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A -t nat $(fix_bang $proto $cli $sports $multiport $dports) -d \$adr
|
||||||
|
__EOF__
|
||||||
|
fi
|
||||||
|
|
||||||
|
indent >&3 << __EOF__
|
||||||
|
run_iptables -t nat -A $chain $(fix_bang $proto $ratelimit $cli $sports $multiport $dports) -d \$adr -j $target1
|
||||||
|
__EOF__
|
||||||
|
else
|
||||||
|
for adr in $(separate_list $addr); do
|
||||||
|
if [ -n "$loglevel" ]; then
|
||||||
|
ensurenatchain $chain
|
||||||
|
log_rule_limit $loglevel $chain $chain $logtarget "$ratelimit" "$logtag" -A -t nat \
|
||||||
|
$(fix_bang $proto $cli $sports $(dest_ip_range $adr) $multiport $dports)
|
||||||
|
fi
|
||||||
|
|
||||||
|
addnatrule $chain $proto $ratelimit $cli $sports \
|
||||||
|
-d $adr $multiport $dports -j $target1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Replace destination port by the new destination port
|
||||||
|
|
||||||
|
if [ -n "$servport" ]; then
|
||||||
|
if [ -z "$multiport" ]; then
|
||||||
|
dports="--dport ${servport#*:}"
|
||||||
|
else
|
||||||
|
dports="--dports ${servport#*:}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ "x$addr" = "x0.0.0.0/0" ] && addr=
|
||||||
|
ratelimit=
|
||||||
|
}
|
||||||
|
@ -122,7 +122,8 @@ New Features:
|
|||||||
option in /etc/shorewall/interfaces or /etc/shorewall/hosts.
|
option in /etc/shorewall/interfaces or /etc/shorewall/hosts.
|
||||||
|
|
||||||
- lib.nat. Must be available if you have entries in
|
- lib.nat. Must be available if you have entries in
|
||||||
/etc/shorewall/masq, /etc/shorewall/nat or /etc/shorewall/netmap.
|
/etc/shorewall/masq, /etc/shorewall/nat or /etc/shorewall/netmap
|
||||||
|
or if you use DNAT or REDIRECT rules.
|
||||||
|
|
||||||
- lib.providers. Must be available if you have entries in
|
- lib.providers. Must be available if you have entries in
|
||||||
/etc/shorewall/providers.
|
/etc/shorewall/providers.
|
||||||
|
Loading…
Reference in New Issue
Block a user