New host `orange'.
[firewall] / functions.m4
index 27bacc6..ebc1661 100644 (file)
@@ -94,12 +94,12 @@ ip46tables () {
 ## Ensure that the named chains exist and are empty.
 clearchain () {
   set -e
-  for chain; do
-    case $chain in
-      *:*) table=${chain%:*} chain=${chain#*:} ;;
+  for _chain; do
+    case $_chain in
+      *:*) table=${_chain%:*} _chain=${_chain#*:} ;;
       *) table=filter ;;
     esac
-    run ip46tables -t $table -N $chain 2>/dev/null || :
+    run ip46tables -t $table -N $_chain 2>/dev/null || :
   done
 }
 
@@ -130,7 +130,7 @@ errorchain () {
   clearchain $table:$chain
   run ip46tables -t $table -A $chain -j LOG \
          -m limit --limit 3/minute --limit-burst 10 \
-         --log-prefix "fw: $chain " --log-level notice
+         --log-prefix "fw: $chain " --log-level notice || :
   run ip46tables -t $table -A $chain -j "$@" \
          -m limit --limit 20/second --limit-burst 100
   run ip46tables -t $table -A $chain -j DROP
@@ -310,6 +310,26 @@ dnsresolver () {
   done
 }
 
+## dnsserver CHAIN
+##
+## Add rules to allow CHAIN to be a DNS server.
+dnsserver () {
+  set -e
+  chain=$1
+
+  ## Allow TCP access.  Hitting us with SYNs will make us deploy SYN cookies,
+  ## but that's tolerable.
+  run ip46tables -A $chain -j ACCEPT -p tcp --destination-port 53
+
+  ## Avoid being a DDoS amplifier by rate-limiting incoming DNS queries.
+  clearchain $chain-udp-dns
+  run ip46tables -A $chain-udp-dns -j ACCEPT \
+         -m limit --limit 20/second --limit-burst 300
+  run ip46tables -A $chain-udp-dns -g dns-rate-limit
+  run ip46tables -A $chain -j $chain-udp-dns \
+         -p udp --destination-port 53
+}
+
 ## openports CHAIN [MIN MAX]
 ##
 ## Add rules to CHAIN to allow the open ports.
@@ -407,9 +427,9 @@ defnetclass () {
        from=$(( $from + $bit ))
       done
       to=$(( ($netclassindex << $BIT_TO) ))
-      tomask=$(( $MASK_MASK ^ (1 << ($netclassindex + $BIT_MASK)) ))
+      tomask=$(( $MASK_TO | $MASK_MASK ^ (1 << ($netclassindex + $BIT_MASK)) ))
       trace "from $name --> set $(printf %08x/%08x $from $frommask)"
-      trace "  to $name --> and $(printf %08x/%08x $to $tomask)"
+      trace "  to $name --> set $(printf %08x/%08x $to $tomask)"
 
       ## Now establish the mark-from-NAME and mark-to-NAME chains.
       clearchain mangle:mark-from-$name mangle:mark-to-$name
@@ -513,14 +533,19 @@ host () {
 defhost () {
   host=$1
   addword allhosts $host
-  eval host_type_$host=endsys
+  eval host_type_$host=server
 }
 
-## router
+## hosttype TYPE
 ##
-## Declare the host to be a router, so it should forward packets and so on.
-router () {
-  eval host_type_$host=router
+## Declare the host to have the given type.
+hosttype () {
+  type=$1
+  case $type in
+    router | server | client) ;;
+     *) echo >&2 "$0: bad host type \`$type'"; exit 1 ;;
+  esac
+  eval host_type_$host=$type
 }
 
 ## iface IFACE NET ...
@@ -534,15 +559,18 @@ iface () {
   done
 }
 
+## matchnets OPT WIN FLAGS PREPARE BASE SUFFIX NEXT NET [NET ...]
+##
 ## Build rules which match a particular collection of networks.
+##
 ## Specifically, use the address-comparison operator OPT (typically `-s' or
-## `-d') to match the addresses of NOT, writing the rules to the chain
-## BASESUFFIX.  If we find a match, dispatch to WIN-CLASS, where CLASS is
-## the class of the matching network.  In order to deal with networks
-## containing negative address ranges, more chains may need to be
-## constructed; they will be named BASE#Q for sequence numbers Q starting
-## with NEXT.  All of this happens on the `mangle' table, and there isn't
-## (currently) a way to tweak this.
+## `-d') to match the addresses of each NET, writing the rules to the chain
+## BASESUFFIX.  If we find a match, dispatch to WIN-CLASS, where CLASS is the
+## class of the matching network.  In order to deal with networks containing
+## negative address ranges, more chains may need to be constructed; they will
+## be named BASE#Q for sequence numbers Q starting with NEXT.  All of this
+## happens on the `mangle' table, and there isn't (currently) a way to tweak
+## this.
 ##
 ## The FLAGS gather additional interesting information about the job,
 ## separated by colons.  The only flag currently is :default: which means