Tutorial

OpenSSH 10.6: update sshd without losing access

Security & Monitoring12 min read14 steps

OpenSSH 10.6 brings eight security fixes without naming a single one with a CVE, and your distribution most likely shows a completely different version number. For an agency that manages dozens of client servers, the question is not "should we move to 10.6?" but "do my servers carry these fixes, and what will applying them break?". This guide shows how to read the version that is actually running, spot the two changes that affect your scripts, and reload `sshd` without losing access to a single server.

Contents· What OpenSSH 10.6 publishes, and what it does not say1/13
  1. 01What OpenSSH 10.6 publishes, and what it does not say
  2. 02The security fixes in 10.6, as listed
  3. 03The version number does not tell you if you are patched
  4. 04What distributions ship as of October 22, 2026
  5. 05Inventory the version actually running
  6. 06What can break across a managed fleet
  7. 07Change, impact, action: the reference table
  8. 08Check the configuration before reloading sshd
  9. 09Roll out the update without locking yourself out
  10. 10Hardening: a procedure, not another checklist
  11. 11Troubleshooting: the messages you may run into
  12. 12Error messages and fixes
  13. 13A consistent fleet updates with a single procedure

What OpenSSH 10.6 publishes, and what it does not say

OpenSSH 10.6, and its portable release 10.6p1 used by Linux distributions, was released on October 6, 2026. The release notes announce "a number of security fixes", several new features and some small bugfixes. They list no CVE identifier and mention no exploitation in the wild: this guide sticks strictly to what they say.

The OpenSSH team adds a remark that matters to anyone running a fleet. It receives a large number of reports produced with AI tools, has seen several bugs discovered independently by different researchers, and concludes that attackers can find them too. It therefore announces more frequent releases, to ship fixes sooner instead of batching them.

For an agency, the consequence is concrete: updating OpenSSH is no longer a yearly event. You need a procedure that repeats safely, server after server, and that tells you each time what actually changed.

The security fixes in 10.6, as listed

  • sftp — the client validates paths returned by the server more strictly, so a server cannot make a recursive copy write outside its target directory.
  • GSSAPI — sshd only stores GSSAPI credentials after a successful authentication, and resets GSSAPI state before each attempt.
  • Compression — the LZ77 dictionary coder is disabled to close a side channel: text injected into one channel could help guess secrets flowing through another channel of the same session.
  • Usernames — ssh refuses the $ and \ characters in a username entered on the command line, to prevent shell injection through ProxyCommand or Match exec.
  • Certificates — ssh-keygen now handles Daylight Saving Time correctly when converting dates; the error could shift a certificate's expiry by one hour.
  • Compressed packets — a compressed payload can no longer inflate past the maximum packet length.
  • authorized_keys — the restrict keyword now also applies to tunnel forwarding (PermitTunnel, disabled by default).
  • none values — some options that accept none, including AuthorizedPrincipalsFile, were read as a file name when a Match block overrode them.

The version number does not tell you if you are patched

The objection comes fast: no CVE in the notes, no stable distribution ships 10.6, and a failed sshd restart can lock you out. Why deal with it now?

Because distributions do not follow upstream numbers. They keep the OpenSSH version they released with and backport fixes into it. Ubuntu did exactly that: the security packages published on October 14, 2026 for releases 22.04, 24.04 and 26.04 carry the eight fixes listed above, including the refusal of $ and \, while staying on 8.9p1, 9.6p1 and 10.2p1. Conversely, as of October 22, 2026, the Debian security tracker still marks the same issues as unfixed on Debian 12 and Debian 13, with no security advisory published; only the development branches forky and sid ship 10.6p1.

An up-to-date Ubuntu server on 9.6p1 is therefore better covered, on these specific points, than a Debian server on 10.0p1. What you check is the installed package and its changelog. The check-and-reload procedure, for its part, will be the same for every future update.

What distributions ship as of October 22, 2026

Scroll the table

DistributionOpenSSH package10.6 fixes
Debian 12 (bookworm)1:9.2p1-2+deb12u10Not backported according to the Debian tracker
Debian 13 (trixie)1:10.0p1-7+deb13u4Not backported according to the Debian tracker
Debian forky and sid1:10.6p1-1Included (upstream 10.6p1)
Ubuntu 22.04 LTS1:8.9p1-3ubuntu0.18Backported by the security update
Ubuntu 24.04 LTS1:9.6p1-3ubuntu13.20Backported by the security update
Ubuntu 26.04 LTS1:10.2p1-2ubuntu3.8Backported by the security update
AlmaLinux 88.0p1Check Red Hat and AlmaLinux advisories
AlmaLinux 9 and 109.9p1Check Red Hat and AlmaLinux advisories

