
Exit Routing
Control where your traffic goes. An exit node opens connections to destinations on your behalf - reach internal networks, specific IP ranges, or route by domain name.
Common scenarios:
- Route
10.0.0.0/8through an exit inside a corporate network - Route
*.internal.corpto an agent with access to internal DNS - Route
0.0.0.0/0for a general-purpose exit to the internet
Route Types
- CIDR routes: Match destinations by IP address (e.g.,
10.0.0.0/8) - Domain routes: Match destinations by domain name (e.g.,
*.example.com)
:::note SOCKS5 vs TUN Interface Domain routes only work with SOCKS5 clients that send the destination hostname. The Mutiauk TUN interface operates at Layer 3 (IP) and only sees IP addresses after DNS resolution, so it can only use CIDR routes. Mutiauk's autoroutes feature fetches only CIDR routes from Muti Metroo. :::
:::tip Configuration See Exit Configuration for all options including CIDR routes, domain routes, and DNS servers. :::
Route Advertisement
Routes are propagated through the mesh:
- Periodic: Every
routing.advertise_interval(default 2m) - On-demand: Via HTTP API
POST /routes/advertise
Trigger Immediate Advertisement
curl -X POST http://localhost:8080/routes/advertise
DNS Resolution
DNS resolution location depends on the route type:
CIDR Routes (DNS at Ingress)
For destinations matching CIDR routes:
- Client connects via SOCKS5 with domain (e.g., example.com)
- Ingress agent resolves domain using the system's DNS resolver
- Ingress performs route lookup using the resolved IP address
- Ingress opens a stream to the exit node with the IP address
- Exit opens TCP connection to the destination IP
Domain Routes (DNS at Exit)
For destinations matching domain routes:
- Client connects via SOCKS5 with domain (e.g., api.internal.corp)
- Ingress checks domain routes first
- If a domain route matches, ingress opens a stream to the exit node with the domain name
- Exit agent resolves domain using the configured DNS servers
- Exit opens TCP connection to the resolved IP
:::tip When to Use Domain Routes Domain routes are ideal for:
- Split-horizon DNS: Internal domains that resolve differently inside vs. outside the network
- Private services: Route
*.internal.corpto an internal exit with access to internal DNS - Geo-specific resolution: Different DNS results based on exit node location :::
Route Selection
Domain Routes
Domain routes are checked first for domain-based requests:
- Exact match:
api.example.commatches onlyapi.example.com - Wildcard match:
*.example.commatches single-level subdomains likefoo.example.com - If no domain route matches, fall back to CIDR routing
Wildcard matching is single-level only:
*.example.commatchesfoo.example.comandbar.example.com*.example.comdoes NOT matcha.b.example.comorexample.com
CIDR Routes
Uses longest-prefix match:
- Filter routes where CIDR contains destination IP
- Select route with longest prefix (most specific)
- If tied, select lowest metric (hop count)
Example:
1.2.3.4/32beats1.2.3.0/24for 1.2.3.41.2.3.0/24beats0.0.0.0/0for 1.2.3.5
Access Control
Exit nodes only allow connections to destinations matching their advertised routes. If an exit advertises 10.0.0.0/8, connections to any other IP range will be rejected. This provides implicit access control - you control what each exit can reach by configuring its routes.
Verifying Routes
Check which routes are available in the mesh:
# View all routes (CIDR and domain)
curl http://localhost:8080/healthz | jq '{route_count: .route_count}'
# Trigger route advertisement after config changes
curl -X POST http://localhost:8080/routes/advertise
Troubleshooting
No Route to Host
curl: (7) Can't complete SOCKS5 connection to 10.1.2.3:443
Causes:
- No exit node advertising a route that covers the destination
- Exit node not connected to the mesh
- Route not yet propagated (wait for advertise interval)
Solutions:
# Check available routes
curl http://localhost:8080/healthz | jq '.route_count'
# Verify peer connections
curl http://localhost:8080/healthz | jq '.peer_count'
# Trigger route advertisement on the exit node
curl -X POST http://exit-node:8080/routes/advertise
Domain Route Not Matching
# Expected to use internal DNS but resolved externally
Causes:
- Using
socks5://instead ofsocks5h://(DNS resolved locally) - Domain pattern doesn't match (wildcards are single-level only)
- CIDR route matching before domain route (IP-based request)
Solutions:
- Use
socks5h://to send hostname to the proxy - Check wildcard pattern:
*.example.commatchesfoo.example.combut nota.b.example.com - Verify domain routes exist:
curl http://localhost:8080/api/dashboard | jq '.domain_routes'
Connection Timeout
curl: (7) Failed to connect to destination
Causes:
- Destination unreachable from exit node's network
- Firewall blocking outbound connections
- DNS resolution failing at exit (for domain routes)
Solutions:
- Verify exit node can reach the destination directly
- Check exit node's DNS configuration for domain routes
- Review firewall rules on the exit node's network
Related
- Configuration - Exit - Full configuration reference
- Concepts - Agent Roles - Understanding exit role
- Concepts - Routing - How routes propagate
- Security - Access Control - Route-based access control