IPFS(InterPlanetary File System)是一個內容尋址、版本化、點對點的分佈式文件系統。node
在官方網站下載對應平臺的安裝包,本文使用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
那麼將在本目錄下獲得一張貓的圖片安全
另外,能夠在瀏覽器中訪問http://localhost:5001/webui來使用ipfs的控制檯
使用add
將一個文件添加到ipfs網絡(能夠被其餘節點訪問到)
> cat 187J3X1.txt Hello!187J3X1! > ipfs add 187J3X1.txt added QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj 187J3X1.txt
文件要能被網絡中全部節點訪問須要必定時間,在某個運行ipfs的節點,使用get
命令能夠獲取到本文件
> ipfs get QmRTxTkdXeUmG9GxJBA7B8Ad8hticjNwkucCY96mkzusXj
更多命令可查看幫助信息
> ipfs --help
能夠從Github下載源碼,自行編譯安裝
在ipfs文件系統中,只要知道文件的Hash,就能夠從節點獲取文件。因此ipfs天生缺少隱私性,加入須要分享私密的文件給別人。一般的作法是分享者將文件用接收者的公鑰加密,接收者從ipfs網絡下載後用私鑰解密。GPG能夠完成加解密的功能。
GPG一樣可使用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
在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.io/ipns/輸入節點的id
如今對文件進行修改,並添加到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顯示新內容
ipns + 節點ID 顯示新內容
ipfs + 舊Hash 顯示舊內容
上面的例子中,咱們修改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文件內容。