eval port_$name=$number
}
+m4_divert(38)m4_dnl
+###--------------------------------------------------------------------------
+### Utility chains (used by function definitions).
+
m4_divert(22)m4_dnl
###--------------------------------------------------------------------------
### Basic chain constructions.
## Pass fragments through, assuming that the eventual destination will sort
## things out properly. Except for TCP, that is, which should never be
- ## fragmented.
+ ## fragmented. This is an extra pain for ip6tables, which doesn't provide
+ ## a pleasant way to detect non-initial fragments.
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
+ run ip6tables -A $chain -j accept-non-init-frag
}
+m4_divert(38)m4_dnl
+## Accept a non-initial fragment. This is only needed by IPv6, to work
+## around a deficiency in the option parser.
+run ip6tables -N accept-non-init-frag
+run ip6tables -A accept-non-init-frag -j RETURN \
+ -m frag --fragfirst
+run ip6tables -A accept-non-init-frag -j ACCEPT
+
+m4_divert(26)m4_dnl
## allowservices CHAIN PROTO SERVICE ...
##
## Add rules to allow the SERVICES on the CHAIN.
###--------------------------------------------------------------------------
### Special forwarding exemptions.
+## Only allow these packets if they're not fragmented. (Don't trust safe
+## hosts's fragment reassembly to be robust against malicious fragments.)
+## There's a hideous bug in iptables 1.4.11.1 which botches the meaning of
+## `! -f', so we do the negation using early return from a subchain.
+clearchain fwd-spec-nofrag
+run iptables -A fwd-spec-nofrag -j RETURN --fragment
+run ip6tables -A fwd-spec-nofrag -j RETURN \
+ -m ipv6header --soft --header frag
+run iptables -A FORWARD -j fwd-spec-nofrag
+
## Allow ping from safe/noloop to untrusted networks.
-run iptables -A FORWARD -j ACCEPT \
- -p icmp ! -f --icmp-type echo-request \
+run iptables -A fwd-spec-nofrag -j ACCEPT \
+ -p icmp --icmp-type echo-request \
-m mark --mark $to_untrusted/$MASK_TO
-run iptables -A FORWARD -j ACCEPT \
- -p icmp ! -f --icmp-type echo-reply \
+run iptables -A fwd-spec-nofrag -j ACCEPT \
+ -p icmp --icmp-type echo-reply \
-m mark --mark $from_untrusted/$MASK_FROM \
-m state --state ESTABLISHED
-run ip6tables -A FORWARD -j ACCEPT \
+run ip6tables -A fwd-spec-nofrag -j ACCEPT \
-p ipv6-icmp --icmpv6-type echo-request \
- -m ipv6header --soft ! --header frag \
-m mark --mark $to_untrusted/$MASK_TO
-run ip6tables -A FORWARD -j ACCEPT \
+run ip6tables -A fwd-spec-nofrag -j ACCEPT \
-p ipv6-icmp --icmpv6-type echo-reply \
- -m ipv6header --soft ! --header frag \
-m mark --mark $from_untrusted/$MASK_FROM \
-m state --state ESTABLISHED
## Allow SSH from safe/noloop to untrusted networks.
-run iptables -A FORWARD -j ACCEPT \
- -p tcp ! -f --destination-port $port_ssh \
+run iptables -A fwd-spec-nofrag -j ACCEPT \
+ -p tcp --destination-port $port_ssh \
-m mark --mark $to_untrusted/$MASK_TO
-run iptables -A FORWARD -j ACCEPT \
- -p tcp ! -f --source-port $port_ssh \
+run iptables -A fwd-spec-nofrag -j ACCEPT \
+ -p tcp --source-port $port_ssh \
-m mark --mark $from_untrusted/$MASK_FROM \
-m state --state ESTABLISHED
-run ip6tables -A FORWARD -j ACCEPT \
+run ip6tables -A fwd-spec-nofrag -j ACCEPT \
-p tcp --destination-port $port_ssh \
- -m ipv6header --soft ! --header frag \
-m mark --mark $to_untrusted/$MASK_TO
-run ip6tables -A FORWARD -j ACCEPT \
+run ip6tables -A fwd-spec-nofrag -j ACCEPT \
-p tcp --source-port $port_ssh \
- -m ipv6header --soft ! --header frag \
-m mark --mark $from_untrusted/$MASK_FROM \
-m state --state ESTABLISHED