Restricting SSH key exchange algorithms keeps remote administration hardened against downgrade attacks and aging cryptography. A small, explicit list of strong KEX values removes weak defaults such as SHA‑1 based Diffie‑Hellman groups and satisfies scanners that flag legacy algorithms during compliance checks.

In OpenSSH, the key exchange phase is controlled by the KexAlgorithms directive in /etc/ssh/sshd_config, which defines both the algorithms a server offers and their preference order. Modern releases ship with robust options such as curve25519-sha256 plus hybrid post‑quantum schemes like sntrup761x25519-sha512@openssh.com and mlkem768x25519-sha256, and commands like sshd -Q kex and sshd -T reveal the supported and currently active lists before any hardening takes place.

Enforcing only strong KEX algorithms must balance compatibility against strictness because older clients, embedded appliances, and some libraries may lack support for curve25519, post‑quantum hybrids, or very large Diffie‑Hellman groups. The procedure below assumes a Linux server running a recent OpenSSH with systemd; configuration validation with sshd -t and access to a console or out‑of‑band method remains critical in case a malformed /sshd_config blocks new SSH logins.

Steps to enforce strong key exchange algorithms in SSH:

  1. Open a terminal session on the SSH server with access to sudo or root privileges.
    $ whoami
    user
  2. List all key exchange algorithms supported by the installed OpenSSH daemon.
    $ sudo sshd -Q kex | sort
    curve25519-sha256
    curve25519-sha256@libssh.org
    ecdh-sha2-nistp256
    ecdh-sha2-nistp384
    ecdh-sha2-nistp521
    diffie-hellman-group-exchange-sha256
    diffie-hellman-group16-sha512
    diffie-hellman-group18-sha512
    diffie-hellman-group14-sha256
    ##### snipped #####

    sshd -Q kex prints the algorithms compiled into the daemon, which must exist before being referenced by KexAlgorithms.

  3. Display the effective key exchange configuration that the running sshd instance will use.
    $ sudo sshd -T | grep -i kexalgorithms
    kexalgorithms mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256

    If no kexalgorithms line appears, the daemon is using its built‑in defaults and will adopt any explicit KexAlgorithms directive added to /sshd_config.

  4. Create a timestamped backup of the existing /etc/ssh/sshd_config file before editing.
    $ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d-%H%M%S)

    A backup copy enables recovery over console or rescue access if a new configuration prevents SSH logins.

  5. Open /etc/ssh/sshd_config in a text editor such as nano to change the key exchange settings.
    $ sudo nano /etc/ssh/sshd_config
  6. Add or update a KexAlgorithms directive so that only strong, SHA‑2 or post‑quantum key exchanges are offered.
    # Strong KEX set without post-quantum algorithms
    KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256
    
    # Optional: include post-quantum KEX first if supported by `sshd -Q kex`
    # KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256

    Avoid SHA‑1 based KEX values such as diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1, and ensure every algorithm listed in KexAlgorithms appears in the sshd -Q kex output.

  7. When only removing weak algorithms instead of rewriting the entire list, use a KexAlgorithms line with a leading minus to subtract them from the defaults.
    # Example: drop legacy SHA-1 based groups from the default list
    KexAlgorithms -diffie-hellman-group1-sha1,-diffie-hellman-group-exchange-sha1

    Subtractive syntax keeps pace with future strong defaults while suppressing known‑weak algorithms that vulnerability scanners report.

  8. Save the configuration file in the chosen editor and return to the shell prompt once the KexAlgorithms directive matches the desired policy.
  9. Validate the modified SSH configuration before restarting the service.
    $ sudo sshd -t

    No output from sshd -t indicates syntactically valid configuration and allows a safe service restart.

  10. Restart the SSH service to load the new key exchange settings.
    $ sudo systemctl restart ssh

    Restarting ssh replaces the daemon process; if validation was skipped or failed, new SSH connections can break until the configuration is corrected over console access.

  11. Confirm that the SSH service is active after the restart.
    $ sudo systemctl status ssh
    ● ssh.service - OpenBSD Secure Shell server
         Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
         Active: active (running) since Thu 2025-12-11 12:34:56 UTC; 5s ago
    ##### snipped #####
  12. From a test client, initiate a verbose SSH connection and confirm that a strong key exchange algorithm is negotiated.
    $ ssh -vv [email protected]
    ##### snipped #####
    debug2: KEX algorithms: mlkem768x25519-sha256,sntrup761x25519-sha512@openssh.com,curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256
    ##### snipped #####
    debug1: kex: algorithm: mlkem768x25519-sha256
    ##### snipped #####

    The kex: algorithm line must show one of the configured strong algorithms so that external audits and vulnerability scans no longer report weak SSH key exchange support.

Discuss the article:

Comment anonymously. Login not required.