Ports and the port guard¶
Host port map¶
| port | service |
|---|---|
| 3978 | teams gateway |
| 8730 | telegram transport |
| 8731 | top --web |
| 8732 | slack gateway |
| 8734 | auth broker |
| 8735 | web-view gateway |
| 8736 | web-view login proxy |
Per-agent bands¶
Every band is loopback-only and sits at base + uid − 1000, so an agent's ports are a pure
function of its uid and never move as other agents come and go.
| band | use |
|---|---|
| 9222+ | Chrome CDP |
| 12730+ | RETIRED (was Remotion Studio) |
| 18730+ | channel WS (telegram transport, or a cross-host connector's local WS) |
| 22730+ | KasmVNC (private display) |
| 28730+ | web-view WS |
Every band sits below the ephemeral range (32768+), so the kernel can never hand one out first.
The matching X display number is :100 + uid − 1000, clear of the shared :99 and of
:0–:10.
The bands are enforced¶
Every agentctl apply renders /etc/agentctl/nftables/agent-ports.nft from the same band
table the CLI uses, and reloads it with nft -f unconditionally. That installs
table inet agentctl on the output hook, dropping any packet to a guarded port whose
originating meta skuid does not own it. agentctl-portguard.service
(WantedBy=sysinit.target) loads it at boot, before anything binds.
| rule | detail |
|---|---|
| kasm band (22730+) | cross-uid allowance: uid 0, for agentctl-webview-gateway.service |
| web-view WS band (28730+) | cross-uid allowance: uid 0, for agentd fetching a workspace upload's bytes with ws write --pull |
| 9222+, 18730+ | owner-only, root included |
a missing /usr/sbin/nft |
fails the apply with exit 1; nftables is a hard package dependency |
apply --dry-run |
returns before the host-wide tail, so it never renders agent-ports.nft |
| rollback | systemctl disable --now agentctl-portguard.service, then leave it disabled |
The pre-flight nft -c -f /etc/agentctl/nftables/agent-ports.nft works only on a host that
has applied at least once.
To reach another agent's port by hand, use sudo -u <agent> curl …: setuid happens before the
socket is created, so the socket carries the agent's uid and matches the accept rule. A plain
root curl is dropped on every band except kasm and web-view WS.
The rollback's ExecStop deletes only table inet agentctl, never Azure's ip security or
Docker's ip nat / ip filter. Leave the unit disabled afterwards, because the next apply
re-asserts the guard.