status+docs: map James's RSA key in the ledger; noroot drop-in is 10- not 60- (#910)
- ssh-operators.json: add James's ssh-rsa fingerprint (SHA256:M4/MRfio…); 25 historical sessions were showing as 'unknown key'. His ed25519 pair was already mapped. - instance-router.md + deploy/README.md: the PermitRootLogin-no drop-in is 10-lchat-noroot.conf, not 60- — sshd is first-match-wins and the box's existing 50-hardening.conf sets prohibit-password, so a 60- file never wins.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
3 files changed,
+11
−5
deploy/README.md+4 −3docs/instance-router.md+5 −1web/status/ssh-operators.json+2 −1
diff --git a/deploy/README.md b/deploy/README.md| index 746f8fc..a271d95 100644 |
| --- a/deploy/README.md |
| +++ b/deploy/README.md |
| @@ -14,9 +14,10 @@ ssh root@<box> '/opt/lchat/lchat add-instance chat.example.com' |
| # 3. operator setup — the last thing the root session does before retiring itself: |
| # create a named account per operator (groups lchat-operators + systemd-journal), |
| # install deploy/sudoers-operators -> /etc/sudoers.d/lchat-operators (0440) |
| -# and deploy/lchat-env-install -> /usr/local/sbin/ (0755), add each operator's |
| -# WireGuard peer, close public 22, and set PermitRootLogin no |
| -# (drop-in /etc/ssh/sshd_config.d/60-lchat-noroot.conf) |
| +# and deploy/lchat-env-install + deploy/lchat-svc -> /usr/local/sbin/ (0755), |
| +# add each operator's WireGuard peer, close public 22, and set |
| +# PermitRootLogin no (drop-in /etc/ssh/sshd_config.d/10-lchat-noroot.conf — |
| +# the 10- prefix wins sshd's first-match over the 50-hardening.conf default) |
| ``` |
| `lchat bootstrap` embeds the unit files (source `deploy/systemd/`) and writes |
diff --git a/docs/instance-router.md b/docs/instance-router.md| index 6b7d18b..449aef7 100644 |
| --- a/docs/instance-router.md |
| +++ b/docs/instance-router.md |
| @@ -630,7 +630,11 @@ else binds a unix socket and needs no capabilities (`CapabilityBoundingSet=`). |
| and the env-placement helper `deploy/lchat-env-install` at |
| `/usr/local/sbin/lchat-env-install` (mode `0755`), add the WireGuard peers — |
| and then disable root logins with a drop-in |
| - `/etc/ssh/sshd_config.d/60-lchat-noroot.conf` (`PermitRootLogin no`). |
| + `/etc/ssh/sshd_config.d/10-lchat-noroot.conf` (`PermitRootLogin no`). The |
| + `10-` prefix matters: sshd_config is first-match-wins, so the drop-in must |
| + sort *before* the box's `50-hardening.conf` (which sets |
| + `prohibit-password`) to take effect — confirm with `sshd -T | grep |
| + permitrootlogin` before trusting the flip. |
| Thereafter operators are named users over the tunnel; root capability exists |
| only through the allowlist, and anything new that needs root gets a line |
| added **via a reviewed PR + redeploy**, never a root shell or a hand-edit on |
diff --git a/web/status/ssh-operators.json b/web/status/ssh-operators.json| index 929b5c8..7679dea 100644 |
| --- a/web/status/ssh-operators.json |
| +++ b/web/status/ssh-operators.json |
| @@ -1,5 +1,6 @@ |
| { |
| "SHA256:5JUe8bzNg0hBATwv4cHOJJ0ZDQzaPWUqTWAs7qDwCyI": "Paul Campbell", |
| "SHA256:U4nJjkf9E6nFIfmMnGJyWMLZKO2K/K4vtIs/0BdxTKI": "James Adam", |
| - "SHA256:eVQy2zp7AHszs159VfsEAH4PiRj+Jc+BxXU0xL6tsVk": "James Adam" |
| + "SHA256:eVQy2zp7AHszs159VfsEAH4PiRj+Jc+BxXU0xL6tsVk": "James Adam", |
| + "SHA256:M4/MRfioKATx++fONz5goN4aDzRaXCViXY594lrydDQ": "James Adam" |
| } |