IPFS 使用全記錄

IPFS是什麼

IPFS(InterPlanetary File System)是一個內容尋址、版本化、點對點的分佈式文件系統。node

  • 內容尋址 - 文件不是以URL尋址,而是根據文件內容的Hash值尋址,一旦內容肯定,文件地址也就肯定
  • 版本化 - 相似於git,能夠跟蹤文件的歷史變化狀況
  • 點對點 - 全部運行ipfs的設備點對點組成一個去中心化網絡

安裝啓動IPFS

bin包安裝

官方網站下載對應平臺的安裝包,本文使用linux-64位版本
安裝linux

或直接使用網址下載git

> wget https://dist.ipfs.io/go-ipfs/v0.4.15/go-ipfs_v0.4.15_linux-amd64.tar.gz

解壓安裝包,將可執行文件放在環境變量目錄github

> tar xvfz go-ipfs_v0.4.15_linux-amd64.tar.gz
> mv ipfs /usr/local/bin/

初始化ipfs節點web

> ipfs init
initializing ipfs node at /root/.go-ipfs
generating 2048-bit RSA keypair...done
peer identity: QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR
to get started, enter:

  ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme

根據提示,檢查安裝狀態redis

> ipfs cat /ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG/readme
Hello and Welcome to IPFS!

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

If you're seeing this, you have successfully installed
IPFS and are now interfacing with the ipfs merkledag!

 -------------------------------------------------------
| Warning:                                              |
|   This is alpha software. use at your own discretion! |
|   Much is missing or lacking polish. There are bugs.  |
|   Not yet secure. Read the security notes for more.   |
 -------------------------------------------------------

Check out some of the other files in this directory:

  ./about
  ./help
  ./quick-start     <-- usage examples
  ./readme          <-- this file
  ./security-notes

前面完成了ipfs節點的配置,接下來就是啓動ipfs守護進程,能夠在另外一個終端啓動,也能夠在本終端加上後臺啓動ubuntu

> ipfs daemon
Initializing daemon...
Successfully raised file descriptor limit to 2048.
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/172.17.0.1/tcp/4001
Swarm listening on /ip4/172.22.16.1/tcp/4001
Swarm listening on /ip4/192.168.0.116/tcp/4001
Swarm listening on /ip4/192.168.122.1/tcp/4001
Swarm listening on /ip6/::1/tcp/4001
Swarm listening on /p2p-circuit/ipfs/QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR
Swarm announcing /ip4/10.103.255.235/tcp/48240
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip4/172.17.0.1/tcp/4001
Swarm announcing /ip4/172.22.16.1/tcp/4001
Swarm announcing /ip4/192.168.0.116/tcp/4001
Swarm announcing /ip4/192.168.122.1/tcp/4001
Swarm announcing /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

在另外一個終端輸入如下命令確保鏈接進ipfs網絡api

> ipfs swarm peers
/ip4/103.214.109.178/tcp/4001/ipfs/QmfZeNauweuRYWNXMjPhB4Tu2CPU6aD5eide9PEhVtHP6A
/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
/ip4/104.223.59.174/tcp/4001/ipfs/QmeWdgoZezpdHz1PX8Ly8AeDQahFkBNtHn6qKeNtWP1jB6
/ip4/104.233.106.156/tcp/4001/ipfs/QmSaLHB9dK7UphxcSWSdySVQyayux2yVMUELnAN8VV96x2
/ip4/106.38.77.82/tcp/49777/ipfs/QmfT3BCVYjLiVVB197mR1P4uhdR7zsKZsE7HLzCV1qSbHJ
/ip4/107.172.55.210/tcp/4001/ipfs/QmcYfPreozdQMKyo5omUhvTShCKRjdeiQhS7328J7CLLXe
/ip4/109.129.112.32/tcp/56478/ipfs/QmRYXX6mvvQQWR1kB1pC5c5dbcwASqyoQ6sjxH2czzPNBs
......

到如今,已經能夠從ipfs網絡中獲取文件了,以一個官方圖片爲例瀏覽器

> ipfs cat /ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg  > cat.jpg

那麼將在本目錄下獲得一張貓的圖片
cat安全

另外,能夠在瀏覽器中訪問http://localhost:5001/webui來使用ipfs的控制檯

console

使用add將一個文件添加到ipfs網絡(能夠被其餘節點訪問到)

> cat 187J3X1.txt 
Hello!187J3X1!
> ipfs add 187J3X1.txt 
added QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj 187J3X1.txt

文件要能被網絡中全部節點訪問須要必定時間,在某個運行ipfs的節點,使用get命令能夠獲取到本文件

> ipfs get QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj

更多命令可查看幫助信息

> ipfs --help

源碼安裝

能夠從Github下載源碼,自行編譯安裝

