diff --git a/config.go b/config.go
index eb603dc8b9..63208b2142 100644
--- a/config.go
+++ b/config.go
@@ -95,6 +95,7 @@ type config struct {
OnionProxyUser string `long:"onionuser" description:"Username 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"`
+ 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"`
RegressionTest bool `long:"regtest" description:"Use the regression 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,
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
// specified options. The default is to use the standard net.Dial
// 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.lookup = net.LookupIP
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{
- Addr: cfg.Proxy,
- Username: cfg.ProxyUser,
- Password: cfg.ProxyPass,
+ Addr: cfg.Proxy,
+ Username: cfg.ProxyUser,
+ Password: cfg.ProxyPass,
+ TorIsolation: cfg.TorIsolation,
}
cfg.dial = proxy.Dial
if !cfg.NoOnion {
@@ -748,11 +775,27 @@ func loadConfig() (*config, []string, error) {
// This allows .onion address traffic to be routed through a different
// proxy than normal traffic.
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) {
proxy := &socks.Proxy{
- Addr: cfg.OnionProxy,
- Username: cfg.OnionProxyUser,
- Password: cfg.OnionProxyPass,
+ Addr: cfg.OnionProxy,
+ Username: cfg.OnionProxyUser,
+ Password: cfg.OnionProxyPass,
+ TorIsolation: cfg.TorIsolation,
}
return proxy.Dial(a, b)
}
diff --git a/doc.go b/doc.go
index fee4199c71..d98cd83089 100644
--- a/doc.go
+++ b/doc.go
@@ -63,7 +63,8 @@ Application Options:
--onionuser= Username for onion proxy server
--onionpass= Password for onion proxy server
--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
--regtest= Use the regression test network
--nocheckpoints= Disable built-in checkpoints. Don't do this unless
diff --git a/docs/configuring_tor.md b/docs/configuring_tor.md
index daffeaa620..d7afb87219 100644
--- a/docs/configuring_tor.md
+++ b/docs/configuring_tor.md
@@ -1,156 +1,190 @@
-### Table of Contents
-1. [Overview](#Overview)
-2. [Client-Only](#Client)
-2.1 [Description](#ClientDescription)
-2.2 [Command Line Example](#ClientCLIExample)
-2.3 [Config File Example](#ClientConfigFileExample)
-3. [Client-Server via Tor Hidden Service](#HiddenService)
-3.1 [Description](#HiddenServiceDescription)
-3.2 [Command Line Example](#HiddenServiceCLIExample)
-3.3 [Config File Example](#HiddenServiceConfigFileExample)
-4. [Bridge Mode (Not Anonymous)](#Bridge)
-4.1 [Description](#BridgeDescription)
-4.2 [Command Line Example](#BridgeCLIExample)
-4.3 [Config File Example](#BridgeConfigFileExample)
-
-
-### 1. Overview
-
-btcd provides full support for anonymous networking via the
-[Tor Project](https://www.torproject.org/), including [client-only](#Client)
-and [hidden service](#HiddenService) configurations. In addition, btcd supports
-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
-routing the regular connections through Tor.
-
-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
-you are connecting to them. We recommend you take the time to setup a Tor
-hidden service for this reason.
-
-
-### 2. Client-Only
-
-
-**2.1 Description**
-
-Configuring btcd as a Tor client is straightforward. The first step is
-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
-line or in the btcd configuration file. Typically the Tor proxy address will be
-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,
-you may specify them with the `--proxyuser` and `--proxypass` flags.
-
-By default, btcd assumes the proxy specified with `--proxy` is a Tor proxy and
-hence will send all traffic, including DNS resolution requests, via the
-specified proxy.
-
-NOTE: Specifying the `--proxy` flag disables listening by default since you will
-not be reachable for inbound connections unless you also configure a Tor
-[hidden service](#HiddenService).
-
-
-**2.2 Command Line Example**
-
-```bash
-$ ./btcd --proxy=127.0.0.1:9050
-```
-
-
-**2.3 Config File Example**
-
-```text
-[Application Options]
-
-proxy=127.0.0.1:9050
-```
-
-
-### 3. Client-Server via Tor Hidden Service
-
-
-**3.1 Description**
-
-The first step is to configure Tor to provide a hidden service. Documentation
-for this can be found on the Tor project website
-[here](https://www.torproject.org/docs/tor-hidden-service.html.en). However,
-there is no need to install a web server locally as the linked instructions
-discuss since btcd will act as the server.
-
-In short, the instructions linked above entail modifying your `torrc` file to
-add something similar to the following, restarting Tor, and opening the
-`hostname` file in the `HiddenServiceDir` to obtain your hidden service .onion
-address.
-
-```text
-HiddenServiceDir /var/tor/btcd
-HiddenServicePort 8333 127.0.0.1:8333
-```
-
-Once Tor is configured to provide the hidden service and you have obtained your
-generated .onion address, configuring btcd as a Tor hidden service requires
-three flags:
-* `--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`
- disables listening by default
-* `--externalip` to set the .onion address that is advertised to other peers
-
-
-**3.2 Command Line Example**
-
-```bash
-$ ./btcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion
-```
-
-
-**3.3 Config File Example**
-
-```text
-[Application Options]
-
-proxy=127.0.0.1:9050
-listen=127.0.0.1
-externalip=fooanon.onion
-```
-
-
-### 4. Bridge Mode (Not Anonymous)
-
-
-**4.1 Description**
-
-btcd provides support for operating as a bridge between regular nodes and hidden
-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.
-_As a result, this mode is **NOT** anonymous._
-
-This mode works by specifying an onion-specific proxy, which is pointed at Tor,
-by using the `--onion` flag via the btcd command line or in the btcd
-configuration file. If you have Tor configured to require a username and
-password, you may specify them with the `--onionuser` and `--onionpass` flags.
-
-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
-hidden service through the Tor network. To enable your hidden service in bridge
-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
-routed via Tor due to the `--onion` flag.
-
-
-**4.2 Command Line Example**
-
-```bash
-$ ./btcd --onion=127.0.0.1:9050 --externalip=fooanon.onion
-```
-
-
-**4.3 Config File Example**
-
-```text
-[Application Options]
-
-onion=127.0.0.1:9050
-externalip=fooanon.onion
-```
\ No newline at end of file
+### Table of Contents
+1. [Overview](#Overview)
+2. [Client-Only](#Client)
+2.1 [Description](#ClientDescription)
+2.2 [Command Line Example](#ClientCLIExample)
+2.3 [Config File Example](#ClientConfigFileExample)
+3. [Client-Server via Tor Hidden Service](#HiddenService)
+3.1 [Description](#HiddenServiceDescription)
+3.2 [Command Line Example](#HiddenServiceCLIExample)
+3.3 [Config File Example](#HiddenServiceConfigFileExample)
+4. [Bridge Mode (Not Anonymous)](#Bridge)
+4.1 [Description](#BridgeDescription)
+4.2 [Command Line Example](#BridgeCLIExample)
+4.3 [Config File Example](#BridgeConfigFileExample)
+5. [Tor Stream Isolation](#TorStreamIsolation)
+5.1 [Description](#TorStreamIsolationDescription)
+5.2 [Command Line Example](#TorStreamIsolationCLIExample)
+5.3 [Config File Example](#TorStreamIsolationFileExample)
+
+
+### 1. Overview
+
+btcd provides full support for anonymous networking via the
+[Tor Project](https://www.torproject.org/), including [client-only](#Client)
+and [hidden service](#HiddenService) configurations along with
+[stream isolation](#TorStreamIsolation). In addition, btcd supports 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 routing the
+regular connections through Tor.
+
+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
+you are connecting to them. We recommend you take the time to setup a Tor
+hidden service for this reason.
+
+
+### 2. Client-Only
+
+
+**2.1 Description**
+
+Configuring btcd as a Tor client is straightforward. The first step is
+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
+line or in the btcd configuration file. Typically the Tor proxy address will be
+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,
+you may specify them with the `--proxyuser` and `--proxypass` flags.
+
+By default, btcd assumes the proxy specified with `--proxy` is a Tor proxy and
+hence will send all traffic, including DNS resolution requests, via the
+specified proxy.
+
+NOTE: Specifying the `--proxy` flag disables listening by default since you will
+not be reachable for inbound connections unless you also configure a Tor
+[hidden service](#HiddenService).
+
+
+**2.2 Command Line Example**
+
+```bash
+$ ./btcd --proxy=127.0.0.1:9050
+```
+
+
+**2.3 Config File Example**
+
+```text
+[Application Options]
+
+proxy=127.0.0.1:9050
+```
+
+
+### 3. Client-Server via Tor Hidden Service
+
+
+**3.1 Description**
+
+The first step is to configure Tor to provide a hidden service. Documentation
+for this can be found on the Tor project website
+[here](https://www.torproject.org/docs/tor-hidden-service.html.en). However,
+there is no need to install a web server locally as the linked instructions
+discuss since btcd will act as the server.
+
+In short, the instructions linked above entail modifying your `torrc` file to
+add something similar to the following, restarting Tor, and opening the
+`hostname` file in the `HiddenServiceDir` to obtain your hidden service .onion
+address.
+
+```text
+HiddenServiceDir /var/tor/btcd
+HiddenServicePort 8333 127.0.0.1:8333
+```
+
+Once Tor is configured to provide the hidden service and you have obtained your
+generated .onion address, configuring btcd as a Tor hidden service requires
+three flags:
+* `--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`
+ disables listening by default
+* `--externalip` to set the .onion address that is advertised to other peers
+
+
+**3.2 Command Line Example**
+
+```bash
+$ ./btcd --proxy=127.0.0.1:9050 --listen=127.0.0.1 --externalip=fooanon.onion
+```
+
+
+**3.3 Config File Example**
+
+```text
+[Application Options]
+
+proxy=127.0.0.1:9050
+listen=127.0.0.1
+externalip=fooanon.onion
+```
+
+
+### 4. Bridge Mode (Not Anonymous)
+
+
+**4.1 Description**
+
+btcd provides support for operating as a bridge between regular nodes and hidden
+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.
+_As a result, this mode is **NOT** anonymous._
+
+This mode works by specifying an onion-specific proxy, which is pointed at Tor,
+by using the `--onion` flag via the btcd command line or in the btcd
+configuration file. If you have Tor configured to require a username and
+password, you may specify them with the `--onionuser` and `--onionpass` flags.
+
+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
+hidden service through the Tor network. To enable your hidden service in bridge
+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
+routed via Tor due to the `--onion` flag.
+
+
+**4.2 Command Line Example**
+
+```bash
+$ ./btcd --onion=127.0.0.1:9050 --externalip=fooanon.onion
+```
+
+
+**4.3 Config File Example**
+
+```text
+[Application Options]
+
+onion=127.0.0.1:9050
+externalip=fooanon.onion
+```
+
+
+### 5. Tor Stream Isolation
+
+
+**5.1 Description**
+
+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.
+
+
+**5.2 Command Line Example**
+
+```bash
+$ ./btcd --proxy=127.0.0.1:9050 --torisolation
+```
+
+
+**5.3 Config File Example**
+
+```text
+[Application Options]
+
+proxy=127.0.0.1:9050
+torisolation=1
+```
diff --git a/sample-btcd.conf b/sample-btcd.conf
index c9ea886b3c..515a1fc9f2 100644
--- a/sample-btcd.conf
+++ b/sample-btcd.conf
@@ -41,6 +41,11 @@
; onionuser=
; 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
; and obtain the external IP address from supported devices. NOTE: This option
; will have no effect if exernal IP addresses are specified.