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

NNCP: лечение online- и цензуро- зависимости store-and-forward методом

Время на прочтение 26 мин
Количество просмотров 7.5K
В этой статье поднят вопрос удручающей ситуации с доступностью данных в Интернете, злоупотреблением цензурой и тотальной слежкой. Власти ли или корпорации в этом виноваты? Что поделать? Создавать собственные соцсети, участвовать в сетях анонимизации, строить mesh-сети и store-and-forward решения. Демонстрация NNCP утилит для создания этих store-and-forward friend-to-friend решений.

Кто виноват?


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

Представители власти говорят что нет речи о запрете, а всего-лишь о контроле: то есть, мол если они смогут читать, то никаких проблем — но мы то знаем что не бывает шифрования «прозрачного» для одних, но надёжного от других. Подобный «контроль» равносилен тому, что любое наше слово должно бы быть передано через посредника, прямое общение между двумя собеседниками недопустимо. Кроме того, наличие централизованного посредника опасно злоупотреблением цензурой и закрытием доступа к пластам информации. Плюс это колоссальный поток приватной информации о людях (каждый их клик будет зафиксирован) — то есть глобальная слежка со всеми отсюда вытекающими проблемами.

Все эти проблемы преподносятся в оппозиционном виде против власти, мол именно они виноваты в том, что мы, простые люди, можем лишиться такого чуда света, как Сеть сетей. Так ли всё плохо и так ли действительно нас, с нашими технологиями, «не любит» власть?

Всё не так плохо — всё гораздо хуже. Потому-что доступность информации, глобальная тотальная слежка и цензура уже давно стали де-фактом, без каких-либо принятых законопроектов. Вот только зачинщиками всего этого были и являются корпорации типа Google, Facebook, Microsoft и Apple.

Не секрет, что Web-технологии крайне сложны, громоздки и трудоёмки в разработке: попробуйте написать Web-броузер с нуля со всеми CSS-ами и JavaScript-ами с DOM-ом. Известно, что активно разрабатываемых броузеров по пальцам посчитать и их разработкой занимаются люди из этих корпораций. Поэтому любая разработка движется исключительно и логично в сторону потребностей корпораций.

Какой Web был раньше, с технологической точки зрения? У пользователей стоит специальная программа (старый добрый тёплый ламповый Web-броузер), которая по стандартизованному HTTP протоколу (говорящему какой документ, какой ресурс нужно получить), подключаясь к серверам, получает HTML (возможно плюс изображения) документ и отображает его. Это распределённая сеть хранения документов в которой один протокол. Мы по сети получаем готовые документы, которые можно сохранить на жёстком диске и читать без дальнейших подключений к серверам.

Как работает Web «корпораций»? У пользователя стоит специальная программа (до сих пор обзывающаяся Web-броузером), которая по транспортному протоколу (это HTTP, но который к гипертексту отношения уже никакого не имеет, который можно заменить какими угодно другими протоколами передачи файлов) получает программу, написанную на JavaScript (хотя сейчас это может быть какой-нибудь WebAssembly, являющийся обычным бинарным исполняемым кодом, аналогично .exe файлу), запускает её в виртуальной машине и эта программа по своему собственному протоколу (то есть правилам взаимодействия с сервером и форматом сообщений) начинает общение с сервером чтобы получить данные и их отобразить на экране. Сохранить отображённые данные, думая что это документ, вряд ли получится. Автоматизировать получение документов тоже не получится, потому-что каждый отдельный сайт это отдельная программа и свой протокол общения со своим форматом сообщений (структурой JSON запросов, например). Теперь это распределённая сеть приложений, скачиваемых на пользовательские компьютеры.

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

Что такое закрытая проприетарная программа? Это то, когда вы не управляете своим компьютером, когда вы не знаете что программа на нём собирается делать Не вы говорите своей машине что ей надо выполнять, а программа вам говорит что вам дозволено делать. Безусловно, всё это касается и любой другой проприетарной программы, не только автоматически скачанному JS-коду. Однако, существенная разница между установленным Microsoft Windows с каким-нибудь Microsoft Word на вашем компьютере и JS-кодом — вы их ставите один раз и если не замечаете ничего опасного или настораживающего в их работе, то просто не беспокоитесь и доверяете. Однако в Web мире вы, каждый раз заходя на сайт, можете получить новую версию программы и любой современный броузер вам этого даже не сообщит. Если раньше вы не замечали что сайт отсылает на сервер приватные данные, то, зайдя на него через пять минут, он может начать. Никто, без специальных плагинов и танцев с бубном, вам об этом не скажет и не предупредит что вы используете другую версию скачанной программы. Экосистема заточена на беспрекословное скачивание несвободных программ. Владельцы таких сайтов могут заставить выполнить на пользовательских компьютеров что им заблагорассудится буквально поменяв несколько файлов на свои серверах и новая версия программы автомагически будет исполнятся.

Может проблемы преувеличены, ведь это же не обычная .exe программа которая имеет доступ до огромного количества ресурсов компьютера, а программа запускающаяся, по идее, в изолированной виртуальной машине? К сожалению, размер и сложность кодовой базы современных броузеров так огромны, что даже просто сделать анализ их безопасности очень затратно, не говоря уж о том, что эта кодовая база меняется настолько быстро, что любой анализ на момент своего завершения будет не актуален. Сложность это главный враг любой системы безопасности. Сложные протоколы типа TLS доказали, что даже если сотни миллионов людей используют и разрабатывают под OpenSSL, который является свободной программой с открытым исходным кодом — там могут быть фатальные критические ошибки. Плюс все мы видели что атаки типа Row hammer можно произвести и из броузера. Кроме того, есть успешные атаки на кэш процессора нацеленные на узнавание ключа AES, выполняемые тоже из броузера. Виртуальная машина столь стремительно изменяющаяся и с такой сложностью не может быть безопасна по определению, ведь даже полная виртуализация в каком-нибудь Xen или KVM не помогает против некоторых атак. Да и какой смысл делать хорошее изолированное окружение, когда бизнес корпораций это наоборот сбор как можно большего количества данных?

