diff --git a/config-joey.hs b/config-joey.hs index 18f0a32..b9a2bed 100644 --- a/config-joey.hs +++ b/config-joey.hs @@ -8,6 +8,7 @@ import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import qualified Propellor.Property.Network as Network import qualified Propellor.Property.Ssh as Ssh +import qualified Propellor.Property.Gpg as Gpg import qualified Propellor.Property.Cron as Cron import qualified Propellor.Property.Sudo as Sudo import qualified Propellor.Property.User as User @@ -22,6 +23,7 @@ import qualified Propellor.Property.Apache as Apache import qualified Propellor.Property.Postfix as Postfix import qualified Propellor.Property.Service as Service import qualified Propellor.Property.Grub as Grub +import qualified Propellor.Property.Obnam as Obnam import qualified Propellor.Property.HostingProvider.DigitalOcean as DigitalOcean import qualified Propellor.Property.HostingProvider.CloudAtCost as CloudAtCost import qualified Propellor.Property.HostingProvider.Linode as Linode @@ -41,7 +43,7 @@ hosts = -- (o) ` & Apt.buildDep ["git-annex"] `period` Daily & Docker.configured - & Docker.docked hosts "android-git-annex" + ! Docker.docked hosts "android-git-annex" , standardSystem "clam.kitenet.net" Unstable "amd64" [ "Unreliable server. Anything here may be lost at any time!" ] @@ -61,38 +63,70 @@ hosts = -- (o) ` [ "Main git-annex build box." ] & ipv4 "138.38.108.179" - & Hostname.sane & Apt.unattendedUpgrades & Postfix.satellite & Docker.configured & Docker.docked hosts "amd64-git-annex-builder" & Docker.docked hosts "i386-git-annex-builder" - & Docker.docked hosts "armel-git-annex-builder-companion" - & Docker.docked hosts "armel-git-annex-builder" & Docker.docked hosts "android-git-annex-builder" + -- not currently working + ! Docker.docked hosts "armel-git-annex-builder-companion" + ! Docker.docked hosts "armel-git-annex-builder" & Docker.garbageCollected `period` Daily & Apt.buildDep ["git-annex"] `period` Daily - , standardSystem "kite.kitenet.net" Unstable "amd64" + -- This is not a complete description of kite, since it's a + -- multiuser system with eg, user passwords that are not deployed + -- with propellor. + , standardSystemUnhardened "kite.kitenet.net" Unstable "amd64" [ "Welcome to the new kitenet.net server!" , "This is still under construction and not yet live.." ] & ipv4 "66.228.36.95" & ipv6 "2600:3c03::f03c:91ff:fe73:b0d2" + -- & alias "kitenet.net" -- not yet live! & Apt.installed ["linux-image-amd64"] & Linode.chainPVGrub 5 - & Hostname.sane & Apt.unattendedUpgrades & Apt.installed ["systemd"] & Ssh.hostKeys (Context "kitenet.net") - + -- Since ssh password authentication is allowed: + & Apt.serviceInstalledRunning "fail2ban" + & Obnam.backup "/" "33 1 * * *" + [ "--repository=sftp://joey@eubackup.kitenet.net/~/lib/backup/kite.obnam" + , "--client-name=kitenet.net" + , "--encrypt-with=" + , "--exclude=/var/cache" + , "--exclude=/var/tmp" + , "--exclude=/home/joey/lib" + , "--exclude=.*/tmp/" + , "--one-file-system" + ] Obnam.OnlyClient + `requires` Gpg.keyImported "98147487" "root" + `requires` Ssh.keyImported SshRsa "root" + (Context "kite.kitenet.net") + `requires` Ssh.knownHost hosts "eubackup.kitenet.net" "root" + + -- & alias "smtp.kitenet.net" -- not yet live! + -- & alias "imap.kitenet.net" -- not yet live! + -- & alias "mail.kitenet.net" -- not yet live! + & JoeySites.kiteMailServer + + & JoeySites.legacyWebSites + + & Apt.installed + ["git-annex", "myrepos" + , "build-essential", "make" + -- Some users have zsh as their login shell. + , "zsh" + ] + , standardSystem "diatom.kitenet.net" Stable "amd64" [ "Important stuff that needs not too much memory or CPU." ] & ipv4 "107.170.31.195" & DigitalOcean.distroKernel - & Hostname.sane & Ssh.hostKeys (Context "diatom.kitenet.net") & Apt.unattendedUpgrades & Apt.serviceInstalledRunning "ntp" @@ -103,10 +137,7 @@ hosts = -- (o) ` & Apt.serviceInstalledRunning "swapspace" & Apt.serviceInstalledRunning "apache2" - & 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" + & JoeySites.kitenetHttps & Apache.multiSSL & File.ownerGroup "/srv/web" "joey" "joey" & Apt.installed ["analog"] @@ -116,14 +147,16 @@ hosts = -- (o) ` & JoeySites.gitServer hosts & alias "downloads.kitenet.net" - & JoeySites.annexWebSite hosts "/srv/git/downloads.git" + & JoeySites.annexWebSite "/srv/git/downloads.git" "downloads.kitenet.net" "840760dc-08f0-11e2-8c61-576b7e66acfd" - [("turtle", "ssh://turtle.kitenet.net/~/lib/downloads/")] + [("usbackup", "ssh://usbackup.kitenet.net/~/lib/downloads/")] + `requires` Ssh.keyImported SshRsa "joey" (Context "downloads.kitenet.net") + `requires` Ssh.knownHost hosts "usbackup.kitenet.net" "joey" & JoeySites.gitAnnexDistributor & alias "tmp.kitenet.net" - & JoeySites.annexWebSite hosts "/srv/git/joey/tmp.git" + & JoeySites.annexWebSite "/srv/git/joey/tmp.git" "tmp.kitenet.net" "26fd6e38-1226-11e2-a75f-ff007033bdba" [] @@ -148,25 +181,28 @@ hosts = -- (o) ` , let ctx = Context "elephant.kitenet.net" in standardSystem "elephant.kitenet.net" Unstable "amd64" - [ "Storage, big data, and backups, omnomnom!" ] + [ "Storage, big data, and backups, omnomnom!" + , "(Encrypt all data stored here.)" + ] & ipv4 "193.234.225.114" & Grub.chainPVGrub "hd0,0" "xen/xvda1" 30 - & Hostname.sane & Postfix.satellite & Apt.unattendedUpgrades & Ssh.hostKeys ctx + & sshPubKey "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAJkoPRhUGT8EId6m37uBdYEtq42VNwslKnc9mmO+89ody066q6seHKeFY6ImfwjcyIjM30RTzEwftuVNQnbEB0=" & Ssh.keyImported SshRsa "joey" ctx & Apt.serviceInstalledRunning "swapspace" & alias "eubackup.kitenet.net" & Apt.installed ["obnam", "sshfs", "rsync"] + & JoeySites.obnamRepos ["wren", "pell", "kite"] & JoeySites.githubBackup - & JoeySites.obnamRepos ["wren", "pell"] - & Ssh.knownHost hosts "usw-s002.rsync.net" "joey" + & JoeySites.rsyncNetBackup hosts + & JoeySites.backupsBackedupTo hosts "usbackup.kitenet.net" "lib/backup/eubackup" & alias "podcatcher.kitenet.net" - & Apt.installed ["git-annex"] + & JoeySites.podcatcher & alias "znc.kitenet.net" & JoeySites.ircBouncer @@ -201,9 +237,9 @@ hosts = -- (o) ` `onChange` Service.restarted "ssh" -- temp - & Docker.docked hosts "amd64-git-annex-builder" - & Docker.docked hosts "i386-git-annex-builder" - & Docker.docked hosts "android-git-annex-builder" + ! Docker.docked hosts "amd64-git-annex-builder" + ! Docker.docked hosts "i386-git-annex-builder" + ! Docker.docked hosts "android-git-annex-builder" --' __|II| ,. @@ -261,8 +297,17 @@ type Motd = [String] -- This is my standard system setup. standardSystem :: HostName -> DebianSuite -> Architecture -> Motd -> Host -standardSystem hn suite arch motd = host hn +standardSystem hn suite arch motd = standardSystemUnhardened hn suite arch motd + -- Harden the system, but only once root's authorized_keys + -- is safely in place. + & check (Ssh.hasAuthorizedKeys "root") + (Ssh.passwordAuthentication False) + +standardSystemUnhardened :: HostName -> DebianSuite -> Architecture -> Motd -> Host +standardSystemUnhardened hn suite arch motd = host hn & os (System (Debian suite) arch) + & Hostname.sane + & Hostname.searchDomain & File.hasContent "/etc/motd" ("":motd++[""]) & Apt.stdSourcesList `onChange` Apt.upgrade & Apt.cacheCleaned @@ -270,10 +315,6 @@ standardSystem hn suite arch motd = host hn & Apt.installed ["ssh"] & GitHome.installedFor "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" (Context hn) & Sudo.enabledFor "joey" @@ -350,6 +391,7 @@ monsters = -- but do want to track their public keys etc. & ipv4 "67.223.19.96" & ipv6 "2001:4978:f:2d9::2" & alias "backup.kitenet.net" + & alias "usbackup.kitenet.net" & sshPubKey "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAokMXQiX/NZjA1UbhMdgAscnS5dsmy+Q7bWrQ6tsTZ/o+6N/T5cbjoBHOdpypXJI3y/PiJTDJaQtXIhLa8gFg/EvxMnMz/KG9skADW1361JmfCc4BxicQIO2IOOe6eilPr+YsnOwiHwL0vpUnuty39cppuMWVD25GzxXlS6KQsLCvXLzxLLuNnGC43UAM0q4UwQxDtAZEK1dH2o3HMWhgMP2qEQupc24dbhpO3ecxh2C9678a3oGDuDuNf7mLp3s7ptj5qF3onitpJ82U5o7VajaHoygMaSRFeWxP2c13eM57j3bLdLwxVXFhePcKXARu1iuFTLS5uUf3hN6MkQcOGw==" , host "wren.kitenet.net" & ipv4 "80.68.85.49" @@ -359,37 +401,46 @@ monsters = -- but do want to track their public keys etc. & 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 "anna.kitenet.net" & alias "bitlbee.kitenet.net" {- Remaining services on kite: + - + - / = ready to go on kite.kitenet.net - - mail - - postfix - - postgrey + - /postfix + - /postgrey - mailman - - spamassassin - - sqwebmail - - courier - - imap - - tls - - apache - - some static websites - - bitlbee - - prosody - - (used by daddy's git-annex) - - named - - (branchable is still pushing to here - - (thinking it's ns2.branchable.com), but it's no - - longer a primary or secondary for anything) + - /spamassassin + - sqwebmail (cannot use this with dovecot, alternatives?) + - /imap server + - /pop server + - /apache + - (need to re-rsync /srv/web to new kite.kitenet.net + - server before decommissioning) + - bitlbee (EOL?) + - prosody (EOL?) - ftpd (EOL) - - - user shell stuff: - - pine, zsh, make, git-annex, myrepos, ... + - Pre-transition: + - - re-rsync /home (skip ~joey and .pine*) + - + - Transition plan: + - - on darkstar: offlineimap run & disable cron job + - & move offlineimap files to tmp + - - take down wren pstfix, imap, pop servers + - - log all users out of wren + - - final /home rsync (skip ~joey and .pine*) + - - rsync /var/mail + - - rsync mailman and mailman list archives dirs + - - switch kitenet.net dns and enable pop.kitenet.net etc aliass + - - point wren.kitenet.net at kite.kitenet.net temporarily + - (make real-wren.kitenet.net alias) + - - reconfigure errol's email client to use new server + - - re-run offlinimap against new server + - - test mail + - - test virus filtering + - - test http://kitenet.net/~kyle/ (user home dirs) + - - migrate user cron jobs -} , host "mouse.kitenet.net" & ipv6 "2001:4830:1600:492::2" diff --git a/debian/changelog b/debian/changelog index 5492366..29dec10 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +propellor (0.8.2) unstable; urgency=medium + + * Fix bug in File.containsLines that caused lines that were already in the + file to sometimes be appended to the end. + * Hostname.sane also configures /etc/mailname. + * Fixed Postfix.satellite to really configure relayhost = smtp.domain. + * Avoid reconfiguring postfix unncessarily when it already has a relayhost. + * Deal with apache 2.4's change in the name of site-available config files. + * Hostname aliases can now be used in several places, including --spin + and Ssh.knownHost. + + -- Joey Hess Mon, 04 Aug 2014 01:12:19 -0400 + propellor (0.8.1) unstable; urgency=medium * Run apt-get update in initial bootstrap. diff --git a/privdata/privdata.gpg b/privdata/privdata.gpg index afafeee..f8c08d8 100644 --- a/privdata/privdata.gpg +++ b/privdata/privdata.gpg @@ -1,439 +1,749 @@ -----BEGIN PGP MESSAGE----- Version: GnuPG v1 -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 -7pa2HSH3ZFmSC8g5gt5ZA3TSQv8iY/7xD5cMsbk= -=6HOm +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 +o6jRkc4= +=fEUC -----END PGP MESSAGE----- diff --git a/propellor.cabal b/propellor.cabal index 50067b8..878113c 100644 --- a/propellor.cabal +++ b/propellor.cabal @@ -1,5 +1,5 @@ Name: propellor -Version: 0.8.1 +Version: 0.8.2 Cabal-Version: >= 1.6 License: BSD3 Maintainer: Joey Hess diff --git a/src/Propellor/Info.hs b/src/Propellor/Info.hs index 00f1b0e..1b89c00 100644 --- a/src/Propellor/Info.hs +++ b/src/Propellor/Info.hs @@ -43,11 +43,15 @@ ipv6 = addDNS . Address . IPv6 -- problems with CNAMEs, and also means that when multiple hosts have the -- same alias, a DNS round-robin is automatically set up. alias :: Domain -> Property -alias = addDNS . CNAME . AbsDomain +alias d = pureInfoProperty ("alias " ++ d) $ mempty + { _aliases = S.singleton d + -- A CNAME is added here, but the DNS setup code converts it to an + -- IP address when that makes sense. + , _dns = S.singleton $ CNAME $ AbsDomain d + } addDNS :: Record -> Property -addDNS r = pureInfoProperty (rdesc r) $ - mempty { _dns = S.singleton r } +addDNS r = pureInfoProperty (rdesc r) $ mempty { _dns = S.singleton r } where rdesc (CNAME d) = unwords ["alias", ddesc d] rdesc (Address (IPv4 addr)) = unwords ["ipv4", addr] @@ -71,8 +75,15 @@ getSshPubKey = askInfo _sshPubKey hostMap :: [Host] -> M.Map HostName Host hostMap l = M.fromList $ zip (map hostName l) l +aliasMap :: [Host] -> M.Map HostName Host +aliasMap = M.fromList . concat . + map (\h -> map (\aka -> (aka, h)) $ S.toList $ _aliases $ hostInfo h) + findHost :: [Host] -> HostName -> Maybe Host -findHost l hn = M.lookup hn (hostMap l) +findHost l hn = maybe (findAlias l hn) Just (M.lookup hn (hostMap l)) + +findAlias :: [Host] -> HostName -> Maybe Host +findAlias l hn = M.lookup hn (aliasMap l) getAddresses :: Info -> [IPAddr] getAddresses = mapMaybe getIPAddr . S.toList . _dns diff --git a/src/Propellor/Property/Apache.hs b/src/Propellor/Property/Apache.hs index cf3e62c..e693089 100644 --- a/src/Propellor/Property/Apache.hs +++ b/src/Propellor/Property/Apache.hs @@ -10,20 +10,21 @@ type ConfigFile = [String] siteEnabled :: HostName -> ConfigFile -> RevertableProperty siteEnabled hn cf = RevertableProperty enable disable where - enable = trivial $ cmdProperty "a2ensite" ["--quiet", hn] + enable = trivial (cmdProperty "a2ensite" ["--quiet", hn]) `describe` ("apache site enabled " ++ hn) `requires` siteAvailable hn cf `requires` installed `onChange` reloaded - disable = trivial $ File.notPresent (siteCfg hn) - `describe` ("apache site disabled " ++ hn) + disable = trivial $ combineProperties + ("apache site disabled " ++ hn) + (map File.notPresent (siteCfg hn)) `onChange` cmdProperty "a2dissite" ["--quiet", hn] `requires` installed `onChange` reloaded siteAvailable :: HostName -> ConfigFile -> Property -siteAvailable hn cf = siteCfg hn `File.hasContent` (comment:cf) - `describe` ("apache site available " ++ hn) +siteAvailable hn cf = combineProperties ("apache site available " ++ hn) $ + map (`File.hasContent` (comment:cf)) (siteCfg hn) where comment = "# deployed with propellor, do not modify" @@ -39,8 +40,15 @@ modEnabled modname = RevertableProperty enable disable `requires` installed `onChange` reloaded -siteCfg :: HostName -> FilePath -siteCfg hn = "/etc/apache2/sites-available/" ++ hn +-- This is a list of config files because different versions of apache +-- use different filenames. Propellor simply writen them all. +siteCfg :: HostName -> [FilePath] +siteCfg hn = + -- Debian pre-2.4 + [ "/etc/apache2/sites-available/" ++ hn + -- Debian 2.4+ + , "/etc/apache2/sites-available/" ++ hn ++ ".conf" + ] installed :: Property installed = Apt.installed ["apache2"] @@ -60,3 +68,19 @@ multiSSL = "/etc/apache2/conf.d/ssl" `File.hasContent` ] `describe` "apache SNI enabled" `onChange` reloaded + +-- | Config file fragment that can be inserted into a +-- stanza to allow global read access to the directory. +-- +-- Works with multiple versions of apache that have different ways to do +-- it. +allowAll :: String +allowAll = unlines + [ "" + , "Order allow,deny" + , "allow from all" + , "" + , "= 2.4>" + , "Require all granted" + , "" + ] diff --git a/src/Propellor/Property/Cron.hs b/src/Propellor/Property/Cron.hs index 5b070ef..d55c3db 100644 --- a/src/Propellor/Property/Cron.hs +++ b/src/Propellor/Property/Cron.hs @@ -4,6 +4,7 @@ import Propellor import qualified Propellor.Property.File as File import qualified Propellor.Property.Apt as Apt import Utility.SafeCommand +import Utility.FileMode import Data.Char @@ -19,22 +20,33 @@ type CronTimes = String -- -- The cron job's output will only be emailed if it exits nonzero. job :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property -job desc times user cddir command = cronjobfile `File.hasContent` - [ "# Generated by propellor" - , "" - , "SHELL=/bin/sh" - , "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" - , "" - , times ++ "\t" ++ user ++ "\t" - ++ "chronic flock -n " ++ shellEscape cronjobfile - ++ " sh -c " ++ shellEscape cmdline +job desc times user cddir command = combineProperties ("cronned " ++ desc) + [ cronjobfile `File.hasContent` + [ "# Generated by propellor" + , "" + , "SHELL=/bin/sh" + , "PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" + , "" + , times ++ "\t" ++ user ++ "\tchronic " ++ shellEscape scriptfile + ] + -- Use a separate script because it makes the cron job name + -- prettier in emails, and also allows running the job manually. + , scriptfile `File.hasContent` + [ "#!/bin/sh" + , "# Generated by propellor" + , "set -e" + , "flock -n " ++ shellEscape cronjobfile + ++ " sh -c " ++ shellEscape cmdline + ] + , scriptfile `File.mode` combineModes (readModes ++ executeModes) ] `requires` Apt.serviceInstalledRunning "cron" `requires` Apt.installed ["util-linux", "moreutils"] - `describe` ("cronned " ++ desc) where cmdline = "cd " ++ cddir ++ " && ( " ++ command ++ " )" - cronjobfile = "/etc/cron.d/" ++ map sanitize desc + cronjobfile = "/etc/cron.d/" ++ name + scriptfile = "/usr/local/bin/" ++ name ++ "_cronjob" + name = map sanitize desc sanitize c | isAlphaNum c = c | otherwise = '_' @@ -42,7 +54,7 @@ job desc times user cddir command = cronjobfile `File.hasContent` -- | Installs a cron job, and runs it niced and ioniced. niceJob :: Desc -> CronTimes -> UserName -> FilePath -> String -> Property niceJob desc times user cddir command = job desc times user cddir - ("nice ionice -c 3 " ++ command) + ("nice ionice -c 3 sh -c " ++ shellEscape command) -- | Installs a cron job to run propellor. runPropellor :: CronTimes -> Property diff --git a/src/Propellor/Property/File.hs b/src/Propellor/Property/File.hs index 0e738f2..bc499e0 100644 --- a/src/Propellor/Property/File.hs +++ b/src/Propellor/Property/File.hs @@ -18,28 +18,32 @@ 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 -> Context -> Property -hasPrivContent f context = withPrivData (PrivFile f) context $ \getcontent -> - property desc $ getcontent $ \privcontent -> - ensureProperty $ fileProperty' writeFileProtected desc - (\_oldcontent -> lines privcontent) f +hasPrivContent = hasPrivContent' writeFileProtected + +-- | Leaves the file at its default or current mode, +-- allowing "private" data to be read. +-- +-- Use with caution! +hasPrivContentExposed :: FilePath -> Context -> Property +hasPrivContentExposed = hasPrivContent' writeFile + +hasPrivContent' :: (String -> FilePath -> IO ()) -> FilePath -> Context -> Property +hasPrivContent' writer f context = + withPrivData (PrivFile f) context $ \getcontent -> + property desc $ getcontent $ \privcontent -> + ensureProperty $ fileProperty' writer desc + (\_oldcontent -> lines privcontent) f where desc = "privcontent " ++ f --- | Leaves the file world-readable. -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. containsLine :: FilePath -> Line -> Property f `containsLine` l = f `containsLines` [l] containsLines :: FilePath -> [Line] -> Property -f `containsLines` l = fileProperty (f ++ " contains:" ++ show l) go f +f `containsLines` ls = fileProperty (f ++ " contains:" ++ show ls) go f where - go ls - | all (`elem` ls) l = ls - | otherwise = ls++l + go content = content ++ filter (`notElem` content) ls -- | Ensures that a line is not present in a file. -- Note that the file is ensured to exist, so if it doesn't, an empty diff --git a/src/Propellor/Property/Hostname.hs b/src/Propellor/Property/Hostname.hs index 1cce4e6..c489e2f 100644 --- a/src/Propellor/Property/Hostname.hs +++ b/src/Propellor/Property/Hostname.hs @@ -3,10 +3,14 @@ module Propellor.Property.Hostname where import Propellor import qualified Propellor.Property.File as File +import Data.List + -- | Ensures that the hostname is set using best practices. -- -- Configures /etc/hostname and the current hostname. -- +-- Configures /etc/mailname with the domain part of the hostname. +-- -- /etc/hosts is also configured, with an entry for 127.0.1.1, which is -- standard at least on Debian to set the FDQN. -- @@ -29,6 +33,8 @@ setTo hn = combineProperties desc go else Just $ trivial $ hostsline "127.0.1.1" [hn, basehost] , Just $ trivial $ hostsline "127.0.0.1" ["localhost"] , Just $ trivial $ cmdProperty "hostname" [basehost] + , Just $ "/etc/mailname" `File.hasContent` + [if null domain then hn else domain] ] hostsline ip names = File.fileProperty desc @@ -37,3 +43,21 @@ setTo hn = combineProperties desc go addhostsline ip names ls = (ip ++ "\t" ++ (unwords names)) : filter (not . hasip ip) ls hasip ip l = headMaybe (words l) == Just ip + +-- | Makes /etc/resolv.conf contain search and domain lines for +-- the domain that the hostname is in. +searchDomain :: Property +searchDomain = property desc (ensureProperty . go =<< asks hostName) + where + desc = "resolv.conf search and domain configured" + go hn = + let (_basehost, domain) = separate (== '.') hn + in File.fileProperty desc (use domain) "/etc/resolv.conf" + use domain ls = filter wanted $ nub (ls ++ cfgs) + where + cfgs = ["domain " ++ domain, "search " ++ domain] + wanted l + | l `elem` cfgs = True + | "domain " `isPrefixOf` l = False + | "search " `isPrefixOf` l = False + | otherwise = True diff --git a/src/Propellor/Property/Obnam.hs b/src/Propellor/Property/Obnam.hs index 15a8494..b5c6d77 100644 --- a/src/Propellor/Property/Obnam.hs +++ b/src/Propellor/Property/Obnam.hs @@ -33,8 +33,8 @@ data NumClients = OnlyClient | MultipleClients -- > [ "--repository=sftp://2318@usw-s002.rsync.net/~/mygitrepos.obnam" -- > , "--encrypt-with=1B169BE1" -- > ] Obnam.OnlyClient --- > `requires` Gpg.keyImported "1B169BE1" "root" --- > `requires` Ssh.keyImported SshRsa "root" +-- > `requires` Gpg.keyImported "1B169BE1" "root" +-- > `requires` Ssh.keyImported SshRsa "root" (Context hostname) -- -- How awesome is that? backup :: FilePath -> Cron.CronTimes -> [ObnamParam] -> NumClients -> Property diff --git a/src/Propellor/Property/Postfix.hs b/src/Propellor/Property/Postfix.hs index ef96e08..b3d1272 100644 --- a/src/Propellor/Property/Postfix.hs +++ b/src/Propellor/Property/Postfix.hs @@ -2,24 +2,120 @@ module Propellor.Property.Postfix where import Propellor import qualified Propellor.Property.Apt as Apt +import Propellor.Property.File +import qualified Propellor.Property.Service as Service + +import qualified Data.Map as M +import Data.List +import Data.Char installed :: Property installed = Apt.serviceInstalledRunning "postfix" +restarted :: Property +restarted = Service.restarted "postfix" + +reloaded :: Property +reloaded = Service.reloaded "postfix" + -- | Configures postfix as a satellite system, which --- relats all mail through a relay host, which defaults to smtp.domain. +-- relays all mail through a relay host, which defaults to smtp.domain. -- -- The smarthost may refuse to relay mail on to other domains, without -- futher coniguration/keys. But this should be enough to get cron job -- mail flowing to a place where it will be seen. satellite :: Property -satellite = setup `requires` installed +satellite = check (not <$> mainCfIsSet "relayhost") setup + `requires` installed where setup = trivial $ property "postfix satellite system" $ do hn <- asks hostName - ensureProperty $ Apt.reConfigure "postfix" - [ ("postfix/main_mailer_type", "select", "Satellite system") - , ("postfix/root_address", "string", "root") - , ("postfix/destinations", "string", " ") - , ("postfix/mailname", "string", hn) + let (_, domain) = separate (== '.') hn + ensureProperties + [ Apt.reConfigure "postfix" + [ ("postfix/main_mailer_type", "select", "Satellite system") + , ("postfix/root_address", "string", "root") + , ("postfix/destinations", "string", " ") + , ("postfix/mailname", "string", hn) + ] + , mainCf ("relayhost", domain) + `onChange` reloaded ] + +-- | Sets up a file by running a property (which the filename is passed +-- to). If the setup property makes a change, postmap will be run on the +-- file, and postfix will be reloaded. +mappedFile :: FilePath -> (FilePath -> Property) -> Property +mappedFile f setup = setup f + `onChange` cmdProperty "postmap" [f] + +-- | Run newaliases command, which should be done after changing +-- /etc/aliases. +newaliases :: Property +newaliases = trivial $ cmdProperty "newaliases" [] + +-- | The main config file for postfix. +mainCfFile :: FilePath +mainCfFile = "/etc/postfix/main.cf" + +-- | Sets a main.cf name=value pair. Does not reload postfix immediately. +mainCf :: (String, String) -> Property +mainCf (name, value) = check notset set + `describe` ("postfix main.cf " ++ setting) + where + setting = name ++ "=" ++ value + notset = (/= Just value) <$> getMainCf name + set = cmdProperty "postconf" ["-e", setting] + +-- | Gets a man.cf setting. +getMainCf :: String -> IO (Maybe String) +getMainCf name = parse . lines <$> readProcess "postconf" [name] + where + parse (l:_) = Just $ + case separate (== '=') l of + (_, (' ':v)) -> v + (_, v) -> v + parse [] = Nothing + +-- | Checks if a main.cf field is set. A field that is set to "" +-- is considered not set. +mainCfIsSet :: String -> IO Bool +mainCfIsSet name = do + v <- getMainCf name + return $ v /= Nothing && v /= Just "" + +-- | Parses main.cf, and removes any initial configuration lines that are +-- overridden to other values later in the file. +-- +-- For example, to add some settings, removing any old settings: +-- +-- > mainCf `File.containsLines` +-- > [ "# I like bars." +-- > , "foo = bar" +-- > ] `onChange` dedupMainCf +-- +-- Note that multiline configurations that continue onto the next line +-- are not currently supported. +dedupMainCf :: Property +dedupMainCf = fileProperty "postfix main.cf dedupped" dedupCf mainCfFile + +dedupCf :: [String] -> [String] +dedupCf ls = + let parsed = map parse ls + in dedup [] (keycounts $ rights parsed) parsed + where + parse l + | "#" `isPrefixOf` l = Left l + | "=" `isInfixOf` l = + let (k, v) = separate (== '=') l + in Right ((filter (not . isSpace) k), v) + | otherwise = Left l + fmt k v = k ++ " =" ++ v + + keycounts = M.fromListWith (+) . map (\(k, _v) -> (k, (1 :: Integer))) + + dedup c _ [] = reverse c + dedup c kc ((Left v):rest) = dedup (v:c) kc rest + dedup c kc ((Right (k, v)):rest) = case M.lookup k kc of + Just n | n > 1 -> dedup c (M.insert k (n - 1) kc) rest + _ -> dedup (fmt k v:c) kc rest diff --git a/src/Propellor/Property/SiteSpecific/JoeySites.hs b/src/Propellor/Property/SiteSpecific/JoeySites.hs index c770907..fa8773d 100644 --- a/src/Propellor/Property/SiteSpecific/JoeySites.hs +++ b/src/Propellor/Property/SiteSpecific/JoeySites.hs @@ -14,12 +14,14 @@ import qualified Propellor.Property.Service as Service import qualified Propellor.Property.User as User import qualified Propellor.Property.Obnam as Obnam import qualified Propellor.Property.Apache as Apache +import qualified Propellor.Property.Postfix as Postfix import Utility.SafeCommand import Utility.FileMode import Utility.Path import Data.List import System.Posix.Files +import Data.String.Utils oldUseNetServer :: [Host] -> Property oldUseNetServer hosts = propertyList ("olduse.net server") @@ -59,9 +61,7 @@ oldUseNetServer hosts = propertyList ("olduse.net server") , " " , " Options Indexes FollowSymlinks" , " AllowOverride None" - -- I had this in the file before. - -- This may be needed by a newer version of apache? - --, " Require all granted" + , Apache.allowAll , " " ] ] @@ -114,11 +114,11 @@ 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/" ++ hn ++ ".obnam" + [ "--repository=sftp://joey@usbackup.kitenet.net/~/lib/backup/" ++ hn ++ ".obnam" , "--client-name=mumble" ] Obnam.OnlyClient `requires` Ssh.keyImported SshRsa "root" (Context hn) - `requires` Ssh.knownHost hosts "turtle.kitenet.net" "root" + `requires` Ssh.knownHost hosts "usbackup.kitenet.net" "root" , trivial $ cmdProperty "chown" ["-R", "mumble-server:mumble-server", "/var/lib/mumble-server"] ] where @@ -142,7 +142,7 @@ gitServer hosts = propertyList "git.kitenet.net setup" , Obnam.backup "/srv/git" "33 3 * * *" [ "--repository=sftp://2318@usw-s002.rsync.net/~/git.kitenet.net" , "--encrypt-with=1B169BE1" - , "--client-name=wren" + , "--client-name=wren" -- historical ] Obnam.OnlyClient `requires` Gpg.keyImported "1B169BE1" "root" `requires` Ssh.keyImported SshRsa "root" (Context "git.kitenet.net") @@ -191,8 +191,8 @@ gitServer hosts = propertyList "git.kitenet.net setup" type AnnexUUID = String -- | A website, with files coming from a git-annex repository. -annexWebSite :: [Host] -> Git.RepoUrl -> HostName -> AnnexUUID -> [(String, Git.RepoUrl)] -> Property -annexWebSite hosts origin hn uuid remotes = propertyList (hn ++" website using git-annex") +annexWebSite :: Git.RepoUrl -> HostName -> AnnexUUID -> [(String, Git.RepoUrl)] -> Property +annexWebSite origin hn uuid remotes = propertyList (hn ++" website using git-annex") [ Git.cloned "joey" origin dir Nothing `onChange` setup , postupdatehook `File.hasContent` @@ -206,8 +206,6 @@ 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" (Context hn) - `requires` Ssh.knownHost hosts "turtle.kitenet.net" "joey" setupscript = [ "cd " ++ shellEscape dir , "git config annex.uuid " ++ shellEscape uuid @@ -348,8 +346,27 @@ githubBackup = propertyList "github-backup box" , let f = "/home/joey/.github-keys" in File.hasPrivContent f anyContext `onChange` File.ownerGroup f "joey" "joey" + , Cron.niceJob "github-backup run" "30 4 * * *" "joey" + "/home/joey/lib/backup" $ intercalate "&&" + [ "mkdir -p github" + , "cd github" + , ". $HOME/.github-keys && github-backup joeyh" + ] ] +rsyncNetBackup :: [Host] -> Property +rsyncNetBackup hosts = Cron.niceJob "rsync.net copied in daily" "30 5 * * *" + "joey" "/home/joey/lib/backup" "mkdir -p rsync.net && rsync --delete -az 2318@usw-s002.rsync.net: rsync.net" + `requires` Ssh.knownHost hosts "usw-s002.rsync.net" "joey" + +backupsBackedupTo :: [Host] -> HostName -> FilePath -> Property +backupsBackedupTo hosts desthost destdir = Cron.niceJob desc + "1 1 * * 3" "joey" "/" cmd + `requires` Ssh.knownHost hosts desthost "joey" + where + desc = "backups copied to " ++ desthost ++ " weekly" + cmd = "rsync -az --delete /home/joey/lib/backup " ++ desthost ++ ":" ++ destdir + obnamRepos :: [String] -> Property obnamRepos rs = propertyList ("obnam repos for " ++ unwords rs) (mkbase : map mkrepo rs) @@ -360,3 +377,354 @@ obnamRepos rs = propertyList ("obnam repos for " ++ unwords rs) mkdir d = File.dirExists d `before` File.ownerGroup d "joey" "joey" +podcatcher :: Property +podcatcher = Cron.niceJob "podcatcher run hourly" "55 * * * *" + "joey" "/home/joey/lib/sound/podcasts" + "xargs git-annex importfeed -c annex.genmetadata=true < feeds; mr --quiet update" + `requires` Apt.installed ["git-annex", "myrepos"] + +kiteMailServer :: Property +kiteMailServer = propertyList "kitenet.net mail server" + [ Postfix.installed + , Apt.installed ["postfix-pcre"] + , Apt.serviceInstalledRunning "postgrey" + + , Apt.serviceInstalledRunning "spamassassin" + , "/etc/default/spamassassin" `File.containsLines` + [ "# Propellor deployed" + , "ENABLED=1" + , "CRON=1" + , "OPTIONS=\"--create-prefs --max-children 5 --helper-home-dir\"" + , "CRON=1" + , "NICE=\"--nicelevel 15\"" + ] `onChange` Service.restarted "spamassassin" + `describe` "spamd enabled" + `requires` Apt.serviceInstalledRunning "cron" + + , Apt.serviceInstalledRunning "spamass-milter" + -- Add -m to prevent modifying messages Subject or body. + , "/etc/default/spamass-milter" `File.containsLine` + "OPTIONS=\"-m -u spamass-milter -i 127.0.0.1\"" + `onChange` Service.restarted "spamass-milter" + `describe` "spamass-milter configured" + + , Apt.serviceInstalledRunning "amavisd-milter" + , "/etc/default/amavisd-milter" `File.containsLines` + [ "# Propellor deployed" + , "MILTERSOCKET=/var/spool/postfix/amavis/amavis.sock" + , "MILTERSOCKETOWNER=\"postfix:postfix\"" + , "MILTERSOCKETMODE=\"0660\"" + ] + `onChange` Service.restarted "amavisd-milter" + `describe` "amavisd-milter configured for postfix" + , Apt.serviceInstalledRunning "clamav-freshclam" + + , Apt.installed ["maildrop"] + , "/etc/maildroprc" `File.hasContent` + [ "# Global maildrop filter file (deployed with propellor)" + , "DEFAULT=\"$HOME/Maildir\"" + , "MAILBOX=\"$DEFAULT/.\"" + , "# Filter spam to a spam folder, unless .keepspam exists" + , "if (/^X-Spam-Status: Yes/)" + , "{" + , " `test -e \"$HOME/.keepspam\"`" + , " if ( $RETURNCODE != 0 )" + , " to ${MAILBOX}spam" + , "}" + ] + `describe` "maildrop configured" + + , "/etc/aliases" `File.hasPrivContentExposed` ctx + `onChange` Postfix.newaliases + , hasJoeyCAChain + , "/etc/ssl/certs/postfix.pem" `File.hasPrivContentExposed` ctx + , "/etc/ssl/private/postfix.pem" `File.hasPrivContent` ctx + + , "/etc/postfix/mydomain" `File.containsLines` + [ "/.*\\.kitenet\\.net/\tOK" + , "/ikiwiki\\.info/\tOK" + , "/joeyh\\.name/\tOK" + ] + `onChange` Postfix.reloaded + `describe` "postfix mydomain file configured" + , "/etc/postfix/obscure_client_relay.pcre" `File.containsLine` + "/^Received: from ([^.]+)\\.kitenet\\.net.*using TLS.*by kitenet\\.net \\(([^)]+)\\) with (E?SMTPS?A?) id ([A-F[:digit:]]+)(.*)/ IGNORE" + `onChange` Postfix.reloaded + `describe` "postfix obscure_client_relay file configured" + , Postfix.mappedFile "/etc/postfix/virtual" + (flip File.containsLines + [ "# *@joeyh.name to joey" + , "@joeyh.name\tjoey" + ] + ) `describe` "postfix virtual file configured" + `onChange` Postfix.reloaded + , Postfix.mappedFile "/etc/postfix/relay_clientcerts" $ + flip File.hasPrivContentExposed ctx + , Postfix.mainCfFile `File.containsLines` + [ "myhostname = kitenet.net" + , "mydomain = $myhostname" + , "append_dot_mydomain = no" + , "myorigin = kitenet.net" + , "mydestination = $myhostname, localhost.$mydomain, $mydomain, kite.$mydomain., localhost, regexp:$config_directory/mydomain" + , "mailbox_command = maildrop" + , "virtual_alias_maps = hash:/etc/postfix/virtual" + + , "# Allow clients with trusted certs to relay mail through." + , "relay_clientcerts = hash:/etc/postfix/relay_clientcerts" + , "smtpd_relay_restrictions = permit_mynetworks,permit_tls_clientcerts,permit_sasl_authenticated,reject_unauth_destination" + + , "# Filter out client relay lines from headers." + , "header_checks = pcre:$config_directory/obscure_client_relay.pcre" + + , "# Enable postgrey." + , "smtpd_recipient_restrictions = permit_mynetworks,reject_unauth_destination,check_policy_service inet:127.0.0.1:10023" + + , "# Enable spamass-milter and amavis-milter." + , "smtpd_milters = unix:/spamass/spamass.sock unix:amavis/amavis.sock" + , "milter_connect_macros = j {daemon_name} v {if_name} _" + + , "# TLS setup -- server" + , "smtpd_tls_CAfile = /etc/ssl/certs/joeyca.pem" + , "smtpd_tls_cert_file = /etc/ssl/certs/postfix.pem" + , "smtpd_tls_key_file = /etc/ssl/private/postfix.pem" + , "smtpd_tls_loglevel = 1" + , "smtpd_tls_received_header = yes" + , "smtpd_use_tls = yes" + , "smtpd_tls_ask_ccert = yes" + , "smtpd_tls_session_cache_database = sdbm:/etc/postfix/smtpd_scache" + + , "# TLS setup -- client" + , "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" + , "smtp_tls_loglevel = 1" + , "smtp_use_tls = yes" + , "smtp_tls_session_cache_database = sdbm:/etc/postfix/smtp_scache" + ] + `onChange` Postfix.dedupMainCf + `onChange` Postfix.reloaded + `describe` "postfix configured" + + , Apt.serviceInstalledRunning "dovecot-imapd" + , Apt.serviceInstalledRunning "dovecot-pop3d" + , "/etc/dovecot/conf.d/10-mail.conf" `File.containsLine` + "mail_location = maildir:~/Maildir" + `onChange` Service.reloaded "dovecot" + `describe` "dovecot mail.conf" + , "/etc/dovecot/conf.d/10-auth.conf" `File.containsLine` + "!include auth-passwdfile.conf.ext" + `onChange` Service.restarted "dovecot" + `describe` "dovecot auth.conf" + , File.hasPrivContent dovecotusers ctx + `onChange` (dovecotusers `File.mode` + combineModes [ownerReadMode, groupReadMode]) + , File.ownerGroup dovecotusers "root" "dovecot" + + , Apt.installed ["mutt", "bsd-mailx", "alpine"] + + , pinescript `File.hasContent` + [ "#!/bin/sh" + , "# deployed with propellor" + , "set -e" + , "pass=$HOME/.pine-password" + , "if [ ! -e $pass ]; then" + , "\ttouch $pass" + , "fi" + , "chmod 600 $pass" + , "exec alpine -passfile $pass \"$@\"" + ] + `onChange` (pinescript `File.mode` + combineModes (readModes ++ executeModes)) + `describe` "pine wrapper script" + , "/etc/pine.conf" `File.containsLines` + [ "inbox-path={localhost/novalidate-cert}inbox" + ] + `describe` "pine configured to use local imap server" + ] + where + ctx = Context "kitenet.net" + pinescript = "/usr/local/bin/pine" + dovecotusers = "/etc/dovecot/users" + +hasJoeyCAChain :: Property +hasJoeyCAChain = "/etc/ssl/certs/joeyca.pem" `File.hasPrivContentExposed` + Context "joeyca.pem" + +kitenetHttps :: Property +kitenetHttps = propertyList "kitenet.net https certs" + [ File.hasPrivContent "/etc/ssl/certs/web.pem" ctx + , File.hasPrivContent "/etc/ssl/private/web.pem" ctx + , File.hasPrivContent "/etc/ssl/certs/startssl.pem" ctx + , toProp $ Apache.modEnabled "ssl" + ] + where + ctx = Context "kitenet.net" + +-- Legacy static web sites and redirections from kitenet.net to newer +-- sites. +legacyWebSites :: Property +legacyWebSites = propertyList "legacy web sites" + [ Apt.serviceInstalledRunning "apache2" + , toProp $ Apache.modEnabled "rewrite" + , toProp $ Apache.modEnabled "cgi" + , toProp $ Apache.modEnabled "speling" + , userDirHtml + , kitenetHttps + , toProp $ Apache.siteEnabled "kitenet.net" $ apachecfg "kitenet.net" True + -- /var/www is empty + [ "DocumentRoot /var/www" + , "" + , " Options Indexes FollowSymLinks MultiViews ExecCGI Includes" + , " AllowOverride None" + , Apache.allowAll + , "" + , "ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/" + + -- for mailman cgi scripts + , "" + , " AllowOverride None" + , " Options ExecCGI" + , Apache.allowAll + , "" + , "Alias /pipermail/ /var/lib/mailman/archives/public/" + , "" + , " Options Indexes MultiViews FollowSymlinks" + , " AllowOverride None" + , Apache.allowAll + , "" + , "Alias /images/ /usr/share/images/" + , "" + , " Options Indexes MultiViews" + , " AllowOverride None" + , Apache.allowAll + , "" + + , "RewriteEngine On" + , "# Force hostname to kitenet.net" + , "RewriteCond %{HTTP_HOST} !^kitenet\\.net [NC]" + , "RewriteCond %{HTTP_HOST} !^$" + , "RewriteRule ^/(.*) http://kitenet\\.net/$1 [L,R]" + + , "# Moved pages" + , "RewriteRule /programs/debhelper http://joeyh.name/code/debhelper/ [L]" + , "RewriteRule /programs/satutils http://joeyh.name/code/satutils/ [L]" + , "RewriteRule /programs/filters http://joeyh.name/code/filters/ [L]" + , "RewriteRule /programs/ticker http://joeyh.name/code/ticker/ [L]" + , "RewriteRule /programs/pdmenu http://joeyh.name/code/pdmenu/ [L]" + , "RewriteRule /programs/sleepd http://joeyh.name/code/sleepd/ [L]" + , "RewriteRule /programs/Lingua::EN::Words2Nums http://joeyh.name/code/Words2Nums/ [L]" + , "RewriteRule /programs/wmbattery http://joeyh.name/code/wmbattery/ [L]" + , "RewriteRule /programs/dpkg-repack http://joeyh.name/code/dpkg-repack/ [L]" + , "RewriteRule /programs/debconf http://joeyh.name/code/debconf/ [L]" + , "RewriteRule /programs/perlmoo http://joeyh.name/code/perlmoo/ [L]" + , "RewriteRule /programs/alien http://joeyh.name/code/alien/ [L]" + , "RewriteRule /~joey/blog/entry/(.+)-[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9].html http://joeyh.name/blog/entry/$1/ [L]" + , "RewriteRule /~anna/.* http://waldeneffect\\.org/ [R]" + , "RewriteRule /~anna/.* http://waldeneffect\\.org/ [R]" + , "RewriteRule /~anna http://waldeneffect\\.org/ [R]" + , "RewriteRule /simpleid/ http://openid.kitenet.net:8081/simpleid/" + , "# Even the kite home page is not here any more!" + , "RewriteRule ^/$ http://www.kitenet.net/ [R]" + , "RewriteRule ^/index.html http://www.kitenet.net/ [R]" + , "RewriteRule ^/joey http://www.kitenet.net/joey/ [R]" + , "RewriteRule ^/joey/index.html http://www.kitenet.net/joey/ [R]" + , "RewriteRule ^/wifi http://www.kitenet.net/wifi/ [R]" + , "RewriteRule ^/wifi/index.html http://www.kitenet.net/wifi/ [R]" + + , "# Old ikiwiki filenames for kitenet.net wiki." + , "rewritecond $1 !^/~" + , "rewritecond $1 !^/doc/" + , "rewritecond $1 !^/pipermail/" + , "rewritecond $1 !^/cgi-bin/" + , "rewritecond $1 !.*/index$" + , "rewriterule (.+).html$ $1/ [r]" + + , "# Old ikiwiki filenames for joey's wiki." + , "rewritecond $1 ^/~joey/" + , "rewritecond $1 !.*/index$" + , "rewriterule (.+).html$ http://kitenet.net/$1/ [L,R]" + + , "# ~joey to joeyh.name" + , "rewriterule /~joey/(.*) http://joeyh.name/$1 [L]" + + , "# Old familywiki location." + , "rewriterule /~family/(.*).html http://family.kitenet.net/$1 [L]" + , "rewriterule /~family/(.*).rss http://family.kitenet.net/$1/index.rss [L]" + , "rewriterule /~family(.*) http://family.kitenet.net$1 [L]" + + , "rewriterule /~kyle/bywayofscience(.*) http://bywayofscience.branchable.com$1 [L]" + , "rewriterule /~kyle/family/wiki/(.*).html http://macleawiki.branchable.com/$1 [L]" + , "rewriterule /~kyle/family/wiki/(.*).rss http://macleawiki.branchable.com/$1/index.rss [L]" + , "rewriterule /~kyle/family/wiki(.*) http://macleawiki.branchable.com$1 [L]" + ] + , alias "anna.kitenet.net" + , toProp $ Apache.siteEnabled "anna.kitenet.net" $ apachecfg "anna.kitenet.net" False + [ "DocumentRoot /home/anna/html" + , "" + , " Options Indexes ExecCGI" + , " AllowOverride None" + , Apache.allowAll + , "" + ] + , alias "sows-ear.kitenet.net" + , alias "www.sows-ear.kitenet.net" + , toProp $ Apache.siteEnabled "sows-ear.kitenet.net" $ apachecfg "sows-ear.kitenet.net" False + [ "ServerAlias www.sows-ear.kitenet.net" + , "DocumentRoot /srv/web/sows-ear.kitenet.net" + , "" + , " Options FollowSymLinks" + , " AllowOverride None" + , Apache.allowAll + , "" + ] + , alias "wortroot.kitenet.net" + , alias "www.wortroot.kitenet.net" + , toProp $ Apache.siteEnabled "wortroot.kitenet.net" $ apachecfg "wortroot.kitenet.net" False + [ "ServerAlias www.wortroot.kitenet.net" + , "DocumentRoot /srv/web/wortroot.kitenet.net" + , "" + , " Options FollowSymLinks" + , " AllowOverride None" + , Apache.allowAll + , "" + ] + , alias "creeksidepress.com" + , toProp $ Apache.siteEnabled "creeksidepress.com" $ apachecfg "creeksidepress.com" False + [ "ServerAlias www.creeksidepress.com" + , "DocumentRoot /srv/web/www.creeksidepress.com" + , "" + , " Options FollowSymLinks" + , " AllowOverride None" + , Apache.allowAll + , "" + ] + , alias "joey.kitenet.net" + , toProp $ Apache.siteEnabled "joey.kitenet.net" $ apachecfg "joey.kitenet.net" False + [ "DocumentRoot /home/joey/html" + , "" + , " Options Indexes ExecCGI" + , " AllowOverride None" + , Apache.allowAll + , "" + + , "RewriteEngine On" + + , "# Old ikiwiki filenames for joey's wiki." + , "rewritecond $1 !.*/index$" + , "rewriterule (.+).html$ http://joeyh.name/$1/ [l]" + + , "rewritecond $1 !.*/index$" + , "rewriterule (.+).rss$ http://joeyh.name/$1/index.rss [l]" + + , "# Redirect all to joeyh.name." + , "rewriterule (.*) http://joeyh.name$1 [r]" + ] + ] + +userDirHtml :: Property +userDirHtml = File.fileProperty "apache userdir is html" (map munge) conf + `onChange` Apache.reloaded + `requires` (toProp $ Apache.modEnabled "userdir") + where + munge = replace "public_html" "html" + conf = "/etc/apache2/mods-available/userdir.conf" diff --git a/src/Propellor/Types/Info.hs b/src/Propellor/Types/Info.hs index 8856e06..de072aa 100644 --- a/src/Propellor/Types/Info.hs +++ b/src/Propellor/Types/Info.hs @@ -12,6 +12,7 @@ data Info = Info { _os :: Val System , _privDataFields :: S.Set (PrivDataField, Context) , _sshPubKey :: Val String + , _aliases :: S.Set HostName , _dns :: S.Set Dns.Record , _namedconf :: Dns.NamedConfMap , _dockerinfo :: DockerInfo @@ -19,11 +20,12 @@ data Info = Info deriving (Eq, Show) instance Monoid Info where - mempty = Info mempty mempty mempty mempty mempty mempty + mempty = Info mempty 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 + , _aliases = _aliases old <> _aliases new , _dns = _dns old <> _dns new , _namedconf = _namedconf old <> _namedconf new , _dockerinfo = _dockerinfo old <> _dockerinfo new