IPFS без болка (но не е сигурно)

IPFS без болка (но не е сигурно)

Въпреки че в Хабр вече имаше не една статия за IPFS.

Искам да уточня, че не съм експерт в тази област, но неведнъж проявявах интерес към тази технология и опитите ми да се занимавам с нея често предизвикваха някаква болка. Днес отново се захванах с експерименти и получих някакви резултати, с които искам да споделя. С две думи, ще бъде описан процесът на инсталиране на IPFS и някои трикове (всичко беше извършено на ubuntu, не съм пробвал на други платформи).

Ако сте пропуснали какво е IPFS, доста подробно е написано тук: habr.com/ru/post/314768

Инсталиране на

За чистотата на експеримента предлагам веднага да се инсталира на някакъв външен сървър, тъй като ще разгледаме някои подводни камъни при работа в локален и отдалечен режим. После, при желание, не е трудно да се премахне, не е много.

Инсталираме go

Официална документация
Актуалната версия можете да видите на golang.org/dl

Забележка: по-добре е да инсталирате IPFS от името на потребителя, който най-често ще се използва. Истината е, че по-долу ще разгледаме варианта с монтиране през FUSE и там има нюанси.

cd ~
curl -O https://dl.google.com/go/go1.12.9.linux-amd64.tar.gz
tar xvf go1.12.9.linux-amd64.tar.gz
sudo chown -R root:root ./go
sudo mv go /usr/local
rm go1.12.9.linux-amd64.tar.gz