Теперь давайте попробуем отключить JavaScript в нашем броузере и походим по самым разным современным сайтам. На сегодняшний день, какая-то часть ресурсов не будет работать совсем, однако на оставшихся 99% сайтов мы увидим, что куда-то подевалось огромное количество рекламы. Мы увидим, что от нас стало исходить на порядки меньшее количество запросов выдающих наши приватные данные посторонним сайтам/серверам — то есть слежка существенно сокращена, как минимум отсутствием контакта с многочисленными третьими лицами.

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

Кто-то может возразить: какая же это слежка за мной в магазине, если я вот пришёл в таком-то пальто и вот моё лицо видно — я сам выдал эту информацию. Действительно, IP адрес, TCP-порты, User-Agent своего броузера я сам присылаю и не могу не присылать — так уж устроен Web. Но если продавец начинает спрашивать как меня зовут, откуда я, ходить за мной по пятам — это уже запрос информации которая не нужна для совершения транзакции купли-продажи, это уже слежка. А ведь сайты корпораций именно этим и занимаются, уничтожая доступ к информации по стандартизованным протоколам (которые так мало о нас говорят) и форматам документов — если они заставят использовать своё ПО, то в нём то уж они вольны следить как заблагорассудится.

Опросите большинство людей кого конкретно по-настоящему задели блокировки Роскомнадзора и они потеряли доступность какой-то информации? Не считая громких кратковременных блокировок типа Github, максимум что люди скажут, так это потеря Рутрэкера. Однако, как и в случае с Pirate Bay, стоит понимать что это уже не прихоть властей и не политика, а власть корпораций типа Голливуда и подобных им. Их денежные состояния и влияние на власть стран достаточно весомы. Самим властям закрывать Рутрэкер или Pirate Bay не имеет смысла, так как, в основном, это дешёвые (с точки зрения инфраструктуры) развлечения отвлекающие людей от политики (потенциально создающей опасность для власти).

А вот потери тонн информации из-за того, что сайт перестал работать простыми HTTP+HTML методами, заставляя людей использовать его ПО, вынуждающее быть постоянно в online (если человек не будет в online, то как о нём собрать информацию?) — по моему, сказались и сказываются всё сильнее и сильнее. Отключите человека от Интернета и он не в состоянии вообще ничего сделать, ни даже прочитать почту или посмотреть свои фотографии или вспомнить о встрече, ведь всё это осталось в облаках.

Информация «попавшая» в соцсеть типа ВКонтакте — недоступна для индексирования сторонними роботами, часто недоступна для неавторизованных лиц. Мол, только если я разрешу скачивать закрытые проприетарные программы, зарегистрируюсь, предоставляя идентификационные данные своего «маячка» (сотового телефона), то только тогда я смогу увидеть пару абзацев текста про какой-нибудь очередной музыкальный концерт. Дикое количество Web-разработчиков просто разучились делать сайты иначе — без слежки и установки каждому пользователю своего ПО они ничего не покажут, ни бита информации полезной нагрузки. Потому-что корпорации обучают людей только такому неэтичному и неуважающему пользователей методу разработки. Чтобы увидеть хотя бы одно сообщение в Google Groups, надо скачать почти два мегабайта JS-программ — комментарии излишни.

Таким образом, тотальная слежка, недоступность информации, централизованная цензура — всё это уже произошло, всё это культивируется самими же разработчиками, обычными людьми. Соцсети «чисты»: мол, никто не заставляет в нас всё это размещать. Действительно, людьми крайне легко манипулировать и крайне легко умалчивать о том чего они лишаются, показывая только положительные стороны своих подходов. А ценность начинают понимать только с потерей.

Есть много людей которые используют практически только ВКонтакте и YouTube: каждое их действие уже отслеживается, вся их переписка (у них нет email, только учётная запись в ВК или Telegram) читается, вся поступающая информация тривиально цензурируется (сколько раз Facebook был замечен за манипуляцией людьми, путём цензуры данных?). И таких уже возможно большинство, однако никто насильно их не заставлял и выбор есть до сих пор. Для них у провайдеров уже есть специальные более дешёвые тарифные планы в которых доступ только до ряда сервисов. Когда масса этих людей станет совсем критической, то останутся только такие тарифные планы, так как какой смысл поддерживать провайдеру инфраструктуру обеспечивающие доступ ко всему Интернету, когда достаточно иметь пиринг с полдюжиной сетей корпораций и 99.99% пользователей довольны? Цены на полноценные тарифы будут повышаться (если останутся вообще) и это уже станет барьером для доступности Интернета.

Людей волнует что в TLS соединении будет принудительно выставлен CA сертификат как это например произошло в Казахстане, для того чтобы следить, прослушивать и цензуру устраивать? Но, при этом, этих же самых людей не волнует что другие стороны (сервисы корпораций) вообще устанавливают своё закрытое ПО и свои протоколы? Эти же самые люди, путём размещения информации только в соцсетях, как-раз поддерживают централизацию и гегемонию одной корпорации над всеми данными. Они уже давно самостоятельно роют себе Интернет-могилы, пытаясь свалить все беды на «дефолтного» крайнего.

К корпорациям с распростёртыми руками, а власть, которая делает куда менее катастрофичные вещи, хаять.

Что делать?


Меньшинству людей которым действительно нужен Интернет, кому нужна возможность, грубо говоря, послать произвольные данные с одного произвольного компьютера на другой?

