diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,14 @@
+propellor (4.6.0) unstable; urgency=medium
+
+  * Add Typeable instance to Bootstrapper, fixing build with old versions
+    of ghc.
+  * Network.static changed to take address and gateway parameters.
+    If you used the old Network.static property, it has been renamed to
+    Network.preserveStatic.
+    (Minor API change)
+
+ -- Joey Hess <id@joeyh.name>  Wed, 26 Jul 2017 20:02:50 -0400
+
 propellor (4.5.2) unstable; urgency=medium
 
   * Added Rsync.installed property.
diff --git a/debian/changelog b/debian/changelog
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+propellor (4.6.0) unstable; urgency=medium
+
+  * Add Typeable instance to Bootstrapper, fixing build with old versions
+    of ghc.
+  * Network.static changed to take address and gateway parameters.
+    If you used the old Network.static property, it has been renamed to
+    Network.preserveStatic.
+    (Minor API change)
+
+ -- Joey Hess <id@joeyh.name>  Wed, 26 Jul 2017 20:02:50 -0400
+
 propellor (4.5.2) unstable; urgency=medium
 
   * Added Rsync.installed property.
diff --git a/joeyconfig.hs b/joeyconfig.hs
--- a/joeyconfig.hs
+++ b/joeyconfig.hs
@@ -182,42 +182,72 @@
 
 honeybee :: Host
 honeybee = host "honeybee.kitenet.net" $ props
-	& standardSystem Testing ARMHF [ "Arm git-annex build box." ]
+	& standardSystem Testing ARMHF
+		[ "Home router and arm git-annex build box." ]
 
-	-- I have to travel to get console access, so no automatic
-	-- upgrades, and try to be robust.
+	-- Hard to get console access, so no automatic upgrades,
+	-- and try to be robust.
 	& "/etc/default/rcS" `File.containsLine` "FSCKFIX=yes"
 
+	-- Cubietruck
 	& Apt.installed ["flash-kernel"]
 	& "/etc/flash-kernel/machine" `File.hasContent` ["Cubietech Cubietruck"]
 	& Apt.installed ["linux-image-armmp"]
-	& Network.dhcp "eth0" `requires` Network.cleanInterfacesFile
-	& Postfix.satellite
-
-	-- ipv6 used for remote access thru firewalls
-	& Apt.serviceInstalledRunning "aiccu"
-	& ipv6 "2001:4830:1600:187::2"
-	-- restart to deal with failure to connect, tunnel issues, etc
-	& Cron.job "aiccu restart daily" Cron.Daily (User "root") "/"
-		"service aiccu stop; service aiccu start"
-
-	-- In case compiler needs more than available ram
-	& Apt.serviceInstalledRunning "swapspace"
+	& Apt.installed ["firmware-brcm80211"]
+		-- Workaround for https://bugs.debian.org/844056
+		`requires` File.hasPrivContent "/lib/firmware/brcm/brcmfmac43362-sdio.txt" anyContext
+		`requires` File.dirExists "/lib/firmware/brcm"
 
-	-- No hardware clock.
+	-- No hardware clock
 	& Apt.serviceInstalledRunning "ntp"
 
-	-- Runs only on weekdays.
+	-- Home router
+	& Network.static "eth0" (IPv4 "192.168.1.42")
+		(Just (Network.Gateway (IPv4 "192.168.1.1")))
+		`requires` Network.cleanInterfacesFile
+	& Network.static "wlan0" (IPv4 "10.1.1.1") Nothing
+		`requires` Network.cleanInterfacesFile
+	& Apt.serviceInstalledRunning "hostapd"
+		`requires` File.hasContent "/etc/hostapd/hostapd.conf"
+			[ "interface=wlan0"
+			, "ssid=house"
+			, "hw_mode=g"
+			, "channel=8"
+			]
+		`requires` File.dirExists "/lib/hostapd"
+	& Apt.serviceInstalledRunning "dnsmasq"
+		`requires` File.hasContent "/etc/dnsmasq.conf"
+			[ "domain-needed"
+			, "bogus-priv"
+			, "interface=wlan0"
+			, "domain=kitenet.net"
+			, "dhcp-range=10.1.1.100,10.1.1.150,24h"
+			, "no-hosts"
+			, "address=/honeybee.kitenet.net/10.1.1.1"
+			]
+		`requires` File.hasContent "/etc/resolv.conf"
+			[ "domain kitenet.net"
+			, "search kitenet.net"
+			, "nameserver 8.8.8.8"
+			, "nameserver 8.8.4.4"
+			]
+	& JoeySites.ipmasq "eth0" "wlan0"
+	& Apt.installed ["ppp", "mtr", "iftop", "git-annex", "screen"]
+	& Postfix.satellite
+
+	-- Autobuild runs only on weekdays.
 	& Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer
 		GitAnnexBuilder.armAutoBuilder
-		Unstable ARMEL Nothing weekends "23h")
-	-- Runs only on weekends.
+		Unstable ARMEL Nothing weekends "10h")
+	-- Autobuild runs only on weekends.
 	& Systemd.nspawned (GitAnnexBuilder.autoBuilderContainer
 		GitAnnexBuilder.stackAutoBuilder
-		(Stable "jessie") ARMEL (Just "ancient") weekdays "23h")
+		(Stable "jessie") ARMEL (Just "ancient") weekdays "10h")
+	-- In case compiler needs more than available ram
+	& Apt.serviceInstalledRunning "swapspace"
   where
