现在大家可以通过这个传统域名访问到这个博客了:
这样的将 IPFS/IPNS 内容绑定到传统域名的方案已经存在很多年了。但是,其中的一个关键部分,之前的主要提供者是 Cloudflare 的 IPFS Gateway。不知为何,这个 Gateway 在过去一年的时间里,大部分时候都是非常不可用的状态,即使是在 Cloudflare 将这个 Web3 Gateway 以付费服务的方式提供之后。
而 ENS 之外的生态系统里,目前又暂时不存在像 ETH.LIMO 这样的高可用的项目。所以,目前大概只能自建了。不过也不复杂,如果你之前有 Linux 和 NGINX 的使用经验,那个原理和过程还挺简单的。大概就是以下 3 个步骤:
- 为域名增加 DNSLink 记录。
- 在 Linux 服务器上安装 Kubo 并进行一些必要的设置。
- 为域名搭建一个源站给 CDN。
为域名增加 DNSLink 记录
以本博客为例,第一步是从 Planet 里 Copy IPNS 获得这样的一个 k51 开头的字符串:
k51qzi5uqu5dkczezx3wje1dizdk7rta8uc50a5o9ix4wmzqniacrdbfapt8cf
假设我们要绑定到 blog.v2ex.com 这个域名,那么我们需要为 _dnslink.blog.v2ex.com 增加这样一条 TXT 类型的 DNS 记录:
dnslink=/ipns/k51qzi5uqu5dkczezx3wje1dizdk7rta8uc50a5o9ix4wmzqniacrdbfapt8cf
在完成这步之后,其实所有的公网上的 IPFS Gateway 就已经可以找到这个博客了,比如:
或者在 Brave 浏览器里直接用 ipns://blog.v2ex.com
也可以打开。
这种在浏览器地址栏里看到新协议的感觉。😊
我们的目标是让这个 IPNS 通过传统域名和传统浏览器也可以访问,所以我们还需要继续为它搭建一个源站。
在 Linux 服务器上安装 Kubo 并进行一些必要的设置
Kubo,也就是 Go 版本的 IPFS 实现的最新版本,可以从这里下载:
https://github.com/ipfs/kubo/releases
第一次运行前,需要初始化,我们选择以 server 配置进行初始化:
ipfs init --profile=server
然后就可以启动了,这里我们打开了和 PubSub 有关的两个试验选项。推荐用 supervisor 或者 systemd 做成常驻服务。
ipfs daemon --enable-pubsub-experiment --enable-namesys-pubsub
为域名搭建一个源站给 CDN
Kubo 启动之后,在 localhost 上就会多一个神奇的 8080 端口。这个端口是可以响应 HTTP 的 Host header 的,也就是说,如果你运行下面的这条指令,就可以拿到这个博客的首页:
curl -H "Host: blog.v2ex.com" http://127.0.0.1:8080/
所以,借助 Kubo 对虚拟主机头的支持,我们可以这样配置一个 NGINX 源站:
upstream ipfs_backend {
server 127.0.0.1:8080;
keepalive 4;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
# SSL
include /etc/nginx/ssl/v2ex.com.conf;
server_name blog.v2ex.com;
access_log /var/log/nginx/blog.v2ex.com.log;
location / {
proxy_cache awesome;
proxy_pass_header Server;
proxy_http_version 1.1;
proxy_set_header Host "blog.v2ex.com";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header Via "Planetable";
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504 http_403 http_404;
proxy_cache_valid 200 60s;
proxy_pass http://ipfs_backend;
}
}
在根目录的 nginx.conf 的 http {} 段落中加入缓存目录的配置:
proxy_cache_path /data/s levels=1:2 keys_zone=awesome:1024m max_size=8g inactive=28d;
proxy_temp_path /data/t 1 2;
这样我们就获得了一个可以给 CDN,比如 Cloudflare 使用的,能够响应 blog.v2ex.com 请求的 http/https 源站。
如果你能够读到这里,那你肯定是对这个话题相当感兴趣了。那我们再把这件事情继续扩展一下:假设你做了一个类似 ENS 的区块链域名项目,你想提供一个类似 ETH.LIMO 那样的 dWeb 网关,那么会还需要什么?这里是一个大致的 To Do 清单。
DNS-over-HTTPS 服务器
你需要为你的区块链域名项目实现一个 DoH 服务器,也就是通过 HTTP 协议提供的 DNS 查询服务。比如这是 ETH.LIMO 项目为 ENS 实现的:
https://dns.eth.limo/dns-query
然后你可以这样来发起查询:
curl --http2 -H "accept: application/dns-json" "https://dns.eth.limo/dns-query?name=vitalik.eth"
会拿到一个这样的结果:
{
"Status": "0",
"RD": false,
"RA": false,
"AD": false,
"CD": false,
"TC": false,
"Question": [
{
"type": 16,
"name": "vitalik.eth"
}
],
"Answer": [
{
"type": 16,
"name": "vitalik.eth",
"data": "dnslink=/ipfs/QmWxRwMg3bHyJxfAuPnUky2yNgNt51qmZqC99Ffenjxa94/",
"ttl": 600
}
]
}
实际上就是这个 DoH 服务器把 ENS 设定里的 content hash,当作一条 DNSLink 的 TXT 记录返回了。
有了这样的一个 DoH 服务器之后,Kubo 在配置中支持你把指定的域名后缀用定制的 DoH 服务器解析。
如果你打算写代码来实现这个 DoH 服务,那么并不需要支持所有类型的 DNS 查询,只要能用 TXT 类型返回 DNSLink 记录就可以了。
相关文档:
https://github.com/ipfs/kubo/blob/master/docs/config.md#dns
假设你的区块链域名项目的后缀叫做 .ape
,支持用户设定类似 EIP-1577 那样的 content hash,在 https://dns.example.com/dns-query 上运行了一个能够解析 .ape 的 DoH 服务器,那么你就可以把这样的配置加入到 Kubo 的 config 中:
{
"DNS": {
"Resolvers": {
"ape.": "https://dns.example.com/dns-query"
}
}
}
然后,只要对之前提到的那个 NGINX 配置文件稍作改造,用 Lua 模块获得用户请求的 .ape 域名,然后加上正确的 proxy_set_header Host 发向配置好了 DoH 服务器的 Kubo upstream,那么一个类似 ETH.LIMO 的 dWeb Gateway 就这样初步搭建好了。
下面这个是一个用 Python Flask 框架写的可以解析 .bit 区块链域名的 DoH 服务器: