packages feed

sproxy2 1.91.0 → 1.92.0

raw patch · 6 files changed

+102/−38 lines, 6 files

Files

ChangeLog.md view
@@ -1,5 +1,18 @@ For differences with the original Sproxy scroll down. +1.92.0+======++  * Allow running in plain HTTP mode (no SSL). Useful when Sproxy is behind some+    other proxy or load-balancer. Added two more options: `ssl` (defaults to true)+    and `https_port` (defaults to like `listen`). Options `ssl_key` and `ssl_cert`+    are required only if `ssl == true`. SSL-terminations is still required at upstream+    proxies, because the cookie is set for HTTPS only.++  * Added "user" table into `sproxy.sql`. No action is required, but PostgreSQL database+    built after this file will be incompatible with Sproxy Web ( <= 0.4.1 at least).++ 1.91.0 ====== 
sproxy.sql view
@@ -30,6 +30,11 @@   "comment" TEXT ); +CREATE TABLE IF NOT EXISTS "user" (+  "email" TEXT NOT NULL PRIMARY KEY,+  "comment" TEXT+);+ -- | group        | -- |--------------| -- | data science |@@ -40,18 +45,18 @@  CREATE TABLE IF NOT EXISTS group_member (   "group" TEXT REFERENCES "group" ("group") ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,-  email TEXT NOT NULL,+  "email" TEXT REFERENCES "user" ("email") ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,   "comment" TEXT,   PRIMARY KEY ("group", email) );  -- | group        | email                  | -- |--------------+------------------------|--- | data science | blah@example.com        |--- | data science | foo@example.com         |--- | devops       | devops1@example.com     |--- | devops       | devops2@example.com     |--- | all          | %@example.com           |+-- | data science | blah@example.com       |+-- | data science | foo@example.com        |+-- | devops       | devops1@example.com    |+-- | devops       | devops2@example.com    |+-- | all          | %@example.com          |  -- Find out which groups a user (email address) belongs to: -- SELECT "group" FROM group_member WHERE 'email.address' LIKE email
sproxy.yml.example view
@@ -10,13 +10,36 @@ # # listen: 443 -# Listen on port 80 and redirect HTTP requests to HTTPS.-# Optional. Default is true when listen == 443, otherwise false.+# Whether SSL is used on port defined by `listen`.+# You should only set it to false iff you intent to do SSL-termination+# somewhere else, e. g. at a load-balancer in a local network.+# If true, you also have to specify `ssl_key` and `ssl_cert`.+# Note that there is no way Sproxy can be usable without HTTPS/SSL at the user side,+# because Sproxy sets cookie for HTTPS only.+# Optional. Default is true.+# ssl: true++# Listen on port 80 and redirect HTTP requests to HTTPS (see `https_port`).+# Optional. Default is true when `listen` == 443, otherwise false. # # listen80: true -# Whether HTTP2 is enabled. Optional. Default is "true"+# Port used in redirection of HTTP requests to HTTPS.+# I. e., http://example.com -> https://example.com[:https_port],+# If `http_port` == 443, the port part if omitted.+# This is useful when behind a dump proxy or load-balancer, like Amazon ELB,+# (and`ssl` == false). It's unlikely that something other than 443+# is exposed to users, but if you are behind a proxy+# you can't really know the correct https port.+# Optional. Default is as `listen`. #+# Example:+# https_port: 4040+#+# https_port:++# Whether HTTP2 is enabled. Optional. Default is true.+# # http2: true  # The system user Sproxy switches to if launched as root (after opening the ports).@@ -30,14 +53,14 @@ # home: "."  -# File with SSL certificate. Required.+# File with SSL certificate. Required if `ssl` == true. # It can be a bundle with the server certificate coming first: # cat me-cert.pem CA-cert.pem > cert.pem # Once again: most wanted certs go first ;-) # Or you can opt in using of `ssl_cert_chain` ssl_cert: /path/cert.pem -# File with SSL key (secret!). Required.+# File with SSL key (secret!). Required if `ssl` = true. ssl_key: /path/key.pem  # Chain SSL certificate files.@@ -53,8 +76,8 @@ # PostgreSQL database connection string. # Optional. If specified, sproxy will periodically pull the data from this # database into internal SQLite3 database. Define password in a file-# referenced by the PGPASSFILE environment variable. Or use the "pgpassfile" option.-# Cannot be used with the "datafile" option.+# referenced by the PGPASSFILE environment variable. Or use the `pgpassfile` option.+# Cannot be used with the `datafile` option. # Example: # database: "user=sproxy-readonly dbname=sproxy port=6001" #@@ -72,7 +95,7 @@ # Optional. If specified, Sproxy will import it on start overwriting # and existing data in the internal database. # Useful for development or some simple deployments.-# Cannot be used with the "database" option.+# Cannot be used with the `database` option. # For example see the datafile.yml.example # # datafile: /path/data.yml
sproxy2.cabal view
@@ -1,5 +1,5 @@ name: sproxy2-version: 1.91.0+version: 1.92.0 synopsis: Secure HTTP proxy for authenticating users via OAuth2 description:   Sproxy is secure by default. No requests makes it to the backend
src/Sproxy/Config.hs view
@@ -17,14 +17,16 @@  data ConfigFile = ConfigFile {   cfListen       :: Word16+, cfSsl          :: Bool , cfUser         :: String , cfHome         :: FilePath , cfLogLevel     :: LogLevel-, cfSslCert      :: FilePath-, cfSslKey       :: FilePath+, cfSslCert      :: Maybe FilePath+, cfSslKey       :: Maybe FilePath , cfSslCertChain :: [FilePath] , cfKey          :: Maybe FilePath , cfListen80     :: Maybe Bool+, cfHttpsPort    :: Maybe Word16 , cfBackends     :: [BackendConf] , cfOAuth2       :: HashMap Text OAuth2Conf , cfDataFile     :: Maybe FilePath@@ -36,14 +38,16 @@ instance FromJSON ConfigFile where   parseJSON (Object m) = ConfigFile <$>         m .:? "listen"         .!= 443+    <*> m .:? "ssl"            .!= True     <*> m .:? "user"           .!= "sproxy"     <*> m .:? "home"           .!= "."     <*> m .:? "log_level"      .!= Debug-    <*> m .:  "ssl_cert"-    <*> m .:  "ssl_key"+    <*> m .:? "ssl_cert"+    <*> m .:? "ssl_key"     <*> m .:? "ssl_cert_chain" .!= []     <*> m .:? "key"     <*> m .:? "listen80"+    <*> m .:? "https_port"     <*> m .:  "backends"     <*> m .:  "oauth2"     <*> m .:? "datafile"
src/Sproxy/Server.hs view
@@ -14,11 +14,12 @@ import Data.Yaml (decodeFileEither) import Network.HTTP.Client (Manager, ManagerSettings(..), defaultManagerSettings, newManager, socketConnection) import Network.HTTP.Client.Internal (Connection)-import Network.Socket ( Family(AF_INET, AF_UNIX), SockAddr(SockAddrInet, SockAddrUnix),+import Network.Socket ( Socket, Family(AF_INET, AF_UNIX), SockAddr(SockAddrInet, SockAddrUnix),   SocketOption(ReuseAddr), SocketType(Stream), bind, close, connect, inet_addr,   listen, maxListenQueue, setSocketOption, socket )+import Network.Wai (Application) import Network.Wai.Handler.WarpTLS (tlsSettingsChain, runTLSSocket)-import Network.Wai.Handler.Warp ( defaultSettings, runSettingsSocket,+import Network.Wai.Handler.Warp ( Settings, defaultSettings, runSettingsSocket,   setHTTP2Disabled, setOnException ) import System.Entropy (getEntropy) import System.Environment (setEnv)@@ -37,6 +38,11 @@ import qualified Sproxy.Server.DB as DB  +{- TODO:+ - Log.error && exitFailure should be replaced+ - by Log.fatal && wait for logger thread to print && exitFailure+-}+ server :: FilePath -> IO () server configFile = do   cf <- readConfigFile configFile@@ -75,12 +81,11 @@            (\f -> Log.info ("reading key from " ++ f) >> BS.readFile f)            (cfKey cf) -  case maybe80 of-    Nothing     -> return ()-    Just sock80 -> do-      Log.info "listening on port 80 (HTTP redirect)"-      listen sock80 maxListenQueue-      void . forkIO $ runSettingsSocket defaultSettings sock80 (redirect $ cfListen cf)+  let+    settings =+      (if cfHTTP2 cf then id else setHTTP2Disabled) $+      setOnException (\_ _ -> return ())+      defaultSettings    oauth2clients <- HM.fromList <$> mapM newOAuth2Client (HM.toList (cfOAuth2 cf)) @@ -90,21 +95,22 @@       return (compile $ beName be, be, m)     ) $ cfBackends cf -  let-    settings =-      (if cfHTTP2 cf then id else setHTTP2Disabled) $-      setOnException (\_ _ -> return ())-      defaultSettings +  warpServer <- newServer cf++  case maybe80 of+    Nothing     -> return ()+    Just sock80 -> do+      let httpsPort = fromMaybe (cfListen cf) (cfHttpsPort cf)+      Log.info "listening on port 80 (HTTP redirect)"+      listen sock80 maxListenQueue+      void . forkIO $ runSettingsSocket settings sock80 (redirect httpsPort)+   -- XXX 2048 is from bindPortTCP from streaming-commons used internally by runTLS.   -- XXX Since we don't call runTLS, we listen socket here with the same options.-  Log.info $ "listening on port " ++ show (cfListen cf) ++ " (HTTPS)"+  Log.info $ "proxy listening on port " ++ show (cfListen cf)   listen sock (max 2048 maxListenQueue)-  runTLSSocket-    (tlsSettingsChain (cfSslCert cf) (cfSslCertChain cf) (cfSslKey cf))-    settings-    sock-    (sproxy key db oauth2clients backends)+  warpServer settings sock (sproxy key db oauth2clients backends)   newDataSource :: ConfigFile -> IO (Maybe DB.DataSource)@@ -165,6 +171,19 @@     managerRawConnection = return $ \_ _ _ -> openConn   , managerConnCount = beConnCount be   }+++newServer :: ConfigFile -> IO (Settings -> Socket -> Application -> IO ())+newServer cf+  | cfSsl cf =+    case (cfSslKey cf, cfSslCert cf) of+      (Just k, Just c) ->+        return $ runTLSSocket (tlsSettingsChain c (cfSslCertChain cf) k)+      _ -> do Log.error "missings SSL certificate"+              exitFailure+  | otherwise = do+      Log.warn "not using SSL!"+      return runSettingsSocket   openUnixSocketConnection :: FilePath -> IO Connection