Add new option --torisolation
Tor stream isolation randomizes proxy user credentials resulting in Tor creating a new circuit for each connection. This makes it more difficult to correlate connections. Idea from Wladimir J. van der Laan via Bitcoin Core.
This commit is contained in:
parent
5f8dbab47a
commit
007bee5ec8
4 changed files with 246 additions and 163 deletions
43
config.go
43
config.go
|
@ -95,6 +95,7 @@ type config struct {
|
||||||
OnionProxyUser string `long:"onionuser" description:"Username for onion proxy server"`
|
OnionProxyUser string `long:"onionuser" description:"Username for onion proxy server"`
|
||||||
OnionProxyPass string `long:"onionpass" default-mask:"-" description:"Password for onion proxy server"`
|
OnionProxyPass string `long:"onionpass" default-mask:"-" description:"Password for onion proxy server"`
|
||||||
NoOnion bool `long:"noonion" description:"Disable connecting to tor hidden services"`
|
NoOnion bool `long:"noonion" description:"Disable connecting to tor hidden services"`
|
||||||
|
TorIsolation bool `long:"torisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."`
|
||||||
TestNet3 bool `long:"testnet" description:"Use the test network"`
|
TestNet3 bool `long:"testnet" description:"Use the test network"`
|
||||||
RegressionTest bool `long:"regtest" description:"Use the regression test network"`
|
RegressionTest bool `long:"regtest" description:"Use the regression test network"`
|
||||||
SimNet bool `long:"simnet" description:"Use the simulation test network"`
|
SimNet bool `long:"simnet" description:"Use the simulation test network"`
|
||||||
|
@ -717,6 +718,16 @@ func loadConfig() (*config, []string, error) {
|
||||||
cfg.ConnectPeers = normalizeAddresses(cfg.ConnectPeers,
|
cfg.ConnectPeers = normalizeAddresses(cfg.ConnectPeers,
|
||||||
activeNetParams.DefaultPort)
|
activeNetParams.DefaultPort)
|
||||||
|
|
||||||
|
// Tor stream isolation requires either proxy or onion proxy to be set.
|
||||||
|
if cfg.TorIsolation && cfg.Proxy == "" && cfg.OnionProxy == "" {
|
||||||
|
str := "%s: Tor stream isolation requires either proxy or " +
|
||||||
|
"onionproxy to be set"
|
||||||
|
err := fmt.Errorf(str, funcName)
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
fmt.Fprintln(os.Stderr, usageMessage)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// Setup dial and DNS resolution (lookup) functions depending on the
|
// Setup dial and DNS resolution (lookup) functions depending on the
|
||||||
// specified options. The default is to use the standard net.Dial
|
// specified options. The default is to use the standard net.Dial
|
||||||
// function as well as the system DNS resolver. When a proxy is
|
// function as well as the system DNS resolver. When a proxy is
|
||||||
|
@ -726,10 +737,26 @@ func loadConfig() (*config, []string, error) {
|
||||||
cfg.dial = net.Dial
|
cfg.dial = net.Dial
|
||||||
cfg.lookup = net.LookupIP
|
cfg.lookup = net.LookupIP
|
||||||
if cfg.Proxy != "" {
|
if cfg.Proxy != "" {
|
||||||
|
_, _, err := net.SplitHostPort(cfg.Proxy)
|
||||||
|
if err != nil {
|
||||||
|
str := "%s: Proxy address '%s' is invalid: %v"
|
||||||
|
err := fmt.Errorf(str, funcName, cfg.Proxy, err)
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
fmt.Fprintln(os.Stderr, usageMessage)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.TorIsolation &&
|
||||||
|
(cfg.ProxyUser != "" || cfg.ProxyPass != "") {
|
||||||
|
btcdLog.Warn("Tor isolation set -- overriding " +
|
||||||
|
"specified proxy user credentials")
|
||||||
|
}
|
||||||
|
|
||||||
proxy := &socks.Proxy{
|
proxy := &socks.Proxy{
|
||||||
Addr: cfg.Proxy,
|
Addr: cfg.Proxy,
|
||||||
Username: cfg.ProxyUser,
|
Username: cfg.ProxyUser,
|
||||||
Password: cfg.ProxyPass,
|
Password: cfg.ProxyPass,
|
||||||
|
TorIsolation: cfg.TorIsolation,
|
||||||
}
|
}
|
||||||
cfg.dial = proxy.Dial
|
cfg.dial = proxy.Dial
|
||||||
if !cfg.NoOnion {
|
if !cfg.NoOnion {
|
||||||
|
@ -748,11 +775,27 @@ func loadConfig() (*config, []string, error) {
|
||||||
// This allows .onion address traffic to be routed through a different
|
// This allows .onion address traffic to be routed through a different
|
||||||
// proxy than normal traffic.
|
// proxy than normal traffic.
|
||||||
if cfg.OnionProxy != "" {
|
if cfg.OnionProxy != "" {
|
||||||
|
_, _, err := net.SplitHostPort(cfg.OnionProxy)
|
||||||
|
if err != nil {
|
||||||
|
str := "%s: Onion proxy address '%s' is invalid: %v"
|
||||||
|
err := fmt.Errorf(str, funcName, cfg.OnionProxy, err)
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
fmt.Fprintln(os.Stderr, usageMessage)
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.TorIsolation &&
|
||||||
|
(cfg.OnionProxyUser != "" || cfg.OnionProxyPass != "") {
|
||||||
|
btcdLog.Warn("Tor isolation set -- overriding " +
|
||||||
|
"specified onionproxy user credentials ")
|
||||||
|
}
|
||||||
|
|
||||||
cfg.oniondial = func(a, b string) (net.Conn, error) {
|
cfg.oniondial = func(a, b string) (net.Conn, error) {
|
||||||
proxy := &socks.Proxy{
|
proxy := &socks.Proxy{
|
||||||
Addr: cfg.OnionProxy,
|
Addr: cfg.OnionProxy,
|
||||||
Username: cfg.OnionProxyUser,
|
Username: cfg.OnionProxyUser,
|
||||||
Password: cfg.OnionProxyPass,
|
Password: cfg.OnionProxyPass,
|
||||||
|
TorIsolation: cfg.TorIsolation,
|
||||||
}
|
}
|
||||||
return proxy.Dial(a, b)
|
return proxy.Dial(a, b)
|
||||||
}
|
}
|
||||||
|
|
3
doc.go
3
doc.go
|
@ -63,7 +63,8 @@ Application Options:
|
||||||
--onionuser= Username for onion proxy server
|
--onionuser= Username for onion proxy server
|
||||||
--onionpass= Password for onion proxy server
|
--onionpass= Password for onion proxy server
|
||||||
--noonion= Disable connecting to tor hidden services
|
--noonion= Disable connecting to tor hidden services
|
||||||
--tor= Specifies the proxy server used is a Tor node
|
--torisolation Enable Tor stream isolation by randomizing user
|
||||||
|
credentials for each connection.
|
||||||
--testnet= Use the test network
|
--testnet= Use the test network
|
||||||
--regtest= Use the regression test network
|
--regtest= Use the regression test network
|
||||||
--nocheckpoints= Disable built-in checkpoints. Don't do this unless
|
--nocheckpoints= Disable built-in checkpoints. Don't do this unless
|
||||||
|
|
|
@ -12,16 +12,21 @@
|
||||||
4.1 [Description](#BridgeDescription)<br />
|
4.1 [Description](#BridgeDescription)<br />
|
||||||
4.2 [Command Line Example](#BridgeCLIExample)<br />
|
4.2 [Command Line Example](#BridgeCLIExample)<br />
|
||||||
4.3 [Config File Example](#BridgeConfigFileExample)<br />
|
4.3 [Config File Example](#BridgeConfigFileExample)<br />
|
||||||
|
5. [Tor Stream Isolation](#TorStreamIsolation)<br />
|
||||||
|
5.1 [Description](#TorStreamIsolationDescription)<br />
|
||||||
|
5.2 [Command Line Example](#TorStreamIsolationCLIExample)<br />
|
||||||
|
5.3 [Config File Example](#TorStreamIsolationFileExample)<br />
|
||||||
|
|
||||||
<a name="Overview" />
|
<a name="Overview" />
|
||||||
### 1. Overview
|
### 1. Overview
|
||||||
|
|
||||||
btcd provides full support for anonymous networking via the
|
btcd provides full support for anonymous networking via the
|
||||||
[Tor Project](https://www.torproject.org/), including [client-only](#Client)
|
[Tor Project](https://www.torproject.org/), including [client-only](#Client)
|
||||||
and [hidden service](#HiddenService) configurations. In addition, btcd supports
|
and [hidden service](#HiddenService) configurations along with
|
||||||
a hybrid, [bridge mode](#Bridge) which is not anonymous, but allows it to
|
[stream isolation](#TorStreamIsolation). In addition, btcd supports a hybrid,
|
||||||
operate as a bridge between regular nodes and hidden service nodes without
|
[bridge mode](#Bridge) which is not anonymous, but allows it to operate as a
|
||||||
routing the regular connections through Tor.
|
bridge between regular nodes and hidden service nodes without routing the
|
||||||
|
regular connections through Tor.
|
||||||
|
|
||||||
While it is easier to only run as a client, it is more beneficial to the Bitcoin
|
While it is easier to only run as a client, it is more beneficial to the Bitcoin
|
||||||
network to run as both a client and a server so others may connect to you to as
|
network to run as both a client and a server so others may connect to you to as
|
||||||
|
@ -154,3 +159,32 @@ $ ./btcd --onion=127.0.0.1:9050 --externalip=fooanon.onion
|
||||||
onion=127.0.0.1:9050
|
onion=127.0.0.1:9050
|
||||||
externalip=fooanon.onion
|
externalip=fooanon.onion
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a name="TorStreamIsolation" />
|
||||||
|
### 5. Tor Stream Isolation
|
||||||
|
|
||||||
|
<a name="TorStreamIsolationDescription" />
|
||||||
|
**5.1 Description**<br />
|
||||||
|
|
||||||
|
Tor stream isolation forces Tor to build a new circuit for each connection
|
||||||
|
making it harder to correlate connections.
|
||||||
|
|
||||||
|
btcd provides support for Tor stream isolation by using the `--torisolation`
|
||||||
|
flag. This option requires --proxy or --onionproxy to be set.
|
||||||
|
|
||||||
|
<a name="TorStreamIsolationCLIExample" />
|
||||||
|
**5.2 Command Line Example**<br />
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./btcd --proxy=127.0.0.1:9050 --torisolation
|
||||||
|
```
|
||||||
|
|
||||||
|
<a name="TorStreamIsolationFileExample" />
|
||||||
|
**5.3 Config File Example**<br />
|
||||||
|
|
||||||
|
```text
|
||||||
|
[Application Options]
|
||||||
|
|
||||||
|
proxy=127.0.0.1:9050
|
||||||
|
torisolation=1
|
||||||
|
```
|
||||||
|
|
|
@ -41,6 +41,11 @@
|
||||||
; onionuser=
|
; onionuser=
|
||||||
; onionpass=
|
; onionpass=
|
||||||
|
|
||||||
|
; Enable Tor stream isolation by randomizing proxy user credentials resulting in
|
||||||
|
; Tor creating a new circuit for each connection. This makes it more difficult
|
||||||
|
; to correlate connections.
|
||||||
|
; torisolation=1
|
||||||
|
|
||||||
; Use Universal Plug and Play (UPnP) to automatically open the listen port
|
; Use Universal Plug and Play (UPnP) to automatically open the listen port
|
||||||
; and obtain the external IP address from supported devices. NOTE: This option
|
; and obtain the external IP address from supported devices. NOTE: This option
|
||||||
; will have no effect if exernal IP addresses are specified.
|
; will have no effect if exernal IP addresses are specified.
|
||||||
|
|
Loading…
Add table
Reference in a new issue