--- title: "Jail Networking Strategy" --- This document defines the current networking model for Clawdie on FreeBSD. ## Current Host Network Typical host interfaces: - public uplink such as `vtnet0` - `tailscale0` if Tailscale is enabled on the host - `lo0` host loopback - `warden0` private bridge for Bastille jails ## Recommended Model Use one private Warden subnet on the host: - bridge: `warden0` - subnet: operator-configurable (`AGENT_SUBNET_BASE` / registry) - host gateway: `.1` Reserved low service slots: - `.2` `git` - `.3` `cms` - `.4` Local AI Models - `.5` optional `db` - `.6` `browser` Worker and automation ranges: - `.101+` workers - `.150+` ephemeral browser task clones ## Internal Naming Use `home.arpa` as the default internal namespace: - `AGENT_DOMAIN=home.arpa` for local DNS zones unless a real public domain is configured - `AGENT_INTERNAL_DOMAIN=.home.arpa` for the host FQDN - `ai.home.arpa` for the operator controlplane where that alias is configured - `cms.home.arpa` and `git.home.arpa` for shared admin surfaces - `.home.arpa` for additive tenant homes - `..home.arpa` for tenant sites Do not use `.local` as the default internal zone. It conflicts with mDNS behavior and makes deterministic local resolution harder. The platform DNS step renders `/usr/local/etc/dnsmasq.conf`, enables the `dnsmasq` rc.d service, and binds the local zone on both `127.0.0.1` and the Warden gateway address. That gives the host and jails the same resolver view for `home.arpa` names. ## PF Baseline Minimum useful PF example: ```pf ext_if = "vtnet0" warden_net = ".0/24" nat on $ext_if from $warden_net to any -> ($ext_if) pass quick on warden0 inet from $warden_net to any keep state ``` That is enough to let VNET jails reach package mirrors, Telegram, providers, and other outbound services. ## Exposure Model Clawdie no longer assumes host nginx ownership of every public surface. The intended web-serving path is: - `cms` serves nginx internally on the jailed subnet - public exposure happens through PF, an existing reverse proxy, or a direct jail IP - `docs.clawdie.si` can be fronted by host nginx or another edge proxy and forwarded to the `cms` jail This is the main reason the service jails keep fixed low addresses on the private Warden network. ## Tailscale Preferred order: 1. host-only Tailscale 2. optional subnet routing of your chosen Warden subnet (for example `192.168.72.0/24`) 3. only later, per-jail Tailscale if a specific jail truly needs its own identity Do not copy host resolver assumptions blindly into VNET jails. ## Validation The host should prove: - `warden0` exists - `warden0` has `.1/24` - forwarding is enabled - PF loads cleanly - VNET jails can reach the internet The host and jails should prove: - `ai.home.arpa` resolves locally - `cms.home.arpa` resolves locally - `git.home.arpa` resolves locally - tenant homes and sites such as `atlas.home.arpa` and `blog.atlas.home.arpa` resolve locally when enabled Use `just setup -- --step dns` to render and apply the dnsmasq zone. Use `just doctor` afterwards; it verifies dnsmasq service state, listener addresses, and every registered host through both loopback and gateway resolver probes.