mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
fixes ssl renewal, replaces rsa with ecdsa for derivative certs
This commit is contained in:
@@ -65,6 +65,7 @@ import Lib.WebServer
|
|||||||
import Model
|
import Model
|
||||||
import Settings
|
import Settings
|
||||||
import Lib.Background
|
import Lib.Background
|
||||||
|
import qualified Daemon.SslRenew as SSLRenew
|
||||||
|
|
||||||
appMain :: IO ()
|
appMain :: IO ()
|
||||||
appMain = do
|
appMain = do
|
||||||
@@ -187,6 +188,10 @@ startupSequence foundation = do
|
|||||||
void . forkIO . forever $ forkIO (runReaderT AppNotifications.fetchAndSave foundation) >> threadDelay 5_000_000
|
void . forkIO . forever $ forkIO (runReaderT AppNotifications.fetchAndSave foundation) >> threadDelay 5_000_000
|
||||||
withAgentVersionLog_ "App notifications refreshing"
|
withAgentVersionLog_ "App notifications refreshing"
|
||||||
|
|
||||||
|
withAgentVersionLog_ "Initializing SSL certificate renewal loop"
|
||||||
|
void . forkIO . forever $ forkIO $ SSLRenew.renewSslLeafCert foundation
|
||||||
|
withAgentVersionLog_ "SSL Renewal daemon started"
|
||||||
|
|
||||||
-- reloading avahi daemon
|
-- reloading avahi daemon
|
||||||
-- DRAGONS! make sure this step happens AFTER system synchronization
|
-- DRAGONS! make sure this step happens AFTER system synchronization
|
||||||
withAgentVersionLog_ "Publishing Agent to Avahi Daemon"
|
withAgentVersionLog_ "Publishing Agent to Avahi Daemon"
|
||||||
|
|||||||
77
agent/src/Daemon/SslRenew.hs
Normal file
77
agent/src/Daemon/SslRenew.hs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
module Daemon.SslRenew where
|
||||||
|
|
||||||
|
import Startlude hiding ( err )
|
||||||
|
|
||||||
|
import Data.String.Interpolate ( i )
|
||||||
|
import System.Process ( system )
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Lib.SystemPaths
|
||||||
|
import Settings
|
||||||
|
import Lib.Ssl
|
||||||
|
import Daemon.ZeroConf ( getStart9AgentHostname )
|
||||||
|
import Lib.Tor
|
||||||
|
import Control.Carrier.Lift
|
||||||
|
import System.Directory ( renameDirectory
|
||||||
|
, removeDirectory
|
||||||
|
)
|
||||||
|
import Lib.SystemCtl
|
||||||
|
import qualified Lib.Notifications as Notifications
|
||||||
|
import Database.Persist.Sql ( runSqlPool )
|
||||||
|
import Lib.Types.Core
|
||||||
|
import Constants
|
||||||
|
|
||||||
|
renewSslLeafCert :: AgentCtx -> IO ()
|
||||||
|
renewSslLeafCert ctx = do
|
||||||
|
let base = appFilesystemBase . appSettings $ ctx
|
||||||
|
hn <- injectFilesystemBase base getStart9AgentHostname
|
||||||
|
tor <- injectFilesystemBase base getAgentHiddenServiceUrl
|
||||||
|
putStr @Text "SSL Renewal Required? "
|
||||||
|
needsRenew <- doesSslNeedRenew (toS $ entityCertPath hn `relativeTo` base)
|
||||||
|
print needsRenew
|
||||||
|
when needsRenew $ runM . injectFilesystemBase base $ do
|
||||||
|
intCaKeyPath <- toS <$> getAbsoluteLocationFor intermediateCaKeyPath
|
||||||
|
intCaConfPath <- toS <$> getAbsoluteLocationFor intermediateCaOpenSslConfPath
|
||||||
|
intCaCertPath <- toS <$> getAbsoluteLocationFor intermediateCaCertPath
|
||||||
|
|
||||||
|
sslDirTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> sslDirectory)
|
||||||
|
entKeyPathTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> entityKeyPath hn)
|
||||||
|
entConfPathTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> entityConfPath hn)
|
||||||
|
entCertPathTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> entityCertPath hn)
|
||||||
|
|
||||||
|
(ec, out, err) <- writeLeafCert
|
||||||
|
DeriveCertificate { applicantConfPath = entConfPathTmp
|
||||||
|
, applicantKeyPath = entKeyPathTmp
|
||||||
|
, applicantCertPath = entCertPathTmp
|
||||||
|
, signingConfPath = intCaConfPath
|
||||||
|
, signingKeyPath = intCaKeyPath
|
||||||
|
, signingCertPath = intCaCertPath
|
||||||
|
, duration = 365
|
||||||
|
}
|
||||||
|
hn
|
||||||
|
tor
|
||||||
|
liftIO $ do
|
||||||
|
putStrLn @Text "openssl logs"
|
||||||
|
putStrLn @Text "exit code: "
|
||||||
|
print ec
|
||||||
|
putStrLn @String $ "stdout: " <> out
|
||||||
|
putStrLn @String $ "stderr: " <> err
|
||||||
|
case ec of
|
||||||
|
ExitSuccess -> pure ()
|
||||||
|
ExitFailure n ->
|
||||||
|
liftIO
|
||||||
|
. void
|
||||||
|
$ flip runSqlPool (appConnPool ctx)
|
||||||
|
$ Notifications.emit (AppId "EmbassyOS") agentVersion
|
||||||
|
$ Notifications.CertRenewFailed (ExitFailure n) out err
|
||||||
|
let sslDir = toS $ sslDirectory `relativeTo` base
|
||||||
|
liftIO $ removeDirectory sslDir
|
||||||
|
liftIO $ renameDirectory sslDirTmp sslDir
|
||||||
|
liftIO $ systemCtl RestartService "nginx" $> ()
|
||||||
|
|
||||||
|
|
||||||
|
doesSslNeedRenew :: FilePath -> IO Bool
|
||||||
|
doesSslNeedRenew cert = do
|
||||||
|
ec <- liftIO $ system [i|openssl x509 -checkend 2592000 -noout -in #{cert}|]
|
||||||
|
pure $ ec /= ExitSuccess
|
||||||
@@ -5,6 +5,7 @@ module Handler.Register.Nginx where
|
|||||||
|
|
||||||
import Startlude hiding ( ask
|
import Startlude hiding ( ask
|
||||||
, catchError
|
, catchError
|
||||||
|
, err
|
||||||
)
|
)
|
||||||
|
|
||||||
import Control.Carrier.Error.Church
|
import Control.Carrier.Error.Church
|
||||||
@@ -23,6 +24,7 @@ import Lib.Tor
|
|||||||
import System.Posix ( removeLink )
|
import System.Posix ( removeLink )
|
||||||
import Data.String.Interpolate.IsString
|
import Data.String.Interpolate.IsString
|
||||||
( i )
|
( i )
|
||||||
|
import Lib.SystemCtl
|
||||||
|
|
||||||
time :: MonadIO m => Text -> StateT UTCTime m ()
|
time :: MonadIO m => Text -> StateT UTCTime m ()
|
||||||
time t = do
|
time t = do
|
||||||
@@ -67,13 +69,13 @@ resetSslState = do
|
|||||||
traverse_
|
traverse_
|
||||||
(liftIO . removePathForcibly . toS . flip relativeTo base)
|
(liftIO . removePathForcibly . toS . flip relativeTo base)
|
||||||
[ rootCaKeyPath
|
[ rootCaKeyPath
|
||||||
, relBase $ (rootCaCertPath `relativeTo` "/") <> ".csr"
|
, relBase $ (rootCaCertPath `relativeTo` base) <> ".csr"
|
||||||
, rootCaCertPath
|
, rootCaCertPath
|
||||||
, intermediateCaKeyPath
|
, intermediateCaKeyPath
|
||||||
, relBase $ (intermediateCaCertPath `relativeTo` "/") <> ".csr"
|
, relBase $ (intermediateCaCertPath `relativeTo` base) <> ".csr"
|
||||||
, intermediateCaCertPath
|
, intermediateCaCertPath
|
||||||
, entityKeyPath host
|
, entityKeyPath host
|
||||||
, relBase $ (entityCertPath host `relativeTo` "/") <> ".csr"
|
, relBase $ (entityCertPath host `relativeTo` base) <> ".csr"
|
||||||
, entityCertPath host
|
, entityCertPath host
|
||||||
, entityConfPath host
|
, entityConfPath host
|
||||||
, nginxSitesAvailable nginxSslConf
|
, nginxSitesAvailable nginxSslConf
|
||||||
@@ -90,7 +92,6 @@ resetSslState = do
|
|||||||
_ <- liftIO $ try @SomeException . removeLink . toS $ nginxSitesEnabled nginxSslConf `relativeTo` base
|
_ <- liftIO $ try @SomeException . removeLink . toS $ nginxSitesEnabled nginxSslConf `relativeTo` base
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
|
|
||||||
bootupHttpNginx :: (HasFilesystemBase sig m, MonadIO m) => m ()
|
bootupHttpNginx :: (HasFilesystemBase sig m, MonadIO m) => m ()
|
||||||
bootupHttpNginx = installAmbassadorUiNginxHTTP "start9-ambassador.conf"
|
bootupHttpNginx = installAmbassadorUiNginxHTTP "start9-ambassador.conf"
|
||||||
|
|
||||||
@@ -172,3 +173,73 @@ writeSslKeyAndCert rsaKeyFileContents = fromSys $ do
|
|||||||
ExitFailure ec -> throwError $ OpenSslE "leaf" ec str1' str2'
|
ExitFailure ec -> throwError $ OpenSslE "leaf" ec str1' str2'
|
||||||
|
|
||||||
readSystemPath' rootCaCertPath
|
readSystemPath' rootCaCertPath
|
||||||
|
|
||||||
|
replaceDerivativeCerts :: (HasFilesystemBase sig m, Has (Error S9Error) sig m, MonadIO m) => m ()
|
||||||
|
replaceDerivativeCerts = do
|
||||||
|
hn <- getStart9AgentHostname
|
||||||
|
tor <- getAgentHiddenServiceUrl
|
||||||
|
|
||||||
|
caKeyPath <- toS <$> getAbsoluteLocationFor rootCaKeyPath
|
||||||
|
caConfPath <- toS <$> getAbsoluteLocationFor rootCaOpenSslConfPath
|
||||||
|
caCertPath <- toS <$> getAbsoluteLocationFor rootCaCertPath
|
||||||
|
|
||||||
|
intCaKeyPath <- toS <$> getAbsoluteLocationFor intermediateCaKeyPath
|
||||||
|
intCaConfPath <- toS <$> getAbsoluteLocationFor intermediateCaOpenSslConfPath
|
||||||
|
intCaCertPath <- toS <$> getAbsoluteLocationFor intermediateCaCertPath
|
||||||
|
|
||||||
|
sslDirTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> sslDirectory)
|
||||||
|
entKeyPathTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> entityKeyPath hn)
|
||||||
|
entConfPathTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> entityConfPath hn)
|
||||||
|
entCertPathTmp <- toS <$> getAbsoluteLocationFor (agentTmpDirectory <> entityCertPath hn)
|
||||||
|
liftIO $ createDirectoryIfMissing True sslDirTmp
|
||||||
|
liftIO $ BS.writeFile entConfPathTmp (domain_CSR_CONF hn)
|
||||||
|
|
||||||
|
-- ensure duplicate certificates are acceptable
|
||||||
|
base <- Fused.ask @"filesystemBase"
|
||||||
|
liftIO $ BS.writeFile (toS $ (rootCaDirectory <> "index.txt.attr") `relativeTo` base) "unique_subject = no\n"
|
||||||
|
liftIO $ BS.writeFile (toS $ (intermediateCaDirectory <> "index.txt.attr") `relativeTo` base)
|
||||||
|
"unique_subject = no\n"
|
||||||
|
|
||||||
|
(ec, out, err) <- writeIntermediateCert DeriveCertificate { applicantConfPath = intCaConfPath
|
||||||
|
, applicantKeyPath = intCaKeyPath
|
||||||
|
, applicantCertPath = intCaCertPath
|
||||||
|
, signingConfPath = caConfPath
|
||||||
|
, signingKeyPath = caKeyPath
|
||||||
|
, signingCertPath = caCertPath
|
||||||
|
, duration = 3650
|
||||||
|
}
|
||||||
|
liftIO $ do
|
||||||
|
putStrLn @Text "openssl logs"
|
||||||
|
putStrLn @Text "exit code: "
|
||||||
|
print ec
|
||||||
|
putStrLn @String $ "stdout: " <> out
|
||||||
|
putStrLn @String $ "stderr: " <> err
|
||||||
|
case ec of
|
||||||
|
ExitSuccess -> pure ()
|
||||||
|
ExitFailure n -> throwError $ OpenSslE "leaf" n out err
|
||||||
|
|
||||||
|
(ec', out', err') <- writeLeafCert
|
||||||
|
DeriveCertificate { applicantConfPath = entConfPathTmp
|
||||||
|
, applicantKeyPath = entKeyPathTmp
|
||||||
|
, applicantCertPath = entCertPathTmp
|
||||||
|
, signingConfPath = intCaConfPath
|
||||||
|
, signingKeyPath = intCaKeyPath
|
||||||
|
, signingCertPath = intCaCertPath
|
||||||
|
, duration = 365
|
||||||
|
}
|
||||||
|
hn
|
||||||
|
tor
|
||||||
|
liftIO $ do
|
||||||
|
putStrLn @Text "openssl logs"
|
||||||
|
putStrLn @Text "exit code: "
|
||||||
|
print ec
|
||||||
|
putStrLn @String $ "stdout: " <> out'
|
||||||
|
putStrLn @String $ "stderr: " <> err'
|
||||||
|
case ec' of
|
||||||
|
ExitSuccess -> pure ()
|
||||||
|
ExitFailure n -> throwError $ OpenSslE "leaf" n out' err'
|
||||||
|
|
||||||
|
sslDir <- toS <$> getAbsoluteLocationFor sslDirectory
|
||||||
|
liftIO $ removeDirectory sslDir
|
||||||
|
liftIO $ renameDirectory sslDirTmp sslDir
|
||||||
|
liftIO $ systemCtl RestartService "nginx" $> ()
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ emit :: MonadIO m => AppId -> Version -> AgentNotification -> SqlPersistT m (Ent
|
|||||||
emit appId version ty = do
|
emit appId version ty = do
|
||||||
uuid <- liftIO nextRandom
|
uuid <- liftIO nextRandom
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
let k = (NotificationKey uuid)
|
let k = NotificationKey uuid
|
||||||
let v = (Notification now Nothing appId version (toCode ty) (toTitle ty) (toMessage appId version ty))
|
let v = Notification now Nothing appId version (toCode ty) (toTitle ty) (toMessage appId version ty)
|
||||||
insertKey k v
|
insertKey k v
|
||||||
putStrLn $ toMessage appId version ty
|
putStrLn $ toMessage appId version ty
|
||||||
pure $ Entity k v
|
pure $ Entity k v
|
||||||
@@ -42,6 +42,7 @@ data AgentNotification =
|
|||||||
| RestoreFailed S9Error
|
| RestoreFailed S9Error
|
||||||
| RestartFailed S9Error
|
| RestartFailed S9Error
|
||||||
| DockerFuckening
|
| DockerFuckening
|
||||||
|
| CertRenewFailed ExitCode String String
|
||||||
|
|
||||||
-- CODES
|
-- CODES
|
||||||
-- RULES:
|
-- RULES:
|
||||||
@@ -54,6 +55,7 @@ data AgentNotification =
|
|||||||
-- The second digit indicates where the error was originated from as follows
|
-- The second digit indicates where the error was originated from as follows
|
||||||
-- 0: Originates from Agent
|
-- 0: Originates from Agent
|
||||||
-- 1: Originates from App (Not presently used)
|
-- 1: Originates from App (Not presently used)
|
||||||
|
-- 2: Originates from Agent ABOUT THE AGENT
|
||||||
--
|
--
|
||||||
-- The remaining section of the code may be as long as you want but must be at least one digit
|
-- The remaining section of the code may be as long as you want but must be at least one digit
|
||||||
-- EXAMPLES:
|
-- EXAMPLES:
|
||||||
@@ -78,6 +80,7 @@ toCode (InstallFailedS9Error _) = "303"
|
|||||||
toCode (BackupFailed _) = "304"
|
toCode (BackupFailed _) = "304"
|
||||||
toCode (RestoreFailed _) = "305"
|
toCode (RestoreFailed _) = "305"
|
||||||
toCode (RestartFailed _) = "306"
|
toCode (RestartFailed _) = "306"
|
||||||
|
toCode CertRenewFailed{} = "320"
|
||||||
|
|
||||||
toTitle :: AgentNotification -> Text
|
toTitle :: AgentNotification -> Text
|
||||||
toTitle InstallSuccess = "Install succeeded"
|
toTitle InstallSuccess = "Install succeeded"
|
||||||
@@ -90,6 +93,7 @@ toTitle (BackupFailed _) = "Backup failed"
|
|||||||
toTitle (RestoreFailed _) = "Restore failed"
|
toTitle (RestoreFailed _) = "Restore failed"
|
||||||
toTitle (RestartFailed _) = "Restart failed"
|
toTitle (RestartFailed _) = "Restart failed"
|
||||||
toTitle DockerFuckening = "App unstoppable"
|
toTitle DockerFuckening = "App unstoppable"
|
||||||
|
toTitle CertRenewFailed{} = "Embassy Certificate Renewal Failed"
|
||||||
|
|
||||||
toMessage :: AppId -> Version -> AgentNotification -> Text
|
toMessage :: AppId -> Version -> AgentNotification -> Text
|
||||||
toMessage appId version InstallSuccess = [i|Successfully installed #{appId} at version #{version}|]
|
toMessage appId version InstallSuccess = [i|Successfully installed #{appId} at version #{version}|]
|
||||||
@@ -107,3 +111,10 @@ toMessage appId _version (BackupFailed reason) = [i|Failed to back up #{appId}:
|
|||||||
toMessage appId _version (RestoreFailed reason) = [i|Failed to restore #{appId}: #{errorMessage $ toError reason}|]
|
toMessage appId _version (RestoreFailed reason) = [i|Failed to restore #{appId}: #{errorMessage $ toError reason}|]
|
||||||
toMessage appId _version (RestartFailed reason) =
|
toMessage appId _version (RestartFailed reason) =
|
||||||
[i|Failed to restart #{appId}: #{errorMessage $ toError reason}. Please manually restart|]
|
[i|Failed to restart #{appId}: #{errorMessage $ toError reason}. Please manually restart|]
|
||||||
|
toMessage _ version (CertRenewFailed ec o e) = [i|Failed to renew SSL Certificates for EmbassyOS (#{version})
|
||||||
|
ExitCode: #{ec}
|
||||||
|
Stdout:
|
||||||
|
#{o}
|
||||||
|
Stderr:
|
||||||
|
#{e}
|
||||||
|
|]
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ module Lib.Ssl
|
|||||||
, writeLeafCert
|
, writeLeafCert
|
||||||
, root_CA_OPENSSL_CONF
|
, root_CA_OPENSSL_CONF
|
||||||
, intermediate_CA_OPENSSL_CONF
|
, intermediate_CA_OPENSSL_CONF
|
||||||
|
, segment
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ parseKernelVersion = do
|
|||||||
major' <- decimal
|
major' <- decimal
|
||||||
minor' <- char '.' *> decimal
|
minor' <- char '.' *> decimal
|
||||||
patch' <- char '.' *> decimal
|
patch' <- char '.' *> decimal
|
||||||
arch <- string "-v7l+" *> pure ArmV7 <|> string "-v8+" *> pure ArmV8
|
arch <- string "-v7l+" $> ArmV7 <|> string "-v8+" $> ArmV8
|
||||||
pure $ KernelVersion (Version (major', minor', patch', 0)) arch
|
pure $ KernelVersion (Version (major', minor', patch', 0)) arch
|
||||||
|
|
||||||
synchronizer :: Synchronizer
|
synchronizer :: Synchronizer
|
||||||
@@ -141,7 +141,7 @@ syncCreateSshDir = SyncOp "Create SSH directory" check migrate False
|
|||||||
syncRemoveAvahiSystemdDependency :: SyncOp
|
syncRemoveAvahiSystemdDependency :: SyncOp
|
||||||
syncRemoveAvahiSystemdDependency = SyncOp "Remove Avahi Systemd Dependency" check migrate False
|
syncRemoveAvahiSystemdDependency = SyncOp "Remove Avahi Systemd Dependency" check migrate False
|
||||||
where
|
where
|
||||||
wanted = decodeUtf8 $ $(embedFile "config/agent.service")
|
wanted = decodeUtf8 $(embedFile "config/agent.service")
|
||||||
check = do
|
check = do
|
||||||
base <- asks $ appFilesystemBase . appSettings
|
base <- asks $ appFilesystemBase . appSettings
|
||||||
content <- liftIO $ readFile (toS $ agentServicePath `relativeTo` base)
|
content <- liftIO $ readFile (toS $ agentServicePath `relativeTo` base)
|
||||||
@@ -172,7 +172,7 @@ sync32BitKernel = SyncOp "32 Bit Kernel Switch" check migrate True
|
|||||||
check = do
|
check = do
|
||||||
settings <- asks appSettings
|
settings <- asks appSettings
|
||||||
cfg <- injectFilesystemBaseFromContext settings getBootCfgPath
|
cfg <- injectFilesystemBaseFromContext settings getBootCfgPath
|
||||||
liftIO . run $ fmap isNothing $ (shell [i|grep "arm_64bit=0" #{cfg} || true|] $| conduit await)
|
liftIO . run $ isNothing <$> (shell [i|grep "arm_64bit=0" #{cfg} || true|] $| conduit await)
|
||||||
migrate = do
|
migrate = do
|
||||||
base <- asks $ appFilesystemBase . appSettings
|
base <- asks $ appFilesystemBase . appSettings
|
||||||
let tmpFile = bootConfigTempPath `relativeTo` base
|
let tmpFile = bootConfigTempPath `relativeTo` base
|
||||||
@@ -234,9 +234,9 @@ syncWriteConf name contents' confLocation = SyncOp [i|Write #{name} Conf|] check
|
|||||||
liftIO
|
liftIO
|
||||||
$ (Just <$> readFile (toS $ confLocation `relativeTo` base))
|
$ (Just <$> readFile (toS $ confLocation `relativeTo` base))
|
||||||
`catch` (\(e :: IOException) -> if isDoesNotExistError e then pure Nothing else throwIO e)
|
`catch` (\(e :: IOException) -> if isDoesNotExistError e then pure Nothing else throwIO e)
|
||||||
case conf of
|
pure $ case conf of
|
||||||
Nothing -> pure True
|
Nothing -> True
|
||||||
Just co -> pure $ if co == contents then False else True
|
Just co -> co /= contents
|
||||||
migrate = do
|
migrate = do
|
||||||
base <- asks $ appFilesystemBase . appSettings
|
base <- asks $ appFilesystemBase . appSettings
|
||||||
void . liftIO $ createDirectoryIfMissing True (takeDirectory (toS $ confLocation `relativeTo` base))
|
void . liftIO $ createDirectoryIfMissing True (takeDirectory (toS $ confLocation `relativeTo` base))
|
||||||
@@ -330,7 +330,7 @@ syncInstallAmbassadorUI = SyncOp "Install Ambassador UI" check migrate False
|
|||||||
streamUntar root stream = Conduit.runConduit $ Conduit.fromBStream stream .| Conduit.untar \f -> do
|
streamUntar root stream = Conduit.runConduit $ Conduit.fromBStream stream .| Conduit.untar \f -> do
|
||||||
let path = toS . (toS root </>) . joinPath . drop 1 . splitPath . B8.unpack . Conduit.filePath $ f
|
let path = toS . (toS root </>) . joinPath . drop 1 . splitPath . B8.unpack . Conduit.filePath $ f
|
||||||
print path
|
print path
|
||||||
if (Conduit.fileType f == Conduit.FTDirectory)
|
if Conduit.fileType f == Conduit.FTDirectory
|
||||||
then liftIO $ createDirectoryIfMissing True path
|
then liftIO $ createDirectoryIfMissing True path
|
||||||
else Conduit.sinkFile path
|
else Conduit.sinkFile path
|
||||||
|
|
||||||
@@ -372,8 +372,8 @@ installAmbassadorUiNginx mSslOverrides fileName = do
|
|||||||
void . liftIO $ systemCtl RestartService "nginx"
|
void . liftIO $ systemCtl RestartService "nginx"
|
||||||
where
|
where
|
||||||
ambassadorUiClientManifiest b = toS $ (ambassadorUiPath <> "/client-manifest.yaml") `relativeTo` b
|
ambassadorUiClientManifiest b = toS $ (ambassadorUiPath <> "/client-manifest.yaml") `relativeTo` b
|
||||||
nginxAvailableConf b = toS $ (nginxSitesAvailable fileName) `relativeTo` b
|
nginxAvailableConf b = toS $ nginxSitesAvailable fileName `relativeTo` b
|
||||||
nginxEnabledConf b = toS $ (nginxSitesEnabled fileName) `relativeTo` b
|
nginxEnabledConf b = toS $ nginxSitesEnabled fileName `relativeTo` b
|
||||||
|
|
||||||
syncOpenHttpPorts :: SyncOp
|
syncOpenHttpPorts :: SyncOp
|
||||||
syncOpenHttpPorts = SyncOp "Open Hidden Service Port 80" check migrate False
|
syncOpenHttpPorts = SyncOp "Open Hidden Service Port 80" check migrate False
|
||||||
@@ -426,6 +426,47 @@ syncPersistLogs :: SyncOp
|
|||||||
syncPersistLogs =
|
syncPersistLogs =
|
||||||
(syncWriteConf "Journald" $(embedFile "config/journald.conf") journaldConfig) { syncOpRequiresReboot = True }
|
(syncWriteConf "Journald" $(embedFile "config/journald.conf") journaldConfig) { syncOpRequiresReboot = True }
|
||||||
|
|
||||||
|
syncRepairSsl :: SyncOp
|
||||||
|
syncRepairSsl = SyncOp "Repair SSL Certs" check migrate False
|
||||||
|
where
|
||||||
|
check = do
|
||||||
|
base <- asks $ appFilesystemBase . appSettings
|
||||||
|
let p = toS $ sslDirectory `relativeTo` base
|
||||||
|
liftIO $ not <$> doesDirectoryExist p
|
||||||
|
migrate = do
|
||||||
|
base <- asks $ appFilesystemBase . appSettings
|
||||||
|
let newCerts = toS $ (agentTmpDirectory <> sslDirectory) `relativeTo` base
|
||||||
|
liftIO $ renameDirectory newCerts (toS $ sslDirectory `relativeTo` base)
|
||||||
|
liftIO $ systemCtl RestartService "nginx" $> ()
|
||||||
|
|
||||||
|
-- syncConvertEcdsaCerts :: SyncOp
|
||||||
|
-- syncConvertEcdsaCerts = SyncOp "Convert Intermediate Cert to ECDSA P256" check migrate False
|
||||||
|
-- where
|
||||||
|
-- check = do
|
||||||
|
-- fs <- asks $ appFilesystemBase . appSettings
|
||||||
|
-- header <- liftIO $ headMay . lines <$> readFile (toS $ intermediateCaKeyPath `relativeTo` fs)
|
||||||
|
-- pure $ case header of
|
||||||
|
-- Nothing -> False
|
||||||
|
-- Just y -> "BEGIN RSA PRIVATE KEY" `T.isInfixOf` y
|
||||||
|
-- migrate = replaceDerivativeCerts
|
||||||
|
|
||||||
|
-- syncConvertEcdsaLeafCert :: SyncOp
|
||||||
|
-- syncConvertEcdsaLeafCert = SyncOp "Convert Intermediate Cert to ECDSA P256" check migrate False
|
||||||
|
-- where
|
||||||
|
-- check = do
|
||||||
|
-- fs <- asks $ appFilesystemBase . appSettings
|
||||||
|
-- h <- injectFilesystemBase fs getStart9AgentHostname
|
||||||
|
-- header <- liftIO $ headMay . lines <$> readFile (toS $ entityKeyPath h `relativeTo` fs)
|
||||||
|
-- pure $ case header of
|
||||||
|
-- Nothing -> False
|
||||||
|
-- Just y -> "BEGIN RSA PRIVATE" `T.isInfixOf` y
|
||||||
|
-- migrate = do
|
||||||
|
-- base <- asks $ appFilesystemBase . appSettings
|
||||||
|
-- _
|
||||||
|
|
||||||
|
-- syncRotateExpiringCerts :: SyncOp
|
||||||
|
-- syncRotateExpiringCerts = _
|
||||||
|
|
||||||
failUpdate :: S9Error -> ExceptT Void (ReaderT AgentCtx IO) ()
|
failUpdate :: S9Error -> ExceptT Void (ReaderT AgentCtx IO) ()
|
||||||
failUpdate e = do
|
failUpdate e = do
|
||||||
ref <- asks appIsUpdateFailed
|
ref <- asks appIsUpdateFailed
|
||||||
|
|||||||
@@ -76,18 +76,15 @@ getAbsoluteLocationFor path = do
|
|||||||
readSystemPath :: (HasFilesystemBase sig m, MonadIO m) => SystemPath -> m (Maybe Text)
|
readSystemPath :: (HasFilesystemBase sig m, MonadIO m) => SystemPath -> m (Maybe Text)
|
||||||
readSystemPath path = do
|
readSystemPath path = do
|
||||||
loadPath <- getAbsoluteLocationFor path
|
loadPath <- getAbsoluteLocationFor path
|
||||||
contents <-
|
liftIO
|
||||||
liftIO
|
|
||||||
$ (Just <$> readFile (toS loadPath))
|
$ (Just <$> readFile (toS loadPath))
|
||||||
`catch` (\(e :: IOException) -> if isDoesNotExistError e then pure Nothing else throwIO e)
|
`catch` (\(e :: IOException) -> if isDoesNotExistError e then pure Nothing else throwIO e)
|
||||||
pure contents
|
|
||||||
|
|
||||||
-- like the above, but throws IO error if file not found
|
-- like the above, but throws IO error if file not found
|
||||||
readSystemPath' :: (HasFilesystemBase sig m, MonadIO m) => SystemPath -> m Text
|
readSystemPath' :: (HasFilesystemBase sig m, MonadIO m) => SystemPath -> m Text
|
||||||
readSystemPath' path = do
|
readSystemPath' path = do
|
||||||
loadPath <- getAbsoluteLocationFor path
|
loadPath <- getAbsoluteLocationFor path
|
||||||
contents <- liftIO . readFile . toS $ loadPath
|
liftIO . readFile . toS $ loadPath
|
||||||
pure contents
|
|
||||||
|
|
||||||
writeSystemPath :: (HasFilesystemBase sig m, MonadIO m) => SystemPath -> Text -> m ()
|
writeSystemPath :: (HasFilesystemBase sig m, MonadIO m) => SystemPath -> Text -> m ()
|
||||||
writeSystemPath path contents = do
|
writeSystemPath path contents = do
|
||||||
|
|||||||
Reference in New Issue
Block a user