Help us understand the problem. What is going on with this article?

IPFS 教學和筆記

More than 1 year has passed since last update.

台湾の中国語で書いたIPFSのチュートリアルです。
CloudFlareは2018年9月17日からIPFSをサッポートしていますから、記事を更新しました。

IPFS 教學和筆記

因為 IPFS 的繁中資料實在太少了,決定邊學習邊筆記。

本篇教學的網址是:

為什麼要使用 IPFS

IPFS (星際檔案系統) 是用來取代已經太過集中化的 HTTP 的一種方案,這裡不做一般性的介紹,因為其它 blog / Wikipedia 上都有寫了。我想使用 IPFS 的理由是:

  1. 網路過度集中化,使用者自願放棄自由,請參考 網際網路已經完蛋了
  2. 依賴單一公司提供的平台所發佈的文章,即使沒有反政府、侵權、政治不正確 blah blah 還是有各種不同的可能被下架,而你已經在 EULA 中同意不去追究了。
  3. Google Blogspot, Tumblr, Facebook Blog 提供的免費、高品質 blog,仍然有上述的疑慮。
  4. 即使是自己架的 Word Press,哪一天被警察用任何理由抄掉了,上面的網頁就沒有了。

去中心化,才能有民主、自由的網路。即使如此,去中心化仍然需要網路中立性的支持,不然你的 ISP 仍然可以獨厚(加速)大公司的網站。

本篇教學 不會 論述以下主題:

  • 免責或匿名性。這是另一個大題目,去中心化不代表你可以匿名。
  • 挖礦、區塊鏈、或任何虛擬貨幣。
  • ICO 特別是 IPFS 最近的 Filecoin ICO 。

完整的介紹性文章,可以參考 InfoQ 的 IPFS:替代HTTP的分布式网络协议

下載、安裝

下載

下載很簡單,請直接到 IPFS 官網 或直接 點這裡下載。我直接下載了 go-ipfs 0.4.10, Mac OS X 請下載 Darwin amd64, Ubuntu 請下載 Linux amd64。

安裝

直接在命令列下打這些指令就好:

$ ipfs init     # 會在 ~/.ipfs 開一個目錄,存放區塊檔,預設是最大 10GB

$ ipfs id       # 列出自己的 ID, 但其實不需要太介意
{
    "ID": "QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR",
    "PublicKey": "...",
    "Addresses": [
        "..."
    ],
    "AgentVersion": "go-ipfs/0.4.10/",
    "ProtocolVersion": "ipfs/0.1.0"
}

想修改預設的暫存大小的話,請下這個指令:

export EDITOR=/usr/bin/vim
ipfs config edit

找到 "StorageMax": "10GB", 這行,把 10GB 換成你要的大小即可。

新增檔案

先來隨便新增一個檔案吧。打開記事本,隨便打幾行字 lorem ipsum dolor sit amet 存成 README.md

ipfs add 可以把檔案加進 IPFS 裡,它會傳回一組 HASH, 那個 HASH 就是這個檔案的唯一識別代碼了。

$ ipfs add README.md
added QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd README.md

$ ipfs cat /ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd
lorem ipsum dolor sit amet

即使你換到別台機器,一樣可以用 ipfs cat /ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd 看到這個檔案的內容。

如果要分享給沒有安裝 IPFS 的朋友(建議順便推坑!) 可以請他使用 IPFS Gateway: https://ipfs.io/ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd 把後面的 HASH 換成你剛剛新增的檔案的 HASH,就可以了!

我比較習慣目錄

大家都還是比較習慣目錄結構吧?已經 ipfs add 的檔案,可以被放進目錄裡。

$ ipfs files mkdir /SmartCity   # 開一個目錄
$ ipfs files cp /ipfs/QmQhK6KAVA2nJgFYzf7D1yHdH11GiGJv6zRTUhoVZwXpDd /SmartCity/README.md
$ ipfs files ls /
SmartCity
$ ipfs files ls /SmartCity/
README.md
$ ipfs files read /SmartCity/README.md
lorem ipsum dolor sit amet

我目前還不知道怎麼把目錄 export 出去,讓別人也可用使用同樣的目錄結構。

上傳一整個目錄

使用 ipfs add -r 可以上傳一整個目錄。比方說,這篇教學可以用這種方式上傳 (小心 不要把 .git/ 下面的東西都傳上去了!)

$ ipfs add -r ipfs-tutorial-taiwan-mandarin
added QmdpYD8hejksA5SHNdRfDzE2EYzpSkbazyVAJq5hRwbKtp ipfs-tutorial-taiwan-mandarin/README.md
added QmWe7m2K8DThCUTPuw5KcbYvpAwogScXt8gazfG7QiRpSo ipfs-tutorial-taiwan-mandarin

