From classical to quantum-safe: a migration playbook for network teams
A staged plan for moving a fleet's SSH management traffic to post-quantum key exchange with GHOSTSHELL 0.2.0: what servers offer today, how to take an inventory, when a profile can refuse classical exchanges, and what stays classical.
A technical paper from the GHOSTSHELL project, describing GHOSTSHELL 0.2.0. It has not been peer reviewed.
Abstract
A network team can move most of its SSH management traffic to post-quantum key exchange from the client side, but only as far as each server shares a post-quantum method. This paper gives a staged plan for that move with GHOSTSHELL 0.2.0: rank hosts by what their sessions carry, record what each one actually negotiates, move the client first, upgrade the servers you control, set Quantum-safe only where every hop of a profile qualifies, and keep a dated list of what stays classical. It sets out what servers offer today, from OpenSSH's release notes and the distributions' archives, and the dates in NIST IR 8547. Against six scripted server offers on 127.0.0.1, the default policy got a post-quantum exchange from every offer that shared a method with it, a Compatible profile saved under 0.1 fell back to classical with the offer of OpenSSH 8.9 to 9.8, and no client tested could connect to a server offering only the ML-KEM-1024 exchange of the CNSA 2.0 profile.
1Introduction
A network team's management plane is mostly SSH: to routers, switches, firewalls and servers, and to the bastions in between. Harvest now, decrypt later explains why the key exchange of those sessions is what a future quantum computer threatens. This paper is about the move itself, across a fleet that is never replaced at once.
Two facts shape the plan. In SSH the key exchange is the first method on the client's list that the server also supports [1], so a client can move every session forward on its own, as far as the servers allow, without touching a server. And the server's support is the limit: a server without a post-quantum method gets a classical exchange from any client, and refusing it means losing access to it. NIST asks organisations to begin the transition with cryptographic inventories and migration planning [2]; for SSH, an inventory is a list of what each connection negotiated.
The plan has six stages (Figure 1). Section 2 sets out what servers offer today, Section 3 the stages, Section 4 what stays classical, and Section 5 measures GHOSTSHELL 0.2.0's policies against server offers modelled on Section 2. The policies themselves are described in Post-quantum by default.
2What servers offer today
2.1Offer and choice
The client's order decides among the methods both sides list in their KEXINITs [1], so what a server offers is a set; its own order does not matter. Before the lists, each side sends an identification string with its software and version [1], such as SSH-2.0-OpenSSH_10.5: a hint about that set, not proof of it.
2.2OpenSSH, release by release
OpenSSH added sntrup761x25519-sha512@openssh.com in 8.5, disabled by default, put it in the default list in 8.9 and made it the default method in 9.0 [3]. Version 9.9 added mlkem768x25519-sha256, available by default, and the name sntrup761x25519-sha512, and 10.0 made mlkem768x25519-sha256 the default [3]. Both methods are now RFCs [4] [5]. Servers older than 9.9 know sntrup761 only by its @openssh.com name, which RFC 9941 recommends announcing and accepting as an alias [5]. Table 1 maps these releases onto the long-term releases a fleet runs [6] [7].
Red Hat Enterprise Linux sets SSH algorithms through system-wide crypto policies instead of OpenSSH's defaults. Red Hat lists post-quantum SSH key exchange from RHEL 10.1, whose default policy prefers the ML-KEM + X25519 hybrid; for RHEL 9 it mentions only an opt-in policy, DEFAULT:PQ, from 9.7, without saying whether it covers SSH [8]. On any system a KexAlgorithms line in the server's configuration overrides all of this, which is why Table 1 is a forecast and the negotiated result is the evidence.
| Release | OpenSSH | Post-quantum key exchange by default |
|---|---|---|
| Debian 11 | 8.4p1 | None |
| Ubuntu 22.04 LTS | 8.9p1 | sntrup761x25519-sha512@openssh.com |
| Debian 12 | 9.2p1 | sntrup761x25519-sha512@openssh.com |
| Ubuntu 24.04 LTS | 9.6p1 | sntrup761x25519-sha512@openssh.com |
| Debian 13 | 10.0p1 | mlkem768x25519-sha256, and sntrup761 under both names |
| Ubuntu 26.04 LTS | 10.2p1 | mlkem768x25519-sha256, and sntrup761 under both names |
| RHEL 9 | crypto policy | None |
| RHEL 10 | crypto policy | ML-KEM + X25519 hybrid, by default from 10.1 |
2.3Windows, network equipment and the other clients
Scripts, automation and proxy commands bring clients of their own. On the test machine, Windows 11's built-in ssh.exe is OpenSSH_for_Windows_9.5p2, with no post-quantum method at all, and OpenSSH 10.5, as Git for Windows ships it, offers neither NIST-curve hybrid by default (Section 5). From 10.1, OpenSSH's client warns when a connection's key agreement is not post-quantum [3].
Network equipment runs SSH servers of its own, which change only with its firmware. Vendors' documents show the range: Juniper documents the sntrup761 + X25519 hybrid for SSH on Junos without naming a release or saying whether it is on by default [9], and Cisco's roadmap lists SSH among the protocols it targets on IOS XE and NX-OS by December 2026, a plan it says may change [10]. No network device was tested for this paper. Until a session to a platform shows otherwise, plan for it as classical.
2.4Deadlines and profiles
NIST IR 8547 deprecates the quantum-vulnerable public-key algorithms (RSA, ECDSA, EdDSA, and finite-field and elliptic-curve Diffie–Hellman) after 2030 and disallows them in NIST standards after 2035 [2]. Under the executive order and OMB memorandum it cites, federal high value assets and high impact systems must use post-quantum key establishment by 31 December 2030 and post-quantum signatures by 31 December 2031. The report puts key establishment first because of harvest-now-decrypt-later, recalls that earlier transitions took 10 to 20 years, expects both kinds of algorithm to be negotiated side by side during the transition, and asks that systems unable to support post-quantum cryptography be identified and prioritised for replacement [2].
The CNSA 2.0 profile for SSH, an Internet-Draft for US national security systems, goes further: mlkem1024-sha384, ML-KEM-1024 with no classical half, must be the only key exchange negotiated, ML-DSA-87 the host key and AES-256-GCM the only cipher, and a client must not trust a host key on first use [11]. GHOSTSHELL 0.2.0 does not implement mlkem1024-sha384, whose wire format the drafts leave ambiguous (Post-quantum by default, section 6), so it cannot make a CNSA 2.0 connection.
3The playbook
3.1Stage 1: rank what the sessions carry
Mosca's theorem, as NIST restates it, puts first the data that must stay secret longest and the systems that take longest to change [2]. For a network team that usually means bastions and jump hosts first, since their outer connection carries the logins for everything behind them; then devices whose configurations hold keys, password hashes or community strings; then the rest. The rank says what a classical session to a host costs, not whether it can be fixed.
3.2Stage 2: record what each host negotiates
A version predicts a server's offer; a connection shows it. Under Quantum-safe preferred, GHOSTSHELL prints what each connection negotiated as soon as the host key is accepted and before any password prompt, and the tab's badge and Connection security… keep the result for every hop (Making post-quantum visible). Connecting once with each profile and noting that line is the inventory: post-quantum and by which method, classical, or refused. While tabs are open, Settings → Security counts them by what their weakest hop negotiated.
At fleet scale, two signals need no credentials. The identification string names the software, and OpenSSH's client prints the server's whole KEXINIT proposal at -vv before authentication, as it did in all 12 runs of Section 5. On servers with OpenSSH 10.6 or later, sshd logs each client whose key agreement is not post-quantum [3], which finds the old clients, such as scripts that run Windows' built-in ssh.exe.
3.3Stage 3: move the client first
Quantum-safe preferred, the default in 0.2.0, offers every post-quantum hybrid first on every profile, including profiles saved before a method existed, and keeps classical methods after them. Three settings work against it:
- Compatible offers exactly what a profile ticks. A profile whose key exchange list was edited under 0.1, when the library had no post-quantum method but
mlkem768x25519-sha256, offers no sntrup761, so it gets a classical exchange from servers that offer what OpenSSH 8.9 to 9.8 offers by default, such as Ubuntu 22.04 and 24.04 and Debian 12 (Section 5). Move it to Quantum-safe preferred, or tick the new methods. - Legacy as the global policy still offers the post-quantum methods first, but adds SHA-1 key exchange and CBC for every server. Set it on the profiles of the devices that need it, and nowhere else.
- A proxy command makes the outer hop with another program, outside every GHOSTSHELL policy, and with Windows'
ssh.exethat hop is classical. Replace it with a jump host, whose connection GHOSTSHELL raises to at least the target's policy.
3.4Stage 4: upgrade the servers you control
Any OpenSSH server from 8.9 offers sntrup761 by default, and 9.9 and later add ML-KEM-768 with X25519 [3], the parameter set NIST recommends by default [2]. On Ubuntu and Debian that is a release upgrade, or a backport where one exists (Debian 12 has 10.0p1 there [7]); on RHEL it is RHEL 10.1 or later [8]. Record each upgraded host again, since a crypto policy or a KexAlgorithms line can remove what the release offers. For network equipment the vendor's firmware notes decide: plan the upgrade into the device's normal cycle, and list the device under Stage 6 until then.
3.5Stage 5: Quantum-safe only, where every hop qualifies
Quantum-safe only turns a classical exchange from a warning into a refusal, so a server that is rebuilt or replaced without a post-quantum method cannot quietly get a classical session. Set it on a profile when every condition of Table 2 holds. It is set per profile and undone in the same place, and its refusal lists what the server offered.
| Condition | Why | Where to look |
|---|---|---|
| The host negotiated a post-quantum method under Quantum-safe preferred | Against a server without one, Quantum-safe only can only refuse | The terminal line or the tab's badge |
| Every jump host on the way did too | A jump host takes the target's policy as its floor, so a classical bastion then refuses the whole chain (Section 5) | Connection security…, one entry per hop |
| No proxy command | No policy reaches the proxy's own connection | The profile's connection settings |
| The server offers AES-256-GCM or ChaCha20-Poly1305, with SHA-2 encrypt-then-MAC | Quantum-safe only offers no other cipher or MAC | Connection security…; OpenSSH 10.5's default cipher list has both |
3.6Stage 6: list what stays classical, and record again
Every host that stays classical goes on a list with its reason and its plan (Section 4). Repeat Stage 2 after every server upgrade, firmware change and new device, and after each GHOSTSHELL release, whose library may add methods: the ML-KEM-1024 exchange of the CNSA 2.0 profile, for example, once its drafts settle on one wire format.
4What stays classical, and why
Table 3 lists what stays classical with GHOSTSHELL 0.2.0, why, and what to do about it.
| What | Why | What to do |
|---|---|---|
| Servers without a post-quantum method: OpenSSH before 8.9 by default, RHEL 9 by default, equipment whose firmware has none | They share no post-quantum method with any client | Keep Quantum-safe preferred, so the session works and is warned; upgrade, or plan the replacement IR 8547 asks for [2] |
| Equipment that needs SHA-1 key exchange or CBC | Only Legacy, or a Compatible profile that ticks them, offers them | Legacy on that device's profile alone |
Servers that offer only mlkem1024-sha384 (CNSA 2.0) | GHOSTSHELL 0.2.0 does not implement it | None in 0.2.0: no policy connects (Section 5) |
| Host and user keys | Most servers have classical host keys, which matter against an attacker with a quantum computer during the handshake, not against a recording | ML-DSA keys where both ends support them; OpenSSH enabled ssh-mldsa44-ed25519 in 10.6 [3] |
Proxy-command hops, WinSCP, scripts on Windows' ssh.exe | Other programs make these connections | Jump hosts in GHOSTSHELL; OpenSSH 10 or later for scripts |
| RDP, VNC, Telnet, serial lines | RDP runs in Windows' own client; Telnet and GHOSTSHELL's VNC viewer carry no encryption; a serial line has no cryptography | Carry RDP and VNC inside an SSH port forward where the path allows; list the rest |
5Evaluation
5.1Method
Each server offer of Table 4 was played by a scripted server on 127.0.0.1, built as in the app's own negotiation tests: it sends an identification string and a KEXINIT with the chosen lists, records the client's KEXINIT and first key exchange message, and hangs up. Offers A to C follow OpenSSH's own lists; D, E and F are constructed. The clients were GHOSTSHELL 0.2.0's SSH library as the app installed it (russh 0.2.0-ghostshell.1), with the lists the app's securityPolicy.ts computes for each policy; OpenSSH 10.5p1 from Git for Windows; and Windows' built-in OpenSSH_for_Windows_9.5p2, both OpenSSH clients with an empty configuration and throwaway files in a temporary folder.
Each choice was read twice: from the RFC 4253 rule [1] applied to the captured lists, and from the length of the public value in the client's first key exchange message, which differs by method (32 bytes for curve25519-sha256, 1,190 for sntrup761, 1,216 for mlkem768x25519-sha256, 1,665 for mlkem1024nistp384-sha384). On the same machine, ssh -Q kex listed the methods each OpenSSH client implements, and ssh -G the ones OpenSSH 10.5 offers by default. The runs were made on Windows 11 x64 with Node 24.22.2 on 12 November 2026.
5.2Results
mlkem768x25519-sha256, sntrup761@ is sntrup761x25519-sha512@openssh.com, mlkem1024p384 is mlkem1024nistp384-sha384, curve25519 is curve25519-sha256, nistp256 is ecdh-sha2-nistp256, group14-sha1 is diffie-hellman-group14-sha1. "0.1 list" is a key exchange list saved under 0.1, here mlkem768x25519-sha256, curve25519-sha256 under both its names, diffie-hellman-group16-sha512 and diffie-hellman-group14-sha256.| Server offer | Quantum-safe only | Quantum-safe preferred | Compatible | Compatible, 0.1 list | Legacy | OpenSSH 10.5 | Windows OpenSSH 9.5 |
|---|---|---|---|---|---|---|---|
| A. No post-quantum method | Refused | curve25519 | curve25519 | curve25519 | curve25519 | curve25519 | curve25519 |
| B. sntrup761@ only, as OpenSSH 8.9 to 9.8 | PQ sntrup761@ | PQ sntrup761@ | PQ sntrup761@ | curve25519 | PQ sntrup761@ | PQ sntrup761@ | curve25519 |
| C. mlkem768 and sntrup761, as OpenSSH 10 | PQ mlkem768 | PQ mlkem768 | PQ mlkem768 | PQ mlkem768 | PQ mlkem768 | PQ mlkem768 | curve25519 |
| D. NIST-curve hybrids and curves only | PQ mlkem1024p384 | PQ mlkem1024p384 | PQ mlkem1024p384 | Refused | PQ mlkem1024p384 | nistp256 | nistp256 |
E. mlkem1024-sha384 only (CNSA 2.0) | Refused | Refused | Refused | Refused | Refused | Refused | Refused |
| F. Old device: group14-sha1, CBC, HMAC-SHA1 | Refused | Refused | Refused | Refused | group14-sha1 | Refused | Refused |
GHOSTSHELL made 36 attempts, the five columns of Table 4 and Quantum-safe preferred with a 0.1 list: 23 started a key exchange and 13 were refused. In all 22 whose value has a fixed length, the length matched the method the rule predicts; the 23rd, diffie-hellman-group14-sha1, sends a number of varying length and was checked by the rule alone. What matters for the plan:
- The default policy got a post-quantum exchange from B, C and D, the offers that share a method with it, and a classical one from A, and the same with a list saved under 0.1, since it adds every hybrid.
- Compatible with a list saved under 0.1 got
curve25519-sha256from B, the offer of OpenSSH 8.9 to 9.8, and was refused by D. - Windows'
ssh.exegot a classical exchange from every offer it could use. OpenSSH 10.5 with its defaults gotecdh-sha2-nistp256from D, where GHOSTSHELL gotmlkem1024nistp384-sha384. - No client connected to E. GHOSTSHELL's refusals named what the server offered, but their advice to change the policy cannot help there.
- F needed Legacy; both OpenSSH clients refused it with their defaults.
- A jump host whose own profile says Quantum-safe preferred, carrying a Quantum-safe only profile named "core-router", offered only post-quantum methods: offer A refused it with a message naming "core-router" as the source of the policy, and offer B gave it sntrup761.
Both OpenSSH clients printed the server's proposal before authentication in all 12 runs. Windows' client implements twelve key exchange methods, none post-quantum; OpenSSH 10.5 implements sixteen and offers mlkem768x25519-sha256 and both sntrup761 names by default, but not mlkem768nistp256-sha256. The app's unit suite, run the same day, passed 244 of 245 tests with 1 skipped, the pure ML-KEM-1024 case that is not built.
6Limitations
- The scripted servers show what each client offers and chooses, not a completed exchange; completed handshakes against the project's test server are in Post-quantum by default. GHOSTSHELL's client has not yet completed one with a real OpenSSH server or a network device.
- Table 1 gives versions from the archives on one day and OpenSSH's defaults for them; it was not checked on running servers, and RHEL's rows rest on Red Hat's page alone.
- Network equipment rests on two vendor documents; no device was tested, and a roadmap is not a release.
- GHOSTSHELL takes the inventory one connection at a time: it keeps no history of what closed sessions negotiated and exports nothing, and Settings → Security counts only open tabs.
- The plan covers SSH. HTTPS, RDP and the other protocols appear only as far as Table 3.
7Conclusion
Moving a fleet to post-quantum SSH is mostly the client's work, within what each server allows. GHOSTSHELL 0.2.0's default does the client's part for every server that shares a method, including OpenSSH 8.9 to 9.8 through sntrup761 and servers limited to NIST curves, and reports each connection, so an inventory is a list of connections. The rest of the plan is the exceptions: profiles that undo the default, and servers that share nothing. Quantum-safe only belongs where every hop already negotiated post-quantum; everything else stays on the default with its warning, on a list, with a date.
References
- [1]T. Ylonen and C. Lonvick (Ed.). The Secure Shell (SSH) Transport Layer Protocol. RFC 4253, January 2006.
- [2]D. Moody, R. Perlner, A. Regenscheid, A. Robinson and D. Cooper. Transition to Post-Quantum Cryptography Standards. NIST Internal Report 8547, final, October 2026. doi:10.6028/NIST.IR.8547.
- [3]OpenSSH project. OpenSSH release notes: 8.5 (3 March 2021), 8.9 (23 February 2022), 9.0 (8 April 2022), 9.9 (19 September 2024), 10.0 (9 April 2025), 10.1 (6 October 2025) and 10.6 (6 October 2026).
- [4]P. Kampanakis, D. Stebila and T. Hansen. Post-Quantum/Traditional Hybrid Key Exchange with the Module-Lattice-Based Key-Encapsulation Mechanism for Use in SSH. RFC 10042, August 2026.
- [5]M. Friedl, J. Mojzis and S. Josefsson. Secure Shell (SSH) Key Exchange Method Using Hybrid Streamlined NTRU Prime sntrup761 and X25519 with SHA-512: sntrup761x25519-sha512. RFC 9941, April 2026.
- [6]Ubuntu. Ubuntu package archive: openssh-server in jammy (22.04 LTS), noble (24.04 LTS) and resolute (26.04 LTS). Read 12 November 2026.
- [7]Debian. Debian package archive: openssh-server in bullseye (11), bookworm (12, with bookworm-backports) and trixie (13). Read 12 November 2026.
- [8]Red Hat. Red Hat Enterprise Linux: Post-Quantum Cryptography. Red Hat Customer Portal. Read 12 November 2026.
- [9]Juniper Networks. Get Started with PQC. Junos OS documentation, undated. Read 12 November 2026.
- [10]Cisco. Cisco Quantum-Safe Communications Roadmap. Last updated 4 November 2026.
- [11]A. Becker, C. Wynn and M. Jenkins. Commercial National Security Algorithm (CNSA) Suite 2.0 Profile for SSH. Internet-Draft draft-becker-cnsa2-ssh-profile-07, October 2026, work in progress.