-	weekdays = Cron.Times "15 6 * * 2-5"
-	weekends = Cron.Times "15 6 * * 6-7"
+	weekdays = Cron.Times "15 10 * * 2-5"
+	weekends = Cron.Times "15 10 * * 6-7"
 
 -- This is not a complete description of kite, since it's a
 -- multiuser system with eg, user passwords that are not deployed
@@ -236,7 +266,7 @@
 		, (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFZftKMnH/zH29BHMKbcBO4QsgTrstYFVhbrzrlRzBO3")
 		]
 
-	& Network.static "eth0" `requires` Network.cleanInterfacesFile
+	& Network.preserveStatic "eth0" `requires` Network.cleanInterfacesFile
 	& Apt.installed ["linux-image-amd64"]
 	& Linode.serialGrub
 	& Linode.mlocateEnabled
diff --git a/propellor.cabal b/propellor.cabal
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -1,5 +1,5 @@
 Name: propellor
-Version: 4.5.2
+Version: 4.6.0
 Cabal-Version: >= 1.20
 License: BSD2
 Maintainer: Joey Hess <id@joeyh.name>
diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs
--- a/src/Propellor/Bootstrap.hs
+++ b/src/Propellor/Bootstrap.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+
 module Propellor.Bootstrap (
 	Bootstrapper(..),
 	Builder(..),
@@ -34,7 +36,7 @@
 	deriving (Show)
 
 data Builder = Cabal | Stack
-	deriving (Show)
+	deriving (Show, Typeable)
 
 defaultBootstrapper :: Bootstrapper
 defaultBootstrapper = Robustly Cabal
diff --git a/src/Propellor/Property/Network.hs b/src/Propellor/Property/Network.hs
--- a/src/Propellor/Property/Network.hs
+++ b/src/Propellor/Property/Network.hs
@@ -39,7 +39,30 @@
 	`describe` ("dhcp " ++ iface)
 	`requires` interfacesDEnabled
 
--- | Writes a static interface file for the specified interface.
+newtype Gateway = Gateway IPAddr
+
+-- | Configures an interface with a static address and gateway.
+static :: Interface -> IPAddr -> Maybe Gateway-> Property DebianLike
+static iface addr gateway = 
+	tightenTargets $ hasContent (interfaceDFile iface) ls
+	`describe` ("static IP address for " ++ iface)
+	`requires` interfacesDEnabled
+  where
+	ls = catMaybes
+		[ Just $ "auto " ++ iface
+		, Just $ "iface " ++ iface ++ " " ++ inet ++ " static"
+		, Just $ "\taddress " ++ val addr
+		, case gateway of
+			Just (Gateway gaddr) -> 
+				Just $ "\tgateway " ++ val gaddr
+			Nothing -> Nothing
+		]
+	inet = case addr of
+		IPv4 _ -> "inet"
+		IPv6 _ -> "inet6"
+
+-- | Writes a static interface file for the specified interface
+-- to preserve its current configuration.
 --
 -- The interface has to be up already. It could have been brought up by
 -- DHCP, or by other means. The current ipv4 addresses
@@ -50,8 +73,8 @@
 --
 -- (ipv6 addresses are not included because it's assumed they come up
 -- automatically in most situations.)
-static :: Interface -> Property DebianLike
-static iface = tightenTargets $ 
+preserveStatic :: Interface -> Property DebianLike
+preserveStatic iface = tightenTargets $ 
 	check (not <$> doesFileExist f) setup
 		`describe` desc
 		`requires` interfacesDEnabled
diff --git a/src/Propellor/Property/OS.hs b/src/Propellor/Property/OS.hs
--- a/src/Propellor/Property/OS.hs
+++ b/src/Propellor/Property/OS.hs
@@ -207,7 +207,7 @@
 			["route", "list", "scope", "global"]
 		case words <$> headMaybe ls of
 			Just ("default":"via":_:"dev":iface:_) ->
-				ensureProperty w $ Network.static iface
+				ensureProperty w $ Network.preserveStatic iface
 			_ -> do
 				warningMessage "did not find any default ipv4 route"
 				return FailedChange
diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs
--- a/src/Propellor/Property/SiteSpecific/JoeySites.hs
+++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs
@@ -929,3 +929,22 @@
 	& Systemd.started "goodmorning.timer"
 	& "/etc/systemd/logind.conf" `ConfFile.containsIniSetting`
 		("Login", "LidSwitchIgnoreInhibited", "no")
+
+-- | Enable IP masqerading, from the intif to the extif.
+ipmasq :: String -> String -> Property DebianLike
+ipmasq extif intif = script `File.hasContent`
+	[ "#!/bin/sh"
+	, "EXTIF=" ++ extif
+	, "INTIF=" ++ intif
+	, "if [ \"$IFACE\" != $EXTIF; then"
+	, "exit 0"
+	, "fi"
+	, "iptables -A FORWARD -i $EXTIF -o $INTIF -m state --state ESTABLISHED,RELATED -j ACCEPT"
+	, "iptables -A FORWARD -i $INTIF -o $EXTIF -j ACCEPT"
+	, "iptables -t nat -A POSTROUTING -o $EXTIF -j MASQUERADE"
+	, "echo 1 > /proc/sys/net/ipv4/ip_forward"
+	]
+	`requires` Apt.installed ["iptables"]
+	`before` (script `File.mode` combineModes (readModes ++ executeModes))
+  where
+	script = "/etc/network/if-up.d/ipmasq"
diff --git a/src/Propellor/Types/Bootloader.hs b/src/Propellor/Types/Bootloader.hs
--- a/src/Propellor/Types/Bootloader.hs
+++ b/src/Propellor/Types/Bootloader.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleInstances, DeriveDataTypeable #-}
 
 module Propellor.Types.Bootloader where
 
