diff options
| author | Joey Hess <joeyh@joeyh.name> | 2016-01-03 16:26:16 -0400 |
|---|---|---|
| committer | Joey Hess <joeyh@joeyh.name> | 2016-01-03 16:26:16 -0400 |
| commit | 3f5cc046915a9f64c31a6d48aaef5254f5eb7598 (patch) | |
| tree | 110bd5acac6adf0c08111efb9f9cd2dc07701b30 | |
| parent | 299d478dfd96037c660109c4f0519fd1cc37a887 (diff) | |
| parent | 93ee9e6966783368fa41fb75c7e287bee04f9c16 (diff) | |
Merge branch 'joeyconfig'
| -rw-r--r-- | config-joey.hs | 47 | ||||
| -rw-r--r-- | debian/changelog | 4 | ||||
| -rw-r--r-- | src/Propellor/Bootstrap.hs | 4 | ||||
| -rw-r--r-- | src/Propellor/CmdLine.hs | 2 | ||||
| -rw-r--r-- | src/Propellor/Info.hs | 4 | ||||
| -rw-r--r-- | src/Propellor/Property/HostingProvider/CloudAtCost.hs | 1 | ||||
| -rw-r--r-- | src/Propellor/Property/Munin.hs | 57 | ||||
| -rw-r--r-- | src/Propellor/Property/Postfix.hs | 136 | ||||
| -rw-r--r-- | src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs | 1 | ||||
| -rw-r--r-- | src/Propellor/Property/SiteSpecific/JoeySites.hs | 9 |
10 files changed, 254 insertions, 11 deletions
diff --git a/config-joey.hs b/config-joey.hs index df6e40dc..d18b4a7b 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -46,6 +46,8 @@ hosts = -- (o) ` [ darkstar , gnu , clam + , mayfly + , oyster , orca , honeybee , kite @@ -118,6 +120,8 @@ clam = standardSystem "clam.kitenet.net" Unstable "amd64" ] & Apt.unattendedUpgrades & Network.ipv6to4 + & Systemd.persistentJournal + & Journald.systemMaxUse "500MiB" & Tor.isRelay & Tor.named "kite1" @@ -134,14 +138,44 @@ clam = standardSystem "clam.kitenet.net" Unstable "amd64" & JoeySites.scrollBox & alias "scroll.joeyh.name" & alias "us.scroll.joeyh.name" + +mayfly :: Host +mayfly = standardSystem "mayfly.kitenet.net" (Stable "jessie") "amd64" + [ "Scratch VM. Contents can change at any time!" ] + & ipv4 "104.167.118.15" + + & CloudAtCost.decruft + & Apt.unattendedUpgrades + & Network.ipv6to4 + & Systemd.persistentJournal + & Journald.systemMaxUse "500MiB" - -- ssh on some extra ports to deal with horrible networks - -- while travelling - & alias "travelling.kitenet.net" - ! Ssh.listenPort 80 - ! Ssh.listenPort 443 + & Tor.isRelay + & Tor.named "kite3" + & Tor.bandwidthRate (Tor.PerMonth "400 GB") +oyster :: Host +oyster = standardSystem "oyster.kitenet.net" Unstable "amd64" + [ "Unreliable server. Anything here may be lost at any time!" ] + & ipv4 "104.167.117.109" + + & CloudAtCost.decruft + & Ssh.hostKeys hostContext + [ (SshEcdsa, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBP0ws/IxQegVU0RhqnIm5A/vRSPTO70wD4o2Bd1jL970dTetNyXzvWGe1spEbLjIYSLIO7WvOBSE5RhplBKFMUU=") + ] + & Apt.unattendedUpgrades + & Network.ipv6to4 & Systemd.persistentJournal + & Journald.systemMaxUse "500MiB" + + & Tor.isRelay + & Tor.named "kite2" + & Tor.bandwidthRate (Tor.PerMonth "400 GB") + + -- Nothing is using http port 80, so listen on + -- that port for ssh, for traveling on bad networks that + -- block 22. + & Ssh.listenPort 80 orca :: Host orca = standardSystem "orca.kitenet.net" Unstable "amd64" @@ -184,6 +218,9 @@ honeybee = standardSystem "honeybee.kitenet.net" Testing "armhf" -- 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" diff --git a/debian/changelog b/debian/changelog index d3c84858..314ba037 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,10 @@ propellor (2.15.2) UNRELEASED; urgency=medium * Added GNUPGBIN environment variable to control the command run for gpg. Allows eg, GNUPGBIN=gpg2 Thanks, Félix Sipma. + * Bootstrap apt-get installs run with deconf noninteractive frontend. + * spin --via: Avoid committing on relay host. + * Postfix: Add service property to enable/disable services in master.cf. + * Added Munin module, contributed by Jelmer Vernooij. -- Joey Hess <id@joeyh.name> Wed, 30 Dec 2015 15:01:19 -0400 diff --git a/src/Propellor/Bootstrap.hs b/src/Propellor/Bootstrap.hs index f2f5af55..c49cb5af 100644 --- a/src/Propellor/Bootstrap.hs +++ b/src/Propellor/Bootstrap.hs @@ -63,7 +63,7 @@ depsCommand = "( " ++ intercalate " ; " (concat [osinstall, cabalinstall]) ++ " , "cabal install --only-dependencies" ] - aptinstall p = "apt-get --no-upgrade --no-install-recommends -y install " ++ p + aptinstall p = "DEBIAN_FRONTEND=noninteractive apt-get --no-upgrade --no-install-recommends -y install " ++ p -- This is the same deps listed in debian/control. debdeps = @@ -86,7 +86,7 @@ depsCommand = "( " ++ intercalate " ; " (concat [osinstall, cabalinstall]) ++ " ] installGitCommand :: ShellCommand -installGitCommand = "if ! git --version >/dev/null; then apt-get update && apt-get --no-install-recommends --no-upgrade -y install git; fi" +installGitCommand = "if ! git --version >/dev/null; then apt-get update && DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends --no-upgrade -y install git; fi" buildPropellor :: IO () buildPropellor = unlessM (actionMessage "Propellor build" build) $ diff --git a/src/Propellor/CmdLine.hs b/src/Propellor/CmdLine.hs index 4a4f71fe..1e61adc8 100644 --- a/src/Propellor/CmdLine.hs +++ b/src/Propellor/CmdLine.hs @@ -118,7 +118,7 @@ defaultMain hostlist = withConcurrentOutput $ do go True cmdline@(Spin _ _) = buildFirst cmdline $ go False cmdline go True cmdline = updateFirst cmdline $ go False cmdline go False (Spin hs mrelay) = do - commitSpin + unless (isJust mrelay) commitSpin forM_ hs $ \hn -> withhost hn $ spin mrelay hn go False cmdline@(SimpleRun hn) = do forceConsole diff --git a/src/Propellor/Info.hs b/src/Propellor/Info.hs index 499b901c..7eb7d4a8 100644 --- a/src/Propellor/Info.hs +++ b/src/Propellor/Info.hs @@ -34,7 +34,7 @@ os system = pureInfoProperty ("Operating " ++ show system) (InfoVal system) getOS :: Propellor (Maybe System) getOS = fromInfoVal <$> askInfo --- | Indidate that a host has an A record in the DNS. +-- | Indicate that a host has an A record in the DNS. -- -- When propellor is used to deploy a DNS server for a domain, -- the hosts in the domain are found by looking for these @@ -46,7 +46,7 @@ getOS = fromInfoVal <$> askInfo ipv4 :: String -> Property HasInfo ipv4 = addDNS . Address . IPv4 --- | Indidate that a host has an AAAA record in the DNS. +-- | Indicate that a host has an AAAA record in the DNS. ipv6 :: String -> Property HasInfo ipv6 = addDNS . Address . IPv6 diff --git a/src/Propellor/Property/HostingProvider/CloudAtCost.hs b/src/Propellor/Property/HostingProvider/CloudAtCost.hs index ef7dd743..bfe3ae17 100644 --- a/src/Propellor/Property/HostingProvider/CloudAtCost.hs +++ b/src/Propellor/Property/HostingProvider/CloudAtCost.hs @@ -17,6 +17,7 @@ decruft = propertyList "cloudatcost cleanup" [ File.notPresent "/etc/rc.local" , File.notPresent "/etc/init.d/S97-setup.sh" , File.notPresent "/zang-debian.sh" + , File.notPresent "/bin/npasswd" , User.nuked (User "user") User.YesReallyDeleteHome ] ] diff --git a/src/Propellor/Property/Munin.hs b/src/Propellor/Property/Munin.hs new file mode 100644 index 00000000..43112a6c --- /dev/null +++ b/src/Propellor/Property/Munin.hs @@ -0,0 +1,57 @@ +-- | Maintainer: Jelmer Vernooij <jelmer@jelmer.uk> +-- +module Propellor.Property.Munin ( + hostListFragment, + hostListFragment', + nodePort, + nodeInstalled, + nodeRestarted, + nodeConfPath, + masterInstalled, + masterRestarted, + masterConfPath, +) where + +import Propellor +import qualified Propellor.Property.Apt as Apt +import qualified Propellor.Property.Service as Service + +nodePort :: Integer +nodePort = 4949 + +nodeInstalled :: Property NoInfo +nodeInstalled = Apt.serviceInstalledRunning "munin-node" + +nodeRestarted :: Property NoInfo +nodeRestarted = Service.restarted "munin-node" + +nodeConfPath :: FilePath +nodeConfPath = "/etc/munin/munin-node.conf" + +masterInstalled :: Property NoInfo +masterInstalled = Apt.serviceInstalledRunning "munin" + +masterRestarted :: Property NoInfo +masterRestarted = Service.restarted "munin" + +masterConfPath :: FilePath +masterConfPath = "/etc/munin/munin.conf" + + +-- | Create the host list fragment for master config. +-- Takes an optional override list for hosts that are accessible on a non-standard host/port. +-- TODO(jelmer): Only do this on hosts where munin is present (in other words, with Munin.installedNode) +hostListFragment' :: [Host] -> [(HostName, (IPAddr, Port))] -> [String] +hostListFragment' hs os = concatMap muninHost hs + where + muninHost :: Host -> [String] + muninHost h = [ "[" ++ (hostName h) ++ "]" + , " address " ++ maybe (hostName h) (fromIPAddr . fst) (hOverride h) + ] ++ (maybe [] (\x -> [" port " ++ (show $ fromPort $ snd x)]) (hOverride h)) ++ [""] + hOverride :: Host -> Maybe (IPAddr, Port) + hOverride h = lookup (hostName h) os + fromPort (Port p) = p + +-- | Create the host list fragment for master config. +hostListFragment :: [Host] -> [String] +hostListFragment hs = hostListFragment' hs [] diff --git a/src/Propellor/Property/Postfix.hs b/src/Propellor/Property/Postfix.hs index 1c8684c7..df244061 100644 --- a/src/Propellor/Property/Postfix.hs +++ b/src/Propellor/Property/Postfix.hs @@ -129,6 +129,142 @@ dedupCf ls = Just n | n > 1 -> dedup c (M.insert k (n - 1) kc) rest _ -> dedup (fmt k v:c) kc rest +-- | The master config file for postfix. +masterCfFile :: FilePath +masterCfFile = "/etc/postfix/master.cf" + +-- | A service that can be present in the master config file. +data Service = Service + { serviceType :: ServiceType + , serviceCommand :: String + , serviceOpts :: ServiceOpts + } + deriving (Show, Eq) + +data ServiceType + = InetService (Maybe HostName) ServicePort + | UnixService FilePath PrivateService + | FifoService FilePath PrivateService + | PassService FilePath PrivateService + deriving (Show, Eq) + +-- Can be a port number or service name such as "smtp". +type ServicePort = String + +type PrivateService = Bool + +-- | Options for a service. +data ServiceOpts = ServiceOpts + { serviceUnprivileged :: Maybe Bool + , serviceChroot :: Maybe Bool + , serviceWakeupTime :: Maybe Int + , serviceProcessLimit :: Maybe Int + } + deriving (Show, Eq) + +defServiceOpts :: ServiceOpts +defServiceOpts = ServiceOpts + { serviceUnprivileged = Nothing + , serviceChroot = Nothing + , serviceWakeupTime = Nothing + , serviceProcessLimit = Nothing + } + +formatServiceLine :: Service -> File.Line +formatServiceLine s = unwords $ map pad + [ (10, case serviceType s of + InetService (Just h) p -> h ++ ":" ++ p + InetService Nothing p -> p + UnixService f _ -> f + FifoService f _ -> f + PassService f _ -> f) + , (6, case serviceType s of + InetService _ _ -> "inet" + UnixService _ _ -> "unix" + FifoService _ _ -> "fifo" + PassService _ _ -> "pass") + , (8, case serviceType s of + InetService _ _ -> bool False + UnixService _ b -> bool b + FifoService _ b -> bool b + PassService _ b -> bool b) + , (8, v bool serviceUnprivileged) + , (8, v bool serviceChroot) + , (8, v show serviceWakeupTime) + , (8, v show serviceProcessLimit) + , (0, serviceCommand s) + ] + where + v f sel = maybe "-" f (sel (serviceOpts s)) + bool True = "y" + bool False = "n" + pad (n, t) = t ++ replicate (n - 1 - length t) ' ' + +-- | Note that this does not handle multi-line service entries, +-- in which subsequent lines are indented. `serviceLine` does not generate +-- such entries. +parseServiceLine :: File.Line -> Maybe Service +parseServiceLine ('#':_) = Nothing +parseServiceLine (' ':_) = Nothing -- continuation of multiline entry +parseServiceLine l = Service + <$> parsetype + <*> parsecommand + <*> parseopts + where + parsetype = do + t <- getword 2 + case t of + "inet" -> do + v <- getword 1 + let (h,p) = separate (== ':') v + if null p + then Nothing + else Just $ InetService + (if null h then Nothing else Just h) p + "unix" -> UnixService <$> getword 1 <*> parseprivate + "fifo" -> FifoService <$> getword 1 <*> parseprivate + "pass" -> PassService <$> getword 1 <*> parseprivate + _ -> Nothing + parseprivate = join . bool =<< getword 3 + + parsecommand = case unwords (drop 7 ws) of + "" -> Nothing + s -> Just s + + parseopts = ServiceOpts + <$> (bool =<< getword 4) + <*> (bool =<< getword 5) + <*> (int =<< getword 6) + <*> (int =<< getword 7) + + bool "-" = Just Nothing + bool "y" = Just (Just True) + bool "n" = Just (Just False) + bool _ = Nothing + + int "-" = Just Nothing + int n = maybe Nothing (Just . Just) (readish n) + + getword n + | nws >= n = Just (ws !! (n -1)) + | otherwise = Nothing + ws = words l + nws = length ws + +-- | Enables a `Service` in postfix's `masterCfFile`. +service :: Service -> RevertableProperty NoInfo +service s = (enable <!> disable) + `describe` desc + where + desc = "enabled postfix service " ++ show (serviceType s) + enable = masterCfFile `File.containsLine` (formatServiceLine s) + `onChange` reloaded + disable = File.fileProperty desc (filter (not . matches)) masterCfFile + `onChange` reloaded + matches l = case parseServiceLine l of + Just s' | s' == s -> True + _ -> False + -- | Installs saslauthd and configures it for postfix, authenticating -- against PAM. -- diff --git a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs index 2312846c..153d714f 100644 --- a/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs +++ b/src/Propellor/Property/SiteSpecific/GitAnnexBuilder.hs @@ -118,6 +118,7 @@ standardAutoBuilder osver@(System _ arch) flavor = & os osver & Apt.stdSourcesList & Apt.unattendedUpgrades + & Apt.cacheCleaned & User.accountFor (User builduser) & tree arch flavor diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index 732714db..f140404d 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -694,16 +694,23 @@ kiteMailServer = propertyList "kitenet.net mail server" $ props `describe` "pine configured to use local imap server" & Apt.serviceInstalledRunning "mailman" + + & Postfix.service ssmtp where ctx = Context "kitenet.net" pinescript = "/usr/local/bin/pine" dovecotusers = "/etc/dovecot/users" + ssmtp = Postfix.Service + (Postfix.InetService Nothing "ssmtp") + "smtpd" Postfix.defServiceOpts + -- Configures postfix to relay outgoing mail to kitenet.net, with -- verification via tls cert. postfixClientRelay :: Context -> Property HasInfo postfixClientRelay ctx = Postfix.mainCfFile `File.containsLines` - [ "relayhost = kitenet.net" + -- Using smtps not smtp because more networks firewall smtp + [ "relayhost = kitenet.net:smtps" , "smtp_tls_CAfile = /etc/ssl/certs/joeyca.pem" , "smtp_tls_cert_file = /etc/ssl/certs/postfix.pem" , "smtp_tls_key_file = /etc/ssl/private/postfix.pem" |
