-### -*-m4-*-
+### -*-sh-*-
###
### Utility functions for firewall scripts
###
###--------------------------------------------------------------------------
### Basic chain constructions.
+## ip46tables ARGS ...
+##
+## Do the same thing for `iptables' and `ip6tables'.
+ip46tables () {
+ set -e
+ iptables "$@"
+ ip6tables "$@"
+}
+
## clearchain CHAIN CHAIN ...
##
## Ensure that the named chains exist and are empty.
*:*) table=${chain%:*} chain=${chain#*:} ;;
*) table=filter ;;
esac
- run iptables -t $table -N $chain
+ run ip46tables -t $table -N $chain
done
}
*) table=filter ;;
esac
clearchain $table:$chain
- run iptables -t $table -A $chain -j LOG \
+ run ip46tables -t $table -A $chain -j LOG \
-m limit --limit 3/minute --limit-burst 10 \
--log-prefix "fw: $chain " --log-level notice
- run iptables -t $table -A $chain -j "$@"
+ run ip46tables -t $table -A $chain -j "$@"
}
m4_divert(24)m4_dnl
conntrack () {
set -e
chain=$1
- run iptables -A $chain -p tcp -m state \
+ run ip46tables -A $chain -p tcp -m state \
--state ESTABLISHED,RELATED -j ACCEPT
- run iptables -A $chain -p tcp ! --syn -g bad-tcp
+ run ip46tables -A $chain -p tcp ! --syn -g bad-tcp
+}
+
+## commonrules CHAIN
+##
+## Add standard IP filtering rules to the CHAIN.
+commonrules () {
+ set -e
+ chain=$1
+
+ ## Pass fragments through, assuming that the eventual destination will sort
+ ## things out properly. Except for TCP, that is, which should never be
+ ## fragmented.
+ run iptables -A $chain -p tcp -f -g tcp-fragment
+ run iptables -A $chain -f -j ACCEPT
+ run ip6tables -A $chain -p tcp -g tcp-fragment \
+ -m ipv6header --soft --header frag
+ run ip6tables -A $chain -j ACCEPT \
+ -m frag ! --fragfirst
}
## allowservices CHAIN PROTO SERVICE ...
for svc; do
case $svc in
*:*)
- n=2
+ n=2
left=${svc%:*} right=${svc#*:}
case $left in *[!0-9]*) eval left=\$port_$left ;; esac
case $right in *[!0-9]*) eval right=\$port_$right ;; esac
svc=$left:$right
;;
*)
- n=1
+ n=1
case $svc in *[!0-9]*) eval svc=\$port_$svc ;; esac
;;
esac
case $svc in
*: | :* | "" | *[!0-9:]*)
- echo >&2 "Bad service name"
+ echo >&2 "Bad service name"
exit 1
;;
esac
count=$(( $count + $n ))
if [ $count -gt 15 ]; then
- run iptables -A $chain -p $proto -m multiport -j ACCEPT \
+ run ip46tables -A $chain -p $proto -m multiport -j ACCEPT \
--destination-ports ${list#,}
list= count=$n
fi
"")
;;
,*,*)
- run iptables -A $chain -p $proto -m multiport -j ACCEPT \
+ run ip46tables -A $chain -p $proto -m multiport -j ACCEPT \
--destination-ports ${list#,}
;;
- *)
- run iptables -A $chain -p $proto -j ACCEPT \
+ *)
+ run ip46tables -A $chain -p $proto -j ACCEPT \
--destination-port ${list#,}
;;
esac
set -e
chain=$1
for p in tcp udp; do
- run iptables -A $chain -j ACCEPT \
+ run ip46tables -A $chain -j ACCEPT \
-m state --state ESTABLISHED \
-p $p --source-port 53
done
set -e
chain=$1; shift
[ $# -eq 0 ] && set -- $open_port_min $open_port_max
- run iptables -A $chain -p tcp -g interesting --destination-port $1:$2
- run iptables -A $chain -p udp -g interesting --destination-port $1:$2
+ run ip46tables -A $chain -p tcp -g interesting --destination-port $1:$2
+ run ip46tables -A $chain -p udp -g interesting --destination-port $1:$2
}
m4_divert(28)m4_dnl
from=$(( $from + $bit ))
done
to=$(( ($netclassindex << $BIT_TO) + \
- (0xf << $BIT_FROM) + \
+ (0xf << $BIT_FROM) + \
(1 << ($netclassindex + $BIT_MASK)) ))
trace "from $name --> set $(printf %x $from)"
trace " to $name --> and $(printf %x $from)"
## Now establish the mark-from-NAME and mark-to-NAME chains.
clearchain mangle:mark-from-$name mangle:mark-to-$name
- run iptables -t mangle -A mark-from-$name -j MARK --set-mark $from
- run iptables -t mangle -A mark-to-$name -j MARK --and-mark $to
+ run ip46tables -t mangle -A mark-from-$name -j MARK --set-mark $from
+ run ip46tables -t mangle -A mark-to-$name -j MARK --and-mark $to
;;
esac
netclassindex=$(( $netclassindex + 1 ))
## indicates that all addresses not matched elsewhere should be considered.
ifaces=:
defaultiface=none
-allnets=
+allnets= allnets6=
defiface () {
set -e
name=$1; shift
*:"$name":*) ;;
*)
clearchain mangle:in-$name
- run iptables -t mangle -A in-classify -i $name -g in-$name
+ run ip46tables -t mangle -A in-classify -i $name -g in-$name
;;
esac
ifaces=$ifaces$name:
default)
defaultiface=$name
defaultclass=$netclass
- run iptables -t mangle -A out-classify -g mark-to-$netclass
+ run ip46tables -t mangle -A out-classify -g mark-to-$netclass
+ ;;
+ *:*)
+ run ip6tables -t mangle -A in-$name -s $addr -g mark-from-$netclass
+ run ip6tables -t mangle -A out-classify -d $addr -g mark-to-$netclass
+ allnets6="$allnets6 $name:$addr"
;;
*)
run iptables -t mangle -A in-$name -s $addr -g mark-from-$netclass
*-+)
root=${iface%+}
for host; do
- name=${host%:*} addr=${host#*:}
+ name=${host%%:*} addr=${host#*:}
defiface $root$name $class:$addr
done
;;