-
Notifications
You must be signed in to change notification settings - Fork 50
Network Isolation
COI provides network isolation to protect your host and private networks from container access.
Requirements: Network isolation (restricted/allowlist modes) requires nftables (nft) plus the passwordless-sudo rule that install.sh creates (/etc/sudoers.d/coi-nft). COI uses nftables rules to filter container traffic in the FORWARD chain. If nftables or passwordless sudo is not available, set [network] mode = "open" in config (optionally with use_sudo = false to disable sudo entirely), or install nftables and configure the sudoers rule.
Blocks local networks, allows internet:
coi shell # Default behavior- Blocks: RFC1918 private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
- Blocks: Cloud metadata endpoints (169.254.0.0/16)
- Allows: All public internet (npm, pypi, GitHub, APIs, etc.)
- IPv6 disabled inside container to prevent bypassing IPv4 firewall rules
Only specific domains allowed:
[network]
mode = "allowlist"- Requires configuration with
allowed_domainslist -
TTL-aware DNS refresh - Domain IPs are re-resolved based on actual DNS TTL values, not a fixed interval. Domains with short TTLs (e.g., CDNs, cloud services) refresh more frequently, preventing allowed domains from becoming unreachable when their IPs rotate. The
refresh_interval_minutesconfig acts as a maximum cap; the actual interval is the minimum TTL across all resolved domains (with a 60-second floor to prevent excessive queries) - Always blocks RFC1918 private networks
- IP caching for DNS failure resilience
No restrictions (trusted projects only):
[network]
mode = "open"Restricted/allowlist enforcement requires COI to run nft via passwordless
sudo (the installer adds /etc/sudoers.d/coi-nft). If you decline that sudoers
rule, set:
[network]
mode = "open"
use_sudo = falseWith use_sudo = false, COI never invokes sudo for network operations:
-
openmode runs normally (no privileged rules are needed). -
restricted/allowlistmodes fail fast with a clear error — they cannot be enforced without sudo, and COI will not silently downgrade to open (fail-closed). Switch tomode = "open"to proceed. -
coi healthreports the nft check as OK in open mode and as a warning (not a hard failure) if you pairuse_sudo = falsewith a mode that needs nft — so a no-sudoers setup gets a clean health report. -
nft network monitoring is skipped (it requires
sudo nft).
The setting can only make COI do less — it never weakens isolation — so it is safe to set from any config scope. It is the supported way to run COI with no sudoers modification at all.
# ~/.coi/config.toml
[network]
mode = "restricted" # restricted | open | allowlist
# Allowlist mode configuration
# Supports both domain names and raw IPv4 addresses
allowed_domains = [
"8.8.8.8", # Google DNS (REQUIRED for DNS resolution)
"1.1.1.1", # Cloudflare DNS (REQUIRED for DNS resolution)
"registry.npmjs.org", # npm package registry
"api.anthropic.com", # Claude API
"platform.claude.com", # Claude Platform
]
refresh_interval_minutes = 30 # Maximum IP refresh interval; actual interval uses DNS TTL if shorter (0 to disable)- Gateway IP is auto-detected and excluded from RFC1918 checks - COI automatically detects your network gateway IP and exempts it from private network blocking. This prevents false-positive alerts on routine DNS/NTP traffic that routes through the Incus bridge gateway. You don't need to add it manually.
-
Public DNS servers required -
8.8.8.8and1.1.1.1must be in the allowlist for DNS resolution to work. - Firewall rule ordering - COI adds ALLOW rules first (for gateway, allowed domains/IPs), then REJECT rules (for RFC1918 ranges), then a default REJECT rule for allowlist mode.
- Supports both domain names (
github.com) and raw IPv4 addresses (8.8.8.8) - Subdomains must be listed explicitly (
github.com≠api.github.com) - Domains behind CDNs may have many IPs that change frequently
- DNS failures use cached IPs from previous successful resolution
By default, COI allows the host machine to access services running in containers. This works by adding an allow rule for the gateway IP (which represents the host) before the RFC1918 block rules. Since the COI-managed nftables rules order the gateway allow rule before the RFC1918 reject rules, the gateway IP is allowed while other private IPs are still blocked.
For example, if a web server runs on port 3000 in the container:
# Inside container: Puma/Rails server listening on 0.0.0.0:3000
# From host: Access via container IP
curl http://<container-ip>:3000Reaching services via <container-ip>:<port> works, but requires looking up the IP and doesn't tell the agent which ports you can reach. The [ports] config section (v0.10.1) publishes container ports at localhost:<port> on the host via Incus proxy devices — and because that uses the userspace forkproxy (bind=host), NOT NAT rules, the nftables isolation described on this page is completely untouched: the container gains no new outbound capability. See Port Publishing.
For development environments where you want machines on your local network to access container services (e.g., accessing containers via tmux from multiple machines), add this to your config:
[network]
allow_local_network_access = true # Allow all RFC1918, not just gatewayWarning: When
allow_local_network_access = true, ALL RFC1918 private network traffic is allowed - there is no RFC1918 blocking at all. A compromised AI tool can reach any machine on your local network, including internal services, NAS devices, and other development machines. Only enable this in fully trusted environments where cross-machine access is genuinely required.
Default behavior: Only the host (gateway IP) can access container services. Other machines on your local network cannot, even if they're on the same subnet.
Note: Nftables rules filter forwarded container traffic. All traffic from the container to the gateway IP is permitted to allow host-to-container communication.
If you see "Connection refused" when trying to access container services:
- Verify container service is listening:
coi container exec <name> -- netstat -tlnp - Check container IP:
coi list(shows IPv4 for running containers) - Ensure firewall allows traffic to the bridge network
Network isolation (restricted/allowlist modes) requires nftables. If you see the error "nft is not available or passwordless sudo is not configured", you have two options:
# ~/.coi/config.toml
[network]
mode = "open"This disables egress filtering but allows you to work immediately. If you also want COI to never invoke sudo for network operations, add use_sudo = false (see Running without sudo).
Nftables provides the FORWARD chain filtering needed for network isolation. Re-running install.sh sets this up automatically, or do it manually:
# 1. Install nftables (Ubuntu/Debian)
sudo apt install nftables
# 2. Allow COI to manage firewall rules (passwordless sudo for nft)
echo "$USER ALL=(ALL) NOPASSWD: /usr/sbin/nft" | sudo tee /etc/sudoers.d/coi-nft
sudo chmod 0440 /etc/sudoers.d/coi-nft(If nft lives elsewhere on your distro, use the path from command -v nft in the sudoers rule — that is what install.sh does.)
- nftables plus passwordless sudo for
nftmust be available for network isolation to work - COI adds nftables rules to the FORWARD chain to filter container traffic
- Rules are scoped by container IP address for precise filtering
- Rules are removed when containers are stopped/deleted
- COI gets the container's IP address from Incus
- Nftables rules are applied per container IP, with allow rules ordered before reject rules
- Restricted mode: Allow gateway, block RFC1918, allow all else
- Allowlist mode: Allow gateway, allow specific IPs, block RFC1918, block all else
- If
nftis unavailable and the host's FORWARD policy is DROP, COI falls back to iptables bridge rules so container traffic can still be forwarded
COI automatically manages firewall resources to prevent accumulation of stale configurations:
-
Cleanup on all termination paths: Firewall rules are cleaned up during normal exit,
coi shutdown,coi kill, and when the security responder auto-kills a container -
Orphaned resource detection:
coi clean --orphansscans for and removes:- Orphaned veth interfaces (no master bridge)
- Orphaned nft rules (for non-existent container IPs)
- Orphaned IPv6 block rules (for containers no longer running)
- Orphaned nftables monitoring rules and chains (when nftables monitoring is enabled)
- Orphaned iptables bridge rules (coi-bridge-forward rules with no COI containers running)
This prevents nftables from accumulating stale rules over time, which could otherwise cause configuration bloat and potential conflicts.
Manual cleanup:
# Clean up all orphaned resources (veths and stale nft/iptables rules)
coi clean --orphans
# Dry run to see what would be cleaned
coi clean --orphans --dry-run-
Use
restrictedmode by default - It's the right balance for most work: full internet access for packages and APIs, no access to your internal network. Only switch away from it when you have a specific reason. -
Use
allowlistmode for untrusted codebases - When working in a repo you didn't write or haven't fully audited, constrain egress to only the services the project legitimately needs (npm, PyPI, GitHub, the project's own API). This limits what a malicious or prompted AI tool can contact. -
Keep DNS servers in the allowlist -
8.8.8.8and1.1.1.1are required for DNS resolution in allowlist mode. Without them, package managers and the AI tool itself will fail to resolve hostnames. -
Do not use
allow_local_network_access = truewithout understanding the risk - This disables all RFC1918 blocking. It's appropriate when running services on other machines in your network that the AI needs to reach, but it removes the lateral movement protection. -
Combine with security monitoring - Network isolation is a preventive control; Security Monitoring is a detective control. Use both together. Monitoring logs network events even in open mode.
-
Clean up orphaned rules periodically - If containers exit abnormally, nftables rules can accumulate. Run
coi clean --orphansor add a cron job to keep rules tidy.
- Security Best Practices - Recommended network settings for different risk levels
- Security Monitoring - How network threats are detected and responded to
- Configuration - Full network configuration reference
- Profiles - Per-profile network mode settings
-
Port Publishing - Reaching container services at
localhost:<port>without weakening isolation
Getting Started
Setup
Configuration & Usage
- Best Practices
- Configuration
- Profiles
- Supported Tools
- Container Lifecycle & Sessions
- Container Operations
- Snapshot Management
- File Transfer
- Port Publishing
- Tmux Automation
- Image Management
- Resource & Time Limits
Security
Maintenance
Help & Reference