add config option server-unix-socket-mode (#1415)
* added config option server-unix-socket-mode to enable custom socket permissions * added server-unix-socket-mode input validation
This commit is contained in:
committed by
Steve Chavez
parent
f9c64d9f65
commit
2e6c78d723
@@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- #1415, Add support for user defined socket permission via `server-unix-socket-mode` config option - @Dansvidania
|
||||||
- #1383, Add support for HEAD request - @steve-chavez
|
- #1383, Add support for HEAD request - @steve-chavez
|
||||||
- #1378, Add support for `Prefer: count=planned` and `Prefer: count=estimated` on GET /table - @steve-chavez
|
- #1378, Add support for `Prefer: count=planned` and `Prefer: count=estimated` on GET /table - @steve-chavez
|
||||||
|
|
||||||
|
|||||||
+13
-6
@@ -12,6 +12,7 @@ import Control.AutoUpdate (defaultUpdateSettings, mkAutoUpdate,
|
|||||||
import Control.Retry (RetryStatus, capDelay,
|
import Control.Retry (RetryStatus, capDelay,
|
||||||
exponentialBackoff, retrying,
|
exponentialBackoff, retrying,
|
||||||
rsPreviousDelay)
|
rsPreviousDelay)
|
||||||
|
import Data.Either.Combinators (whenLeft)
|
||||||
import Data.IORef (IORef, atomicWriteIORef, newIORef,
|
import Data.IORef (IORef, atomicWriteIORef, newIORef,
|
||||||
readIORef)
|
readIORef)
|
||||||
import Data.String (IsString (..))
|
import Data.String (IsString (..))
|
||||||
@@ -31,6 +32,8 @@ import Network.Wai.Handler.Warp (defaultSettings, runSettings,
|
|||||||
import System.Directory (removeFile)
|
import System.Directory (removeFile)
|
||||||
import System.IO (BufferMode (..), hSetBuffering)
|
import System.IO (BufferMode (..), hSetBuffering)
|
||||||
import System.IO.Error (isDoesNotExistError)
|
import System.IO.Error (isDoesNotExistError)
|
||||||
|
import System.Posix.Files (setFileMode)
|
||||||
|
import System.Posix.Types (FileMode)
|
||||||
|
|
||||||
import PostgREST.App (postgrest)
|
import PostgREST.App (postgrest)
|
||||||
import PostgREST.Config (AppConfig (..), configPoolTimeout',
|
import PostgREST.Config (AppConfig (..), configPoolTimeout',
|
||||||
@@ -163,6 +166,7 @@ main = do
|
|||||||
port = configPort conf
|
port = configPort conf
|
||||||
proxy = configProxyUri conf
|
proxy = configProxyUri conf
|
||||||
maybeSocketAddr = configSocket conf
|
maybeSocketAddr = configSocket conf
|
||||||
|
socketFileMode = configSocketMode conf
|
||||||
pgSettings = toS (configDatabase conf) -- is the db-uri
|
pgSettings = toS (configDatabase conf) -- is the db-uri
|
||||||
roleClaimKey = configRoleClaimKey conf
|
roleClaimKey = configRoleClaimKey conf
|
||||||
appSettings =
|
appSettings =
|
||||||
@@ -171,13 +175,15 @@ main = do
|
|||||||
. setServerName (toS $ "postgrest/" <> prettyVersion) $
|
. setServerName (toS $ "postgrest/" <> prettyVersion) $
|
||||||
defaultSettings
|
defaultSettings
|
||||||
|
|
||||||
|
whenLeft socketFileMode panic
|
||||||
|
|
||||||
-- Checks that the provided proxy uri is formated correctly
|
-- Checks that the provided proxy uri is formated correctly
|
||||||
when (isMalformedProxyUri $ toS <$> proxy) $
|
when (isMalformedProxyUri $ toS <$> proxy) $
|
||||||
panic
|
panic
|
||||||
"Malformed proxy uri, a correct example: https://example.com:8443/basePath"
|
"Malformed proxy uri, a correct example: https://example.com:8443/basePath"
|
||||||
|
|
||||||
-- Checks that the provided jspath is valid
|
-- Checks that the provided jspath is valid
|
||||||
when (isLeft roleClaimKey) $
|
whenLeft roleClaimKey $
|
||||||
panic $ show roleClaimKey
|
panic $ show roleClaimKey
|
||||||
|
|
||||||
--
|
--
|
||||||
@@ -250,7 +256,7 @@ main = do
|
|||||||
runSettings appSettings postgrestApplication
|
runSettings appSettings postgrestApplication
|
||||||
Just socketAddr -> do
|
Just socketAddr -> do
|
||||||
-- run postgrest application with user defined socket
|
-- run postgrest application with user defined socket
|
||||||
sock <- createAndBindSocket (unpack socketAddr)
|
sock <- createAndBindSocket (unpack socketAddr) (rightToMaybe socketFileMode)
|
||||||
listen sock maxListenQueue
|
listen sock maxListenQueue
|
||||||
putStrLn $ ("Listening on unix socket " :: Text) <> show socketAddr
|
putStrLn $ ("Listening on unix socket " :: Text) <> show socketAddr
|
||||||
runSettingsSocket appSettings sock postgrestApplication
|
runSettingsSocket appSettings sock postgrestApplication
|
||||||
@@ -324,11 +330,12 @@ loadDbUriFile conf = extractDbUri mDbUri
|
|||||||
Just filename -> strip <$> readFile (toS filename)
|
Just filename -> strip <$> readFile (toS filename)
|
||||||
setDbUri dbUri = conf {configDatabase = dbUri}
|
setDbUri dbUri = conf {configDatabase = dbUri}
|
||||||
|
|
||||||
createAndBindSocket :: FilePath -> IO Socket
|
createAndBindSocket :: FilePath -> Maybe FileMode -> IO Socket
|
||||||
createAndBindSocket filePath = do
|
createAndBindSocket socketFilePath maybeSocketFileMode = do
|
||||||
deleteSocketFileIfExist filePath
|
deleteSocketFileIfExist socketFilePath
|
||||||
sock <- socket AF_UNIX Stream defaultProtocol
|
sock <- socket AF_UNIX Stream defaultProtocol
|
||||||
bind sock $ SockAddrUnix filePath
|
bind sock $ SockAddrUnix socketFilePath
|
||||||
|
mapM_ (setFileMode socketFilePath) maybeSocketFileMode
|
||||||
return sock
|
return sock
|
||||||
where
|
where
|
||||||
deleteSocketFileIfExist path = removeFile path `catch` handleDoesNotExist
|
deleteSocketFileIfExist path = removeFile path `catch` handleDoesNotExist
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ executable postgrest
|
|||||||
, base64-bytestring >= 1 && < 1.1
|
, base64-bytestring >= 1 && < 1.1
|
||||||
, bytestring >= 0.10.8 && < 0.11
|
, bytestring >= 0.10.8 && < 0.11
|
||||||
, directory >= 1.2.6 && < 1.4
|
, directory >= 1.2.6 && < 1.4
|
||||||
|
, either >= 4.4.1 && < 5.1
|
||||||
, hasql >= 1.4 && < 1.5
|
, hasql >= 1.4 && < 1.5
|
||||||
, hasql-pool >= 0.5 && < 0.6
|
, hasql-pool >= 0.5 && < 0.6
|
||||||
, hasql-transaction >= 0.7.2 && < 0.8
|
, hasql-transaction >= 0.7.2 && < 0.8
|
||||||
|
|||||||
@@ -46,8 +46,10 @@ import Data.Text.IO (hPutStrLn)
|
|||||||
import Data.Version (versionBranch)
|
import Data.Version (versionBranch)
|
||||||
import Development.GitRev (gitHash)
|
import Development.GitRev (gitHash)
|
||||||
import Network.Wai.Middleware.Cors (CorsResourcePolicy (..))
|
import Network.Wai.Middleware.Cors (CorsResourcePolicy (..))
|
||||||
|
import Numeric (readOct)
|
||||||
import Paths_postgrest (version)
|
import Paths_postgrest (version)
|
||||||
import System.IO.Error (IOError)
|
import System.IO.Error (IOError)
|
||||||
|
import System.Posix.Types (FileMode)
|
||||||
|
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Data.Monoid
|
import Data.Monoid
|
||||||
@@ -63,6 +65,7 @@ import Protolude hiding (concat, hPutStrLn, intercalate, null,
|
|||||||
take, (<>))
|
take, (<>))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- | Config file settings for the server
|
-- | Config file settings for the server
|
||||||
data AppConfig = AppConfig {
|
data AppConfig = AppConfig {
|
||||||
configDatabase :: Text
|
configDatabase :: Text
|
||||||
@@ -72,6 +75,7 @@ data AppConfig = AppConfig {
|
|||||||
, configHost :: Text
|
, configHost :: Text
|
||||||
, configPort :: Int
|
, configPort :: Int
|
||||||
, configSocket :: Maybe Text
|
, configSocket :: Maybe Text
|
||||||
|
, configSocketMode :: Either Text FileMode
|
||||||
|
|
||||||
, configJwtSecret :: Maybe B.ByteString
|
, configJwtSecret :: Maybe B.ByteString
|
||||||
, configJwtSecretIsBase64 :: Bool
|
, configJwtSecretIsBase64 :: Bool
|
||||||
@@ -155,6 +159,7 @@ readOptions = do
|
|||||||
<*> (fromMaybe "!4" <$> optString "server-host")
|
<*> (fromMaybe "!4" <$> optString "server-host")
|
||||||
<*> (fromMaybe 3000 <$> optInt "server-port")
|
<*> (fromMaybe 3000 <$> optInt "server-port")
|
||||||
<*> optString "server-unix-socket"
|
<*> optString "server-unix-socket"
|
||||||
|
<*> parseSocketFileMode "server-unix-socket-mode"
|
||||||
<*> (fmap encodeUtf8 <$> optString "jwt-secret")
|
<*> (fmap encodeUtf8 <$> optString "jwt-secret")
|
||||||
<*> (fromMaybe False <$> optBool "secret-is-base64")
|
<*> (fromMaybe False <$> optBool "secret-is-base64")
|
||||||
<*> parseJwtAudience "jwt-aud"
|
<*> parseJwtAudience "jwt-aud"
|
||||||
@@ -169,6 +174,19 @@ readOptions = do
|
|||||||
<*> optString "root-spec"
|
<*> optString "root-spec"
|
||||||
<*> (maybe [] (fmap encodeUtf8 . splitOnCommas) <$> optValue "raw-media-types")
|
<*> (maybe [] (fmap encodeUtf8 . splitOnCommas) <$> optValue "raw-media-types")
|
||||||
|
|
||||||
|
parseSocketFileMode :: C.Key -> C.Parser C.Config (Either Text FileMode)
|
||||||
|
parseSocketFileMode k =
|
||||||
|
C.optional k C.string >>= \case
|
||||||
|
Nothing -> pure $ Right 493 -- return default 755 mode if no value was provided
|
||||||
|
Just fileModeText ->
|
||||||
|
case (readOct . unpack) fileModeText of
|
||||||
|
[] ->
|
||||||
|
pure $ Left "Invalid server-unix-socket-mode: not an octal"
|
||||||
|
(fileMode, _):_ ->
|
||||||
|
if fileMode < 384 || fileMode > 511
|
||||||
|
then pure $ Left "Invalid server-unix-socket-mode: needs to be between 600 and 777"
|
||||||
|
else pure $ Right fileMode
|
||||||
|
|
||||||
parseJwtAudience :: C.Key -> C.Parser C.Config (Maybe StringOrURI)
|
parseJwtAudience :: C.Key -> C.Parser C.Config (Maybe StringOrURI)
|
||||||
parseJwtAudience k =
|
parseJwtAudience k =
|
||||||
C.optional k C.string >>= \case
|
C.optional k C.string >>= \case
|
||||||
@@ -248,6 +266,9 @@ readOptions = do
|
|||||||
|## unix socket location
|
|## unix socket location
|
||||||
|## if specified it takes precedence over server-port
|
|## if specified it takes precedence over server-port
|
||||||
|# server-unix-socket = "/tmp/pgrst.sock"
|
|# server-unix-socket = "/tmp/pgrst.sock"
|
||||||
|
|## unix socket file mode
|
||||||
|
|## when none is provided, 755 is applied by default
|
||||||
|
|# server-unix-socket-mode = "755"
|
||||||
|
|
|
|
||||||
|## base url for swagger output
|
|## base url for swagger output
|
||||||
|# server-proxy-uri = ""
|
|# server-proxy-uri = ""
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ _baseCfg = -- Connection Settings
|
|||||||
AppConfig mempty "postgrest_test_anonymous" Nothing "test" "localhost" 3000
|
AppConfig mempty "postgrest_test_anonymous" Nothing "test" "localhost" 3000
|
||||||
-- No user configured Unix Socket
|
-- No user configured Unix Socket
|
||||||
Nothing
|
Nothing
|
||||||
|
-- No user configured Unix Socket file mode (defaults to 755)
|
||||||
|
(Right 493)
|
||||||
-- Jwt settings
|
-- Jwt settings
|
||||||
(Just $ encodeUtf8 "reallyreallyreallyreallyverysafe") False Nothing
|
(Just $ encodeUtf8 "reallyreallyreallyreallyverysafe") False Nothing
|
||||||
-- Connection Modifiers
|
-- Connection Modifiers
|
||||||
|
|||||||
Reference in New Issue
Block a user