Synopsis #
- Install
ssh-auditand inventory the algorithms offered by the listening server. - Compare audit findings with the effective sshd_config(5) configuration and current OpenSSH documentation.
- Avoid replacing maintained OpenSSH cryptographic defaults with frozen allowlists unless a specific, documented requirement justifies the change.
- Express optional local policy as additions, removals, or preference changes to the defaults where the directive supports them.
- Validate the configuration, reload sshd(8) , audit the listening daemon, and verify the algorithm negotiated by a real client.
What an Audit Shows #
A key exchange algorithm (KEX) establishes the session secrets. A host-key algorithm authenticates the server. A cipher protects the session data. A message authentication code (MAC) protects integrity when the selected cipher requires a separate MAC. These mechanisms do not provide the same property.
ssh-audit connects to a server and inventories the algorithms that the server offers. Its [fail], [warn], and recommendation lines apply the tool’s own policy and knowledge base. They do not, by themselves, establish that OpenSSH has deprecated or disabled an algorithm. The OpenBSD manual pages and official OpenSSH release notes define OpenSSH support and defaults.
An offered algorithm is also not necessarily the algorithm selected for a connection. Client and server capabilities and preferences determine the negotiated result. A clean audit is useful evidence, but it is not the sole definition of a secure configuration.
Install and Run ssh-audit #
Install the package with pkg_add(1) , then audit the local listener:
# pkg_add ssh-audit
# Install the auditing utility
$ ssh-audit localhost
# Inventory the algorithms offered on port 22
Specify a different port with -p:
$ ssh-audit -p 31415 localhost
A remote audit uses the same protocol view as any other unauthenticated client. It does not require a server account.
Preserve Maintained Defaults #
The maintained general baseline is to leave KexAlgorithms, MACs, and HostKeyAlgorithms unspecified. OpenSSH can then revise its maintained defaults during supported system updates. The installed sshd_config(5)
manual documents the defaults for each directive.
For KexAlgorithms and MACs, a plain comma-separated value replaces the directive’s complete default set. OpenBSD 7.9 documents these list modifiers:
+appends matching algorithms to the default set;-removes matching algorithms, including wildcard matches, from the default set;^places algorithms before the default set.
Server KEX ordering is not significant because the client supplies the preference order. Therefore, ^ does not make a server select a particular KEX. The server-side HostKeyAlgorithms entry documents an offered list but does not document these modifiers. Do not assume that a modifier applies to a directive unless the installed manual documents it.
A frozen allowlist may look strict when written, but it also prevents later OpenSSH defaults from taking effect. The former Handbook KEX recipe demonstrated this failure. It replaced the complete default set with classical algorithms. After OpenSSH gained and preferred hybrid post-quantum KEX, the server continued to offer only the old local list.
Review every explicit algorithm directive after an OpenBSD or OpenSSH upgrade. Remove a local override when its documented requirement no longer applies.
Key Exchange and Post-Quantum Protection #
In OpenBSD 7.9, OpenSSH 10.3’s maintained server KEX defaults include mlkem768x25519-sha256, both names for sntrup761/X25519, Curve25519, and the three NIST ECDH methods. Leaving KexAlgorithms unspecified retains that set and allows later supported updates to revise it. See sshd_config(5)
for the complete installed default.
The ML-KEM/X25519 and sntrup761/X25519 methods are hybrid key exchanges. Each combines a post-quantum mechanism with classical X25519. The session remains protected if either component remains secure. The X25519 component therefore protects against an unexpected weakness in the newer post-quantum mechanism while the post-quantum component protects recorded traffic against a future quantum attack on classical key exchange.
“Store now, decrypt later” describes an attacker recording encrypted traffic now and retaining it until a future system can break the classical key exchange. OpenSSH 10.1 and later warn when a client negotiates no post-quantum KEX because this risk concerns the confidentiality of the recorded session. The warning concerns key exchange. It does not say that the host key, cipher, and MAC provide the same post-quantum property. See the OpenSSH 10.1 release notes .
OpenSSH 9.9 added mlkem768x25519-sha256; OpenSSH 10.0
made it the preferred scheme. OpenSSH has offered sntrup761/X25519 by default since OpenSSH 9.0
. See the official OpenSSH post-quantum cryptography notes
and OpenSSH 9.9 release notes
.
Optional Stricter KEX Policy #
The OpenBSD 7.9 package index
lists ssh-audit-3.3.0p1. Its upstream 3.3.0 policy marks ecdh-sha2-nistp256, ecdh-sha2-nistp384, and ecdh-sha2-nistp521 as failures. Later versions may apply a different policy. OpenSSH 10.3 still includes these algorithms in its maintained server defaults. The audit label is not evidence that OpenSSH considers them deprecated, nor does it establish claims about a backdoor. The versioned ssh-audit policy database
records the tool’s classification.
A site that has separately decided to exclude these curves can express that decision without replacing the other defaults:
KexAlgorithms -ecdh-sha2-nistp*
This optional policy retains the maintained post-quantum methods and other defaults. It is stricter than OpenSSH’s default, not a correction for an insecure default. Test every required client before deployment. A client that supports none of the remaining methods will be unable to connect.
MAC Policy #
OpenSSH 10.3 defaults prefer encrypt-then-MAC algorithms, whose names contain -etm. sshd_config(5)
describes these as safer and recommends their use. The defaults also retain other MACs for compatibility.
The former Handbook recommendation replaced the complete set with three -etm algorithms. That policy produced a smaller audit surface but froze the list and could exclude a stronger future default. The Handbook therefore does not recommend an explicit MACs directive as a general baseline.
If a documented local policy rejects SHA-1 MACs and 64-bit UMAC, it can remove those families while preserving other defaults:
MACs -hmac-sha1*,umac-64*
This example is a local compatibility decision. It is not required to make the OpenSSH defaults secure, and it is not equivalent to an ETM-only allowlist. Audit and test the effective result after applying it.
Host-Key Algorithm Policy #
Leave HostKeyAlgorithms unspecified unless an interoperability or organizational requirement calls for a restriction. The sshd_config(5)
defaults include certificate, Ed25519, ECDSA, security-key, and RSA SHA-2 signature algorithms. The server can offer only algorithms for which it has suitable host-key or certificate material.
The former fixed list of ssh-ed25519,rsa-sha2-256,rsa-sha2-512 intentionally excluded ECDSA, certificates, and security-key host signatures. It could also exclude a future algorithm introduced by an OpenSSH update. No general benefit justifies that frozen list.
Changing HostKeyAlgorithms does not require regenerating host keys. Algorithm policy controls which existing keys and signature methods the daemon may use. Rotate a host key only for a reason such as compromise, unsuitable key material, or a planned key-lifecycle change. A new host key changes the server identity recorded by clients and can cause host-key mismatch warnings. Distribute and verify a new fingerprint through an independent channel before removing the old identity.
Do not enable a new or experimental host-signature algorithm merely because the installed OpenSSH code supports it. Follow the defaults and the deployment’s documented key-management requirements.
Diffie-Hellman Moduli #
The maintained OpenSSH 10.3 server KEX defaults do not include finite-field Diffie-Hellman group exchange. The moduli(5)
file at /etc/moduli is used only by the diffie-hellman-group-exchange-sha1 and diffie-hellman-group-exchange-sha256 methods.
Do not filter or replace /etc/moduli as routine hardening when neither method is enabled. Review moduli only when a deliberate compatibility policy enables group-exchange KEX. The former routine filtering procedure did not affect the recommended OpenSSH 10.3 policy.
Validate and Apply Changes Safely #
Keep an established administrative SSH session open. An independent console provides an additional recovery path. Make one policy change at a time and test a second connection before closing the recovery session.
Use sshd(8) to validate syntax and host-key sanity:
# sshd -t
Inspect the effective algorithm configuration:
# sshd -T | grep -E '^(kexalgorithms|macs|hostkeyalgorithms) '
Run these checks as root. Private server host keys are normally unreadable by an unprivileged account. In that case, sshd -t or sshd -T may report sshd: no hostkeys available -- exiting. This message can reflect insufficient permission to read the keys rather than absent host-key files.
For configuration-only changes, reload the validated daemon with rcctl(8) :
# rcctl reload sshd
The reload causes the listening daemon to read the new configuration without ending established sessions. A restart is not required for the algorithm-policy changes described here.
Audit the active listener again:
$ ssh-audit localhost
$ ssh-audit -p 31415 localhost
Finally, use ssh(1) to open a second client connection with verbose logging:
$ ssh -v host.example.com
The client output identifies the selected KEX. A post-quantum negotiation on the documented release can include:
debug1: kex: algorithm: mlkem768x25519-sha256
This client check answers a different question from ssh-audit: it shows the algorithm negotiated for that connection, not every algorithm the server offers.
Interpret Terrapin and Strict KEX Output #
OpenSSH 9.6 added the strict-KEX protocol extension as a countermeasure to the Terrapin attack. It is enabled automatically when both peers support it. ssh-audit 3.3.0 may print an informational paragraph for chacha20-poly1305@openssh.com and for CBC ciphers combined with encrypt-then-MAC when the other peer lacks strict-KEX support.
The maintained OpenSSH defaults include ChaCha20-Poly1305. Do not remove it only to suppress an informational paragraph. Confirm that required peers support strict KEX and apply primary-source OpenSSH security guidance. The OpenSSH 9.6 release notes
describe the countermeasure. The versioned ssh-audit reporting source
defines the tool’s informational text.
Review After Upgrades #
After each OpenBSD or OpenSSH upgrade:
- read the OpenSSH release notes and the installed manual pages;
- inspect sshd(8)
output from
sshd -Tfor local overrides and effective defaults; - audit the listening daemon;
- test required clients and inspect the negotiated KEX;
- remove obsolete exceptions and record the reason for those that remain.
This workflow treats ssh-audit as a useful independent signal while leaving OpenSSH responsible for its maintained baseline.