## Installation on a local host,
install/$(THISHOST): $(THISHOST).sh
[ "x$(SCRIPTS)" = x ] || $(ROOT) install -m755 $(SCRIPTS) $(sbindir)
- $(ROOT) ./$(THISHOST).sh replace
+ $(ROOT) ./$(THISHOST).sh replace </dev/tty
## Installation on a remote host.
$(addprefix install/, $(OTHERHOSTS)): install/%: %.sh
### BEGIN INIT INFO
# Provides: firewall
-# Required-Start: mountkernfs
+# Required-Start: $local_fs
# Required-Stop:
# X-Start-Before: ifupdown
# X-Stop-After: ifupdown
###
### The mangle chains are arranged as follows.
###
-### The INPUT and FORWARD hooks simply invokes in-classify and out-classify
+### The INPUT and FORWARD hooks simply invoke in-classify and out-classify
### chains as subroutines. These will tail-call appropriate classification
### chains.
###
### goes to bad-source-address, which logs a message and drops the packet.
### The default interface is special. If no explicit matches are found, it
### dispatches to in-default which forbids a few obviously evil things and
-### finally dispatches to mark-from-untrusted.
+### finally dispatches to mark-from-DEFAULT (usually `untrusted').
###
### The out-classify is simpler because it doesn't care about the interface.
### It simply checks each network range in turn, dispatching to mark-to-CLASS
-### on a match or mark-to-DEFAULT (probably untrusted) if there is no match.
+### on a match or mark-to-DEFAULT (probably `untrusted') if there is no
+### match.
clearchain mangle:in-classify mangle:in-default mangle:out-classify
clearchain mangle:local-source
## over the loopback interface, I shouldn't see a packet from me over any
## other interface. Except that I will if I sent a broadcast or multicast.
## Allow the broadcasts, and remember not to trust them. There are no
-## broadcast addresses in IPv6 (only link-local multicast)m so we don't have
+## broadcast addresses in IPv6 (only link-local multicast) so we don't have
## to worry about that.
run iptables -t mangle -A local-source -j RETURN \
-m addrtype --dst-type BROADCAST
done
## Fill in the black holes in the network. Some of these might actually be
-## known networks, so don't fill those in again. See RFC5735 or its
-## successors.
+## known networks, so don't fill those in again. See RFC5735 and RFC4291,
+## and their successors.
for addr in \
10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 \
127.0.0.0/8 \
done
for addr in \
fc00::/7 \
+ ::0:0/96 ::ffff:0:0/96 \
2001:db8::/32
do
case $alladdrs in *!$addr!*) continue ;; esac
run ip46tables -A $chain -p udp -g interesting --destination-port $1:$2
}
+bcp38_setup=:
+bcp38 () {
+ ipv=$1 ifname=$2; shift 2
+ ## Add rules for BCP38 egress filtering for IP version IPV (either 4 or 6).
+ ## IFNAME is the outgoing interface; the remaining arguments are network
+ ## prefixes.
+
+ ## Sort out which command we're using
+ case $ipv in
+ 4) ipt=iptables ;;
+ 6) ipt=ip6tables ;;
+ *) echo >&2 "Unknown IP version $ipv"; exit 1 ;;
+ esac
+
+ ## If we've not set up the error chain then do that.
+ case $bcp38_setup in
+ :)
+ errorchain bcp38 DROP
+ clearchain bcp38-check
+ ip46tables -A bcp38-check -g bcp38
+ ;;
+ esac
+
+ ## Stitch our egress filter into the outbound chains if we haven't done
+ ## that yet. Do this for both IP versions: if we're only ever given
+ ## IPv6 addresses for a particular interface then we assume that IPv4
+ ## packets aren't allowed on it at all.
+ case $bcp38_setup in
+ *:$ifname:*) ;;
+ *)
+ run ip46tables -A OUTPUT -j bcp38-check -o $ifname
+ case $forward in
+ 1) run ip46tables -A FORWARD -j bcp38-check -o $ifname ;;
+ esac
+ bcp38_setup=$bcp38_setup$ifname:
+ ;;
+ esac
+
+ ## Finally, add in our allowed networks.
+ for i in "$@"; do
+ run $ipt -I bcp38-check -j RETURN -s $i
+ done
+}
+
m4_divert(20)m4_dnl
###--------------------------------------------------------------------------
### Packet classification.
run ip46tables -A check-icmp -j ACCEPT
## Done.
-for i in $inchains; do run ip46tables -A $i -p icmp -j check-icmp; done
+for i in $inchains; do
+ run iptables -A $i -p icmp -j check-icmp
+ run ip6tables -A $i -p icmpv6 -j check-icmp
+done
m4_divert(-1)
###----- That's all, folks --------------------------------------------------
defnet default untrusted
-## Colocated hosts.
-defhost jaguar
+## Hosts.
defhost jaguar
iface eth0 default
+m4_divert(80)m4_dnl
+###--------------------------------------------------------------------------
+### Connection tracking helper modules.
+
+for i in ftp; do
+ modprobe nf_conntrack_$i
+done
+
m4_divert(80)m4_dnl
###--------------------------------------------------------------------------
### Special forwarding exemptions.
run ip46tables -A inbound -j forbidden
run ip46tables -A INPUT -m mark --mark $from_untrusted/$MASK_FROM -g inbound
+## Allow responses from the scary outside world into the untrusted net, but
+## don't let untrusted things run services.
+case $forward in
+ 1)
+ run ip46tables -A FORWARD -j ACCEPT \
+ -m mark --mark $to_untrusted/$(( $MASK_FROM | $MASK_TO )) \
+ -m state --state ESTABLISHED,RELATED
+ ;;
+esac
+
## Otherwise process as indicated by the mark.
for i in $inchains; do
run ip46tables -A $i -m mark ! --mark 0/$MASK_MASK -j ACCEPT
defport netbios_ns 137
defport netbios_dgm 138
defport netbios_ssn 139
+defport imap 143
defport https 443
defport microsoft_ds 445
defport syslog 514 # UDP only!
defport rsync 873
defport imaps 993
defport h323 1720
+defport ssquid 3127
defport squid 3128
defport icp 3130
defport tripe 4070
defport tor_public 9001
defport tor_directory 9030
defport git 9418
+defport pgp_keys 11371
defport i2p 16911
defport disorder 23599
defport udpkey 59274