diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,11 @@
+propellor (3.2.1) unstable; urgency=medium
+
+  * Simplify Debootstrap.sourceInstall since #770217 was fixed.
+  * Debootstap.installed: Fix inverted logic that made this never install
+    debootstrap. Thanks, mithrandi.
+
+ -- Joey Hess <id@joeyh.name>  Mon, 03 Oct 2016 18:06:31 -0400
+
 propellor (3.2.0) unstable; urgency=medium
 
   [ Sean Whitton ]
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -51,9 +51,4 @@
 propellor.1: doc/usage.mdwn doc/mdwn2man
 	doc/mdwn2man propellor 1 < doc/usage.mdwn > propellor.1
 
-# Upload to hackage.
-hackage:
-	@cabal sdist
-	@cabal upload dist/*.tar.gz
-
 .PHONY: tags
diff --git a/debian/changelog b/debian/changelog
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+propellor (3.2.1) unstable; urgency=medium
+
+  * Simplify Debootstrap.sourceInstall since #770217 was fixed.
+  * Debootstap.installed: Fix inverted logic that made this never install
+    debootstrap. Thanks, mithrandi.
+
+ -- Joey Hess <id@joeyh.name>  Mon, 03 Oct 2016 18:06:31 -0400
+
 propellor (3.2.0) unstable; urgency=medium
 
   [ Sean Whitton ]
diff --git a/joeyconfig.hs b/joeyconfig.hs
--- a/joeyconfig.hs
+++ b/joeyconfig.hs
@@ -454,16 +454,17 @@
 	& alias "family.kitenet.net"
 
 	& Apt.installed ["linux-image-amd64"]
-	& Linode.chainPVGrub 5
 	& Apt.unattendedUpgrades
 	& Branchable.server hosts
 
+-- See https://joeyh.name/code/keysafe/servers/ for requirements.
 keysafe :: Host
 keysafe = host "keysafe.joeyh.name" $ props
 	& ipv4 "139.59.17.168"
 	& Hostname.sane
 	& osDebian (Stable "jessie") X86_64
 	& Apt.stdSourcesList `onChange` Apt.upgrade
+	& Apt.unattendedUpgrades
 	& DigitalOcean.distroKernel
 	-- This is a 500 mb VM, so need more ram to build propellor.
 	& Apt.serviceInstalledRunning "swapspace"
@@ -485,7 +486,29 @@
 	& Tor.installed
 	& Tor.hiddenServiceAvailable "keysafe" (Port 4242)
 		`requires` Tor.hiddenServiceData "keysafe" hostContext
+	& Tor.bandwidthRate (Tor.PerMonth "750 GB")
+
 	-- keysafe installed manually until package is available
+	& Systemd.enabled "keysafe"
+
+	& Gpg.keyImported (Gpg.GpgKeyId "CECE11AE") (User "root")
+	& Ssh.knownHost hosts "usw-s002.rsync.net" (User "root")
+	& Ssh.userKeys (User "root")
+		(Context "keysafe.joeyh.name")
+		[ (SshEd25519, "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEx8bK9ZbXVEgEvxQeXLjnr9cGa/QvoB459aglP529My root@keysafe")
+		]
+	-- Note that this is not an incremental backup; it uploads the
+	-- whole content every time. So, only run weekly.
+	& Cron.niceJob "keysafe backup" Cron.Weekly (User "root") "/" backupcmd
+		`requires` Apt.installed ["rsync"]
+  where
+	datadir = "/var/lib/keysafe"
+	backupdir = "/var/backups/keysafe"
+	rsyncnetbackup = "2318@usw-s002.rsync.net:keysafe"
+	backupcmd = unwords
+		[ "keysafe --store-directory", datadir, "--backup-server", backupdir
+		, "&& rsync -a --delete --max-delete 3 ",  backupdir , rsyncnetbackup
+		]
 
 iabak :: Host
 iabak = host "iabak.archiveteam.org" $ props
diff --git a/propellor.cabal b/propellor.cabal
--- a/propellor.cabal
+++ b/propellor.cabal
@@ -1,5 +1,5 @@
 Name: propellor
-Version: 3.2.0
+Version: 3.2.1
 Cabal-Version: >= 1.8
 License: BSD2
 Maintainer: Joey Hess <id@joeyh.name>
diff --git a/src/Propellor/Property/Debootstrap.hs b/src/Propellor/Property/Debootstrap.hs
--- a/src/Propellor/Property/Debootstrap.hs
+++ b/src/Propellor/Property/Debootstrap.hs
@@ -74,9 +74,7 @@
 		cmd <- fromMaybe "debootstrap" <$> programPath
 		de <- standardPathEnv
 		ifM (boolSystemEnv cmd params (Just de))
-			( do
-				fixForeignDev target
-				return MadeChange
+			( return MadeChange
 			, return FailedChange
 			)
 
@@ -102,7 +100,7 @@
 installed :: RevertableProperty Linux Linux
 installed = install <!> remove
   where
-	install = check (isJust <$> programPath) $
+	install = check (isNothing <$> programPath) $
 		(aptinstall `pickOS` sourceInstall)
 			`describe` "debootstrap installed"
 
@@ -165,7 +163,6 @@
 		case l of
 			(subdir:[]) -> do
 				changeWorkingDirectory subdir
-				makeDevicesTarball
 				makeWrapperScript (localInstallDir </> subdir)
 				return MadeChange
 			_ -> errorMessage "debootstrap tar file did not contain exactly one directory"
@@ -205,40 +202,6 @@
 		, dir </> "debootstrap" ++ " \"$@\""
 		]
 	modifyFileMode wrapperScript (addModes $ readModes ++ executeModes)
-
--- Work around for <http://bugs.debian.org/770217>
-makeDevicesTarball :: IO ()
-makeDevicesTarball = do
-	-- TODO append to tarball; avoid writing to /dev
-	writeFile foreignDevFlag "1"
-	ok <- boolSystem "sh" [Param "-c", Param tarcmd]
-	nukeFile foreignDevFlag
-	unless ok $
-		errorMessage "Failed to tar up /dev to generate devices.tar.gz"
-  where
-	tarcmd = "(cd / && tar cf - dev) | gzip > devices.tar.gz"
-
-fixForeignDev :: FilePath -> IO ()
-fixForeignDev target = whenM (doesFileExist (target ++ foreignDevFlag)) $ do
-	de <- standardPathEnv
-	void $ boolSystemEnv "chroot"
-		[ File target
-		, Param "sh"
-		, Param "-c"
-		, Param $ intercalate " && "
-			[ "apt-get update"
-			, "apt-get -y install makedev"
-			, "rm -rf /dev"
-			, "mkdir /dev"
-			, "cd /dev"
-			, "mount -t proc proc /proc"
-			, "/sbin/MAKEDEV std ptmx fd consoleonly"
-			]
-		]
-		(Just de)
-
-foreignDevFlag :: FilePath
-foreignDevFlag = "/dev/.propellor-foreign-dev"
 
 localInstallDir :: FilePath
 localInstallDir = "/usr/local/debootstrap"
diff --git a/src/Propellor/Property/Tor.hs b/src/Propellor/Property/Tor.hs
--- a/src/Propellor/Property/Tor.hs
+++ b/src/Propellor/Property/Tor.hs
@@ -145,7 +145,7 @@
 		r <- satisfy
 		mh <- liftIO $ tryIO $ readFile (varLib </> hn </> "hostname")
 		case mh of
-			Right h -> warningMessage $ unwords ["hidden service hostname:", h]
+			Right h -> infoMessage ["hidden service hostname:", h]
 			Left _e -> warningMessage "hidden service hostname not available yet"
 		return r
 
