From f3ccb9b51019054adedfcc87ebfd2b299bec30e0 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Jul 2014 15:21:19 -0400 Subject: propellor spin --- config-joey.hs | 71 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) (limited to 'config-joey.hs') diff --git a/config-joey.hs b/config-joey.hs index 2c73b3e5..4ed5637e 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -42,7 +42,7 @@ hosts = -- (o) ` & Docker.configured & Docker.docked hosts "android-git-annex" - -- Nothing super-important lives here and mostly it's docker containers. + -- Unreliable server. , standardSystem "clam.kitenet.net" Unstable "amd64" & ipv4 "162.248.143.249" & ipv6 "2002:5044:5531::1" @@ -52,39 +52,10 @@ hosts = -- (o) ` & Network.ipv6to4 & Tor.isBridge & Postfix.satellite - & Docker.configured - - & Docker.docked hosts "oldusenet-shellbox" - & Docker.docked hosts "openid-provider" - `requires` Apt.serviceInstalledRunning "ntp" - & Docker.docked hosts "ancient-kitenet" - - -- 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 - - & alias "znc.kitenet.net" - & JoeySites.ircBouncer - - -- For https port 443, shellinabox with ssh login to - -- kitenet.net - & alias "shell.kitenet.net" - & JoeySites.kiteShellBox - - -- Nothing is using http port 80 on clam, so listen on - -- that port for ssh, for traveling on bad networks that - -- block 22. - & "/etc/ssh/sshd_config" `File.containsLine` "Port 80" - `onChange` Service.restarted "ssh" + & Apt.installed ["git-annex", "mtr", "screen"] + & Docker.configured & Docker.garbageCollected `period` Daily - & Apt.installed ["git-annex", "mtr", "screen"] -- Orca is the main git-annex build box. , standardSystem "orca.kitenet.net" Unstable "amd64" @@ -201,8 +172,38 @@ hosts = -- (o) ` & alias "podcatcher.kitenet.net" & Apt.installed ["git-annex"] + & alias "znc.kitenet.net" + & JoeySites.ircBouncer + + -- 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 "ns3.kitenet.net" + & myDnsSecondary + & Docker.configured + + & Docker.docked hosts "oldusenet-shellbox" + & Docker.docked hosts "openid-provider" + `requires` Apt.serviceInstalledRunning "ntp" + & Docker.docked hosts "ancient-kitenet" + & Docker.garbageCollected `period` (Weekly (Just 1)) + + -- For https port 443, shellinabox with ssh login to + -- kitenet.net + & alias "shell.kitenet.net" + & JoeySites.kiteShellBox + -- Nothing is using http port 80, so listen on + -- that port for ssh, for traveling on bad networks that + -- block 22. + & "/etc/ssh/sshd_config" `File.containsLine` "Port 80" + `onChange` Service.restarted "ssh" + --' __|II| ,. ---- __|II|II|__ ( \_,/\ @@ -309,14 +310,14 @@ branchableSecondary :: RevertableProperty branchableSecondary = Dns.secondaryFor ["branchable.com"] hosts "branchable.com" -- Currently using diatom (ns2) as primary with secondaries --- clam (ns9) and gandi. +-- elephant (ns3) 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 "ns3.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 @@ -377,7 +378,7 @@ monsters = -- but do want to track their public keys etc. - some static websites - bitlbee - prosody - - (used by anna and daddy's git-annex) + - (used by daddy's git-annex) - named - (branchable is still pushing to here - (thinking it's ns2.branchable.com), but it's no -- cgit v1.3-2-g0d8e From d72e8c84b183a612ecc658b37255b08b9a67a5f3 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Jul 2014 15:34:39 -0400 Subject: propellor spin --- config-joey.hs | 3 +- privdata/elephant.kitenet.net.gpg | 272 +++++++++++++++++++++++--------------- 2 files changed, 166 insertions(+), 109 deletions(-) (limited to 'config-joey.hs') diff --git a/config-joey.hs b/config-joey.hs index 4ed5637e..bfe6db42 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -44,8 +44,7 @@ hosts = -- (o) ` -- Unreliable server. , standardSystem "clam.kitenet.net" Unstable "amd64" - & ipv4 "162.248.143.249" - & ipv6 "2002:5044:5531::1" + & ipv4 "162.248.9.29" & CloudAtCost.decruft & Apt.unattendedUpgrades diff --git a/privdata/elephant.kitenet.net.gpg b/privdata/elephant.kitenet.net.gpg index 41eda0d5..6a1002b5 100644 --- a/privdata/elephant.kitenet.net.gpg +++ b/privdata/elephant.kitenet.net.gpg @@ -1,111 +1,169 @@ -----BEGIN PGP MESSAGE----- Version: GnuPG v1 -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 -qQxw6B5ksDEcXeNKy5xa7gfOl5OJ+WxvbNHOy2s= -=oXYz +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 +=su4u -----END PGP MESSAGE----- -- cgit v1.3-2-g0d8e From 7a6208e72c981bd8b647dcc62c8f7f8820779c87 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 5 Jul 2014 18:15:24 -0400 Subject: cleanup --- config-joey.hs | 1 - 1 file changed, 1 deletion(-) (limited to 'config-joey.hs') diff --git a/config-joey.hs b/config-joey.hs index bfe6db42..86117070 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -51,7 +51,6 @@ hosts = -- (o) ` & Network.ipv6to4 & Tor.isBridge & Postfix.satellite - & Apt.installed ["git-annex", "mtr", "screen"] & Docker.configured & Docker.garbageCollected `period` Daily -- cgit v1.3-2-g0d8e From 58f79c12aad3511b70f2233226d3f0afc5214b10 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 6 Jul 2014 15:56:56 -0400 Subject: propellor spin --- config-joey.hs | 30 +++--- debian/changelog | 11 +- doc/security.mdwn | 15 +-- propellor.cabal | 1 + src/Propellor/CmdLine.hs | 32 +++--- src/Propellor/PrivData.hs | 116 ++++++++++++--------- src/Propellor/Property/Docker.hs | 7 +- src/Propellor/Property/File.hs | 13 +-- src/Propellor/Property/Gpg.hs | 17 +-- src/Propellor/Property/OpenId.hs | 5 +- .../Property/SiteSpecific/GitAnnexBuilder.hs | 38 +++---- src/Propellor/Property/SiteSpecific/JoeySites.hs | 28 ++--- src/Propellor/Property/Ssh.hs | 45 ++++---- src/Propellor/Property/User.hs | 23 ++-- src/Propellor/Types.hs | 31 ++---- src/Propellor/Types/Info.hs | 5 +- src/Propellor/Types/PrivData.hs | 34 ++++++ 17 files changed, 252 insertions(+), 199 deletions(-) create mode 100644 src/Propellor/Types/PrivData.hs (limited to 'config-joey.hs') diff --git a/config-joey.hs b/config-joey.hs index 86117070..31ea685c 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -72,14 +72,15 @@ hosts = -- (o) ` & Apt.buildDep ["git-annex"] `period` Daily -- Important stuff that needs not too much memory or CPU. - , standardSystem "diatom.kitenet.net" Stable "amd64" + , let ctx = Context "diatom.kitenet.net " + in standardSystem "diatom.kitenet.net" Stable "amd64" & ipv4 "107.170.31.195" & DigitalOcean.distroKernel & Hostname.sane - & Ssh.hostKey SshDsa - & Ssh.hostKey SshRsa - & Ssh.hostKey SshEcdsa + & Ssh.hostKey SshDsa ctx + & Ssh.hostKey SshRsa ctx + & Ssh.hostKey SshEcdsa ctx & Apt.unattendedUpgrades & Apt.serviceInstalledRunning "ntp" & Postfix.satellite @@ -89,9 +90,9 @@ hosts = -- (o) ` & Apt.serviceInstalledRunning "swapspace" & Apt.serviceInstalledRunning "apache2" - & File.hasPrivContent "/etc/ssl/certs/web.pem" - & File.hasPrivContent "/etc/ssl/private/web.pem" - & File.hasPrivContent "/etc/ssl/certs/startssl.pem" + & File.hasPrivContent "/etc/ssl/certs/web.pem" (Context "kitenet.net") + & File.hasPrivContent "/etc/ssl/private/web.pem" (Context "kitenet.net") + & File.hasPrivContent "/etc/ssl/certs/startssl.pem" (Context "kitenet.net") & Apache.modEnabled "ssl" & Apache.multiSSL & File.ownerGroup "/srv/web" "joey" "joey" @@ -133,16 +134,17 @@ hosts = -- (o) ` & Dns.secondaryFor ["animx"] hosts "animx.eu.org" -- storage and backup server - , standardSystem "elephant.kitenet.net" Unstable "amd64" + , let ctx = Context "elephant.kitenet.net" + in standardSystem "elephant.kitenet.net" Unstable "amd64" & ipv4 "193.234.225.114" & Hostname.sane & Postfix.satellite & Apt.unattendedUpgrades - & Ssh.hostKey SshDsa - & Ssh.hostKey SshRsa - & Ssh.hostKey SshEcdsa - & Ssh.keyImported SshRsa "joey" + & Ssh.hostKey SshDsa ctx + & Ssh.hostKey SshRsa ctx + & Ssh.hostKey SshEcdsa ctx + & Ssh.keyImported SshRsa "joey" ctx -- PV-grub chaining -- http://notes.pault.ag/linode-pv-grub-chainning/ @@ -263,13 +265,13 @@ standardSystem hn suite arch = host hn & Apt.installed ["etckeeper"] & Apt.installed ["ssh"] & GitHome.installedFor "root" - & User.hasSomePassword "root" + & User.hasSomePassword "root" (Context hn) -- Harden the system, but only once root's authorized_keys -- is safely in place. & check (Ssh.hasAuthorizedKeys "root") (Ssh.passwordAuthentication False) & User.accountFor "joey" - & User.hasSomePassword "joey" + & User.hasSomePassword "joey" (Context hn) & Sudo.enabledFor "joey" & GitHome.installedFor "joey" & Apt.installed ["vim", "screen", "less"] diff --git a/debian/changelog b/debian/changelog index 83a9a767..5530e5c8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,14 @@ -propellor (0.7.1) UNRELEASED; urgency=medium +propellor (0.8.0) UNRELEASED; urgency=medium + + * Completely reworked privdata storage. There is now a single file, + and each host is sent only the privdata that its Properties actually use. + + To transition existing privdata, run propellor against a host and + watch out for the red failure messages, and run the suggested commands + to store the privdata using the new storage scheme. * Add --edit to edit a privdata value in $EDITOR. - * Add --list-fields to list a host's currently set privdata fields. + * Add --list-fields to list all currently set privdata fields. * Fix randomHostKeys property to run openssh-server's postinst in a non-failing way. * Hostname.sane now cleans up the 127.0.0.1 localhost line in /etc/hosts, diff --git a/doc/security.mdwn b/doc/security.mdwn index 5576bf06..075d68ec 100644 --- a/doc/security.mdwn +++ b/doc/security.mdwn @@ -27,10 +27,11 @@ Since the propoellor git repository is public, you can't store in cleartext private data such as passwords, ssh private keys, etc. Instead, `propellor --spin $host` looks for a -`~/.propellor/privdata/$host.gpg` file and if found decrypts it and sends -it to the remote host using ssh. This lets a remote host know its own -private data, without seeing all the rest. - -To securely store private data, use: `propellor --set $host $field` -The field name will be something like 'Password "root"'; see PrivData.hs -for available fields. +`~/.propellor/privdata/privdata.gpg` file and if found decrypts it, +extracts the private that that the $host needs, and sends it to to the +$host using ssh. This lets a host know its own private data, without +seeing all the rest. + +To securely store private data, use: `propellor --set $field $context` +Propellor will tell you the details when you use a Property that needs +PrivData. diff --git a/propellor.cabal b/propellor.cabal index 2ac8a44a..1f606d31 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -105,6 +105,7 @@ Library Propellor.Types Propellor.Types.OS Propellor.Types.Dns + Propellor.Types.PrivData Other-Modules: Propellor.Types.Info Propellor.CmdLine diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs index 1027fd8d..b6dd2bc1 100644 --- a/src/Propellor/CmdLine.hs +++ b/src/Propellor/CmdLine.hs @@ -27,10 +27,10 @@ usage = do , " propellor hostname" , " propellor --spin hostname" , " propellor --add-key keyid" - , " propellor --set hostname field" - , " propellor --dump hostname field" - , " propellor --edit hostname field" - , " propellor --list-fields hostname" + , " propellor --set field context" + , " propellor --dump field context" + , " propellor --edit field context" + , " propellor --list-fields" ] exitFailure @@ -41,10 +41,10 @@ processCmdLine = go =<< getArgs go ("--spin":h:[]) = return $ Spin h go ("--boot":h:[]) = return $ Boot h go ("--add-key":k:[]) = return $ AddKey k - go ("--set":h:f:[]) = withprivfield f (return . Set h) - go ("--dump":h:f:[]) = withprivfield f (return . Dump h) - go ("--edit":h:f:[]) = withprivfield f (return . Edit h) - go ("--list-fields":h:[]) = return $ ListFields h + go ("--set":f:c:[]) = withprivfield f c Set + go ("--dump":f:c:[]) = withprivfield f c Dump + go ("--edit":f:c:[]) = withprivfield f c Edit + go ("--list-fields":[]) = return ListFields go ("--continue":s:[]) = case readish s of Just cmdline -> return $ Continue cmdline Nothing -> errorMessage "--continue serialization failure" @@ -60,8 +60,8 @@ processCmdLine = go =<< getArgs else return $ Run s go _ = usage - withprivfield s f = case readish s of - Just pf -> f pf + withprivfield s c f = case readish s of + Just pf -> return $ f pf (Context c) Nothing -> errorMessage $ "Unknown privdata field " ++ s defaultMain :: [Host] -> IO () @@ -73,10 +73,10 @@ defaultMain hostlist = do go True cmdline where go _ (Continue cmdline) = go False cmdline - go _ (Set hn field) = setPrivData hn field - go _ (Dump hn field) = dumpPrivData hn field - go _ (Edit hn field) = editPrivData hn field - go _ (ListFields hn) = listPrivDataFields hn + go _ (Set field context) = setPrivData field context + go _ (Dump field context) = dumpPrivData field context + go _ (Edit field context) = editPrivData field context + go _ ListFields = listPrivDataFields go _ (AddKey keyid) = addKey keyid go _ (Chain hn) = withhost hn $ \h -> do r <- runPropellor h $ ensureProperties $ hostProperties h @@ -182,11 +182,11 @@ spin hn = do void $ gitCommit [Param "--allow-empty", Param "-a", Param "-m", Param "propellor spin"] void $ boolSystem "git" [Param "push"] cacheparams <- toCommand <$> sshCachingParams hn - go cacheparams url =<< gpgDecrypt (privDataFile hn) + go cacheparams url =<< gpgDecrypt privDataFile where go cacheparams url privdata = withBothHandles createProcessSuccess (proc "ssh" $ cacheparams ++ [user, bootstrapcmd]) $ \(toh, fromh) -> do let finish = do - senddata toh (privDataFile hn) privDataMarker privdata + senddata toh privDataLocal privDataMarker privdata hClose toh -- Display remaining output. diff --git a/src/Propellor/PrivData.hs b/src/Propellor/PrivData.hs index c2af4284..d57b2e6f 100644 --- a/src/Propellor/PrivData.hs +++ b/src/Propellor/PrivData.hs @@ -2,18 +2,20 @@ module Propellor.PrivData where -import qualified Data.Map as M import Control.Applicative import System.FilePath import System.IO import System.Directory import Data.Maybe -import Data.List +import Data.Monoid import Control.Monad import Control.Monad.IfElse import "mtl" Control.Monad.Reader +import qualified Data.Map as M +import qualified Data.Set as S import Propellor.Types +import Propellor.Types.Info import Propellor.Message import Utility.Monad import Utility.PartialPrelude @@ -25,40 +27,57 @@ import Utility.Misc import Utility.FileMode import Utility.Env --- | When the specified PrivDataField is available on the host Propellor --- is provisioning, it provies the data to the action. Otherwise, it prints --- a message to help the user make the necessary private data available. -withPrivData :: PrivDataField -> (String -> Propellor Result) -> Propellor Result -withPrivData field a = maybe missing a =<< liftIO (getPrivData field) +-- | Allows a Property to access the value of a specific PrivDataField, +-- for use in a specific Context. +-- +-- Example use: +-- +-- > withPrivData (PrivFile pemfile) (Context "joeyh.name") $ \getdata -> +-- > property "joeyh.name ssl cert" $ getdata $ \privdata -> +-- > liftIO $ writeFile pemfile privdata +-- > where pemfile = "/etc/ssl/certs/web.pem" +-- +-- Note that if the value is not available, the action is not run +-- and instead it prints a message to help the user make the necessary +-- private data available. +withPrivData + :: PrivDataField + -> Context + -> (((PrivData -> Propellor Result) -> Propellor Result) -> Property) + -> Property +withPrivData field context@(Context cname) mkprop = addinfo $ mkprop $ \a -> + maybe missing a =<< liftIO (getLocalPrivData field context) + where + missing = liftIO $ do + warningMessage $ "Missing privdata " ++ show field ++ " (for " ++ cname ++ ")" + putStrLn $ "Fix this by running: propellor --set '" ++ show field ++ "' '" ++ cname ++ "'" + return FailedChange + addinfo p = p { propertyInfo = propertyInfo p <> mempty { _privDataFields = S.singleton (field, context) } } + +{- Gets the requested field's value, in the specified context if it's + - available, from the host's local privdata cache. -} +getLocalPrivData :: PrivDataField -> Context -> IO (Maybe PrivData) +getLocalPrivData field context = + getPrivData field context . fromMaybe M.empty <$> localcache where - missing = do - host <- asks hostName - let host' = if ".docker" `isSuffixOf` host - then "$parent_host" - else host - liftIO $ do - warningMessage $ "Missing privdata " ++ show field - putStrLn $ "Fix this by running: propellor --set "++host'++" '" ++ show field ++ "'" - return FailedChange - -getPrivData :: PrivDataField -> IO (Maybe String) -getPrivData field = do - m <- catchDefaultIO Nothing $ readish <$> readFile privDataLocal - return $ maybe Nothing (M.lookup field) m - -setPrivData :: HostName -> PrivDataField -> IO () -setPrivData host field = do + localcache = catchDefaultIO Nothing $ readish <$> readFile privDataLocal + +getPrivData :: PrivDataField -> Context -> (M.Map (PrivDataField, Context) PrivData) -> Maybe PrivData +getPrivData field context = M.lookup (field, context) + +setPrivData :: PrivDataField -> Context -> IO () +setPrivData field context = do putStrLn "Enter private data on stdin; ctrl-D when done:" - setPrivDataTo host field =<< hGetContentsStrict stdin + setPrivDataTo field context =<< hGetContentsStrict stdin -dumpPrivData :: HostName -> PrivDataField -> IO () -dumpPrivData host field = +dumpPrivData :: PrivDataField -> Context -> IO () +dumpPrivData field context = maybe (error "Requested privdata is not set.") putStrLn - =<< getPrivDataFor host field + =<< (getPrivData field context <$> decryptPrivData) -editPrivData :: HostName -> PrivDataField -> IO () -editPrivData host field = do - v <- getPrivDataFor host field +editPrivData :: PrivDataField -> Context -> IO () +editPrivData field context = do + v <- getPrivData field context <$> decryptPrivData v' <- withTmpFile "propellorXXXX" $ \f h -> do hClose h maybe noop (writeFileProtected f) v @@ -66,35 +85,30 @@ editPrivData host field = do unlessM (boolSystem editor [File f]) $ error "Editor failed; aborting." readFile f - setPrivDataTo host field v' + setPrivDataTo field context v' -listPrivDataFields :: HostName -> IO () -listPrivDataFields host = do - putStrLn (host ++ "'s currently set privdata fields:") - mapM_ list . M.keys =<< decryptPrivData host +listPrivDataFields :: IO () +listPrivDataFields = do + putStrLn ("All currently set privdata fields:") + mapM_ list . M.keys =<< decryptPrivData where list = putStrLn . ("\t" ++) . shellEscape . show -setPrivDataTo :: HostName -> PrivDataField -> String -> IO () -setPrivDataTo host field value = do +setPrivDataTo :: PrivDataField -> Context -> PrivData -> IO () +setPrivDataTo field context value = do makePrivDataDir - let f = privDataFile host - m <- decryptPrivData host - let m' = M.insert field (chomp value) m - gpgEncrypt f (show m') + m <- decryptPrivData + let m' = M.insert (field, context) (chomp value) m + gpgEncrypt privDataFile (show m') putStrLn "Private data set." - void $ boolSystem "git" [Param "add", File f] + void $ boolSystem "git" [Param "add", File privDataFile] where chomp s | end s == "\n" = chomp (beginning s) | otherwise = s -getPrivDataFor :: HostName -> PrivDataField -> IO (Maybe String) -getPrivDataFor host field = M.lookup field <$> decryptPrivData host - -decryptPrivData :: HostName -> IO (M.Map PrivDataField String) -decryptPrivData host = fromMaybe M.empty . readish - <$> gpgDecrypt (privDataFile host) +decryptPrivData :: IO (M.Map (PrivDataField, Context) PrivData) +decryptPrivData = fromMaybe M.empty . readish <$> gpgDecrypt privDataFile makePrivDataDir :: IO () makePrivDataDir = createDirectoryIfMissing False privDataDir @@ -102,8 +116,8 @@ makePrivDataDir = createDirectoryIfMissing False privDataDir privDataDir :: FilePath privDataDir = "privdata" -privDataFile :: HostName -> FilePath -privDataFile host = privDataDir host ++ ".gpg" +privDataFile :: FilePath +privDataFile = privDataDir "privdata.gpg" privDataLocal :: FilePath privDataLocal = privDataDir "local" diff --git a/src/Propellor/Property/Docker.hs b/src/Propellor/Property/Docker.hs index 1521eb65..4d443986 100644 --- a/src/Propellor/Property/Docker.hs +++ b/src/Propellor/Property/Docker.hs @@ -55,10 +55,11 @@ installed = Apt.installed ["docker.io"] -- | Configures docker with an authentication file, so that images can be -- pushed to index.docker.io. Optional. configured :: Property -configured = property "docker configured" go `requires` installed +configured = prop `requires` installed where - go = withPrivData DockerAuthentication $ \cfg -> ensureProperty $ - "/root/.dockercfg" `File.hasContent` (lines cfg) + prop = withPrivData DockerAuthentication anyContext $ \getcfg -> + property "docker configured" $ getcfg $ \cfg -> ensureProperty $ + "/root/.dockercfg" `File.hasContent` (lines cfg) -- | A short descriptive name for a container. -- Should not contain whitespace or other unusual characters, diff --git a/src/Propellor/Property/File.hs b/src/Propellor/Property/File.hs index 0b060177..0e738f25 100644 --- a/src/Propellor/Property/File.hs +++ b/src/Propellor/Property/File.hs @@ -17,16 +17,17 @@ f `hasContent` newcontent = fileProperty ("replace " ++ f) -- -- The file's permissions are preserved if the file already existed. -- Otherwise, they're set to 600. -hasPrivContent :: FilePath -> Property -hasPrivContent f = property desc $ withPrivData (PrivFile f) $ \privcontent -> - ensureProperty $ fileProperty' writeFileProtected desc - (\_oldcontent -> lines privcontent) f +hasPrivContent :: FilePath -> Context -> Property +hasPrivContent f context = withPrivData (PrivFile f) context $ \getcontent -> + property desc $ getcontent $ \privcontent -> + ensureProperty $ fileProperty' writeFileProtected desc + (\_oldcontent -> lines privcontent) f where desc = "privcontent " ++ f -- | Leaves the file world-readable. -hasPrivContentExposed :: FilePath -> Property -hasPrivContentExposed f = hasPrivContent f `onChange` +hasPrivContentExposed :: FilePath -> Context -> Property +hasPrivContentExposed f context = hasPrivContent f context `onChange` mode f (combineModes (ownerWriteMode:readModes)) -- | Ensures that a line is present in a file, adding it to the end if not. diff --git a/src/Propellor/Property/Gpg.hs b/src/Propellor/Property/Gpg.hs index 64ea9fea..b4698663 100644 --- a/src/Propellor/Property/Gpg.hs +++ b/src/Propellor/Property/Gpg.hs @@ -9,6 +9,8 @@ import System.PosixCompat installed :: Property installed = Apt.installed ["gnupg"] +type GpgKeyId = String + -- | Sets up a user with a gpg key from the privdata. -- -- Note that if a secret key is exported using gpg -a --export-secret-key, @@ -21,19 +23,20 @@ installed = Apt.installed ["gnupg"] -- The GpgKeyId does not have to be a numeric id; it can just as easily -- be a description of the key. keyImported :: GpgKeyId -> UserName -> Property -keyImported keyid user = flagFile' (property desc go) genflag +keyImported keyid user = flagFile' prop genflag `requires` installed where desc = user ++ " has gpg key " ++ show keyid genflag = do d <- dotDir user return $ d ".propellor-imported-keyid-" ++ keyid - go = withPrivData (GpgKey keyid) $ \key -> makeChange $ - withHandle StdinHandle createProcessSuccess - (proc "su" ["-c", "gpg --import", user]) $ \h -> do - fileEncoding h - hPutStr h key - hClose h + prop = withPrivData GpgKey (Context keyid) $ \getkey -> + property desc $ getkey $ \key -> makeChange $ + withHandle StdinHandle createProcessSuccess + (proc "su" ["-c", "gpg --import", user]) $ \h -> do + fileEncoding h + hPutStr h key + hClose h dotDir :: UserName -> IO FilePath dotDir user = do diff --git a/src/Propellor/Property/OpenId.hs b/src/Propellor/Property/OpenId.hs index 051d6425..39cb6ff0 100644 --- a/src/Propellor/Property/OpenId.hs +++ b/src/Propellor/Property/OpenId.hs @@ -25,5 +25,6 @@ providerFor users baseurl = propertyList desc $ -- the identitites directory controls access, so open up -- file mode - identfile u = File.hasPrivContentExposed $ - concat $ [ "/var/lib/simpleid/identities/", u, ".identity" ] + identfile u = File.hasPrivContentExposed + (concat [ "/var/lib/simpleid/identities/", u, ".identity" ]) + (Context baseurl) diff --git a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs index 85584e43..4cb26a50 100644 --- a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs +++ b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs @@ -23,29 +23,25 @@ builddir = gitbuilderdir "build" type TimeOut = String -- eg, 5h -autobuilder :: CronTimes -> TimeOut -> Bool -> Property -autobuilder crontimes timeout rsyncupload = combineProperties "gitannexbuilder" +autobuilder :: Architecture -> CronTimes -> TimeOut -> Property +autobuilder arch crontimes timeout = combineProperties "gitannexbuilder" [ Apt.serviceInstalledRunning "cron" , Cron.niceJob "gitannexbuilder" crontimes builduser gitbuilderdir $ "git pull ; timeout " ++ timeout ++ " ./autobuild" -- The builduser account does not have a password set, -- instead use the password privdata to hold the rsync server -- password used to upload the built image. - , property "rsync password" $ do - let f = homedir "rsyncpassword" - if rsyncupload - then withPrivData (Password builduser) $ \p -> do - oldp <- liftIO $ catchDefaultIO "" $ - readFileStrict f - if p /= oldp - then makeChange $ writeFile f p - else noChange - else do - ifM (liftIO $ doesFileExist f) - ( noChange - , makeChange $ writeFile f "no password configured" - ) + , withPrivData (Password builduser) context $ \getpw -> + property "rsync password" $ getpw $ \pw -> do + oldpw <- liftIO $ catchDefaultIO "" $ + readFileStrict pwfile + if pw /= oldpw + then makeChange $ writeFile pwfile pw + else noChange ] + where + context = Context ("gitannexbuilder " ++ arch) + pwfile = homedir "rsyncpassword" tree :: Architecture -> Property tree buildarch = combineProperties "gitannexbuilder tree" @@ -101,13 +97,13 @@ standardAutoBuilderContainer dockerImage arch buildminute timeout = Docker.conta & User.accountFor builduser & tree arch & buildDepsApt - & autobuilder (show buildminute ++ " * * * *") timeout True + & autobuilder arch (show buildminute ++ " * * * *") timeout androidAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host androidAutoBuilderContainer dockerImage crontimes timeout = androidContainer dockerImage "android-git-annex-builder" (tree "android") builddir & Apt.unattendedUpgrades - & autobuilder crontimes timeout True + & autobuilder "android" crontimes timeout -- Android is cross-built in a Debian i386 container, using the Android NDK. androidContainer :: (System -> Docker.Image) -> Docker.ContainerName -> Property -> FilePath -> Host @@ -154,7 +150,7 @@ armelCompanionContainer dockerImage = Docker.container "armel-git-annex-builder- -- The armel builder can ssh to this companion. & Docker.expose "22" & Apt.serviceInstalledRunning "ssh" - & Ssh.authorizedKeys builduser + & Ssh.authorizedKeys builduser (Context "armel-git-annex-builder") armelAutoBuilderContainer :: (System -> Docker.Image) -> Cron.CronTimes -> TimeOut -> Host armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "armel-git-annex-builder" @@ -172,9 +168,9 @@ armelAutoBuilderContainer dockerImage crontimes timeout = Docker.container "arme -- git-annex/standalone/linux/install-haskell-packages -- which is not fully automated.) & buildDepsNoHaskellLibs - & autobuilder crontimes timeout True + & autobuilder "armel" crontimes timeout `requires` tree "armel" - & Ssh.keyImported SshRsa builduser + & Ssh.keyImported SshRsa builduser (Context "armel-git-annex-builder") & trivial writecompanionaddress where writecompanionaddress = scriptProperty diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 57023cb5..bffc8a30 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -29,7 +29,7 @@ oldUseNetServer hosts = propertyList ("olduse.net server") [ "--repository=sftp://2318@usw-s002.rsync.net/~/olduse.net" , "--client-name=spool" ] Obnam.OnlyClient - `requires` Ssh.keyImported SshRsa "root" + `requires` Ssh.keyImported SshRsa "root" (Context "olduse.net") `requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root" , check (not . isSymbolicLink <$> getSymbolicLinkStatus newsspool) $ property "olduse.net spool in place" $ makeChange $ do @@ -97,7 +97,7 @@ kgbServer = withOS desc $ \o -> case o of (Just (System (Debian Unstable) _)) -> ensureProperty $ propertyList desc [ Apt.serviceInstalledRunning "kgb-bot" - , File.hasPrivContent "/etc/kgb-bot/kgb.conf" + , File.hasPrivContent "/etc/kgb-bot/kgb.conf" anyContext `onChange` Service.restarted "kgb-bot" , "/etc/default/kgb-bot" `File.containsLine` "BOT_ENABLED=1" `describe` "kgb bot enabled" @@ -108,17 +108,19 @@ kgbServer = withOS desc $ \o -> case o of desc = "kgb.kitenet.net setup" mumbleServer :: [Host] -> Property -mumbleServer hosts = combineProperties "mumble.debian.net" +mumbleServer hosts = combineProperties hn [ Apt.serviceInstalledRunning "mumble-server" , Obnam.latestVersion , Obnam.backup "/var/lib/mumble-server" "55 5 * * *" - [ "--repository=sftp://joey@turtle.kitenet.net/~/lib/backup/mumble.debian.net.obnam" + [ "--repository=sftp://joey@turtle.kitenet.net/~/lib/backup/" ++ hn ++ ".obnam" , "--client-name=mumble" ] Obnam.OnlyClient - `requires` Ssh.keyImported SshRsa "root" + `requires` Ssh.keyImported SshRsa "root" (Context hn) `requires` Ssh.knownHost hosts "turtle.kitenet.net" "root" , trivial $ cmdProperty "chown" ["-R", "mumble-server:mumble-server", "/var/lib/mumble-server"] ] + where + hn = "mumble.debian.net" obnamLowMem :: Property obnamLowMem = combineProperties "obnam tuned for low memory use" @@ -141,16 +143,16 @@ gitServer hosts = propertyList "git.kitenet.net setup" , "--client-name=wren" ] Obnam.OnlyClient `requires` Gpg.keyImported "1B169BE1" "root" - `requires` Ssh.keyImported SshRsa "root" + `requires` Ssh.keyImported SshRsa "root" (Context "git.kitenet.net") `requires` Ssh.knownHost hosts "usw-s002.rsync.net" "root" - `requires` Ssh.authorizedKeys "family" + `requires` Ssh.authorizedKeys "family" (Context "git.kitenet.net") `requires` User.accountFor "family" , Apt.installed ["git", "rsync", "gitweb"] -- backport avoids channel flooding on branch merge , Apt.installedBackport ["kgb-client"] -- backport supports ssh event notification , Apt.installedBackport ["git-annex"] - , File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf" + , File.hasPrivContentExposed "/etc/kgb-bot/kgb-client.conf" anyContext , toProp $ Git.daemonRunning "/srv/git" , "/etc/gitweb.conf" `File.containsLines` [ "$projectroot = '/srv/git';" @@ -202,7 +204,7 @@ annexWebSite hosts origin hn uuid remotes = propertyList (hn ++" website using g dir = "/srv/web/" ++ hn postupdatehook = dir ".git/hooks/post-update" setup = userScriptProperty "joey" setupscript - `requires` Ssh.keyImported SshRsa "joey" + `requires` Ssh.keyImported SshRsa "joey" (Context hn) `requires` Ssh.knownHost hosts "turtle.kitenet.net" "joey" setupscript = [ "cd " ++ shellEscape dir @@ -270,9 +272,9 @@ mainhttpscert True = gitAnnexDistributor :: Property gitAnnexDistributor = combineProperties "git-annex distributor, including rsync server and signer" [ Apt.installed ["rsync"] - , File.hasPrivContent "/etc/rsyncd.conf" + , File.hasPrivContent "/etc/rsyncd.conf" (Context "git-annex distributor") `onChange` Service.restarted "rsync" - , File.hasPrivContent "/etc/rsyncd.secrets" + , File.hasPrivContent "/etc/rsyncd.secrets" (Context "git-annex distributor") `onChange` Service.restarted "rsync" , "/etc/default/rsync" `File.containsLine` "RSYNC_ENABLE=true" `onChange` Service.running "rsync" @@ -315,7 +317,7 @@ ircBouncer = propertyList "IRC bouncer" [ Apt.installed ["znc"] , User.accountFor "znc" , File.dirExists (parentDir conf) - , File.hasPrivContent conf + , File.hasPrivContent conf anyContext , File.ownerGroup conf "znc" "znc" , Cron.job "znconboot" "@reboot" "znc" "~" "znc" -- ensure running if it was not already @@ -341,7 +343,7 @@ githubBackup :: Property githubBackup = propertyList "github-backup box" [ Apt.installed ["github-backup", "moreutils"] , let f = "/home/joey/.github-keys" - in File.hasPrivContent f + in File.hasPrivContent f anyContext `onChange` File.ownerGroup f "joey" "joey" ] diff --git a/src/Propellor/Property/Ssh.hs b/src/Propellor/Property/Ssh.hs index bc0e7cab..6785ede6 100644 --- a/src/Propellor/Property/Ssh.hs +++ b/src/Propellor/Property/Ssh.hs @@ -75,42 +75,43 @@ randomHostKeys = flagFile prop "/etc/ssh/.unique_host_keys" ensureProperty $ scriptProperty [ "DPKG_MAINTSCRIPT_NAME=postinst DPKG_MAINTSCRIPT_PACKAGE=openssh-server /var/lib/dpkg/info/openssh-server.postinst configure" ] --- | Sets ssh host keys from the site's PrivData. --- --- (Uses a null username for host keys.) -hostKey :: SshKeyType -> Property -hostKey keytype = combineProperties desc - [ property desc (install writeFile (SshPubKey keytype "") ".pub") - , property desc (install writeFileProtected (SshPrivKey keytype "") "") +-- | Sets ssh host keys. +hostKey :: SshKeyType -> Context -> Property +hostKey keytype context = combineProperties desc + [ installkey (SshPubKey keytype "") (install writeFile ".pub") + , installkey (SshPrivKey keytype "") (install writeFileProtected "") ] `onChange` restartSshd where desc = "known ssh host key (" ++ fromKeyType keytype ++ ")" - install writer p ext = withPrivData p $ \key -> do + installkey p a = withPrivData p context $ \getkey -> + property desc $ getkey a + install writer ext key = do let f = "/etc/ssh/ssh_host_" ++ fromKeyType keytype ++ "_key" ++ ext s <- liftIO $ readFileStrict f if s == key then noChange else makeChange $ writer f key --- | Sets up a user with a ssh private key and public key pair --- from the site's PrivData. -keyImported :: SshKeyType -> UserName -> Property -keyImported keytype user = combineProperties desc - [ property desc (install writeFile (SshPubKey keytype user) ".pub") - , property desc (install writeFileProtected (SshPrivKey keytype user) "") +-- | Sets up a user with a ssh private key and public key pair from the +-- PrivData. +keyImported :: SshKeyType -> UserName -> Context -> Property +keyImported keytype user context = combineProperties desc + [ installkey (SshPubKey keytype user) (install writeFile ".pub") + , installkey (SshPrivKey keytype user) (install writeFileProtected "") ] where desc = user ++ " has ssh key (" ++ fromKeyType keytype ++ ")" - install writer p ext = do + installkey p a = withPrivData p context $ \getkey -> + property desc $ getkey a + install writer ext key = do f <- liftIO $ keyfile ext ifM (liftIO $ doesFileExist f) ( noChange , ensureProperties - [ property desc $ - withPrivData p $ \key -> makeChange $ do - createDirectoryIfMissing True (takeDirectory f) - writer f key + [ property desc $ makeChange $ do + createDirectoryIfMissing True (takeDirectory f) + writer f key , File.ownerGroup f user user , File.ownerGroup (takeDirectory f) user user ] @@ -143,9 +144,9 @@ knownHost hosts hn user = property desc $ return FailedChange -- | Makes a user have authorized_keys from the PrivData -authorizedKeys :: UserName -> Property -authorizedKeys user = property (user ++ " has authorized_keys") $ - withPrivData (SshAuthorizedKeys user) $ \v -> do +authorizedKeys :: UserName -> Context -> Property +authorizedKeys user context = withPrivData (SshAuthorizedKeys user) context $ \get -> + property (user ++ " has authorized_keys") $ get $ \v -> do f <- liftIO $ dotFile "authorized_keys" user liftIO $ do createDirectoryIfMissing True (takeDirectory f) diff --git a/src/Propellor/Property/User.hs b/src/Propellor/Property/User.hs index eef2a57e..f9c400a8 100644 --- a/src/Propellor/Property/User.hs +++ b/src/Propellor/Property/User.hs @@ -24,17 +24,18 @@ nuked user _ = check (isJust <$> catchMaybeIO (homedir user)) $ cmdProperty "use -- | Only ensures that the user has some password set. It may or may -- not be the password from the PrivData. -hasSomePassword :: UserName -> Property -hasSomePassword user = check ((/= HasPassword) <$> getPasswordStatus user) $ - hasPassword user - -hasPassword :: UserName -> Property -hasPassword user = property (user ++ " has password") $ - withPrivData (Password user) $ \password -> makeChange $ - withHandle StdinHandle createProcessSuccess - (proc "chpasswd" []) $ \h -> do - hPutStrLn h $ user ++ ":" ++ password - hClose h +hasSomePassword :: UserName -> Context -> Property +hasSomePassword user context = check ((/= HasPassword) <$> getPasswordStatus user) $ + hasPassword user context + +hasPassword :: UserName -> Context -> Property +hasPassword user context = withPrivData (Password user) context $ \getpassword -> + property (user ++ " has password") $ + getpassword $ \password -> makeChange $ + withHandle StdinHandle createProcessSuccess + (proc "chpasswd" []) $ \h -> do + hPutStrLn h $ user ++ ":" ++ password + hClose h lockedPassword :: UserName -> Property lockedPassword user = check (not <$> isLockedPassword user) $ cmdProperty "passwd" diff --git a/src/Propellor/Types.hs b/src/Propellor/Types.hs index 59652f66..037cd962 100644 --- a/src/Propellor/Types.hs +++ b/src/Propellor/Types.hs @@ -17,7 +17,9 @@ module Propellor.Types , ActionResult(..) , CmdLine(..) , PrivDataField(..) - , GpgKeyId + , PrivData + , Context(..) + , anyContext , SshKeyType(..) , module Propellor.Types.OS , module Propellor.Types.Dns @@ -32,6 +34,7 @@ import "MonadCatchIO-transformers" Control.Monad.CatchIO import Propellor.Types.Info import Propellor.Types.OS import Propellor.Types.Dns +import Propellor.Types.PrivData -- | Everything Propellor knows about a system: Its hostname, -- properties and other info. @@ -135,30 +138,12 @@ data CmdLine = Run HostName | Spin HostName | Boot HostName - | Set HostName PrivDataField - | Dump HostName PrivDataField - | Edit HostName PrivDataField - | ListFields HostName + | Set PrivDataField Context + | Dump PrivDataField Context + | Edit PrivDataField Context + | ListFields | AddKey String | Continue CmdLine | Chain HostName | Docker HostName deriving (Read, Show, Eq) - --- | Note that removing or changing field names will break the --- serialized privdata files, so don't do that! --- It's fine to add new fields. -data PrivDataField - = DockerAuthentication - | SshPubKey SshKeyType UserName - | SshPrivKey SshKeyType UserName - | SshAuthorizedKeys UserName - | Password UserName - | PrivFile FilePath - | GpgKey GpgKeyId - deriving (Read, Show, Ord, Eq) - -type GpgKeyId = String - -data SshKeyType = SshRsa | SshDsa | SshEcdsa | SshEd25519 - deriving (Read, Show, Ord, Eq) diff --git a/src/Propellor/Types/Info.hs b/src/Propellor/Types/Info.hs index 5f034492..8856e06f 100644 --- a/src/Propellor/Types/Info.hs +++ b/src/Propellor/Types/Info.hs @@ -1,6 +1,7 @@ module Propellor.Types.Info where import Propellor.Types.OS +import Propellor.Types.PrivData import qualified Propellor.Types.Dns as Dns import qualified Data.Set as S @@ -9,6 +10,7 @@ import Data.Monoid -- | Information about a host. data Info = Info { _os :: Val System + , _privDataFields :: S.Set (PrivDataField, Context) , _sshPubKey :: Val String , _dns :: S.Set Dns.Record , _namedconf :: Dns.NamedConfMap @@ -17,9 +19,10 @@ data Info = Info deriving (Eq, Show) instance Monoid Info where - mempty = Info mempty mempty mempty mempty mempty + mempty = Info mempty mempty mempty mempty mempty mempty mappend old new = Info { _os = _os old <> _os new + , _privDataFields = _privDataFields old <> _privDataFields new , _sshPubKey = _sshPubKey old <> _sshPubKey new , _dns = _dns old <> _dns new , _namedconf = _namedconf old <> _namedconf new diff --git a/src/Propellor/Types/PrivData.hs b/src/Propellor/Types/PrivData.hs new file mode 100644 index 00000000..16d6cdb1 --- /dev/null +++ b/src/Propellor/Types/PrivData.hs @@ -0,0 +1,34 @@ +module Propellor.Types.PrivData where + +import Propellor.Types.OS + +-- | Note that removing or changing field names will break the +-- serialized privdata files, so don't do that! +-- It's fine to add new fields. +data PrivDataField + = DockerAuthentication + | SshPubKey SshKeyType UserName + | SshPrivKey SshKeyType UserName + | SshAuthorizedKeys UserName + | Password UserName + | PrivFile FilePath + | GpgKey + deriving (Read, Show, Ord, Eq) + +-- | Context in which a PrivDataField is used. +-- +-- Often this will be a domain name. For example, +-- Context "www.example.com" could be used for the SSL cert +-- for the web server serving that domain. Multiple hosts might +-- use that privdata. +newtype Context = Context String + deriving (Read, Show, Ord, Eq) + +-- | Use when a PrivDataField is not dependent on any paricular context. +anyContext :: Context +anyContext = Context "any" + +type PrivData = String + +data SshKeyType = SshRsa | SshDsa | SshEcdsa | SshEd25519 + deriving (Read, Show, Ord, Eq) -- cgit v1.3-2-g0d8e From 9bc7ddd95c0cef52d210c0b9e5217745dc23e2b8 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 6 Jul 2014 17:23:55 -0400 Subject: desc --- config-joey.hs | 1 + 1 file changed, 1 insertion(+) (limited to 'config-joey.hs') diff --git a/config-joey.hs b/config-joey.hs index 31ea685c..aff03bb5 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -162,6 +162,7 @@ hosts = -- (o) ` [ "configfile (xen/xvda1)/boot/grub/grub.cfg" ] & Apt.installed ["grub-xen"] & flagFile (scriptProperty ["update-grub; grub-mkimage --prefix '(xen/xvda1)/boot/grub' -c /boot/load.cf -O x86_64-xen /usr/lib/grub/x86_64-xen/*.mod > /boot/xen-shim"]) "/boot/xen-shim" + `describe` "/boot-xen-shim" & alias "eubackup.kitenet.net" & Apt.installed ["obnam", "sshfs", "rsync"] -- cgit v1.3-2-g0d8e From 9f812cda9d21bc0cfc3e6f4520aa325921b3056c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sun, 6 Jul 2014 18:12:38 -0400 Subject: propellor spin --- config-joey.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'config-joey.hs') diff --git a/config-joey.hs b/config-joey.hs index aff03bb5..783c548f 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -72,7 +72,7 @@ hosts = -- (o) ` & Apt.buildDep ["git-annex"] `period` Daily -- Important stuff that needs not too much memory or CPU. - , let ctx = Context "diatom.kitenet.net " + , let ctx = Context "diatom.kitenet.net" in standardSystem "diatom.kitenet.net" Stable "amd64" & ipv4 "107.170.31.195" -- cgit v1.3-2-g0d8e