IPFS━━IPNS和DNSLink

IPFS和DNSLink简析

IPNS

官方文档-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记录:

  1. 直接使用网关:需要将选定的域名使用Alias(如CNAME)记录指向一个IPFS网关地址,此时添加对应域名的TXT记录会冲突,可以将对应的TXT链接记录添加到带_dnslink前缀的子域名上(指向IPFS网关的好处:可以直接使用该域名,从IPFS网关获取该链接记录对应的IPFS对象)

  2. 控制权委派的场景:如果需要将可变内容存储在服务商,可以将DNSLink记录的控制权委派给第三方(通过将_dnslink前缀的子域名设置一条NS记录,指向授权的服务商的DNS服务器),此时授权的服务商的DNS负责该条DNS记录的解析:

如图,将item1.example.com表示的对象代理给托管服务hosting.com,添加一条对应的NS记录

安全性:使你能够设置自动发布或将对你的DNSLink记录的控制权委托给第三方,而不放弃对原始DNS域的完全控制

  1. 推荐使用_dnslink前缀子域名下的TXT记录

解析流程

原理具体参考[1],简而言之,IPFS网关会自动解析DNSLink,首先检查/ipns/后面部分是否是DNS域名,会检查在该域名或者带_dnslink前缀版本域名下的DNSLinkTXT记录

对于直接使用网关解析的域名,结合了A记录和DNSLink记录,解析过程:

  1. 浏览器检查该域名的A/CNAME记录,发现指向IPFS网关

  2. 浏览器链接IPFS网关,并且使用HOST:yourdomain.com HTTP头

  3. 然后IPFS网关会解析头部中的HOST:yourdomain.com 中域名,检查yourdomain.com或者_dnslink.yourdomain.com关联的DNSLink记录,类似:

➜ dig +short TXT yourdomain.com
"dnslink=/ipns/k2k4r8ovabtlzi2o4guz1mv7lnizpjzm72yfilfhac1hqfweg7s4eti3"
  1. 查询到DNSLink后,假设在yourdomain.com下有记录

  2. IPFS网关从IPFS中查询和获取到IPFS对象内容后,发送给浏览器

  3. 浏览器渲染对象,且仍然保留yourdomain.com原始的名称

Links

1. dnslink原理
2. https://docs.ipfs.io/concepts/dnslink/

posted @ 2021-10-13 20:53  qxxiao  阅读(825)  评论(0)    收藏  举报