IPFS 官方还没有很完整的 Gateway 部署指南,而且 Gateway 也缺少 Authorization 支持,本文就是简单记录下 Gateway 的部署过程,分别使用 Nginx 与 Caddy 作为服务器软件,最终将会得到:
基于 Docker 部署的 IPFS 实例;
支持 HTTPS 的 Gateway;
支持 HTTP Basic Authentication 的 API Server;
在开始前,你需要提前准备以下几项内容:
知道一些基本操作,或者会找相关的资料学习解决。比如如何安装 Docker Compose 等,我在此不会涉及太多这些内容。
一台云服务器主机。例如我在 Vultr 临时创建了一个系统为 Ubuntu 22.04 的实例用作演示,价格为 $6/月。
一个域名。例如我用来演示的域名托管在 Cloudflare 上。下文统一使用 your.domain 指代这个域名。小技巧:可以使用 Chrome 扩展 FindR 来替换 your.domain 成你自己的域名使得阅读与复制更加方便。
1. Docker 部署 IPFS
首先在云服务器 Ubuntu 上安装好 docker 与 docker-compose,然后执行以下操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 mkdir ipfs && cd ipfsecho " version: '3' services: ipfs: container_name: kubo image: ipfs/kubo:latest restart: unless-stopped volumes: - ./ipfs:/data/ipfs - ./ipfs_fuse:/ipfs - ./ipns_fuse:/ipns environment: - IPFS_PATH=/data/ipfs ports: - 4001:4001/tcp - 4001:4001/udp - 127.0.0.1:5001:5001 - 127.0.0.1:8080:8080 " > docker-compose.ymldocker-compose up -d curl localhost:8080/ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
现在 IPFS 实例已经部署完成了,现在我们修改一些 IPFS 的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 docker exec -it kubo /bin/sh ipfs config --json Swarm.ResourceMgr.Limits.System.ConnsInbound 2048 ipfs config --json Gateway.PublicGateways '{ "gateway.your.domain": { "UseSubdomains": true, "InlineDNSLink": true, "Paths": ["/ipfs", "/ipns"] } }' exit docker-compose restart
然后,进行防火墙配置,我这里执行 ufw disable 关闭 UFW,改成使用云服务器提供的防火墙服务,你也可以直接使用系统内的防火墙。主要就是同时开启 IPv4 与 IPv6 的 TCP 22/80/443/4001 端口与 UDP 4001 端口,如下:
Action
Protocol
Port
Source
accept
SSH
22
0.0.0.0/0,::/0
accept
TCP (HTTP)
80
0.0.0.0/0,::/0
accept
TCP (HTTPS)
443
0.0.0.0/0,::/0
accept
TCP
4001
0.0.0.0/0,::/0
accept
UDP
4001
0.0.0.0/0,::/0
drop
any
0 - 65535
0.0.0.0/0,::/0
2. DNS 配置
找到 Vultr 实例的 IP,比如我的分别为 IPv4: 149.28.140.214,IPv6: 2401:c080:1400:6016:5400:04ff:fe45:2010。那就在 your.domain 的 DNS 管理中添加以下几个记录,如果你是在 Cloudflare 中,暂时不要开启 Proxy:
Type
Name
Content
A
gateway
149.28.140.214
A
*.ipfs.gateway
149.28.140.214
A
*.ipns.gateway
149.28.140.214
AAAA
gateway
2401:c080:1400:6016:5400:04ff:fe45:2010
AAAA
*.ipfs.gateway
2401:c080:1400:6016:5400:04ff:fe45:2010
AAAA
*.ipns.gateway
2401:c080:1400:6016:5400:04ff:fe45:2010
3. Nginx 作为服务器
Nginx 是常用的服务器工具,下面介绍 Nginx 作为 IPFS 的服务器的配置。
3.1 Nginx 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 apt install nginx echo ' server { listen 80; listen [::]:80; server_name gateway.your.domain; location /ipfs { proxy_pass http://127.0.0.1:8080; proxy_set_header Host gateway.your.domain; } location /ipns { proxy_pass http://127.0.0.1:8080; proxy_set_header Host gateway.your.domain; } location /api { proxy_pass http://127.0.0.1:5001; proxy_set_header Host gateway.your.domain; } } ' > /etc/nginx/conf.d/ipfsgateway.confecho ' server { listen 80; listen [::]:80; server_name *.ipfs.gateway.your.domain; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; } } ' > /etc/nginx/conf.d/ipfsgateway_ipfs.confecho ' server { listen 80; listen [::]:80; server_name *.ipns.gateway.your.domain; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; } } ' > /etc/nginx/conf.d/ipfsgateway_ipns.confnginx -t && nginx -s reload
访问 http://gateway.your.domain/ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme 查看 Nginx 是否配置成功。
3.2 HTTPS 证书生成
我们借助 Certbot 帮忙生成 HTTPS 证书,因为我们使用通配符子域名,自动配置时需要完成 DNS 挑战。首先在 Cloudflare 用户界面 创建一个权限为 Zone:DNS:Edit 的 API Token,“Zone Resources” 选择现在所用的域名,将生成的 Token 按照格式 dns_cloudflare_api_token = YOUR_API_TOKEN 写入文件 ~/.secrets/certbot/cloudflare.ini。 然后如下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 chmod 600 ~/.secrets/certbot/cloudflare.inisnap install certbot --classic snap set certbot trust-plugin-with-root=ok snap install certbot-dns-cloudflare certbot --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini --dns-cloudflare-propagation-seconds 20 \ --installer nginx \ -d gateway.your.domain \ -d *.ipfs.gateway.your.domain -d *.ipns.gateway.your.domain
最后,修改 ipfsgateway.conf,为 /ipns, /ipfs 两个 location 添加 proxy_set_header X-Forwarded-Proto "https";,
1 2 3 4 5 6 7 8 9 10 11 location /ipfs { proxy_pass http://127.0.0.1:8080; proxy_set_header Host gateway.your.domain; proxy_set_header X-Forwarded-Proto "https"; } location /ipns { proxy_pass http://127.0.0.1:8080; proxy_set_header Host gateway.your.domain; proxy_set_header X-Forwarded-Proto "https"; }
然后执行 nginx -t && nginx -s reload 以生效,这样 Gateway 在需要重定向时会自动重定向为 HTTPS。现在测试下下面的链接:
3.3 IPFS API Server 添加认证
默认的 IPFS API Server,不做认证,如果暴露在公网,则谁都可以访问,而且 IPFS 并没有提供相关的认证功能。所以我们在 Nginx 里为 API Server 添加 Basic Auth:
1 2 3 4 apt install apache2-utils htpasswd -c /etc/nginx/.htpasswd your_username
然后修改 Nginx 配置,为 /api 添加 auth_basic 配置。
1 2 3 4 5 6 location /api { auth_basic "Auth Required Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://127.0.0.1:5001; proxy_set_header Host gateway.your.domain; }
然后执行 nginx -t && nginx -s reload 以生效。然后可以测试如下命令,注意将 your_username 与 your_password 替换:
1 2 curl -X POST "https://gateway.your.domain/api/v0/cat?arg=/ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme" \ -H "Authorization: Basic $(echo -n 'your_username:your_password' | base64) "
4. Caddy 作为服务器
Caddy 能够自动生成 HTTPS 证书,且也可以实现 Basic Auth,所以这里整理下 Caddy 作为服务器的配置。
4.1 构建带有额外组件的 Caddy Docker 镜像
和 Nginx 中使用 Certbot 生成证书类似,由于我们需要使用通配子域名,也要安装额外的组件,Caddy 原始镜像不提供这个功能,需要自行构建,新建 Dockerfile 以及 docker-compose.yml 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 mkdir caddy && cd caddyecho `FROM caddy:2.6.2-builder AS builder RUN xcaddy build \ --with github.com/caddy-dns/cloudflare FROM caddy:2.6.2 COPY --from=builder /usr/bin/caddy /usr/bin/caddy ` > Dockerfile echo `version: "3" services: caddy: build: . container_name: caddy restart: unless-stopped ports: - "80:80" - "80:80/udp" - "443:443" - "443:443/udp" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - ./data/:/data/caddy/ - ./config/:/config/caddy networks: - caddynet networks: caddynet: name: caddy_network ` > docker-compose.yml docker-compose build
然后在相同目录下创建 Caddyfile,注意替换其中的以下内容
邮箱地址:用于证书生成
Cloudflare API Token:获取方法与 Nginx 配置中一致
Basic Auth 用户名和密码:用户名使用明文,密码可以在 caddy 服务启动后使用命令 docker exec -it caddy caddy hash-password 生成,见 basicauth - Caddy Documentation
域名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 { auto_https ignore_loaded_certs email your@email.address acme_dns cloudflare your_dns_cloudflare_api_token } gateway.your.domain { handle /ipfs/* { reverse_proxy kubo:8080 { header_up HOST gateway.your.domain header_up X-Forwarded-Proto "https" } } handle /ipns/* { reverse_proxy kubo:8080 { header_up HOST gateway.your.domain header_up X-Forwarded-Proto "https" } } handle /api/* { reverse_proxy kubo:5001 { header_up HOST gateway.your.domain } } basicauth /api/* { your_username your_password } } *.ipfs.gateway.your.domain { handle * { reverse_proxy kubo:8080 { header_up HOST {host} header_up X-Forwarded-Proto "https" } } } *.ipns.gateway.your.domain { handle * { reverse_proxy kubo:8080 { header_up HOST {host} header_up X-Forwarded-Proto "https" } } }
现在可以使用 docker-compose up -d 启动 caddy 服务。
4.2 Caddy 访问 Kubo 服务
要使 Caddy 在 Docker 实例中能够访问 Kubo 服务,需要让 Kubo 加入 Caddy 的网络,只需要在 Kubo 的 docker-compose.yml 中添加 Caddy 的网络如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 version: '3' services: ipfs: container_name: kubo image: ipfs/kubo:latest restart: unless-stopped volumes: - ./ipfs:/data/ipfs - ./ipfs_fuse:/ipfs - ./ipns_fuse:/ipns environment: - IPFS_PATH=/data/ipfs ports: - 4001 :4001/tcp - 4001 :4001/udp - 127.0 .0 .1 :5001:5001 - 127.0 .0 .1 :8080:8080 networks: - ipfsnet networks: ipfsnet: name: caddy_network external: true
然后使用 docker-compose up -d --force-recreate 重新创建 Kubo 服务即可。
开启 Cloudflare Proxy 的问题
为了保护和加速网站的访问,首先你可以在 Cloudflare 为 gateway.your.domain 开启 Proxy。如果访问 Gateway 发生 ERR_TOO_MANY_REDIRECTS(xxx redirected you too many times) 错误,需要把域名的 SSL/TLS Encryption mode 配置从 Flexible 调整为 Full 。
Cloudflare 免费支持通配符,且免费为 *.your.domain 这样的通配二级域名子域名提供 HTTPS 证书,但是本文 Gateway 场景中需要为 *.ipfs.gateway.your.domain 通配四级域名子域名提供 HTTPS 证书,在 Cloudflare 中需要订阅 Advanced Certificate Manager 或者 Business Plan 才能实现自动生成或者自主上传涵盖这种子域名的高级证书。
此时如果强制为 *.ipfs.gateway 或者 *.ipns.gateway 开启 Proxy,会提示 This hostname is not covered by a certificate ,访问时也会出现 ERR_SSL_VERSION_OR_CIPHER_MISMATCH(This site can’t provide a secure xxx uses an unsupported protocol.) 错误。
这类功能确实属于高级功能,作为普通用户如果不愿意付费也没有关系,选择不开启 Proxy 至此也能完全正常使用了。也可以在 IPFS PublicGateways 配置时将 UseSubdomains 改为 false ,这样可以禁用不受保护的 ipfs 与 ipns 子域名,且不再重定向,代价就是这样的 URL 路径违反了同源策略(Same-origin policy)会造成一些兼容性问题。
Reference
Hosting a public IPFS gateway
IPFS Gateway | IPFS Docs
Kubo Config - Gateway
Restricting Access with HTTP Basic Authentication | NGINX Plus
certbot-dns-cloudflare’s Documentation
ERR_TOO_MANY_REDIRECTS · Cloudflare SSL/TLS docs
ERR_SSL_VERSION_OR_CIPHER_MISMATCH · Cloudflare SSL/TLS docs