Securing SSH with post-quantum algorithms

Securing SSH with post-quantum algorithms

·4 min read·Updated on January 13, 2026

Why post-quantum, and why now

The usual objection — "quantum computers are far off" — ignores a very concrete, present-day threat: harvest now, decrypt later. An attacker captures encrypted traffic today, stores it, and waits twenty years for quantum technology to decrypt it retroactively.

For a home NAS the risk stays limited. But OpenSSH has supported post-quantum algorithms since 9.x and Debian 13 ships a recent enough version, so the good habits may as well start now.

Host keys

By default Debian generates ECDSA, Ed25519 and RSA. Drop ECDSA and DSA (obsolete) and keep only Ed25519 and RSA 4096:

# Remove unwanted host keys
rm -f /etc/ssh/ssh_host_ecdsa_key*
rm -f /etc/ssh/ssh_host_dsa_key*

# Regenerate the RSA key at 4096 bits if needed
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""

Then be explicit in sshd_config:

# /etc/ssh/sshd_config - Host keys
 HostKey /etc/ssh/ssh_host_ed25519_key
 HostKey /etc/ssh/ssh_host_rsa_key
 HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

Ed25519 first — compact, fast, Curve25519-based — with RSA 4096 as backup for out-of-date clients.

Post-quantum key exchanges

OpenSSH offers hybrid algorithms combining a classical exchange (X25519) with a post-quantum one. If the post-quantum algorithm turns out weak, classical security still holds — and vice versa.

# /etc/ssh/sshd_config - Key exchange
KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com,curve25519-sha256,diffie-hellman-group16-sha512
  • mlkem768x25519-sha256: hybrid ML-KEM 768 (NIST FIPS 203 standard, formerly CRYSTALS-Kyber) + X25519. The most recent option and the current recommendation.
  • sntrup761x25519-sha512@openssh.com: hybrid NTRU Prime 761 + X25519, in OpenSSH for longer, an excellent fallback.
  • curve25519-sha256: classical exchange, for clients without post-quantum support.
  • diffie-hellman-group16-sha512: classical DH as a last resort.

Ciphers and MACs

# /etc/ssh/sshd_config - Ciphers
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

ChaCha20-Poly1305 by default, fast and well studied; the AES-GCM options for machines with AES-NI acceleration, including the Intel N95.

Hardened authentication

SSH keys only, no passwords:

# /etc/ssh/sshd_config - Authentication
 PermitRootLogin no
 PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30

PermitRootLogin no forces logging in as nasadmin then using sudo, MaxAuthTries 3 limits brute-forcing, and LoginGraceTime 30 narrows the authentication window to thirty seconds, which discourages bots quickly.

Warning banner

Often overlooked, yet mandatory in some jurisdictions to be able to prosecute an intrusion attempt:

# /etc/ssh/sshd_config
Banner /etc/ssh/banner.txt
# /etc/ssh/banner.txt
*************************************************************
WARNING: Unauthorized access to this system is prohibited.
All connections are monitored and recorded.
By connecting, you agree to comply with applicable policies.
*************************************************************

Ansible automation

All of it is deployed through an Ansible role built on the devsec.hardening collection, which applies hundreds of CIS- and ANSSI-based rules:

# playbook.yml - excerpt
- name: Harden SSH
  hosts: nas
  roles:
    - role: devsec.hardening.ssh_hardening
      vars:
        ssh_kex:
          - mlkem768x25519-sha256
          - sntrup761x25519-sha512@openssh.com
          - curve25519-sha256
          - diffie-hellman-group16-sha512
        ssh_host_key_algorithms:
          - ssh-ed25519
          - rsa-sha2-512
          - rsa-sha2-256
        ssh_ciphers:
          - chacha20-poly1305@openssh.com
          - aes256-gcm@openssh.com
          - aes128-gcm@openssh.com
        ssh_allow_users: nasadmin
        ssh_max_auth_retries: 3

The playbook is idempotent: running it fifty times changes nothing.

Client side and verification

An Ed25519 key on the client, and a check of supported algorithms:

# Generate an Ed25519 key
ssh-keygen -t ed25519 -C "user@workstation"

# Check supported algorithms
ssh -Q kex

If mlkem768x25519-sha256 appears in the output, the client is compatible. After deployment, validate the actual negotiation:

ssh -vv nasadmin@192.168.1.50 2>&1 | grep "kex:"

# Expected result:
# debug1: kex: algorithm: mlkem768x25519-sha256

Configuring SSH for post-quantum is neither complex nor costly in performance: with OpenSSH 9.x and Debian 13 everything is available, you just set the right parameters and let Ansible do the rest.

ShareLinkedInXBluesky

Related articles