Если не нравятся сервисы корпораций или соцсети, то никто не заставляет их использовать и всегда можно сделать свой аналог (с блэкджеком и шлюхами, опционально). У каждого дома есть мощный компьютер, быстрая сеть и все возможности технической реализации. Движки для соцсетей типа Diaspora или GNU Social уже давно существуют.

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

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

Если не нравится что всё большее количество провайдеров не даёт статические IP-адреса, вообще не даёт полноценных адресов, а только внутренний адрес за NAT-ом, то размещение ресурсов внутри overlay сетей типа Tor hidden service (.onion) или I2P (.i2p) может быть единственным способом подключиться к вам извне. Необходимо не забывать об участии в подобных сетях и жертвовать, зачастую неиспользуемые, ресурсы ваших компьютеров. Развивать и поддерживать не только low-latency сети, априори подверженные ряду атак из-за своей природы, но и сети типа Freenet и GNUnet. Чтобы не было как всегда: пока гром не грянет.

Если цензура, поддерживаемая корпорациями, действительно достигнет такого состояния, когда произвольные компьютеры не смогут обмениваться шифрованным трафиком между собой, то бишь, закроется Интернет и останется только whitelist удалённый доступ до дюжины сервисов, то можно сделать свою сеть.

Прокладывать оптоволокно или кабели вряд ли можно рассматривать, так как это стоит огромных денег (забудем про то, что это ещё и не разрешат). Но mesh-сети поверх беспроводных каналов связи реализовать можно и в спартанских домашних условиях. Вариантом может быть не обязательно создание полностью изолированной сети, а той, в которой хотя бы кто-то будет иметь доступ до работающего Интернета, являясь шлюзом. Проектов достаточно много чтобы было среди чего выбирать.

Но не забываем про желания корпораций о запрете изменения прошивок на WiFi-маршрутизаторах и не забываем что огромное количество WiFi модулей не работают без бинарных блобов. Подобный vendor-lockin не исключает жёсткий контроль над трафиком, как например, в современных проприетарных ОС невозможно установить программы не криптографически подписанные корпорациями (одобрившими запуск данного ПО). Сделать WiFi чип самостоятельно в домашних условиях очень дорого и не исключено что с рынка пропадут и те, на которых можно было бы сделать mesh-сеть. Речь не только про WiFi, но и любые другие беспроводные решения с толстым каналом связи. Любительские радиостанции можно сделать и в домашних условиях, но ёмкость их каналов плачевна, да и нельзя так просто взять и поднять такую станцию дома — нужны разрешения.

Mesh сеть возможно создать в теории, но на практике нужно большое количество достаточно географически распределённых людей чтобы создать нечто внушительного размера и имеющее практическую пользу, а не только академическую. Есть разные мнения, но лично мой опыт показывает что люди не особо стремятся сотрудничать и поэтому не приходится надеяться, что mesh-сеть, хотя бы, в Москве можно было бы создать. А людей нужно действительно много, потому-что WiFi (или другие доступные ёмкие радиорешения) работает на относительно коротких расстояниях.

Кроме того, mesh-сети и их протоколы хорошо заточены исключительно под real-time соединения. Они рассчитаны на то, чтобы можно было бы в реальном времени открывать сайты или удалённо использовать терминал. Если связанность в сети теряется, то это равносильно разрыву кабеля и, до восстановления, другой участок сети будет недоступен, приводя в негодность real-time low-delay программы. Необходимо ещё и обеспечивать хорошее резервирование каналов — что дорого и ресурсоёмко.

Более кардинальное решение это забыть о real-time сервисах и вспомнить что и без них жизнь вполне возможна. Так ли критично что ваше сообщение дойдёт не сиюсекундно, а возможно через несколько минут или часов? Электронная почта остаётся самым надёжным и распространённым методом общения и она не гарантирует никаких временных рамок по доставке: задержки в десятки минут штатны.

Для чтения большинства сайтов real-time не нужен в принципе. Сайт можно скачать, доступными во всех свободных ОС, программами типа GNU Wget и отправить зеркало сайта к себе. Существует и стандарт для хранения Web-данных: WARC (Web ARChive), используемый в Internet Archive. Один файл может содержать полностью весь Web-сайт. Такой же подход используется и в Freenet сети: сайты тоже помещаются в архив, чтобы не качать через сеть сотни блоков данных, которые наверняка были бы запрошены, а атомарно сразу же получить всё. Подчеркну: формат Web архивов уже стандартизован и десятки петабайт Internet Archive сделаны именно в нём. Ценные страницы стоит сохранить просто средствами Web-броузера на диске, ведь сегодня ссылка рабочая, а завтра уже запросто нет. Вы возможно усвоили информацию по ней, но дать своему товарищу уже не сможете. Это потерянная информация, особенно в условиях централизованных систем типа CDN и соцсетей.

Если отказаться от real-time и обязательного сиюминутного online режима работы, то не нужны даже mesh-сети, а достаточны гораздо менее требовательные store-and-forward (сохранить и отправить дальше) решения. Одной из таких сетей, существующей до сих пор, является FidoNet, который, до распространения дешёвого Интернета, был вполне себе распространённой (среди того самого меньшинства) глобальной сетью. Да, сообщения шли часами или целыми днями, но, поверьте, интересного общения в Фидо запросто было куда больше чем сейчас можно найти среди невероятного количества Интернет форумов и рассылок.

Node-to-Node CoPy


Я ничуть не призываю возродить FidoNet или UUCP (Unix-to-Unix CoPy), про использование которого я уже писал раньше!

