|
|
|
DNS isolation for the editor.land private network.
Development environments that communicate over the public internet expose services to unnecessary risk. DNS resolution for local services goes through external resolvers, leaking information about the development setup.
"Nothing leaks to the public internet. A clean network boundary between the editor and the outside world."
Mist provides DNS isolation and private network resolution for the Land
Code Editor. It creates a secure DNS sandbox that resolves all *.editor.land
domains locally to 127.0.0.1, ensuring that all private network communication
remains local and secure. External DNS queries are restricted to a strict
allowlist, preventing sidecars from accessing arbitrary external hosts.
Editor components need to discover each other on the private network, but
standard DNS resolution leaks queries to external resolvers. Mist solves this
by running a local authoritative DNS server for the editor.land zone —
every query stays on the machine, and nothing escapes to the public internet.
Mist is engineered to:
- Provide Private DNS Resolution — Operate a local DNS server
authoritative for the
editor.landzone, resolving all subdomains to127.0.0.1for secure local communication. - Enforce Forward Security — Implement a forward allowlist that only
permits DNS resolution to specific, trusted external domains (e.g.,
update.editor.land). - Support DNSSEC — Sign the
editor.landzone with ECDSA P-256 keys for DNSSEC, providing cryptographic assurance of DNS responses. - Enable Sidecar Isolation — Allow
Node.jssidecars (like Cocoon) to use the local DNS server via a custom DNS override, ensuring they cannot access arbitrary external hosts.
Private DNS Zone — Authoritative zone for *.editor.land domains. All
subdomains resolve to 127.0.0.1, creating a fully isolated private network
for the editor's internal services. No DNS queries ever leave the machine.
Forward Security — Allowlist-based DNS forwarding prevents sidecars from
reaching arbitrary external hosts. Only explicitly trusted domains (such as
update.editor.land) can be resolved externally. All other queries are
refused by default.
DNSSEC Signing — The editor.land zone is signed with ECDSA P-256 keys,
providing cryptographic assurance of DNS responses. Clients can verify the
authenticity of every DNS record through DNSKEY and RRSIG records.
Dynamic Port Allocation — Automatically finds available ports using
portpicker, avoiding port conflicts with other services. Prefers a
configurable starting port and falls back to system-assigned ports when
needed.
WebSocket Transport — Real-time DNS data streaming over WebSocket for
local-first JSON-RPC communication between editor components. Supports
secure, low-latency message delivery within the private network.
Loopback Binding — The DNS server binds exclusively to 127.0.0.1,
ensuring no external host can query the private DNS server. Combined with
the forward allowlist, this creates a complete network boundary.
| Principle | Description | Key Components |
|---|---|---|
| Network Isolation | All editor.land DNS resolution stays local. The server binds to 127.0.0.1 only, and external queries require explicit allowlisting. |
Server, ForwardSecurity |
| Cryptographic Trust | DNSSEC signing with ECDSA P-256 keys ensures DNS responses cannot be spoofed. Every zone record carries a verifiable signature. | Zone, ring DNSSEC operations |
| Minimal Surface | A flat module structure with no unnecessary abstractions. Each module has a single, well-defined responsibility with clear public APIs. | Library, Server, Zone, Resolver |
| Composability | Independent DNS resolver for use by other Land components. Any consumer can create a resolver pointed at the local DNS server without additional configuration. | Resolver, LandDnsResolver |
graph LR
classDef mist fill:#e0f0ff,stroke:#2471a3,stroke-width:2px,color:#001030;
classDef zone fill:#d4f5d4,stroke:#27ae60,stroke-width:1px,color:#0a3a0a;
classDef forward fill:#fff3c0,stroke:#f39c12,stroke-width:1px,stroke-dasharray:5 5,color:#5a3e00;
classDef consumer fill:#f0d0ff,stroke:#9b59b6,stroke-width:1px,color:#2c0050;
classDef external fill:#ebebeb,stroke:#888,stroke-width:1px,stroke-dasharray:5 5,color:#333;
subgraph CONSUMERS["Land Components - DNS Clients"]
Mountain["Mountain ⛰️\nstarts Mist, reads DnsPort"]:::consumer
Cocoon["Cocoon 🦋\nNode.js sidecar (DNS override)"]:::consumer
Air["Air 🪁\nHTTP client with custom DNS"]:::consumer
end
subgraph MIST["Mist 🌫️ - Local DNS Server (127.0.0.1:PORT)"]
direction TB
Server["Server.rs - Hickory DNS\nUDP + TCP listeners"]:::mist
Zone["Zone.rs - Authoritative Zone\n*.editor.land → 127.0.0.1\nDNSSEC signed ECDSA P-256"]:::zone
Forward["ForwardSecurity.rs - Allowlist\nupdate.editor.land only"]:::forward
Resolver["Resolver.rs - LandDnsResolver"]:::mist
WSTransport["WebSocket.rs - DNS data stream"]:::mist
Server --> Zone
Server --> Forward
Server --> Resolver
Resolver --- WSTransport
end
subgraph INTERNET["External ☁️"]
UpdateServer["update.editor.land\nallowlisted only"]:::external
end
Mountain -- spawns + DnsPort --> Server
Cocoon -- DNS queries --> Server
Air -- DNS queries --> Resolver
Forward -- forwards allowed --> UpdateServer
Connection paths:
| Path | Protocol | Use Case |
|---|---|---|
| Mountain → Mist | Process spawn + port handoff | Application initialization, reads DnsPort managed state |
| Cocoon → Mist | DNS over UDP/TCP to 127.0.0.1 |
Node.js sidecar DNS resolution for editor.land domains |
| Air → Mist | LandDnsResolver (Hickory client) |
HTTP client DNS configured to use local resolver |
| Mist → External | UDP DNS (allowlisted only) | Forwarding queries for update.editor.land |
| Component | Path | Description |
|---|---|---|
| Library Entry | Source/Library.rs |
Main library entry point, exports public API and manages DNS server state. |
| DNS Server | Source/Server.rs |
DNS server implementation using Hickory, handles UDP/TCP listeners and catalog management. |
| Zone Configuration | Source/Zone.rs |
DNS zone configuration for editor.land, including record definitions and authority creation. |
| DNS Resolver | Source/Resolver.rs |
DNS resolver for use by other components, provides interface to the local DNS server. |
| Forward Security | Source/ForwardSecurity.rs |
Forward allowlist management, restricts which external domains can be resolved. |
| WebSocket Transport | Source/WebSocket.rs |
WebSocket transport layer for real-time DNS data streaming. |
Mist/
├── Source/
│ ├── Library.rs # Library root, DNS server lifecycle
│ ├── Server.rs # Hickory DNS server (UDP/TCP listeners)
│ ├── Zone.rs # Authoritative editor.land zone + DNSSEC
│ ├── Resolver.rs # LandDnsResolver for consumer use
│ ├── ForwardSecurity.rs # Allowlist-based forward DNS
│ └── WebSocket.rs # JSON-RPC over WebSocket transport
├── tests/
│ └── integration.rs # Integration test suite
├── Documentation/
│ ├── GitHub/
│ │ ├── Architecture.md # Internal module design
│ │ └── DeepDive.md # In-depth technical details
│ └── Rust/
│ └── doc/ # Cargo doc output
└── Cargo.toml
Mist provides the DNS isolation that secures the Land private network. All
*.editor.land domains resolve to 127.0.0.1, preventing external network
leakage. External DNS queries are restricted to a strict allowlist.
Mist is part of the networking/IPC connectivity stack alongside Air 🪁
(background daemon, uses Mist's DNS resolver for its HTTP client) and Vine
🌿 (gRPC protocol layer).
| Consumer | How Mist is Used |
|---|---|
| Mountain ⛰️ | Starts the DNS server during application initialization and provides the port to other components via the DnsPort managed state. |
| Air 🪁 | Uses the DNS server for secure HTTP requests, configuring HTTP clients to use the local DNS resolver. |
| SideCar 🏍️ | Spawns Node.js sidecars with DNS override configuration, ensuring all DNS queries go through the local server. |
| Cocoon 🦋 | The Node.js extension host can resolve editor.land domains via the local DNS server for gRPC communication with Mountain. |
Authoritative Zone: editor.land — All subdomains of editor.land resolve
to 127.0.0.1:
code.editor.land→127.0.0.1api.editor.land→127.0.0.1*.editor.land→127.0.0.1
Forward Allowlist — Only allowlisted external domains can be resolved:
update.editor.land— For application updates
All other external queries are refused by default.
DNSSEC — The editor.land zone is signed with ECDSA P-256 keys:
DNSKEYrecords provide the public signing keyRRSIGrecords provide cryptographic signatures- Clients can verify the authenticity of DNS responses
- Rust 1.75 or later
- No system DNS configuration required — Mist binds to
127.0.0.1only
cd Element/Mist
cargo build --release# Run all tests
cargo test
# Run integration tests
cargo test --test integration
# Run with logging
RUST_LOG=debug cargo testuse Mist::start;
// Start on preferred port 5380
let Port = Mist::start(5380)?;
// Or let the system select an available port
let Port = Mist::start(0)?;
println!("DNS server running on 127.0.0.1:{}", Port);use Mist::resolver::{land_resolver, LandDnsResolver};
// Simple resolver
let Port = Mist::dns_port();
let Resolver = land_resolver(Port);
// Or with explicit interface
let Resolver = LandDnsResolver::new(Port);| Crate | Purpose |
|---|---|
hickory-server |
DNS server implementation |
hickory-proto |
DNS protocol implementation |
hickory-client |
DNS client for resolvers |
ring |
Cryptographic signing for DNSSEC |
tokio |
Async runtime |
anyhow |
Error handling |
tracing |
Logging and instrumentation |
once_cell |
Thread-safe lazy initialization |
portpicker |
Random port selection |
async-trait |
Async trait support |
reqwest |
HTTP client with DNS integration |
Mist enforces security at multiple layers:
| Layer | Mechanism |
|---|---|
| Network isolation | All editor.land domains resolve to 127.0.0.1, preventing any external network access for private services. |
| Forward allowlist | External DNS queries are restricted to a trusted allowlist, preventing sidecars from accessing arbitrary external hosts. |
| DNSSEC | Zone signing provides cryptographic assurance of DNS responses, preventing DNS spoofing attacks. |
| Loopback binding | The DNS server only binds to 127.0.0.1, preventing external access to the private DNS server. |
Mist is designed to be compatible with:
| Target | Integration |
|---|---|
| Mountain ⛰️ | Starts the DNS server at initialization and distributes DnsPort via managed state |
| Air 🪁 | Uses LandDnsResolver as reqwest DNS override for secure HTTP requests |
| Cocoon 🦋 | Resolves editor.land domains through the local DNS server for gRPC IPC |
| SideCar 🏍️ | Spawns Node.js sidecars with DNS override pointing at the local server |
- Architecture Overview — Internal module structure
- Deep Dive — In-depth technical details
- Land Documentation — Complete documentation index
- Air 🪁 — Background daemon that consumes Mist for HTTP client DNS — GitHub
- Vine 🌿 —
gRPCprotocol layer — GitHub - Mountain ⛰️ — Main application process — GitHub
- CHANGELOG — Version history
This project is funded through NGI0 Commons Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program, under grant agreement No 101135429.
The project is operated by PlayForm, based in Sofia, Bulgaria. PlayForm acts as the open-source steward for Code Editor Land under the NGI0 Commons Fund grant.
|
|
|
|
|