Skip to content

Commit fb06747

Browse files
author
docs-bot
committed
docs: update from source@c4129eb
1 parent 5e74fa1 commit fb06747

4 files changed

Lines changed: 117 additions & 7 deletions

File tree

docs/features.html

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,14 +415,16 @@ <h3 id="what-are-namespaces">What Are Namespaces?</h3>
415415
</tbody>
416416
</table></div>
417417
<h3 id="network-namespace-isolation-net">Network Namespace Isolation (<code>--net</code>)</h3>
418-
<p>Droidspaces supports three networking modes that determine whether a network namespace (<code>CLONE_NEWNET</code>) is used:</p>
418+
<p>Droidspaces supports four networking modes that determine whether a network namespace (<code>CLONE_NEWNET</code>) is used:</p>
419419
<ol>
420420
<li><strong>Host Mode (<code>--net=host</code>) - Default</strong>: Droidspaces deliberately does <strong>not</strong> unshare the network namespace. The container shares the host's network stack. This greatly simplifies setup: containers get internet access immediately without virtual bridges, NAT, or firewall rules. On Android, where networking is already complex (cellular, Wi-Fi, VPN), this avoids a whole category of connectivity issues.
421421
</li>
422-
<li><strong>NAT Mode (<code>--net=nat</code>)</strong>: The container is placed in a private network namespace. It is connected to the host via a virtual bridge or veth pair, providing <strong>Pure Network Isolation</strong> while maintaining internet access through the host's active internet uplink, which is detected automatically. Compatible with the vast majority of Android devices.
422+
<li><strong>NAT Mode (<code>--net=nat</code>)</strong>: The container is placed in a private network namespace. It is connected to the host via a virtual bridge or veth pair, providing <strong>Pure Network Isolation</strong> while maintaining internet access through the host's active internet uplink, which is detected automatically (or pinned manually with <code>--upstream</code>, see below). Compatible with the vast majority of Android devices.
423423
</li>
424424
<li><strong>None Mode (<code>--net=none</code>)</strong>: The container is placed in a private, air-gapped network namespace with only the loopback interface enabled for maximum security.
425425
</li>
426+
<li><strong>Gateway Mode (<code>--net=gateway</code>)</strong>: The container's LAN is delegated to <em>another</em> running container (typically OpenWRT). Droidspaces does only the L2 plumbing (bridge + veth pairs) and lets the gateway container own all policy - DHCP, DNS, firewall, routing, VPN. Ideal for VPN killswitches, segmented LANs, and traffic analysis. See the dedicated <a href="networking-from-zero.html" rel="noopener noreferrer">Networking From Zero</a> guide for the full deep dive.
427+
</li>
426428
</ol>
427429
<h3 id="how-it-compares-to-chroot">How It Compares to Chroot</h3>
428430
<p>A <code>chroot</code> only changes the apparent root directory for a process. It provides no process isolation, no mount isolation, no hostname isolation, and no IPC isolation. Any process inside a chroot shares the host's PID space, can see and signal other processes, and cannot run an init system like systemd.</p>
@@ -601,15 +603,17 @@ <h3 id="soft-fail-model">Soft-Fail Model</h3>
601603
<h3 id="security">Security</h3>
602604
<p>Droidspaces validates bind mount targets with two protections: 1. <strong>Pre-mount:</strong> Uses <code>lstat()</code> to ensure the target inside the rootfs is not a symlink 2. <strong>Post-mount:</strong> Uses <code>realpath()</code> via the <code>is_subpath()</code> helper to verify the mounted path cannot escape the container root</p>
603605
<hr>
604-
<h2 id="network-isolation-3-modes">Network Isolation (3 Modes)</h2>
605-
<p>Droidspaces provides three distinct networking modes to balance ease-of-use with advanced isolation.</p>
606+
<h2 id="network-isolation-4-modes">Network Isolation (4 Modes)</h2>
607+
<p>Droidspaces provides four distinct networking modes to balance ease-of-use with advanced isolation.</p>
606608
<h3 id="1-host-mode-nethost-default">1. Host Mode (<code>--net=host</code>) - Default</h3>
607609
<p>The container shares the host's network namespace. - <strong>Pros</strong>: Zero configuration, instant internet access, works with all Android VPNs/hotspots. - <strong>Cons</strong>: No port isolation; services inside the container bind to host ports directly.</p>
608610
<h3 id="2-nat-mode-netnat">2. NAT Mode (<code>--net=nat</code>)</h3>
609611
<p>The container is placed in a private network namespace (<code>CLONE_NEWNET</code>) and connected to the host via a virtual bridge (<code>ds-br0</code>) or a direct veth pair. - <strong>Deterministic IP</strong>: Each container is assigned a unique IP in the <code>172.28.0.0/16</code> range, derived from its PID. - <strong>Embedded DHCP</strong>: Droidspaces includes a minimal, built-in DHCP server to automatically configure the container's <code>eth0</code>. - <strong>Pure Isolation</strong>: The container cannot see or interact with the host's network interfaces directly. - <strong>Automatic Uplink Detection</strong>: No configuration needed. Droidspaces reads the kernel's own ground truth to find the interface that provides internet access - on Android, the policy-routing rule netd installs for the active default network; on standard Linux, the main routing table's default route. CLAT (464xlat) interfaces on IPv6-only mobile networks are handled automatically.</p>
610612
<div class="callout callout-important"><strong class="callout-title">IMPORTANT</strong> NAT mode is <strong>IPv4 only</strong>. If the host's uplink lacks an IPv4 address (IPv6-only network), internet access will not work. See <a href="troubleshooting.html#ipv4-quirks" rel="noopener noreferrer">IPv4 NAT Quirks</a> for a workaround.</div>
611613
<h3 id="3-none-mode-netnone">3. None Mode (<code>--net=none</code>)</h3>
612614
<p>The container gets a private network namespace with only the loopback (<code>lo</code>) interface enabled. - <strong>Use Case</strong>: Maximum security for offline tasks.</p>
615+
<h3 id="4-gateway-mode-netgateway">4. Gateway Mode (<code>--net=gateway</code>)</h3>
616+
<p>The container is placed on an isolated L2 bridge whose <strong>policy is owned by another running container</strong> (typically OpenWRT) instead of by Droidspaces. Droidspaces does only the plumbing - it creates the bridge and the veth pairs and moves them into place; the gateway container provides DHCP, DNS, firewall, routing and VPN. - <strong>Required flag</strong>: <code>--gateway=NAME</code> names the running container that acts as the router. - <strong>Segments</strong>: <code>--gateway-net=NAME</code> (default <code>lan</code>) selects which bridge/segment the client lands on. Multiple clients sharing a <code>--gateway-net</code> share a LAN; different <code>--gateway-net</code> values are isolated segments through the same gateway. - <strong>Interface naming</strong>: <code>--gateway-iface=IFACE</code> (default <code>eth1</code>) controls what the LAN interface is called <em>inside</em> the gateway container, so it matches the gateway's own config. - <strong>Self-healing</strong>: wiring is driven entirely from the host side, so clients are (re)wired automatically when the gateway container starts or reboots - no client restart needed. - <strong>Use Cases</strong>: VPN killswitch for selected containers, VLAN-style segmented LANs, single-chokepoint traffic analysis, gateway-wide DNS filtering. See <a href="networking-from-zero.html" rel="noopener noreferrer">Networking From Zero</a> for the complete walkthrough.</p>
613617
<h3 id="port-forwarding-nat-mode">Port Forwarding (NAT Mode)</h3>
614618
<p>In NAT mode, you can expose container services to the host or local network using the <code>--port</code> flag. Supported formats:</p>
615619
<div class="code-block"><button class="copy-btn" onclick="copyCode(this)"><i class="fa-regular fa-copy"></i> Copy</button><pre><code># Forward host port 8080 to container port 80
@@ -626,7 +630,28 @@ <h3 id="port-forwarding-nat-mode">Port Forwarding (NAT Mode)</h3>
626630
</code></pre></div>
627631
<p>Forwarded ports are reachable from any network the host belongs to - including clients connected to the phone's own hotspot or USB tethering on Android.</p>
628632
<h3 id="real-time-uplink-monitoring">Real-Time Uplink Monitoring</h3>
629-
<p>On Android, the connection often hops between Wi-Fi and Mobile Data. Droidspaces includes a <strong>Route Monitor</strong> that subscribes to kernel routing events (FIB rules, routes, links, addresses). The moment Android switches its default network (e.g., you walk out of Wi-Fi range), the monitor updates the kernel's policy routing to keep the container connected - no configuration, no restart.</p>
633+
<p>On Android, the connection often hops between Wi-Fi and Mobile Data. Droidspaces includes a <strong>Route Monitor</strong> that subscribes to kernel routing events (FIB rules, routes, links, addresses). The moment Android switches its default network (e.g., you walk out of Wi-Fi range), the monitor updates the kernel's policy routing to keep the container connected - no configuration, no restart. The same monitor works on desktop Linux (e.g. a Wi-Fi to ethernet handoff), where it follows the main routing table's default route.</p>
634+
<h3 id="manual-uplink-pinning-upstream">Manual Uplink Pinning (<code>--upstream</code>)</h3>
635+
<p>By default the uplink is fully automatic. When you want the container's WAN to <strong>ignore the host's active network</strong> and go out through a specific interface instead, pin it with <code>--upstream</code>. This switches auto-detection off entirely - the listed interface(s) become the <em>only</em> WAN candidates.</p>
636+
<div class="code-block"><button class="copy-btn" onclick="copyCode(this)"><i class="fa-regular fa-copy"></i> Copy</button><pre><code># Single interface
637+
--upstream=wlan0
638+
639+
# Priority-ordered list with wildcards (comma-separated)
640+
--upstream=wlan0,rmnet*
641+
</code></pre></div>
642+
<ul>
643+
<li><strong>Authoritative, not a fallback</strong>: traffic never hops to whatever <code>netd</code> marks active - only to interfaces you listed.
644+
</li>
645+
<li>**Priority failover <em>within</em> the list**: the Route Monitor re-resolves on every link/route change and uses the first listed interface that is up and has internet. <code>wlan0,rmnet*</code> prefers Wi-Fi and falls back to mobile data, then back to Wi-Fi when it returns.
646+
</li>
647+
<li><strong>Literals and wildcards</strong> (<code>*</code>, <code>?</code>): use <code>rmnet*</code> for mobile data, whose interface number is not stable across reconnects.
648+
</li>
649+
<li><strong>Disappear/reappear</strong> mid-session is handled: no WAN until a pinned interface is up, then it wires automatically.
650+
</li>
651+
<li><strong>Use cases</strong>: pin <code>tun0</code> to route the container exclusively through a phone-side VPN (a free killswitch), or pin <code>rmnet*</code> (with "Mobile data always active") to keep the container on cellular while the phone stays on Wi-Fi.
652+
</li>
653+
</ul>
654+
<blockquote><p><code>--upstream</code> is only valid with <code>--net=nat</code>; it is ignored (with a warning) in other modes.</p></blockquote>
630655
<hr>
631656
<h2 id="rootfs-image-support">Rootfs Image Support</h2>
632657
<h3 id="why-use-images">Why Use Images?</h3>

