Post-Quantum SSH: What Changed on Ubuntu
OpenSSH already negotiates a post-quantum key exchange by default. Check what your Ubuntu box really uses, and learn why host keys are still classical.
What changed in post-quantum SSH
Post-quantum SSH is already switched on for most people, and nobody had to configure it. A current OpenSSH client talking to a current OpenSSH server picks a hybrid post-quantum key exchange by default, so the session key resists an attacker who records your traffic today and decrypts it years from now. The protection is real, and it is narrower than the phrase "quantum-safe SSH" suggests.
Two terms first. SSH (secure shell) is the protocol you log into a server with. The key exchange, usually written "kex", is the first step of every SSH connection: the two ends agree on a shared secret, and that secret encrypts everything that follows. The key exchange is the part that changed. Nothing else did.
Do not trust this page, run the commands
Every algorithm name below comes out of a command you can run yourself. That is on purpose. The default moves with each OpenSSH release, so a guide written two years ago names an algorithm your machine no longer prefers, and it has no way to tell you. Learn these commands and you stop needing articles about this, including this one.
Start with what your build knows how to do.
ssh -V
ssh -Q kexssh -V prints a version line beginning with OpenSSH_, followed by the Ubuntu package suffix and the OpenSSL version. ssh -Q kex prints one key exchange algorithm per line. On a build with post-quantum support you will find names such as mlkem768x25519-sha256 and sntrup761x25519-sha512@openssh.com in that list, sitting next to classical names like curve25519-sha256.
What your build supports is not what it offers
This is the distinction most posts skip. ssh -Q kex answers one question: what could this binary do. It does not answer the question you care about: what will this connection actually propose. The two lists are different, and the gap between them is where old advice does real damage.
ssh -G example.com | grep -i '^kexalgorithms'
sudo sshd -T | grep -i '^kexalgorithms'ssh -G <host> prints the client's effective configuration for that host, after ~/.ssh/config and /etc/ssh/ssh_config have been applied. sshd -T does the same for the server. Each prints a single kexalgorithms line in preference order, and the first name on it is that side's first choice. That line is what goes on the wire.
The gap is not theoretical. OpenSSH 8.5, released on 2021-03-03, added sntrup761x25519-sha512@openssh.com and deliberately left it out of the default list. On that release ssh -Q kex shows the algorithm and ssh -G does not, which means the binary can do a post-quantum key exchange and no connection ever asks it to.
Read the algorithm your connection negotiated
ssh -v example.com 2>&1 | grep 'kex: algorithm'Between a current client and a current server, that prints:
debug1: kex: algorithm: mlkem768x25519-sha256mlkem768x25519-sha256 is a hybrid. It runs ML-KEM (module-lattice key encapsulation mechanism, standardised as FIPS 203) at parameter set 768, together with X25519 elliptic curve Diffie-Hellman, and mixes both outputs into the session key.
Against an older server you may see this instead:
debug1: kex: algorithm: curve25519-sha256That name has no post-quantum half. curve25519-sha256 is elliptic curve Diffie-Hellman on its own, and a large quantum computer breaks it. That is the whole reason the default moved.
One negotiation rule explains why a single old machine holds a session back. The client sends its list in preference order, the server sends its own, and the algorithm chosen is the first name on the client's list that also appears on the server's. The client's preference wins, so the older of the two ends decides how far up the list you get. Upgrading your laptop does not upgrade a session to a server that has never heard of ML-KEM.
Drop the grep and ssh -v shows the rest of the negotiation, including the line that the next section is about:
debug1: kex: host key algorithm: ssh-ed25519Which OpenSSH release made the hybrid exchange the default
The upstream release notes give a clear sequence. The dates matter more than the version numbers, because they show how long this has been running quietly.
- 8.5, released 2021-03-03, added
sntrup761x25519-sha512@openssh.comand left it disabled by default. - 9.0, released 2022-04-08, turned it on. The notes say OpenSSH will "use the hybrid Streamlined NTRU Prime + x25519 key exchange method by default". This is the release where a post-quantum key exchange became the normal case.
- 9.9, released 2024-09-19, added
mlkem768x25519-sha256as a second option. The same release gave the older method its IANA registered name,sntrup761x25519-sha512, so newer builds list it under both spellings. - 10.0, released 2025-04-09, made
mlkem768x25519-sha256the default for key agreement. - 10.1, released 2025-10-06, added a client warning when a connection negotiates a key exchange with no post-quantum half. It is controlled by the
WarnWeakCryptooption inssh_configand is on by default.
April 2022 is the date worth remembering. Any pair of machines running OpenSSH 9.0 or newer has been doing a post-quantum key exchange since then, with no configuration and no announcement to the person typing ssh.
Which Ubuntu release ships it
Ubuntu freezes an OpenSSH version at release, then backports security fixes into it without moving the version number. So the Ubuntu release you run decides your default algorithm. Check the machine in front of you with ssh -V rather than trusting a list. As of August 2026 the archive holds these versions:
- 22.04 LTS ships
1:8.9p1, which predates the 9.0 default, so a stock install negotiatescurve25519-sha256. - 24.04 LTS ships
1:9.6p1, which is after 9.0 and before 9.9, so its default issntrup761x25519-sha512@openssh.comand it has no ML-KEM. - 25.10 ships
1:10.0p1, whose default ismlkem768x25519-sha256. - 26.04 LTS ships
1:10.2p1, which defaults tomlkem768x25519-sha256and warns about connections that are not post-quantum.
Work through a real pair of machines. A 26.04 laptop connects to a 24.04 server. The client's first choice, mlkem768x25519-sha256, is not in the 9.6 server's list. The client's next post-quantum choice that the server does have is sntrup761x25519-sha512@openssh.com, and that is the name ssh -v reports. The session is post-quantum on the key exchange, against a server built in 2024, with nothing configured by anybody.
The 22.04 case goes the other way, and it shows exactly why ssh -Q kex on its own misleads. OpenSSH 8.9 knows the sntrup761x25519-sha512@openssh.com name, so ssh -Q kex on that box lists it, but the default proposal leaves it out, so the negotiation settles on curve25519-sha256. From an OpenSSH 10.1 or newer client, the connection says so:
** WARNING: connection is not using a post-quantum key exchange algorithm.
** This session may be vulnerable to "store now, decrypt later" attacks.That warning is a fact about the server you are reaching, not about your client. The answer is to upgrade the server. Setting WarnWeakCrypto no removes the message and changes nothing about the connection.
Why hybrid, and what harvest now decrypt later means
The threat has a plain shape. An attacker who can see your traffic records the encrypted bytes today and stores them. They cannot read them today. They keep them until a quantum computer large enough to break X25519 exists, and then they read them. This is called harvest now, decrypt later, or store now, decrypt later. It asks nothing clever of the attacker in the present. It asks for disk space and patience.
Encryption has this problem and signatures do not, and that asymmetry drives everything else. A recorded ciphertext keeps its value for as long as the data inside it stays sensitive. A signature only has to be unforgeable at the moment it is checked. Breaking a signature algorithm in 2035 lets somebody impersonate a server in 2035. It does not let them go back and forge a login from 2026. So the key exchange had to be fixed first, and the signature side can wait.
Hybrid means both algorithms run and both results feed the session key. To recover the secret behind mlkem768x25519-sha256 an attacker must break ML-KEM 768 and X25519. The pairing is deliberate: ML-KEM is much newer than X25519 and has had far less time under attack from cryptanalysts, so a flaw found in the new algorithm does not cost you the protection you already had.
What is protected and what is not
The key exchange is protected. The shared secret encrypting your session came out of a hybrid exchange, so a recording of that session made today does not become readable when quantum computers arrive.
The host key is not protected. The debug1: kex: host key algorithm: ssh-ed25519 line names a classical signature, and so do rsa-sha2-512 and the ECDSA (elliptic curve digital signature algorithm) types. An attacker holding a working quantum computer could forge that signature and impersonate your server, but only during a live connection at that future time, and never against traffic recorded now.
Your login key is not protected either. The key in ~/.ssh/id_ed25519 is the same kind of classical signature, and the same reasoning covers it. What protects that key this year is where it lives and who can read it, so sensible SSH key management moves your real risk much further than any algorithm name on this page.
There is nothing for you to do about either of those, because there is nothing to switch to. OpenSSH has said post-quantum signature support is coming in a future release. Until it ships, OpenSSH has no post-quantum host key type and no post-quantum user key type, and ssh-keygen has none to offer you. A guide telling you to generate one is describing software that does not exist yet.
TLS on the same server is a separate question with a separate answer. TLS (transport layer security) is what your web server speaks on port 443, and it is a different codebase on a different schedule. Upgrading OpenSSH changes nothing there. If you are running a self-signed certificate for a private service on the same VPS, its signature and its key exchange are decided by OpenSSL and your web server, so ask about that stack on its own terms.
What a sensible operator does now
Keep OpenSSH current, and stop there. That really is the whole strategy for this problem. sudo apt update && sudo apt upgrade keeps you on the version your Ubuntu release ships, and moving to a newer Ubuntu release is what moves you to a newer OpenSSH. Turning on unattended security upgrades gets those patches applied without you remembering to. Building OpenSSH from source to chase an algorithm name is a poor trade, because you give up the distribution's security updates for the most exposed service on the box. If you fetch source anyway, check the download against its published checksum before you build it.
Do not hand-write a KexAlgorithms line. This is the one action that reliably makes things worse. A hardening guide from 2018 hands you a list that was correct in 2018, and pasting it into sshd_config replaces the default list rather than adding to it. Every algorithm invented since then is now excluded, so a server that would have negotiated mlkem768x25519-sha256 on its own quietly drops to whatever survives in the pinned list. Run sudo sshd -T | grep -i '^kexalgorithms' on any server you inherited. If that line is shorter than the one on a fresh install of the same release, somebody pinned it.
If you have a real reason to change the list, add to it instead of replacing it. OpenSSH reads a leading + as append, a leading - as remove, and a leading ^ as move to the front.
KexAlgorithms ^mlkem768x25519-sha256Test the file before you rely on it. sudo sshd -t parses the configuration and prints nothing when it is valid. A KexAlgorithms line naming an algorithm the build does not have stops sshd from starting, and on a remote box that means you cannot get back in, so keep a second session open while you work. When the two sides' lists stop overlapping, the client says so plainly:
Unable to negotiate with 203.0.113.10 port 22: no matching key exchange method found. Their offer: curve25519-sha256,ecdh-sha2-nistp256Read "quantum-safe" marketing as a claim about one layer. A vendor calling a product quantum-safe is describing whichever layer they named, and that layer is usually a key exchange somewhere. Ask for the algorithm name and the protocol it applies to. For OpenSSH in August 2026 the honest version of the claim is that the key exchange is hybrid post-quantum while the signatures are classical. Anything wider than that should arrive with a name you can find in ssh -Q kex output.
Keep doing the boring parts. A post-quantum key exchange does nothing about a guessable password, or a private key copied onto a laptop that later gets stolen. Those are what actually take servers, and standard SSH hardening on a VPS still carries almost all of the weight. If the negotiation steps here were unfamiliar, what SSH does when you connect covers the stages this page assumes you know.
FAQ
Is my SSH connection already post-quantum?
Run ssh -v yourserver 2>&1 | grep 'kex: algorithm' and read the name it prints. mlkem768x25519-sha256 and sntrup761x25519-sha512@openssh.com are hybrid post-quantum exchanges. curve25519-sha256, ecdh-sha2-nistp256 and any diffie-hellman-group name are classical. Both ends need a version that offers a post-quantum name, because the negotiation picks the client's first choice that the server also supports, so the older machine sets the ceiling.
Which OpenSSH release made post-quantum key exchange the default?
OpenSSH 9.0, released on 2022-04-08, made sntrup761x25519-sha512@openssh.com the default key exchange. OpenSSH 9.9, released on 2024-09-19, added mlkem768x25519-sha256, and OpenSSH 10.0, released on 2025-04-09, made that one the default instead. OpenSSH 10.1, released on 2025-10-06, began warning when a connection negotiates neither. Check what your own build does with ssh -Q kex and ssh -G <host>, because your Ubuntu release decides which of those you have.
Should I generate a post-quantum SSH key?
No, because OpenSSH has no such key type. The post-quantum work so far covers the key exchange, which needs no key files from you and no configuration at all. Host keys and login keys are still classical signatures such as Ed25519 and RSA, and upstream has said post-quantum signatures will come in a future release. Keep using an Ed25519 key and protect where it is stored.
Why does ssh warn that my connection is not post-quantum?
OpenSSH 10.1 and newer print ** WARNING: connection is not using a post-quantum key exchange algorithm. when the negotiated exchange has no post-quantum half. The warning is about the server, not your client, because your client offered a post-quantum name and the server accepted none of them. Upgrade the server's OpenSSH, or check that nobody pinned a KexAlgorithms line in its sshd_config that excludes the modern names. Setting WarnWeakCrypto no hides the message and leaves the connection exactly as weak as it was.