diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,14 @@
+propellor (0.5.1) unstable; urgency=medium
+
+  * Primary DNS servers now have allow-transfer automatically populated
+    with the IP addresses of secondary dns servers. So, it's important
+    that all secondary DNS servers have an ipv4 (and/or ipv6) property
+    configured.
+  * Deal with old ssh connection caching sockets.
+  * Add missing build deps and deps. Closes: #745459
+
+ -- Joey Hess <joeyh@debian.org>  Thu, 24 Apr 2014 18:09:58 -0400
+
 propellor (0.5.0) unstable; urgency=medium
 
   * Removed root domain records from SOA. Instead, use RootDomain
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@
 
 deps:
 	@if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install gnupg ghc cabal-install libghc-missingh-dev libghc-ansi-terminal-dev libghc-ifelse-dev libghc-unix-compat-dev libghc-hslogger-dev libghc-network-dev libghc-quickcheck2-dev libghc-mtl-dev libghc-monadcatchio-transformers-dev; fi || true
-	@if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev || cabal update; cabal install async; fi || true
+	@if [ $$(whoami) = root ]; then apt-get --no-upgrade --no-install-recommends -y install libghc-async-dev || (cabal update; cabal install async); fi || true
 
 dist/setup-config: propellor.cabal
 	if [ "$(CABAL)" = ./Setup ]; then ghc --make Setup; fi
diff --git a/Propellor/Attr.hs b/Propellor/Attr.hs
--- a/Propellor/Attr.hs
+++ b/Propellor/Attr.hs
@@ -59,7 +59,7 @@
   where
 	m = _namedconf d
 	domain = confDomain conf
-	new = case (confType conf, confType <$> M.lookup domain m) of
+	new = case (confDnsServerType conf, confDnsServerType <$> M.lookup domain m) of
 		(Secondary, Just Master) -> m
 		_  -> M.insert domain conf m
 
diff --git a/Propellor/CmdLine.hs b/Propellor/CmdLine.hs
--- a/Propellor/CmdLine.hs
+++ b/Propellor/CmdLine.hs
@@ -10,6 +10,7 @@
 import System.PosixCompat
 import Control.Exception (bracket)
 import System.Posix.IO
+import Data.Time.Clock.POSIX
 
 import Propellor
 import qualified Propellor.Property.Docker as Docker
@@ -346,14 +347,37 @@
 				setLevel DEBUG .  setHandlers [f]
 	go _ = noop
 
--- Parameters can be passed to both ssh and scp.
+-- Parameters can be passed to both ssh and scp, to enable a ssh connection
+-- caching socket.
+--
+-- If the socket already exists, check if its mtime is older than 10
+-- minutes, and if so stop that ssh process, in order to not try to
+-- use an old stale connection. (atime would be nicer, but there's
+-- a good chance a laptop uses noatime)
 sshCachingParams :: HostName -> IO [CommandParam]
 sshCachingParams hn = do
 	home <- myHomeDir
 	let cachedir = home </> ".ssh" </> "propellor"
 	createDirectoryIfMissing False cachedir
 	let socketfile = cachedir </> hn ++ ".sock"
-	return
+	let ps = 
 		[ Param "-o", Param ("ControlPath=" ++ socketfile)
 		, Params "-o ControlMaster=auto -o ControlPersist=yes"
 		]
+
+	maybe noop (expireold ps socketfile)
+		=<< catchMaybeIO (getFileStatus socketfile)
+	
+	return ps
+		
+  where
+	expireold ps f s = do
+		now <- truncate <$> getPOSIXTime :: IO Integer
+		if modificationTime s > fromIntegral now - tenminutes
+			then touchFile f
+			else do
+				void $ boolSystem "ssh" $
+					[ Params "-O stop" ] ++ ps ++
+					[ Param "localhost" ]
+				nukeFile f
+	tenminutes = 600
diff --git a/Propellor/Property/Dns.hs b/Propellor/Property/Dns.hs
--- a/Propellor/Property/Dns.hs
+++ b/Propellor/Property/Dns.hs
@@ -40,6 +40,17 @@
 -- that cannot be configured elsewhere. This often includes NS records,
 -- TXT records and perhaps CNAMEs pointing at hosts that propellor does
 -- not control.
