Network Isolation
Wasmrun provides per-process network namespace isolation for WASM processes, ensuring each process runs in its own isolated network environment with full socket API support.
Overview
Network isolation provides:
- Per-process namespaces preventing cross-process interference
- Full WASI socket API implementation
- Isolated network stacks for each WASM process
- Security through namespace separation
This feature was introduced in v0.15.x and is part of the OS Mode capabilities.
WASI Socket API Support
Wasmrun implements the complete WASI socket API:
Socket Operations
sock_open- Create new socketssock_bind- Bind socket to addresssock_listen- Listen for connectionssock_accept- Accept incoming connectionssock_connect- Connect to remote hostssock_send- Send datasock_recv- Receive datasock_shutdown- Shutdown socket
Supported Socket Types
- TCP sockets for reliable connections
- UDP sockets for datagram communication
- Unix domain sockets (local communication)
DNS Resolution
getaddrinfo- Hostname to IP address resolution- IPv4 and IPv6 address resolution
- Integration with host DNS resolver (respects
/etc/resolv.conf) - Support for numeric and string port formats
- Comprehensive error handling and validation
How It Works
Network Namespace Creation
When a WASM process starts:
- New namespace created for the process
- Isolated network stack initialized
- Loopback interface configured
- Socket syscalls routed to the namespace
Process Isolation
Each process gets:
- Its own network interfaces
- Separate routing tables
- Isolated port bindings
- Independent firewall rules
Usage
Basic Network Operations
// Rust example with WASI sockets
use std::net::{TcpListener, TcpStream};
fn main() {
// Listen on isolated namespace
let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
for stream in listener.incoming() {
let stream = stream.unwrap();
handle_connection(stream);
}
}
# Run with network isolation
wasmrun os ./network-app
DNS Resolution Example
// Rust example with DNS resolution
use std::net::ToSocketAddrs;
fn main() {
// Resolve hostname to IP addresses
let addrs: Vec<_> = "google.com:443"
.to_socket_addrs()
.unwrap()
.collect();
println!("Resolved addresses: {:?}", addrs);
// Connect to resolved address
let stream = std::net::TcpStream::connect(&addrs[0]).unwrap();
println!("Connected to {}", addrs[0]);
}
# Run with DNS resolution support
wasmrun os ./dns-app
OS Mode Integration
Network isolation is automatically enabled in OS mode:
# Node.js server with isolated network
wasmrun os ./node-server --language nodejs
# Python web app with isolated network
wasmrun os ./python-app --language python
Security Benefits
Prevents Cross-Process Interference
Without isolation:
Process A binds to :8080 → Success
Process B binds to :8080 → Port conflict error
With isolation:
Process A (namespace 1) binds to :8080 → Success
Process B (namespace 2) binds to :8080 → Success (different namespace)
Attack Surface Reduction
- Processes can't sniff other processes' traffic
- Network attacks limited to single namespace
- Easier to apply per-process firewall rules
Port Forwarding
To expose services running in isolated namespaces to the host or external networks, use the port forwarding feature:
# Forward host port to WASM process port
wasmrun os ./app --forward 8080:3000
See Port Forwarding for details.
Configuration
Default Isolation
Network isolation is enabled by default in OS mode:
# Isolation automatically enabled
wasmrun os ./app
Custom Network Settings
Configure network behavior in .wasmrun.toml:
[network]
# Enable/disable network isolation (default: true)
isolation = true
# Namespace configuration
namespace_prefix = "wasmrun"
# Network interface settings
loopback_enabled = true
Compatibility
Supported Platforms
- Linux - Full support with kernel namespaces
- macOS - Limited support (simulated isolation)
- Windows - Limited support (simulated isolation)
Requirements
- Linux kernel 3.8+ for full namespace support
- Root/CAP_NET_ADMIN for namespace creation (or unprivileged user namespaces)
Troubleshooting
Permission Denied
# If namespace creation fails due to permissions
sudo wasmrun os ./app
# Or configure unprivileged user namespaces (Linux)
sudo sysctl -w kernel.unprivileged_userns_clone=1
Connection Refused
# Ensure service is listening in the namespace
# Check logs for bind errors
wasmrun os ./app --verbose
Port Conflicts
If you see port conflicts even with isolation:
- Check if isolation is actually enabled
- Verify namespace creation succeeded
- Review logs with
--verbose
Examples
HTTP Server
// Node.js server in isolated namespace
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello from isolated namespace!');
});
server.listen(3000, () => {
console.log('Server running on port 3000');
});
# Run with network isolation
wasmrun os ./server --language nodejs
# Access via port forwarding
wasmrun os ./server --language nodejs --forward 8080:3000
Multiple Isolated Processes
# Terminal 1: Process A on port 8080 in namespace A
wasmrun os ./app-a --forward 8080:8080
# Terminal 2: Process B on port 8080 in namespace B
wasmrun os ./app-b --forward 8081:8080
# No port conflict - different namespaces!
See Also
- OS Mode - Full OS mode documentation
- Port Forwarding - Exposing isolated services
- WASI Support - WASI socket APIs
- OS Mode Usage - OS mode command reference