ZeroNet Blogs

Static ZeroNet blogs mirror

kostaNew

Блог человека, который пришел в ZeroNet потусоваться.

Примерно неделю назад я начал разработку инструмента, для сбора и анализа статистики по ZeroNet. Надеюсь, что в итоге это станет либо аналогом Google Analytics, либо инструментом для администраторов прокси. Пока что это просто плагин для записи информации, которая выводится в https://www.zerogate.tk/Stats в разделе Sites, и скрипт для ее обработки.

Несмотря на такой маленький функционал, плагин уже позволяет узнавать некоторые интересные вещи: - Сравнивать популярность блогов. - Сравнивать размеры коммьюнити на разных языках. - Оценивать суточные колебания количества пиров и размеры сети.


Какие результаты можно получить?

Пример. Сравнение популярности блогов GomZik и kostaNew по количеству пиров. Видно что блог GomZik, значительно популярнее.

rus_dev_blog

Сравнение ZeroTalk и национальных коммьюнити.

community

Суточные колебания пиров по наиболее популярным сайтам. Заметьте, что ZeroTalk вообще мало кому нужен по сравнению с почтой и Play. Стоит отметить, что эти цифры нельзя считать максимальным размером сети, однако качественные результаты достаточно надежны.

zeronet

Данные собирались из узла, находящегося в Нью-Йорке. К сожалению, по многим сайтам данные писались не с самого начала.

Какие требования?

Для работы плагина, в используемом Python должны быть доступны модули numpy и pandas. Для обработки данных, необходимы numpy, matplotlib и pandas.

Как запустить сбор статистики?

  1. Скачать все из репозитория проекта
  2. Скопировать папку EasyMetrics в ZeroNet/plugins
  3. Перезапустить ZeroNet
  4. Подождать 2 минуты и проверить что в папке ZeroNet/metrics появилась новая папка с форматом YY_MM_DD_HH_MM_SS и в ней файлы zite.py и params.json

Как обрабатывать статистику?

Ближайшие несколько месяцев я не планирую включать обработку данных в графический интерфейс ZeroNet. Тем не менее уже есть набор ipython notebooks и специальный скрипт с несколькими стандартными графиками.

Для использования скрипта с предложенным по умолчанию дата сетом: 1. Перейдите в папку DataProcessing. 2. Вызовете python ./go peers zeronet 3. Подождите, посмотрите на картинку, подумайте;) 4. Так же возможны вызовы python ./go peers community, python ./go peers rus_dev_blog.

Теперь попробуем понять, что произошло. python ./go вызывает скрипт обработки данных, принимающий <task> и <scope>. <task> определяет то, что мы хотим вывести на экран. На данный момент доступен только один вариант: peers. Эта задача строит график количества пиров по времени для нескольких зайтов. <scope> определяет область интереса: зайты, пользователи, узлы... <scope> - прописаны в файле config.json. На данный момент реализованы <scope> включающие только зайты. Например:

"rus_dev_blog":[{"zite":"1CpGZyfbUBBV5uXUoY653wVoqZFRojbEzd","label":"GomZik"}, {"zite":"1FMeSorqAS8Kq5E5XJpGGBJ8Qb2CxXhaYb","label":"kostaNew"} ], содержит два зайта. Параметр "zite" - определяет адрес зайта. Адрес должен быть полным, .bit домены не поддерживаются. "label" - название графика в легенде.

Для того чтобы указать путь до папки с обрабатываемыми данными поменяйте параметр "folder": "../DataProcessingExamples/2016-03-14_14-30-28".

Вручную можно построить более интересные графики. Если вы умеете, используйте pandas самостоятельно.

Почему все так сложно?

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

Что будет дальше?

Я планирую улучшать информативность построения графиков и добавить несколько новых <task>, в том числе обрабатывающих данные зайтов и анализирующие файлы content.json. Жду от вас идеи графиков, которые позволят понять что-нибудь интересное.

Недавно выяснилось, что большинство людей не в курсе о таких диагностических возможностях ZeroNet как Stats, Benchmark и т.д. Поэтому, я покопался в ядре и посмотрел что в нем вообще есть.

Нашел еще 2-3 интересные штуки, но самый ЭПИК я осознал в конце. Оказалось, что владельцы прокси не отключают Stats плагин и уязвимы к (D)DOS из-за этого.

