Почему при использовании torify с aiohttp возникает ошибка «Cannot connect to host python.org:80 ssl:default [Could not contact DNS servers]»?

В системе Linux Mint с установленным Python 3.12, я заметил, что команда torify работает корректно с curl. После активации виртуального окружения и запуска Tor, при выполнении следующего кода возникает ошибка. Вот сам код:

```python
import aiohttp
import asyncio

async def main():
    async with aiohttp.ClientSession(trust_env=True) as session:
        async with session.get(
            'http://python.org'
        ) as response:
            print("Status:", response.status)
            print("Content-type:", response.headers['content-type'])
            html = await response.text()
            print("Body:", html[:15], "...")

asyncio.run(main())
```

Когда я запускаю скрипт с помощью `$ python3 test.py`, он выдает ожидаемые результаты:

```
Status: 200
Content-type: text/html; charset=utf-8
Body:  ...
```

Однако, при выполнении `$ torify python3 test.py` появляется следующая ошибка:

```
(.venv) oleg@oleg:~/Документы/pyscripts/$ torify python3 test.py
Traceback (most recent call last):
  File "/home/oleg/Документы/pyscripts/.venv/lib/python3.12/site-packages/aiohttp/resolver.py", line 103, in resolve
    resp = await self._resolver.getaddrinfo(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
aiodns.error.DNSError: (11, 'Could not contact DNS servers')

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/oleg/Документы/pyscripts/.venv/lib/python3.12/site-packages/aiohttp/connector.py", line 1362, in _create_direct_connection
    hosts = await self._resolve_host(host, port, traces=traces)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

Как можно решить проблему с ошибкой "Could not contact DNS servers" при использовании torify для запуска скрипта?
  • 18 марта 2025 г. 2:54
Ответы на вопрос 1
Ошибка, с которой вы столкнулись, связана с тем, что `aiohttp`, использующий `aiodns` для разрешения DNS, не может обратиться к DNS-серверам при запуске через `torify`. Это происходит потому, что `torify` перенаправляет весь трафик через Tor, включая DNS-запросы, но за его пределами `aiohttp` может пытаться разрешить DNS-запросы напрямую, что недоступно из-за Tor.

Вот несколько шагов, которые могут помочь решить вашу проблему:

1. **Настройка aiohttp для использования Tor:**
   Чтобы гарантировать, что все DNS-запросы проходят через Tor, вы можете использовать специальный IPv4-транспортный прокси-транспорт из библиотеки aiohttp. Попробуйте использовать `aiohttp_socks`, который поддерживает SOCKS-прокси.

   Установите библиотеку `aiohttp_socks`:
   ```bash
   pip install aiohttp_socks
   ```

2. **Модификация вашего кода:**
   Внесите изменения в код, чтобы использовать SOCKS-прокси через `aiohttp_socks`. Вот как можно измененный код:

   ```python
   import aiohttp
   import asyncio
   from aiohttp_socks import ProxyConnector

   async def main():
       connector = ProxyConnector.from_url('socks5h://127.0.0.1:9050')  # Используйте SOCKS5 через Tor
       async with aiohttp.ClientSession(connector=connector, trust_env=True) as session:
           async with session.get('http://python.org') as response:
               print("Status:", response.status)
               print("Content-type:", response.headers['content-type'])
               html = await response.text()
               print("Body:", html[:15], "...")

   asyncio.run(main())
   ```

3. **Проверка конфигурации Tor:**
   Убедитесь, что Tor запущен и работает корректно. Tor по умолчанию работает на порту `9050` (SOCKS5). Вы можете также проверить конфигурацию Tor, включая информацию о том, какие порты используются.

4. **Использование torify без ошибок:**
   Если вы хотите сохранить способ запуска через `torify`, убедитесь, что ваш код использует только те способы, которые разрешают DNS через Tor. Обычно использование доменов в формате `socks5h://` позволяет делать это автоматически.

После внесения этих изменений попробуйте снова запустить ваш скрипт через Tor и проверьте результат.
Похожие вопросы