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 —
sshdonly 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 —
sshrefuses the$and\characters in a username entered on the command line, to prevent shell injection throughProxyCommandorMatch exec. - Certificates —
ssh-keygennow 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
restrictkeyword now also applies to tunnel forwarding (PermitTunnel, disabled by default). - none values — some options that accept
none, includingAuthorizedPrincipalsFile, were read as a file name when aMatchblock 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
| Distribution | OpenSSH package | 10.6 fixes |
|---|---|---|
| Debian 12 (bookworm) | 1:9.2p1-2+deb12u10 | Not backported according to the Debian tracker |
| Debian 13 (trixie) | 1:10.0p1-7+deb13u4 | Not backported according to the Debian tracker |
| Debian forky and sid | 1:10.6p1-1 | Included (upstream 10.6p1) |
| Ubuntu 22.04 LTS | 1:8.9p1-3ubuntu0.18 | Backported by the security update |
| Ubuntu 24.04 LTS | 1:9.6p1-3ubuntu13.20 | Backported by the security update |
| Ubuntu 26.04 LTS | 1:10.2p1-2ubuntu3.8 | Backported by the security update |
| AlmaLinux 8 | 8.0p1 | Check Red Hat and AlmaLinux advisories |
| AlmaLinux 9 and 10 | 9.9p1 | Check Red Hat and AlmaLinux advisories |
Inventory the version actually running
Read the client version
ssh -Vprints 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.Read the server version
sudo /usr/sbin/sshd -Vprints 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.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.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, theSECURITY UPDATEentries mention for example "invalid chars in command-line username" or "incorrect use of LZ77 dictionary coder".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 calledsshdon AlmaLinux) with the package installation date.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.6 | Impact on a fleet | Action |
|---|---|---|
| `$` and `\` refused in a command-line username | Scripts and `DOMAIN\user` accounts fail | Write the name literally in `User` within a `Host` block |
| LZ77 dictionary disabled | `Compression yes` less effective | Compress before the transfer (`tar`, `rsync -z`) |
| GSSAPI credentials stored only after success | None outside Kerberos authentication | Test a Kerberos login after the update |
| `restrict` applied to tunnels | A `restrict` key no longer opens a tunnel | List service keys that rely on `PermitTunnel` |
| `none` values read correctly in `Match` | An `AuthorizedPrincipalsFile none` finally disables the option | Review `Match` blocks with `sshd -T -C` |
| `scp -R` deprecated | Warning on standard error | Drop `-R`: the copy goes through the machine running `scp` |
| `WarnWeakCrypto` enabled on the server | New lines in `sshd` logs | Spot old clients that need updating |
| Daylight Saving Time fixed in `ssh-keygen` | Certificate expiries previously off by one hour | Check 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
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.Snapshot the effective configuration
sudo sshd -T > /root/sshd-T-before.txt. This file will tell you what the update changed, value by value.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*'.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.Reload the service
sudo systemctl reload sshon Debian and Ubuntu,sudo systemctl reload sshdon AlmaLinux. The package has often restarted the service already: reloading costs nothing and guarantees that the configuration in use is the right one.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.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.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
ProxyJumpentries: 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 inUserwithin aHostblock.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, andsshdstops withterminating, 1 bad configuration options.Missing privilege separation directory: /run/sshd—sshd -twas run while the service is stopped, on Debian or Ubuntu; create the directory withsudo mkdir -p /run/sshd, then run the test again.warning: remote/remote -R copy mode is deprecated and will soon be removed— remove-Rfrom yourscpscripts before a future release ignores it.invalid username— aProxyJumpjump host carries a refused name; move the name into aHostblock dedicated to the bastion.- Changed port ignored on Ubuntu —
ssh.socketstill listens on the old port; runsudo systemctl daemon-reload, thensudo 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.