IPFS━━IPNS和DNSLink
IPFS和DNSLink简析
IPNS
IPNS通过创建一个可以更新的地址(映射)来解决每次文件更新其链接也会更新的问题。基本原理:通过一个映射(IPNS记录),将一个IPNS地址映射为IPFS地址或者其他地址信息:
- 注意的是IPNS显示的ID字符串有两种形式:
base58btc encoded multihash对应于CIDv0格式,只有multihash的base58btc字符串编码(RSA);结果类似于12D...(哈希类型是idenity时),Qm...(哈希类型是sha2-256时)multibase encoded CID对应于CIDv1格式,有完整的base前缀(可能是base32|base36)等格式;结果类似于k...(base36),b...(base32)
- 一个IPNS记录对应一对
key pair,IPNS ID是和公钥相关:- 以前使用多是
RSA生成的公私钥,ID中的multihash是sha2-256 : 256类型 - 现在默认是
ed25519生成公私钥,ID中的multihash是identity : 288原类型 - 注意对应CIDv1的全格式,
codec编码为libp2p-key(0x72),cid-version编码为0x01
- 以前使用多是
总而言之,显示的字符串形式(PeerID或者IPNS ID)都可以看作是CID格式,可能是CIDv0或者是CIDv1格式,值与公钥(哈希)有关. 补充一个解释
实现相关
IPNS规范给出了IPNS记录的格式:
message IpnsEntry {
enum ValidityType {
// setting an EOL says "this record is valid until..."
EOL = 0;
}
required bytes value = 1;
required bytes signature = 2;
optional ValidityType validityType = 3;
optional bytes validity = 4;
optional uint64 sequence = 5;
optional uint64 ttl = 6;
optional bytes pubKey = 7;
}
主要包含记录的内容value,签名signature,公钥pubKey以及和版本、过期时间。
工作流程概括:
使用
IPFS初始化后默认生成
self的密钥对,默认发布IPNS记录使用self密钥,生成的ID与PeerID相同(都是self对应的公钥)
节点可以生成多个用于发布的IPNS的密钥对key pair:
ipfs key gen [--type=ed25519] [--size=2048] keyname # type: rsa/默认是ed25519
---------------------------------
# 显示所有的key(默认使用base36的CIDv1格式字符串)
ipfs key list -l
k51qzi5uqu5dks266jl6c9mf9fq4vwnymo3tdcz9yn7haxvs38rhwgz8w3k1pg self
k2k4r8ovabtlzi2o4guz1mv7lnizpjzm72yfilfhac1hqfweg7s4eti2 myweb
通过生成的key来发布ipfs对象,默认使用key=self:
# 默认使用nodeID相同的公钥
ipfs name publish <ipfs-addr>
# 将CID发布到其他IPNS Name,需要加上--key=xxx 参数
# 其值可以是keyname别名,也可以是CID表示
ipfs name publish --key=keyname <ipfs-addr>
- 注意<ipfs-addr>可以是CID,也可以是
/ipns/...或者是DNSLink,可以嵌套的
DNSLink
说明
【本质也是一个映射关系】DNS链接使用DNS TXT记录映射域名到一个IPFS地址。因为你可以编辑自己的DNS记录,可以使他们总是指向最新版本的IPFS中的对象。其目的是提供一个阅读记忆友好的名字。
一个DNS链接地址看起来像一个IPNS地址,但是DNS链接使用域名代替了被哈希的公钥:
/ipns/yourdomain.com
就像普通的IPFS地址(通过解析),也可以使用目录形式来寻址其链接的IPFS对象:
/ipns/yourdomain.com/docs/...
使用
选择域名链接
选择一个自己的域名(可以是子域名),添加一个TXT记录,其内容可以为:
dnslink=/ipfs/QmVMxjouRQCA2QykL5Rc77DvjfaX6m8NL6RyHXRTaZ9iya # 使用ipfs地址
dnslink=/ipns/k2k4r8ovabtlzi2o4guz1mv7lnizpjzm72yfilfhac1hqfweg7s4eti3 # ipns
dnslink=/ipns/yourdomain2.com # dnslink
具体的地址或链接根据实际需要寻址的IPFS对象确定,说明:一般使用IPNS地址,可以不用频繁更新dnslink链接
使用_dnslink子域名
有时候会需要使用_dnslink前缀的子域名来发布DNSLink记录:
-
直接使用网关:需要将选定的域名使用
Alias(如CNAME)记录指向一个IPFS网关地址,此时添加对应域名的TXT记录会冲突,可以将对应的TXT链接记录添加到带_dnslink前缀的子域名上(指向IPFS网关的好处:可以直接使用该域名,从IPFS网关获取该链接记录对应的IPFS对象) -
控制权委派的场景:如果需要将可变内容存储在服务商,可以将DNSLink记录的控制权委派给第三方(通过将
_dnslink前缀的子域名设置一条NS记录,指向授权的服务商的DNS服务器),此时授权的服务商的DNS负责该条DNS记录的解析:
如图,将
item1.example.com表示的对象代理给托管服务hosting.com,添加一条对应的NS记录安全性:使你能够设置自动发布或将对你的DNSLink记录的控制权委托给第三方,而不放弃对原始DNS域的完全控制
- 推荐使用
_dnslink前缀子域名下的TXT记录
解析流程
原理具体参考[1],简而言之,IPFS网关会自动解析DNSLink,首先检查/ipns/后面部分是否是DNS域名,会检查在该域名或者带_dnslink前缀版本域名下的DNSLinkTXT记录
对于直接使用网关解析的域名,结合了A记录和DNSLink记录,解析过程:
-
浏览器检查该域名的
A/CNAME记录,发现指向IPFS网关 -
浏览器链接IPFS网关,并且使用
HOST:yourdomain.comHTTP头 -
然后IPFS网关会解析头部中的
HOST:yourdomain.com中域名,检查yourdomain.com或者_dnslink.yourdomain.com关联的DNSLink记录,类似:
➜ dig +short TXT yourdomain.com
"dnslink=/ipns/k2k4r8ovabtlzi2o4guz1mv7lnizpjzm72yfilfhac1hqfweg7s4eti3"
-
查询到DNSLink后,假设在
yourdomain.com下有记录 -
IPFS网关从IPFS中查询和获取到IPFS对象内容后,发送给浏览器
-
浏览器渲染对象,且仍然保留
yourdomain.com原始的名称

浙公网安备 33010602011771号