Inventory the version actually running

  1. Read the client version

    ssh -V prints the version of the OpenSSH client and of its cryptographic library, on standard error. The client is what enforces the username check: on an admin workstation or a bastion, this is the version that counts.

  2. Read the server version

    sudo /usr/sbin/sshd -V prints the daemon version. The option exists since OpenSSH 9.2: on an older server, such as AlmaLinux 8 on 8.0p1, it is not recognised, and you go through the package manager instead.

  3. Read the installed package

    On Debian and Ubuntu: dpkg -s openssh-server | grep ^Version. On AlmaLinux and Rocky Linux: rpm -q openssh-server. Note the full number, distribution suffix included: that is what you compare with the table above.

  4. Look for the fixes in the package changelog

    On Debian and Ubuntu: apt changelog openssh-server | head -60. On AlmaLinux: rpm -q --changelog openssh-server | head -60. On Ubuntu, the SECURITY UPDATE entries mention for example "invalid chars in command-line username" or "incorrect use of LZ77 dictionary coder".

  5. Check that the service restarted

    An updated package protects nothing if the old daemon is still running. Compare systemctl show -p ActiveEnterTimestamp ssh (the service is called sshd on AlmaLinux) with the package installation date.

  6. Sweep the fleet in one command

    List your servers in servers.txt, one per line, then run: while read -r h; do printf '%s : ' "$h"; ssh -n -o BatchMode=yes "$h" 'dpkg -s openssh-server 2>/dev/null | grep ^Version || rpm -q openssh-server'; done < servers.txt. The output is one line per server, to sort by operating system family.

What can break across a managed fleet

The notes list three items as potentially incompatible changes; only one really affects your scripts.

The first is the refusal of $ and \ in a username entered on the command line, with user@host as well as with -l. ssh then stops with remote username contains invalid characters. Real-world cases: a domain account in the form DOMAIN\user, or a script that builds the ssh command from external data. A name written literally in the User directive of a Host block is not subject to the check; the source code shows, however, that a User built with % tokens is. In a ProxyJump, an invalid name on a jump host is refused with invalid username.

The second is compression: Compression yes is still accepted, but compresses less well without the LZ77 dictionary. Nothing breaks; a transfer over a slow link may simply take longer. The OpenSSH team recommends compressing at the application level rather than inside SSH.

The third, disabling GatewayPorts and StreamLocalForwarding, only concerns old platforms such as QNX 6 or SCO OpenServer 5, not your Linux servers. Two visible side effects come on top: scp -R prints a deprecation warning, and sshd logs by default, through the new WarnWeakCrypto option, clients that negotiate a key exchange that is not resistant to quantum computers.

Change, impact, action: the reference table

Scroll the table

