Description
The OpenSSH server negotiates three families of algorithms with each client, set by
Ciphers, MACs and KexAlgorithms in sshd_config. This control requires every algorithm
the server offers to be in an allow list:
- ciphers: ChaCha20-Poly1305, AES-GCM, AES-CTR;
- MACs: HMAC-SHA2-256/512, preferably in encrypt-then-MAC (
-etm) mode; - key exchange: hybrid post-quantum (
mlkem768x25519-sha256,sntrup761x25519-sha512), Curve25519, NIST ECDH, and Diffie-Hellman groups of at least 2048 bits with SHA-2.
The first key exchange algorithm offered must be a hybrid post-quantum one.
Debian 12 (OpenSSH 9.2) and 13 (OpenSSH 10.0) already exclude weak ciphers and put a
post-quantum key exchange first, but both still offer SHA-1 and UMAC MACs. The fix writes the
three lists in /etc/ssh/sshd_config.d/00-cirsec.conf, keeping only the algorithms the installed
OpenSSH supports (ssh -Q), so mlkem768x25519-sha256 is only set on Debian 13.
Rationale
CBC ciphers, RC4, 3DES, SHA-1 and MD5 based MACs, 64-bit tag UMAC and SHA-1 Diffie-Hellman are broken or too weak for long-term protection; UMAC is kept out to stay with the widely reviewed HMAC-SHA2 constructions. Sessions recorded today can be decrypted later by a quantum computer unless the key exchange is post-quantum, which is why it must be preferred.
Impact
Old clients and network equipment that only support removed algorithms cannot connect anymore
(for example hmac-sha1 or diffie-hellman-group14-sha1). Check the clients, automation tools
and SFTP libraries in use before applying.
Applies when
Detected: when: OpenSSH server is installed A scanner reports the control not applicable when one is false.
Setting
| Location | /etc/ssh/sshd_config.d/00-cirsec.conf (`Ciphers`, `MACs`, `KexAlgorithms`) |
| Default | OpenSSH defaults, including hmac-sha1 and umac-64 MACs |
| Recommended | Only the allowed algorithms, post-quantum key exchange first |
Audit
Run sshd -T | grep -E '^(ciphers|macs|kexalgorithms) ' and check that:
- ciphers are among
[email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr; - MACs are among
[email protected],[email protected],hmac-sha2-512,hmac-sha2-256; - key exchange algorithms are among
mlkem768x25519-sha256,sntrup761x25519-sha512(with or without@openssh.com),curve25519-sha256(with or without@libssh.org),ecdh-sha2-nistp256/384/521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, and the first one ismlkem768x25519-sha256orsntrup761x25519-sha512.
Automated: every check must pass. Scanners report each check by its id.
ciphers
Effective Ciphers list.
key: ciphers
operator: match
value: ^((chacha20-poly1305@openssh\.com|aes(128|256)-gcm@openssh\.com|aes(128|192|256)-ctr)(,|$))+$
macs
Effective MACs list.
key: macs
operator: match
value: ^(hmac-sha2-(256|512)(-etm@openssh\.com)?(,|$))+$
kex
Effective KexAlgorithms list.
key: kexalgorithms
operator: match
value: ^((mlkem768x25519-sha256|sntrup761x25519-sha512(@openssh\.com)?|curve25519-sha256(@libssh\.org)?|ecdh-sha2-nistp(256|384|521)|diffie-hellman-group-exchange-sha256|diffie-hellman-group14-sha256|diffie-hellman-group(16|18)-sha512)(,|$))+$
kex-post-quantum
First key exchange algorithm is a hybrid post-quantum one.
key: kexalgorithms
operator: match
value: ^(mlkem768x25519-sha256|sntrup761x25519-sha512(@openssh\.com)?)(,|$)
Remediation
Create /etc/ssh/sshd_config.d/00-cirsec.conf (mode 0600) with the lists below, removing the
algorithms that ssh -Q cipher, ssh -Q mac or ssh -Q kex does not print:
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
MACs [email protected],[email protected],hmac-sha2-512,hmac-sha2-256
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,[email protected],curve25519-sha256,[email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256
Check with sshd -t, then run systemctl reload ssh. Keep an open session until a new
connection succeeds.
| Restart | service: ssh |
| Disruption | low |
| Lockout risk | yes: can cut off administrative access. Off by default in generated scripts and playbooks, opt in through a tailoring file. |
Rollback
Remove the three lines from /etc/ssh/sshd_config.d/00-cirsec.conf and run systemctl reload ssh.
algorithms
# CB-DEB-NET-015: set strong SSH server algorithms, keeping only those this OpenSSH version supports.
PATH="$PATH:/usr/sbin"
f=/etc/ssh/sshd_config.d/00-cirsec.conf
grep -Eqi '^[[:space:]]*Include[[:space:]]+/etc/ssh/sshd_config.d/\*\.conf' /etc/ssh/sshd_config || {
echo '/etc/ssh/sshd_config does not include sshd_config.d/*.conf' >&2
exit 1
}
# keep TYPE LIST: the algorithms of LIST that "ssh -Q TYPE" knows, comma separated, in LIST order.
keep() {
sup=$(ssh -Q "$1") || return 1
out=
for a in $(printf '%s' "$2" | tr ',' ' '); do
printf '%s\n' "$sup" | grep -Fxq -- "$a" && out="${out:+$out,}$a"
done
[ -n "$out" ] && printf '%s' "$out"
}
nokeep() {
echo "ssh -Q $1 failed or knows none of the recommended algorithms" >&2
exit 1
}
c=$(keep cipher [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr) || nokeep cipher
m=$(keep mac [email protected],[email protected],hmac-sha2-512,hmac-sha2-256) || nokeep mac
k=$(keep kex mlkem768x25519-sha256,sntrup761x25519-sha512,[email protected],curve25519-sha256,[email protected],ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256,diffie-hellman-group18-sha512,diffie-hellman-group16-sha512,diffie-hellman-group14-sha256) || nokeep kex
mkdir -p /etc/ssh/sshd_config.d
cb_backup "$f"
touch "$f"
chmod 600 "$f"
sed -i '/^[[:space:]]*\(ciphers\|macs\|kexalgorithms\)[[:space:]]/Id' "$f"
printf 'ciphers %s\nmacs %s\nkexalgorithms %s\n' "$c" "$m" "$k" >>"$f"
if ! sshd -t; then
cb_restore "$f"
echo 'sshd -t rejected the change, reverted' >&2
exit 1
fi
Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.
References
- sshd_config(5), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- ssh(1), Debian manual pages (ssh -Q) Debian, vendor-doc, accessed 2026-10-18
- OpenSSH - Post-Quantum Cryptography OpenSSH, vendor-doc, accessed 2026-10-18
- NIST IR 7966 - Security of Interactive and Automated Access Management Using Secure Shell (SSH) NIST, guide, accessed 2026-10-18
Mappings
| Framework | ID | Relation | Note |
|---|---|---|---|
| NIST SP 800-53 Rev. 55.1.1 | SC-8 | partial | |
| NIST SP 800-53 Rev. 55.1.1 | SC-13 | partial |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
People and lifecycle
| Authors |
|
| Verified | 2026-10-18 by Sn0wAlice on 12, Proxmox VM 921, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. fix.sh writes the lists filtered with ssh -Q; SSH by key accepted before and after the fix and after reboot. |
| Verified | 2026-10-18 by Sn0wAlice on 13, Proxmox VM 931, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. fix.sh writes the lists filtered with ssh -Q; SSH by key accepted before and after the fix and after reboot. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-18, 2026-10-18 |
| Translations | fr |