Как стать автором
Обновить

Обход блокировок, анонимность или как я свою проксю писал

Привет Хабр! Это моя первая статья и в ней я хотел бы поделиться одним интересным проектом, но сначала небольшая предыстория.

Всё началось с того, что у меня перестал работать тор. Вот прям совсем. Я сначала подумал что это очередная блокировка моста или какой-то сбой, но нет. после пары дней попыток и экспериментов я обнаружил что он не работает повсеместно в сети моего провайдера. Я в полной уверенности что такую махину как тор нереально заблокировать начал искать в чем же проблема и как оказалось я не один столкнулся с этим.

Я начал изучать что да как и меня это довольно сильно увлекло. В тот момент я работал над проектом в котором без прокси ну никак не обойтись и тут меня осенило - почему бы не написать приблуду, чтобы всё и сразу. В общем, свой тор с бэкендом и шлюзами.

Ближе к делу

Детально изучив механизм работы тор и проштудировав пару десятков статей я сел за работу... А в прочем это совсем другая история. Это обзор результата, а процесс создания сего чуда - тема для отдельной статьи (намёк вы поняли).

После пары недель проб и ошибок моё детище наконец-то было готово. Я бы сказал что получилось мягко говоря... интересно.

Основным отличием от того же Тора было то, что для каждого подключения (сокета) создавался новый туннель. Затратно? с одной стороны да, но оптимизация берёт своё. Плюс небольшой финт ушами позволил добиться в определённых случаях даже большей производительность чем обычный http-прокси. А самое весёлое что написано всё на Python. Да да, на том самом гибриде улитки и змеи. Он по прежнему занимает особое место в моём сердечке, да и на самом деле, если верить нагрузочным тестам, то он неплохо справляется с поставленной задачей. Впрочем я далеко ушел.

Использование этого инструмента подразумевает создание сети из одной или более ноды, через которые туннелируется весь трафик. сами идею с такой структурой сети я позаимствовал у одной известной луковицы. Можете почитать об этом если вам интересно. Я же просто скажу что в отличае от тор в моей сети может быть неограниченное количество промежуточных точек, а все служебные данные шифруются с помощью написанного на коленке протокола RecRoll.

И так, давайте же пощупаем наконец сам проект.

Практическая часть

Проект можно найти на гите. Или установив пакет через pip.

Я собственно воспользуюсь пипом.

pip install NREP

После установки создаём папку проекта и берём стандартный "маяк" из примеров проекта.

from NREP.beacon import Beacon
from NREP.utils.spec import Config

config = Config('beacon_config.json')
node = Beacon(config)

Создаём файл beacon_config.json и кладём туда следующее:

{
	"location": "asshole",
	"host": "",
	"port": 80,
	"nodelist": "nodes.json"
}

чтобы запустить на локалхосте, оставим поле host пустым

Создаём nodes.json. Это список (листинг) всех доступных нод.

{
	"RU": {
		"REGION1": {
			"node1": {
				"host": "localhost",
				"port": "5689",
				"publickey": "-----BEGIN RSA PUBLIC KEY-----\nMEgCQQCsZGoibHma36u1koAw82g6xyqQlPdOuedBehc0xLhzJlh5yqc31pwotrYD\n42fZWua+OUGPjOFiDHpnCYw0jHTvAgMBAAE=\n-----END RSA PUBLIC KEY-----\n"
			}
		}
	}
}

Ах да, чуть не забыл. генерируем пару aes ключей и кладём паблик в конфиг ноды (в маяке). Очень муторно, но уже скоро появится автолистинг и вам не придётся так извращаться с настройками. Для ленивых на гите есть готовый маяк, просто покрутите конфиги.

Готово, теперь осталось собрать ноду и мост.

Здесь думаю пришло время сделать небольшое отступление и объяснить какого черта мы делаем.

Как я уже говорил основу сети составляют ноды, но так же есть и маяки. Они нужны для того, чтобы сообщить пользователю через что он может проложить "трубу". а мосты здесь, в отличие от тора нужны для трансляции из различных протоколов к nrep/recroll. Пока есть только http2nrep.

Вернёмся к вакханалии с настройкой сетевого окружения.

Создаём node.py

from NREP.node import Node
from NREP.utils.spec import Config

config = Config('config.json')
node = Node(config)

И конфиг к нему

{
	"location": "asshole",
	"max_connections": 100,
	"host": "",
	"port": 5689,
	"clean_interval": 0.1,
	"privatekey": "-----BEGIN RSA PRIVATE KEY-----\nMIIBPgIBAAJBAKxkaiJseZrfq7WSgDDzaDrHKpCU906550F6FzTEuHMmWHnKpzfW\nnCi2tgPjZ9la5r45QY+M4WIMemcJjDSMdO8CAwEAAQJBAKWEJ67zbXI4bHmBtljJ\navp8PS7iB+xra1Cfc2ZztVcqs8p+fhWKeMSbsQZ9MG2PoFZ7aJifq7Cq9zUAmmPN\nWJkCIwDBS/NZiv7PUFRX/3zjFUUB5dwG9HHY3xvDw+JBkCKF9izlAh8A5FB8DQfo\nU8RXlhKv0FjE2bFE5ibFmC+rGHrk3ZFDAiMAsyOxbv37MqTO1hMIaefvYVfmt2da\nD1SOBbsHeB2dcSt55QIfAL9OeUNp9tAJ2uIS8mJ/nyJRmUvH/RWSC6lNgGvvhQIi\nDuryDswMdPn5jm2LaLDqg/rzyGNfx5DsuuByZbUUWttTCQ==\n-----END RSA PRIVATE KEY-----\n"
}

Кидаем сюда приватный ключ rsa, сгенерированный нами ранее. Из параметров, можно отметить max_connections - максимальное количество труб, и clean_interval - время очистки пула труб в секундах. Порт смысла трогать нет, а вот хост пишите тот, на котором поднимаете ноду. Не забудьте и в маяке его прописать.

С мостом всё куда проще, просто тянем его из пакета.

from NREP.bridge.http2nrep import Bridge

Bridge("127.0.0.1", 8080)

Вот и всё. Маяк запускаете на локальной машине, а за ним и мост. Именно в таком порядке. Мост кэширует конфиг из маяка и запускает http/https proxy. У меня лично винда, я прописываю его настройках. После запускаем ноду на удаленной/локальной машине.

Можно приступать к тестированию. Теперь каждое новое подключение будет проходить через наш импровизированный прокси. Запускаем спид-тест из примеров и нет, я не буду его сюда писать)) Получаем следующие результаты:

With NREP (no piping): 0.7313602799999999s
With NREP (piping): 0.24336806599999947s
Without NREP (first request): 0.7303720800000001s
Without NREP (second request): 0.2465090479999998s
NREP is 0.1 % slower
NREP (piping) is 1.3 % faster

Довольно неплохие результаты, учитывая что это avg из 50 тестов.

Подводя итоги могу сказать что эксперимент удался. Оно даже тянет ютуб в 4К) Но есть над чем поработать. Надеюсь, проект будет вам полезен. Планирую и дальше его развивать, так что присоединяйтесь.

Благодарю, что дочитали до конца. Спасибо всем. Надеюсь на вашу поддержку и не судите слишком строго. Это как ни как мой первый пост.

GitHub проекта.

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.