SSH cipher strength
high on-server
What it inspects
The ciphers, macs and kexalgorithms lines of `sshd -T` output. The check fails if any of these are offered: 3des-cbc, blowfish-cbc, cast128-cbc, arcfour*, aes*-cbc; hmac-md5*, hmac-sha1, hmac-sha1-96, umac-64 variants; diffie-hellman-group1-sha1, group14-sha1 or group-exchange-sha1. Note that stock OpenSSH defaults often still offer hmac-sha1 and umac-64 for compatibility.
Why it matters
Older algorithms are kept for compatibility with ancient clients, but CBC ciphers, SHA-1 based MACs and SHA-1 key exchange have known weaknesses and are retired in modern guidance. Restricting sshd to current algorithms costs nothing for up-to-date clients. Very old SSH clients and embedded devices may no longer connect, which is why you should test a second session first.
How to verify
sudo sshd -T | grep -iE '^(ciphers|macs|kexalgorithms) '
How to fix
Debian/Ubuntu: remove the flagged algorithms from the defaults in a 00- drop-in (keeping the rest, including post-quantum key exchange), validate, and reload. RHEL family: algorithms come from the system crypto-policy, so the step adds an SSH-only subpolicy that removes HMAC-SHA1, restarts sshd after validating, and resets the policy if validation fails.
Remove weak algorithms from sshd's defaults (Debian/Ubuntu) or add an SSH-scoped crypto-policy module (RHEL)
Debian / Ubuntu
# Keep this session open and test a fresh login from a SECOND session before closing it.
if grep -q '^Include /etc/ssh/sshd_config.d' /etc/ssh/sshd_config; then
install -m 0644 /dev/stdin /etc/ssh/sshd_config.d/00-umbermark-ssh_weak_ciphers.conf <<'EOF'
Ciphers -*-cbc,arcfour*
MACs -hmac-md5*,hmac-sha1*,umac-64*
KexAlgorithms -diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1
EOF
sshd -t && systemctl reload ssh
if ! sshd -t >/dev/null 2>&1; then rm -f /etc/ssh/sshd_config.d/00-umbermark-ssh_weak_ciphers.conf; echo 'sshd -t failed: drop-in removed, nothing changed'; fi
else
echo 'sshd_config has no Include for sshd_config.d (older distro). Put these directives at the TOP of /etc/ssh/sshd_config instead, then run: sshd -t'
fi
RHEL / Rocky / Alma / Fedora
# RHEL 8+/Rocky/Alma/Fedora: sshd's algorithms come from the crypto-policy, not sshd_config.
# This adds a subpolicy that applies to SSH only (the @SSH scope) and removes HMAC-SHA1 there.
# Stock DEFAULT otherwise already leaves out CBC ciphers and SHA-1 key exchange; verify that afterwards.
# Keep this session open and test a fresh login from a SECOND session before closing it.
# The module is appended to whatever policy is active now (never replaces it); FIPS hosts are left alone.
if command -v update-crypto-policies >/dev/null 2>&1; then
cur=$(update-crypto-policies --show)
case "$cur" in
FIPS*)
echo 'FIPS policy active: leave the crypto-policy to your FIPS process; not changed'
;;
*)
install -m 0644 /dev/stdin /etc/crypto-policies/policies/modules/UMBERMARK-SSH.pmod <<'EOF'
mac@SSH = -HMAC-SHA1
EOF
case "$cur" in *UMBERMARK-SSH*) new="$cur" ;; *) new="$cur:UMBERMARK-SSH" ;; esac
update-crypto-policies --set "$new"
sshd -t && systemctl restart sshd
if ! sshd -t >/dev/null 2>&1; then update-crypto-policies --set "$cur"; echo 'sshd -t failed: crypto-policy reset to previous value'; fi
;;
esac
# Afterwards, `update-crypto-policies --show` should print your previous policy followed by :UMBERMARK-SSH and
# `sshd -T | grep -iE '^(ciphers|macs|kexalgorithms) '` should list nothing the check flags.
# If it still does, add another scoped line to the .pmod, e.g. `cipher@SSH = -*-CBC`, and re-run this step.
else
echo 'update-crypto-policies not found: this host does not use system crypto-policies; set Ciphers/MACs/KexAlgorithms in sshd_config instead'
fi