diff --git a/NOnion.Tests/HiddenServicesTests.cs b/NOnion.Tests/HiddenServicesTests.cs index f75c1473..72ddbd2e 100644 --- a/NOnion.Tests/HiddenServicesTests.cs +++ b/NOnion.Tests/HiddenServicesTests.cs @@ -16,6 +16,7 @@ using NOnion.Network; using NOnion.Http; using NOnion.Cells.Relay; +using NOnion.Client; using NOnion.Directory; using NOnion.Tests.Utility; using NOnion.Services; @@ -24,6 +25,23 @@ namespace NOnion.Tests { public class HiddenServicesTests { + [OneTimeSetUp] + public void Init() + { + cachePath = + new DirectoryInfo( + Path.Combine( + Path.GetTempPath(), + Path.GetFileNameWithoutExtension( + Path.GetRandomFileName() + ) + ) + ); + cachePath.Create(); + } + + private DirectoryInfo cachePath = null; + /* It's possible that the router returned by GetRandomFallbackDirectory or * GetRandomRoutersForDirectoryBrowsing be inaccessable so we need to continue * retrying if an exceptions happened to make sure the issues are not related @@ -33,11 +51,8 @@ public class HiddenServicesTests private async Task CreateIntroductionCircuit() { - var node = (CircuitNodeDetail.Create)(await CircuitHelper.GetRandomRoutersForDirectoryBrowsingWithRetry()).First(); - using TorGuard guard = await TorGuard.NewClientAsync(node.EndPoint); - var circuit = new TorCircuit(guard); - - await circuit.CreateAsync(CircuitNodeDetail.FastCreate); + using TorClient torClient = await TorClient.BootstrapWithGithubAsync(cachePath); + var circuit = await torClient.CreateCircuitAsync(1, CircuitPurpose.Unknown, FSharpOption.None); await circuit.RegisterAsIntroductionPointAsync(FSharpOption.None, StubCallback, DisconnectionCallback); } @@ -61,12 +76,8 @@ private async Task CreateRendezvousCircuit() var array = new byte[Constants.RendezvousCookieLength]; RandomNumberGenerator.Create().GetNonZeroBytes(array); - var nodes = await CircuitHelper.GetRandomRoutersForDirectoryBrowsingWithRetry(2); - using TorGuard guard = await TorGuard.NewClientAsync(((CircuitNodeDetail.Create)nodes[0]).EndPoint); - var circuit = new TorCircuit(guard); - - await circuit.CreateAsync(nodes[0]); - await circuit.ExtendAsync(nodes[1]); + using TorClient torClient = await TorClient.BootstrapWithGithubAsync(cachePath); + var circuit = await torClient.CreateCircuitAsync(2, CircuitPurpose.Unknown, FSharpOption.None); await circuit.RegisterAsRendezvousPointAsync(array); } @@ -92,10 +103,10 @@ private async Task ReadExact(TorStream stream, byte[] buffer, int off, int public async Task BrowseFacebookOverHS() { - TorDirectory directory = await TorDirectory.BootstrapAsync(FallbackDirectorySelector.GetRandomFallbackDirectory(), new DirectoryInfo(Path.GetTempPath())); + using TorClient torClient = await TorClient.BootstrapWithGithubAsync(cachePath); - var client = await TorServiceClient.ConnectAsync(directory, "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); - var httpClient = new TorHttpClient(client.GetStream(), "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); + var serviceClient = await TorServiceClient.ConnectAsync(torClient, "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); + var httpClient = new TorHttpClient(serviceClient.GetStream(), "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); try { @@ -117,11 +128,11 @@ public void CanBrowseFacebookOverHS() public async Task BrowseFacebookOverHSWithTLS() { - TorDirectory directory = await TorDirectory.BootstrapAsync(FallbackDirectorySelector.GetRandomFallbackDirectory(), new DirectoryInfo(Path.GetTempPath())); - - var client = await TorServiceClient.ConnectAsync(directory, "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion:443"); + using TorClient torClient = await TorClient.BootstrapWithGithubAsync(cachePath); + + var serviceClient = await TorServiceClient.ConnectAsync(torClient, "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion:443"); - var sslStream = new SslStream(client.GetStream(), true, (sender, cert, chain, sslPolicyErrors) => true); + var sslStream = new SslStream(serviceClient.GetStream(), true, (sender, cert, chain, sslPolicyErrors) => true); await sslStream.AuthenticateAsClientAsync(string.Empty, null, SslProtocols.Tls12, false); var httpClientOverSslStream = new TorHttpClient(sslStream, "www.facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion"); @@ -147,10 +158,8 @@ public void CanBrowseFacebookOverHSWithTLS() public async Task EstablishAndCommunicateOverHSConnectionOnionStyle() { - int descriptorUploadRetryLimit = 2; - - TorDirectory directory = await TorDirectory.BootstrapAsync(FallbackDirectorySelector.GetRandomFallbackDirectory(), new DirectoryInfo(Path.GetTempPath())); - + using TorClient torClient = await TorClient.BootstrapWithGithubAsync(cachePath); + TorLogger.Log("Finished bootstraping"); SecureRandom random = new SecureRandom(); @@ -158,7 +167,7 @@ public async Task EstablishAndCommunicateOverHSConnectionOnionStyle() kpGen.Init(new Ed25519KeyGenerationParameters(random)); Ed25519PrivateKeyParameters masterPrivateKey = (Ed25519PrivateKeyParameters)kpGen.GenerateKeyPair().Private; - TorServiceHost host = new TorServiceHost(directory, descriptorUploadRetryLimit, TestsRetryCount, FSharpOption.Some(masterPrivateKey)); + TorServiceHost host = new TorServiceHost(torClient, FSharpOption.Some(masterPrivateKey)); await host.StartAsync(); TorLogger.Log("Finished starting HS host"); @@ -175,8 +184,8 @@ public async Task EstablishAndCommunicateOverHSConnectionOnionStyle() var clientSide = Task.Run(async () => { - var client = await TorServiceClient.ConnectAsync(directory, host.ExportUrl()); - var stream = client.GetStream(); + var serviceClient = await TorServiceClient.ConnectAsync(torClient, host.ExportUrl()); + var stream = serviceClient.GetStream(); var lengthBytes = new byte[sizeof(int)]; await ReadExact(stream, lengthBytes, 0, lengthBytes.Length); var length = BitConverter.ToInt32(lengthBytes); diff --git a/NOnion.Tests/TorClientTests.cs b/NOnion.Tests/TorClientTests.cs new file mode 100644 index 00000000..c7cb3ef4 --- /dev/null +++ b/NOnion.Tests/TorClientTests.cs @@ -0,0 +1,47 @@ +using Microsoft.FSharp.Core; +using System.IO; +using System.Threading.Tasks; + +using NUnit.Framework; + +using NOnion.Client; + +namespace NOnion.Tests +{ + public class TorClientTests + { + private async Task BootstrapWithGithub() + { + await TorClient.BootstrapWithGithubAsync(FSharpOption.None); + } + + [Test] + public void CanBootstrapWithGithub() + { + Assert.DoesNotThrowAsync(BootstrapWithGithub); + } + + private async Task BootstrapWithEmbeddedList() + { + await TorClient.BootstrapWithEmbeddedListAsync(FSharpOption.None); + } + + [Test] + public void CanBootstrapWithEmbeddedList() + { + Assert.DoesNotThrowAsync(BootstrapWithEmbeddedList); + } + + private async Task CreateCircuit() + { + using TorClient client = await TorClient.BootstrapWithEmbeddedListAsync(FSharpOption.None); + await client.CreateCircuitAsync(3, CircuitPurpose.Unknown, FSharpOption.None); + } + + [Test] + public void CanCreateCircuit() + { + Assert.DoesNotThrowAsync(CreateCircuit); + } + } +} diff --git a/NOnion/Client/TorClient.fs b/NOnion/Client/TorClient.fs new file mode 100644 index 00000000..b23b02d0 --- /dev/null +++ b/NOnion/Client/TorClient.fs @@ -0,0 +1,280 @@ +namespace NOnion.Client + +open System +open System.Collections.Concurrent +open System.IO +open System.Net +open System.Net.Http +open System.Text.RegularExpressions + +open NOnion.Directory +open NOnion.Utility +open NOnion +open NOnion.Network + +type CircuitPurpose = + | Unknown + | Exit + +type TorClient internal (directory: TorDirectory) = + static let maximumBootstrapTries = 5 + + static let maximumExtendByNodeRetry = 5 + + static let ConvertFallbackIncToList(fallbackIncString: string) = + let ipv4Pattern = "\"([0-9\\.]+)\\sorport=(\\S*)\\sid=(\\S*)\"" + let matches = Regex.Matches(fallbackIncString, ipv4Pattern) + + matches + |> Seq.cast + |> Seq.map(fun (regMatch: Match) -> + regMatch.Groups.[1].Value, int regMatch.Groups.[2].Value + ) + |> Seq.toList + + static let SelectRandomEndpoints(fallbackList: List) = + fallbackList + |> SeqUtils.TakeRandom maximumBootstrapTries + |> Seq.map(fun (ipString, port) -> + let ipAddress = IPAddress.Parse ipString + IPEndPoint(ipAddress, port) + ) + |> Seq.toList + + static let BootstrapDirectory + (cachePath: Option) + (ipEndPointList: List) + = + async { + let rec tryBootstrap(ipEndPointList: List) = + async { + match ipEndPointList with + | ipEndPoint :: tail -> + try + let cacheDirectory = + match cachePath with + | None -> + let tempDir = + DirectoryInfo( + Path.Combine( + Path.GetTempPath(), + Path.GetFileNameWithoutExtension( + Path.GetRandomFileName() + ) + ) + ) + + tempDir.Create() + tempDir + | Some path -> path + + let! directory = + TorDirectory.Bootstrap ipEndPoint cacheDirectory + + return directory + with + | :? NOnionException -> return! tryBootstrap tail + | [] -> return failwith "Maximum bootstrap tries reached!" + } + + return! tryBootstrap ipEndPointList + } + + static let CreateClientFromFallbackString + (fallbackListString: string) + (cachePath: Option) + = + async { + let! directory = + fallbackListString + |> ConvertFallbackIncToList + |> SelectRandomEndpoints + |> BootstrapDirectory cachePath + + return new TorClient(directory) + } + + let guardsToDispose = ConcurrentBag() + + static member AsyncBootstrapWithEmbeddedList + (cachePath: Option) + = + async { + let fallbackListString = + EmbeddedResourceUtility.ExtractEmbeddedResourceFileContents( + "fallback_dirs.inc" + ) + + return! CreateClientFromFallbackString fallbackListString cachePath + } + + static member BootstrapWithEmbeddedListAsync + (cachePath: Option) + = + TorClient.AsyncBootstrapWithEmbeddedList cachePath |> Async.StartAsTask + + static member AsyncBootstrapWithGithub(cachePath: Option) = + async { + // Don't put this inside the fallbackListString or it gets disposed + // before the task gets executed + use httpClient = new HttpClient() + + let! fallbackListString = + let urlToTorServerList = + "https://raw.githubusercontent.com/torproject/tor/main/src/app/config/fallback_dirs.inc" + + httpClient.GetStringAsync urlToTorServerList |> Async.AwaitTask + + return! CreateClientFromFallbackString fallbackListString cachePath + } + + static member BootstrapWithGithubAsync(cachePath: Option) = + TorClient.AsyncBootstrapWithGithub cachePath |> Async.StartAsTask + + member __.Directory = directory + + member internal __.AsyncCreateCircuitWithCallback + (hopsCount: int) + (purpose: CircuitPurpose) + (extendByNodeOpt: Option) + (serviceStream: uint16 -> TorCircuit -> Async) + = + async { + let rec createNewGuard() = + async { + let! ipEndPoint, nodeDetail = + directory.GetRouter RouterType.Guard + + try + let! guard = + TorGuard.NewClientWithIdentity + ipEndPoint + (nodeDetail.GetIdentityKey() |> Some) + + guardsToDispose.Add guard + return guard, nodeDetail + with + | :? GuardConnectionFailedException -> + return! createNewGuard() + } + + let rec tryCreateCircuit(tryNumber: int) = + async { + if tryNumber > maximumExtendByNodeRetry then + return raise <| DestinationNodeCantBeReachedException() + else + try + let! guard, guardDetail = createNewGuard() + let circuit = TorCircuit(guard, serviceStream) + + do! + circuit.Create guardDetail + |> Async.Ignore + + let rec extend + (numHopsToExtend: int) + (nodesSoFar: List) + = + async { + if numHopsToExtend > 0 then + let rec findUnusedNode() = + async { + let! _ipEndPoint, nodeDetail = + if numHopsToExtend = 1 then + match purpose with + | Unknown -> + directory.GetRouter + RouterType.Normal + | Exit -> + directory.GetRouter + RouterType.Exit + else + directory.GetRouter + RouterType.Normal + + if (List.contains + nodeDetail + nodesSoFar) then + return! findUnusedNode() + else + return nodeDetail + } + + let! newUnusedNode = findUnusedNode() + + do! + circuit.Extend newUnusedNode + |> Async.Ignore + + return! + extend + (numHopsToExtend - 1) + (newUnusedNode :: nodesSoFar) + else + () + } + + do! + extend + (hopsCount - 1) + (List.singleton guardDetail) + + match extendByNodeOpt with + | Some extendByNode -> + try + do! + circuit.Extend extendByNode + |> Async.Ignore + with + | :? NOnionException -> + return + raise + <| DestinationNodeCantBeReachedException + () + | None -> () + + return circuit + with + | :? DestinationNodeCantBeReachedException -> + return! tryCreateCircuit(tryNumber + 1) + | ex -> + match FSharpUtil.FindException ex + with + | Some _nonionEx -> + return! tryCreateCircuit tryNumber + | None -> return raise <| FSharpUtil.ReRaise ex + } + + let startTryNumber = 1 + + return! tryCreateCircuit startTryNumber + } + + member self.AsyncCreateCircuit + (hopsCount: int) + (purpose: CircuitPurpose) + (extendByNodeOpt: Option) + = + let noop _ _ = + async { return () } + + self.AsyncCreateCircuitWithCallback + hopsCount + purpose + extendByNodeOpt + noop + + member self.CreateCircuitAsync + ( + hopsCount: int, + purpose: CircuitPurpose, + extendByNode: Option + ) = + self.AsyncCreateCircuit hopsCount purpose extendByNode + |> Async.StartAsTask + + + interface IDisposable with + member __.Dispose() = + for guard in guardsToDispose do + (guard :> IDisposable).Dispose() diff --git a/NOnion/Exceptions.fs b/NOnion/Exceptions.fs index 98c7ab94..757f34ab 100644 --- a/NOnion/Exceptions.fs +++ b/NOnion/Exceptions.fs @@ -53,3 +53,6 @@ type NOnionSocketException "Got socket exception during data transfer", innerException ) + +type DestinationNodeCantBeReachedException() = + inherit NOnionException("Destination node can't be reached") diff --git a/NOnion/NOnion.fsproj b/NOnion/NOnion.fsproj index 904f1ae7..c5e3b282 100644 --- a/NOnion/NOnion.fsproj +++ b/NOnion/NOnion.fsproj @@ -13,6 +13,7 @@ + @@ -85,6 +86,7 @@ + diff --git a/NOnion/Services/TorServiceClient.fs b/NOnion/Services/TorServiceClient.fs index 9264dfbc..074de3e3 100644 --- a/NOnion/Services/TorServiceClient.fs +++ b/NOnion/Services/TorServiceClient.fs @@ -12,6 +12,7 @@ open Org.BouncyCastle.Security open NOnion open NOnion.Cells.Relay +open NOnion.Client open NOnion.Crypto open NOnion.Utility open NOnion.Directory @@ -21,7 +22,7 @@ open NOnion.Network type TorServiceClient = private { - RendezvousGuard: TorGuard + TorClient: TorClient RendezvousCircuit: TorCircuit Stream: TorStream } @@ -29,16 +30,16 @@ type TorServiceClient = member self.GetStream() = self.Stream - static member ConnectAsync (directory: TorDirectory) (url: string) = - TorServiceClient.Connect directory url |> Async.StartAsTask + static member ConnectAsync (client: TorClient) (url: string) = + TorServiceClient.Connect client url |> Async.StartAsTask - static member Connect (directory: TorDirectory) (url: string) = + static member Connect (client: TorClient) (url: string) = async { let publicKey, port = HiddenServicesUtility.DecodeOnionUrl url let getIntroductionPointInfo() = async { - let! networkStatus = directory.GetLiveNetworkStatus() + let! networkStatus = client.Directory.GetLiveNetworkStatus() let periodNum, periodLength = networkStatus.GetTimePeriod() let srv = networkStatus.GetCurrentSRVForClient() @@ -49,7 +50,7 @@ type TorServiceClient = publicKey let! responsibleDirs = - directory.GetResponsibleHiddenServiceDirectories + client.Directory.GetResponsibleHiddenServiceDirectories blindedPublicKey srv periodNum @@ -64,36 +65,16 @@ type TorServiceClient = raise <| DescriptorDownloadFailedException() | hsDirectory :: tail -> try - let! guardEndPoint, randomGuardNode = - directory.GetRouter RouterType.Guard - - let! _, randomMiddleNode = - directory.GetRouter RouterType.Normal - let! hsDirectoryNode = - directory.GetCircuitNodeDetailByIdentity + client.Directory.GetCircuitNodeDetailByIdentity hsDirectory - use! guardNode = - TorGuard.NewClientWithIdentity - guardEndPoint - (randomGuardNode.GetIdentityKey() - |> Some) - - let circuit = TorCircuit guardNode - - do! - circuit.Create randomGuardNode - |> Async.Ignore - - do! - circuit.Extend randomMiddleNode - |> Async.Ignore - try - do! - circuit.Extend hsDirectoryNode - |> Async.Ignore + let! circuit = + client.AsyncCreateCircuit + 2 + CircuitPurpose.Unknown + (Some hsDirectoryNode) use dirStream = new TorStream(circuit) @@ -394,18 +375,14 @@ type TorServiceClient = .Create() .GetNonZeroBytes randomGeneratedCookie - let! endpoint, guardnode = directory.GetRouter RouterType.Guard - let! _, rendezvousNode = directory.GetRouter RouterType.Normal + let! _, rendezvousNode = + client.Directory.GetRouter RouterType.Normal - let! rendezvousGuard = - TorGuard.NewClientWithIdentity - endpoint - (guardnode.GetIdentityKey() |> Some) - - let rendezvousCircuit = TorCircuit rendezvousGuard - - do! rendezvousCircuit.Create guardnode |> Async.Ignore - do! rendezvousCircuit.Extend rendezvousNode |> Async.Ignore + let! rendezvousCircuit = + client.AsyncCreateCircuit + 1 + CircuitPurpose.Unknown + (Some rendezvousNode) do! rendezvousCircuit.RegisterAsRendezvousPoint @@ -438,7 +415,7 @@ type TorServiceClient = ] } - let! networkStatus = directory.GetLiveNetworkStatus() + let! networkStatus = client.Directory.GetLiveNetworkStatus() let periodInfo = networkStatus.GetTimePeriod() let data, macKey = @@ -471,13 +448,11 @@ type TorServiceClient = macKey } - let introCircuit = TorCircuit rendezvousGuard - - do! introCircuit.Create guardnode |> Async.Ignore - - do! - introCircuit.Extend introductionPointNodeDetail - |> Async.Ignore + let! introCircuit = + client.AsyncCreateCircuit + 1 + Unknown + (Some introductionPointNodeDetail) let rendezvousJoin = rendezvousCircuit.WaitingForRendezvousJoin @@ -507,7 +482,7 @@ type TorServiceClient = return { - RendezvousGuard = rendezvousGuard + TorClient = client RendezvousCircuit = rendezvousCircuit Stream = serviceStream } @@ -515,7 +490,3 @@ type TorServiceClient = return failwith "Never happens. GetRouter never returns FastCreate" } - - interface IDisposable with - member self.Dispose() = - (self.RendezvousGuard :> IDisposable).Dispose() diff --git a/NOnion/Services/TorServiceHost.fs b/NOnion/Services/TorServiceHost.fs index 2fb2beab..25f9b595 100644 --- a/NOnion/Services/TorServiceHost.fs +++ b/NOnion/Services/TorServiceHost.fs @@ -19,6 +19,7 @@ open Org.BouncyCastle.Security open NOnion open NOnion.Cells.Relay open NOnion.Crypto +open NOnion.Client open NOnion.Directory open NOnion.Utility open NOnion.Network @@ -36,9 +37,7 @@ type IntroductionPointInfo = type TorServiceHost ( - directory: TorDirectory, - maxDescriptorUploadRetryCount: int, - maxRendezvousConnectRetryCount: int, + client: TorClient, maybeMasterPrivateKey: Option ) = @@ -125,28 +124,19 @@ type TorServiceHost introEncPubKey = async { - let! endPoint, randomNodeDetails = - directory.GetRouter RouterType.Guard - - let! guard = - TorGuard.NewClientWithIdentity - endPoint - (randomNodeDetails.GetIdentityKey() |> Some) - - let rendezvousCircuit = - TorCircuit(guard, self.IncomingServiceStreamCallback) - - do! rendezvousCircuit.Create randomNodeDetails |> Async.Ignore - - do! - rendezvousCircuit.Extend( - CircuitNodeDetail.Create( - rendezvousEndpoint, - onionKey, - rendezvousFingerPrint - ) + let lastNodeDetails = + CircuitNodeDetail.Create( + rendezvousEndpoint, + onionKey, + rendezvousFingerPrint ) - |> Async.Ignore + + let! rendezvousCircuit = + client.AsyncCreateCircuitWithCallback + 2 + CircuitPurpose.Unknown + (Some lastNodeDetails) + self.IncomingServiceStreamCallback do! rendezvousCircuit.Rendezvous @@ -181,7 +171,7 @@ type TorServiceHost introductionPointDetails.EncryptionKey.Private :?> X25519PrivateKeyParameters - let! networkStatus = directory.GetLiveNetworkStatus() + let! networkStatus = client.Directory.GetLiveNetworkStatus() let periodInfo = networkStatus.GetTimePeriod() let decryptedData, macKey = @@ -237,7 +227,7 @@ type TorServiceHost | Some linkSpecifier -> linkSpecifier.Data | None -> failwith "No rendezvous fingerprint found!" - let connectToRendezvousJob = + do! tryConnectingToRendezvous rendezvousEndpoint rendezvousFingerPrint @@ -248,11 +238,6 @@ type TorServiceHost introEncPrivKey introEncPubKey - do! - FSharpUtil.Retry - connectToRendezvousJob - maxRendezvousConnectRetryCount - return () } @@ -265,10 +250,10 @@ type TorServiceHost async { try let! guardEndPoint, guardNodeDetail = - directory.GetRouter RouterType.Guard + client.Directory.GetRouter RouterType.Guard let! _, introNodeDetail = - directory.GetRouter RouterType.Normal + client.Directory.GetRouter RouterType.Normal match introNodeDetail with | FastCreate -> @@ -368,73 +353,52 @@ type TorServiceHost member self.UploadDescriptor (directoryToUploadTo: string) (document: HiddenServiceFirstLayerDescriptorDocument) - (retry: int) = async { - if retry > maxDescriptorUploadRetryCount then - return () - else - try - let! hsDirectoryNode = - directory.GetCircuitNodeDetailByIdentity - directoryToUploadTo - - let! guardEndPoint, randomGuardNode = - directory.GetRouter RouterType.Guard - - let! _, randomMiddleNode = - directory.GetRouter RouterType.Normal - - use! guardNode = - TorGuard.NewClientWithIdentity - guardEndPoint - (randomGuardNode.GetIdentityKey() |> Some) - - let circuit = TorCircuit guardNode - do! circuit.Create randomGuardNode |> Async.Ignore - do! circuit.Extend randomMiddleNode |> Async.Ignore - do! circuit.Extend hsDirectoryNode |> Async.Ignore - - use dirStream = new TorStream(circuit) - do! dirStream.ConnectToDirectory() |> Async.Ignore - - let! _response = - TorHttpClient( - dirStream, - Constants.DefaultHttpHost - ) - .PostString - (sprintf - "/tor/hs/%i/publish" - Constants.HiddenServices.Version) - (document.ToString()) - - TorLogger.Log( - sprintf - "TorServiceHost: descriptor uploaded to node with identity %s" - directoryToUploadTo - ) - - return () - with - | :? UnsuccessfulHttpResponseException -> - // During testing, after migration to microdescriptor, we saw instances of - // 404 error msg when trying to publish our descriptors which mean for - // some reason we're trying to upload descriptor to a directory that - // is not a hidden service directory, there is no point in retrying here. - return () - | ex -> - TorLogger.Log( - sprintf - "TorServiceHost: hs descriptor upload failed, ex=%s" - (ex.ToString()) + try + let! hsDirectoryNode = + client.Directory.GetCircuitNodeDetailByIdentity + directoryToUploadTo + + let! circuit = + client.AsyncCreateCircuit + 2 + CircuitPurpose.Unknown + (Some hsDirectoryNode) + + use dirStream = new TorStream(circuit) + do! dirStream.ConnectToDirectory() |> Async.Ignore + + let! _response = + TorHttpClient( + dirStream, + Constants.DefaultHttpHost ) + .PostString + (sprintf + "/tor/hs/%i/publish" + Constants.HiddenServices.Version) + (document.ToString()) + + TorLogger.Log( + sprintf + "TorServiceHost: descriptor uploaded to node with identity %s" + directoryToUploadTo + ) - return! - self.UploadDescriptor - directoryToUploadTo - document - (retry + 1) + return () + with + | :? DestinationNodeCantBeReachedException + | :? UnsuccessfulHttpResponseException -> + // During testing, after migration to microdescriptor, we saw instances of + // 404 error msg when trying to publish our descriptors which mean for + // some reason we're trying to upload descriptor to a directory that + // is not a hidden service directory, there is no point in retrying here. + + // TorClient tries multiple times with different circuit to connect to + // the directory, if destination node can't be reached with any circuit + // we stop trying. + return () } member self.BuildAndUploadDescriptor @@ -450,7 +414,7 @@ type TorServiceHost (masterPublicKey.GetEncoded()) let! responsibleDirs = - directory.GetResponsibleHiddenServiceDirectories + client.Directory.GetResponsibleHiddenServiceDirectories blindedPublicKey srv periodNum @@ -698,7 +662,7 @@ type TorServiceHost let jobs = responsibleDirs - |> Seq.map(fun dir -> self.UploadDescriptor dir outerWrapper 1) + |> Seq.map(fun dir -> self.UploadDescriptor dir outerWrapper) do! Async.Parallel( @@ -756,7 +720,7 @@ type TorServiceHost //TODO: this should refresh every 60-120min member self.KeepDescriptorsUpToDate() = async { - let! networkStatus = directory.GetLiveNetworkStatus() + let! networkStatus = client.Directory.GetLiveNetworkStatus() let firstDescriptorBuildJob = self.UpdateFirstDescriptor networkStatus diff --git a/NOnion/fallback_dirs.inc b/NOnion/fallback_dirs.inc new file mode 100644 index 00000000..1302099e --- /dev/null +++ b/NOnion/fallback_dirs.inc @@ -0,0 +1,1102 @@ +/* type=fallback */ +/* version=4.0.0 */ +/* timestamp=20210412000000 */ +/* source=offer-list */ +// +// Generated on: Thu, 12 Jan 2023 16:00:16 +0000 + +"142.132.165.154 orport=443 id=6D9E22C1F4F0E99867F98F2546A9B76D5F08B4CF" +" ipv6=[2a01:4f8:1c1c:43c::1]:443" +/* nickname=libreapp01 */ +/* extrainfo=0 */ +/* ===== */ +, +"18.18.82.18 orport=9001 id=BF54EE3193751481579BA7CC7D8E1DF0A01AFB30" +/* nickname=gesdm */ +/* extrainfo=0 */ +/* ===== */ +, +"72.92.146.128 orport=9001 id=C5E420FAF05680EE590542AE7216C77602FE68DC" +/* nickname=TreeFiddy */ +/* extrainfo=0 */ +/* ===== */ +, +"116.203.17.238 orport=9001 id=28090710ABE433A47021F22208B3EC245A912900" +/* nickname=dismail */ +/* extrainfo=0 */ +/* ===== */ +, +"116.203.50.182 orport=8080 id=00E1649E69FF91D7F01E74A5E62EF14F7D9915E4" +" ipv6=[2a01:4f8:1c1c:b16b::1]:8080" +/* nickname=dragonhoard */ +/* extrainfo=0 */ +/* ===== */ +, +"144.76.154.13 orport=9001 id=10A5EFCCD2FB9C1A4AC20FB779A5DB11B58957A7" +" ipv6=[2a01:4f8:200:2211::2]:9001" +/* nickname=eridanus */ +/* extrainfo=0 */ +/* ===== */ +, +"94.46.171.245 orport=9001 id=904F36E7AFE6346F5D1D66971F920FFCC47DF120" +/* nickname=sunandfun03 */ +/* extrainfo=0 */ +/* ===== */ +, +"176.9.38.121 orport=9100 id=8284C8A45D22F2981C4B6287C7FB4367116E7CCE" +" ipv6=[2a01:4f8:161:353a::2]:9100" +/* nickname=Turik */ +/* extrainfo=0 */ +/* ===== */ +, +"78.31.67.22 orport=9001 id=6982D789D3875C21433D6EE10838AC5FDC6BA82C" +/* nickname=tor2lhvmct */ +/* extrainfo=0 */ +/* ===== */ +, +"185.220.101.206 orport=443 id=EB9DD80E64DD829A5F7C7ACA5D5FEADFEBFDD847" +" ipv6=[2a0b:f4c2:2:1::206]:443" +/* nickname=ForPrivacyNET */ +/* extrainfo=0 */ +/* ===== */ +, +"185.175.158.198 orport=9090 id=A489D37070A5081D814C1F112139EEF0DDC03A48" +/* nickname=Trurangers2 */ +/* extrainfo=0 */ +/* ===== */ +, +"87.62.96.246 orport=9032 id=E384748293FC4429E2B427360DB4F9D4C3D619D1" +/* nickname=PXArelay02 */ +/* extrainfo=0 */ +/* ===== */ +, +"94.130.246.106 orport=9001 id=1C0736CF3744A3B87C2D2269B8BD3388C7E60552" +" ipv6=[2a01:4f8:10b:3344:106::106]:9001" +/* nickname=FreedomFries2 */ +/* extrainfo=0 */ +/* ===== */ +, +"95.214.54.80 orport=443 id=5A79BD5CC6C128D7D8DFB4969B0246794F117FC6" +" ipv6=[2a03:cfc0:8000:7::5fd6:3647]:443" +/* nickname=bauruine */ +/* extrainfo=0 */ +/* ===== */ +, +"185.220.101.72 orport=9100 id=D3DFB8F9A878F44ED80E2B34F794FDF6334FC5F9" +/* nickname=CCCStuttgartBer */ +/* extrainfo=0 */ +/* ===== */ +, +"51.15.150.228 orport=443 id=46E0487EEEFD694CE625CC6E12D032395C01DB82" +/* nickname=NTH100 */ +/* extrainfo=0 */ +/* ===== */ +, +"51.15.75.120 orport=444 id=0040A5B04C7E309D37CBE7EDB2B72D3E15D057C1" +" ipv6=[2001:bc8:1860:1329::1]:444" +/* nickname=dc6jgk11d */ +/* extrainfo=0 */ +/* ===== */ +, +"185.181.229.77 orport=9001 id=44730B2450213BC3E2DAA4854458D134F0644FF2" +/* nickname=RedLightDistrict */ +/* extrainfo=0 */ +/* ===== */ +, +"91.219.29.94 orport=9001 id=09E0BD68FBAEB7C10107DE67624D25B007FF26A2" +/* nickname=Unnamed */ +/* extrainfo=0 */ +/* ===== */ +, +"51.81.56.195 orport=443 id=EEDB9FEFC9165F9B41B515A282F95A574A807FBA" +/* nickname=trash1 */ +/* extrainfo=0 */ +/* ===== */ +, +"89.147.108.35 orport=9105 id=B30D36FBA3DD300E11916A086D7166A6BE3169FE" +/* nickname=LessIsMore */ +/* extrainfo=0 */ +/* ===== */ +, +"5.255.98.7 orport=443 id=37788F0C00728A44ED8202780D853223EDCA3D3F" +" ipv6=[2a04:52c0:103:ba24::1]:443" +/* nickname=vhult4 */ +/* extrainfo=0 */ +/* ===== */ +, +"144.91.125.15 orport=9001 id=F15A2A08BF91017DCFB6042171635661E13A8256" +" ipv6=[2a02:c207:2033:4966::1]:9001" +/* nickname=WitchNode */ +/* extrainfo=0 */ +/* ===== */ +, +"172.98.15.136 orport=9001 id=518B031A3DF503E08F6F815DB194DBD7B15C9C57" +/* nickname=FrozenChosen */ +/* extrainfo=0 */ +/* ===== */ +, +"138.201.123.109 orport=9001 id=2C13A54E3E8A6AFB18E0DE5890E5B08AAF5B0F36" +/* nickname=history */ +/* extrainfo=0 */ +/* ===== */ +, +"216.250.119.225 orport=9001 id=A56B3845D290791CB26BCE89FE4CE08CF7DC8A2C" +/* nickname=QECm1r4 */ +/* extrainfo=0 */ +/* ===== */ +, +"89.58.54.129 orport=443 id=3B642FF7FE3915C42E20445A1C725A75BAA0A9E3" +" ipv6=[2a03:4000:69:e40::1]:443" +/* nickname=TorRelay1a */ +/* extrainfo=0 */ +/* ===== */ +, +"185.232.70.209 orport=443 id=D36EFFB24481694E384787FAAB80F56AAA5CCD9A" +" ipv6=[2a03:4000:4e:f48:54ac:99ff:fee4:b238]:443" +/* nickname=08eRPfaL2Relay2 */ +/* extrainfo=0 */ +/* ===== */ +, +"109.202.212.1 orport=9001 id=196ABA69C056520E041FAE26EFB329940AB110AF" +" ipv6=[2001:1620:4:d401:29:64aa:f77f:d8e0]:9001" +/* nickname=habo01 */ +/* extrainfo=0 */ +/* ===== */ +, +"185.195.71.3 orport=443 id=3C5915348D731505C48112F4F03235FDE7B8C837" +/* nickname=AccessNow001 */ +/* extrainfo=0 */ +/* ===== */ +, +"212.83.43.93 orport=443 id=B86137AE9681701901C6720E55C16805B46BD8E3" +" ipv6=[2a00:f48:2000:1038:72a7:e81a:29ff:abba]:443" +/* nickname=BeastieJoy60 */ +/* extrainfo=0 */ +/* ===== */ +, +"79.137.196.223 orport=9091 id=47A77C3BC4E50D6DE2D3BF24046C57A72ED1E45F" +/* nickname=VitaminCoin */ +/* extrainfo=0 */ +/* ===== */ +, +"91.208.162.197 orport=8081 id=D3D2E42D8E625D36489015AB1E8081CE520DF2FE" +" ipv6=[2001:678:6d4:5100::a1b]:8081" +/* nickname=pissnissemoldova */ +/* extrainfo=0 */ +/* ===== */ +, +"45.91.77.77 orport=443 id=C2B6ADF4EFEA73CA2EFB2789E2B74C1034C1F5F2" +" ipv6=[2a0f:4ac4:42::704:c0ca:1eaf]:443" +/* nickname=c0ca1eaf */ +/* extrainfo=0 */ +/* ===== */ +, +"82.66.61.19 orport=995 id=40FA09C151C3893B7018DEF55A9854BC9768B82C" +" ipv6=[2a01:e0a:5d6:6de0:acab:3:3:3]:995" +/* nickname=Abeille */ +/* extrainfo=0 */ +/* ===== */ +, +"185.243.218.27 orport=8443 id=5B9086D4BFB9EA36C95897DAED72FC3973847B43" +" ipv6=[2a03:94e0:ffff:185:243:218:0:27]:8443" +/* nickname=bauruine */ +/* extrainfo=0 */ +/* ===== */ +, +"212.83.61.218 orport=443 id=D0562BB74A5CC8872D11B222677009A8922FC38C" +/* nickname=mitropoulos */ +/* extrainfo=0 */ +/* ===== */ +, +"37.200.99.251 orport=9001 id=F6EC46933CE8D4FAD5CCDAA8B1C5A377685FC521" +" ipv6=[2a00:1158:3::1ba]:9001" +/* nickname=JPsi2 */ +/* extrainfo=0 */ +/* ===== */ +, +"94.230.208.147 orport=8443 id=311A4533F7A2415F42346A6C8FA77E6FD279594C" +" ipv6=[2a02:418:6017::147]:8443" +/* nickname=DigiGesTor3e2 */ +/* extrainfo=0 */ +/* ===== */ +, +"54.36.120.156 orport=443 id=D0273C8566CC9AECE4C762376C9B066FE0F1DADD" +/* nickname=Kimchi */ +/* extrainfo=0 */ +/* ===== */ +, +"5.45.102.119 orport=9100 id=189C44DD06312D6DF8FB57A944E6819FF245740C" +" ipv6=[2a03:4000:6:608:942a:42ff:fe77:728c]:9100" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.74 orport=443 id=9C1E7D92115D431385B8CAEA6A7C15FB89CE236B" +" ipv6=[2620:7:6001::ffff:c759:e64a]:80" +/* nickname=QuintexAirVPN21 */ +/* extrainfo=0 */ +/* ===== */ +, +"145.239.206.31 orport=8001 id=912A7C57E05606AF602EC63D1D06BBD5C7AAE516" +" ipv6=[2001:41d0:800:b1f::]:8001" +/* nickname=0x3d02 */ +/* extrainfo=0 */ +/* ===== */ +, +"144.217.90.187 orport=9001 id=7040C1F5728746C5FB5E12845101A26EE8636D7E" +" ipv6=[2607:5300:201:3100::5b0d]:9001" +/* nickname=SaruTorUmidanuki */ +/* extrainfo=0 */ +/* ===== */ +, +"138.201.250.33 orport=9011 id=2BA2C8E96B2590E1072AECE2BDB5C48921BF8510" +/* nickname=storm */ +/* extrainfo=0 */ +/* ===== */ +, +"87.118.116.103 orport=443 id=26C28F29B611DF4DE23ACF5D9DC1EB4895EF5E8B" +" ipv6=[2001:1b60:3:221:4134:101:0:1]:443" +/* nickname=artikel5ev4 */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.110 orport=443 id=7FA8E7E44F1392A4E40FFC3B69DB3B00091B7FD3" +" ipv6=[2620:7:6001::110]:80" +/* nickname=Quintex20 */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.82 orport=443 id=A0DB820FEC87C0405F7BF05DEE5E4ADED2BB9904" +" ipv6=[2620:7:6001::ffff:c759:e652]:80" +/* nickname=QuintexAirVPN29 */ +/* extrainfo=0 */ +/* ===== */ +, +"5.2.72.110 orport=9001 id=5847D5A01C47166143F738C7703344517B39EB10" +/* nickname=7342426259276943 */ +/* extrainfo=0 */ +/* ===== */ +, +"50.39.143.177 orport=59090 id=A1C515432EF6BF2E699A6184ED78DF0B9A595655" +/* nickname=lilonionboi */ +/* extrainfo=0 */ +/* ===== */ +, +"174.128.250.163 orport=443 id=F7A052D4EEA2F4BC942DFB054AF2DC54A2A37E5D" +/* nickname=rockstars1 */ +/* extrainfo=0 */ +/* ===== */ +, +"163.172.213.212 orport=10010 id=CB7DB13172E15D4AD7F9404667021DF7DF6E9A4A" +/* nickname=noconname */ +/* extrainfo=0 */ +/* ===== */ +, +"65.108.10.141 orport=9001 id=7B46F20449D6F25150E189428B62E1E3BA5848A9" +" ipv6=[2a01:4f9:6a:4642::2]:9001" +/* nickname=galtlandeu */ +/* extrainfo=0 */ +/* ===== */ +, +"185.112.156.72 orport=443 id=089E8959D386C4DC283FFDA2B590A65FCE85C8B4" +/* nickname=TheAdoptee */ +/* extrainfo=0 */ +/* ===== */ +, +"15.235.29.234 orport=9001 id=1B3098A711D00ECD428576EB2E868ED4D22C96B1" +/* nickname=BSSP08 */ +/* extrainfo=0 */ +/* ===== */ +, +"135.125.202.252 orport=9001 id=720ABE4554C55EE6F6099491CA55D1F5550512C5" +/* nickname=slotor02 */ +/* extrainfo=0 */ +/* ===== */ +, +"135.148.52.231 orport=443 id=BA6E064596B86AF9F55F0603A82C90E958E86E7A" +/* nickname=twoandtwoone */ +/* extrainfo=0 */ +/* ===== */ +, +"92.222.79.186 orport=443 id=78AA54A1B4169242310499DD81C72EF519B070F3" +/* nickname=CebolaServer */ +/* extrainfo=0 */ +/* ===== */ +, +"213.144.135.21 orport=443 id=BB5FAE50BCE5B13C810CD17A931A0498E4681D41" +" ipv6=[2a02:168:6a16:1130::32:101]:443" +/* nickname=YoYuD1N01NoExit */ +/* extrainfo=0 */ +/* ===== */ +, +"139.162.166.237 orport=443 id=8BEA5AB8F95DE1920775A1A8F4C34B947A7DE505" +/* nickname=shadowdancer */ +/* extrainfo=0 */ +/* ===== */ +, +"95.216.101.247 orport=443 id=38CC95A8CE92A591D4A5779359BEFFBA13FA1B88" +" ipv6=[2a01:4f9:2b:151f:95:216:101:247]:443" +/* nickname=TykRelay02 */ +/* extrainfo=0 */ +/* ===== */ +, +"191.252.111.55 orport=443 id=1D1FA50D605FDC8F6DC39A0A60A7233DD35D0001" +/* nickname=K4M1K4Z3 */ +/* extrainfo=0 */ +/* ===== */ +, +"131.188.40.188 orport=11180 id=EBE718E1A49EE229071702964F8DB1F318075FF8" +" ipv6=[2001:638:a000:4140::ffff:188]:11180" +/* nickname=fluxe4 */ +/* extrainfo=0 */ +/* ===== */ +, +"50.236.201.218 orport=9001 id=B5053ABFF845C96B1DD8F45DCF32E6BE1E63F127" +/* nickname=Stephen304 */ +/* extrainfo=0 */ +/* ===== */ +, +"5.182.211.119 orport=9001 id=DD7BD3E5BD0BA48A8C70B0CDF017FA5988B87E27" +/* nickname=Assange014nl */ +/* extrainfo=0 */ +/* ===== */ +, +"209.51.188.48 orport=443 id=CEE804FA03A87A65CAA6BCB3A250B5ED923C08BD" +" ipv6=[2001:470:142:5::48]:443" +/* nickname=FSF */ +/* extrainfo=0 */ +/* ===== */ +, +"185.228.136.146 orport=9100 id=F0D01EB1FDC508279AB3412AF3FC950BB1DA2AD1" +" ipv6=[2a03:4000:23:50:c8ed:bcff:fe13:ee61]:9100" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"89.58.52.189 orport=9001 id=C3277FBEAB946672D468E90A16BB027B4CACC537" +" ipv6=[2a03:4000:69:d5d::2]:9001" +/* nickname=itrickl02 */ +/* extrainfo=0 */ +/* ===== */ +, +"188.40.147.177 orport=443 id=1D702DA43D588FE9D308D3879A6F5E61BB2ECCFA" +/* nickname=schumacher */ +/* extrainfo=0 */ +/* ===== */ +, +"82.220.38.150 orport=443 id=A4DE3FC1ACEC3767F5C4049BCEF57317E7B0583C" +/* nickname=eclipse12 */ +/* extrainfo=0 */ +/* ===== */ +, +"65.39.97.13 orport=9001 id=0D1AD0392583CBC22B5F712165D9D752D35F0699" +/* nickname=TorNodeAlpha */ +/* extrainfo=0 */ +/* ===== */ +, +"23.137.251.61 orport=8443 id=B558F456FB410E6CDF3D33AC5EB5305D66DA8B19" +" ipv6=[2602:fc24:13:e::fefe]:8443" +/* nickname=bauruine */ +/* extrainfo=0 */ +/* ===== */ +, +"81.6.40.139 orport=995 id=E36536404200A74930DB165858BD5BB554D2BEA2" +" ipv6=[2a02:168:2000:5f:7b5c:fee4:84b2:30b]:995" +/* nickname=naiveTorer */ +/* extrainfo=0 */ +/* ===== */ +, +"185.194.141.178 orport=9100 id=1B6BCBCDB384364B6FB4F3576CA70AECFC083641" +" ipv6=[2a03:4000:1c:7e3:e8aa:c8ff:fe36:66ee]:9100" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"185.220.101.206 orport=8443 id=ADF0D51946DA3294C1F242B0ACADC91FF5F058EF" +" ipv6=[2a0b:f4c2:2:1::206]:8443" +/* nickname=ForPrivacyNET */ +/* extrainfo=0 */ +/* ===== */ +, +"158.69.207.216 orport=9001 id=6565F31D9EC0C7DFFEA1920BE3BA4C73EF35B5C4" +" ipv6=[2607:5300:201:3000::dfc]:9001" +/* nickname=oscar */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.141 orport=443 id=B7ECD9C6A910A170B55165742049CBCC777494F2" +" ipv6=[2620:7:6001::141]:80" +/* nickname=Quintex52 */ +/* extrainfo=0 */ +/* ===== */ +, +"178.175.148.205 orport=9001 id=8769AF6DCC45DAB9C219CD9F464EAE3268550CFD" +" ipv6=[2a00:1dc0:caff:ad::e746]:9001" +/* nickname=yellowsun */ +/* extrainfo=0 */ +/* ===== */ +, +"51.15.59.15 orport=444 id=B1F926DA3895A89AF288623F5A4F913979299C53" +" ipv6=[2001:bc8:1860:1419::1]:444" +/* nickname=artikel5ev13b */ +/* extrainfo=0 */ +/* ===== */ +, +"192.42.116.17 orport=443 id=0485027A0A349D454D978F6C1CECDD29EA17769A" +" ipv6=[2001:67c:6ec:203:218:33ff:fe44:5517]:443" +/* nickname=hviv117 */ +/* extrainfo=0 */ +/* ===== */ +, +"193.108.118.218 orport=443 id=79D9E66BB2FDBF25E846B635D8248FE1194CFD26" +" ipv6=[2604:86c0:f001:2:9baf:37c2:e99e:babe]:443" +/* nickname=BeastieJoy65 */ +/* extrainfo=0 */ +/* ===== */ +, +"83.78.216.58 orport=43633 id=7ACCD860B360118F43275FCF215F6A4C9D5E016B" +/* nickname=bauruine */ +/* extrainfo=0 */ +/* ===== */ +, +"23.154.177.3 orport=443 id=76CA636C1D33E3E8630B7AC22A1D07420FCE8761" +/* nickname=UnredactedManning */ +/* extrainfo=0 */ +/* ===== */ +, +"213.149.82.60 orport=9001 id=45D8C1EEFF044043AA6806C4B9130F8F189EF316" +" ipv6=[2a02:2488:4211:3400::3]:9001" +/* nickname=Feuermagier */ +/* extrainfo=0 */ +/* ===== */ +, +"49.12.225.94 orport=9001 id=EE2A9108A9EDBFCB5C44F2993267573188176AA4" +/* nickname=myzwiebel03 */ +/* extrainfo=0 */ +/* ===== */ +, +"172.107.202.142 orport=443 id=036E015AD84D3C605666E3A3306B1E3E18A89482" +/* nickname=parsel */ +/* extrainfo=0 */ +/* ===== */ +, +"94.199.217.225 orport=443 id=05D01D243BB76468B80670CCF8F07F5E9296736D" +/* nickname=madblock */ +/* extrainfo=0 */ +/* ===== */ +, +"185.233.100.23 orport=443 id=F47B13BFCE4EF48CDEF6C4D7C7A99208EBB972B5" +" ipv6=[2a0c:e300::23]:443" +/* nickname=Elenagb */ +/* extrainfo=0 */ +/* ===== */ +, +"213.135.244.242 orport=24071 id=2D938F19EAF660D902C656B5E6002F39B45C4BE4" +/* nickname=VoxBox */ +/* extrainfo=0 */ +/* ===== */ +, +"45.132.246.38 orport=9001 id=431702B3A68A6015F9955DD4FD0129175B43EA0F" +" ipv6=[2a03:4000:48:182:74dd:c1ff:fea8:d21e]:9001" +/* nickname=bituman */ +/* extrainfo=0 */ +/* ===== */ +, +"82.223.23.176 orport=443 id=C22A591FF4EE577C408DAFD26C75302615E5165E" +" ipv6=[2001:ba0:1800:8188::1]:443" +/* nickname=FrankyThePooper */ +/* extrainfo=0 */ +/* ===== */ +, +"23.175.32.11 orport=443 id=56BAF2F6CAE76B1AC6C1F08C148D04C219E85E70" +" ipv6=[2606:d680:cafe:80:23:175:32:11]:443" +/* nickname=Wat1E1TorNodeIo */ +/* extrainfo=0 */ +/* ===== */ +, +"91.203.5.165 orport=443 id=AF1F15819AC766D6508A2B05DA989E99AB511F9F" +/* nickname=duchin */ +/* extrainfo=0 */ +/* ===== */ +, +"96.126.105.219 orport=5353 id=60A5547B2203DD2E148EF9BDD6FF3891081C5DF4" +" ipv6=[2600:3c03::f03c:91ff:fe93:5318]:5353" +/* nickname=HotPotato */ +/* extrainfo=0 */ +/* ===== */ +, +"212.32.240.165 orport=9001 id=CFDF99EE1923D870329F8DAE54398FD45409F01F" +/* nickname=UlhasTor */ +/* extrainfo=0 */ +/* ===== */ +, +"185.140.251.125 orport=9001 id=215CC28D7E273AE3308F041E45A8EE3BA6D85658" +/* nickname=HoarseSupernova */ +/* extrainfo=0 */ +/* ===== */ +, +"38.145.211.218 orport=9010 id=3FAFFA13BC88AB28EBA464A902FDED2EA453A581" +" ipv6=[2605:f700:40:401::2efa:261a]:9010" +/* nickname=edaks */ +/* extrainfo=0 */ +/* ===== */ +, +"217.112.131.24 orport=443 id=7896A8075D51F60B950D8E63AAC2899731060843" +/* nickname=licinius */ +/* extrainfo=0 */ +/* ===== */ +, +"46.38.232.203 orport=443 id=8B3A07D9155E76BB4AE922C8F99AE3AB7D88DD23" +/* nickname=ConcordiaConstanzia */ +/* extrainfo=0 */ +/* ===== */ +, +"194.76.227.152 orport=9001 id=2F98E853A570AC7A79B4082364B781AD67705074" +/* nickname=FireMateria */ +/* extrainfo=0 */ +/* ===== */ +, +"192.99.43.171 orport=9001 id=C92ECAF73512E2CCB15827A192B7AF3E9DBC896E" +/* nickname=Unnamed */ +/* extrainfo=0 */ +/* ===== */ +, +"104.244.72.20 orport=9001 id=799E0B28F45548F545668A78DF04CD23490EC585" +" ipv6=[2605:6400:30:efe6:1313:cafe:dead:beef]:9001" +/* nickname=Hermes */ +/* extrainfo=0 */ +/* ===== */ +, +"89.58.4.238 orport=9001 id=4745ACB16234385EF1694D530E109F7A573E30C6" +" ipv6=[2a03:4000:5e:d48:acab::10]:9001" +/* nickname=tweinode3 */ +/* extrainfo=0 */ +/* ===== */ +, +"51.15.54.117 orport=443 id=547E6E68ADE1B6F492C44443588A939610401DFB" +" ipv6=[2001:bc8:1820:c0d::1]:443" +/* nickname=taki */ +/* extrainfo=0 */ +/* ===== */ +, +"37.235.48.247 orport=7654 id=1F2077BF01CAF23F819D4892A89883196ABA842A" +" ipv6=[2a03:f80:48:37:235:48:247:1]:7654" +/* nickname=plutoa */ +/* extrainfo=0 */ +/* ===== */ +, +"51.159.184.219 orport=9001 id=6BE5AA34A5C391724677A3FDC2AA77B3768F6E26" +" ipv6=[2001:bc8:1200:4137::1]:9001" +/* nickname=tormaumauhosting */ +/* extrainfo=0 */ +/* ===== */ +, +"85.239.34.40 orport=9001 id=8E97A9FDBC262A2DB1C87B53F12CF1925866F355" +" ipv6=[2001:678:6d4:7410::12e]:9001" +/* nickname=itsnotjesse */ +/* extrainfo=0 */ +/* ===== */ +, +"198.251.68.144 orport=9001 id=83AEDBDB4BE3AD0ED91850BF1A521B843077759E" +/* nickname=focaltohr */ +/* extrainfo=0 */ +/* ===== */ +, +"89.58.3.65 orport=443 id=FF8B7CAD5F508972509D79F933FB24D2F524AB75" +" ipv6=[2a03:4000:5d:b8f:1478:68ff:fec4:27c7]:443" +/* nickname=einNettesRelay */ +/* extrainfo=0 */ +/* ===== */ +, +"172.106.112.50 orport=443 id=996F4CFD78130203B80E854A4EF6CA2355C6C72C" +/* nickname=Reeses1 */ +/* extrainfo=0 */ +/* ===== */ +, +"37.252.190.176 orport=443 id=81A59766272894D27FE8375C4F83A6BA453671EF" +/* nickname=chutney */ +/* extrainfo=0 */ +/* ===== */ +, +"185.25.51.138 orport=9001 id=D2380745937A994FE1E19859CBEBF181DBB80443" +" ipv6=[2a04:2180:0:1::fb6f:72f2]:9001" +/* nickname=IndigoMagick */ +/* extrainfo=0 */ +/* ===== */ +, +"93.95.231.115 orport=9001 id=3417F1F24A7CA4033DB514610321A1A9F410CC31" +/* nickname=MetalsAG */ +/* extrainfo=0 */ +/* ===== */ +, +"104.192.3.74 orport=443 id=849626A2A3DD1364E8C51423D6F3213A3AE16FFD" +" ipv6=[2605:aa80:0:9::3]:443" +/* nickname=OnionsHaveLayers */ +/* extrainfo=0 */ +/* ===== */ +, +"193.108.117.103 orport=9001 id=438F3EA4C9FB0DB63F5377A3271AB5435FAD7E04" +/* nickname=dolemite */ +/* extrainfo=0 */ +/* ===== */ +, +"68.67.32.33 orport=9001 id=4338C8026D468B811D3EB11AE9E421E2089B8239" +/* nickname=kgXuCTCWVMALFMb74Ld */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.118 orport=443 id=5F4CD12099AF20FAF9ADFDCEC65316A376D0201C" +" ipv6=[2620:7:6001::118]:80" +/* nickname=QuintexAirVPN7 */ +/* extrainfo=0 */ +/* ===== */ +, +"140.78.100.42 orport=5443 id=9D970B7FBAC353D8F6049AD4E0CEE06BBDE4E17E" +/* nickname=INSRelay42at5443 */ +/* extrainfo=0 */ +/* ===== */ +, +"190.211.254.182 orport=9001 id=3B557E3F0C29D4339A904AD8C641F582151FEF71" +/* nickname=ForestIsland */ +/* extrainfo=0 */ +/* ===== */ +, +"74.82.47.194 orport=9001 id=80E23F24D5BE0195D2827557D260D1676DEA5451" +" ipv6=[2001:470:1:908::9001]:9001" +/* nickname=deadbabecafe */ +/* extrainfo=0 */ +/* ===== */ +, +"130.61.174.201 orport=9001 id=519351E3D54202933F85E608D88484A5DC4E4EF0" +/* nickname=bigman */ +/* extrainfo=0 */ +/* ===== */ +, +"185.220.101.203 orport=8443 id=8F11B2E253CEC4C5C463BF38AB1CA645B7294D52" +" ipv6=[2a0b:f4c2:2:1::203]:8443" +/* nickname=ForPrivacyNET */ +/* extrainfo=0 */ +/* ===== */ +, +"185.241.208.204 orport=9000 id=9A8902B985E2F58BC740671040E7165AC904DD40" +/* nickname=Aramis */ +/* extrainfo=0 */ +/* ===== */ +, +"85.208.144.164 orport=443 id=B13C2C569F3FD0C530B7D96E5FF7933DF7A0E834" +" ipv6=[2a09:8740:0:3::13:4008]:443" +/* nickname=porte */ +/* extrainfo=0 */ +/* ===== */ +, +"185.14.30.57 orport=9001 id=58FC2AAB3792AC37897D34331F4F4E00341DEC0C" +" ipv6=[2a02:27ab:0:2::22]:9001" +/* nickname=zwewwlNL1 */ +/* extrainfo=0 */ +/* ===== */ +, +"193.56.240.157 orport=443 id=8E6225BC8A770DF63B20A2FDAC1ABCD795A18987" +/* nickname=skaalz */ +/* extrainfo=0 */ +/* ===== */ +, +"185.244.195.103 orport=9100 id=DFA97DED4CE79FF6F31DAF917C2810CCE8729E9D" +" ipv6=[2a03:4000:27:713:4489:4cff:feab:96fc]:9100" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"155.248.212.228 orport=443 id=E5E553F51D82035A2CE555DBC7D883FAA32ED0B5" +" ipv6=[2603:c024:c000:e400:5d76:a308:5c3a:b70]:443" +/* nickname=yyzz1 */ +/* extrainfo=0 */ +/* ===== */ +, +"95.216.27.105 orport=9001 id=0B45375A2CE8065E8A649D52CC35F39D128745A8" +" ipv6=[2a01:4f9:2a:1b96:2::2]:443" +/* nickname=Ranlvor */ +/* extrainfo=0 */ +/* ===== */ +, +"185.220.101.68 orport=9000 id=42438E63C78CF0624BD7D212524FFE292D8FE3D5" +/* nickname=CCCStuttgartBer */ +/* extrainfo=0 */ +/* ===== */ +, +"103.28.52.93 orport=443 id=C5A6FEE5BC3BE19F5B9EB086CA95DAD393D8A4F6" +/* nickname=jivin */ +/* extrainfo=0 */ +/* ===== */ +, +"82.66.10.17 orport=19001 id=8F7521CEDA9AB705A42254E1E829268DEF57C70E" +/* nickname=bigbrother23470 */ +/* extrainfo=0 */ +/* ===== */ +, +"185.247.226.98 orport=443 id=9AB4B4F5B279DC611BEB62E4528EB91F59A6BB14" +" ipv6=[2a06:1700:2:17:0:5232:2d:4432]:443" +/* nickname=R2D2 */ +/* extrainfo=0 */ +/* ===== */ +, +"178.27.106.248 orport=9031 id=9C305BC09852C7CB62E9A41F9ECA108BBFB23521" +/* nickname=Feidhlim04 */ +/* extrainfo=0 */ +/* ===== */ +, +"140.78.100.28 orport=5443 id=0DBA891A70AE95D4AD77593A936E6C04ABF2E7CE" +/* nickname=INSRelay28at5443 */ +/* extrainfo=0 */ +/* ===== */ +, +"65.108.136.183 orport=443 id=C3F7F3E1E32A64B22B2F0734E7C7A312F993D102" +" ipv6=[2a01:4f9:6b:3408::4]:443" +/* nickname=arbitraryKenzie4 */ +/* extrainfo=0 */ +/* ===== */ +, +"51.15.185.201 orport=443 id=1079E628FC6B0025656AC024F2D9975C441498CD" +/* nickname=PoochySloochy */ +/* extrainfo=0 */ +/* ===== */ +, +"171.25.193.234 orport=80 id=CF1C1804C33CD69D8A75587FABC63D5D0E2980FA" +" ipv6=[2001:67c:289c:2::234]:80" +/* nickname=DFRI10 */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.105 orport=443 id=9F2856F6D2B89AD4EF6D5723FAB167DB5A53519A" +" ipv6=[2620:7:6001::105]:80" +/* nickname=Quintex15 */ +/* extrainfo=0 */ +/* ===== */ +, +"89.236.112.100 orport=443 id=00CCE6A84E6D63A1A42E105839BC8ED5D4B16669" +/* nickname=effiorg1984 */ +/* extrainfo=0 */ +/* ===== */ +, +"209.209.11.184 orport=31289 id=21FFF594CFE691A4A03B828E9597A9F74F878053" +" ipv6=[2602:ffd5:1:112::1]:31288" +/* nickname=Woodman */ +/* extrainfo=0 */ +/* ===== */ +, +"93.95.230.85 orport=443 id=3B20B5D120AB8CC1780F43216DC9C6051ED5C387" +/* nickname=Unnamed */ +/* extrainfo=0 */ +/* ===== */ +, +"84.158.138.52 orport=10222 id=C4C462506D54EDC8EFC8E88E32F4AE014755035A" +/* nickname=s0yb3an */ +/* extrainfo=0 */ +/* ===== */ +, +"89.147.108.62 orport=443 id=F3A9588FB45F76DA4DE5B350C425C130F6FFA983" +/* nickname=Reichsfunkmast2 */ +/* extrainfo=0 */ +/* ===== */ +, +"46.4.103.29 orport=9001 id=46DB04323499DD535956531DF2BF7B03EB2AB15D" +" ipv6=[2a01:4f8:140:94d6::2]:9001" +/* nickname=mickymouse */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.168 orport=443 id=F664E5E50B4D216E5940DA7E9CF653F5F9DC561B" +" ipv6=[2620:7:6001::168]:80" +/* nickname=Quintex79 */ +/* extrainfo=0 */ +/* ===== */ +, +"185.239.222.245 orport=443 id=3DCECAF7089B1C2CE3EA9504EE05CE754F4CF9A8" +" ipv6=[2a09:2681:101:9001::6]:443" +/* nickname=BM06 */ +/* extrainfo=0 */ +/* ===== */ +, +"94.16.117.97 orport=9000 id=13FBC97516DC854399E70BC7CA9A4513FFD4F08C" +" ipv6=[2a03:4000:29:1:d4b9:91ff:fe6e:e48a]:9000" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"46.163.76.170 orport=9001 id=3E2C933BE54585C760FD6D2F3FA7A33E373A7145" +" ipv6=[2a01:488:66:1000:2ea3:4caa:0:1]:9001" +/* nickname=judas */ +/* extrainfo=0 */ +/* ===== */ +, +"204.85.191.8 orport=443 id=7C0AA4E3B73E407E9F5FEB1912F8BE26D8AA124D" +/* nickname=ibibUNC0 */ +/* extrainfo=0 */ +/* ===== */ +, +"109.190.177.33 orport=9999 id=A8874E2C45F445DBA462A914ED8D3AF045734FFB" +/* nickname=computel */ +/* extrainfo=0 */ +/* ===== */ +, +"176.10.119.69 orport=9001 id=FFC3F4BE4D5C392246DC7A37B256A6158C3D8562" +/* nickname=euler */ +/* extrainfo=0 */ +/* ===== */ +, +"162.251.116.106 orport=443 id=24A818D9F1E09F1845FC1589DE5AAF15C8E0867E" +/* nickname=goingin */ +/* extrainfo=0 */ +/* ===== */ +, +"198.50.238.128 orport=443 id=C7946D9A192BBE44C1C8A926A8B135AC495D6636" +/* nickname=t0adwarri0r */ +/* extrainfo=0 */ +/* ===== */ +, +"157.90.92.115 orport=9001 id=AC633C90E126E0BCA96F14ECE5D222B586FA0D56" +" ipv6=[2a01:4f8:252:3df0::2]:9001" +/* nickname=SODrelay */ +/* extrainfo=0 */ +/* ===== */ +, +"132.145.22.208 orport=443 id=A8FB73D917B7C2B851A358729359E13EBA5978FA" +" ipv6=[2603:c020:c007:cab:5235:2d:534b:31]:443" +/* nickname=R5SK1 */ +/* extrainfo=0 */ +/* ===== */ +, +"91.203.144.194 orport=443 id=B1B687C3C4EF46249D638DCE77DDC7AAA39F2996" +/* nickname=yetiready */ +/* extrainfo=0 */ +/* ===== */ +, +"204.85.191.9 orport=443 id=C59E079437340E3AD14E6785C0A91A5B6F328566" +/* nickname=ibibUNC1 */ +/* extrainfo=0 */ +/* ===== */ +, +"46.232.250.51 orport=443 id=D1C60F9BCF2DBA07A775978F66C9927D3A9490BB" +" ipv6=[2a03:4000:2b:673:24da:28ff:feb5:e5c5]:443" +/* nickname=juggernautrelay */ +/* extrainfo=0 */ +/* ===== */ +, +"45.155.168.206 orport=443 id=6F9B7403B4CD1F48269730D1F9ED0E7A75C1F049" +/* nickname=WizardFair */ +/* extrainfo=0 */ +/* ===== */ +, +"185.243.218.27 orport=443 id=A5E42F1A3AFA948A7F2FDB1954A4CF6C6489D418" +" ipv6=[2a03:94e0:ffff:185:243:218:0:27]:443" +/* nickname=bauruine */ +/* extrainfo=0 */ +/* ===== */ +, +"51.75.129.204 orport=443 id=2CE9BE1FC88B9D0FA03F387C9E4F000B5D4B2AE9" +/* nickname=ridin */ +/* extrainfo=0 */ +/* ===== */ +, +"188.68.36.28 orport=9001 id=7260949459C2D4D4A5ABC3AC10C1AD6939E6525C" +" ipv6=[2a03:4000:13:7c3:a401:f1ff:fe45:7ffc]:9001" +/* nickname=Piratenpartei05 */ +/* extrainfo=0 */ +/* ===== */ +, +"82.149.227.124 orport=8080 id=7A6EC43FD4CD5990230FCE48EC37AFC578E36CE6" +" ipv6=[2a01:440:108:11:82:149:227:124]:8080" +/* nickname=cryzrelay03 */ +/* extrainfo=0 */ +/* ===== */ +, +"135.148.100.90 orport=443 id=728F97D5BCB131698814D8C713C2220C6E7267DE" +/* nickname=CanisLatrans */ +/* extrainfo=0 */ +/* ===== */ +, +"185.183.157.127 orport=9100 id=34B80D703F4D6350146B684E66D962A23A830117" +" ipv6=[2a03:4000:1d:b56:5850:c5ff:feca:c5b0]:9100" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"179.43.159.194 orport=9001 id=617C95FCF5F00E98E73E35A71C066ED20614F26D" +/* nickname=FreeExit */ +/* extrainfo=0 */ +/* ===== */ +, +"185.244.195.157 orport=9100 id=69042D6B301F080105D11478A5BC848EB0B5D5DB" +" ipv6=[2a03:4000:27:747:4804:22ff:fe7a:e606]:9100" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"178.254.6.130 orport=443 id=7A2D44E76934D709CBF0E0AE8FEB132B61B6F35D" +" ipv6=[2a00:6800:3:35b::2]:443" +/* nickname=zensursula */ +/* extrainfo=0 */ +/* ===== */ +, +"142.132.204.165 orport=4080 id=6CBA90E31188A65E2B6AC1EE8412E8DE571ECAD6" +" ipv6=[2a01:4f8:261:50da::2]:4080" +/* nickname=spicyavocado */ +/* extrainfo=0 */ +/* ===== */ +, +"66.183.173.29 orport=22 id=E8FA2C9B690F3BC16ADE9A4803CE2C51132F10A6" +/* nickname=tengu */ +/* extrainfo=0 */ +/* ===== */ +, +"31.171.154.165 orport=9001 id=A1177D4BF4698A74B926AE1E0FC533578FA55667" +/* nickname=Tirana */ +/* extrainfo=0 */ +/* ===== */ +, +"91.134.147.134 orport=9001 id=2AD82F3964D325B3FE2FF74E980FB006374EF190" +/* nickname=Unnamed */ +/* extrainfo=0 */ +/* ===== */ +, +"193.105.73.80 orport=9001 id=9DC8B0282A8D3C45212167C454B503243BC93957" +/* nickname=akira */ +/* extrainfo=0 */ +/* ===== */ +, +"140.78.100.22 orport=5443 id=69D7FEF9B0026393C2FD73E897C71C102ABACA5C" +/* nickname=INSRelay22at5443 */ +/* extrainfo=0 */ +/* ===== */ +, +"23.129.64.217 orport=443 id=41C80C52AC82295A4D4308D30DCCD3D4ABC4F66C" +" ipv6=[2620:18c:0:192::217]:443" +/* nickname=EO */ +/* extrainfo=0 */ +/* ===== */ +, +"65.108.253.128 orport=443 id=0B53BF919B9A01ED62ED10E51292ACA50DDB10EB" +" ipv6=[2a01:4f9:c011:9e93::1]:443" +/* nickname=l0z3rzb3d4m3d */ +/* extrainfo=0 */ +/* ===== */ +, +"198.98.60.107 orport=443 id=23C64D7C96C8390013C9E583230E81E70F81F756" +/* nickname=BingusBongus */ +/* extrainfo=0 */ +/* ===== */ +, +"188.68.40.46 orport=9100 id=2EFC2B8BC724CF435C14066087936BE7CA3C57A3" +" ipv6=[2a03:4000:17:5c:24df:84ff:fe54:82aa]:9100" +/* nickname=Quetzalcoatl */ +/* extrainfo=0 */ +/* ===== */ +, +"138.201.35.6 orport=9001 id=94B710C41B9E8FB592D0916E71B5A89FF4995996" +" ipv6=[2a01:4f8:171:369a::2]:9001" +/* nickname=torrelay */ +/* extrainfo=0 */ +/* ===== */ +, +"51.81.208.164 orport=443 id=756576CF5DA387CDD7EABCCA3F8EAEF933CB4486" +/* nickname=screenslaver */ +/* extrainfo=0 */ +/* ===== */ +, +"89.147.109.91 orport=443 id=7155DE90C1C3C9BF4D637580C7F027E57227BD30" +/* nickname=Unnamed */ +/* extrainfo=0 */ +/* ===== */ +, +"152.70.197.164 orport=443 id=F882E4A4B73447C561617005C8E692B0A7080802" +/* nickname=screwTheNSA */ +/* extrainfo=0 */ +/* ===== */ +, +"163.172.211.16 orport=443 id=05F5062943054646CC7A65532CE52598052628FA" +/* nickname=FreeUyghur */ +/* extrainfo=0 */ +/* ===== */ +, +"174.128.250.164 orport=80 id=5197FC89F7A1623CA90D6E0254ABCCBC6D85A86E" +/* nickname=ready2 */ +/* extrainfo=0 */ +/* ===== */ +, +"13.211.32.165 orport=9001 id=956CD533B7C331C675D30A50900A2E9777D42782" +/* nickname=BlueMonkey */ +/* extrainfo=0 */ +/* ===== */ +, +"116.12.180.237 orport=7443 id=10805A3833774B812D07EB7D1D75A54021590F56" +/* nickname=tommyboy */ +/* extrainfo=0 */ +/* ===== */ +, +"212.192.246.55 orport=443 id=7B24FA67347BEAEC6923D884EACF1C123180DE32" +/* nickname=0x616e6f6e */ +/* extrainfo=0 */ +/* ===== */ +, +"150.246.240.221 orport=443 id=E3F7DA7CC7D5B6CC085799AE0404AA4D2D503E50" +/* nickname=90377Sedna */ +/* extrainfo=0 */ +/* ===== */ +, +"5.189.155.39 orport=9001 id=00962D2DD0B9BF3A6AF1D5EB201132388ACA1424" +/* nickname=BlackBeluga */ +/* extrainfo=0 */ +/* ===== */ +, +"104.244.72.91 orport=9001 id=BD140758135A15605996CCEE3BBFA4127F97B233" +/* nickname=Hydra44 */ +/* extrainfo=0 */ +/* ===== */ +, +"103.109.100.207 orport=9001 id=D08C694485A0031692FAFE8C3205FBBBDBCD9402" +/* nickname=thelastvampire */ +/* extrainfo=0 */ +/* ===== */ +, +"171.25.193.80 orport=80 id=491B4E55B4FD4FDEC63B229B0A3E59868FCA1F1F" +" ipv6=[2001:67c:289c:4::79]:80" +/* nickname=DFRI22 */ +/* extrainfo=0 */ +/* ===== */ +, +"199.249.230.152 orport=443 id=4EE488AC0742BC6B747BB637A5635CE14E877F39" +" ipv6=[2620:7:6001::152]:80" +/* nickname=Quintex63 */ +/* extrainfo=0 */ +/* ===== */ +, +"188.68.224.83 orport=443 id=A6BBD33695A4E3C4545BA370605A4DCD87D98BEE" +/* nickname=ATLANTIS */ +/* extrainfo=0 */ +/* ===== */ +, +"37.133.161.205 orport=9001 id=96C36107664B4406C38CD8676AEA85E4D8BCE825" +/* nickname=tor4win */ +/* extrainfo=0 */ +/* ===== */ +, +"198.180.150.9 orport=9001 id=60E4C5E306D2DB22890EE24A09F9B6C30AF396A8" +" ipv6=[2001:418:8006::9]:9001" +/* nickname=rgiad */ +/* extrainfo=0 */ +/* ===== */ +, +"129.151.246.99 orport=9001 id=439CD12F87CEB496D2601B5DC1FF5186BD9AC2D1" +/* nickname=tallinn21 */ +/* extrainfo=0 */ +/* ===== */ +, +"130.162.218.212 orport=9001 id=944E947CA80D1CF8B2EBE3C3247B2C11931438B8" +/* nickname=Perch */ +/* extrainfo=0 */ +/* ===== */ +, +"86.115.2.103 orport=9001 id=E816C4D4CDA9810D2CB1371257462FF6BCE4DF91" +/* nickname=homebox57 */ +/* extrainfo=0 */ +/* ===== */ +, diff --git a/README.md b/README.md index 28e3dfcd..d73da86e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + NOnion ------------------------------- [![Build Status](https://github.com/aarani/NOnion/actions/workflows/CI.yml/badge.svg?branch=master&event=push)](https://github.com/aarani/NOnion/actions/workflows/CI.yml) @@ -5,6 +6,7 @@ NOnion _Unofficial_ work in progress .NET TOR client library (implemented in F#) - [How do I add this to my project?](#how-do-i-add-this-to-my-project) +- [Getting Started](#getting-started) - [Contributing](#contributing) - [Contributors](https://github.com/aarani/NOnion/graphs/contributors) - [License](https://github.com/aarani/NOnion/blob/master/LICENSE) @@ -23,6 +25,76 @@ Install via NuGet: > Install-Package NOnion ``` +# Getting Started (F#) + +## Bootstrapping + +To utilize the Tor network, start by bootstrapping your directory. This step involves downloading the most recent information about available routers and their identity keys. + +To initiate the bootstrapping process, you require a list of initial nodes for communication. In NOnion, there are two methods to obtain this list: +1- [Download from Github](https://github.com/torproject/tor/blob/main/src/app/config/fallback_dirs.inc) +2- Utilize the embedded list in the NOnion binary (Note: this list could potentially be outdated) + +Based on what option you choose use one of the following commands to bootstrap a TorClient object: +``` +let! torClient = TorClient.AsyncBootstrapWithEmbeddedList None +``` +### OR +``` +let! torClient = TorClient.AsyncBootstrapWithGithub None +``` +## Browsing the web + +To route your traffic through Tor, you require a circuit, which consists of multiple hops or routers. NOnion simplifies this process for you. Just specify the desired length of your circuit and use the following command: +``` +let hopCount = 3 // any length you want +let! circuit = torClient.AsyncCreateCircuit hopCount Exit None +``` +Once the circuit is established, generate a stream to channel your traffic and establish a connection with your intended destination. +``` +let address = "google.com" // Hostname you want to connect to +let port = 80 // Port you want to connect it + +do! + stream.ConnectToOutside address port + |> Async.Ignore +``` +Now, utilize the stream just like any other `System.IO.Stream`: +``` +do! stream.AsyncWrite [|1uy; 2uy; 3uy; 4uy|] +``` + +## Connecting to hidden services + +To connect to a hidden service using the Tor network, use the folowing command: +``` +let onionAddress = "facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion" + +let! serviceClient = TorServiceClient.Connect torClient onionAddress +let stream = serviceClient.GetStream() +``` +Now, utilize the stream just like any other `System.IO.Stream`: +``` +do! + sprintf "GET / HTTP/1.0\r\n\r\n" + |> System.Text.Encoding.ASCII.GetBytes + |> stream.AsyncWrite +``` +## Hosting a hidden service +Start a hidden service, use the following command: +``` +let serviceHost = new TorServiceHost(torClient, None) +do! serviceHost.Start() +``` +*Note: use TorServiceHost's `maybeMasterPrivateKey` parameter to supply your existing bouncy castle private key* + +Now use the following command to wait for incoming streams/clients: +``` +let! incomingStream = serviceHost.AcceptClient() +``` +Now, utilize the stream just like any other `System.IO.Stream`. + +#### Everything mentioned above can be accomplished in C#. Our test project is also written in C#, so feel free to examine it. # Contributing Don't underestimate the power of your contribution - even a small pull request can make a big difference in a small project, so submit yours today!