Во-первых, все эти системы были созданы во времена, когда криптография фактически не была доступна для простых смертных и когда каналы связи навряд ли прослушивались и, если и прослушивались, то только целенаправленно, а не массово (чисто технически сейчас проще прослушивать всех, чем конкретно заданных лиц). Тогда ещё не было бизнеса основанного на слежке за людьми. Шифрования и сильной аутентификации они не предоставляли.

Во-вторых, тот же FidoNet, был создан для простых персональных компьютеров с DOS-ом, в отличии от UUCP бывшим де-факто методом связи между Unix-системами. Сейчас почти любая свободная ОС это Unix-like мир. Не многие захотят отказаться от привычного почтового клиента и привычных программ для общения с «внешним миром». FidoNet с UUCP это совершенно иные экосистемы.

В идеале, хотелось бы иметь нечто, что было бы как можно более прозрачно для email и передачи файлов. Вместе с этим и имело современную криптографическую безопасность. Этого можно достичь с UUCP, но прикручивая к нему дополнительные обёртки для шифрования и аутентификации. Кроме того, ни FidoNet ни UUCP не заточены из коробки на работу через сменные накопители информации. Да, в FidoNet можно скопировать исходящие пакеты на дискету и на целевом узле скопировать их назад, но это ручное действие, легко получающееся в виду простоты системы, но штатно не предусмотренное (нет команд «вот тебе дискета, я хочу пойти к Вовану», «вот я с дискетой от Вована, побывавшая и у Васька, действуй»).

Для удовлетворения этой хотелки и создан набор свободных (GNU GPLv3+) программ NNCP. Они заточены на то, чтобы, как можно с меньшими человеческими затратами, организовать современную небольшую store-and-forward сеть.

Рассмотрим как всем этим пользоваться на конкретных примерах.

Мы, Алиса (возьмём имена уж из мира криптографии) и Боб, установили себе NNCP и у нас куча nncp-* команд. Для начала создадим (командой nncp-cfgnew) свои собственные пары криптографических ключей:

alice% nncp-cfgnew | tee alice.yaml
self:
  id: ZY3VTECZP3T5W6MTD627H472RELRHNBTFEWQCPEGAIRLTHFDZARQ
  exchpub: F73FW5FKURRA6V5LOWXABWMHLSRPUO5YW42L2I2K7EDH7SWRDAWQ
  exchprv: 3URFZQXMZQD6IMCSAZXFI4YFTSYZMKQKGIVJIY7MGHV3WKZXMQ7Q
  signpub: D67UXCU3FJOZG7KVX5P23TEAMT5XUUUME24G7DSDCKRAKSBCGIVQ
  signprv: TEXUCVA4T6PGWS73TKRLKF5GILPTPIU4OHCMEXJQYEUCYLZVR7KB7P2LRKNSUXMTPVK36X5NZSAGJ632KKGCNODPRZBRFIQFJARDEKY
  noiseprv: 7AHI3X5KI7BE3J74BW4BSLFW5ZDEPASPTDLRI6XRTYSHEFZPGVAQ
  noisepub: 56NKDPWRQ26XT5VZKCJBI5PZQBLMH4FAMYAYE5ZHQCQFCKTQ5NKA
neigh:
  self:
    id: ZY3VTECZP3T5W6MTD627H472RELRHNBTFEWQCPEGAIRLTHFDZARQ
    exchpub: F73FW5FKURRA6V5LOWXABWMHLSRPUO5YW42L2I2K7EDH7SWRDAWQ
    signpub: D67UXCU3FJOZG7KVX5P23TEAMT5XUUUME24G7DSDCKRAKSBCGIVQ
    noisepub: 56NKDPWRQ26XT5VZKCJBI5PZQBLMH4FAMYAYE5ZHQCQFCKTQ5NKA
    sendmail:
    - /usr/sbin/sendmail
spool: /var/spool/nncp/alice
log: /var/spool/nncp/alice/log

NNCP создаёт исключительно Friend-to-Friend (F2F) сети, где каждый участник знает о соседях с которыми общается. Если Алисе надо контактировать с Бобом, то, предварительно, они обязаны обменяться своими публичными ключами и прописать их в конфигурационные файлы. Узлы обмениваются между собой, так называемыми, зашифрованными пакетами — неким аналогом OpenPGP. Каждый пакет явно адресован заданному участнику. Это не Peer-to-Peer (P2P), где любой может подключиться к любому и что-то отослать: это создаёт возможность Sybil атак, когда ноды злоумышленника могут вывести всю сеть из строя или, как минимум, следить за активностью участников в ней.

Простейший конфигурационный файл содержит следующие поля:

  • self.id — идентификатор нашей ноды
  • self.exchpub/self.exchprv и self.signpub/self.signprv — ключи используемые для создания зашифрованных пакетов
  • self.noisepub/self.noiseprv — опциональные ключи используемые при общении узлов по TCP соединению
  • neigh — содержит информацию обо всех известных участниках сети, «соседях». Всегда содержит запись self — в ней находятся ваши публичные данные и именно её можно смело раздавать людям, так как в ней только публичные части ключей
  • spool — путь до spool-директории где находятся исходящие зашифрованные пакеты и необработанные входящие
  • log — путь до журнала в котором сохраняются все выполняемые действия (отправленный файл/письмо, принятые, итд)

Боб генерирует свой файл. Обменивается с Алисой своим ключом и добавляет её в свой конфигурационный файл (Алиса делает то же самое):