docs/linux-cli.html

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,12 +479,26 @@ <h3 id="networking">Networking</h3>
479479
<tr><th>Option</th><th>Short</th><th>Description</th></tr>
480480
</thead>
481481
<tbody>
482-
<tr><td><code>--net=MODE</code></td><td></td><td>Networking mode: <code>host</code> (default), <code>nat</code>, or <code>none</code>.</td></tr>
482+
<tr><td><code>--net=MODE</code></td><td></td><td>Networking mode: <code>host</code> (default), <code>nat</code>, <code>none</code>, or <code>gateway</code>.</td></tr>
483+
<tr><td><code>--upstream=IFACE</code></td><td></td><td>Pin the NAT WAN to specific interface(s); disables automatic uplink detection. Comma-separated, priority-ordered, supports wildcards. Example: <code>--upstream=wlan0,rmnet*</code>. NAT mode only.</td></tr>
483484
<tr><td><code>--port HOST:CONT[/proto]</code></td><td></td><td>Forward host port to container (NAT mode). Supports TCP/UDP.</td></tr>
484485
<tr><td><code>--dns=SERVERS</code></td><td><code>-d</code></td><td>Custom DNS servers, comma-separated. Example: <code>--dns=1.1.1.1,8.8.8.8</code></td></tr>
485486
<tr><td><code>--disable-ipv6</code></td><td></td><td>Disable IPv6 networking support (Host mode only).</td></tr>
486487
</tbody>
487488
</table></div>
489+
<h4 id="gateway-mode">Gateway Mode</h4>
490+
<p>Delegate a container's LAN to another running container (e.g. OpenWRT), which then owns DHCP, DNS, firewall and routing. Droidspaces only does the L2 plumbing. See <a href="networking-from-zero.html" rel="noopener noreferrer">Networking From Zero</a> for the full guide.</p>
491+
<div class="table-wrap"><table>
492+
<thead>
493+
<tr><th>Option</th><th>Short</th><th>Description</th></tr>
494+
</thead>
495+
<tbody>
496+
<tr><td><code>--gateway=NAME</code></td><td></td><td><strong>Required</strong> for <code>--net=gateway</code>. The running container that acts as the router.</td></tr>
497+
<tr><td><code>--gateway-net=NAME</code></td><td></td><td>LAN segment name / host bridge suffix (default: <code>lan</code>). Clients sharing a value share a LAN; different values are isolated segments.</td></tr>
498+
<tr><td><code>--gateway-iface=IFACE</code></td><td></td><td>Interface name as seen <em>inside</em> the gateway container (default: <code>eth1</code>). Each segment needs a unique name.</td></tr>
499+
<tr><td><code>--gateway-bridge=BR</code></td><td></td><td>Override the host bridge name (default: <code>ds-{gateway-net}</code>).</td></tr>
500+
</tbody>
501+
</table></div>
488502
<h3 id="feature-flags">Feature Flags</h3>
489503
<div class="table-wrap"><table>
490504
<thead>
@@ -596,6 +610,23 @@ <h3 id="nat-isolation-with-port-forwarding">NAT Isolation with Port Forwarding</
596610
--port=8080:80 \
597611
start
598612
</code></pre></div>
613+
<h3 id="nat-with-a-pinned-uplink">NAT with a Pinned Uplink</h3>
614+
<p>Force the container's internet out through a specific interface instead of following the host's active network. Pin a VPN tunnel (<code>tun0</code>) as a killswitch, or <code>rmnet*</code> to stay on mobile data while the phone uses Wi-Fi:</p>
615+
<div class="code-block"><button class="copy-btn" onclick="copyCode(this)"><i class="fa-regular fa-copy"></i> Copy</button><pre><code>sudo droidspaces \
616+
--name=vpnbox \
617+
--rootfs-img=/path/to/rootfs.img \
618+
--net=nat \
619+
--upstream=tun0 \
620+
start
621+
</code></pre></div>
622+
<h3 id="gateway-mode-lan-owned-by-openwrt">Gateway Mode (LAN owned by OpenWRT)</h3>
623+
<p>Start the router container first (in NAT mode), then attach clients to it:</p>
624+
<div class="code-block"><button class="copy-btn" onclick="copyCode(this)"><i class="fa-regular fa-copy"></i> Copy</button><pre><code># 1. the router
625+
sudo droidspaces --name=openwrt --rootfs=/data/openwrt --net=nat start
626+
627+
# 2. a client whose LAN/DHCP/firewall is owned by openwrt
628+
sudo droidspaces --name=kali --rootfs=/data/kali --net=gateway --gateway=openwrt start
629+
</code></pre></div>
599630
<h3 id="ephemeral-testing">Ephemeral Testing</h3>
600631
<div class="code-block"><button class="copy-btn" onclick="copyCode(this)"><i class="fa-regular fa-copy"></i> Copy</button><pre><code>sudo droidspaces --name=test --rootfs=/path/to/rootfs --volatile start
601632
</code></pre></div>

0 commit comments

Comments
 (0)