+--
+-- The primary server is configured to only allow zone transfers to
+-- secondary dns servers. These are determined in two ways:
+--
+-- 1. By looking at the properties of other hosts, to find hosts that
+-- are configured as the secondary dns server.
+--
+-- 2. By looking for NS Records in the passed list of records.
+--
+-- In either case, the secondary dns server Host should have an ipv4 and/or
+-- ipv6 property defined.
 primary :: [Host] -> Domain -> SOA -> [(BindDomain, Record)] -> RevertableProperty
 primary hosts domain soa rs = RevertableProperty setup cleanup
   where
@@ -52,22 +63,31 @@
 			`requires` namedConfWritten
 			`onChange` Service.reloaded "bind9"
 
-	(partialzone, warnings) = genZone hosts domain soa
+	(partialzone, zonewarnings) = genZone hosts domain soa
 	zone = partialzone { zHosts = zHosts partialzone ++ rs }
 	zonefile = "/etc/bind/propellor/db." ++ domain
 	baseprop = Property ("dns primary for " ++ domain)
 		(makeChange $ writeZoneFile zone zonefile)
 		(addNamedConf conf)
 	withwarnings p = adjustProperty p $ \satisfy -> do
-		mapM_ warningMessage warnings
+		mapM_ warningMessage $ zonewarnings ++ secondarywarnings
 		satisfy
 	conf = NamedConf
 		{ confDomain = domain
-		, confType = Master
+		, confDnsServerType = Master
 		, confFile = zonefile
 		, confMasters = []
+		, confAllowTransfer = nub $
+			concatMap (\h -> hostAddresses h hosts) $
+				secondaries ++ nssecondaries
 		, confLines = []
 		}
+	secondaries = otherServers Secondary hosts domain
+	secondarywarnings = map (\h -> "No IP address defined for DNS seconary " ++ h) $
+		filter (\h -> null (hostAddresses h hosts)) secondaries
+	nssecondaries = mapMaybe (domainHostName <=< getNS) rootRecords
+	rootRecords = map snd $
+		filter (\(d, _r) -> d == RootDomain || d == AbsDomain domain) rs
 	needupdate = do
 		v <- readZonePropellorFile zonefile
 		return $ case v of
@@ -86,12 +106,7 @@
 -- Note that if a host is declared to be a primary and a secondary dns
 -- server for the same domain, the primary server config always wins.
 secondary :: [Host] -> Domain -> RevertableProperty
-secondary hosts domain = secondaryFor masters hosts domain
-  where
-	masters = M.keys $ M.filter ismaster $ hostAttrMap hosts
-	ismaster attr = case M.lookup domain (_namedconf attr) of
-		Nothing -> False
-		Just conf -> confType conf == Master && confDomain conf == domain
+secondary hosts domain = secondaryFor (otherServers Master hosts domain) hosts domain
 
 -- | This variant is useful if the primary server does not have its DNS
 -- configured via propellor.
@@ -105,19 +120,29 @@
  	desc = "dns secondary for " ++ domain
 	conf = NamedConf
 		{ confDomain = domain
-		, confType = Secondary
+		, confDnsServerType = Secondary
 		, confFile = "db." ++ domain
 		, confMasters = concatMap (\m -> hostAddresses m hosts) masters
-		, confLines = ["allow-transfer { }"]
+		, confAllowTransfer = []
+		, confLines = []
 		}
 