使用GPG完成私密文件分享

在ipfs文件系統中,只要知道文件的Hash,就能夠從節點獲取文件。因此ipfs天生缺少隱私性,加入須要分享私密的文件給別人。一般的作法是分享者將文件用接收者的公鑰加密,接收者從ipfs網絡下載後用私鑰解密。GPG能夠完成加解密的功能。

GPG一樣可使用bin包安裝或源碼安裝

bin包安裝

以ubuntu 爲例

> sudo apt-get install gnupg

源碼安裝

(TODO)

密鑰生成

接收者使用gen-key生成密鑰對

> gpg --gen-key
gpg (GnuPG) 1.4.20; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

加密方案使用默認RSA就行

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection?

密鑰長度依然選擇默認

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)

設置密鑰過時時間,選擇永遠不過時

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)

輸入祕鑰建立者一些信息

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: chenmo
Email address: 13688368470@163.com
Comment: 
You selected this USER-ID:
    "chenmo <13688368470@163.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?

建立私鑰密碼(很是重要)

You need a Passphrase to protect your secret key.
Enter passphrase:
Repeat passphrase:

接下來,程序將開始生成密鑰,爲了使生成過程使用的隨機數更加隨機,你能夠採用敲鍵盤、移動鼠標等方式增長隨機數的隨機特性。

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
f
Not enough random bytes available.  Please do some other work to give
the OS a chance to collect more entropy! (Need 186 more bytes)

本機生成的祕鑰對能夠用--list-keys命令查看

gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/F0AA19A1 2018-07-08
uid                  chenmo <13688368470@163.com>
sub   2048R/54C6ABC4 2018-07-08

其中的F0AA19A1就是公鑰id, 54C6ABC4是私鑰id

可使用armor命令將祕鑰導出爲filename文件

gpg --armor --output [filename] --export [密鑰id]

密鑰分享

接收者須要告訴發送者本身的公鑰,以便發送者加密。這能夠經過公鑰服務器完成。本文使用
hkp://pgp.mit.edu

> gpg --send-keys [公鑰id] --keyserver hkp://pgp.mit.edu
gpg: "--keyserver" not a key ID: skipping
gpg: "hkp://pgp.mit.edu" not a key ID: skipping
gpg: sending key [公鑰id] to hkp server keys.gnupg.net

發送方搜索該密鑰

> gpg --keyserver hkp://pgp.mit.edu -search-keys [公鑰id]

加密文件

發送方加密待分享的文件ipfs_demo.txt

> cat ipfs_demo.txt
This file is just for test --- 187J3X1
> gpg --encrypt --recipient [公鑰id] ipfs_demo.txt

將加密後的文件ipfs_demo.txt.gpg 添加到ipfs網絡中

> ipfs add ipfs_demo.txt.gpg 
added QmbvjL7BnCpUgzrJj2E2QkhqRBJeWKmo1TCfpMmKEQMYYc ipfs_demo.txt.gpg

解密文件

接收方獲取文件

>ipfs get QmQRLCz3c6BwtkcACxwwraDX62g4ZAS7fQmrn3Y3rJh1xN
Saving file(s) to QmQRLCz3c6BwtkcACxwwraDX62g4ZAS7fQmrn3Y3rJh1xN
 24 B / 24 B [======================================================] 100.00% 0s

該操做可能會有必定時間延時,也可經過網頁訪問文件地址來接收文件

接下來用私鑰解密出原文件

gpg --decrypt QmbvjL7BnCpUgzrJj2E2QkhqRBJeWKmo1TCfpMmKEQMYYc > ipfs_demo.txt

You need a passphrase to unlock the secret key for
user: "chenmo <13688368470@163.com>"
2048-bit RSA key, ID 54C6ABC4, created 2018-07-08 (main key ID F0AA19A1)

gpg: encrypted with 2048-bit RSA key, ID 54C6ABC4, created 2018-07-08
      "chenmo <13688368470@163.com>"
> cat ipfs_demo.txt 
This file is just for test --- 187J3X1

添加文件

在ipfs守護進程啓動以後,可使用ipfs add命令將文件添加到ipfs網絡

> echo "Hello!187J3X1!" > 187J3X1.txt
> ipfs add 187J3X1.txt
added QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj 187J3X1.txt

其中QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj就是文件內容的Hash值,一旦文件內容改變,這個值就會改變。須要注意,這個值與文件名徹底沒有關係,它只是內容的Hash,無論文件名是什麼,只要內容同樣,它的Hash值就是同樣的。

本地位置

ipfs的本地存儲空間在~/.ipfs,全部ipfs自身的文件和本地添加到ipfs網絡的文件都存放在此目錄

> ls /.ipfs
api  blocks  config  datastore  datastore_spec  keystore  repo.lock  version

