diff --git a/go/internal/runtime/microvm/boot_microvm_test.go b/go/internal/runtime/microvm/boot_microvm_test.go index 4fba5b181..e334c4b45 100644 --- a/go/internal/runtime/microvm/boot_microvm_test.go +++ b/go/internal/runtime/microvm/boot_microvm_test.go @@ -24,6 +24,9 @@ import ( "testing" "time" + "connectrpc.com/connect" + + compassv1 "github.com/RigelBuild/compass/go/internal/gen/compass/v1" "github.com/RigelBuild/compass/go/internal/microvmtest" ) @@ -182,6 +185,88 @@ func TestFullBoot(t *testing.T) { } } +// armRuleset is a minimal but representative in-guest egress arm: it creates the +// inet table + a conntrack-stateful output rule, forcing a representative slice +// of the netfilter autoload chain — the NETLINK_NETFILTER socket (nfnetlink), +// the nf_tables subsystem, and the `ct state` expression (nf_conntrack + +// nft_ct). Once the usermode helper is staged, request_module resolves ANY +// module from the full /lib/modules tree, so this slice proves the mechanism the +// real base ruleset relies on (its interval sets and DNS rules pull further +// modules the same way). It is `set -eu` so any nft failing aborts non-zero, +// like EgressPolicy.NftScript()'s base ruleset. Kept as a local literal, not a +// runtime.EgressPolicy call, because this package must not import +// internal/runtime (config.go: no runtime dep, no cycle). +const armRuleset = `set -eu +nft add table inet compass_egress +nft add chain inet compass_egress output '{ type filter hook output priority 0 ; policy drop ; }' +nft add rule inet compass_egress output ct state established,related accept` + +// TestInGuestEgressArmAutoloadsNetfilter is the RIG-3028 proof: on a real guest +// boot, Provision with a NON-EMPTY nft_script (the §(d) in-guest arm W1 landed) +// must succeed. The arm runs `/bin/sh -c