Change in 10.6Impact on a fleetAction
`$` and `\` refused in a command-line usernameScripts and `DOMAIN\user` accounts failWrite the name literally in `User` within a `Host` block
LZ77 dictionary disabled`Compression yes` less effectiveCompress before the transfer (`tar`, `rsync -z`)
GSSAPI credentials stored only after successNone outside Kerberos authenticationTest a Kerberos login after the update
`restrict` applied to tunnelsA `restrict` key no longer opens a tunnelList service keys that rely on `PermitTunnel`
`none` values read correctly in `Match`An `AuthorizedPrincipalsFile none` finally disables the optionReview `Match` blocks with `sshd -T -C`
`scp -R` deprecatedWarning on standard errorDrop `-R`: the copy goes through the machine running `scp`
`WarnWeakCrypto` enabled on the serverNew lines in `sshd` logsSpot old clients that need updating
Daylight Saving Time fixed in `ssh-keygen`Certificate expiries previously off by one hourCheck certificates issued near a clock change

Check the configuration before reloading sshd

sshd -t checks the validity of the configuration file and of the keys, without starting anything. The manual page recommends it precisely for updating sshd reliably, since configuration options may change from one version to the next. No output and an exit code of 0: the file is readable.

sshd -T goes further: it prints the effective configuration, defaults included. This is your before-and-after snapshot. To check a Match block, simulate a connection with -C, for example sudo sshd -T -C user=deploy,host=bastion.your-domain.com,addr=203.0.113.10. The accepted keywords are user, host, addr, laddr, lport and rdomain.

The reload command depends on the family: the service is called ssh on Debian and Ubuntu, sshd on AlmaLinux and Rocky Linux. Sessions already open survive a reload. On recent Ubuntu, ssh.socket listens instead of the daemon: changing Port requires systemctl daemon-reload, then restarting ssh.socket.

Roll out the update without locking yourself out

  1. Keep a rescue session open

    Open an SSH session on the server, become root with sudo -i, and close it only at the very end. If the new configuration refuses connections, this is the session you fix it from.

  2. Snapshot the effective configuration

    sudo sshd -T > /root/sshd-T-before.txt. This file will tell you what the update changed, value by value.

  3. Update the packages

    Debian and Ubuntu: sudo apt update && sudo apt install --only-upgrade openssh-server openssh-client. AlmaLinux and Rocky Linux: sudo dnf upgrade 'openssh*'.

  4. Test the configuration

    sudo sshd -t && echo OK. If a line is refused, fix it before anything else: a daemon that cannot read its configuration will not start at the next server reboot either.

  5. Reload the service

    sudo systemctl reload ssh on Debian and Ubuntu, sudo systemctl reload sshd on AlmaLinux. The package has often restarted the service already: reloading costs nothing and guarantees that the configuration in use is the right one.

  6. Open a new connection from another terminal

    ssh -v [email protected]. Actually log in, with your usual key and user. Until this connection succeeds, the rescue session stays open.

  7. Compare before and after

    sudo sshd -T | diff /root/sshd-T-before.txt -. An unexpected line gets fixed now, not on the day a client calls.

  8. Extend to the fleet in waves, through the bastion

    One pilot server per operating system family first, the rest afterwards. If your access goes through a bastion, update it last, after checking your ProxyJump entries: the setup is described in our guide to an SSH bastion on a VPS.

Hardening: a procedure, not another checklist

This guide does not repeat sshd_config hardening: PasswordAuthentication no, PermitRootLogin, AllowUsers or AllowGroups and MaxAuthTries are covered in the hardening checklist for agencies and in initial hardening of a Linux server. One point does change with an upstream 10.6 sshd: the new PubkeyOptions max-pk-ok option lets a client test up to six public keys by default without those probes counting against MaxAuthTries. A low MaxAuthTries therefore stops rejecting the administrator who keeps many keys in their agent.

Troubleshooting: the messages you may run into

The messages below come from the OpenSSH 10.6p1 source code. They appear in the terminal for the client, and in the service log for the server (journalctl -u ssh or journalctl -u sshd). Always read the full message before acting: most of them point to the faulty line.

Error messages and fixes

  • remote username contains invalid characters — the name passed on the command line contains $, \ or another refused character; write the account literally in User within a Host block.
  • Bad configuration option: AgentSocketPath — an option introduced in 10.6 was copied to a server that does not know it; the message names the file and line, and sshd stops with terminating, 1 bad configuration options.
  • Missing privilege separation directory: /run/sshd — sshd -t was run while the service is stopped, on Debian or Ubuntu; create the directory with sudo mkdir -p /run/sshd, then run the test again.
  • warning: remote/remote -R copy mode is deprecated and will soon be removed — remove -R from your scp scripts before a future release ignores it.
  • invalid username — a ProxyJump jump host carries a refused name; move the name into a Host block dedicated to the bastion.
  • Changed port ignored on Ubuntu — ssh.socket still listens on the old port; run sudo systemctl daemon-reload, then sudo systemctl restart ssh.socket.

A consistent fleet updates with a single procedure

What makes an OpenSSH update risky is not the version: it is a fleet where every server has its own history. Three distributions, four ways of naming the service, scripts that pass usernames on the command line: every difference becomes an exception to handle by hand, often on an evening when a client is waiting.

An agency running ten or fifty servers has every reason to reduce these differences. One operating system family, one check procedure (sshd -t, sshd -T before and after, a rescue session), and an inventory that tells you in one command which package runs where. On ServOrbit.com, the agency space gathers your clients' portfolio — domain names, hosting accounts, VPS — and their renewal dates on a single platform. The update procedure itself stays yours: this guide describes it as is, so you can run it on every server.

Your clients' fleet in one place

An agency space to follow your clients' portfolio, from a domain's expiry date to a VPS's root access. You keep the client relationship, we run the infrastructure.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.

Message us on WhatsAppopens in a new tab