alice% cat bob.yaml
self:
  id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
  exchpub: GQ5UPYX44T7YK5EJX7R73652J5J7UPOKCGLKYNLJTI4EBSNX4M2Q
  exchprv: HXDO6IG275S7JNXFDRGX6ZSHHBBN4I7DQ3UGLOZKDY7LIBU65LPA
  signpub: 654X6MKHHSVOK3KAQJBR6MG5U22JFLTPP4SXWDPCL6TLRANRJWQA
  signprv: TT2F5TIWJIQYCXUBC2F2A5KKND5LDGIHDQ3P2P3HTZUNDVAH7QUPO6L7GFDTZKXFNVAIEQY7GDO2NNESVZXX6JL3BXRF7JVYQGYU3IA
  noiseprv: NKMWTKQVUMS3M45R3XHGCZIWOWH2FOZF6SJJMZ3M7YYQZBYPMG7A
  noisepub: M5V35L5HOFXH5FCRRV24ZDGBVVHMAT3S63AGPULND4FR2GIPPFJA
neigh:
  self:
    id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
    exchpub: GQ5UPYX44T7YK5EJX7R73652J5J7UPOKCGLKYNLJTI4EBSNX4M2Q
    signpub: 654X6MKHHSVOK3KAQJBR6MG5U22JFLTPP4SXWDPCL6TLRANRJWQA
    noisepub: M5V35L5HOFXH5FCRRV24ZDGBVVHMAT3S63AGPULND4FR2GIPPFJA
    sendmail:
    - /usr/sbin/sendmail
  alice:
    id: ZY3VTECZP3T5W6MTD627H472RELRHNBTFEWQCPEGAIRLTHFDZARQ
    exchpub: F73FW5FKURRA6V5LOWXABWMHLSRPUO5YW42L2I2K7EDH7SWRDAWQ
    signpub: D67UXCU3FJOZG7KVX5P23TEAMT5XUUUME24G7DSDCKRAKSBCGIVQ
    noisepub: 56NKDPWRQ26XT5VZKCJBI5PZQBLMH4FAMYAYE5ZHQCQFCKTQ5NKA
spool: /var/spool/nncp/bob
log: /var/spool/nncp/bob/log

Далее, Боб хочет послать файл Алисе:

bob% nncp-file -cfg bob.yaml ifmaps.tar.xz alice:
2017-06-11T15:33:20Z File ifmaps.tar.xz (350 KiB) transfer to alice:ifmaps.tar.xz: sent

и ещё и бэкап своей файловой системы, но делая через Unix-way конвейеры:

bob% export NNCPCFG=/path/to/bob.yaml
bob% zfs send zroot@backup | xz -0 | nncp-file - alice:bobnode-$(date "+%Y%m%d").zfs.xz
2017-06-11T15:44:20Z File - (1.1 GiB) transfer to alice:bobnode-20170611.zfs.xz: sent

Затем он может посмотреть на то, чем загромождена его spool директория:

bob% nncp-stat
self
alice
        nice: 196 | Rx:        0 B,   0 pkts | Tx:    1.1 GiB,   2 pkts

Каждый пакет, кроме информации об отправителе и получателе, содержит ещё и, так называемый, nice уровень. Это просто однобайтное число — приоритет. Почти все действия можно сопроводить ограничением на максимально допустимый уровень nice. Это аналог grade в UUCP. Используется для того, чтобы в первую очередь обрабатывать пакеты с более высоким приоритетом (меньшим значением nice), чтобы почтовые сообщения проходили не смотря на то, что в фоне пытается передаться фильм на DVD. По-умолчанию, для отправки файлов задаётся приоритет 196, который мы и видим. Rx это принятые пакеты, ещё не обработанные, а Tx это пакеты для передачи.

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

При передаче файлов можно указать опцию -chunked, указав ей размер кусочка на которые должен будет быть побит файл. Тут используется очень напоминающая BitTorrent схема: файл бьётся на части и добавляется meta-файл содержащий информацию о каждом кусочке, для гарантированного, с точки зрения целостности, восстановления файла. Это может быть полезно, если нужно скрыть размеры огромных файлов (как с трупом — одним куском его проблематично перетаскивать, а вот разделив на шесть частей, куда проще). Ещё полезно, когда нужно передать большие объёмы данных через накопители заведомо меньших размеров: тогда передача данных произведётся за несколько итераций.

Теперь это надо как-то передать Алисе. Один из способов — через накопитель данных, через копирование файлов на файловой системе.

Боб берёт USB flash накопитель, создаёт на нём файловую систему, запускает:

bob% nncp-xfer -mkdir /mnt/media
2017-06-11T18:23:28Z Packet transfer, sent to node alice (1.1 GiB)
2017-06-11T18:23:28Z Packet transfer, sent to node alice (350 KiB)

и получает там набор директорий со всеми исходящими пакетами для каждой известной ему ноды. Какие именно ноды «рассматривать» можно ограничить опцией -node. Опция -mkdir требуется только для первого запуска — если директории для соответствующих нод уже есть на накопителе, то они будут обработаны, а в противном случае ноды просто будут пропущены. Это удобно тем, что если флешка «ходит» только между некоторыми участниками «сети», то только пакеты для них и будут помещаться на накопитель, без необходимости постоянно указывать -node.

Вместо USB накопителя может выступать временная директория из которой будет создан ISO образ для записи на компакт-диск. Это может быть какой-то публичный FTP/NFS/SMB сервер, подмонтированный в /mnt/media директорию. Подобный NAS может быть размещён на работе или ещё где-то — лишь бы двое контактирующих участников хоть изредка но имели возможность подключиться к нему. Это может быть портативный PirateBox, по пути собирающий и раздающий NNCP пакеты. Это может USB dead drop, к которому время от времени, подключаются совершенно разные и незнакомые люди: если в целевой директории есть неизвестные ноды, то мы их игнорируем и можем только узнать о факте их существования и количестве передаваемых пакетов.

Все эти накопители и хранилища содержат только зашифрованные пакеты. Видно от кого и кому они предназначены, сколько, какого размера и приоритета. Но не более. Без приватных ключей нельзя узнать даже тип пакета (почтовое сообщение это, файл или транзитный пакет). NNCP не пытается быть анонимным.

