Correct the SSH note: the :2222 connect is intermittently refused, not blocked

The earlier note blamed git-over-HTTP on Local Network privacy and used a
url.insteadOf workaround. The real finding: HTTP genuinely does not
work for git (per-binary entitlement - curl reaches it), while SSH on
2222 works but the connect is intermittently refused with 'Undefined
error: 0'. The Host mini-eq ssh block now sets BatchMode, ConnectTimeout
and ConnectionAttempts 5, so ssh retries the refused connect; plain
git-over-ssh is 5/5 reliable and needs no GIT_SSH_COMMAND.

Also recorded both pinned Mini-EQ host keys - :22 and :2222 keep separate
keys - and that ssh-keyscan without -p 2222 scans the wrong port.
This commit is contained in:
B.D. Murphy
2026-11-06 18:00:16 -08:00
parent b53a868d04
commit 6bb69729b9

View File

@@ -416,16 +416,35 @@ Each pass has quality gates. Quality is the primary concern; generation speed is
- **Mini-EQ addressing quirk**: `mini-eq` resolves to **192.168.123.138**, and the server is
also reachable at **192.168.123.18** — verified the *same* machine (identical Gitea, SSH
banner, ED25519 host key). Both forms are in `known_hosts`.
- **⚠ `git` over HTTP to Mini-EQ is blocked by macOS Local Network privacy (TCC), but SSH
works.** `git push minieq main` fails instantly with *"Immediate connect fail for
192.168.123.18: No route to host"* — while `curl http://192.168.123.18:3001/api/v1/version`
returns **200** from the same shell. It is **per-binary**: `/usr/bin/git` lacks the Local
Network entitlement, `curl` has it. The symptom is misleading because `nc -z` also reports
the port **open**. Fix in place (repo-local `.git/config`, already applied):
`git config url."ssh://git@mini-eq:2222/umbragit/".insteadOf "http://192.168.123.18:3001/umbragit/"`
— the HTTP remote URL is unchanged and now transparently rides SSH. Use
`GIT_SSH_COMMAND="ssh -o BatchMode=yes -o ConnectTimeout=10"` for the push itself; without
it git's bundled ssh got *"Undefined error: 0"* on connect (also TCC-shaped).
- **The Git server is SSH on port 2222.** The remote is now
`minieq` → `ssh://git@mini-eq:2222/umbragit/UmbraAudio.git`. The `Host mini-eq`
block in `~/.ssh/config` carries `Port 2222`, `User umbragit`,
`IdentityFile ~/.ssh/id_ed25519`, `IdentitiesOnly yes`.
- **⚠ The connect to :2222 is INTERMITTENTLY refused** with
`ssh: connect to host mini-eq port 2222: Undefined error: 0` — a macOS
Local-Network-privacy-shaped refusal, not a key or auth problem. It comes and
goes: the same command line succeeds on one run and fails on the next, and
`git push` fails on the first attempt while a retry succeeds. **Fix in place:**
the `Host mini-eq` block now has `BatchMode yes`, `ConnectTimeout 10` and
**`ConnectionAttempts 5`**, so ssh retries the refused connect instead of
failing the whole push. With that, plain `git ls-remote` / `git fetch` /
`git push` over SSH is 5/5 reliable and **no `GIT_SSH_COMMAND` is needed**
(an earlier workaround set one; it is unnecessary now). Config backup:
`~/.ssh/config.bak.20261106_175458`.
- **Git over HTTP to Mini-EQ does not work on this machine.** `git push` to
`http://192.168.123.18:3001/...` fails instantly with *"Immediate connect fail
for 192.168.123.18: No route to host"* — while `curl http://192.168.123.18:3001/api/v1/version`
returns **200** from the same shell. It is **per-binary**: `/usr/bin/git` lacks
the Local Network entitlement, `curl` has it. The symptom is misleading because
`nc -z` also reports the port **open**. Use SSH, not HTTP.
- **Two different host keys for Mini-EQ — both pinned, both verified.** The
system sshd on **:22** and Gitea's SSH server on **:2222** keep separate keys,
and `known_hosts` stores them separately (`mini-eq` vs `[mini-eq]:2222`):
- `:2222` ED25519 `SHA256:SErbWxiAY00aiE2SxzopWjcMKZZuRAh77hAnRzMt/Ls`
- `:22` ED25519 `SHA256:15DnUT1iUbbMSLofyggPPXDe4TvJ68CG8cCABXofvvo`
`ssh-keyscan` of the live server matched both pinned values — **no key drift**.
Note `ssh-keyscan HOST` scans port 22; use `ssh-keyscan -p 2222 HOST` for
Gitea, or you will "discover" the :22 key and think it changed.
- **The remote `main` can move without the local branch.** A push was rejected *"fetch first"*
because the remote had a commit (the Apache-2.0 LICENSE/SPDX headers) that the local branch
did not — **fetch before assuming the local history is the whole story**, and merge rather