今後目錄下這裏能夠找到剛纔添加的文件

grep -rn "187J3X1"
Binary file blocks/ZF/CIQIXJZ7NCVBEU67XHWSTICDNGNRD2SIAE33W4SSDI6LZTE4PLRSZFA.data matches

讀取文件

使用ipfs cat命令能夠獲取添加到ipfs網絡中的文件,若是文件內容就在本地,那麼顯示將會很快,若是是在另外一個節點,那麼要等本節點從網絡中得到該文件內容後,纔會顯示

> ipfs cat QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj
Hello!187J3X1!

能夠將文件內容重定向到一個文件,文件名徹底沒必要與原來的同樣,由於在ipfs網絡中存儲的只有內容,沒有文件名

> ipfs cat QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj > recv.txt
> cat recv.txt
Hello!187J3X1!

添加文件名信息

向ipfs網站中添加單個文件是沒有文件名等信息的,經過在ipfs add命令中添加-w選項,能夠將該文件的文件名和所處文件夾的信息一同添加到ipfs網絡

> pwd
/home/yc/workspace/ipfs/tmp
> ipfs add -w 187J3X1.txt 
added QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj 187J3X1.txt
added Qmdjqtwaj2vFkQ4P49qbnR9ksFphkSvUEf3S5rPNDVo7Kn

與剛纔僅添加一個文件不一樣的是,這裏會獲得兩個Hash值,第一個QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj是文件內容的Hash值,與以前的同樣,另外一個Qmdjqtwaj2vFkQ4P49qbnR9ksFphkSvUEf3S5rPNDVo7Kn就是文件所處目錄的信息的Hash值。

使用ipfs ls命令能夠列出這種層次關係(不能使用ipfs cat)

ipfs ls -v Qmdjqtwaj2vFkQ4P49qbnR9ksFphkSvUEf3S5rPNDVo7Kn
Hash                                           Size Name
QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj 23   187J3X1.txt

能夠利用目錄和文件關係找到顯示文件的內容

> ipfs cat Qmdjqtwaj2vFkQ4P49qbnR9ksFphkSvUEf3S5rPNDVo7Kn/187J3X1.txt
Hello!187J3X1!

添加目錄

經過在ipfs add命令中添加-r選項,能夠將一個目錄和其中的內容添加到ipfs網絡中

> pwd
/home/yc/workspace/ipfs/tmp
> echo "My Second file" > Second_file.txt
> ls
187J3X1.txt  Second_file.txt
> ipfs add -r .
added QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj tmp/187J3X1.txt
added QmT96ZpTMV9kjtfEySjovvnfi92NxRqkogVtiwtD5Xs7rX tmp/Second_file.txt
added QmZ813ofgBrNuUpH8VFCR4A8LVkp1vSZcmxnET5PqCtj65 tmp

能夠看到該命令將整個目錄的內容都添加到了ipfs網絡,前兩個Hash值是文件,最後一個Hash值是目錄。經過'ipfs ls'查看

> ipfs ls -v QmZ813ofgBrNuUpH8VFCR4A8LVkp1vSZcmxnET5PqCtj65
Hash                                           Size Name
QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj 23   187J3X1.txt
QmT96ZpTMV9kjtfEySjovvnfi92NxRqkogVtiwtD5Xs7rX 23   Second_file.txt

IPNS是什麼

ipfs中,一個文件的Hash值徹底取決於其內容,修改它的內容,其相應的Hash值也會發生改變。若是咱們把修改先後的文件都經過ipfs add添加到ipfs網絡中,那麼咱們將能夠經過這兩個Hash值訪問到先後兩個版本的內容。這種靜態特性有利於提升數據的安全,好比 Alice 能夠將一份本身簽名(私鑰加密)的文件放到ipfs中,那麼即便她後來對文件進行了修改並從新簽名和發佈,那麼以前的文件依然存在,她不能抵賴曾經發布過老版本的文件。但對於一些須要保持動態性的文件來講,好比網頁,在新版本出現後,舊版本的內容將毫無心義。而且,總不能要求網頁訪問者每次要在瀏覽器中輸入不一樣的ipfs地址來訪問不一樣時期的網頁吧。

IPNS(Inter-Planetary Naming System)提供了一種爲文件增長動態性的解決方案。它容許節點的PeerID限定的命名空間提供一個指向具體ipfs文件(目錄)Hash的指針,經過改變這個指針每次都指向最新的文件內容,可使得其餘人始終訪問最新的內容。

例子

> echo "This is old version file" > myfile.txt 
> ipfs add myfile.txt
added QmQECo2p8LdVcjtkEWDVNVM7Hrsc7arW52P5vz5BVuvEgR myfile.txt