Использование nncp-xfer не требует никаких приватных ключей: нужны только знания о соседях — их идентификаторы. Таким образом, можно отправляться в дорогу с spool директорией и минимальным конфигурационным файлом (без приватных ключей) подготовленным командой nncp-cfgmin, не боясь за компрометацию ключей. nncp-toss вызов, требующий приватных ключей, можно выполнить в любое другое удобное время. Однако, если всё же боязно за безопасность приватных ключей или даже конфигурационного файла, где все ваши соседи перечислены, то можно использовать утилиту nncp-cfgenc, позволяющую его зашифровать. В качестве ключа шифрования используется парольная фраза введённая с клавиатуры: в зашифрованном файле есть соль, пароль усиливается CPU и memory hard алгоритмом Balloon, поэтому, имея хорошую парольную фразу, можно особо не беспокоиться о компрометации (кроме паяльника).

Алисе достаточно выполнить команду чтобы скопировать предназначенные для неё файлы в свою spool директорию:

alice% nncp-xfer /mnt/media
2017-06-11T18:41:29Z Packet transfer, received from node bob (1.1 GiB)
2017-06-11T18:41:29Z Packet transfer, received from node bob (350 KiB)
alice% nncp-stat
self
bob
        nice: 196 | Rx:    1.1 GiB,   2 pkts | Tx:        0 B,   0 pkts

Мы видим, что у неё появились необработанные (Rx) пакеты в spool директории. Однако, не всё так просто. У нас хоть и сеть друзей (F2F), доверяй, но проверяй. Вы должны явно разрешить заданной ноде отправлять вам файлы. Для этого Алиса должна добавить в раздел Боба конфигурационного файла указание куда помещать передаваемые от него файлы.

bob:
  id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
  exchpub: GQ5UPYX44T7YK5EJX7R73652J5J7UPOKCGLKYNLJTI4EBSNX4M2Q
  signpub: 654X6MKHHSVOK3KAQJBR6MG5U22JFLTPP4SXWDPCL6TLRANRJWQA
  noisepub: M5V35L5HOFXH5FCRRV24ZDGBVVHMAT3S63AGPULND4FR2GIPPFJA
  incoming: /home/alice/bob/incoming

После этого, нужно запустить обработку входящих зашифрованных пакетов командой nncp-toss (аналогично tosser-у в FidoNet):

alice% nncp-toss
2017-06-11T18:49:21Z Got file ifmaps.tar.xz (350 KiB) from bob
2017-06-11T18:50:34Z Got file bobnode-20170611.zfs.xz (1.1 GiB) from bob

Эта команда имеет опцию -cycle, позволяющая ей висеть в фоне и регулярно проверять и обрабатывать spool директорию.

Кроме отправки файлов, есть возможность и запроса на передачу файла. Для этого, необходимо в конфигурационном файле явно прописать freq (file request) запись для каждой ноды из какой директории можно запрашивать файлы:

bob:
  id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
  exchpub: GQ5UPYX44T7YK5EJX7R73652J5J7UPOKCGLKYNLJTI4EBSNX4M2Q
  signpub: 654X6MKHHSVOK3KAQJBR6MG5U22JFLTPP4SXWDPCL6TLRANRJWQA
  noisepub: M5V35L5HOFXH5FCRRV24ZDGBVVHMAT3S63AGPULND4FR2GIPPFJA
  incoming: /home/alice/nncp/bob/incoming
  freq: /home/alice/nncp/bob/pub

теперь Боб может сделать запрос на файл:

bob% nncp-freq alice:pulp_fiction.avi PulpFiction.avi
2017-06-11T18:55:32Z File request from alice:pulp_fiction.avi to pulp_fiction.avi: sent
bob% nncp-xfer -node alice /mnt/media

а Алиса, после обработки входящих сообщений, автоматически ему отправит запрошенный файл:

alice% nncp-toss
2017-06-11T18:59:14Z File /home/alice/nncp/bob/pub/pulp_fiction.avi (650 MiB) transfer to bob:PulpFiction.avi: sent
2017-06-11T18:59:14Z Got file request pulp_fiction.avi to bob

Нет функционала по отправке списка файлов, но о нём всегда можно договориться пользователям, например, сохранив вывод ls -lR в ls-lR файле корневой директории.

Теперь, представим, что Алиса и Боб знают Еву (но эта Eve хорошая, не плохая криптографическая, ведь у нас же сеть друзей), однако Алиса не имеет прямого контакта с ней. Они живут в разных городах и только Боб курирует между ними время от времени. В NNCP поддерживаются транзитные пакеты, устроенные аналогично луковичному шифрованию в Tor: Алиса может создать зашифрованный пакет для Евы, и поместить его в ещё один зашифрованный пакет для Боба, с указанием, что его надо переслать Еве. Длина цепочки не ограничена и промежуточный участник знает только предыдущее и последующее звено цепи, не зная настоящего отправителя и получателя.

Указание транзитного пути задаётся записью via в ноде. Например Алиса хочет сказать что Ева доступна через Боба:

bob:
  id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
  exchpub: GQ5UPYX44T7YK5EJX7R73652J5J7UPOKCGLKYNLJTI4EBSNX4M2Q
  signpub: 654X6MKHHSVOK3KAQJBR6MG5U22JFLTPP4SXWDPCL6TLRANRJWQA
  noisepub: M5V35L5HOFXH5FCRRV24ZDGBVVHMAT3S63AGPULND4FR2GIPPFJA
eve:
  self:
  id: URVEPJR5XMJBDHBDXFL3KCQTY3AT54SHE3KYUYPL263JBZ4XZK2A
  exchpub: QI7L34EUPXQNE6WLY5NDHENWADORKRMD5EWHZUVHQNE52CTCIEXQ
  signpub: KIRJIZMT3PZB5PNYUXJQXZYKLNG6FTXEJTKXXCKN3JCWGJNP7PTQ
  noisepub: RHNYP4J3AWLIFHG4XE7ETADT4UGHS47MWSAOBQCIQIBXM745FB6A
  via: [bob]

Как конкретно Ева контактирует с Бобом Алисе не известно и нет необходимости знать: как-то сообщения до неё должны дойти и Боб видит только факты отправки транзитного трафика. Исходящее сообщение до Евы у Боба создаётся автоматически nncp-toss-ом после обработки сообщения от Алисы.

Если речь идёт о хорошей безопасности, то для этого нужно использовать компьютеры с воздушным зазором (air-gapped) — не подключённые к сетям передачи данных, в идеале имеющих, например, только CD-ROM/RW. А «перед» ними находится компьютер в который втыкаются флешки или трафик от других нод: на нём можно убедиться что флешки не содержат ничего вредоносного, и, если он подключён к Интернету или другой сети, то уязвимости ОС не могут скомпрометировать air-gapped компьютер. На подобную ноду приходят только транзитные пакеты, которые породят исходящие сообщения для air-gapped компьютера записываемые на компакт-диск.

Если в конфигурационный файл добавить раздел:

notify:
  file:
    from: nncp@bobnode
    to: bob+file@example.com
  freq:
    from: nncp@bobnode
    to: bob+freq@example.com

то на почту bob+file@example.com будут отправляться уведомления о переданных файлах, а на bob+freq@example.com уведомления о запрошенных файлах.

NNCP может быть легко интегрирован с почтовым сервером для прозрачной передачи почты. Чем обычный SMTP не подходит, ведь он тоже store-and-forward? Тем, что нельзя использовать флешки (без плясок), тем что SMTP трафик, как и почтовые сообщения, не очень компактен (бинарные данные в Base64 виде), плюс в нём довольно серьёзные ограничения на максимальное время ожидания доставки корреспонденции. Если вы деревушка в Уганде и до вас раз в неделю ходит курьер с флешкой, то SMTP тут никак не подойдёт, а NNCP в самый раз передаст пачку писем для каждого жителя деревушки и заберёт назад в город.

Для отправки почты используется nncp-mail команда. Фактически это точно такая же передача файла, но на целевой машине вызывается sendmail, вместо сохранения сообщения на диск, и само сообщение сжимается. Настройка Postfix занимает буквально считанные строки:

  • в master.cf указывается как использовать nncp транспорт (как вызвать nncp-mail команду)
  • для заданного домена/пользователя задаётся что должен быть использован этот nncp транспорт
  • указать что заданный домен или пользователь является транзитным (relay)

На целевой машине необходимо для заданной ноды прописать путь до команды отправляющей почту (если она не будет задана, то почта не будет отправляться):

bob:
  id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
  exchpub: GQ5UPYX44T7YK5EJX7R73652J5J7UPOKCGLKYNLJTI4EBSNX4M2Q
  signpub: 654X6MKHHSVOK3KAQJBR6MG5U22JFLTPP4SXWDPCL6TLRANRJWQA
  noisepub: M5V35L5HOFXH5FCRRV24ZDGBVVHMAT3S63AGPULND4FR2GIPPFJA
  sendmail: [/usr/sbin/sendmail, "-v"]

Подобный прозрачный подход позволяет полностью избавиться от POP3/IMAP4 серверов и почтовых клиентов сохраняющих письма как черновики, когда нужно прозрачно принимать и отсылать почту между вашим почтовым сервером и ноутбуком. Почтовый сервер всегда смотрит в Интернет, а ноутбук без разницы как часто подключается: NNCP примет почту и отправит в его локальный sendmail, который доставит до локального почтового ящика. И аналогично отправка: падающие сообщения в локальный почтовый сервер на ноутбуке сохранятся в NNCP spool директории и будут отправлены на сервер как только, так сразу (с точки зрения почтового клиента почта успешно отправлена сразу же). Плюс сжатый почтовый трафик.

Использование переносных накопителей не всегда удобно, особенно сейчас, когда Интернет у нас всё же работоспособный имеется. NNCP можно удобно использовать для передачи пакетов поверх TCP соединений. Для этого имеется nncp-daemon демон и nncp-call команда его вызывающая.

Для обмена зашифрованными пакетами можно было бы использовать rsync протокол, возможно поверх OpenSSH соединения, но это бы означало какой-то костыль, плюс очередное звено и очередные ключи для аутентификации нод. В NNCP используется самостоятельный протокол синхронизации SP (sync protocol), используемый поверх Noise-IK зашифрованного и аутентифицированного канала связи. NNCP пакеты хоть и зашифрованы, но светиться ими публично в каналах связи не хорошо — поэтому над этим и имеется дополнительный слой. Noise предоставляет совершенную прямую секретность (PFS, когда компрометация приватных ключей Noise не даст прочитать ранее перехваченный трафик) и двустороннюю аутентификацию: к вам не смогут подключиться незнакомые люди и что-то отправить или попытаться принять.

SP протокол пытается быть максимально эффективным в полудуплексном режиме: как можно больше данных должно быть передано в одну сторону, ничего не ожидая в ответ. Это критично для спутниковых каналов связи, где протоколы, ожидающие подтверждение принятия или отправляющие запросы на следующий кусочек данных, полностью деградируют по производительности. Однако полнодуплексный режим полностью поддерживается, пытаясь утилизировать канал связи в обе стороны.

SP старается быть экономным в количестве пересылаемых пакетов данных: уже в момент Noise-IK рукопожатия сразу же отправляются списки пакетов доступных для скачивания, а запросы на скачивание отправляются пачкой.

