Git Product home page Git Product logo

aiotor's Introduction

aiotor Python Versions Build Status Build status Coverage Status

A pure python asynchronous Tor client implementation. aiotor can be used to communicate with clearnet hosts or hidden services through the Tor Network.

Features

  • Asynchronous implementation
  • No Stem or official Tor client required
  • Support v2 hidden services (v2 specification)
  • Support Basic and Stealth authorization protocol
  • ...

Note: This product is produced independently from the Tor® anonymity software and carries no guarantee from The Tor Project about quality, suitability or anything else.

Console examples

There are several console utilities to test the client.

A simple HTTP/HTTPS request:

$ aiotor --aiohttp-lib --url https://ifconfig.me --header "User-Agent" "curl/7.37.0"
Loading cached NetworkStatusDocument from TorCacheDirStorage: .../.local/share/aiotor/network_status
Loading cached DirKeyCertificateList from TorCacheDirStorage: .../.local/share/aiotor/dir_key_certificates
Connecting to guard node 51.161.43.235:443 (BungeeNet1; Tor 0.4.4.6) (TorClient)...
Creating new circuit #80000001 with 51.161.43.235:443 (BungeeNet1; Tor 0.4.4.6) router...
Getting descriptor for 51.161.43.235:443 (BungeeNet1; Tor 0.4.4.6)...
Connecting to guard node 185.90.61.219:443 (Unnamed; Tor 0.4.4.5) (Router descriptor downloader)...
Creating new circuit #80000002 with 185.90.61.219:443 (Unnamed; Tor 0.4.4.5) router...
Building 0 hops circuit...
Stream #1: creating attached to #80000002 circuit...
Stream #1: connecting to dir
Stream #1: EOF received from remote (DONE)
Stream #1: close
Got descriptor
Building 3 hops circuit...
Extending the circuit #80000001 with 104.57.231.27:80 (bosses2; Tor 0.4.3.6)...
Getting descriptor for 104.57.231.27:80 (bosses2; Tor 0.4.3.6)...
Stream #2: creating attached to #80000002 circuit...
Stream #2: connecting to dir
Stream #2: EOF received from remote (DONE)
Stream #2: close
Got descriptor
Extending the circuit #80000001 with 171.25.193.25:443 (DFRI5; Tor 0.4.3.6)...
Getting descriptor for 171.25.193.25:443 (DFRI5; Tor 0.4.3.6)...
Stream #3: creating attached to #80000002 circuit...
Stream #3: connecting to dir
Stream #3: EOF received from remote (DONE)
Stream #3: close
Got descriptor
Stream #4: creating attached to #80000001 circuit...
Stream #4: connecting to ('ifconfig.me', 443)
Closing guard connection 51.161.43.235:443 (BungeeNet1; Tor 0.4.4.6) (TorClient)...
Destroy circuit #80000001
Stream #4: close
Closing guard connection 185.90.61.219:443 (Unnamed; Tor 0.4.4.5) (Router descriptor downloader)...
Destroy circuit #80000002
> 171.25.193.25

aiotor module also has a command-line interface:

$ python3.7 -m aiotor --aiohttp-lib --url https://facebookcorewwwi.onion --to-file index.html
Loading cached NetworkStatusDocument from TorCacheDirStorage: .../.local/share/aiotor/network_status
Loading cached DirKeyCertificateList from TorCacheDirStorage: .../.local/share/aiotor/dir_key_certificates
Connecting to guard node 188.120.234.26:443 (morha; Tor 0.4.3.5) (TorClient)...
Creating new circuit #80000001 with 188.120.234.26:443 (morha; Tor 0.4.3.5) router...
Getting descriptor for 188.120.234.26:443 (morha; Tor 0.4.3.5)...
Connecting to guard node 51.15.118.10:443 (Yggdrasil; Tor 0.4.4.6) (Router descriptor downloader)...
Creating new circuit #80000002 with 51.15.118.10:443 (Yggdrasil; Tor 0.4.4.6) router...
Building 0 hops circuit...
Stream #1: creating attached to #80000002 circuit...
Stream #1: connecting to dir
Stream #1: EOF received from remote (DONE)
Stream #1: close
Got descriptor
Building 3 hops circuit...
Extending the circuit #80000001 with 188.165.255.84:4443 (Unnamed; Tor 0.4.3.7)...
Getting descriptor for 188.165.255.84:4443 (Unnamed; Tor 0.4.3.7)...
Stream #2: creating attached to #80000002 circuit...
Stream #2: connecting to dir
Stream #2: EOF received from remote (DONE)
Stream #2: close
Got descriptor
Extending the circuit #80000001 with 185.220.101.129:10129 (relayon0224; Tor 0.4.3.6)...
Getting descriptor for 185.220.101.129:10129 (relayon0224; Tor 0.4.3.6)...
Stream #3: creating attached to #80000002 circuit...
Stream #3: connecting to dir
Stream #3: EOF received from remote (DONE)
Stream #3: close
Got descriptor
Stream #4: creating attached to #80000001 circuit...
Extending #80000001 circuit for hidden service facebookcorewwwi.onion...
Rendezvous established (CellRelayRendezvousEstablished())
Iterate over responsible dirs of the hidden service
Iterate over introduction points of the hidden service
...
Create circuit for hsdir
Creating new circuit #80000006 with 188.120.234.26:443 (morha; Tor 0.4.3.5) router...
Building 0 hops circuit...
Extending the circuit #80000006 with 5.135.162.49:9001 (AnotherTorRelay; Tor 0.4.4.6)...
Getting descriptor for 5.135.162.49:9001 (AnotherTorRelay; Tor 0.4.4.6)...
Stream #11: creating attached to #80000002 circuit...
Stream #11: connecting to dir
Stream #11: EOF received from remote (DONE)
Stream #11: close
Got descriptor
Stream #12: creating attached to #80000006 circuit...
Stream #12: connecting to dir
Stream #12: EOF received from remote (DONE)
Stream #12: close
Destroy circuit #80000006
Creating new circuit #80000007 with 188.120.234.26:443 (morha; Tor 0.4.3.5) router...
Building 0 hops circuit...
Extending the circuit #80000007 with 62.210.125.130:443 (bradburn; Tor 0.3.5.10)...
Getting descriptor for 62.210.125.130:443 (bradburn; Tor 0.3.5.10)...
Stream #13: creating attached to #80000002 circuit...
Stream #13: connecting to dir
Stream #13: EOF received from remote (DONE)
Stream #13: close
Got descriptor
Introduced (CellRelayIntroduceAck())
Destroy circuit #80000007
Stream #4: connecting to ('facebookcorewwwi.onion', 443)
Stream #14: creating attached to #80000001 circuit...
Extending #80000001 circuit for hidden service facebookcorewwwi.onion...
Stream #14: connecting to ('www.facebookcorewwwi.onion', 443)
Closing guard connection 188.120.234.26:443 (morha; Tor 0.4.3.5) (TorClient)...
Destroy circuit #80000001
Stream #4: close
Stream #14: close
Closing guard connection 51.15.118.10:443 (Yggdrasil; Tor 0.4.4.6) (Router descriptor downloader)...
Destroy circuit #80000002
Writing to file index.html

Usage examples

A basic example of how to send some data to a clearnet host or a hidden service:

from aiotor import TorClient

hostname = 'ifconfig.me'  # It's possible use onion hostname here as well
async with TorClient() as tor:
    # Choose random guard node and create 3-hops circuit
    async with tor.create_circuit(3) as circuit:
        # Create tor connection to host
        async with circuit.create_connection(hostname, 80) as (r, w):
            # Now we can communicate with host
            w.write(b'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % hostname.encode())
            response = await r.read()

TorConnector is a convenient TCPConnector for the aiohttp library. The following example shows the usage of TorConnector:

from aiotor.utils import aiohttp_client_session

async with aiohttp_client_session() as client:
    async with client.request("GET", "https://httpbin.org/headers") as resp:
        assert resp.status == 200
        print(await resp.text())

For more examples see test_integration.py

Installation

  • Just pip3 install aiohttp
  • Or for using TorConnector with aiohttp library you need install extras: pip3 install aiotor[aiohttp]

Contribute

  • Use It
  • Code review is appreciated
  • Open Issue, send PR

TODO

  • Implement v3 hidden services specification
  • Refactor Tor cells serialization/deserialization
  • More unit tests
  • Implement onion services

License

Licensed under the Apache License, Version 2.0

References

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.