Содержание: - Инструменты ядра: Console, Debug, TestStream - Инструменты Stats: Benchmark, Stats, GcCollect - Уязвимость ZeroNet прокси


Введение

Итак, в ZeroNet есть набор средств диагностики лежащих по текстовым адресам вида.

<https://www.zerogate.tk/Console>
<https://www.zerogate.tk/Debug>
<https://www.zerogate.tk/TestStream>
<https://www.zerogate.tk/Benchmark>
<https://www.zerogate.tk/Stats>
<https://www.zerogate.tk/GcCollect>
<https://www.zerogate.tk/Dumpobj>
<https://www.zerogate.tk/Listobj>

Обратите внимание, что это не .bit домены!

Когда вы обращаетесь по любому адресу, запрос улетает в функцию route(path) объекта UiRequest. Если обращение идет не по адресу сайта и не по .bit домену, то происходит вызов функции вида actionXXXXX. Например, обращение по адресу Debug вызовет функцию actionDebug.

Такой механизм очень здорово подходит для плагинов. Потому что позволяет делать не конфликтующие плагины, если адреса, по которым вызываются инструменты, не пересекаются. Плагин Stats работает как раз через этот механизм. Концепция полностью аналогична навешиванию на WebSocket, о котором я написал в конце этого поста.

Теперь рассмотрим какие инструменты входят в стандартный бандл.

Инструменты ядра

Тут совсем негусто. В основном, инструменты ядра нужны для отладки. Они требуют Werkzeug и запуск с ключом --debug для правильной работы. Предназначение инструментов Console и Debug описано в официальной документации.

<https://www.zerogate.tk/Console>

Вызывает интерактивную Python консоль, если есть Werkzeug, иначе, просто вываливает ошибку. При выпадении ошибки видно некоторую полезную информацию: версию python, gevent, ZeroNet; плагины; используемые трекеры...

<https://www.zerogate.tk/Debug>

Позволяет отлаживать последнюю выпавшую ошибку через механизм DebugHook. Как конкретно этот механизм работает внутри, я пока не понял, но его классы лежат в папке Debug.

<https://www.zerogate.tk/TestStream>

Выводит "Hello!" с задержкой. Скорее всего, нужен чтобы убедиться, что взаимодействие с браузером вообще работает.

Инструменты Stats

А вот тут начинается самое интересное. Плагин Stats добавляет в ZeroNet три очень важных и интересных вызова;)

<https://www.zerogate.tk/Benchmark>

Тестирует производительность вашей системы для работы с ZeroNet. Ниже привожу полный дамп для моей системы:

Benchmarking ZeroNet 0.3.6 (rev966) Python 2.7.9 (default, Apr 2 2015, 15:33:21) [GCC 4.9.2] on: linux2...

CryptBitcoin:
- hdPrivatekey x 10..........0.223s [x3.14: WOW]
- sign x 10..........0.113s [x3.09: WOW]
- openssl verify x 100..........0.177s [x2.10: Fast]
- pure-python verify x 10..........0.493s [x3.25: WOW]

CryptHash:
- sha256 5M x 10..........0.455s [x1.32: Fine]
- sha512 5M x 10..........0.290s [x2.07: Fast]
- os.urandom(256) x 100 000..........2.179s [x0.30: Sloooow]

Msgpack:
- pack 5K x 10 000..........0.449s [x1.74: Fast]
- unpack 5K x 10 000..........0.746s [x1.61: Fine]
- streaming unpack 5K x 10 000..........0.804s [x1.74: Fast]

Db:
- Open x 10..........2.855s [x0.05: Sloooow]
- Insert x 10 x 1000..........0.688s [x1.45: Fine]
- Buffered insert x 100 x 100..........0.975s [x1.33: Fine]
- Total rows in db: 20000
- Indexed query x 1000..........0.171s [x1.46: Fine]
- Not indexed query x 100..........0.296s [x2.03: Fast]
- Like query x 100..........0.787s [x2.29: Fast]

Done. Total: 12.40s

По данным с форумов и блога @musickiller, показатели общего времени прохождения теста на ПК составляют от 5 до 20 секунд, на Android -- 90 и выше. Обратите внимание, что тест сильно грузит машину. При этом, его можно запустить много раз.

<https://www.zerogate.tk/Stats>

