packages feed

moesocks 0.1.1.20 → 0.1.1.30

raw patch · 14 files changed

+169/−139 lines, 14 filesdep +lens-aeson

Dependencies added: lens-aeson

Files

CHANGELOG.md view
@@ -1,14 +1,15 @@+0.1.1.30+--------+* Add more encryption methods from OpenSSL+* Add a `--list-methods` flag to show all supported encryption methods+ 0.1.1.20 ---------* Implement TFO in remote. If your browser and the website your are visiting-  both support TFO, you can enjoy TFO all the way through. This could lead to a-  huge reduction of latency.+* Implement TFO in remote.   0.1.1.10 ---------* Add TCP Fast Open (TFO) capability. It can be turned on by adding a -  `"fast_open":true` field in `config.json` or specifying a `--fast-open` flag-  in the command line arguments.+* Add TCP Fast Open (TFO) capability.   0.1.1.0 -------
README.md view
@@ -35,15 +35,15 @@ * Edit `config.json` to fit your setup (at least the `remote` and `password`   fields) -* Start a remote node outside the firewall: +* Start a remote node outside a firewall:                     moesocks --role remote -c config.json -* Start a local node inside the firewall: +* Start a local node inside a firewall:               moesocks --role local -c config.json -* Now you have a socks5 proxy running inside the firewall using port +* Now you have a socks5 proxy running inside a firewall using port    `localPort`.  * Shadowsocks compatible obfuscation can be turned on with the `-o` flag to make@@ -82,13 +82,13 @@  ## [TFO] means faster response in this case -Both local and remote will use TFO when instructed. If your browser and the-website your are visiting both support TFO, you can enjoy TFO all the way-through. This could lead to a huge reduction of latency.+Both local and remote will use TFO when instructed. If the browser in use and+the website to visit both support TFO, you can enjoy TFO all the way through.+This could lead to a huge reduction of latency.  ## Enable TFO in your OS runtime.  -On Linux 3.7+, you could check the availability of TFO using:+On Linux 3.7+, to check the availability of TFO:      cat /proc/sys/net/ipv4/tcp_fastopen @@ -98,13 +98,13 @@  ## Enable TFO in MoeSocks -TFO can be turned on by adding a `"fast_open":true` field in-`config.json` or specifying a `--fast-open` flag in the command line arguments.+TFO can be turned on by adding a `"fastOpen":true` field in `config.json` or+specifying a `--fast-open` flag in the command line arguments.  ## Verify -Use `tcpdump` on the `remotePort`, you should see that the first packet `SYN`-will carry the initial data with it. An example command is:+Use `tcpdump` on the `remotePort`, check for that `SYN` should start to carry+payload. An example command is:      tcpdump port 8388 -i any -X -v 
config.json view
@@ -4,7 +4,7 @@   "local":"localhost",   "localPort":1090,   "password":"birthday!",-  "fast_open":true,+  "fastOpen":true,   "method":"aes-256-cfb" } 
moesocks.cabal view
@@ -1,6 +1,6 @@ name:               moesocks category:           Network-version:            0.1.1.20+version:            0.1.1.30 license:            Apache-2.0 synopsis:           A functional firewall killer description:        A socks5 proxy using the client / server architecture.@@ -38,6 +38,7 @@                       , hslogger                       , iproute                       , lens +                      , lens-aeson                       , mtl                       , network                       , optparse-applicative
src/Main.hs view
@@ -13,8 +13,10 @@ main :: IO () main = ssl - do   _options <- execParser opts-  r <- runExceptT - runReaderT moeApp _options-  case r of-    Left e -> error_ e >> exitFailure-    Right _ -> pure ()+  +  withGateOptions _options - do+    r <- runExceptT - runReaderT moeApp _options+    case r of+      Left e -> error_ e >> exitFailure+      Right _ -> pure () 
src/Network/MoeSocks/App.hs view
@@ -10,18 +10,18 @@ import Control.Monad.Reader hiding (local) import Control.Monad.Writer hiding (listen) import Data.Aeson hiding (Result)+import Data.Aeson.Lens import Data.ByteString (ByteString)-import Data.ByteString.Lazy (toStrict)+import Data.Maybe (fromMaybe) import Data.Text (Text) import Data.Text.Lens-import Data.Text.Strict.Lens (utf8) import Network.MoeSocks.Config import Network.MoeSocks.Constant+import Network.MoeSocks.Encrypt (initCipherBox, safeMethods, unsafeMethods) import Network.MoeSocks.Helper import Network.MoeSocks.TCP import Network.MoeSocks.Type import Network.MoeSocks.UDP-import Network.MoeSocks.Encrypt (initCipherBox) import Network.Socket hiding (send, recv, recvFrom, sendTo) import Network.Socket.ByteString import Prelude hiding ((-), take)@@ -29,101 +29,94 @@ import System.Log.Handler.Simple import System.Log.Logger import qualified Data.HashMap.Strict as H+import qualified Data.Map as Map import qualified Data.Text as T import qualified Data.Text.IO as TIO import qualified System.IO as IO import qualified System.Log.Handler as LogHandler  +withGateOptions :: MoeOptions -> IO a -> IO ()+withGateOptions aOption aIO = do+  if aOption ^. listMethods+    then do+      let _br = putStrLn ""++      _br+      putStrLn "Recommended:"+      itraverse_ (\k _ -> putStrLn - "\t\t" <> k ^. _Text) - safeMethods++      _br+      putStrLn "Supported:"+      itraverse_ (\k _ -> putStrLn - "\t\t" <> k ^. _Text) - unsafeMethods++    else+      () <$ aIO+ parseConfig :: MoeOptions -> MoeMonadT MoeConfig parseConfig aOption = do   let _maybeFilePath = aOption ^. configFile     _v <- case _maybeFilePath of           Nothing -> pure - Just - Object mempty-          Just _filePath -> do-                              _data <- io - TIO.readFile - _filePath ^. _Text-                              pure --                                (decodeStrict - review utf8 _data -                                    :: Maybe Value)+          Just _filePath -> fmap (preview _JSON) - +                            io - TIO.readFile - _filePath ^. _Text    let -      fromShadowSocksConfig :: [(Text, Value)] -> [(Text, Value)]-      fromShadowSocksConfig _configList = -        let fixes =++      asList :: ([(Text, Value)] -> [(Text, Value)]) -> Value -> Value+      asList f = over _Object - H.fromList . f . H.toList +      +      fromShadowSocksConfig :: Text -> Text+      fromShadowSocksConfig x = +        let fixes = Map.fromList               [                 ("server", "remote")               , ("server_port", "remotePort")               , ("local_address", "local")-              , ("local_port", "localPort")-              , ("fast_open", "fastOpen")               ]          in-        foldl (flip duplicateKey) _configList fixes--      fromSS :: [(Text, Value)] -> [(Text, Value)]-      fromSS = fromShadowSocksConfig-+        fixes ^? ix x & fromMaybe x -  let        toParsableConfig :: Value -> Value-      toParsableConfig (Object _obj) =-          Object - -            _obj -                & H.toList -                & fromSS -                & over (mapped . _1) (T.cons '_')  -                & H.fromList-      toParsableConfig _ = Null-  +      toParsableConfig = asList - each . _1 %~  (+                                                  T.cons '_' +                                                . toCamelCase+                                                . fromShadowSocksConfig+                                                )          toReadableConfig :: Value -> Value-      toReadableConfig (Object _obj) =-          Object --            _obj-                & H.toList -                & over (mapped . _1) T.tail -                & H.fromList--      toReadableConfig _ = Null+      toReadableConfig = asList - each . _1 %~ T.tail         showConfig :: MoeConfig -> Text-      showConfig =    view utf8 -                    . toStrict -                    . encode +      showConfig =  review _JSON                     . toReadableConfig -                    . toJSON --      +                    . review _JSON         filterEssentialConfig :: Value -> Value-      filterEssentialConfig (Object _obj) =-          Object --            foldl (flip H.delete) _obj - -              [-                "_password"-              ]+      filterEssentialConfig = over _Object - \_obj ->+                                foldl (flip H.delete) _obj - +                                  [+                                    "_password"+                                  ]           -      filterEssentialConfig _ = Null-       insertConfig :: Value -> Value -> Value-      insertConfig (Object _x) (Object _y) =-          Object - _x `H.union` _y-      insertConfig _ _ = Null+      insertConfig (Object _from) = over _Object (_from `H.union`)+      insertConfig _ = const Null        insertParams :: [(Text, Value)] -> Value -> Value-      insertParams xs (Object _x) =-          Object - H.fromList xs `H.union` _x-      insertParams _ _ = Null+      insertParams _from = over _Object (H.fromList _from `H.union`) +      fallbackConfig :: Value -> Value -> Value+      fallbackConfig = flip insertConfig        optionalConfig = filterEssentialConfig - toJSON defaultMoeConfig              _maybeConfig = _v                       >>= decode                            . encode -                          . flip insertConfig optionalConfig+                          . fallbackConfig optionalConfig                           . insertParams (aOption ^. params)                           . toParsableConfig  @@ -150,6 +143,7 @@       let configStr = showConfig _config ^. _Text :: String       io - debug_ - "Using config: " <> configStr       pure - _config +                & method .~ "camellia-128-cfb8"                 initLogger :: Priority -> IO ()
src/Network/MoeSocks/Common.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell #-}  module Network.MoeSocks.Common where @@ -23,6 +24,9 @@ showAddressType (IPv6_address xs) = xs ^.. each . to show                                        ^.. folding (concat . L.intersperse ":")                                        ^. from _Text+++makePrisms ''IPRange  checkForbidden_IP_List :: AddressType -> [IPRange] -> Bool checkForbidden_IP_List _address@(IPv4_address _) aForbidden_IP_List =
src/Network/MoeSocks/Config.hs view
@@ -34,5 +34,6 @@   , _disableSocks5 = False   , _obfuscation = False   , _forbidden_IP = ["127.0.0.1", "0.0.0.0", "::1"]+  , _listMethods = False   , _params = []   } 
src/Network/MoeSocks/Encrypt.hs view
@@ -10,6 +10,8 @@   initCipherBox , identityCipher , ssl+, safeMethods+, unsafeMethods ) where @@ -54,23 +56,58 @@  type MaybeT_IO = ExceptT () IO -methods :: Map Text KeyLength-methods = fromList-    [ ("aes-128-cfb"      , 16)-    , ("aes-192-cfb"      , 24)-    , ("aes-256-cfb"      , 32)-    , ("bf-cfb"           , 16)-    , ("camellia-128-cfb" , 16)-    , ("camellia-192-cfb" , 24)-    , ("camellia-256-cfb" , 32)-    , ("cast5-cfb"        , 16)-    , ("des-cfb"          , 8 )-    , ("idea-cfb"         , 16)-    , ("rc2-cfb"          , 16)-    , ("rc4"              , 16)-    , ("seed-cfb"         , 16)-    ]+type Method = Map Text KeyLength +safeMethods :: Method+safeMethods = fromList - +  [ +    ("aes-128-cfb"        , 16)+  , ("aes-192-cfb"        , 24)+  , ("aes-256-cfb"        , 32)+  , ("aes-128-ofb"        , 16)+  , ("aes-192-ofb"        , 24)+  , ("aes-256-ofb"        , 32)+  , ("aes-128-ctr"        , 16)+  , ("aes-192-ctr"        , 24)+  , ("aes-256-ctr"        , 32)+  , ("aes-128-cfb8"       , 16)+  , ("aes-192-cfb8"       , 24)+  , ("aes-256-cfb8"       , 32)+  , ("aes-128-cfb1"       , 16)+  , ("aes-192-cfb1"       , 24)+  , ("aes-256-cfb1"       , 32)+  , ("aes-128-gcm"        , 16)+  , ("aes-192-gcm"        , 24)+  , ("aes-256-gcm"        , 32)+  , ("bf-cfb"             , 16)+  , ("camellia-128-cfb"   , 16)+  , ("camellia-192-cfb"   , 24)+  , ("camellia-256-cfb"   , 32)+  , ("camellia-128-ofb"   , 16)+  , ("camellia-192-ofb"   , 24)+  , ("camellia-256-ofb"   , 32)+  , ("camellia-128-cfb8"  , 16)+  , ("camellia-192-cfb8"  , 24)+  , ("camellia-256-cfb8"  , 32)+  , ("camellia-128-cfb1"  , 16)+  , ("camellia-192-cfb1"  , 24)+  , ("camellia-256-cfb1"  , 32)+  , ("cast5-cfb"          , 16)+  , ("des-cfb"            , 8 )+  {-, ("idea-cfb"           , 16)-}+  , ("seed-cfb"           , 16)+  ]+++unsafeMethods :: Method+unsafeMethods = fromList - +  [+    ("rc2-cfb"            , 16) -- unsafe+  , ("rc4"                , 16) -- unsafe+  ]++methods :: Method+methods = safeMethods <> unsafeMethods  hashKey :: ByteString -> KeyLength -> IV_Length -> ByteString hashKey aPassword aKeyLen a_IV_len = loop mempty mempty 
src/Network/MoeSocks/Helper.hs view
@@ -14,13 +14,13 @@ import Data.Binary import Data.Binary.Put import Data.ByteString (ByteString)-import Data.IP import Data.Maybe import Data.Monoid import Data.Text (Text)+import qualified Data.Text as T import Data.Text.Lens import Data.Time.Clock-import Network.MoeSocks.Internal.Socket (sendAllFastOpenTo)+import Network.MoeSocks.Internal.Socket (sendAllToFastOpen) import Network.Socket hiding (send, recv) import Network.Socket.ByteString import Prelude hiding (take, (-)) @@ -33,7 +33,6 @@ import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Lazy as LB import qualified Data.Strict as S-{-import Data.List (isPrefixOf)-}   -- BEGIN backports@@ -261,7 +260,7 @@   sendFast_ :: Socket -> ByteString -> SockAddr -> IO ()-sendFast_ = sendAllFastOpenTo+sendFast_ = sendAllToFastOpen   sendAllRandom :: Int -> Socket -> ByteString -> IO ()@@ -457,18 +456,9 @@  tryIO :: String -> IO a -> IO (Either IOException a) tryIO _ = try -- . logException aID-  -maybeIPv4Range :: IPRange -> Maybe (AddrRange IPv4)-maybeIPv4Range (IPv4Range x) = Just x-maybeIPv4Range _ = Nothing -maybeIPv6Range :: IPRange -> Maybe (AddrRange IPv6)-maybeIPv6Range (IPv6Range x) = Just x-maybeIPv6Range _ = Nothing--_IPv4Range :: Prism' IPRange (AddrRange IPv4) -_IPv4Range = prism' IPv4Range maybeIPv4Range--_IPv6Range :: Prism' IPRange (AddrRange IPv6)-_IPv6Range = prism' IPv6Range maybeIPv6Range-+toCamelCase :: Text -> Text+toCamelCase x = x +                  & T.split (`elem` ['_', '-'])+                  & over (_tail . traversed) T.toTitle+                  & T.concat
src/Network/MoeSocks/Internal/Socket.hs view
@@ -31,20 +31,20 @@         c_sendto s ptr (fromIntegral $ nbytes) (fromIntegral flags)                           p_addr (fromIntegral sz) -sendToWithFlag :: Socket      -- ^ Socket+sendToWithFlagNoRetry :: Socket      -- ^ Socket        -> ByteString  -- ^ Data to send        -> SockAddr    -- ^ Recipient address        -> Int        -> IO Int      -- ^ Number of bytes sent-sendToWithFlag sock xs addr flags =+sendToWithFlagNoRetry sock xs addr flags =     unsafeUseAsCStringLen xs $ \(str, len) ->        sendBufToWithFlagNoRetry sock str len addr flags -sendAllFastOpenTo :: Socket      -- ^ Socket+sendAllToFastOpen :: Socket      -- ^ Socket           -> ByteString  -- ^ Data to send           -> SockAddr    -- ^ Recipient address           -> IO ()-sendAllFastOpenTo sock xs addr = do+sendAllToFastOpen sock xs addr = do     let _MSG_FASTOPEN  = 0x20000000  -    sent <- sendToWithFlag sock xs addr _MSG_FASTOPEN-    when (sent < S.length xs) $ sendAllTo sock (S.drop sent xs) addr+    sent <- sendToWithFlagNoRetry sock xs addr _MSG_FASTOPEN+    when (sent < S.length xs) $ sendAll sock (S.drop sent xs)
src/Network/MoeSocks/Options.hs view
@@ -61,6 +61,11 @@                       long "disable-socks5"                   <>  help ("Do not start a socks5 server on local. It can be "                           <> "useful to run moesocks only as a secure tunnel")+      +      _listMethods :: O.Parser Bool+      _listMethods = switch -+                      long "list-methods"+                  <>  help "Show supported encryption methods"                          _tcpBufferSize = intParam -                               long "tcp-buffer-size"@@ -76,7 +81,7 @@                       short 'c'                   <>  long "config"                   <>  metavar "CONFIG"-                  <>  help "Point to the path of the configuration file"+                  <>  help "Set the path of the configuration file"                         _remote = textParam -                       short 's'@@ -123,11 +128,11 @@                     <>  defaultHelp (_c ^. timeout                                         & show                                         & view (from _Text))-                                    "timeout connection in seconds"+                                    "Timeout connection in seconds"                                _fastOpen = boolParam -                         long "fast-open"-                    <>  help ("use TCP_FASTOPEN, requires Linux 3.7+")+                    <>  help ("Use TCP_FASTOPEN, requires Linux 3.7+")              _obfuscation :: O.Parser Bool        _obfuscation = switch -@@ -255,6 +260,7 @@               <*> _disableSocks5               <*> _obfuscation               <*> fmap parseForbidden_IP _forbidden_IP+              <*> _listMethods               <*> _params  opts :: ParserInfo MoeOptions
src/Network/MoeSocks/TCP.hs view
@@ -206,7 +206,7 @@   _decodeIV <- recv aSocket (_cipherBox ^. ivLength)   _decrypt <- _cipherBox ^. decryptBuilder - _decodeIV -  (_leftOverBytes, _clientRequest) <- parseSocket +  (_partialBytesAfterRequest, _clientRequest) <- parseSocket                                            "clientRequest"                                           mempty                                           _decrypt@@ -223,26 +223,19 @@     withCheckedForbidden_IP_List _addr _forbidden_IP - do       setSocketSendFast _targetSocket -      let _initBytes = _leftOverBytes-      let _connectNormal = do-            connect _targetSocket _targetAddress-            send_ _targetSocket _initBytes+      _remotePeerAddr <- getPeerName aSocket+      let _msg = showRelay _remotePeerAddr _clientRequest +      info_ - "RT: " <> _msg+      +      let _initBytes = _partialBytesAfterRequest+       if _c ^. fastOpen         then           sendFast_ _targetSocket _initBytes _targetAddress-           {-`onException` -}-            {-( do-}-              {-error_ - "TCP Fast Open not availabe for: " <> show _targetSocket-}-              {-_connectNormal-}-            {-)-}         else do-          _connectNormal-      -      _remotePeerAddr <- getPeerName aSocket-      let _msg = showRelay _remotePeerAddr _clientRequest--      info_ - "RT: " <> _msg+          connect _targetSocket _targetAddress+          send_ _targetSocket _initBytes              let            handleTarget __targetSocket = do
src/Network/MoeSocks/Type.hs view
@@ -97,6 +97,7 @@   , _disableSocks5 :: Bool   , _obfuscation :: Bool   , _forbidden_IP :: [IPRange]+  , _listMethods :: Bool   , _params :: [(Text, Value)]   }   deriving (Show, Eq)