Compare commits

...

1 Commits

Author SHA1 Message Date
effbf169d3 Use Tor Http Proxy instead of our internal hack one 2020-06-10 13:21:36 +09:00
8 changed files with 55 additions and 23 deletions

View File

@ -147,6 +147,10 @@ namespace BTCPayServer.Tests
config.AppendLine($"socksendpoint={SocksEndpoint}");
config.AppendLine($"debuglog=debug.log");
if (SocksHTTPProxy is string v)
{
config.AppendLine($"sockshttpproxy={v}");
}
if (!string.IsNullOrEmpty(SSHPassword) && string.IsNullOrEmpty(SSHKeyFile))
config.AppendLine($"sshpassword={SSHPassword}");
@ -291,6 +295,8 @@ namespace BTCPayServer.Tests
public string SSHPassword { get; internal set; }
public string SSHKeyFile { get; internal set; }
public string SSHConnection { get; set; }
public string SocksHTTPProxy { get; set; }
public T GetController<T>(string userId = null, string storeId = null, bool isAdmin = false) where T : Controller
{
var context = new DefaultHttpContext();

View File

@ -56,6 +56,7 @@ namespace BTCPayServer.Tests
// TODO: The fact that we use same conn string as development database can cause huge problems with tests
// since in dev we already can have some users / stores registered, while on CI database is being initalized
// for the first time and first registered user gets admin status by default
SocksHTTPProxy = GetEnvironment("TESTS_SOCKSHTTP", "http://127.0.0.1:8118/"),
Postgres = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver"),
MySQL = GetEnvironment("TESTS_MYSQL", "User ID=root;Host=127.0.0.1;Port=33036;Database=btcpayserver")
};

View File

@ -989,12 +989,16 @@ namespace BTCPayServer.Tests
}
[Fact(Timeout = TestTimeout)]
[Trait("Integration", "Integration")]
public async Task CanUseTorClient()
[Theory(Timeout = TestTimeout)]
[Xunit.InlineData(true)]
[Xunit.InlineData(false)]
public async Task CanUseTorClient(bool useInternalTorSocksProxy)
{
using (var tester = ServerTester.Create())
{
if (useInternalTorSocksProxy)
tester.PayTester.SocksHTTPProxy = null;
await tester.StartAsync();
var proxy = tester.PayTester.GetService<Socks5HttpProxyServer>();
void AssertConnectionDropped()

View File

@ -12,6 +12,7 @@ services:
environment:
TESTS_BTCRPCCONNECTION: server=http://bitcoind:43782;ceiwHEbqWI83:DwubwWsoo3
TESTS_LTCRPCCONNECTION: server=http://litecoind:43782;ceiwHEbqWI83:DwubwWsoo3
TESTS_SOCKSHTTP: http://tor:8118/
TESTS_BTCNBXPLORERURL: http://nbxplorer:32838/
TESTS_LTCNBXPLORERURL: http://nbxplorer:32838/
TESTS_DB: "Postgres"
@ -328,9 +329,13 @@ services:
container_name: tor
environment:
TOR_PASSWORD: btcpayserver
TOR_EXTRA_ARGS: |
CookieAuthentication 1
HTTPTunnelPort 0.0.0.0:8118
ports:
- "9050:9050" # SOCKS
- "9051:9051" # Tor Control
- "8118:8118" # HTTP Proxy
volumes:
- "tor_datadir:/home/tor/.tor"
- "torrcdir:/usr/local/etc/tor"

View File

@ -43,7 +43,7 @@ namespace BTCPayServer.Configuration
private set;
}
public EndPoint SocksEndpoint { get; set; }
public Uri SocksHttpProxy { get; set; }
public List<NBXplorerConnectionSetting> NBXplorerConnectionSettings
{
get;
@ -171,7 +171,11 @@ namespace BTCPayServer.Configuration
throw new ConfigException("Invalid value for socksendpoint");
SocksEndpoint = endpoint;
}
var socksuri = conf.GetOrDefault<Uri>("sockshttpproxy", null);
if (socksuri != null)
{
SocksHttpProxy = socksuri;
}
var sshSettings = ParseSSHConfiguration(conf);
if ((!string.IsNullOrEmpty(sshSettings.Password) || !string.IsNullOrEmpty(sshSettings.KeyFile)) && !string.IsNullOrEmpty(sshSettings.Server))

View File

@ -44,6 +44,7 @@ namespace BTCPayServer.Configuration
app.Option("--sshtrustedfingerprints", "SSH Host public key fingerprint or sha256 (default: empty, it will allow untrusted connections)", CommandOptionType.SingleValue);
app.Option("--torrcfile", "Path to torrc file containing hidden services directories (default: empty)", CommandOptionType.SingleValue);
app.Option("--socksendpoint", "Socks endpoint to connect to onion urls (default: empty)", CommandOptionType.SingleValue);
app.Option("--sockshttpproxy", "Socks v5 HTTP proxy, this is currently used only for sending payjoin to tor endpoints. You can get a socks http proxy with the HTTPTunnelPort setting on Tor 0.3.2.x. (default: empty)", CommandOptionType.SingleValue);
app.Option("--debuglog", "A rolling log file for debug messages.", CommandOptionType.SingleValue);
app.Option("--debugloglevel", "The severity you log (default:information)", CommandOptionType.SingleValue);
app.Option("--disable-registration", "Disables new user registrations (default:true)", CommandOptionType.SingleValue);

View File

@ -62,23 +62,32 @@ namespace BTCPayServer.HostedServices
{
if (_opts.SocksEndpoint is null || _ServerContext != null)
return Task.CompletedTask;
_Cts = new CancellationTokenSource();
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
Port = ((IPEndPoint)(socket.LocalEndPoint)).Port;
Uri = new Uri($"http://127.0.0.1:{Port}");
socket.Listen(5);
_ServerContext = new ServerContext()
if (_opts.SocksHttpProxy is Uri uri)
{
SocksEndpoint = _opts.SocksEndpoint,
ServerSocket = socket,
CancellationToken = _Cts.Token,
ConnectionCount = 0
};
socket.BeginAccept(Accept, _ServerContext);
Logs.PayServer.LogInformation($"Internal Socks HTTP Proxy listening at {Uri}");
return Task.CompletedTask;
Logs.PayServer.LogInformation($"sockshttpproxy is set, we will be using a socks http proxy at {uri.AbsoluteUri}");
return Task.CompletedTask;
}
else
{
Logs.PayServer.LogInformation($"sockshttpproxy is not set, we will be using an internal socks http proxy");
_Cts = new CancellationTokenSource();
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
Port = ((IPEndPoint)(socket.LocalEndPoint)).Port;
Uri = new Uri($"http://127.0.0.1:{Port}");
socket.Listen(5);
_ServerContext = new ServerContext()
{
SocksEndpoint = _opts.SocksEndpoint,
ServerSocket = socket,
CancellationToken = _Cts.Token,
ConnectionCount = 0
};
socket.BeginAccept(Accept, _ServerContext);
Logs.PayServer.LogInformation($"Internal Socks HTTP Proxy listening at {Uri}");
return Task.CompletedTask;
}
}
public int Port { get; private set; }

View File

@ -1,14 +1,16 @@
using System.Net;
using System;
using System.Net;
using System.Net.Http;
using BTCPayServer.Configuration;
using BTCPayServer.HostedServices;
namespace BTCPayServer.Services
{
public class Socks5HttpClientHandler : HttpClientHandler
{
public Socks5HttpClientHandler(Socks5HttpProxyServer sock5)
public Socks5HttpClientHandler(BTCPayServerOptions opts, Socks5HttpProxyServer sock5)
{
this.Proxy = new WebProxy(sock5.Uri);
this.Proxy = new WebProxy(sock5.Uri ?? opts.SocksHttpProxy);
}
}
}