core: access messaging servers via SOCKS5 proxy (#835)

* core: access messaging servers via SOCKS5 proxy

* update option info

* update simplexmq
This commit is contained in:
Evgeny Poberezkin 2022-07-23 14:49:04 +01:00 committed by GitHub
parent 88d1d3448d
commit 4fd13c637c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 97 additions and 12 deletions

View file

@ -140,7 +140,7 @@ What is already implemented:
We plan to add soon:
1. Access to messaging servers via Tor. Currently clients access servers via public Internet, and the servers can observe IP addresses of the clients. Depending which platform you use, you might be able to configure access via Tor independently. The servers provided by SimpleX Chat do not correlate users by or log IP addresses, and you can use your own servers, but in some scenarios that may be not a sufficient level of privacy.
1. Access to messaging servers via Tor. Currently it is supported only for [terminal CLI clients](./docs/CLI.md); mobile clients access servers via public Internet, and the servers can observe IP addresses of the clients. Depending which platform you use, you might be able to configure access via Tor independently. The servers provided by SimpleX Chat do not correlate users by or log IP addresses, and you can use your own servers, but in some scenarios that may be not a sufficient level of privacy.
2. Message queue rotation. Currently the queues created between two users are used until the contact is deleted, providing a long-term pairwise identifiers of the conversation. We are planning to add queue rotation to make these identifiers termporary and rotate based on some schedule TBC (e.g., every X messages, or every X hours/days).
3. Local database encryption. Currently the local chat database stored on your device is not encrypted.
4. Independent implementation audit.

View file

@ -3,6 +3,7 @@
module Main where
import Control.Concurrent (threadDelay)
import Network.Socks5 (SocksConf (..))
import Server
import Simplex.Chat.Controller (versionNumber)
import Simplex.Chat.Core
@ -30,7 +31,10 @@ main = do
threadDelay $ chatCmdDelay opts * 1000000
welcome :: ChatOpts -> IO ()
welcome ChatOpts {dbFilePrefix} = do
welcome ChatOpts {dbFilePrefix, socksProxy} = do
putStrLn $ "SimpleX Chat v" ++ versionNumber
putStrLn $ "db: " <> dbFilePrefix <> "_chat.db, " <> dbFilePrefix <> "_agent.db"
case socksProxy of
Just (SocksConf s _) -> putStrLn $ "using SOCKS5 proxy " <> show s
_ -> putStrLn "use -x CLI option to connect via SOCKS5 at :9050"
putStrLn "type \"/help\" or \"/h\" for usage info"

View file

@ -5,7 +5,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: eb1f9370c1f254022019906fb6cf741d7687c525
tag: d788c3ca95f74d7ec2d737f3ef3ad8dc69d32abc
source-repository-package
type: git

View file

@ -12,6 +12,7 @@
- [Using Haskell stack](#using-haskell-stack)
- [Usage](#usage)
- [Running the chat client](#running-the-chat-client)
- [Access messaging servers via Tor (BETA)](#access-messaging-servers-via-tor-beta)
- [How to use SimpleX chat](#how-to-use-simplex-chat)
- [Groups](#groups)
- [Sending files](#sending-files)
@ -139,6 +140,23 @@ You can still talk to people using default or any other server - it only affects
Run `simplex-chat -h` to see all available options.
### Access messaging servers via Tor (BETA)
Install Tor and run it as SOCKS5 proxy on port 9050, e.g. on Mac you can:
```
brew install tor
brew services start tor
```
Use `-x` option to access servers via Tor:
```
simplex-chat -x
```
You can also use option `--socks-proxy=ipv4:port` or `--socks-proxy=:port` to configure host and port of your SOCKS5 proxy, e.g. if you are running it on some other host or port.
### How to use SimpleX chat
Once you have started the chat, you will be prompted to specify your "display name" and an optional "full name" to create a local chat profile. Your display name is an alias for your contacts to refer to you by - it is not unique and does not serve as a global identity. If some of your contacts chose the same display name, the chat client adds a numeric suffix to their local display name.

View file

@ -28,10 +28,12 @@ dependencies:
- filepath == 1.4.*
- http-types == 0.12.*
- mtl == 2.2.*
- network >= 3.1.2.7 && < 3.2
- optparse-applicative >= 0.15 && < 0.17
- process == 1.6.*
- simple-logger == 0.1.*
- simplexmq >= 3.0
- socks == 0.6.*
- sqlite-simple == 0.4.*
- stm == 2.5.*
- terminal == 0.2.*

View file

@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."eb1f9370c1f254022019906fb6cf741d7687c525" = "0lwzs3gy2ajjf2iv53ajmm32zix3zi06njgjpr096fv6xhzypbdb";
"https://github.com/simplex-chat/simplexmq.git"."d788c3ca95f74d7ec2d737f3ef3ad8dc69d32abc" = "0sxaf8by830cc2pfkpn1bkfyr68b9iz901pihip12r9g6v3asssh";
"https://github.com/simplex-chat/aeson.git"."3eb66f9a68f103b5f1489382aad89f5712a64db7" = "0kilkx59fl6c3qy3kjczqvm8c3f4n3p0bdk9biyflf51ljnzp4yp";
"https://github.com/simplex-chat/haskell-terminal.git"."f708b00009b54890172068f168bf98508ffcd495" = "0zmq7lmfsk8m340g47g5963yba7i88n4afa6z93sg9px5jv1mijj";
"https://github.com/zw3rk/android-support.git"."3c3a5ab0b8b137a072c98d3d0937cbdc96918ddb" = "1r6jyxbim3dsvrmakqfyxbd6ms6miaghpbwyl0sr6dzwpgaprz97";

View file

@ -76,10 +76,12 @@ library
, filepath ==1.4.*
, http-types ==0.12.*
, mtl ==2.2.*
, network >=3.1.2.7 && <3.2
, optparse-applicative >=0.15 && <0.17
, process ==1.6.*
, simple-logger ==0.1.*
, simplexmq >=3.0
, socks ==0.6.*
, sqlite-simple ==0.4.*
, stm ==2.5.*
, terminal ==0.2.*
@ -114,11 +116,13 @@ executable simplex-bot
, filepath ==1.4.*
, http-types ==0.12.*
, mtl ==2.2.*
, network >=3.1.2.7 && <3.2
, optparse-applicative >=0.15 && <0.17
, process ==1.6.*
, simple-logger ==0.1.*
, simplex-chat
, simplexmq >=3.0
, socks ==0.6.*
, sqlite-simple ==0.4.*
, stm ==2.5.*
, terminal ==0.2.*
@ -153,11 +157,13 @@ executable simplex-bot-advanced
, filepath ==1.4.*
, http-types ==0.12.*
, mtl ==2.2.*
, network >=3.1.2.7 && <3.2
, optparse-applicative >=0.15 && <0.17
, process ==1.6.*
, simple-logger ==0.1.*
, simplex-chat
, simplexmq >=3.0
, socks ==0.6.*
, sqlite-simple ==0.4.*
, stm ==2.5.*
, terminal ==0.2.*
@ -199,6 +205,7 @@ executable simplex-chat
, simple-logger ==0.1.*
, simplex-chat
, simplexmq >=3.0
, socks ==0.6.*
, sqlite-simple ==0.4.*
, stm ==2.5.*
, terminal ==0.2.*
@ -249,6 +256,7 @@ test-suite simplex-chat-test
, simple-logger ==0.1.*
, simplex-chat
, simplexmq >=3.0
, socks ==0.6.*
, sqlite-simple ==0.4.*
, stm ==2.5.*
, terminal ==0.2.*

View file

@ -87,7 +87,13 @@ defaultChatConfig =
yesToMigrations = False
},
yesToMigrations = False,
defaultServers = InitialAgentServers {smp = _defaultSMPServers, ntf = _defaultNtfServers},
defaultServers =
InitialAgentServers
{ smp = _defaultSMPServers,
ntf = _defaultNtfServers,
socksProxy = Nothing,
tcpTimeout = 5000000
},
tbqSize = 64,
fileChunkSize = 15780,
subscriptionConcurrency = 16,
@ -116,7 +122,7 @@ logCfg :: LogConfig
logCfg = LogConfig {lc_file = Nothing, lc_stderr = True}
newChatController :: SQLiteStore -> Maybe User -> ChatConfig -> ChatOpts -> Maybe (Notification -> IO ()) -> IO ChatController
newChatController chatStore user cfg@ChatConfig {agentConfig = aCfg, tbqSize, defaultServers} ChatOpts {dbFilePrefix, smpServers, logConnections} sendToast = do
newChatController chatStore user cfg@ChatConfig {agentConfig = aCfg, tbqSize, defaultServers} ChatOpts {dbFilePrefix, smpServers, socksProxy, tcpTimeout, logConnections} sendToast = do
let f = chatStoreFile dbFilePrefix
config = cfg {subscriptionEvents = logConnections}
sendNotification = fromMaybe (const $ pure ()) sendToast
@ -124,7 +130,7 @@ newChatController chatStore user cfg@ChatConfig {agentConfig = aCfg, tbqSize, de
firstTime <- not <$> doesFileExist f
currentUser <- newTVarIO user
servers <- resolveServers defaultServers
smpAgent <- getSMPAgentClient aCfg {dbFile = dbFilePrefix <> "_agent.db"} servers
smpAgent <- getSMPAgentClient aCfg {dbFile = dbFilePrefix <> "_agent.db"} servers {socksProxy, tcpTimeout}
agentAsync <- newTVarIO Nothing
idsDrg <- newTVarIO =<< drgNew
inputQ <- newTBQueueIO tbqSize

View file

@ -67,6 +67,8 @@ mobileChatOpts =
ChatOpts
{ dbFilePrefix = undefined,
smpServers = [],
socksProxy = Nothing,
tcpTimeout = 5000000,
logConnections = False,
logAgent = False,
chatCmd = "",

View file

@ -1,6 +1,8 @@
{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Simplex.Chat.Options
( ChatOpts (..),
@ -11,6 +13,9 @@ where
import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.ByteString.Char8 as B
import Data.Maybe (fromMaybe)
import Network.Socket (HostAddress, SockAddr (..), tupleToHostAddress)
import Network.Socks5 (SocksConf, defaultSocksConf)
import Options.Applicative
import Simplex.Chat.Controller (updateStr, versionStr)
import Simplex.Messaging.Agent.Protocol (SMPServer)
@ -21,6 +26,8 @@ import System.FilePath (combine)
data ChatOpts = ChatOpts
{ dbFilePrefix :: String,
smpServers :: [SMPServer],
socksProxy :: Maybe SocksConf,
tcpTimeout :: Int,
logConnections :: Bool,
logAgent :: Bool,
chatCmd :: String,
@ -46,10 +53,26 @@ chatOpts appDir defaultDbFileName = do
( long "server"
<> short 's'
<> metavar "SERVER"
<> help
"Comma separated list of SMP server(s) to use"
<> help "Comma separated list of SMP server(s) to use"
<> value []
)
socksProxy <-
flag' (Just defaultSocksProxy) (short 'x' <> help "use local SOCKS5 proxy at :9050")
<|> option
parseSocksConf
( long "socks-proxy"
<> metavar "SOCKS5"
<> help "`ipv4:port` or `:port` of SOCKS5 proxy"
<> value Nothing
)
t <-
option
auto
( long "tcp-timeout"
<> metavar "TIMEOUT"
<> help "TCP timeout, seconds (default: 5/10 without/with SOCKS5 proxy)"
<> value 0
)
logConnections <-
switch
( long "connections"
@ -95,13 +118,30 @@ chatOpts appDir defaultDbFileName = do
<> short 'm'
<> help "Run in maintenance mode (/_start to start chat)"
)
pure ChatOpts {dbFilePrefix, smpServers, logConnections, logAgent, chatCmd, chatCmdDelay, chatServerPort, maintenance}
pure ChatOpts {dbFilePrefix, smpServers, socksProxy, tcpTimeout = useTcpTimeout socksProxy t, logConnections, logAgent, chatCmd, chatCmdDelay, chatServerPort, maintenance}
where
useTcpTimeout p t = 1000000 * if t > 0 then t else maybe 5 (const 10) p
defaultDbFilePath = combine appDir defaultDbFileName
parseSMPServers :: ReadM [SMPServer]
parseSMPServers = eitherReader $ parseAll smpServersP . B.pack
defaultSocksHost :: HostAddress
defaultSocksHost = tupleToHostAddress (127, 0, 0, 1)
defaultSocksProxy :: SocksConf
defaultSocksProxy = defaultSocksConf $ SockAddrInet 9050 defaultSocksHost
parseSocksConf :: ReadM (Maybe SocksConf)
parseSocksConf = eitherReader $ parseAll socksConfP . B.pack
where
socksConfP = do
host <- maybe defaultSocksHost tupleToHostAddress <$> optional ipv4P
port <- fromMaybe 9050 <$> optional (A.char ':' *> (fromInteger <$> A.decimal))
pure . Just . defaultSocksConf $ SockAddrInet port host
ipv4P = (,,,) <$> ipNum <*> ipNum <*> ipNum <*> A.decimal
ipNum = A.decimal <* A.char '.'
parseServerPort :: ReadM (Maybe String)
parseServerPort = eitherReader $ parseAll serverPortP . B.pack

View file

@ -1,3 +1,4 @@
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
@ -28,7 +29,9 @@ terminalChatConfig =
"smp://hpq7_4gGJiilmz5Rf-CswuU5kZGkm_zOIooSw6yALRg=@smp5.simplex.im",
"smp://PQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo=@smp6.simplex.im"
],
ntf = ["ntf://FB-Uop7RTaZZEG0ZLD2CIaTjsPh-Fw0zFAnb7QyA8Ks=@ntf2.simplex.im"]
ntf = ["ntf://FB-Uop7RTaZZEG0ZLD2CIaTjsPh-Fw0zFAnb7QyA8Ks=@ntf2.simplex.im"],
socksProxy = Nothing,
tcpTimeout = 5000000
}
}

View file

@ -49,7 +49,7 @@ extra-deps:
# - simplexmq-1.0.0@sha256:34b2004728ae396e3ae449cd090ba7410781e2b3cefc59259915f4ca5daa9ea8,8561
# - ../simplexmq
- github: simplex-chat/simplexmq
commit: eb1f9370c1f254022019906fb6cf741d7687c525
commit: d788c3ca95f74d7ec2d737f3ef3ad8dc69d32abc
# - terminal-0.2.0.0@sha256:de6770ecaae3197c66ac1f0db5a80cf5a5b1d3b64a66a05b50f442de5ad39570,2977
- github: simplex-chat/aeson
commit: 3eb66f9a68f103b5f1489382aad89f5712a64db7

View file

@ -49,6 +49,8 @@ testOpts =
ChatOpts
{ dbFilePrefix = undefined,
smpServers = ["smp://LcJUMfVhwD8yxjAiSaDzzGF3-kLG4Uh0Fl_ZIjrRwjI=@localhost:5001"],
socksProxy = Nothing,
tcpTimeout = 5000000,
logConnections = False,
logAgent = False,
chatCmd = "",