I am trying to connect to a .onion
site using python. I have tor running on port 9050 and I am getting the following error:
Traceback (most recent call last):
File "/Users/jane/code/test/test.py", line 15, in main
res = await fetch(session, id)
File "/Users/jane/code/test/test.py", line 9, in fetch
async with session.get(url) as res:
File "/usr/local/lib/python3.7/site-packages/aiohttp/client.py", line 1005, in __aenter__
self._resp = await self._coro
File "/usr/local/lib/python3.7/site-packages/aiohttp/client.py", line 476, in _request
timeout=real_timeout
File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 522, in connect
proto = await self._create_connection(req, traces, timeout)
File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 854, in _create_connection
req, traces, timeout)
File "/usr/local/lib/python3.7/site-packages/aiohttp/connector.py", line 959, in _create_direct_connection
raise ClientConnectorError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host intelex7ny6coqno.onion:80 ssl:None [nodename nor servname provided, or not known]
The code:
import asyncio
import aiohttp
from aiohttp_socks import SocksConnector
async def fetch(session, id):
print('Starting {}'.format(id))
url = 'http://intelex7ny6coqno.onion/topic/{}'.format(id)
async with session.get(url) as res:
return res.text
async def main(id):
connector = SocksConnector.from_url('socks5://localhost:9050')
async with aiohttp.ClientSession(connector=connector) as session:
res = await fetch(session, id)
print(res)
if __name__ == '__main__':
ids = ['10', '11', '12']
loop = asyncio.get_event_loop()
future = [asyncio.ensure_future(main(id)) for id in ids]
loop.run_until_complete(asyncio.wait(future))
This code works fine:
import requests
session = requests.session()
session.proxies['http'] = 'socks5h://localhost:9050'
session.proxies['https'] = 'socks5h://localhost:9050'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
}
res = session.get(url, headers=headers)
print(res)
Why am I getting Cannot connect to host intelex7ny6coqno.onion:80 ssl:None [nodename nor servname provided, or not known]
?
What am I missing here?
By default it appears to be using the local DNS resolver to asynchronously resolve hostnames. When using requests socks5h
you are getting DNS resolution over SOCKS (Tor).
Adding rdns=True appears to work for .onion addresses:
connector = SocksConnector.from_url('socks5://localhost:9050', rdns=True)