Offer the sshd fix the row says is missing, and count the kernel fixes it has - #15
Merged
Merged
Conversation
…s it has Two rows promised a change the tool then would not make. The ssh probe set Fix.Tool = "tui-ssh (planned)" as its first statement and never cleared it, so the detail screen credited a tool that does not exist yet for six keywords tui-secure sets itself, and the fix column read the same on any machine whose weaknesses happened to be graded by one rule and offered by another. MaxAuthTries was exactly that: the row warned above 6 while the table wanted 4, so a stock sshd at 6 -- the value OpenSSH ships -- was painted as a finding with nothing behind `a`. On a Fedora 41 container with a stock sshd, 0.2.1 offered three fixes for four weak rows and named tui-ssh; this offers four and names itself. The grading now lives in the SSHDKeys table next to Weak, so a keyword cannot be flagged by one and refused by the other, and a test drives both over a corpus of values to hold them to it. A keyword sshd did not report is `unknown` rather than `ok`: nobody read it, and the fix hint says `sshd -T` needs root instead of leaving an empty column. The kernel row had the same disagreement with its own picker. It counted every key below the recommended value, including net.ipv4.ip_forward, which is reported and deliberately never offered -- so it read "4 keys" over a picker holding three. Both backends now grade through one GradeHardening, whose summary counts the fixes it returns and says the advisory key in a clause of its own. Validated on a throwaway Fedora 41 systemd container against a real sshd: MaxAuthTries 6 -> 4 through the staged file, `sshd -t -f`, the install and the reload, with the row flipping afterwards. The two tests that drive it are skipped unless TUI_SECURE_ROOT_LAB=1 and the process is root. The same run showed why the shadow warning exists: 50-redhat.conf sets X11Forwarding and sorts first, so the drop-in this tool writes is read and ignored -- the dialog already says so, and the README now says it too. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MCypLQF5AD8JD831Ea9S9q
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two rows promised a change the tool then would not make. Both were found on
camera and reproduced on a real machine.
The ssh probe only viewed
probeSSHsetFix.Tool = "tui-ssh (planned)"as its first statement andnever cleared it, so the detail screen credited a tool that does not exist yet
for the six keywords tui-secure sets itself. The fix column showed the same
whenever the actions came out empty, and they came out empty more often than
they should have: the row was graded by one rule and offered by another.
MaxAuthTriesis the clearest case — the probe warned above 6 whileSSHDKeyswanted 4, so a stock sshd at 6, the value OpenSSH ships, waspainted as a finding with nothing behind
a.Grading now lives in the
SSHDKeystable next toWeak, so a keyword cannotbe flagged by one half and refused by the other, and
TestSSHDGradeMatchesWeakdrives both over a corpus of values to hold them to it. A keyword sshd did not
report is
unknownrather thanok— nobody read it — and the hint sayssshd -Tneeds root instead of leaving an empty fix column.On a Fedora 41 container with a stock sshd:
Four weak rows, four fixes, and the tool names itself.
The kernel row counted what it would not fix
It said "4 hardening key(s) below the recommended value" over a picker holding
three, because
net.ipv4.ip_forwardis graded and deliberately never offered.Both backends now grade through one
GradeHardening, whose summary counts thefixes it returns and puts the advisory key in a clause of its own:
A key nobody could read counts as neither.
Validated
make lint,go test ./...,test/smoke.sh(26 passed).--demoparity: the sample sshd now offersSet PasswordAuthentication to noandSet MaxAuthTries to 4, and applying both turns the row green. Thedemo's sshd state is an overlay rather than one hard-coded field, so every
keyword moves in
--demoas it would on a machine.MaxAuthTries6 → 4 through the staged file,
sshd -t -f, theinstalland the reload,with the probe flipping afterwards.
TestRealAppliesTheSSHDChangeandTestRealNamesTheDropInThatShadowsItdrive it; both skip unlessTUI_SECURE_ROOT_LAB=1and the process is root, so CI never runs them.50-redhat.confsetsX11Forwardingand sorts before50-tui-secure.conf,so the file this tool writes is read and ignored. The dialog already said so;
the README now says it too.
The demo router VM was not reachable while this was written (the lab
hypervisor is down), which is why the container stands in for it.
🤖 Generated with Claude Code
https://claude.ai/code/session_01MCypLQF5AD8JD831Ea9S9q