SP рассчитан на работу в каналах связи без ошибок: это не обязательно должен быть TCP — в качестве транспорта всё что угодно, лишь бы без ошибок. Пакеты с нарушенной целостностью не будут взяты в обработку. Успешность принятия пакета сообщается противоположной стороне только после проверки целостности.

Протокол позволяет продолжить скачивание любого пакета с любого произвольного места. То есть, при обрыве соединения, самое ощутимая потеря это TCP+Noise рукопожатие, а дальше продолжение с того же места. Как только на ноде появляется новый пакет для отправки, то противоположная сторона сразу же (раз в секунду) об этом осведомляется, позволяя ей прервать текущее скачивание и поставить в очередь более приоритетный пакет.

% nncp-daemon -nice 128 -bind [::]:5400

команда поднимает демона, слушающего на всех адресах по 5400 TCP порту, но пропускающий пакеты с уровнем nice не выше 128-го. Если возможные адреса демона заданной ноды известны, то их можно прописать в конфигурационном файле:

bob:
  id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
  ...
  addrs:
    lan: "[fe80::be5f:f4ff:fedd:2752%igb0]:5400"
    pub: "bob.example.com:5400"

а затем вызвать ноду:

% nncp-call bob
% nncp-call bob:lan
% nncp-call bob:main
% nncp-call bob forced.bob.example.com:1234

В первой команде будут опробованы все адреса из addrs, во второй и третьей явно сказано использовать lan и pub записи, а последняя говорит использовать чётко заданный адрес, не смотря на конфигурационный файл.

Демону, как и nncp-call, можно указать минимальный необходимый nice уровень: например пропускать только почтовые сообщения поверх Интернет канала (предполагая что у них бОльший приоритет), а передачу тяжёлых файлов оставить на переносные накопители или отдельно запущенного демона, слушающего только в быстрой локальной сети. nncp-call можно указать опции -rx и -tx, заставляющие его только принимать или только отправлять пакеты.

К сожалению, в SP протоколе нет возможности договориться сторонам о том, что соединение может быть закрыто. Сейчас это реализуется за счёт timeout: если обе ноды ничего не имеют для отправки и получения, то через заданное время они рвут соединение. Но это время можно выставить -onlinedeadline опцией на очень большой срок (часы) и тогда у нас будет долгоживущее соединение, в котором сразу будут слаться оповещения о новых пакетах. Это позволяет экономить на дорогих рукопожатиях протокола. В случае с отправкой почты, это также и очень быстрое оповещение о пришедшей корреспонденции, без необходимости как в POP3 постоянно делать polling, разрывая соединение.

TCP соединения можно использовать и без подключения к Интернету. Например, немножко помазавшись shell-скриптами можно настроить на ноутбуке поднятие ad-hoc WiFi сети и слушать демоном на IPv6 link-local адресе, пытаясь постоянно подключаться в другому известному адресу. И проезжая в метро на эскалаторе, два ноутбука, относительно быстро, могут увидеть друг друга в общей ad-hoc сети и быстро «пострелять» друг в друга NNCP пакетами. WiFi довольно быстр, поэтому даже за считанные секунды можно передать одной только почты в больших количествах. А если это вагон электрички, где регулярно одни и те же люди, примерно в одно и то же время ездят каждый день на работу или с неё, то там могут быть и десятки минут постоянной связи. Но не забываем, что, передавая каждый день двухтерабайтный жёсткий диск, мы получим только в одном направлении 185 мегабитный канал связи с отличным качеством (без ошибок).

Ещё одной отличительной утилитой является nncp-caller. Это демон, который занимается вызовом соседей по TCP в заданное время, по заданным адресам, с заданными параметрами передачи/приёма. Его конфигурация прописывается для каждой нужной ноды с использованием cron-выражений. Например:

bob:
  id: FG5U7XHVJ342GRR6LN4ZG6SMAU7RROBL6CSU5US42GQ75HEWM7AQ
  ...
  calls:
    -
      cron: "*/10 9-21 * * MON-FRI"
      nice: 128
      addr: pub
      xx: rx
    -
      cron: "*/1 21-23,0-9 * * MON-FRI"
      onlinedeadline: 3600
      addr: lan
    -
      cron: "*/1 * * * SAT,SUN"
      onlinedeadline: 3600
      addr: lan

Это описание вызовов говорит следующее: каждые десять минут в будние дни, в рабочее время, свяжись с Бобом (по публичному адресу, чтобы попытка соединения с локальным IPv6 link-local адресом не выдала его адреса в сеть), принимая только высокоприоритетные пакеты (наверняка почта), но ничего не отправляя; в не рабочее время пытайся связаться с ним по LAN адресу, принимая пакеты любых приоритетов и удерживая TCP соединение (незачем тратиться на рукопожатия), как минимум, в течении часа простоя; в выходные дни работай круглосуточно только с его LAN адресом.

Подобные описания вызовов позволяют гибко управлять когда и как с кем общаться. Если между нодами телефонная линия, то время звонка напрямую отражается на стоимости. К сожалению, сейчас вызов не по TCP адресам не реализован, но это точно будет прописываться в addrs секции конфигурационного файла.

Рассмотрены конечно же не все функции и сценарии использования NNCP. Совсем не рассмотрены форматы пакетов и SP протокол. Основной принцип при создании этих утилит: KISS и бойкот сложности. Хотя этот набор далеко не всё делает в Unix-way стиле и берёт много задач сверх минимально необходимого для store-and-forward сетей, но это исключительно для экономии на дополнительных зависимостях.
Теги:
Хабы:
+6
Комментарии 8
Комментарии Комментарии 8

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн