Skip to content

Commit 5b732d9

Browse files
committed
loopd: add SOCKS proxy config option to dial swap server over Tor
This allows Loop users to further improve their privacy by not revealing their source IP address. Note that the identity of the lnd node behind Loop can still be revealed when performing a Loop In due to the swap server extending an off-chain HTLC to the user. Onion addresses don't yet exist for the swap servers, but they will be added at a later time.
1 parent a473ab5 commit 5b732d9

File tree

5 files changed

+29
-11
lines changed

5 files changed

+29
-11
lines changed

client.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type Client struct {
7878
}
7979

8080
// NewClient returns a new instance to initiate swaps with.
81-
func NewClient(dbDir string, serverAddress string, insecure bool,
81+
func NewClient(dbDir string, serverAddress, proxyAddress string, insecure bool,
8282
tlsPathServer string, lnd *lndclient.LndServices, maxLSATCost,
8383
maxLSATFee btcutil.Amount) (*Client, func(), error) {
8484

@@ -92,8 +92,8 @@ func NewClient(dbDir string, serverAddress string, insecure bool,
9292
}
9393

9494
swapServerClient, err := newSwapServerClient(
95-
serverAddress, insecure, tlsPathServer, lsatStore, lnd,
96-
maxLSATCost, maxLSATFee,
95+
serverAddress, proxyAddress, insecure, tlsPathServer, lsatStore,
96+
lnd, maxLSATCost, maxLSATFee,
9797
)
9898
if err != nil {
9999
return nil, nil, err

loopd/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ type config struct {
4545
MaxLSATCost uint32 `long:"maxlsatcost" description:"Maximum cost in satoshis that loopd is going to pay for an LSAT token automatically. Does not include routing fees."`
4646
MaxLSATFee uint32 `long:"maxlsatfee" description:"Maximum routing fee in satoshis that we are willing to pay while paying for an LSAT token."`
4747

48-
Lnd *lndConfig `group:"lnd" namespace:"lnd"`
48+
Lnd *lndConfig `group:"lnd" namespace:"lnd"`
49+
Proxy string `long:"proxy" description:"The host:port of a SOCKS proxy through which all connections to the swap server will be established over."`
4950

5051
View viewParameters `command:"view" alias:"v" description:"View all swaps in the database. This command can only be executed when loopd is not running."`
5152
}

loopd/daemon.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ func daemon(config *config, lisCfg *listenerCfg) error {
5050
// If no swap server is specified, use the default addresses for mainnet
5151
// and testnet.
5252
if config.SwapServer == "" {
53+
// TODO(wilmer): Use onion service addresses when proxy is
54+
// active.
5355
switch config.Network {
5456
case "mainnet":
5557
config.SwapServer = mainnetServer

loopd/utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func getClient(config *config, lnd *lndclient.LndServices) (*loop.Client,
1919
}
2020

2121
swapClient, cleanUp, err := loop.NewClient(
22-
storeDir, config.SwapServer, config.Insecure,
22+
storeDir, config.SwapServer, config.Proxy, config.Insecure,
2323
config.TLSPathSwapSrv, lnd, btcutil.Amount(config.MaxLSATCost),
2424
btcutil.Amount(config.MaxLSATFee),
2525
)

swap_server_client.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/hex"
77
"errors"
88
"fmt"
9+
"net"
910
"time"
1011

1112
"github.com/btcsuite/btcd/btcec"
@@ -15,6 +16,7 @@ import (
1516
"github.com/lightninglabs/loop/lsat"
1617
"github.com/lightningnetwork/lnd/lntypes"
1718
"github.com/lightningnetwork/lnd/routing/route"
19+
"github.com/lightningnetwork/lnd/tor"
1820
"google.golang.org/grpc"
1921
"google.golang.org/grpc/credentials"
2022
)
@@ -52,8 +54,8 @@ type grpcSwapServerClient struct {
5254

5355
var _ swapServerClient = (*grpcSwapServerClient)(nil)
5456

55-
func newSwapServerClient(address string, insecure bool, tlsPath string,
56-
lsatStore lsat.Store, lnd *lndclient.LndServices,
57+
func newSwapServerClient(address, proxyAddress string, insecure bool,
58+
tlsPath string, lsatStore lsat.Store, lnd *lndclient.LndServices,
5759
maxLSATCost, maxLSATFee btcutil.Amount) (*grpcSwapServerClient, error) {
5860

5961
// Create the server connection with the interceptor that will handle
@@ -62,7 +64,7 @@ func newSwapServerClient(address string, insecure bool, tlsPath string,
6264
lnd, lsatStore, serverRPCTimeout, maxLSATCost, maxLSATFee,
6365
)
6466
serverConn, err := getSwapServerConn(
65-
address, insecure, tlsPath, clientInterceptor,
67+
address, proxyAddress, insecure, tlsPath, clientInterceptor,
6668
)
6769
if err != nil {
6870
return nil, err
@@ -243,9 +245,11 @@ func (s *grpcSwapServerClient) Close() {
243245
s.conn.Close()
244246
}
245247

246-
// getSwapServerConn returns a connection to the swap server.
247-
func getSwapServerConn(address string, insecure bool, tlsPath string,
248-
interceptor *lsat.Interceptor) (*grpc.ClientConn, error) {
248+
// getSwapServerConn returns a connection to the swap server. A non-empty
249+
// proxyAddr indicates that a SOCKS proxy found at the address should be used to
250+
// establish the connection.
251+
func getSwapServerConn(address, proxyAddress string, insecure bool,
252+
tlsPath string, interceptor *lsat.Interceptor) (*grpc.ClientConn, error) {
249253

250254
// Create a dial options array.
251255
opts := []grpc.DialOption{grpc.WithUnaryInterceptor(
@@ -273,6 +277,17 @@ func getSwapServerConn(address string, insecure bool, tlsPath string,
273277
opts = append(opts, grpc.WithTransportCredentials(creds))
274278
}
275279

280+
// If a SOCKS proxy address was specified, then we should dial through
281+
// it.
282+
if proxyAddress != "" {
283+
log.Infof("Proxying connection to %v over Tor SOCKS proxy %v",
284+
address, proxyAddress)
285+
torDialer := func(_ context.Context, addr string) (net.Conn, error) {
286+
return tor.Dial(addr, proxyAddress, false)
287+
}
288+
opts = append(opts, grpc.WithContextDialer(torDialer))
289+
}
290+
276291
conn, err := grpc.Dial(address, opts...)
277292
if err != nil {
278293
return nil, fmt.Errorf("unable to connect to RPC server: %v",

0 commit comments

Comments
 (0)