След това трябва да обновите средата (подробно тук: golang.org/doc/code.html#GOPATH).

echo 'export GOPATH=$HOME/work' >> ~/.bashrc
echo 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin' >> ~/.bashrc
source ~/.bashrc

Проверяваме дали go е инсталиран

go version

Инсталираме IPFS

Най-много ми хареса начинът на инсталиране чрез ipfs-update.

Инсталираме го с командата

go get -v -u github.com/ipfs/ipfs-update

След това можете да изпълнявате следните команди:

ipfs-update versions — за да видите всички налични версии за изтегляне.
ipfs-update version — за да видите текущата инсталирана версия (понеже IPFS не е инсталиран, ще бъде none).
ipfs-update install latest — инсталирайте последната версия на IPFS. Вместо latest можете да зададете всяка желана версия от списъка с налични.

Инсталираме ipfs

ipfs-update install latest

Проверяваме.

ipfs --version

По принцип с инсталацията всичко е наред.

Стартиране на IPFS

Инициализация

Първо трябва да извършите инициализация.

ipfs init

В отговор ще получите нещо подобно:

 ipfs init
initializing IPFS node at /home/USERNAME/.ipfs
generating 2048-bit RSA keypair...done
peer identity: QmeCWX1DD7HnXXXXXXXXXXXXXXXXXXXXXXXXxxx
to get started, enter:
	ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

Можете да изпълните предложената команда

ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

Резултат

Здравейте и добре дошли в IPFS!

██╗██████╗ ███████╗███████╗
██║██╔══██╗██╔════╝██╔════╝
██║██████╔╝█████╗  ███████╗
██║██╔═══╝ ██╔══╝  ╚════██║
██║██║     ██║     ███████║
╚═╝╚═╝     ╚═╝     ╚══════╝

Ако виждате това, Вие успешно сте инсталирали
IPFS и в момента взаимодействате с меркледаг на ipfs!

 -------------------------------------------------------
| Внимание:                                            |
|   Това е алфа софтуер. Използвайте на собствена отговорност! |
|   Липсва много или е недовършено. Има грешки.        |
|   Още не е сигурно. Прочетете бележките за сигурност за повече информация.   |
 -------------------------------------------------------

Разгледайте някои от другите файлове в тази директория:

  ./about
  ./help
  ./quick-start     <-- примери за употреба
  ./readme          <-- този файл
  ./security-notes

Тук, според мен, вече започва да става интересно. Момчетата още на етапа на инсталация започват да използват свои собствени технологии. Предложеният хеш QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv — не е генериран специално за вас, а е вграден в релиза. Тоест преди релиза са подготвили приветствието, качили са го в IPFS и адреса е добавен в инсталационния пакет. Мисля, че това е много готино. И този файл (всъщност, цялата папка) сега може да бъде видяна не само локално, но и на официалния шлюз. ipfs.io/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv. При това можете да бъдете сигурни, че съдържанието на папката по никакъв начин не е променяно, защото ако беше променено, хешът също щеше да се промени.

Според мен, в този случай IPFS има известно сходство с система за контрол на версиите. Ако в оригиналните файлове на папката се направят промени и след това отново се качи в IPFS, тя ще получи нов адрес. В същото време старата папка няма да изчезне просто така и ще бъде достъпна по стария си адрес.

Пряко стартиране

ipfs daemon

Трябва да получите нещо такова в отговор:

ipfs daemon
Initializing daemon...
go-ipfs version: 0.4.22-
Repo version: 7
System version: amd64/linux
Golang version: go1.12.7
Swarm listening on /ip4/x.x.x.x/tcp/4001
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip6/::1/tcp/4001
Swarm listening on /p2p-circuit
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip6/::1/tcp/4001
API server listening on /ip4/127.0.0.1/tcp/5001
WebUI: http://127.0.0.1:5001/webui
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready

Отваряме врати за Интернет

Обърнете внимание на тези две реда:

WebUI: http://127.0.0.1:5001/webui
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080

Ако сте инсталирали IPFS локално, ще можете да се свържете с интерфейсите на IPFS по локалните адреси и всичко ще ви бъде достъпно (Например, localhost:5001/webui/). Но когато инсталирате на външен сървър, по подразбиране шлюзите са затворени за интернет. Има два шлюза:

  1. Админка webui (github) на порт 5001.
  2. Външно API на порт 8080 (само за четене).

Засега за експерименти можете да отворите и двата порта (5001 и 8080), но на продуктивен сървър е добре порт 5001 да бъде закрит зад защитна стена. Има и порт 4001, който е необходим, за да могат другите пирове да ви намерят. Той трябва да остане отворен за външни заявки.

Отваряме за редактиране ~/ipfs/config и намираме тези редове:

"Addresses": {
  "Swarm": [
    "/ip4/0.0.0.0/tcp/4001",
    "/ip6/::/tcp/4001"
  ],
  "Announce": [],
  "NoAnnounce": [],
  "API": "/ip4/127.0.0.1/tcp/5001",
  "Gateway": "/ip4/127.0.0.1/tcp/8080"
}

Заменяме 127.0.0.1 с ip адреса на вашия сървър и записваме файла, след което перезапускаме ipfs (спираме запуснатата команда с Ctrl+C и стартираме отново).

Трябва да получите

...
WebUI: http://ip_вашия_сървър:5001/webui
Gateway (само за четене) сървър слуша на /ip4/ip_вашия_сървър/tcp/8080

Сега външните интерфейси трябва да са достъпни.

Проверете

http://домен_или_ip_сървъра:8080/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

Трябва да се отвори предоставеният по-горе readme файл.

http://домен_или_ip_сървъра:5001/webui/

Трябва да се отвори уеб интерфейсът.

Ако вашият webui работи, можете да променяте настройките на IPFS директно в него, включително да преглеждате статистиката, но по-долу ще разгледам вариантите за конфигуриране именно чрез файла за конфигурация. Това не е критично, но е добре да запомните къде точно се намира конфигурацията и какво да правите с нея, защото, ако уеб интерфейсът не работи, ще стане по-трудно.

Настройваме уеб интерфейса за работа със собствения си сървър

Тук е първият капан, на който ми отне три часа.

Ако сте инсталирали IPFS на външен сървър, но не сте инсталирали или стартирали IPFS локално, когато отидете на /webui в уеб интерфейса, трябва да видите грешка при свързването:

IPFS без болка (но не е сигурно)

Работата е там, че, според мен, webui работи доста нееднозначно. Първо той се опитва да се свърже с API-то на сървъра, където е отворен интерфейсът (разбира се, на базата на адреса в браузъра). И ако там не успее, след това опитва да се свърже с локалния шлюз. И ако имате локално стартиран IPFS, вашият webui ще работи нормално, но ще работите с локалния IPFS, а не с външния, дори и да сте отворили webui на външен сървър. След това качвате файлове, но по някаква причина не ги виждате просто така на външния сървър…

Ако локално не е стартирано, получаваме грешка при свързването. В нашия случай грешката вероятно се дължи на CORS, за което показва и webui, предлагаща добавяне на конфигурация.

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://ip_вашия сървър:5001", "http://127.0.0.1:5001", "https://webui.ipfs.io"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'

Аз просто написах wildcard при мен.

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'

Добавените заглавия могат да бъдат намерени в същия ~/.ipfs/config. В моя случай това е

  "API": {
    "HTTPHeaders": {
      "Access-Control-Allow-Origin": [
        "*"
      ]
    }
  },

Рестартираме ipfs и виждаме, че webui успешно се свърза (въпреки че трябва да работи, ако сте отворили шлюзите за външни заявки, както е описано по-горе).

Сега можете директно през уеб интерфейса да качвате папки и файлове, както и да създавате свои папки.

Монтиране на файловата система FUSE

Това е доста интересна функция.

Файловете (както и папките) можем да добавяме не само през уеб интерфейса, но и директно в терминала, например

ipfs add test -r
added QmfYuz2gegRZNkDUDVLNa5DXzKmxxxxxxxxxx test/test.txt
added QmbnzgRVAP4fL814h5mQttyqk1aURxxxxxxxxxxxx test

Последният хеш е хешът на коренната папка.

С този хеш можем да отворим папката на всяка ipfs-нод, която може да открие нашата нода и да получи съдържанието, можем в уеб интерфейса на порт 5001 или 8080, а можем и локално през ipfs.

ipfs ls QmbnzgRVAP4fL814h5mQttyqk1aUxxxxxxxxxxxxx
QmfYuz2gegRZNkDUDVLNa5DXzKmKVxxxxxxxxxxxxxx 10 test.txt

Но можем да я отворим и като обикновена папка.

Нека създадем две папки в корена и да предоставим правата им на нашия потребител.

sudo mkdir /ipfs /ipns
sudo chown USERNAME /ipfs /ipns

и рестартираме ipfs с флага —mount

ipfs daemon --mount

Можете да създадете папки и на други места и да посочите пътя им чрез параметрите ipfs daemon —mount —mount-ipfs /ipfs_path —mount-ipns /ipns_path

Сега четенето от тази папка е малко необичайно.

ls -la /ipfs
ls: reading directory '/ipfs': Operation not permitted
total 0

Това означава, че нямате директен достъп до корена на тази папка. Но можете да получите съдържанието, знаейки хеш-кода.

ls -la /ipfs/QmbnzgRVAP4fL814h5mQttyqxxxxxxxxxxxxxxxxx
total 0
-r--r--r-- 1 root root 10 Aug 31 07:03 test.txt

cat /ipfs/QmbnzgRVAP4fL814h5mQttyqxxxxxxxxxxxxxxxxx/test.txt 
test
test

При това вътре в папката дори автоматичното допълване работи при посочване на пътя.

Както споменах по-горе, при такава конфигурация има детайли: по подразбиране, монтираните FUSE директории са достъпни само за текущия потребител (дори root не може да чете от такава директория, да не говорим за други потребители в системата). Ако искате да направите тези директории достъпни за други потребители, трябва да промените в конфигурацията "FuseAllowOther": false на "FuseAllowOther": true. Но и това не е всичко. Ако стартирате IPFS от името на root, всичко е наред. А ако стартирате от името на обикновен потребител (дори и с sudo), ще получите грешка.

mount helper error: fusermount: option allow_other only allowed if 'user_allow_other' is set in /etc/fuse.conf

В такъв случай е необходимо да редактирате /etc/fuse.conf, като разкоментирате реда #user_allow_other.

След това перезапускаме ipfs.

Известни проблеми с FUSE

Често е забелязвана проблема, че след рестартиране на ipfs с монтиране (или в други случаи), точките на монтиране /ipfs и /ipns стават недостъпни. Няма достъп до тях, а ls -la /ipfs показва ???? в списъка с права.

Намерих такова решение:

fusermount -z -u /ipfs
fusermount -z -u /ipns

След което рестартираме ipfs.

Добавяме услуга

Разбира се, стартирането в терминала подхожда само за първоначални тестове. В продукционен режим, демона трябва да се стартира автоматично при стартиране на системата.

От името на sudo създаваме файл /etc/systemd/system/ipfs.service и записваме в него:

[Unit]
Description=IPFS Daemon
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
ExecStart=/home/USERNAME/work/bin/ipfs daemon --mount
User=USERNAME
Restart=always

[Install]
WantedBy=multi-user.target

USERNAME разбира се трябва да бъде заменено с вашия потребител (и възможно е целият път до програмата ipfs да е различен (трябва да указвате именно целия път)).

Активираме услугата.

sudo systemctl enable ipfs.service

Стартираме услугата.

sudo service ipfs start

Проверяваме статуса на услугата.

sudo service ipfs status

За чистота на експеримента, ще бъде полезно в бъдеще да рестартирате сървъра, за да проверите, че ipfs успешно стартира автоматично.

Добавяме известни ни пирове

Нека разгледаме ситуацията, когато имаме инсталирани IPFS възли както на външен сървър, така и локално. На външния сървър добавяме някой файл и се опитваме да го получим локално чрез IPFS по CID. Какво ще се случи? Разбира се, локалният сървър вероятно не знае нищо за нашия външен сървър и просто ще се опита да намери файла по CID, като „пита“ всички налични IPFS пирове (с които вече е „запознат“). Те, от своя страна, ще питат другите. И така, докато файлът не бъде намерен. Всъщност, същото се случва и когато се опитваме да получим файл чрез официален шлюз ipfs.io. Ако имаме късмет, файлът ще бъде намерен за няколко секунди. А ако не, няма да бъде намерен и за няколко минути, което много силно понижава комфорта на работа. Но ние знаем къде този файл първоначално ще се появи. Защо да не кажем веднага на нашия локален сървър „Търси първо там“? Изглежда, че това може да се направи.

1. Влизаме в дистанционния сървър и в конфигурационния файл ~/.ipfs/config търсим

"Identity": {
    "PeerID": "QmeCWX1DD7HnPSuMHZSh6tFuxxxxxxxxxxxxxxxx",

2. Изпълняваме sudo service ipfs status и търсим в него записи Swarm, например:

Swarm announcing /ip4/ip_вашия_сървър/tcp/4001

3. Сглобяваме общ адрес от вида „/ip4/ip_вашия_сървър/tcp/4001/ipfs/$PeerID“.

4. За надеждност, през нашия локален webui опитваме да добавим този адрес в пировете.

IPFS без болка (но не е сигурно)

5. Ако всичко е ОК, отваряме локалния конфиг ~/.ipfs/config, намираме в него „Bootstrap“: […
и добавяме първия получен адрес в масива.

Рестартираме IPFS.

Сега добавяме файл на външния сървър и опитваме да го поискам локално. Той трябва да влезе бързо.

Но тази функционалност все още е нестабилна. Както разбирам, дори когато задаваме адрес на пир в Bootstrap, в процеса на работа, IPFS променя списъка с активни връзки с пирите. Във всеки случай, дискусии по този въпрос и желания относно възможността да се задават постоянни пири се провеждат тук и изглежда, че се предполага ще добавят някаква функционалност в ipfs@5.0+

Списъкът с текущи пирове може да бъде прегледан както в webui, така и в терминала.

ipfs swarm peers

И на двете места можете ръчно да добавите своя пир.

ipfs swarm connect "/ip4/ip_вашия_сървър/tcp/4001/ipfs/$PeerID"

Докато не подобрим тази функционалност, можем да напишем инструмент, който да провери наличието на връзка с нужния пир и ако няма такава, да добавя връзката.

Разсъждения

Сред хората, които вече са запознати с IPFS, има както аргументи в полза на IPFS, така и против него. В принципе, преди два дни дискусията възбуди отново интереса ми към IPFS. И по отношение на споменатата дискусия: не мога да кажа, че съм силно против аргументите на изказалите се (не съм съгласен само с това, че само един и половина програмисти използват IPFS). По принцип и двете страни имат свои основания (особено коментарът относно чековете предизвиква размисъл). Но ако отхвърлим моралната и юридическата оценка, каква техническа оценка би дал всеки? Лично у мен има едно вътрешно усещане, че "това е необходимо, има определени перспективи". Но защо точно, няма ясна формулировка. Например, ако погледнем вече наличните централизирани средства, те по много параметри са значително напред (стабилност, скорост, управляемост и т.н.). Въпреки това имам една идея, която изглежда има смисъл и която едва ли може да бъде реализирана без подобни децентрализирани системи. Разбира се, може би е твърде амбициозно от моя страна, но бих я формулирал така: принципът на разпространение на информация в Интернет трябва да бъде променен.

Обяснявам. Ако така помислим, в момента информацията се разпространява по принципа "Надявам се, че този, на когото я предадох, ще я защити и тя няма да бъде загубена или получена от тези, за които не е предназначена". Лесно е да се разгледат различни имейл услуги, облачни хранилища и т.н. И какво имаме накрая? На Хабра хаб Информационната безопасност е на първо място и почти всеки ден получаваме новини за нови глобални изтичания. В принципе, всичко интересно е изброено в чудесната статия Лято почти свърши. Почти няма изтекли данни. Тоест, основните интернет гиганти стават все по-големи, акумулирайки все повече информация, и подобни изтичания – това са своебразни атомни взривове на информация. Никога не е било такова нещо, и ето отново. При това, въпреки че много хора разбират, че рисковете съществуват, ще продължат да доверяват данните си на трети страни. Първо, няма особени алтернативи, и второ, те обещават, че всичките дупки са запушени и такова нещо вече няма да се повтори.

Какво ми изглежда като вариант? Според мен, данните трябва да се разпространяват открито от самото начало. Но откритост в този случай не означава, че всичко трябва да бъде лесно четимо. Говоря за откритост в съхранението и разпространението, а не за тотална откритост в четенето. Предполагам, че информацията трябва да се разпространява с отворени ключове. Все пак, принципът на отворените/затворени ключове е стар, почти колкото интернет. Ако информацията не е конфиденциална и е предназначена за широка аудитория, тя се публикува веднага с отворен ключ (но все пак в криптиран вид, просто всеки може да я декриптира с предоставения ключ). А ако не, тя се публикува без отворен ключ, а самият ключ се предава на този, който трябва да има достъп до тази информация. В същото време, онзи, който трябва да я прочете, трябва само да има ключа, а къде да намери информацията, не трябва да го тревожи особено — той просто я извлича от мрежата (това е новият принцип на разпространение по съдържанието, а не по адрес).

По този начин, за злонамерените е нужно да получат огромно количество закрити ключове, и навярно няма да могат да го направят на едно място. Тази задача, ми се струва, е по-сложна, отколкото да се хакне конкретен сервис.

И тук се решава още един проблем: потвърждението на авторството. В момента в интернет може да се намери множество цитати, написани от нашите познати. Но къде е гаранцията, че точно те са ги писали? Ако всяка такава записка беше придружавана от цифров подпис, би било много по-просто. И не е важно къде е информацията, най-важното е подписът, който е трудно да се фалшифицира.

И тук е интересно: IPFS вече съдържа средства за криптиране (всъщност, той е построен на технологията блокчейн). В конфигурацията веднага е указан частният ключ.

  "Identity": {
    "PeerID": "QmeCWX1DD7HnPSuMHZSh6tFuMxxxxxxxxxxxxxx",
    "PrivKey": "CAASqAkwggSkAgEAAoIBAQClZedVmj8JkPvT92sGrNIQmofVF3ne8xSWZIGqkm+t9IHNN+/NDI51jA0MRzpBviM3o/c/Nuz30wo95vWToNyWzJlyAISXnUHxnVhvpeJAbaeggQRcFxO9ujO9DH61aqgN1m+JoEplHjtc4KS5
pUEDqamve+xAJO8BWt/LgeRKA70JN4hlsRSghRqNFFwjeuBkT1kB6tZsG3YmvAXJ0o2uye+y+7LMS7jKpwJNJBiFAa/Kuyu3W6PrdOe7SqrXfjOLHQ0uX1oYfcqFIKQsBNj/Fb+GJMiciJUZaAjgHoaZrrf2b/Eii3z0i+QIVG7OypXT3Z9JUS60
KKLfjtJ0nVLjAgMBAAECggEAZqSR5sbdffNSxN2TtsXDa3hq+WwjPp/908M10QQleH/3mcKv98FmGz65zjfZyHjV5C7GPp24e6elgHr3RhGbM55vT5dQscJu7SGng0of2bnzQCEw8nGD18dZWmYJsE4rUsMT3wXxhUU4s8/Zijgq27oLyxKNr9T7
2gxqPCI06VTfMiCL1wBBUP1wHdFmD/YLJwOjV/sVzbsl9HxqzgzlDtfMn/bJodcURFI1sf1e6WO+MyTc3.................

Не съм специалист по сигурността и не мога точно да знам как да го използвам правилно, но ми се струва, че на ниво обмен между IPFS възли тези ключове се използват. А също така js-ipfs и проекти-примери като orbit-db, на която работи orbit.chat. Тоест теоретично всяко устройство (мобилно и не само) може лесно да бъде оборудвано със свои шифровално-дешифровални машини. В такъв случай всеки ще трябва да се погрижи за запазването на своите частни ключове и всеки сам ще бъде отговорен за своята сигурност, а не да бъде заложник на човешкия фактор в някой супер популярен интернет гигант.

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

Чували ли сте преди за IPFS?

  • Никога не съм чувал за IPFS, но звучи интересно

  • Не съм чувал и не искам да чувам

  • Чувал съм, но не ме заинтересува

  • Чувал съм, но не разбрах, а сега изглежда интересно

  • Отдавна активно използвам IPFS

Гласували са 69 потребители. Въздържали се 13 потребители.

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster