Key Auth Broken After a CIS Hardening Window
A Rocky Linux 9 host runs OpenSSH 8.7 with SELinux enforcing and firewalld. After a CIS hardening role ran, key-based login for deploy stopped working: ssh -v deploy@host shows the key being offered and then Permission denied (publickey,gssapi-keyex,gssapi-with-mic). The sre account on the same host still logs in with its key. Between the two change windows /home was restored from a tar archive created on a non-SELinux Ubuntu host. The hardening role also rewrote /etc/ssh/sshd_config, appending its own block that contains a second PubkeyAuthentication no line, while an earlier PubkeyAuthentication yes remains near the top. sshd -t reports no syntax errors, and the operator ran systemctl reload sshd, not a restart. Logging is at the default LogLevel INFO.
1. Rank the plausible causes and say which one you would investigate first and why.
Read the worked answer
The duplicate directive is the most eye-catching clue and the least likely cause. sshd_config uses first-obtained-value semantics - unlike most config files - so the first PubkeyAuthentication yes wins and the appended no is inert. And because sre still authenticates by key, pubkey auth is clearly working globally, which rules it out entirely as the root cause.
That the failure is per-account points at the deploy account's files or labels:
- SELinux label damage from the tar restore. A tar archive without
-xattr/--selinuxproduces files labelled by the destination default, so sshd cannot readauthorized_keys. - Ownership/permission drift - sshd's StrictModes refuses group/world-writable homes, and refuses keys whose owner is not the target user or root.
- An
AllowUsers/AllowGroups/Matchclause added by the role that excludesdeploy.
Investigate with evidence, cheapest first:
sshd -T | grep -Ei 'pubkey|allowusers|allowgroups|strictmodes'
namei -l /home/deploy/.ssh/authorized_keys
ls -Zd /home/deploy /home/deploy/.ssh /home/deploy/.ssh/authorized_keys
getsebool -a | grep ssh
ausearch -m AVC,USER_AVC -ts today | grep -i sshd
sshd -T is the only reliable way to read effective config; reading the file only tells you what was typed. The AVC search settles the SELinux question rather than guessing.
2. Assuming the tar restore is the cause, give the repair, and the safe way to clean up the configuration while you are in there.
Read the worked answer
Repair the labels rather than disabling enforcement:
restorecon -Rv /home/deploy # .ssh gets ssh_home_t from the shipped policy
ls -Zd /home/deploy/.ssh/authorized_keys
If a location is non-standard and restorecon cannot classify it, use semanage fcontext -a -t ssh_home_t '/path(/.*)?' followed by restorecon -Rv /path - persistent, unlike chcon.
Do not touch setenforce 0 to test this. If you want to test, use ausearch to prove the denial exists first; and remember a permissive test clears the denial from the way you would notice it later.
Then fix permissions, which the restore may also have changed:
chown -R deploy:deploy /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys
For the config: delete the duplicate PubkeyAuthentication line rather than trusting ordering, keep local changes in a single /etc/ssh/sshd_config.d/*.conf drop-in that sorts before the main file's own settings (drop-ins are included at the top on RHEL, and again first-wins applies), then validate and reload:
sshd -t && systemctl reload sshd && sshd -T | grep -i pubkey
Also verify no % or shell metacharacters were introduced into any Match block, and that any new Match sits at the end of the file - everything after it inherits its conditions.