IPFS redistribute

Posted: 2024-01-05 in IT, Networks
Метки:

Всем привет. Сегодня мы поговорим о чуть более надёжном хранении, репликации и редистрибуции файлов в публичном интернете. Естественно, в духе современного Web 3.0

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

Это особенно раздражает, когда информация была редкая и при этом толковая.

И если популярным книгам / фильмам / играм / софту тут относительно повезло — они популярны в торрент-дистрибуции, то пропавшие картинки с веб-страниц или вообще умершие страницы чаще всего утрачены безвозвратно.

Проблема известна и в целом осознаётся, однако пока что качественно мало что меняется.

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

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

IPFS  Logo PNG from IPFS Gateway
Сперва поговорим о технических подробностях.

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

— случайно опубликованное, но уже скачанное другими участниками (и интересное для них!) удалить будет практически невозможно.
— при выходе новой версии старые версии удалить также почти невозможно (но ничто не мешает убрать ссылки и старые копии у себя).
— чем интереснее и распространённее файл, тем быстрее он скачивается и надёжнее хранится, хотя для доступности достаточно всего одной ноды.

— Интересные файлы лучше скачать к себе (за-pin-ить). Для этого есть ряд вариантов — своя нода, сервис типа Pinata.cloud, возможности ipfs-ready браузеров типа Brave / Opera, где IPFS встроен.
— Очень мощной может получиться связка IPFS и BitTorrent. IPFS по сути — специфичная DHT для отдельных файлов, причем контентно-адресуемая, чего торренту местами не помешает.

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

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

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

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

2. Практика.
Начнём с самого логичного и простого — сделаем ноду IPFS и повторно раздадим в эту IPFS некоторые файлы, уже раздаваемые через бит-торрент.

Я использовал клиент ipfs-go — это один большой бинарь. В федоровских репах его нет, так что качаем с их гитхаба последний релиз kubo:

https://github.com/ipfs/kubo/releases

Например, для нашего 64-битного линукса файл будет kubo_v0.25.0_darwin-amd64.tar.gz

Нам нужен с него бинарный файл ipfs, весит он под 85 Мб, зато все зависимости внутри.

Запускаеть его будем от отдельного пользователя, никакие особые права доступа ему не требуются. В файевроле стоит открыть порты TCP+UDP 4001.

Сперва даём команду

./ipfs init

для генерации ключа ноды и создания базовых конфигов, который запишутся в ~/.ipfs

Для запуска в виртуальном терминале достаточно прописать в автозапуск такую команду:

/usr/bin/su - ipfs -c "screen -dmS IPFSd /opt/ipfs daemon" &

Если у вас SystemD / UpStart / OpenRC или ещё что-то — в документации есть описание наиболее правильного способа автозапуска программы под нужным пользователем.
Пример юнита для systemd:

# cat /lib/systemd/system/ipfs.service

[Unit]
Description=IPFS Daemon
After=network.target

[Service]
ExecStart=/opt/ipfs daemon
User=ipfs
Restart=always
LimitNOFILE=10240
Environment=“IPFS_PATH=/home/ipfs”

[Install]
WantedBy=multi-user.target

Если всё ок, то вы увидите открытые им сетевые порты:

# netstat -nltp | grep ipfs
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 1426/ipfs
tcp 0 0 0.0.0.0:4001 0.0.0.0:* LISTEN 1426/ipfs
tcp 0 0 127.0.0.1:5001 0.0.0.0:* LISTEN 1426/ipfs
tcp6 0 0 :::4001 :::* LISTEN 1426/ipfs

Порт 4001 по-умолчанию нужен для межсерверного взаимодействия, на 5001 висит веб-морда http://127.0.0.1:5001/webui, на 8080 — локальная нода для получения файлов из IPFS-сети по адресам вида http://127.0.0.1:8080/ipfs/$CID/%5Bpath?%5D

Важный момент !
Чтобы стало возможным прикрепление уже существующих файлов, каталоги с раздаваемыми файлами должен быть симлинкнуты в ~/.ipfs ! Без этого IPFS откажется их добавлять. Вилимо, сделано как страховочная мера от случайного расшаривания всей файловой системы =)

$ ls -l ~/.ipfs/ | grep lr
...
lrwxrwxrwx. 1 ipfs ipfs 27 янв 5 19:37 Share_42 -> /mnt/raid5/Share_42
lrwxrwxrwx. 1 ipfs ipfs 23 дек 24 19:53 Torrents -> /mnt/raid5/Torrents
...

Поскольку файлы для раздачи у нас уже есть, мы их просто добавим в список прикреплённых к IPFS-ноде:

/opt/ipfs add -r -w --nocopy ~/.ipfs/Torrents/OS/Fedora39_DVD_x64/

Самое главное — не забыть опцию —nocopy !
Начнётся процесс вычисления хэшей, и мы увидим что-то подобное:

added Qm...aaa filename.iso
added Qm...bbb filename.iso.sha256
added Qm...ccc screenshot.png
added Qm...ddd Fedora39_DVD_x64
added Qm...xxx

Теперь немного надо рассказать об опциях.

Самая главная: nocopy. Она позволяет не тратить лишнее место под ещё одну копию файла.

Опция -r говорит добавить каталог целиком, recursive. Если вы публикуете целый каталог, обязательно её укажите.

Опция -w самая интересная. Wrap files with a directory object.
Она создаёт ещё один крохотный объект IPFS, который сохранит исходное имя файла / каталога.

Объясню на примере выше. Сперва будет добавлено содержимое ISO-файла, которое будет доступно по CID (хэшу) Qm…aaa. Соедержимое файла с контрольной суммой filename.iso.sha256 — по хэшу Qm…bbb, а скриншот по хэшу Qm…ссс. Однако сами имена файлов внутри храниться НЕ будут, по этим хэшам будет только их внутреннее содержимое !

