Commit b64ca400 authored by Branko Mikić's avatar Branko Mikić
Browse files

~ BugFix! The FORWARD_PORT target host argument didn't handle the optional...

~ BugFix! The FORWARD_PORT target host argument didn't handle the optional port correctly when omitted. This has been fixed.
~ ALLOW_PORT and FORWARD_PORT now have an optional protocol argument. When omitted ALLOW_PORT creates rules for both protocols (tcp|udp) while FORWARD_PORT defaults to tcp only.
~ checkProtocol() function added for argument check.
~ formatSubnetAsHexID() function renamed to formatAsHexID() as the function can be used on either an IP address or a subnet mask.
parent fc9a37d3
...@@ -15,10 +15,10 @@ printAbout() ...@@ -15,10 +15,10 @@ printAbout()
[ALLOW_LINK_LOCAL on_link] [ALLOW_LINK_LOCAL on_link]
[ALLOW_SERVICE_DISCOVERY on_link] [ALLOW_SERVICE_DISCOVERY on_link]
[ALLOW_TUNNEL mode on_link from_address] [ALLOW_TUNNEL mode on_link from_address]
[ALLOW_PORT|ALLOW_SERVICE port[,port,port,...] ip|link] [ALLOW_PORT|ALLOW_SERVICE port[,port,port,...] ip|link [tcp|udp]]
[FORWARD_SUBNET subnet/mask to_link] [FORWARD_SUBNET subnet/mask to_link]
[FORWARD_SUBNET_PROTECTIVE subnet/mask to_link] [FORWARD_SUBNET_PROTECTIVE subnet/mask to_link]
[FORWARD_PORT|FORWARD_ROUTING ip|link port(s) to_address[:to_port]] [FORWARD_PORT|FORWARD_ROUTING ip|link port(s) to_address[:to_port] [tcp|udp]]
[MAC_FILTER chain mac_address] [MAC_FILTER chain mac_address]
[POSTROUTING_MASQUERADE subnet/mask to_link] [POSTROUTING_MASQUERADE subnet/mask to_link]
[DEBUG_CHAIN chain_name] [DEBUG_CHAIN chain_name]
...@@ -313,6 +313,22 @@ checkSubnetArgFormat() ...@@ -313,6 +313,22 @@ checkSubnetArgFormat()
return $? return $?
} }
###
### $1: Either tcp or udp
###
### Returns a string either 'tcp', 'udp'
### or 'any' if none of the other
###
checkProtocol()
{
echo $1 | grep -iP "(tcp|udp)" 1>/dev/nul 2>/dev/nul
if (($? == 0)); then
printf $1
else
printf "any"
fi
}
### ###
### $1: chain to search for device occurence in any rule ### $1: chain to search for device occurence in any rule
### ###
...@@ -451,7 +467,7 @@ deallocChain() ...@@ -451,7 +467,7 @@ deallocChain()
### ###
### Prints a hexadecimal representation (eg: 0xC0A8000010) ### Prints a hexadecimal representation (eg: 0xC0A8000010)
### ###
formatSubnetAsHexID() { formatAsHexID() {
local sz; local sy; local sz; local sy;
# sed using bash! ${1//REPLACE_ME/WITH_THIS} # sed using bash! ${1//REPLACE_ME/WITH_THIS}
if [ $ENVID -eq 4 ]; then if [ $ENVID -eq 4 ]; then
...@@ -853,6 +869,9 @@ formatSubnetAsHexID() { ...@@ -853,6 +869,9 @@ formatSubnetAsHexID() {
(( $? != 0 )) && error 70 "ALLOW_PORT expects a destination port or ports argument (eg: 80,443)" (( $? != 0 )) && error 70 "ALLOW_PORT expects a destination port or ports argument (eg: 80,443)"
done done
# $3 == protocol?
PROTO=$(checkProtocol $3)
# $2 == device node or IP address? # $2 == device node or IP address?
checkIPArgFormat "$2" checkIPArgFormat "$2"
if (( $? != 0 )); then if (( $? != 0 )); then
...@@ -862,23 +881,30 @@ formatSubnetAsHexID() { ...@@ -862,23 +881,30 @@ formatSubnetAsHexID() {
(( $? != 0 )) && printf "# WARNING! '$2' currently not available. Maybe invoked later?\n" (( $? != 0 )) && printf "# WARNING! '$2' currently not available. Maybe invoked later?\n"
FILTER_BY="-i $2" FILTER_BY="-i $2"
printf "# allow port(s): %s to reach %s\n (WARNING! Ports reachable for any address configured on this device! Maybe this is unintended?)\n" $1 $2 printf "# allow port(s): %s (%s) to reach %s\n (WARNING! Ports reachable for any address configured on this device! Maybe this is unintended?)\n" $1 $PROTO $2
sz="$2"
else else
sz=$(obtainNetPrefix $2) sz=$(obtainNetPrefix $2)
[ -z $sz ] && error 73 "ALLOW_PORT has no route to '$2' or argument has malformed IP format" [ -z $sz ] && error 73 "ALLOW_PORT has no route to '$2' or argument has malformed IP format"
sz=$(obtainLinkFromSubnetPrefix $sz)
FILTER_BY="-d $2" FILTER_BY="-d $2"
printf "# allow port(s): %s to reach %s on %s\n" $1 $2 $sz printf "# allow port(s): %s (%s) to reach %s on %s\n" $1 $PROTO $2 $(obtainLinkFromSubnetPrefix $sz)
sz="$(formatAsHexID $2)"
fi fi
ID="ALLOW_PORT_$1_$(formatSubnetAsHexID $2)_$sz" ID="ALLOW_PORT_$1_$sz"
deleteRules USER-IN "$ID" deleteRules USER-IN "$ID"
$IPTABLES -A USER-IN $FILTER_BY -p tcp -m multiport --dports $1 -j ACCEPT -m comment --comment "$ID" if [[ $PROTO =~ any ]]; then
$IPTABLES -A USER-IN $FILTER_BY -p tcp -m multiport --ports $1 -j ACCEPT -m comment --comment "$ID"
$IPTABLES -A USER-IN $FILTER_BY -p udp -m multiport --ports $1 -j ACCEPT -m comment --comment "$ID"
else
$IPTABLES -A USER-IN $FILTER_BY -p $PROTO -m multiport --ports $1 -j ACCEPT -m comment --comment "$ID"
shift;
fi
shift; shift; shift; shift;
unset FILTER_BY; unset ay; unset ID; unset FILTER_BY; unset PROTO; unset ay; unset ID;
;; ;;
FORWARD_SUBNET) FORWARD_SUBNET)
...@@ -930,12 +956,12 @@ formatSubnetAsHexID() { ...@@ -930,12 +956,12 @@ formatSubnetAsHexID() {
(( $? != 0 )) && sz=" (WARNING! '$2' currently not available. Maybe invoked later?)" (( $? != 0 )) && sz=" (WARNING! '$2' currently not available. Maybe invoked later?)"
printf "# forwarding protectively %s (%s) to %s.%s\n" $1 $DEV $2 "$sz" printf "# forwarding protectively %s (%s) to %s.%s\n" $1 $DEV $2 "$sz"
ID=$(printf "FORWARD_SUBNET_PROTECTIVE_%s_%s_%s" $DEV $(formatSubnetAsHexID "$1") $2) ID=$(printf "FORWARD_SUBNET_PROTECTIVE_%s_%s_%s" $DEV $(formatAsHexID "$1") $2)
deleteRules FORWARD "$ID" deleteRules FORWARD "$ID"
# for IPv6 subnets the max chain name length can # for IPv6 subnets the max chain name length can
# be easily exceeded so we need a shorter name # be easily exceeded so we need a shorter name
#CHAIN=$(printf "%s-%s-%s" $(formatSubnetAsHexID "$1") $2 $DEV) #CHAIN=$(printf "%s-%s-%s" $(formatAsHexID "$1") $2 $DEV)
CHAIN=$(printf "%X-IN" $(cksum <<<"$ID" | grep -oP "^\d*")) CHAIN=$(printf "%X-IN" $(cksum <<<"$ID" | grep -oP "^\d*"))
allocChain $CHAIN allocChain $CHAIN
...@@ -965,8 +991,6 @@ formatSubnetAsHexID() { ...@@ -965,8 +991,6 @@ formatSubnetAsHexID() {
$IPTABLES -I FORWARD $n -i $2 -o $DEV -d $1 -j $CHAIN -m comment --comment "$ID" $IPTABLES -I FORWARD $n -i $2 -o $DEV -d $1 -j $CHAIN -m comment --comment "$ID"
# for IPv6 subnets the max chain name length can
# be easily exceeded so we need a shorter name
CHAIN=$(printf "%X-OUT" $(cksum <<<"$ID" | grep -oP "^\d*")) CHAIN=$(printf "%X-OUT" $(cksum <<<"$ID" | grep -oP "^\d*"))
allocChain $CHAIN allocChain $CHAIN
...@@ -1011,7 +1035,11 @@ formatSubnetAsHexID() { ...@@ -1011,7 +1035,11 @@ formatSubnetAsHexID() {
# create a mark ID (cksum) # create a mark ID (cksum)
MARK_ID=$(printf "0x%x" $(cksum <<<"$1$2$3" | grep -oP "^\d*")) MARK_ID=$(printf "0x%x" $(cksum <<<"$1$2$3" | grep -oP "^\d*"))
printf "# prerouting port fowarding from %s:%s to %s (MARK_ID: %s)\n" $1 $2 $3 $MARK_ID # $4 == protocol (tcp|udp) with 'tcp' as default when not specified
PROTO=$(checkProtocol $4)
[[ $PROTO =~ any ]] && PROTO=tcp
printf "# prerouting port fowarding from %s:%s to %s (ID: %s)\n" $1 $2 $3 $MARK_ID
ID="FORWARD_ROUTING $MARK_ID" ID="FORWARD_ROUTING $MARK_ID"
deleteRules FORWARD "$ID" deleteRules FORWARD "$ID"
...@@ -1023,8 +1051,8 @@ formatSubnetAsHexID() { ...@@ -1023,8 +1051,8 @@ formatSubnetAsHexID() {
# This may look complicated but makes absolutely sense since our POSTROUTING # This may look complicated but makes absolutely sense since our POSTROUTING
# needs to distinguish from traffic carrying our MARK_ID _and_ traffic on the # needs to distinguish from traffic carrying our MARK_ID _and_ traffic on the
# corresponding port returned from the forwarded host. # corresponding port returned from the forwarded host.
$IPTABLES -t nat -A PREROUTING $FILTER_BY -p tcp -m multiport --dports $2 -j MARK --set-mark $MARK_ID -m comment --comment "$ID" $IPTABLES -t nat -A PREROUTING $FILTER_BY -p $PROTO -m multiport --dports $2 -j MARK --set-mark $MARK_ID -m comment --comment "$ID"
$IPTABLES -t nat -A PREROUTING -m mark --mark $MARK_ID -p tcp -j DNAT --to $3 -m comment --comment "$ID" $IPTABLES -t nat -A PREROUTING -m mark --mark $MARK_ID -p $PROTO -j DNAT --to $3 -m comment --comment "$ID"
# prerouting rewrites destination address for marked packets therefore these # prerouting rewrites destination address for marked packets therefore these
# go through the FORWARD chain instead of INPUT, to avoid having other rules # go through the FORWARD chain instead of INPUT, to avoid having other rules
...@@ -1035,16 +1063,16 @@ formatSubnetAsHexID() { ...@@ -1035,16 +1063,16 @@ formatSubnetAsHexID() {
# allow packets back & forth from the forwarded host # allow packets back & forth from the forwarded host
# Attention! >> These response packets are _not_ carrying our MARK_ID # Attention! >> These response packets are _not_ carrying our MARK_ID
# therefore these rules are all inserted at index 1 so order matters! # therefore these rules are all inserted at index 1 so order matters!
sz=${3#*:} [[ $3 =~ : ]] && sz=${3#*:} || sz=$2
[ -z $sz ] && sz=$2 $IPTABLES -I FORWARD 1 -p $PROTO -s ${3%:*}/32 -m multiport --sports $sz -j ACCEPT -m comment --comment "$ID"
$IPTABLES -I FORWARD 1 -p tcp -s ${3%:*}/32 -m multiport --sports $sz -j ACCEPT -m comment --comment "$ID" $IPTABLES -I FORWARD 1 -p $PROTO -d ${3%:*}/32 -m multiport --dports $sz -j ACCEPT -m comment --comment "$ID"
$IPTABLES -I FORWARD 1 -p tcp -d ${3%:*}/32 -m multiport --dports $sz -j ACCEPT -m comment --comment "$ID"
# Masquerade only those carrying our MARK_ID! # Masquerade only those carrying our MARK_ID!
$IPTABLES -t nat -I POSTROUTING 1 -m mark --mark $MARK_ID -d ${3%:*}/32 -j MASQUERADE -m comment --comment "$ID" $IPTABLES -t nat -I POSTROUTING 1 -m mark --mark $MARK_ID -d ${3%:*}/32 -j MASQUERADE -m comment --comment "$ID"
shift; shift; shift; shift; shift; shift;
unset FILTER_BY; unset MARK_ID; [[ $(checkProtocol $4) =~ any ]] && shift
unset FILTER_BY; unset PROTO; unset MARK_ID;
unset ID; unset ID;
;; ;;
...@@ -1082,7 +1110,7 @@ formatSubnetAsHexID() { ...@@ -1082,7 +1110,7 @@ formatSubnetAsHexID() {
(( $? != 0 )) && sz=" (WARNING! '$2' currently not available. Maybe invoked later?)" (( $? != 0 )) && sz=" (WARNING! '$2' currently not available. Maybe invoked later?)"
printf "# masquerading %s when leaving through %s.%s\n" $1 $2 "$sz" printf "# masquerading %s when leaving through %s.%s\n" $1 $2 "$sz"
ID=$(printf "POSTROUTING_MASQUERADE %s_%s_%s" $(obtainLinkFromSubnetPrefix $1) $(formatSubnetAsHexID "$1") $2) ID=$(printf "POSTROUTING_MASQUERADE %s_%s_%s" $(obtainLinkFromSubnetPrefix $1) $(formatAsHexID "$1") $2)
deleteRules -t nat POSTROUTING "$ID" deleteRules -t nat POSTROUTING "$ID"
$IPTABLES -t nat -A POSTROUTING -s $1 -o $2 -j MASQUERADE -m comment --comment "$ID" $IPTABLES -t nat -A POSTROUTING -s $1 -o $2 -j MASQUERADE -m comment --comment "$ID"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment