381 lines
12 KiB
Markdown
381 lines
12 KiB
Markdown
|
|
# Network Architecture: IPNS DNSLink + Cloudflare IPFS Gateway
|
||
|
|
|
||
|
|
Integration guide for Sonr's decentralized storage layer using IPNS DNSLink with Cloudflare's enterprise IPFS gateway.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
||
|
|
│ SONR NETWORK TOPOLOGY │
|
||
|
|
├─────────────────────────────────────────────────────────────────────────────┤
|
||
|
|
│ │
|
||
|
|
│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
|
||
|
|
│ │ Browser Client │ │ Cloudflare Edge (330+) │ │
|
||
|
|
│ │ │ HTTPS │ │ │
|
||
|
|
│ │ vault.sonr.org ────┼───────────────────►│ IPFS Gateway + CDN Cache │ │
|
||
|
|
│ │ │ │ │ │
|
||
|
|
│ └─────────────────────┘ └──────────────┬──────────────┘ │
|
||
|
|
│ │ │ │
|
||
|
|
│ │ Circuit Relay │ Bitswap │
|
||
|
|
│ ▼ ▼ │
|
||
|
|
│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
|
||
|
|
│ │ Sonr Relay Node │◄──────────────────►│ IPFS Network │ │
|
||
|
|
│ │ relay.sonr.org │ P2P/DHT │ │ │
|
||
|
|
│ │ │ │ • Content Discovery │ │
|
||
|
|
│ │ • Helia + Coord │ │ • Block Exchange │ │
|
||
|
|
│ │ • IPNS Publishing │ │ • DHT Routing │ │
|
||
|
|
│ └─────────────────────┘ └─────────────────────────────┘ │
|
||
|
|
│ │ │
|
||
|
|
│ │ IPNS Publish │
|
||
|
|
│ ▼ │
|
||
|
|
│ ┌─────────────────────────────────────────────────────────────────────┐ │
|
||
|
|
│ │ Cloudflare DNS (sonr.org) │ │
|
||
|
|
│ │ │ │
|
||
|
|
│ │ _dnslink.vault.sonr.org TXT "dnslink=/ipns/<PEER_ID>" │ │
|
||
|
|
│ │ vault.sonr.org CNAME cloudflare-ipfs.com (proxied) │ │
|
||
|
|
│ │ │ │
|
||
|
|
│ └─────────────────────────────────────────────────────────────────────┘ │
|
||
|
|
└─────────────────────────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
## Cloudflare Enterprise Features
|
||
|
|
|
||
|
|
### Plan Comparison
|
||
|
|
|
||
|
|
| Feature | Free/Pro/Business | Enterprise |
|
||
|
|
|---------|-------------------|------------|
|
||
|
|
| Total Gateways | 15 | Unlimited |
|
||
|
|
| Gateway Types | DNSLink only | DNSLink + Universal Path |
|
||
|
|
| Included Bandwidth | 50 GB | 100 GB |
|
||
|
|
| File Size Limit | None | None |
|
||
|
|
| SLA | Standard | Enterprise SLA |
|
||
|
|
| Support | Ticket | 24/7 Dedicated |
|
||
|
|
| Peering Priority | Standard | Custom peering configuration |
|
||
|
|
|
||
|
|
### Enterprise Benefits
|
||
|
|
|
||
|
|
| Benefit | Description |
|
||
|
|
|---------|-------------|
|
||
|
|
| Unlimited Gateways | No limit on custom domain gateways |
|
||
|
|
| Universal Path Gateway | Access any CID via `gateway.sonr.org/ipfs/<CID>` |
|
||
|
|
| Custom Peering | Direct peering with Sonr relay nodes |
|
||
|
|
| Edge Caching | 330+ PoPs, automatic cache invalidation on IPNS update |
|
||
|
|
| Origin Isolation | XSS protection via subdomain isolation |
|
||
|
|
|
||
|
|
## DNS Configuration
|
||
|
|
|
||
|
|
### Required Records
|
||
|
|
|
||
|
|
| Type | Name | Value | Proxy |
|
||
|
|
|------|------|-------|-------|
|
||
|
|
| CNAME | `vault.sonr.org` | `cloudflare-ipfs.com` | Proxied |
|
||
|
|
| TXT | `_dnslink.vault.sonr.org` | `dnslink=/ipns/<PEER_ID>` | N/A |
|
||
|
|
| CNAME | `gateway.sonr.org` | `cloudflare-ipfs.com` | Proxied |
|
||
|
|
| TXT | `_dnslink.gateway.sonr.org` | `dnslink=/ipns/<PEER_ID>` | N/A |
|
||
|
|
|
||
|
|
### DNSLink Format
|
||
|
|
|
||
|
|
```
|
||
|
|
dnslink=/ipns/<PEER_ID>
|
||
|
|
dnslink=/ipns/<DOMAIN>
|
||
|
|
dnslink=/ipfs/<CID>
|
||
|
|
```
|
||
|
|
|
||
|
|
| Format | Use Case |
|
||
|
|
|--------|----------|
|
||
|
|
| `/ipns/<PEER_ID>` | Mutable content, updates without DNS change |
|
||
|
|
| `/ipns/<DOMAIN>` | Recursive resolution to another DNSLink |
|
||
|
|
| `/ipfs/<CID>` | Immutable content, requires DNS update |
|
||
|
|
|
||
|
|
### Verification
|
||
|
|
|
||
|
|
```bash
|
||
|
|
dig +short TXT _dnslink.vault.sonr.org
|
||
|
|
```
|
||
|
|
|
||
|
|
## Gateway Types
|
||
|
|
|
||
|
|
### DNSLink Gateway (Restricted)
|
||
|
|
|
||
|
|
Serves content from a single IPNS/CID specified in DNS.
|
||
|
|
|
||
|
|
```
|
||
|
|
https://vault.sonr.org/
|
||
|
|
└── Resolves _dnslink.vault.sonr.org
|
||
|
|
└── /ipns/k51qzi5uqu5...
|
||
|
|
└── /ipfs/bafy...
|
||
|
|
```
|
||
|
|
|
||
|
|
### Universal Path Gateway (Enterprise)
|
||
|
|
|
||
|
|
Serves any content by CID or IPNS path.
|
||
|
|
|
||
|
|
```
|
||
|
|
https://gateway.sonr.org/ipfs/<CID>
|
||
|
|
https://gateway.sonr.org/ipns/<PEER_ID>
|
||
|
|
https://gateway.sonr.org/ipns/<DOMAIN>
|
||
|
|
```
|
||
|
|
|
||
|
|
## IPNS Publishing
|
||
|
|
|
||
|
|
### Helia Integration
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { createHelia } from 'helia'
|
||
|
|
import { ipns } from '@helia/ipns'
|
||
|
|
import { unixfs } from '@helia/unixfs'
|
||
|
|
import { generateKeyPair } from '@libp2p/crypto/keys'
|
||
|
|
|
||
|
|
const helia = await createHelia()
|
||
|
|
const name = ipns(helia)
|
||
|
|
const fs = unixfs(helia)
|
||
|
|
|
||
|
|
const cid = await fs.addBytes(encryptedEnclaveBlob)
|
||
|
|
|
||
|
|
await name.publish(privateKey, cid, {
|
||
|
|
lifetime: 24 * 60 * 60 * 1000
|
||
|
|
})
|
||
|
|
```
|
||
|
|
|
||
|
|
### DNSLink Resolution
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { dnsLink } from '@helia/dnslink'
|
||
|
|
|
||
|
|
const resolver = dnsLink(helia)
|
||
|
|
const result = await resolver.resolve('vault.sonr.org')
|
||
|
|
```
|
||
|
|
|
||
|
|
## TTL Configuration
|
||
|
|
|
||
|
|
### DNS TTL
|
||
|
|
|
||
|
|
| Use Case | TTL | Rationale |
|
||
|
|
|----------|-----|-----------|
|
||
|
|
| Frequently updated content | 60s | Fast propagation |
|
||
|
|
| Stable content | 3600s | Reduce DNS queries |
|
||
|
|
| Production default | 300s | Balance between freshness and efficiency |
|
||
|
|
|
||
|
|
### IPNS Lifetime
|
||
|
|
|
||
|
|
| Parameter | Value | Description |
|
||
|
|
|-----------|-------|-------------|
|
||
|
|
| `lifetime` | 24h | Record validity period |
|
||
|
|
| `ttl` | 1h | Suggested cache duration for resolvers |
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
await name.publish(privateKey, cid, {
|
||
|
|
lifetime: 24 * 60 * 60 * 1000,
|
||
|
|
ttl: 60 * 60 * 1000
|
||
|
|
})
|
||
|
|
```
|
||
|
|
|
||
|
|
## Cloudflare API Integration
|
||
|
|
|
||
|
|
### Create Web3 Gateway
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl "https://api.cloudflare.com/client/v4/zones/{zone_id}/web3/hostnames" \
|
||
|
|
--header "Authorization: Bearer <API_TOKEN>" \
|
||
|
|
--header "Content-Type: application/json" \
|
||
|
|
--data '{
|
||
|
|
"name": "vault.sonr.org",
|
||
|
|
"description": "Sonr Vault IPFS Gateway",
|
||
|
|
"target": "ipfs",
|
||
|
|
"dnslink": "/ipns/<PEER_ID>"
|
||
|
|
}'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Update DNSLink
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl "https://api.cloudflare.com/client/v4/zones/{zone_id}/web3/hostnames/{gateway_id}" \
|
||
|
|
--request PATCH \
|
||
|
|
--header "Authorization: Bearer <API_TOKEN>" \
|
||
|
|
--header "Content-Type: application/json" \
|
||
|
|
--data '{
|
||
|
|
"dnslink": "/ipns/<NEW_PEER_ID>"
|
||
|
|
}'
|
||
|
|
```
|
||
|
|
|
||
|
|
### Create TXT Record
|
||
|
|
|
||
|
|
```bash
|
||
|
|
curl "https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records" \
|
||
|
|
--header "Authorization: Bearer <API_TOKEN>" \
|
||
|
|
--header "Content-Type: application/json" \
|
||
|
|
--data '{
|
||
|
|
"type": "TXT",
|
||
|
|
"name": "_dnslink.vault.sonr.org",
|
||
|
|
"content": "dnslink=/ipns/<PEER_ID>",
|
||
|
|
"ttl": 300
|
||
|
|
}'
|
||
|
|
```
|
||
|
|
|
||
|
|
## Domain Strategy
|
||
|
|
|
||
|
|
### Subdomain Allocation
|
||
|
|
|
||
|
|
| Subdomain | Type | Purpose |
|
||
|
|
|-----------|------|---------|
|
||
|
|
| `vault.sonr.org` | DNSLink | User enclave data (IPNS) |
|
||
|
|
| `did.sonr.org` | DNSLink | DID document resolution (IPNS) |
|
||
|
|
| `gateway.sonr.org` | Universal | General IPFS access (Enterprise) |
|
||
|
|
| `relay.sonr.org` | Direct | Circuit Relay server (WSS) |
|
||
|
|
|
||
|
|
### Resolution Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
User Request: https://vault.sonr.org/
|
||
|
|
│
|
||
|
|
▼
|
||
|
|
Cloudflare Edge
|
||
|
|
│
|
||
|
|
├── Check edge cache
|
||
|
|
│ └── Hit: Return cached content
|
||
|
|
│
|
||
|
|
├── DNS Lookup: _dnslink.vault.sonr.org
|
||
|
|
│ └── TXT: dnslink=/ipns/k51qzi5uqu5...
|
||
|
|
│
|
||
|
|
├── IPNS Resolution
|
||
|
|
│ └── k51qzi5uqu5... → /ipfs/bafy...
|
||
|
|
│
|
||
|
|
├── IPFS Fetch (Bitswap)
|
||
|
|
│ └── Retrieve blocks from network
|
||
|
|
│
|
||
|
|
└── Cache + Return
|
||
|
|
```
|
||
|
|
|
||
|
|
## Caching Behavior
|
||
|
|
|
||
|
|
### Edge Cache
|
||
|
|
|
||
|
|
| Trigger | Action |
|
||
|
|
|---------|--------|
|
||
|
|
| First request | Fetch from IPFS, cache at edge |
|
||
|
|
| Subsequent requests | Serve from edge cache |
|
||
|
|
| IPNS update | Cache invalidated on TTL expiry |
|
||
|
|
| Manual purge | API-triggered cache clear |
|
||
|
|
|
||
|
|
### Cache Headers
|
||
|
|
|
||
|
|
```
|
||
|
|
Cache-Control: public, max-age=3600
|
||
|
|
X-IPFS-Path: /ipfs/bafy...
|
||
|
|
X-IPFS-Roots: bafy...
|
||
|
|
ETag: "bafy..."
|
||
|
|
```
|
||
|
|
|
||
|
|
## Content Update Flow
|
||
|
|
|
||
|
|
### Without DNS Change (IPNS)
|
||
|
|
|
||
|
|
```
|
||
|
|
1. Encrypt new enclave blob
|
||
|
|
2. Add to Helia: cid = await fs.addBytes(blob)
|
||
|
|
3. Publish IPNS: await name.publish(key, cid)
|
||
|
|
4. Cloudflare resolves new CID on next request (after TTL)
|
||
|
|
```
|
||
|
|
|
||
|
|
### With DNS Change (CID)
|
||
|
|
|
||
|
|
```
|
||
|
|
1. Add content to IPFS
|
||
|
|
2. Update _dnslink TXT record via Cloudflare API
|
||
|
|
3. Wait for DNS propagation (TTL)
|
||
|
|
4. Cloudflare serves new content
|
||
|
|
```
|
||
|
|
|
||
|
|
## Security
|
||
|
|
|
||
|
|
### Transport Security
|
||
|
|
|
||
|
|
| Layer | Protection |
|
||
|
|
|-------|------------|
|
||
|
|
| Client → Cloudflare | TLS 1.3 |
|
||
|
|
| Cloudflare → IPFS | Bitswap (encrypted channels) |
|
||
|
|
| Content | AES-256-GCM (client-side) |
|
||
|
|
|
||
|
|
### Content Integrity
|
||
|
|
|
||
|
|
| Mechanism | Guarantee |
|
||
|
|
|-----------|-----------|
|
||
|
|
| CID | SHA-256 hash of content |
|
||
|
|
| IPNS Signature | Ed25519 signed record |
|
||
|
|
| DNSLink | DNSSEC (if enabled) |
|
||
|
|
|
||
|
|
### Access Control
|
||
|
|
|
||
|
|
| Method | Implementation |
|
||
|
|
|--------|----------------|
|
||
|
|
| Private content | Encrypt before upload |
|
||
|
|
| Rate limiting | Cloudflare WAF rules |
|
||
|
|
| Blocklist | Universal gateway content filtering |
|
||
|
|
|
||
|
|
## Monitoring
|
||
|
|
|
||
|
|
### Cloudflare Analytics
|
||
|
|
|
||
|
|
| Metric | Source |
|
||
|
|
|--------|--------|
|
||
|
|
| Requests | Web3 Gateway dashboard |
|
||
|
|
| Bandwidth | Zone analytics |
|
||
|
|
| Cache hit ratio | Cache analytics |
|
||
|
|
| Error rates | Firewall events |
|
||
|
|
|
||
|
|
### IPNS Health
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
const status = {
|
||
|
|
peerId: helia.libp2p.peerId.toString(),
|
||
|
|
peers: helia.libp2p.getPeers().length,
|
||
|
|
ipnsRecords: await getPublishedRecords()
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Implementation Checklist
|
||
|
|
|
||
|
|
### Cloudflare Setup
|
||
|
|
|
||
|
|
- [ ] Enable Web3 gateway on zone
|
||
|
|
- [ ] Create DNSLink gateway for `vault.sonr.org`
|
||
|
|
- [ ] Create DNSLink gateway for `did.sonr.org`
|
||
|
|
- [ ] Create Universal gateway for `gateway.sonr.org` (Enterprise)
|
||
|
|
- [ ] Configure TXT records for each subdomain
|
||
|
|
- [ ] Verify CNAME proxying enabled
|
||
|
|
- [ ] Set appropriate TTLs
|
||
|
|
|
||
|
|
### Relay Node Setup
|
||
|
|
|
||
|
|
- [ ] Deploy `ipfs-service-provider` with relay enabled
|
||
|
|
- [ ] Generate persistent IPNS keypair
|
||
|
|
- [ ] Configure IPNS publishing on content update
|
||
|
|
- [ ] Set up monitoring for IPNS record health
|
||
|
|
- [ ] Configure peering with Cloudflare (Enterprise)
|
||
|
|
|
||
|
|
### SDK Integration
|
||
|
|
|
||
|
|
- [ ] Add `@helia/ipns` for publishing
|
||
|
|
- [ ] Add `@helia/dnslink` for resolution
|
||
|
|
- [ ] Implement enclave CID tracking
|
||
|
|
- [ ] Add IPNS publish on enclave save
|
||
|
|
- [ ] Handle offline/online sync
|
||
|
|
|
||
|
|
## Dependencies
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"@helia/ipns": "^8.0.0",
|
||
|
|
"@helia/dnslink": "^4.0.0",
|
||
|
|
"@helia/unixfs": "^4.0.0",
|
||
|
|
"helia": "^5.0.0"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## References
|
||
|
|
|
||
|
|
- [Cloudflare Web3 Gateway](https://developers.cloudflare.com/web3/)
|
||
|
|
- [IPFS DNSLink Specification](https://dnslink.dev/)
|
||
|
|
- [Helia IPNS Package](https://github.com/ipfs/helia/tree/main/packages/ipns)
|
||
|
|
- [Cloudflare API - Web3](https://developers.cloudflare.com/api/resources/web3/)
|