Введение

Еще в 1990-х годах Интернет был небезопасным местом, где сетевой трафик в значительной степени не шифровался и отслеживался, что позволяло хакерам выполнять атаки «человек посередине» и легко собирать личные данные. Чтобы решить эту проблему, группа исследователей из военно-морской исследовательской лаборатории США запустила проект The Onion Routing (TOR) с целью анонимизации и защиты коммуникаций в Интернете.

Методология

TOR использует модель распределенного доверия для защиты вашего сетевого трафика через Интернет. Это методология, при которой ваши данные шифруются несколькими сторонами для обеспечения многоуровневой защиты данных (например, Onion). Так что ваши данные будут в безопасности, если только кто-то не сможет взломать все стороны, участвующие в шифровании.

На практике TOR выбирает 3 уникальных ретранслятора, управляемых разными организациями, для шифрования и маршрутизации вашего сетевого трафика до достижения конечного пункта назначения.

Вот простая диаграмма, иллюстрирующая методологию.

Чтобы узнать больше о TOR, у Velentin Quelquejay есть отличная статья.

В этой статье я сосредоточусь на практическом аспекте настройки прокси-сервера TOR с Python, поскольку я чувствовал, что в этой области не хватает онлайн-материалов и дискуссий.

Чтобы помочь вам учиться более эффективно, я разделил это руководство на 3 уровня сложности, охватывая полезные функции TOR, которые позволяют вам использовать весь его потенциал.

Предпосылки

Прежде чем продолжить работу с этим учебным пособием, убедитесь, что у вас установлено следующее.

  1. Python3
  2. Шток установки штифта
  3. Git-клон https://github.com/ohyicong/Tor

Базовая настройка: конфигурация по умолчанию

Вот простой и эффективный код для создания прокси-сервера TOR с использованием конфигурации по умолчанию:

  1. Установить прокси на локальный порт 9050
  2. Установите соединение TOR через 3 уникальных реле (случайно)
  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. Вот некоторые возможные причины:

  1. Избегайте ретрансляции из определенных стран из-за кибербезопасности/закона/политических соображений.
  2. Изменение частоты обновления IP-адреса TOR.
  3. Использование другого метода аутентификации для подключения TOR

Код ниже создает прокси-сервер TOR на локальном порту 9050 со следующей конфигурацией:

  1. EntryNodes: TOR должен использовать ретранслятор из Франции в качестве входного узла.
  2. Выходные узлы: TOR должен использовать ретранслятор из Японии в качестве выходного узла.
  3. StrictNodes: подключение TOR должно строго следовать конфигурации пользователя.
  4. CookieAuthentication: использовать аутентификацию с помощью файлов cookie.
  5. MaxCircuitDirtiness: обновлять IP каждые 60 секунд.
  6. 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 отвечал за выбор реле для создания своего соединения. Однако могут быть случаи, когда вы хотите выбрать конкретное реле, чтобы повысить свою анонимность и безопасность в Интернете.

Вот некоторые соображения по выбору хорошего реле:

  1. Скорость и надежность сети
  2. Надежность/репутация поставщика
  3. Время безотказной работы службы

Чтобы найти хорошее реле TOR, мы можем использовать https://metrics.torproject.org/rs.html

  1. Поиск общедоступного реле. Лично мне нравится использовать ретранслятор, размещенный у «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 мы можем сделать еще много интересного, я напишу об этом в ближайшие недели! Следите за обновлениями :)