這樣就可以用下列方式取得 README.md 的內容:

  1. ipfs cat /ipfs/QmdpYD8hejksA5SHNdRfDzE2EYzpSkbazyVAJq5hRwbKtp
  2. ipfs cat /ipfs/QmWe7m2K8DThCUTPuw5KcbYvpAwogScXt8gazfG7QiRpSo/README.md

避免被垃圾回收 (Garbage Collection, GC)

ipfs 會自動做垃圾回收,減少佔用的本機空間。為了避免我們剛發佈的網頁被垃圾回收,可以把整個目錄 pin 起來。

$ ipfs pin add -r /ipfs/QmWe7m2K8DThCUTPuw5KcbYvpAwogScXt8gazfG7QiRpSo

記得要 pin 的是目錄的 hash 不要貼錯了喲!

我在 IPFS 上的第一個網頁

IPFS 的本質是分散式的檔案系統,如果只是要 host 分散式的部落格的話,可以使用 ZeroNet 。晚一點我會再寫一篇 ZeroNet 的介紹。

請注意 如果在 pinpublish 的過程中遇到任何問題,可能是防火牆的關係。跑 ipfs daemon 的時候,它會列出對外連線的 port 請在防火牆打開。

% ipfs daemon
Initializing daemon...
Adjusting current ulimit to 2048...
Successfully raised file descriptor limit to 2048.
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/192.168.2.1/tcp/4001
Swarm listening on /ip4/220.xxx.xx.xxx/tcp/4001 ← 這個!!
Swarm listening on /ip6/::1/tcp/4001
API server listening on /ip4/127.0.0.1/tcp/5001
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready

Debian 系的 Linux 請愛用 sudo ufw allow 4001 即可。

出於莫名的原因,我決定不要使用最常見的 Jekyll 。以下範例是 Hugo 做的 :)

Huge 後面還有使用 ipfs 範例中的 mdown 來 render 的例子。

安裝 Hugo

參考 Hugo官網 的說明,在 Mac 上安裝 Hugo:

$ brew install hugo
Updating Homebrew...
Warning: hugo 0.26 is already installed
$ hugo version
Hugo Static Site Generator v0.26 darwin/amd64 BuildDate: 2017-08-08T14:55:38+08:00
$ hugo new site ipfs-tutorial-zh-TW
Congratulations! Your new Hugo site is created in /Users/miaoski/github/ipfs-tutorial-zh-TW.
$ git init
Initialized empty Git repository in /Users/miaoski/github/ipfs-tutorial-zh-TW/.git/
$ git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke
Cloning into '/Users/miaoski/github/ipfs-tutorial-zh-TW/themes/ananke'...
$ echo 'theme = "ananke"' >> config.toml

修改 config.toml 設定一下 title 和語系什麼的,就可以了。

新增 blog 文章

$ hugo new posts/ipfs-tutorial.md
/Users/miaoski/github/ipfs-tutorial-zh-TW/content/posts/ipfs-tutorial.md created
$ cat ../ipfs-tutorial/README.md >> ./content/posts/ipfs-tutorial.md

修改一下,把 draft: true 改成 draft: false 再執行一次 hugo 就可以 render 出網頁了。

把部落格新增到 IPFS 上

依據 hugo 的建議,先 rm -fr public/ 再重新執行 hugo 比較好...

$ rm -fr ./public/
$ hugo
$ ipfs add -r ./public/
added QmW7dJkAjtLgUtJcgUrTPC2jSLTD8uS4bfzPPXYdsZGhFN public/posts
added QmecA1oy5du9TwNrJrwxjq5emUdG7jbukv8Pzuo2q8CjRc public/tags
added QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf public
$ ipfs pin add -r /ipfs/QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf
pinned QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf recursively

請跳到 IPNS 一節閱讀。

mdown

mdown 是 ipfs 範例中的 markdown-viewer 是以 MIT 版權宣告的。有時候我們只是想分享一份簡單的 markdown,它十分輕量,render 出來的效果也不錯。它的背後是 StrapDownJS。

本文的 Github repo 已經把 mdown 加在裡面了,直接 make 就會看到 ipfs add 上去的 HASH。它也會寫在 published-version 檔案裡。接著我們可以用 IPNS 發佈它。

IPNS

拿到網站的 HASH 後,建議註冊 IPNS ,因為每次更新部落格的內容,上面的 HASH 都會變,我們需要一個固定的 ID 指向最新的 HASH 。以本文為例:

$ ipfs name publish QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf
Published to QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR: /ipfs/QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf
$ ipfs name resolve QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR
/ipfs/QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf

以後每次更新完網站,都要重新 ipfs add -r ./public/ 一 次,然後再執行 ipfs name publish ... ,這樣/ipns/QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR 才會指向最新的 HASH 哦! (注意是 IPNS 不要搞錯!)

使用 hugo 的同學,順便更新 config.toml:

baseURL = "https://ipfs.io/ipns/QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR/"
languageCode = "zh-tw"
title = "第一次用 IPFS 就上手"
theme = "ananke"

快取 (pin)

把內容快取到本地端,並且提供給其他人。

ipfs pin add QmT7TX5vGmFz86V8cDkPuTss1vp4qTXeaziGZrjdJhURFf

add 本身就是遞歸的,所有的子目錄都會被 pin 住。可以用 ipfs pin ls 看看本地端 pin 了什麼。 這一篇 的指令都可以玩玩看。

TXT

因為一串 HASH 真的很難記,所以可以用修改 DNS 的 TXT 欄的方式,讓使用者可以用 https://ipfs.io/ipns/miaoski.idv.tw/ 這種方式,存取到你的檔案或部落格。要特別注意, TXT 設定完後,如果你用筆電的話,不要太快離線,不然別人可能還來不及 cache 住 TXT 解析的內容。

$ host -t TXT miaoski.idv.tw
miaoski.idv.tw descriptive text "dnslink=/ipns/QmNmfAqjiQgdLJscpM3FufbaXY9QEqWZiWqDTbsrUjSKDR"

下面的情況都是正常的。但是 ipfs name resolve -r 必須要能正確解析出 /ipfs/ 的位址,別人才看得到你公開的內容。
```
$ ipfs name resolve miaoski.idv.tw
Error: Could not resolve name (recursion limit exceeded).

$ ipfs dns -r atnnn.com
Error: not a valid domain name

$ ipfs dns atnnn.com
Error: Could not resolve name (recursion limit exceeded).
```

來試試看我的網頁吧! https://ipfs.io/ipns/miaoski.idv.tw/

推上 CloudFlare

CloudFlare 在 2018.9.17 的時候和 IPFS 合作,提供入口及 SSL 憑證,應該會讓 IPFS 穩定許多。建議要發佈網頁的朋友,可以和 CloudFlare 連在一起。做法如下:

  1. 需要有自己的 domain name
  2. 可以修改 TXT 欄位 (像上面寫的 ipns 那樣)
  3. 把網頁內容丟進一個目錄裡,入口是 index.html
  4. 把網頁的網域名稱 CNAME 到 www.cloudflare-ipfs.com
  5. 加一個 _dnslink.your.website = dnslink=/ipfs/<your_hash_here>
  6. https://www.cloudflare.com/distributed-web-gateway/#connectingyourwebsite 登錄

舉例而言,

  1. 我在 DNS Server 上新增一個 ipfs.miaoski.idv.tw
  2. 把它 CNAME 到 www.cloudflare-ipfs.com
  3. 新增 TXT 欄位 Hostname: _dnslink.ipfs.miaoski.idv.tw / TXT: dnslink=/ipfs/QmR2PvgrHny4ispfEVygvvWkNqwjbU7hareWda41ASF5wC
  4. https://www.cloudflare.com/distributed-web-gateway/#connectingyourwebsite 登錄

這樣以後看 https://ipfs.miaoski.idv.tw/ 就會自動被轉址為 https://cloudflare-ipfs.com/ipfs/QmR2PvgrHny4ispfEVygvvWkNqwjbU7hareWda41ASF5wC 而且會有合法的 SSL 憑證。

nslookup 檢查一下:

$ nslookup
> set type=ANY
> ipfs.miaoski.idv.tw.

ipfs.miaoski.idv.tw canonical name = www.cloudflare-ipfs.com.

> _dnslink.ipfs.miaoski.idv.tw.

_dnslink.ipfs.miaoski.idv.tw    text = "dnslink=/ipfs/QmR2PvgrHny4ispfEVygvvWkNqwjbU7hareWda41ASF5wC"

我還不懂的部份

  • BitSwap
  • DHT
  • 把 git repo 和 IPFS 整合在一起

參考資料

License 版權聲明

我自己編寫的部份,全部使用 CC BY-SA 4.0 聲明。如果有引用他人的部份,請參考各該文件所屬的版權聲明。

miaoski
トレンドマイクロ株式会社のミャウスキです。
https://github.com/miaoski/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away