+otherServers :: DnsServerType -> [Host] -> Domain -> [HostName]
+otherServers wantedtype hosts domain =
+	M.keys $ M.filter wanted $ hostAttrMap hosts
+  where
+	wanted attr = case M.lookup domain (_namedconf attr) of
+		Nothing -> False
+		Just conf -> confDnsServerType conf == wantedtype
+			&& confDomain conf == domain
+
 -- | Rewrites the whole named.conf.local file to serve the zones
 -- configured by `primary` and `secondary`, and ensures that bind9 is
 -- running.
 servingZones :: Property
 servingZones = namedConfWritten
-	`requires` Apt.serviceInstalledRunning "bind9"
 	`onChange` Service.reloaded "bind9"
+	`requires` Apt.serviceInstalledRunning "bind9"
 
 namedConfWritten :: Property
 namedConfWritten = property "named.conf configured" $ do
@@ -130,20 +155,26 @@
 confStanza c =
 	[ "// automatically generated by propellor"
 	, "zone \"" ++ confDomain c ++ "\" {"
-	, cfgline "type" (if confType c == Master then "master" else "slave")
+	, cfgline "type" (if confDnsServerType c == Master then "master" else "slave")
 	, cfgline "file" ("\"" ++ confFile c ++ "\"")
 	] ++
-	(if null (confMasters c) then [] else mastersblock) ++
+	mastersblock ++
+	allowtransferblock ++
 	(map (\l -> "\t" ++ l ++ ";") (confLines c)) ++
 	[ "};"
 	, ""
 	]
   where
 	cfgline f v = "\t" ++ f ++ " " ++ v ++ ";"
-	mastersblock =
-		[ "\tmasters {" ] ++
-		(map (\ip -> "\t\t" ++ fromIPAddr ip ++ ";") (confMasters c)) ++
+	ipblock name l = 
+		[ "\t" ++ name ++ " {" ] ++
+		(map (\ip -> "\t\t" ++ fromIPAddr ip ++ ";") l) ++
 		[ "\t};" ]
+	mastersblock
+		| null (confMasters c) = []
+		| otherwise = ipblock "masters" (confMasters c)
+	-- an empty block prohibits any transfers
+	allowtransferblock = ipblock "allow-transfer" (confAllowTransfer c)
 
 namedConfFile :: FilePath
 namedConfFile = "/etc/bind/named.conf.local"
diff --git a/Propellor/Property/SiteSpecific/JoeySites.hs b/Propellor/Property/SiteSpecific/JoeySites.hs
--- a/Propellor/Property/SiteSpecific/JoeySites.hs
+++ b/Propellor/Property/SiteSpecific/JoeySites.hs
@@ -102,6 +102,30 @@
   where
 	desc = "kgb.kitenet.net setup"
 
+mumbleServer :: [Host] -> Property
+mumbleServer hosts = combineProperties "mumble.debian.net" 
+	[ Obnam.latestVersion
+	, Obnam.backup "/var/lib/mumble-server" "55 5 * * *"
+		[ "--repository=sftp://joey@turtle.kitenet.net/~/lib/backup/mumble.debian.net.obnam"
+		, "--client-name=mumble"
+		] Obnam.OnlyClient
+		`requires` Ssh.keyImported SshRsa "root"
+		`requires` Ssh.knownHost hosts "turtle.kitenet.net" "root"
+	, trivial $ cmdProperty "chown" ["-R", "mumble-server:mumble-server", "/var/lib/mumble-server"]
+	, Apt.serviceInstalledRunning "mumble-server"
+	]
+
+obnamLowMem :: Property
+obnamLowMem = combineProperties "obnam tuned for low memory use"
+	[ Obnam.latestVersion
+	, "/etc/obnam.conf" `File.containsLines`
+		[ "[config]"
+		, "# Suggested by liw to keep Obnam memory consumption down (at some speed cost)."
+		, "upload-queue-size = 128"
+		, "lru-size = 128"
+		]
+	]
+
 -- git.kitenet.net and git.joeyh.name
 gitServer :: [Host] -> Property
 gitServer hosts = propertyList "git.kitenet.net setup"
@@ -229,9 +253,8 @@
 	, "  SSLCertificateChainFile /etc/ssl/certs/startssl.pem"
 	]
 		
-
-annexRsyncServer :: Property
-annexRsyncServer = combineProperties "rsync server for git-annex autobuilders"
+gitAnnexDistributor :: Property
+gitAnnexDistributor = combineProperties "git-annex distributor, including rsync server and signer"
 	[ Apt.installed ["rsync"]
 	, File.hasPrivContent "/etc/rsyncd.conf"
 	, File.hasPrivContent "/etc/rsyncd.secrets"
@@ -239,6 +262,8 @@
 			`onChange` Service.running "rsync"
 	, endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild"
 	, endpoint "/srv/web/downloads.kitenet.net/git-annex/autobuild/x86_64-apple-mavericks"
+	-- git-annex distribution signing key
+	, Gpg.keyImported "89C809CB" "joey"
 	]
   where
 	endpoint d = combineProperties ("endpoint " ++ d)
diff --git a/Propellor/SimpleSh.hs b/Propellor/SimpleSh.hs
--- a/Propellor/SimpleSh.hs
+++ b/Propellor/SimpleSh.hs
@@ -32,7 +32,6 @@
 	forever $ do
 		(client, _addr) <- accept s
 		h <- socketToHandle client ReadWriteMode
-		hSetBuffering h LineBuffering
 		maybe noop (run h) . readish =<< hGetLine h
   where
 	run h (Cmd cmd params) = do
@@ -47,6 +46,7 @@
 		let runwriter = do
 			v <- readChan chan
 			hPutStrLn h (show v)
+			hFlush h
 			case v of
 				Done -> noop
 				_ -> runwriter
@@ -73,8 +73,8 @@
 	s <- socket AF_UNIX Stream defaultProtocol
 	connect s (SockAddrUnix namedpipe)
 	h <- socketToHandle s ReadWriteMode
-	hSetBuffering h LineBuffering
 	hPutStrLn h $ show $ Cmd cmd params
+	hFlush h
 	resps <- catMaybes . map readish . lines <$> hGetContents h
 	hClose h `after` handler resps
 
diff --git a/Propellor/Types/Dns.hs b/Propellor/Types/Dns.hs
--- a/Propellor/Types/Dns.hs
+++ b/Propellor/Types/Dns.hs
@@ -1,5 +1,7 @@
 module Propellor.Types.Dns where
 
+import Propellor.Types.OS (HostName)
+
 import Data.Word
 
 type Domain = String
@@ -14,14 +16,15 @@
 -- | Represents a bind 9 named.conf file.
 data NamedConf = NamedConf
 	{ confDomain :: Domain
-	, confType :: Type
+	, confDnsServerType :: DnsServerType
 	, confFile :: FilePath
 	, confMasters :: [IPAddr]
+	, confAllowTransfer :: [IPAddr]
 	, confLines :: [String]
 	}
 	deriving (Show, Eq, Ord)
 
-data Type = Master | Secondary
+data DnsServerType = Master | Secondary
 	deriving (Show, Eq, Ord)
 
 -- | Represents a bind 9 zone file.
@@ -66,6 +69,10 @@
 getCNAME (CNAME d) = Just d
 getCNAME _ = Nothing
 
+getNS :: Record -> Maybe BindDomain
+getNS (NS d) = Just d
+getNS _ = Nothing
+
 -- | Bind serial numbers are unsigned, 32 bit integers.
 type SerialNumber = Word32
 
@@ -78,3 +85,8 @@
 -- to add nameservers, MX's, etc to a domain.
 data BindDomain = RelDomain Domain | AbsDomain Domain | RootDomain
 	deriving (Read, Show, Eq, Ord)