Для сохранения имён файлов в каталоге будет создан отдельный объект с тремя ссылками на файловые объекты с хэшем Qm…ddd. Но внутри будет только содержимое списка файлов — индекс каталога, в котором сохранятся имена вложенных файлов и их хэши, но не имя самого каталога Fedora39_DVD_x64. А вот опция -w сгенерит нам ещё один объект — Qm…xxx, в котором и будет сохранено имя исходного каталога.

То есть схема получается такая:

Qm...xxx -> [ Fedora39_DVD_x64 -> Qm...ddd ]
Qm...ddd ->
[ filename.iso -> Qm...aaa
filename.iso.sha256 -> Qm...bbb
screenshot.png -> Qm...ccc ]
Qm...ccc -> [binary data (PNG)]
Qm...bbb -> [text-data (sha256)]
Qm...aaa -> [binary data (ISO)]

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

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

Повторить это может любой, кто знает значение хэша.

Если же на втором сервере файла нет, и мы хотим его просто поддержать, то мы даём команду для фиксации у себя локальной копии нужного нам файла. Например, вот там мы сделаем себе свою копию логотипа IPFS из этой стаатьи:

./ipfs pin add QmSNssW5a9S3KVRCYMemjsTByrNNrtXFnxNYLfmDr9Vaan
pinned QmSNssW5a9S3KVRCYMemjsTByrNNrtXFnxNYLfmDr9Vaan recursively

Чтобы посмотреть, какие файлы у нас уже раздаёт IPFS, есть такая команда:

./ipfs files ls -l

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

Если у нас нет своего сервера, то мы можем зарегаться на той же pinata.cloud, и просто залить файлы туда — получим те же хэши. Также ничто не мешает на той же пинате прикрепить свои уже ранее добавленные в сеть файлы по CID (локальные имена тут не важны). Вообще связка облачный IPFS-гейт + пин файла в этом же облаке позволяет получать файлы из этого облака без задержек, но в случае аврала относительно легко переключиться хоть на другой гейт, хоть вообще на свою ноду.

Важная заметка. Как и в торренте, крупные файлы, подкреплённые буквально парой серверов, могут отдаваться далеко не сразу и не быстро — тут нужно время. Самый правильный путь — добавлять к себе, тут как в торренте. Хочешь всегда доступный файл — присоединись к раздаче.

После того, как файл добавлен, берем любой гейт из списка:
https://ipfs.github.io/public-gateway-checker/

и пробуем открыть файл через него:

IPFS-over-gateway link to IPFS Logo

Только вместо QmSN…Vaan подставляем свои значения. Если файл нормально аннонсировался — должен открыться. Зная хэш, можно открыть файл через любой из шлюзов, включая собсьвенный.

Есть уже даже браузер — Brave, в котором поддержка IPFS есть из коробки. Для файерфокса и хрома есть расширение ipfs-companion.

И вот такие адреса уже можно пробовать использовать как минимум в качестве целевых для скачивания внутри тегов a href=…
Для использования внутри тегов img src=… надо убедится, что файл нормально отдаётся, гейт не блокирует отдачу, а CSP-политика на веб-сервере не запрещает загрузку с гейта.

Для применения у себя я бы рекомендовал апнуть свой гейт — это несложно, а для малого объёма файлов не накладно. Не забудьте настроить опцию NoFetch, если конечно вы не желаете сделать публичный IPFS-прокси для всего интернета. Также для стыковки с веб-серверами может потребоваться настройка CORS.

Например, ссылка на каталог с образом и описанием готовой виртуальной машины для шлюза (файервол iptables / NAT / tcpdump / VLAN / QinQ / DNS / DHCP ) может выглядеть вот так:

ipfs://QmfTTAnV58sS7zce5Z9mNrjpvEkBP92rpD8YnaagDj13e6/

Она будет работать только в браузерах с поддержкой IPFS или в самом локальном pfs-клиенте. Тут нет никакого адреса севрера.

Либо можно её же открыть через шлюзы:
https://cloudflare-ipfs.com/ipfs/QmfTTAnV58sS7zce5Z9mNrjpvEkBP92rpD8YnaagDj13e6/
https://ipfs.io/ipfs/QmfTTAnV58sS7zce5Z9mNrjpvEkBP92rpD8YnaagDj13e6/
https://hardbin.com/ipfs/QmfTTAnV58sS7zce5Z9mNrjpvEkBP92rpD8YnaagDj13e6/
https://bafybeih6ksy666sj5hltc3gnoduiclkxcnnk3zahag4j76647ihggwpab4.ipfs.dweb.link/

Все эти ссылки ведут на один и тот же объект.
Вы наверняка заметили, что хэши бывают двух видов. Для конвертации есть готовый сервис:
https://cid.ipfs.io/

+ конвертацию умеет делать локальный клиент.

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

Вот такая вот занятная технология, ещё пару лет назад упоминавшаяся больше в контексте хранения содержимого NFT.

Вообще идея IPFS мне понравилась, штука достаточно изящная, удобная и внятно автоматизируемая. По мере освоения я планирую задублировать туда часть контента с моего блога для большей сохранности.

- комментарии
  1. Микола Федорович Крисюк:

    В статье Узнаём истинный объём флешки не могу оставить коментарий
    Флешка прошитая на 8гб, реально 500 Мб, но скрипт показывает OK. Почему?
    https://dropmefiles.net/ru/2VBhZEALw

  2. Amin:

    Значит мошенники замаппили и дальнюю область памяти, и такая быстрая проверка уже не помогает. Тут только тяжелые решения (и долгие по времени выполнения) тогда, с записью полной ёмкости.

Оставьте комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.