Введение
Еще в 1990-х годах Интернет был небезопасным местом, где сетевой трафик в значительной степени не шифровался и отслеживался, что позволяло хакерам выполнять атаки «человек посередине» и легко собирать личные данные. Чтобы решить эту проблему, группа исследователей из военно-морской исследовательской лаборатории США запустила проект The Onion Routing (TOR) с целью анонимизации и защиты коммуникаций в Интернете.
Методология
TOR использует модель распределенного доверия для защиты вашего сетевого трафика через Интернет. Это методология, при которой ваши данные шифруются несколькими сторонами для обеспечения многоуровневой защиты данных (например, Onion). Так что ваши данные будут в безопасности, если только кто-то не сможет взломать все стороны, участвующие в шифровании.
На практике TOR выбирает 3 уникальных ретранслятора, управляемых разными организациями, для шифрования и маршрутизации вашего сетевого трафика до достижения конечного пункта назначения.
Вот простая диаграмма, иллюстрирующая методологию.
Чтобы узнать больше о TOR, у Velentin Quelquejay есть отличная статья.
В этой статье я сосредоточусь на практическом аспекте настройки прокси-сервера TOR с Python, поскольку я чувствовал, что в этой области не хватает онлайн-материалов и дискуссий.
Чтобы помочь вам учиться более эффективно, я разделил это руководство на 3 уровня сложности, охватывая полезные функции TOR, которые позволяют вам использовать весь его потенциал.
Предпосылки
Прежде чем продолжить работу с этим учебным пособием, убедитесь, что у вас установлено следующее.
- Python3
- Шток установки штифта
- Git-клон https://github.com/ohyicong/Tor
Базовая настройка: конфигурация по умолчанию
Вот простой и эффективный код для создания прокси-сервера TOR с использованием конфигурации по умолчанию:
- Установить прокси на локальный порт 9050
- Установите соединение TOR через 3 уникальных реле (случайно)
- Меняет IP-адрес каждые 10 минут
# complete code found in create_basic_tor_proxy.py import io import os import stem.process import re SOCKS_PORT = 9050 TOR_PATH = os.path.normpath(os.getcwd()+"\\tor\\tor.exe") tor_process = stem.process.launch_tor_with_config( config = { 'SocksPort': str(SOCKS_PORT), }, init_msg_handler = lambda line: print(line) if re.search('Bootstrapped', line) else False, tor_cmd = TOR_PATH )
Чтобы проверить, прошла ли ваша настройка успешно, вы можете сделать запрос GET на http://ip-api.com/json/. Если IP-адрес из другой страны, вы успешно настроили свой первый прокси-сервер TOR!
import requests import json from datetime import datetime PROXIES = { 'http': 'socks5://127.0.0.1:9050', 'https': 'socks5://127.0.0.1:9050' } response = requests.get("http://ip-api.com/json/", proxies=PROXIES) result = json.loads(response.content) print('TOR IP [%s]: %s %s'%(datetime.now().strftime("%d-%m-%Y %H:%M:%S"), result["query"], result["country"]))
Не забудьте остановить прокси перед началом следующего упражнения. Вот команда, чтобы остановить это.
tor_process.kill()
Промежуточная настройка: выберите реле из определенных стран.
В некоторых случаях вам может понадобиться больше контроля над соединением TOR. Вот некоторые возможные причины:
- Избегайте ретрансляции из определенных стран из-за кибербезопасности/закона/политических соображений.
- Изменение частоты обновления IP-адреса TOR.
- Использование другого метода аутентификации для подключения TOR
Код ниже создает прокси-сервер TOR на локальном порту 9050 со следующей конфигурацией:
- EntryNodes: TOR должен использовать ретранслятор из Франции в качестве входного узла.
- Выходные узлы: TOR должен использовать ретранслятор из Японии в качестве выходного узла.
- StrictNodes: подключение TOR должно строго следовать конфигурации пользователя.
- CookieAuthentication: использовать аутентификацию с помощью файлов cookie.
- MaxCircuitDirtiness: обновлять IP каждые 60 секунд.
- GeoIPFile: использовать указанный географический файл ipv4. Загружается с https://raw.githubusercontent.com/torproject/tor/main/src/config/geoip
# complete code found in create_intermediate_tor_proxy.py import io import os import stem.process import re import urllib.request SOCKS_PORT = 9050 TOR_PATH = os.path.normpath(os.getcwd()+"\\tor\\tor.exe") GEOIPFILE_PATH = os.path.normpath(os.getcwd()+"\\data\\tor\\geoip") try: urllib.request.urlretrieve('https://raw.githubusercontent.com/torproject/tor/main/src/config/geoip', GEOIPFILE_PATH) except: print ('[INFO] Unable to update geoip file. Using local copy.') tor_process = stem.process.launch_tor_with_config( config = { 'SocksPort' : str(SOCKS_PORT), 'EntryNodes' : '{FR}', 'ExitNodes' : '{JP}', 'StrictNodes' : '1', 'CookieAuthentication' : '1', 'MaxCircuitDirtiness' : '60', 'GeoIPFile' : 'https://raw.githubusercontent.com/torproject/tor/main/src/config/geoip', }, init_msg_handler = lambda line: print(line) if re.search('Bootstrapped', line) else False, tor_cmd = TOR_PATH )
Чтобы проверить, прошла ли ваша настройка успешно, вы можете сделать запрос GET на http://ip-api.com/json/. Если IP-адрес из Японии и меняется каждые 60 секунд, вы успешно настроили соединение TOR.
import requests import time from datetime import datetime PROXIES = { 'http': 'socks5://127.0.0.1:9050', 'https': 'socks5://127.0.0.1:9050' } for i in range(10): response = requests.get("http://ip-api.com/json/", proxies=PROXIES) result = json.loads(response.content) print('TOR IP [%s]: %s %s'%(datetime.now().strftime("%d-%m-%Y %H:%M:%S"), result["query"], result["country"])) time.sleep(60)
Расширенная настройка: выбор надежного реле для вашего соединения TOR.
В предыдущих упражнениях TOR отвечал за выбор реле для создания своего соединения. Однако могут быть случаи, когда вы хотите выбрать конкретное реле, чтобы повысить свою анонимность и безопасность в Интернете.
Вот некоторые соображения по выбору хорошего реле:
- Скорость и надежность сети
- Надежность/репутация поставщика
- Время безотказной работы службы
Чтобы найти хорошее реле TOR, мы можем использовать https://metrics.torproject.org/rs.html
- Поиск общедоступного реле. Лично мне нравится использовать ретранслятор, размещенный у «Hetzner», поскольку они являются поставщиком центров обработки данных с заслуживающим доверия опытом.
2. Скопируйте отпечаток реле
3. Этот код позволит вам использовать выбранное реле в качестве узла входа (1-е реле).
# complete code found in create_advanced_tor_proxy.py import io import os import stem.process from stem.control import Controller from stem import Signal import re import requests import json from datetime import datetime import time SOCKS_PORT = 9050 CONTROL_PORT = 9051 TOR_PATH = os.path.normpath(os.getcwd()+"\\tor\\tor.exe") tor_process = stem.process.launch_tor_with_config( config = { 'SocksPort' : str(SOCKS_PORT), 'ControlPort' : str(CONTROL_PORT), 'CookieAuthentication' : '1' , 'EntryNodes' : '9695DFC35FFEB861329B9F1AB04C46397020CE31', 'StrictNodes' : '1' }, init_msg_handler = lambda line: print(line) if re.search('Bootstrapped', line) else False, tor_cmd = TOR_PATH )
4. Чтобы проверить, была ли ваша установка успешной, вы можете перечислить свои схемы TOR. Убедитесь, что ваш 1-й узел имеет тот же отпечаток пальца, что и ваша конфигурация.
from stem import CircStatus from stem.control import Controller with Controller.from_port(port = 9051) as controller: controller.authenticate() for circ in sorted(controller.get_circuits()): if circ.status == CircStatus.BUILT: print("Circuit %s (%s)" % (circ.id, circ.purpose)) for i, entry in enumerate(circ.path): div = '+' if (i == len(circ.path) - 1) else '|' fingerprint, nickname = entry desc = controller.get_network_status(fingerprint, None) address = desc.address if desc else 'unknown' print(" %s- %s (%s, %s)" % (div, fingerprint, nickname, address))
Не волнуйтесь, если вы видите несколько каналов, TOR автоматически создает дополнительные каналы в качестве резервных.
Заключительные слова
Я надеюсь, что вам понравилось это практическое руководство так же, как и мне. Было весело исследовать TOR и базовую библиотеку. На самом деле с TOR мы можем сделать еще много интересного, я напишу об этом в ближайшие недели! Следите за обновлениями :)