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:
David Hill 2015-05-13 16:34:33 -04:00
parent 5f8dbab47a
commit 007bee5ec8
4 changed files with 246 additions and 163 deletions

View file

@ -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
View file

@ -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

View file

@ -1,156 +1,190 @@
### Table of Contents ### Table of Contents
1. [Overview](#Overview)<br /> 1. [Overview](#Overview)<br />
2. [Client-Only](#Client)<br /> 2. [Client-Only](#Client)<br />
2.1 [Description](#ClientDescription)<br /> 2.1 [Description](#ClientDescription)<br />
2.2 [Command Line Example](#ClientCLIExample)<br /> 2.2 [Command Line Example](#ClientCLIExample)<br />
2.3 [Config File Example](#ClientConfigFileExample)<br /> 2.3 [Config File Example](#ClientConfigFileExample)<br />
3. [Client-Server via Tor Hidden Service](#HiddenService)<br /> 3. [Client-Server via Tor Hidden Service](#HiddenService)<br />
3.1 [Description](#HiddenServiceDescription)<br /> 3.1 [Description](#HiddenServiceDescription)<br />
3.2 [Command Line Example](#HiddenServiceCLIExample)<br /> 3.2 [Command Line Example](#HiddenServiceCLIExample)<br />
3.3 [Config File Example](#HiddenServiceConfigFileExample)<br /> 3.3 [Config File Example](#HiddenServiceConfigFileExample)<br />
4. [Bridge Mode (Not Anonymous)](#Bridge)<br /> 4. [Bridge Mode (Not Anonymous)](#Bridge)<br />
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 />
<a name="Overview" /> 5.1 [Description](#TorStreamIsolationDescription)<br />
### 1. Overview 5.2 [Command Line Example](#TorStreamIsolationCLIExample)<br />
5.3 [Config File Example](#TorStreamIsolationFileExample)<br />
btcd provides full support for anonymous networking via the
[Tor Project](https://www.torproject.org/), including [client-only](#Client) <a name="Overview" />
and [hidden service](#HiddenService) configurations. In addition, btcd supports ### 1. Overview
a hybrid, [bridge mode](#Bridge) which is not anonymous, but allows it to
operate as a bridge between regular nodes and hidden service nodes without btcd provides full support for anonymous networking via the
routing the regular connections through Tor. [Tor Project](https://www.torproject.org/), including [client-only](#Client)
and [hidden service](#HiddenService) configurations along with
While it is easier to only run as a client, it is more beneficial to the Bitcoin [stream isolation](#TorStreamIsolation). In addition, btcd supports a hybrid,
network to run as both a client and a server so others may connect to you to as [bridge mode](#Bridge) which is not anonymous, but allows it to operate as a
you are connecting to them. We recommend you take the time to setup a Tor bridge between regular nodes and hidden service nodes without routing the
hidden service for this reason. regular connections through Tor.
<a name="Client" /> While it is easier to only run as a client, it is more beneficial to the Bitcoin
### 2. Client-Only network to run as both a client and a server so others may connect to you to as
you are connecting to them. We recommend you take the time to setup a Tor
<a name="ClientDescription" /> hidden service for this reason.
**2.1 Description**<br />
<a name="Client" />
Configuring btcd as a Tor client is straightforward. The first step is ### 2. Client-Only
obviously to install Tor and ensure it is working. Once that is done, all that
typically needs to be done is to specify the `--proxy` flag via the btcd command <a name="ClientDescription" />
line or in the btcd configuration file. Typically the Tor proxy address will be **2.1 Description**<br />
127.0.0.1:9050 (if using standalone Tor) or 127.0.0.1:9150 (if using the Tor
Browser Bundle). If you have Tor configured to require a username and password, Configuring btcd as a Tor client is straightforward. The first step is
you may specify them with the `--proxyuser` and `--proxypass` flags. obviously to install Tor and ensure it is working. Once that is done, all that
typically needs to be done is to specify the `--proxy` flag via the btcd command
By default, btcd assumes the proxy specified with `--proxy` is a Tor proxy and line or in the btcd configuration file. Typically the Tor proxy address will be
hence will send all traffic, including DNS resolution requests, via the 127.0.0.1:9050 (if using standalone Tor) or 127.0.0.1:9150 (if using the Tor
specified proxy. Browser Bundle). If you have Tor configured to require a username and password,
you may specify them with the `--proxyuser` and `--proxypass` flags.
NOTE: Specifying the `--proxy` flag disables listening by default since you will
not be reachable for inbound connections unless you also configure a Tor By default, btcd assumes the proxy specified with `--proxy` is a Tor proxy and
[hidden service](#HiddenService). hence will send all traffic, including DNS resolution requests, via the
specified proxy.
<a name="ClientCLIExample" />
**2.2 Command Line Example**<br /> NOTE: Specifying the `--proxy` flag disables listening by default since you will
not be reachable for inbound connections unless you also configure a Tor
```bash [hidden service](#HiddenService).
$ ./btcd --proxy=127.0.0.1:9050
``` <a name="ClientCLIExample" />
**2.2 Command Line Example**<br />
<a name="ClientConfigFileExample" />
**2.3 Config File Example**<br /> ```bash
$ ./btcd --proxy=127.0.0.1:9050
```text ```
[Application Options]
<a name="ClientConfigFileExample" />
proxy=127.0.0.1:9050 **2.3 Config File Example**<br />
```
```text
<a name="HiddenService" /> [Application Options]
### 3. Client-Server via Tor Hidden Service
proxy=127.0.0.1:9050
<a name="HiddenServiceDescription" /> ```
**3.1 Description**<br />
<a name="HiddenService" />
The first step is to configure Tor to provide a hidden service. Documentation ### 3. Client-Server via Tor Hidden Service
for this can be found on the Tor project website
[here](https://www.torproject.org/docs/tor-hidden-service.html.en). However, <a name="HiddenServiceDescription" />
there is no need to install a web server locally as the linked instructions **3.1 Description**<br />
discuss since btcd will act as the server.
The first step is to configure Tor to provide a hidden service. Documentation
In short, the instructions linked above entail modifying your `torrc` file to for this can be found on the Tor project website
add something similar to the following, restarting Tor, and opening the [here](https://www.torproject.org/docs/tor-hidden-service.html.en). However,
`hostname` file in the `HiddenServiceDir` to obtain your hidden service .onion there is no need to install a web server locally as the linked instructions
address. discuss since btcd will act as the server.
```text In short, the instructions linked above entail modifying your `torrc` file to
HiddenServiceDir /var/tor/btcd add something similar to the following, restarting Tor, and opening the
HiddenServicePort 8333 127.0.0.1:8333 `hostname` file in the `HiddenServiceDir` to obtain your hidden service .onion
``` address.
Once Tor is configured to provide the hidden service and you have obtained your ```text
generated .onion address, configuring btcd as a Tor hidden service requires HiddenServiceDir /var/tor/btcd
three flags: HiddenServicePort 8333 127.0.0.1:8333
* `--proxy` to identify the Tor (SOCKS 5) proxy to use for outgoing traffic. ```
This is typically 127.0.0.1:9050.
* `--listen` to enable listening for inbound connections since `--proxy` Once Tor is configured to provide the hidden service and you have obtained your
disables listening by default generated .onion address, configuring btcd as a Tor hidden service requires
* `--externalip` to set the .onion address that is advertised to other peers three flags:
* `--proxy` to identify the Tor (SOCKS 5) proxy to use for outgoing traffic.
<a name="HiddenServiceCLIExample" /> This is typically 127.0.0.1:9050.
**3.2 Command Line Example**<br /> * `--listen` to enable listening for inbound connections since `--proxy`
disables listening by default
```bash * `--externalip` to set the .onion address that is advertised to other peers
$ ./btcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion
``` <a name="HiddenServiceCLIExample" />
**3.2 Command Line Example**<br />
<a name="HiddenServiceConfigFileExample" />
**3.3 Config File Example**<br /> ```bash
$ ./btcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion
```text ```
[Application Options]
<a name="HiddenServiceConfigFileExample" />
proxy=127.0.0.1:9050 **3.3 Config File Example**<br />
listen=127.0.0.1
externalip=fooanon.onion ```text
``` [Application Options]
<a name="Bridge" /> proxy=127.0.0.1:9050
### 4. Bridge Mode (Not Anonymous) listen=127.0.0.1
externalip=fooanon.onion
<a name="BridgeDescription" /> ```
**4.1 Description**<br />
<a name="Bridge" />
btcd provides support for operating as a bridge between regular nodes and hidden ### 4. Bridge Mode (Not Anonymous)
service nodes. In particular this means only traffic which is directed to or
from a .onion address is sent through Tor while other traffic is sent normally. <a name="BridgeDescription" />
_As a result, this mode is **NOT** anonymous._ **4.1 Description**<br />
This mode works by specifying an onion-specific proxy, which is pointed at Tor, btcd provides support for operating as a bridge between regular nodes and hidden
by using the `--onion` flag via the btcd command line or in the btcd service nodes. In particular this means only traffic which is directed to or
configuration file. If you have Tor configured to require a username and from a .onion address is sent through Tor while other traffic is sent normally.
password, you may specify them with the `--onionuser` and `--onionpass` flags. _As a result, this mode is **NOT** anonymous._
NOTE: This mode will also work in conjunction with a hidden service which means This mode works by specifying an onion-specific proxy, which is pointed at Tor,
you could accept inbound connections both via the normal network and to your by using the `--onion` flag via the btcd command line or in the btcd
hidden service through the Tor network. To enable your hidden service in bridge configuration file. If you have Tor configured to require a username and
mode, you only need to specify your hidden service's .onion address via the password, you may specify them with the `--onionuser` and `--onionpass` flags.
`--externalip` flag since traffic to and from .onion addresses are already
routed via Tor due to the `--onion` flag. NOTE: This mode will also work in conjunction with a hidden service which means
you could accept inbound connections both via the normal network and to your
<a name="BridgeCLIExample" /> hidden service through the Tor network. To enable your hidden service in bridge
**4.2 Command Line Example**<br /> mode, you only need to specify your hidden service's .onion address via the
`--externalip` flag since traffic to and from .onion addresses are already
```bash routed via Tor due to the `--onion` flag.
$ ./btcd --onion=127.0.0.1:9050 --externalip=fooanon.onion
``` <a name="BridgeCLIExample" />
**4.2 Command Line Example**<br />
<a name="BridgeConfigFileExample" />
**4.3 Config File Example**<br /> ```bash
$ ./btcd --onion=127.0.0.1:9050 --externalip=fooanon.onion
```text ```
[Application Options]
<a name="BridgeConfigFileExample" />
onion=127.0.0.1:9050 **4.3 Config File Example**<br />
externalip=fooanon.onion
``` ```text
[Application Options]
onion=127.0.0.1:9050
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
```

View file

@ -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.