Выводит данные о ваших соединениях с пирами и статистику по загруженным вами 0сайтам. Здесь можно посмотреть у каких пиров какая версия ZeroNet. А так же ту статистику, которые вы видите в правой боковой панели по 0сайту, для всех сайтов сразу.

В режиме --debug так же пишет дополнительную информацию: объем занимаемой классами и объектами памяти; ошибки гринлетов (greenlet) и адреса подключения воркеров (workers); параметры cоединений по различным адресам, сокетам; данные о работе msgpack; загруженные модули python и пути до них. Многое из этого требует дальнейшего изучения.

Прокомментирую термины, которые уже начал понимать. Гринлеты (greenlets) - это легковесные потоки, предоставляемые gevent. Они предоставляют конкурентное выполнение задач, более удобным способом, чем встроенные механизмы Python. К сожалению, для них работает GIL, а значит нет настоящего параллелизма. Воркеры (workers) - это элементы очереди задач ядра ZeroNet, именно эти штуки следят за загрузкой нужных файлов из пиров.

<https://www.zerogate.tk/GcCollect>

Вызывает сборку мусора в ядре ZeroNet и возвращает сколько объектов было собрано. Эта команда работает даже без режима отладки.

<https://www.zerogate.tk/Dumpobj>
<https://www.zerogate.tk/Listobj>

Команды работающие только в режиме Debug. Должны выводить данные об объектах в памяти в определенном формате. Однако, у меня почему то не заработали. Возможно, я просто не дождался, так как в коде обеих функций используется команда gc.get_objects().

Уязвимость ZeroNet прокси

Барабанная дробь. Владельцы прокси вообще не поняли что они позапускали, ни на одном из них плагин Stats не отключен. Любой может быстро стучаться извне на /Benchmark и положить сервер частыми запросами. Более того, серверы компрометируют таким образом свое оборудование и свои коннекты, что не очень хорошо.

Используя список прокси от @eugenere, который лежит тут я благополучно стырил с трех из них данные. Если такие данные кому то нужны для изучения без злого умысла, могу переслать лично.

В заключение

Некоторые вещи вообще непонятно как работают. Если у кого то получилось использовать их правильно, напишите в комментарии, пожалуйста. Так же в коде ядра есть еще более 10 функций вида actionXXXXXX, но мне кажется они должны использоваться по-другому, а не вызываться из адресной строки.

Немного инсайтов

- Posted in kostaNew by with comments

Так как с серьезными вещами все идет очень медленно, а документации и примеров страшно не хватает, то я решил написать про несколько "открытий". Надеюсь, это поможет некоторым лучше понять ZeroNet, если они на том же этапе, что и я.

В этом посте: - О шрифтах - О публикации зайта - Об опциональных файлах - Как писать плагины для ZeroNet


О шрифтах На большинстве зайтов, основанных на стандартом шаблоне ZeroTalk и ZeroBlog, есть проблемы с отображением шрифтов. Русские буквы выглядят широкими, а английские маленькими. Это связано с тем, что в системе не стоят кириллические версии используемых шрифтов.

Исправить это можно руками, скачав нужные семейства с Google Fonts и проставив все семейство в систему. Есть более продвинутые методы, но я к сожалению потерял описание, которое мне давали.

Обычно проблемы вылазят на Ubuntu, со шрифтами Roboto и Tinos.

О публикации зайта К зайтам лучше относиться не как к веб страницам, а как к нативным приложениям Android или iOS. Когда вы публикуете приложение для Android, то вы его сначала подписываете, а потом засылаете на проверку в Google. Тут аналогично. Все действия делаются в 3 этапа.

python zeronet.py siteCreate
python zeronet.py siteSign
python zeronet.py sitePublish

Первая команда создает зайт. Она создаст папку с вашим зайтом, файл index.html и content.json внутри нее. Название этой папки, по сути, является открытым ключом зайта. Закрытый ключ будет выведен в консоль. НЕ ПОТЕРЯЙТЕ ЕГО! Иначе ваш зайт превратится из кареты в тыкву, которую будет невозможно выложить по тому же адресу.

Вторая команда ну ОЧЕНЬ интеллектуальна. Ее главное предназначение это подписывать файл content.json. Однако, помимо этого, она записывает в content.json все лежащие в папке файлы. При этом тактично опуская временные файлы редактора, типа ogrizok_gedit.js~ и еще некоторый мусор. Так же, эта команда должна компилировать *.coffee скрипты, но к сожалению делает это только на Windows.

