Files
opencode-devbox/scripts
joakimp 668592da0d
Validate / docs-check (push) Successful in 9s
Validate / base-change-warning (push) Successful in 11s
Validate / validate-with-pi (push) Failing after 4m6s
Validate / validate-omos (push) Failing after 4m31s
Validate / validate-omos-with-pi (push) Failing after 4m52s
Validate / validate-base (push) Failing after 13m20s
Base: SSH ControlMaster default on a writable socket path
Devboxes typically mount ~/.ssh from the host read-only (security: keys
readable, but agents can't tamper with config / known_hosts /
authorized_keys / plant a malicious ProxyCommand). OpenSSH's default
ControlPath is ~/.ssh/cm/... which is unwritable on such mounts, so
any attempt to multiplex fails with:

  unix_listener: cannot bind to path .../cm/...: Read-only file system
  kex_exchange_identification: Connection closed by remote host

The second line is downstream — when ControlMaster fails, ssh falls
back to fresh TCP connections, and on residential CGNAT (most European
ISPs) the per-(src,dst) concurrent-flow cap (~4) silently drops further
SYNs once exceeded, manifesting as banner-exchange timeouts that look
like a remote problem.

Fix: bake /etc/ssh/ssh_config.d/00-devbox-controlmaster.conf in the
base image with Host * defaults — ControlPath rooted at /tmp/sshcm/
(per-container, always writable), ControlMaster auto, ControlPersist
10m, ServerAlive{Interval=30,CountMax=6}. Companion entrypoint-user.sh
creates /tmp/sshcm mode 700 on each container start (/tmp is
per-container so the dir can't be baked into a layer; mode 700 is
required by OpenSSH for ControlPath dirs). Debian's stock ssh_config
sources ssh_config.d/*.conf before its own Host * block, so user
~/.ssh/config overrides still win.

Two smoke assertions catch regressions: (a) the conf file exists, (b)
ssh -G reports a controlpath rooted at /tmp/sshcm/ — second one catches
the silent case where something later in the config chain shadows the
bake-in.

Discovered while running a recon shell from inside pi-devbox to a
Proxmox node — fresh ssh hit banner-exchange timeout, debug output
pointed at the read-only socket dir as the actual root cause.

Cascades to all variants and to pi-devbox automatically on next build
against base-latest. No size/threshold impact (~250-byte conf file).
2026-05-24 19:51:38 +00:00
..