feat(firecracker): NAT'd egress link for the orchestrator/builder VM
The orchestrator/gateway VM is trusted infra, not an isolated agent: it builds agent images in-VM (buildah must FROM-pull + apt/npm) and, in the Stage B cutover, forwards agent egress upstream. Give it a dedicated TAP (`bborch0`) on a /31 at the top of the IP_BASE /16 (clear of the bbfc* agent pool at the bottom), NAT'd out the host uplink — while agent VMs keep their fail-closed, gateway-only isolation table. - netpool.defaults.env / netpool.py: new BOT_BOTTLE_FC_ORCH_IFACE + `orch_slot()` (index -1 sentinel; host x.y.255.0 / guest x.y.255.1). - scripts/firecracker-netpool.sh: create + address the orchestrator TAP; `bot_bottle_fc_nat` table masquerades its /31 out the uplink and accepts its forward path. Because bootstrap still runs Docker (whose FORWARD policy is DROP), a best-effort, guarded, idempotent DOCKER-USER ACCEPT is added too (skipped once Docker is gone). down/status updated. - nix/firecracker-netpool.nix: mirror the option, pass it via the unit Environment= (the store-copied script can't read the defaults file), and add iptables to the unit path for the DOCKER-USER step. Agent isolation is unchanged: the new rules only ever accept/masquerade the orchestrator link and never drop, so they can't weaken the bbfc* drops. Applied by re-running `sudo ./scripts/firecracker-netpool.sh up`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
This commit is contained in:
@@ -64,6 +64,21 @@ class TestNetpoolProbes(unittest.TestCase):
|
||||
patch.object(netpool, "tap_present", side_effect=[True, False]):
|
||||
self.assertEqual(["bbfc1"], netpool.missing_taps())
|
||||
|
||||
def test_orch_slot_is_top_of_ip_base_16(self):
|
||||
# Dedicated orchestrator link: /31 at the top of the IP_BASE /16,
|
||||
# clear of the pool (bottom of the block). Must match the shell
|
||||
# script's orch_host()/orch_guest() and be a non-pool index.
|
||||
with patch.dict("os.environ", {"BOT_BOTTLE_FC_IP_BASE": "10.243.0.0"}):
|
||||
s = netpool.orch_slot()
|
||||
self.assertEqual(netpool.ORCH_IFACE, s.iface)
|
||||
self.assertEqual("10.243.255.0", s.host_ip)
|
||||
self.assertEqual("10.243.255.1", s.guest_ip)
|
||||
self.assertEqual(-1, s.index)
|
||||
# Never collides with a pool slot's guest address.
|
||||
with patch.dict("os.environ", {"BOT_BOTTLE_FC_IP_BASE": "10.243.0.0"}):
|
||||
pool_guests = {sl.guest_ip for sl in netpool.all_slots()}
|
||||
self.assertNotIn(s.guest_ip, pool_guests)
|
||||
|
||||
|
||||
class TestConsoleTail(unittest.TestCase):
|
||||
def test_reads_tail(self):
|
||||
|
||||
Reference in New Issue
Block a user