Третья команда выкладывает зайт в открытый доступ. Для того что бы она сработала, вам требуется открытый порт 15441.

Стоит отметить, что в формате objectAction есть еще несколько полезных команд для zeronet.py. Посмотреть их можно, используя ключ --help. А сам процесс публикации хорошо расписан в стандартной документации и презентации.

Об опциональных файлах В ноябре 2015 года в ZeroNet была добавлена возможность делать зайты с опциональными для загрузки файлами. К сожалению, в документации этот момент отразился настолько в хитром месте, что многие так и не поняли как же этой возможностью воспользоваться.

Тем не менее, все очень просто. Надо написать в content.json строку "optional": "optional_files/.*". Тогда во время подписывания зайта, все файлы, попадающие под указанный шаблон (в данном случае содержимое папки optional_files), станут опциональными. Проверить это можно в content.json. Секция "files" декларирует обязательные для загрузки зайта файлы, а секция "optional\_files" опциональные.

Посмотреть пример на опциональные файлы с проигрыванием музыки можно тут, а его исходный код тут. Тег <audio src="audio/Little_Bits.mp3" preload="auto"> обращается к обязательному файлу и плеер гарантированно будет готов к проигрыванию при открытии зайта. Тэг <audio src="audio_optional/April_Kisses.mp3" preload="none"> не требует файла до нажатия кнопки play. Таким образом второй музыкальный файл не скачивается до запуска воспроизведения.

Стоит отметить, что файлы можно загружать со стороны пользователя и делать их опциональными в папках с пользовательскими данными. Таким способом уже работает 0chan. Мне кажется, что появление большего количества зайтов с загружаемым пользовательским контентом, это дело времени, количества программистов и качества документации...

Как писать плагины для ZeroNet

А теперь мы подошли к самому интересному. Плагины для zeronet лежат в папке plugins и уже реализуют очень большой кусок логики. Плагин, по сути, является обычным питоновским модулем, который PluginManager дергает в определенное время и через механизм декораторов накладывает на код основного ядра. Отключенные плагины имеет префикс disabled. Плагины работающие только в режиме дебага, начинаются с Debug.

Что бы сделать свой плагин нужно: - Создать новую папку, например TestPlugin - Создать файлы __init__.py и TestPlugin.py - В __init__.py написать import TestPlugin - В TestPlugin.py написать импорт класса PluginManager: from Plugin import PluginManager - Определить класс плагина class UiRequestPlugin(object): - Определить в декораторе, на какой класс ядра он будет навешиваться. Например, навешивание на UiRequest: @PluginManager.registerTo("UiRequest")

Логика работы очень простая. Если что то вызывает определенный в UiRequestPlugin метод, а его нет в ядре, то вызовется метод плагина. Если же метод в ядре есть, то он вызван не будет, а будет вызван метод вашего плагина. Во втором случае, важно правильно вернуть управление в ядро. Например так: return super(UiRequestPlugin, self).route(path). Некоторые функции, которые вы переписываете, могут быть итераторами, поэтому используйте yield, примеров на это в стандартном бандле куча.

Код простого плагина, пишущего строку в лог, можно найти тут.

Если плагинов на один класс много, то они будут навешиваться по очереди. Навеситься можно не на все классы ядра, а только на те, у которых подписано @PluginManager.acceptPlugins. На данный момент таких классов девять.

  • main.py
  • Config.py
  • File/FileRequest.py
  • User/User.py
  • User/UserManager.py
  • Ui/UiWebsocket.py
  • Ui/UiRequest.py
  • Site/Site.py
  • Site/SiteManager.py

Стоит особо отметить файл UiWebsocket.py. Все реквесты из ZeroFrame улетают в ее метод handleRequest. Этот метод обрабатывает логику responce запроса, потом отсеивает попытки позвать административные команды без прав (sitePause, siteResume, siteDelete, siteList, siteSetLimit, siteClone, channelJoinAllsite, serverUpdate, serverPortcheck, serverShutdown, certSet, configSet). И в конце вызывает в объекте UiWebsocket метод, который состоит из слова action и названия команды с большой буквы. Например: actionFileWrite. Таким образом к UiWebsocket можно написать 100500 плагинов и все они не будут конфликтовать, если использовать разные названия для вызываемых из UI методов.