Skip to content

Cover SSH certificates and existing SSH CAs [30m after #29] - #14

Closed
jpawlowski wants to merge 5 commits into
wintermeyer:mainfrom
jpawlowski:feat/ssh-certificates
Closed

jpawlowski wants to merge 5 commits into
wintermeyer:mainfrom
jpawlowski:feat/ssh-certificates

Conversation

@jpawlowski

@jpawlowski jpawlowski commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Gap: heinzel does not recognize SSH certificates or SSH CAs; details in #17.

Change: New rules/ssh-certificates.md: host and user certificates recorded separately; expiry, principals, revocation, CA keys on hosts; host CA trust on servers and the workstation; fleet-wide CA work; independent of the CA software. Its probes use the SSH configuration reading from #29. Audits and housekeeping check it. Guard: certificates beside a key are readable, losing the revocation list is denied.

Size: Four commits, one per part (guard, rule, audits, README). Includes #29's commit until it is merged. Merges cleanly with every other open PR (#27).

Verified: guard test matrix 564 passed, 0 failed. Against a local OpenSSH 10.3 sshd: failure messages, reload, key-ID revocation, ssh-keygen -F.

An AI agent wrote this text in my name. I know that is problematic.

Part of #27.
Closes #17.

@jpawlowski
jpawlowski marked this pull request as ready for review September 19, 2026 13:26
@jpawlowski

jpawlowski commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

Merge recommendation

The order of all open PRs is kept in one place now: #27. For #14 it says: after #29, in any order with every other PR; #31 follows #14.

Squash-merge #14 with the title Cover SSH certificates and existing SSH CAs (without the review bracket), and keep Closes #17. in the commit message. VERSION and CHANGELOG are left to you.

An AI agent wrote this text in my name. I know that is problematic.

The probes read sshd_config and sshd_config.d/*.conf under /etc/ssh.
Include can pull in any file (macOS reads /etc/ssh/crypto.conf), the
FreeBSD package and appliances use /usr/local/etc/ssh, and a daemon
started with -f reads another file entirely. And since OpenSSH 10.4,
sshd -T and sshd -G print directive names in mixed case
(PermitRootLogin), so a filter like grep '^permitrootlogin ' finds
nothing and the security and fleet audits read an empty config.

New rules/ssh-config.md:
- one sshd probe that takes a -f from the running daemon, tries
  sshd -G (OpenSSH 9.3+, no host keys needed) and falls back to
  sshd -T, and lists every file read (sshd -dd);
- the ssh -v -G client probe, per account that connects out;
- grep -i on every filter over that output.

The security audit's fallback and weak-algorithm check and the fleet
audit's sshd probe use grep -i. The security audit reports a server's
SSH client (StrictHostKeyChecking no, a /dev/null known-hosts file).
rules/<family>.md name sshd's unit, config directory, auth log,
checksum tool and job scheduler per OS. CLAUDE.md points to the rule.

Tested against a local sshd (OpenSSH 10.3) with an Include outside
sshd_config.d and a daemon started with -f. The mixed case of 10.4
is taken from the upstream commit (f6acdce690), not tested.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jpawlowski
jpawlowski force-pushed the feat/ssh-certificates branch from 26cb209 to 7930c6d Compare September 19, 2026 17:49
jpawlowski added a commit to jpawlowski/fork.wintermeyer_heinzel that referenced this pull request Sep 19, 2026
With a directory behind SSSD, everyone who can get a certificate and
resolves on a host could log in there. The rule now limits that in
three places, checked in the step-ca source and the SSSD and authentik
docs:
- The OIDC provisioner's groups and domains decide who gets a
  certificate.
- The principals come from token claims, and step-ca does not check
  email_verified, so the claim must not be editable by users.
- A principal equal to a local account name logs in as that account,
  and OIDC admins may request any principal and host certificates, so
  reserved names go into a deny policy.
- SSSD's access_provider defaults to permit and must name the
  allowed groups.

An offboarding note says how long access lasts after a person is
disabled. The security audit warns when every directory user may log
in, the fleet audit compares the SSSD access rule (filtered by key,
since sssd.conf holds the bind password), and section 7 uses the
privilege ladder wintermeyer#14 now runs once per host.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jpawlowski jpawlowski changed the title Cover SSH certificates and existing SSH CAs [30m after #13] Cover SSH certificates and existing SSH CAs [30m after #13, #29] Sep 19, 2026
@jpawlowski
jpawlowski force-pushed the feat/ssh-certificates branch from 7930c6d to 452960f Compare September 19, 2026 18:12
@jpawlowski jpawlowski changed the title Cover SSH certificates and existing SSH CAs [30m after #13, #29] Cover SSH certificates and existing SSH CAs [30m after #29] Sep 19, 2026
jpawlowski and others added 4 commits September 19, 2026 20:18
ssh-keygen -L on ssh_host_ed25519_key-cert.pub or id_ed25519-cert.pub
was denied as if it named the private key beside it, so heinzel
could not read a host or user certificate at all. KEYPRIV now lets
"-cert." pass; any other hyphen suffix (ssh_host_rsa_key-old,
id_ed25519-work) is still a private key.

Once sshd_config names a RevokedKeys file, a missing or unreadable
one makes sshd refuse every public key login, authorized_keys
included. The guard denies deleting, moving or re-permissioning it,
directly or through an interpreter. Writing it (ssh-keygen -k, cp,
an empty file) stays allowed, and so do the CA trust and principals
files: a mistake there affects certificate logins only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
heinzel did not recognize host certificates or user CAs, so hosts run
by an SSH CA were neither checked nor handled correctly.

New rules/ssh-certificates.md, independent of the CA software:
- host and user certificates detected (a quick probe on first
  connection, a full check with root) and recorded separately;
- host certificate validity, key match, principals, renewal and the
  sshd reload it needs; user CA fingerprints, principals that reach
  root, revocation, a CA signing key left on the host;
- heinzel's own login by certificate, including Windows workstations;
- the host CA a client trusts, on servers that connect out and on
  the workstation against each host's CA, [host]:port included;
- what "Certificate invalid:" means, and connecting a server to an
  existing CA and maintaining it, on one server and across all
  servers that trust it (revocation, offboarding, CA rotation).

CLAUDE.md points to it and treats sshd's revocation list like a key.
The unreachable, connection, activity, anomaly, secrets, OS
replacement and dual-boot rules point to it where certificates
matter.

Tested against a local sshd (OpenSSH 10.3): failure messages,
reload behaviour, revocation by key ID into an empty KRL, and
ssh-keygen -F for plain and bracketed names.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The security audit reports host and user certificates as separate
lines, with severities for validity, renewal, principals, revocation
and a CA signing key on the host. The fleet audit compares host
certificates, user CA fingerprints, revocation list checksums and the
host CA lines of each global known-hosts file across hosts.
Housekeeping checks host certificate expiry on Linux, macOS and
FreeBSD.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jpawlowski
jpawlowski force-pushed the feat/ssh-certificates branch from 452960f to 88c487e Compare September 19, 2026 18:22
@wintermeyer

Copy link
Copy Markdown
Owner

Thanks for the work on this. I'm closing it together with #17; the reason is in my note there.

An AI agent wrote this text in my name. I know that is problematic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Detect and handle SSH certificates and existing SSH CAs

2 participants