mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
Merge pull request #737 from Roasbeef/tor-docs
tor: add stream isolation, additional documentation, neutrino support
This commit is contained in:
commit
9709e5f31f
@ -174,6 +174,27 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB,
|
||||
ChainParams: *activeNetParams.Params,
|
||||
AddPeers: cfg.NeutrinoMode.AddPeers,
|
||||
ConnectPeers: cfg.NeutrinoMode.ConnectPeers,
|
||||
Dialer: func(addr net.Addr) (net.Conn, error) {
|
||||
return cfg.net.Dial(addr.Network(), addr.String())
|
||||
},
|
||||
NameResolver: func(host string) ([]net.IP, error) {
|
||||
addrs, err := cfg.net.LookupHost(host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ips := make([]net.IP, 0, len(addrs))
|
||||
for _, strIP := range addrs {
|
||||
ip := net.ParseIP(strIP)
|
||||
if ip == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
},
|
||||
}
|
||||
neutrino.WaitForMoreCFHeaders = time.Second * 1
|
||||
neutrino.MaxPeers = 8
|
||||
|
10
config.go
10
config.go
@ -134,8 +134,9 @@ type autoPilotConfig struct {
|
||||
}
|
||||
|
||||
type torConfig struct {
|
||||
Socks string `long:"socks" description:"The port that Tor's exposed SOCKS5 proxy is listening on. Using Tor allows outbound-only connections (listening will be disabled) -- NOTE port must be between 1024 and 65535"`
|
||||
DNS string `long:"dns" description:"The DNS server as IP:PORT that Tor will use for SRV queries - NOTE must have TCP resolution enabled"`
|
||||
Socks string `long:"socks" description:"The port that Tor's exposed SOCKS5 proxy is listening on. Using Tor allows outbound-only connections (listening will be disabled) -- NOTE port must be between 1024 and 65535"`
|
||||
DNS string `long:"dns" description:"The DNS server as IP:PORT that Tor will use for SRV queries - NOTE must have TCP resolution enabled"`
|
||||
StreamIsolation bool `long:"streamisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."`
|
||||
}
|
||||
|
||||
// config defines the configuration options for lnd.
|
||||
@ -325,8 +326,9 @@ func loadConfig() (*config, error) {
|
||||
}
|
||||
|
||||
cfg.net = &torsvc.TorProxyNet{
|
||||
TorDNS: cfg.Tor.DNS,
|
||||
TorSocks: cfg.Tor.Socks,
|
||||
TorDNS: cfg.Tor.DNS,
|
||||
TorSocks: cfg.Tor.Socks,
|
||||
StreamIsolation: cfg.Tor.StreamIsolation,
|
||||
}
|
||||
|
||||
// If we are using Tor, since we only want connections routed
|
||||
|
120
docs/configuring_tor.md
Normal file
120
docs/configuring_tor.md
Normal file
@ -0,0 +1,120 @@
|
||||
# Table of Contents
|
||||
1. [Overview](#Overview)
|
||||
2. [Outbound Connections Only](#outbound-connections-only)
|
||||
3. [Tor Stream Isolation](#tor-stream-isolation)
|
||||
|
||||
## 1. Overview
|
||||
|
||||
`lnd` currently has _partial_ support for using Lightning over
|
||||
[Tor](https://www.torproject.org/). Usage of Lightning over Tor is valuable as
|
||||
routing nodes no longer need to potentially expose their location via their
|
||||
advertised IP address. Additionally, leaf nodes can also protect their location
|
||||
by using Tor for anonymous networking to establish connections.
|
||||
|
||||
At the time of the writing of this documentation, `lnd` only supports usage of
|
||||
Tor for establishing _outbound_ connections. In the near future, support for
|
||||
full [Onion Service](https://www.torproject.org/docs/onion-services.html.en)
|
||||
usage will be added as well. Support for both `v2` and `v3` onion services are
|
||||
planned. With widespread usage of Onion Services within the network, concerns
|
||||
about the difficulty of proper NAT traversal are alleviated, as usage of Onion
|
||||
Services allows nodes to accept inbound connections even if they're behind a
|
||||
NAT.
|
||||
|
||||
Before following the remainder of this documentation, you should ensure that
|
||||
you already have Tor installed locally. Official instructions to install the
|
||||
latest release of Tor can be found
|
||||
[here](https://www.torproject.org/docs/tor-doc-unix.html.en).
|
||||
|
||||
**NOTE**: This documentation covers how to ensure that `lnd`'s _Lightning
|
||||
protocol traffic_ is tunnled over Tor. Users will need to take care that if
|
||||
they're running using a Bitcoin full-node, then that is also configured to
|
||||
proxy all trafic over Tor. If using the `neutrino` backend for `lnd`, then it
|
||||
will automatically also default to Tor usage if active within `lnd`.
|
||||
|
||||
|
||||
## 2. Outbound Connections Only
|
||||
|
||||
Currenty, `lnd` only supports purely _outbound_ Tor usage. In this mode, `lnd`
|
||||
_won't_ listen at all, and will only be able to establish outbound connections.
|
||||
_All_ protocol traffic will be tunneled over Tor. Additionally, we'll also
|
||||
force any DNS requests over Tor such that we don't leak our IP address to the
|
||||
clear net.
|
||||
|
||||
The remainder of this tutorial assumes one already has the `tor` daemon
|
||||
installed locally.
|
||||
|
||||
First, you'll want to run `tor` locally before starting up `lnd`. Depending on
|
||||
how you installed Tor, you'll find the configuration file at
|
||||
`/usr/local/etc/tor/torrc`. Here's an example configuration file that we'll be
|
||||
using for the remainder of the tutorial:
|
||||
```
|
||||
SOCKSPort 9050 # Default: Bind to localhost:9050 for local connections.
|
||||
Log notice stdout
|
||||
ControlPort 9051
|
||||
CookieAuthentication 1
|
||||
```
|
||||
|
||||
With the configuration file created, you'll then want to start the Tor daemon:
|
||||
```
|
||||
⛰ tor
|
||||
Feb 05 17:02:06.501 [notice] Tor 0.3.1.8 (git-ad5027f7dc790624) running on Darwin with Libevent 2.1.8-stable, OpenSSL 1.0.2l, Zlib 1.2.8, Liblzma N/A, and Libzstd N/A.
|
||||
Feb 05 17:02:06.502 [notice] Tor can't help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning
|
||||
Feb 05 17:02:06.502 [notice] Read configuration file "/usr/local/etc/tor/torrc".
|
||||
Feb 05 17:02:06.506 [notice] Opening Socks listener on 127.0.0.1:9050
|
||||
Feb 05 17:02:06.506 [notice] Opening Control listener on 127.0.0.1:9051
|
||||
```
|
||||
|
||||
Once the `tor` daemon has started and it has finished bootstrapping, you'll see this in the logs:
|
||||
```
|
||||
Feb 05 17:02:06.000 [notice] Bootstrapped 0%: Starting
|
||||
Feb 05 17:02:07.000 [notice] Starting with guard context "default"
|
||||
Feb 05 17:02:07.000 [notice] Bootstrapped 80%: Connecting to the Tor network
|
||||
Feb 05 17:02:07.000 [notice] Bootstrapped 85%: Finishing handshake with first hop
|
||||
Feb 05 17:02:08.000 [notice] Bootstrapped 90%: Establishing a Tor circuit
|
||||
Feb 05 17:02:11.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
|
||||
Feb 05 17:02:11.000 [notice] Bootstrapped 100%: Done
|
||||
```
|
||||
|
||||
This indicates the daemon is fully bootstrapped and ready to proxy connections.
|
||||
At this point, we can now start `lnd` with the relevant arguments:
|
||||
|
||||
```
|
||||
⛰ ./lnd -h
|
||||
|
||||
<snip>
|
||||
|
||||
Tor:
|
||||
--tor.socks= The port that Tor's exposed SOCKS5 proxy is listening on. Using Tor allows outbound-only connections (listening will be disabled) -- NOTE port must be between 1024 and 65535
|
||||
--tor.dns= The DNS server as IP:PORT that Tor will use for SRV queries - NOTE must have TCP resolution enabled
|
||||
```
|
||||
|
||||
The `--tor.socks` argument should point to the interface that the `Tor` daemon
|
||||
is listening on to proxy connections. The `--tor.dns` flag is required in order
|
||||
to be able to properly automatically bootstrap a set of peer connections. The
|
||||
`tor` daemon doesn't currently support proxying `SRV` queries over Tor. So
|
||||
instead, we need to connect directly to the authoritative DNS server over TCP,
|
||||
in order query for `SRV` records that we can use to bootstrap our connections.
|
||||
As of the time this documentation was written, for Bitcoin's Testnet, clients
|
||||
should point to `nodes.lightning.directory`.
|
||||
|
||||
Finally, we'll start `lnd` with the proper arguments:
|
||||
```
|
||||
⛰ ./lnd --tor.socks=9050 --tor.dns=nodes.lightning.directory
|
||||
```
|
||||
|
||||
With the above arguments, `lnd` will proxy _all_ network traffic over Tor!
|
||||
|
||||
|
||||
## 3. Tor Stream Isolation
|
||||
|
||||
Our support for Tor also has an additional privacy enhancing modified: stream
|
||||
isolation. Usage of this mode means that Tor will always use _new circuit_ for
|
||||
each connection. This added features means that it's harder to correlate
|
||||
connections. As otherwise, several applications using Tor might share the same
|
||||
circuit.
|
||||
|
||||
Activating stream isolation is very straightforward, we only require the
|
||||
specification of an additional argument:
|
||||
```
|
||||
⛰ ./lnd --tor.socks=9050 --tor.dns=nodes.lightning.directory --tor.streamisolation
|
||||
```
|
6
glide.lock
generated
6
glide.lock
generated
@ -1,5 +1,5 @@
|
||||
hash: a69cfd6352bed3cc0d24a01f42609b849f9f6d5664be7470b281bf6b09c58d84
|
||||
updated: 2018-02-06T17:14:31.208312805-08:00
|
||||
hash: 63c0706e71ebdd4664e6a452bf58035571a8799b24e517ea0d8aa2fb8dd94155
|
||||
updated: 2018-02-08T15:26:31.423935935-08:00
|
||||
imports:
|
||||
- name: github.com/aead/chacha20
|
||||
version: d31a916ded42d1640b9d89a26f8abd53cc96790c
|
||||
@ -72,7 +72,7 @@ imports:
|
||||
- name: github.com/lightninglabs/gozmq
|
||||
version: 0d266ba6d55ea65c18c7a02d8992c89355149e80
|
||||
- name: github.com/lightninglabs/neutrino
|
||||
version: 6c8f30a130bb170348ceb754ce4204156efe2741
|
||||
version: c933ad49936ac3e5bc1b42e855f2da69745e34cc
|
||||
subpackages:
|
||||
- filterdb
|
||||
- headerfs
|
||||
|
@ -73,7 +73,7 @@ import:
|
||||
subpackages:
|
||||
- chaincfg
|
||||
- package: github.com/lightninglabs/neutrino
|
||||
version: 6c8f30a130bb170348ceb754ce4204156efe2741
|
||||
version: c933ad49936ac3e5bc1b42e855f2da69745e34cc
|
||||
- package: gopkg.in/macaroon.v2
|
||||
- package: gopkg.in/macaroon-bakery.v2
|
||||
- package: github.com/juju/loggo
|
||||
|
7
lnd.go
7
lnd.go
@ -251,6 +251,13 @@ func lndMain() error {
|
||||
}
|
||||
idPrivKey.Curve = btcec.S256()
|
||||
|
||||
if cfg.Tor.Socks != "" && cfg.Tor.DNS != "" {
|
||||
srvrLog.Infof("Proxying all network traffic via Tor "+
|
||||
"(stream_isolation=%v)! NOTE: If running with a full-node "+
|
||||
"backend, ensure that is proxying over Tor as well",
|
||||
cfg.Tor.StreamIsolation)
|
||||
}
|
||||
|
||||
// Set up the core server which will listen for incoming peer
|
||||
// connections.
|
||||
server, err := newServer(cfg.Listeners, chanDB, activeChainControl,
|
||||
|
@ -1700,7 +1700,6 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
|
||||
neutrino.Config{
|
||||
DataDir: tempTestDirAlice,
|
||||
Database: aliceDB,
|
||||
Namespace: []byte("alice"),
|
||||
ChainParams: *netParams,
|
||||
ConnectPeers: []string{
|
||||
miningNode.P2PAddress(),
|
||||
@ -1726,7 +1725,6 @@ func runTests(t *testing.T, walletDriver *lnwallet.WalletDriver,
|
||||
neutrino.Config{
|
||||
DataDir: tempTestDirBob,
|
||||
Database: bobDB,
|
||||
Namespace: []byte("bob"),
|
||||
ChainParams: *netParams,
|
||||
ConnectPeers: []string{
|
||||
miningNode.P2PAddress(),
|
||||
|
@ -261,3 +261,20 @@ litecoin.node=btcd
|
||||
; within the wallet should be used to automatically establish channels. The total
|
||||
; amount of attempted channels will still respect the maxchannels param.
|
||||
; autopilot.allocation=0.6
|
||||
|
||||
[tor]
|
||||
; The port that Tor's exposed SOCKS5 proxy is listening on. Using Tor allows
|
||||
; outbound-only connections (listening will be disabled) -- NOTE port must be
|
||||
; between 1024 and 65535
|
||||
; tor.socks=9050
|
||||
|
||||
; The DNS server as IP:PORT that Tor will use for SRV queries - NOTE must have
|
||||
; TCP resolution enabled. The current active DNS sever for Testnet listening is
|
||||
; nodes.lightning.directory
|
||||
; tor.dns=nodes.lightning.directory
|
||||
|
||||
; Enable Tor stream isolation by randomizing user credentials for each
|
||||
; connection. With this mode active, each connection will use a new circuit.
|
||||
; This means that multiple applications (other than lnd) using Tor won't be mixed
|
||||
; in with lnd's traffic.
|
||||
; tor.streamisolation=1
|
||||
|
@ -39,6 +39,12 @@ type TorProxyNet struct {
|
||||
// This is used for an outbound-only mode, so the node will not listen for
|
||||
// incoming connections
|
||||
TorSocks string
|
||||
|
||||
// StreamIsolation is a bool that determines if we should force the
|
||||
// creation of a new circuit for this connection. If true, then this
|
||||
// means that our traffic may be harder to correlate as each connection
|
||||
// will now use a distinct circuit.
|
||||
StreamIsolation bool
|
||||
}
|
||||
|
||||
// Dial on the Tor network uses the torsvc TorDial() function, and requires
|
||||
@ -47,7 +53,7 @@ func (t *TorProxyNet) Dial(network, address string) (net.Conn, error) {
|
||||
if network != "tcp" {
|
||||
return nil, fmt.Errorf("Cannot dial non-tcp network via Tor")
|
||||
}
|
||||
return TorDial(address, t.TorSocks)
|
||||
return TorDial(address, t.TorSocks, t.StreamIsolation)
|
||||
}
|
||||
|
||||
// LookupHost on Tor network uses the torsvc TorLookupHost function.
|
||||
|
@ -44,9 +44,16 @@ var (
|
||||
)
|
||||
|
||||
// TorDial returns a connection to a remote peer via Tor's socks proxy. Only
|
||||
// TCP is supported over Tor.
|
||||
func TorDial(address, socksPort string) (net.Conn, error) {
|
||||
p := &socks.Proxy{Addr: localhost + ":" + socksPort}
|
||||
// TCP is supported over Tor. The final argument determines if we should force
|
||||
// stream isolation for this new connection. If we do, then this means this new
|
||||
// connection will use a fresh circuit, rather than possibly re-using an
|
||||
// existing circuit.
|
||||
func TorDial(address, socksPort string, streamIsolation bool) (net.Conn, error) {
|
||||
p := &socks.Proxy{
|
||||
Addr: localhost + ":" + socksPort,
|
||||
TorIsolation: streamIsolation,
|
||||
}
|
||||
|
||||
return p.Dial("tcp", address)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user