+
+domainHostName :: BindDomain -> Maybe HostName
+domainHostName (RelDomain d) = Just d
+domainHostName (AbsDomain d) = Just d
+domainHostName RootDomain = Nothing
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -12,17 +12,17 @@
 to get started. There is fairly complete 
 [API documentation](http://hackage.haskell.org/package/propellor/),
 which includes many built-in Properties for dealing with
-[Apt](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Apt.html)
+[Apt](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apt.html)
 and
-[Apache](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Apache.html)
+[Apache](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apache.html)
 ,
-[Cron](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Cron.html)
+[Cron](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Cron.html)
 and
-[Commands](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Cmd.html)
+[Commands](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Cmd.html)
 ,
-[Dns](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Dns.html)
+[Dns](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Dns.html)
 and
-[Docker](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Docker.html), etc.
+[Docker](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Docker.html), etc.
 
 There is no special language as used in puppet, chef, ansible, etc.. just
 the full power of Haskell. Hopefully that power can be put to good use in
diff --git a/config-joey.hs b/config-joey.hs
--- a/config-joey.hs
+++ b/config-joey.hs
@@ -64,6 +64,9 @@
 		-- I'd rather this were on diatom, but it needs unstable.
 		& alias "kgb.kitenet.net"
 		& JoeySites.kgbServer
+
+		& alias "mumble.kitenet.net"
+		& JoeySites.mumbleServer hosts
 		
 		& alias "ns9.kitenet.net"
 		& myDnsSecondary
@@ -97,6 +100,10 @@
 		& Apt.unattendedUpgrades
 		& Apt.serviceInstalledRunning "ntp"
 		& Postfix.satellite
+
+		-- Diatom has 500 mb of memory, so tune for that.
+		& JoeySites.obnamLowMem
+		& Apt.serviceInstalledRunning "swapspace"
 	
 		& Apt.serviceInstalledRunning "apache2"
 		& File.hasPrivContent "/etc/ssl/certs/web.pem"
@@ -105,6 +112,7 @@
 		& Apache.modEnabled "ssl"
 		& Apache.multiSSL
 		& File.ownerGroup "/srv/web" "joey" "joey"
+		& Apt.installed ["analog"]
 
 		& alias "git.kitenet.net"
 		& alias "git.joeyh.name"
@@ -115,7 +123,7 @@
 			"downloads.kitenet.net"
 			"840760dc-08f0-11e2-8c61-576b7e66acfd"
 			[("turtle", "ssh://turtle.kitenet.net/~/lib/downloads/")]
-		& JoeySites.annexRsyncServer
+		& JoeySites.gitAnnexDistributor
 
 		& alias "tmp.kitenet.net"
 		& JoeySites.annexWebSite hosts "/srv/git/joey/tmp.git"
@@ -129,18 +137,17 @@
 		& JoeySites.oldUseNetServer hosts
 		
 		& alias "ns2.kitenet.net"
-		& myDnsSecondary
-		& Dns.primary hosts "olduse.net"
-			(Dns.mkSOA "ns2.kitenet.net" 100)
-			[ (RootDomain, NS $ AbsDomain "ns2.kitenet.net")
-			, (RootDomain, NS $ AbsDomain "ns6.gandi.net")
-			, (RootDomain, NS $ AbsDomain "ns9.kitenet.net")
-			, (RootDomain, MX 0 $ AbsDomain "kitenet.net")
-			, (RootDomain, TXT "v=spf1 a -all")
-			, (RelDomain "article", CNAME $ AbsDomain "virgil.koldfront.dk")
-			]
-
-		& Apt.installed ["ntop"]
+		& myDnsPrimary "kitenet.net" []
+		& myDnsPrimary "joeyh.name" []
+		& myDnsPrimary "ikiwiki.info" []
+		& myDnsPrimary "olduse.net"
+			[ (RelDomain "article",
+				CNAME $ AbsDomain "virgil.koldfront.dk") ]
+	
+		& alias "ns3.branchable.com"
+		& branchableSecondary
+		
+		& Dns.secondaryFor ["animx"] hosts "animx.eu.org"
 
 
 	    --'                        __|II|      ,.
@@ -168,7 +175,7 @@
 	, standardContainer "ancient-kitenet" Stable "amd64"
 		& Docker.publish "1994:80"
 		& Apt.serviceInstalledRunning "apache2"
-		& Git.cloned "root" "git://git.kitenet.net/kitewiki" "/var/www"
+		& Git.cloned "root" "git://kitenet-net.branchable.com/" "/var/www"
 			(Just "remotes/origin/old-kitenet.net")
 	
 	-- git-annex autobuilder containers
@@ -253,18 +260,29 @@
 
 myDnsSecondary :: Property
 myDnsSecondary = propertyList "dns secondary for all my domains" $ map toProp
-	[ Dns.secondaryFor wren hosts "kitenet.net"
-	, Dns.secondaryFor wren hosts "joeyh.name"
-	, Dns.secondaryFor wren hosts "ikiwiki.info"
+	[ Dns.secondary hosts "kitenet.net"
+	, Dns.secondary hosts "joeyh.name"
+	, Dns.secondary hosts "ikiwiki.info"
 	, Dns.secondary hosts "olduse.net"
-	, Dns.secondaryFor branchable hosts "branchable.com"
 	]
-  where
-	wren = ["wren.kitenet.net"]
-	branchable = ["branchable.com"]
 
+branchableSecondary :: RevertableProperty
+branchableSecondary = Dns.secondaryFor ["branchable.com"] hosts "branchable.com"
 
+-- Currently using diatom (ns2) as primary with secondaries
+-- clam (ns9) and gandi.
+-- kite handles all mail.
+myDnsPrimary :: Domain -> [(BindDomain, Record)] -> RevertableProperty
+myDnsPrimary domain extras = Dns.primary hosts domain
+	(Dns.mkSOA "ns2.kitenet.net" 100) $
+	[ (RootDomain, NS $ AbsDomain "ns2.kitenet.net")
+	, (RootDomain, NS $ AbsDomain "ns6.gandi.net")
+	, (RootDomain, NS $ AbsDomain "ns9.kitenet.net")
+	, (RootDomain, MX 0 $ AbsDomain "kitenet.net")
+	, (RootDomain, TXT "v=spf1 a ?all")
+	] ++ extras
 
+
                           --                                o
                           --             ___                 o              o
                        {-----\          / o \              ___o            o
@@ -282,20 +300,49 @@
 		& sshPubKey "ssh-dss AAAAB3NzaC1kc3MAAAEBAI6ZsoW8a+Zl6NqUf9a4xXSMcV1akJHDEKKBzlI2YZo9gb9YoCf5p9oby8THUSgfh4kse7LJeY7Nb64NR6Y/X7I2/QzbE1HGGl5mMwB6LeUcJ74T3TQAlNEZkGt/MOIVLolJHk049hC09zLpkUDtX8K0t1yaCirC9SxDGLTCLEhvU9+vVdVrdQlKZ9wpLUNbdAzvbra+O/IVvExxDZ9WCHrnfNA8ddVZIGEWMqsoNgiuCxiXpi8qL+noghsSQNFTXwo7W2Vp9zj1JkCt3GtSz5IzEpARQaXEAWNEM0n1nJ686YUOhou64iRM8bPC1lp3QXvvZNgj3m+QHhIempx+de8AAAAVAKB5vUDaZOg14gRn7Bp81ja/ik+RAAABACPH/bPbW912x1NxNiikzGR6clLh+bLpIp8Qie3J7DwOr8oC1QOKjNDK+UgQ7mDQEgr4nGjNKSvpDi4c1QCw4sbLqQgx1y2VhT0SmUPHf5NQFldRQyR/jcevSSwOBxszz3aq9AwHiv9OWaO3XY18suXPouiuPTpIcZwc2BLDNHFnDURQeGEtmgqj6gZLIkTY0iw7q9Tj5FOyl4AkvEJC5B4CSzaWgey93Wqn1Imt7KI8+H9lApMKziVL1q+K7xAuNkGmx5YOSNlE6rKAPtsIPHZGxR7dch0GURv2jhh0NQYvBRn3ukCjuIO5gx56HLgilq59/o50zZ4NcT7iASF76TcAAAEAC6YxX7rrs8pp13W4YGiJHwFvIO1yXLGOdqu66JM0plO4J1ItV1AQcazOXLiliny3p2/W+wXZZKd5HIRt52YafCA8YNyMk/sF7JcTR4d4z9CfKaAxh0UpzKiAk+0j/Wu3iPoTOsyt7N0j1+dIyrFodY2sKKuBMT4TQ0yqQpbC+IDQv2i1IlZAPneYGfd5MIGygs2QMfaMQ1jWAKJvEO0vstZ7GB6nDAcg4in3ZiBHtomx3PL5w+zg48S4Ed69BiFXLZ1f6MnjpUOP75pD4MP6toS0rgK9b93xCrEQLgm4oD/7TCHHBo2xR7wwcsN2OddtwWsEM2QgOkt/jdCAoVCqwQ=="
 	, host "github.com" 
 		& sshPubKey "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ=="
+	, host "ns6.gandi.net"
+		& ipv4 "217.70.177.40"
 	, host "turtle.kitenet.net"
 		& ipv4 "67.223.19.96"
 		& ipv6 "2001:4978:f:2d9::2"
+		& alias "backup.kitenet.net"
 		& sshPubKey "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAokMXQiX/NZjA1UbhMdgAscnS5dsmy+Q7bWrQ6tsTZ/o+6N/T5cbjoBHOdpypXJI3y/PiJTDJaQtXIhLa8gFg/EvxMnMz/KG9skADW1361JmfCc4BxicQIO2IOOe6eilPr+YsnOwiHwL0vpUnuty39cppuMWVD25GzxXlS6KQsLCvXLzxLLuNnGC43UAM0q4UwQxDtAZEK1dH2o3HMWhgMP2qEQupc24dbhpO3ecxh2C9678a3oGDuDuNf7mLp3s7ptj5qF3onitpJ82U5o7VajaHoygMaSRFeWxP2c13eM57j3bLdLwxVXFhePcKXARu1iuFTLS5uUf3hN6MkQcOGw=="
 	, host "wren.kitenet.net"
 		& ipv4 "80.68.85.49"
 		& ipv6 "2001:41c8:125:49::10"
-		& alias "kite.kitenet.net"
 		& alias "kitenet.net"
+		& alias "kite.kitenet.net"
 		& alias "ns1.kitenet.net"
+		& alias "ftp.kitenet.net"
+		& alias "mail.kitenet.net"
+		& alias "smtp.kitenet.net"
+		& alias "sows-ear.kitenet.net"
+		& alias "www.sows-ear.kitenet.net"
+		& alias "wortroot.kitenet.net"
+		& alias "www.wortroot.kitenet.net"
+		& alias "joey.kitenet.net"
+		& alias "annex.kitenet.net"
+		& alias "ipv6.kitenet.net"
+	, host "mouse.kitenet.net"
+		& ipv6 "2001:4830:1600:492::2"
+	, host "beaver.kitenet.net"
+		& ipv6 "2001:4830:1600:195::2"
+	, host "hydra.kitenet.net"
+		& ipv4 "192.25.206.60"
 	, host "branchable.com"
 		& ipv4 "66.228.46.55"
 		& ipv6 "2600:3c03::f03c:91ff:fedf:c0e5"
 		& alias "olduse.net"
 		& alias "www.olduse.net"
-		& alias "git.olduse.net"
+		& alias "www.kitenet.net"
+		& alias "joeyh.name"
+		& alias "campaign.joeyh.name"
+		& alias "ikiwiki.info"
+		& alias "git.ikiwiki.info"
+		& alias "l10n.ikiwiki.info"
+		& alias "dist-bugs.kitenet.net"
+		& alias "family.kitenet.net"
+	, host "animx"
+		& ipv4 "76.7.162.101"
+		& ipv4 "76.7.162.186"
 	]
diff --git a/debian/changelog b/debian/changelog
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,14 @@
+propellor (0.5.1) unstable; urgency=medium
+
+  * Primary DNS servers now have allow-transfer automatically populated
+    with the IP addresses of secondary dns servers. So, it's important
+    that all secondary DNS servers have an ipv4 (and/or ipv6) property
+    configured.
+  * Deal with old ssh connection caching sockets.
+  * Add missing build deps and deps. Closes: #745459
+
+ -- Joey Hess <joeyh@debian.org>  Thu, 24 Apr 2014 18:09:58 -0400
+
 propellor (0.5.0) unstable; urgency=medium
 
   * Removed root domain records from SOA. Instead, use RootDomain
diff --git a/debian/control b/debian/control
--- a/debian/control
+++ b/debian/control
@@ -11,6 +11,8 @@
 	libghc-unix-compat-dev,
 	libghc-ansi-terminal-dev,
 	libghc-ifelse-dev,
+	libghc-network-dev,
+	libghc-quickcheck2-dev,
 	libghc-mtl-dev,
 	libghc-monadcatchio-transformers-dev,
 Maintainer: Joey Hess <joeyh@debian.org>
@@ -30,6 +32,8 @@
 	libghc-unix-compat-dev,
 	libghc-ansi-terminal-dev,
 	libghc-ifelse-dev,
+	libghc-network-dev,
+	libghc-quickcheck2-dev,
 	libghc-mtl-dev,
 	libghc-monadcatchio-transformers-dev,
 	git,
diff --git a/doc/README.mdwn b/doc/README.mdwn
--- a/doc/README.mdwn
+++ b/doc/README.mdwn
@@ -12,17 +12,17 @@
 to get started. There is fairly complete 
 [API documentation](http://hackage.haskell.org/package/propellor/),
 which includes many built-in Properties for dealing with
-[Apt](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Apt.html)
+[Apt](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apt.html)
 and
-[Apache](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Apache.html)
+[Apache](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Apache.html)
 ,
-[Cron](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Cron.html)
+[Cron](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Cron.html)
 and
-[Commands](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Cmd.html)
+[Commands](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Cmd.html)
 ,
-[Dns](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Dns.html)
+[Dns](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Dns.html)
 and
-[Docker](http://hackage.haskell.org/package/propellor-0.4.0/docs/Propellor-Property-Docker.html), etc.
+[Docker](http://hackage.haskell.org/package/propellor/docs/Propellor-Property-Docker.html), etc.
 
 There is no special language as used in puppet, chef, ansible, etc.. just
 the full power of Haskell. Hopefully that power can be put to good use in
diff --git a/propellor.cabal b/propellor.cabal
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -1,5 +1,5 @@
 Name: propellor
-Version: 0.5.0
+Version: 0.5.1
 Cabal-Version: >= 1.6
 License: GPL
 Maintainer: Joey Hess <joey@kitenet.net>
@@ -35,7 +35,7 @@
 
 Executable propellor
   Main-Is: propellor.hs
-  GHC-Options: -Wall
+  GHC-Options: -Wall -threaded
   Build-Depends: MissingH, directory, filepath, base >= 4.5, base < 5, 
    IfElse, process, bytestring, hslogger, unix-compat, ansi-terminal,
    containers, network, async, time, QuickCheck, mtl,
diff --git a/propellor.hs b/propellor.hs
--- a/propellor.hs
+++ b/propellor.hs
@@ -74,7 +74,7 @@
 		void $ boolSystem "git" [Param "remote", Param "add", Param "upstream", Param srcrepo]
 		-- Connect synthetic git repo with upstream history so
 		-- merging with upstream will work going forward.
-		-- Note -s outs is used to avoid getting any divergent
+		-- Note -s ours is used to avoid getting any divergent
 		-- changes from upstream.
 		when fromsrcdir $ do
 			void $ boolSystem "git" [Param "fetch", Param "upstream"]