使用ipfs publish命令發佈本節點ipns到ipfs的映射

> ipfs name publish /ipfs/QmQECo2p8LdVcjtkEWDVNVM7Hrsc7arW52P5vz5BVuvEgR
Published to QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR: /ipfs/QmQECo2p8LdVcjtkEWDVNVM7Hrsc7arW52P5vz5BVuvEgR

QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR正是本節點的ID,這一點能夠經過ipfs id看到

ipfs id
{
    "ID": "QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR",
    ......

使用命令ipfs resolve能夠解析ipns到ipfs的映射關係

> ipfs name resolve QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR
/ipfs/QmQECo2p8LdVcjtkEWDVNVM7Hrsc7arW52P5vz5BVuvEgR

在本地執行該命令,很快就能夠獲得結果。若是在其餘節點執行,會花費一些時間。
能夠看出解析的結果正是myfile.txt文件的內容。

這一點也能夠在瀏覽器中驗證

在ipfs.io/ipfs/直接輸入文件內容的Hash
ipfs

在ipfs.io/ipns/輸入節點的id
ipns

如今對文件進行修改,並添加到ipfs網絡

> echo "This is new version file" > myfile.txt 
> ipfs add myfile.txt
added Qmdzqe3yA4JZM5wQe2hV8pfi9CA7aWUq8vHAJd7p7USJQb myfile.txt

再修改ipns到ipfs的映射關係,使本節點的id映射到新的文件內容Hash

> ipfs name publish Qmdzqe3yA4JZM5wQe2hV8pfi9CA7aWUq8vHAJd7p7USJQb
Published to QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR: /ipfs/Qmdzqe3yA4JZM5wQe2hV8pfi9CA7aWUq8vHAJd7p7USJQb

驗證其映射關係

> ipfs name resolve QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR
/ipfs/Qmdzqe3yA4JZM5wQe2hV8pfi9CA7aWUq8vHAJd7p7USJQb

在瀏覽器中驗證:

ipfs + 新Hash顯示新內容
ipfs-new

ipns + 節點ID 顯示新內容
ipns-new

ipfs + 舊Hash 顯示舊內容
ipfs

上面的例子中,咱們修改ipns下的節點ID和ipfs文件內容的映射關係,使得雖然訪問的是同一個地址但實際訪問的文件內容卻不相同,這不只適用於單個文件,咱們徹底能夠對一個目錄做這種操做。

可是一個節點的ID只有一個,假設我須要同時保留多個這樣的映射實例,該怎麼辦呢?

其實ipns的映射關係除了節點ID<->文件內容,還有一種是key<->文件內容

經過ipfs key list命令能夠看到本節點的key

> ipfs key list -l
QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR self

能夠看到,節點默認具備一個名爲self的key,它的值正是節點ID。

而在ipfs name publish命令的完整形式是

ipfs name publish [--resolve=false] [--lifetime=<lifetime> | -t] [--ttl=<ttl>] [--key=<key> | -k] [--] <ipfs-path>

注意其中的key,若是不帶這個參數,那麼久表示使用默認的key, 也就是節點ID。

可使用ipfs key gen建立新的key,這裏建立一個名爲another的key

> ipfs key gen --type=rsa --size=2048 another 
QmYTpEqtNYvNFUwFysuRsEufNDJJBBEJfqsqrFXDT93sEE
> ipfs key list -l
QmQQ5t88W44Je5WgvmgpV1xSZTg1y5UXdYFHcQQ7EayxwR self    
QmYTpEqtNYvNFUwFysuRsEufNDJJBBEJfqsqrFXDT93sEE another

嘗試用新的key,映射一個ipfs文件內容

> echo "This is another file" > another.txt
> ipfs add another.txt 
added QmPoyokqso3BKYCqwiU1rspLE59CPCv5csYhcPkEd6xvtm another.txt

> ipfs name publish --key=another  QmPoyokqso3BKYCqwiU1rspLE59CPCv5csYhcPkEd6xvtm
Published to QmYTpEqtNYvNFUwFysuRsEufNDJJBBEJfqsqrFXDT93sEE: /ipfs/QmPoyokqso3BKYCqwiU1rspLE59CPCv5csYhcPkEd6xvtm

ipfs resolve解析

> ipfs resolve /ipns/QmYTpEqtNYvNFUwFysuRsEufNDJJBBEJfqsqrFXDT93sEE
/ipfs/QmPoyokqso3BKYCqwiU1rspLE59CPCv5csYhcPkEd6xvtm

小結

IPNS能夠爲ipfs的動態內容提供映射,用戶經過publish操做,使得其餘人訪問固定的IPNS地址就能夠最終訪問到不一樣的ipfs文件內容。

相關文章
相關標籤/搜索