OpenSSH 10.4, released on 6 July 2026, includes security fixes and makes the SSH transport protocol stricter. That combination is a good reason to plan an update, but it is also a reason not to treat a remote-access service like an ordinary package refresh. A syntactically valid sshd_config can still lock out the only administrator who has the required key, source address, or jump host path.
This guide prepares a Linux host for a distribution-provided OpenSSH 10.4 update. The result is a recorded effective server configuration, a tested administrative connection, and a rollback-safe update sequence. The commands are documentation-verified examples, not observations from a particular host. Run them from a console, out-of-band management session, or a second SSH session that remains open until the new daemon has accepted a fresh connection.
Start with the access path
Before inspecting configuration, write down how the host is normally reached. Record the account name, the hostname or address, the port, whether a bastion is involved, and the client key or certificate used for administration. This is not paperwork for its own sake: Match blocks can make the effective configuration differ by user, source address, local address, or destination port.
Keep the current administrative session open. If the host has a serial console, IPMI/iDRAC-style remote console, hypervisor console, or cloud provider recovery console, confirm that it works before the maintenance window. Do not count a second terminal multiplexed over the same SSH connection as independent recovery access.
From the administrator workstation, make a fresh verbose connection in a separate terminal. Replace the placeholders with the normal management path.
ssh -vvv -p <ssh-port> <admin-user>@<server-name>
The verbose log is useful before and after the update. It identifies the host-key algorithm, the negotiated key-exchange, cipher and MAC or AEAD, the offered authentication keys, and the point where authentication succeeds. Save it with the change record only after removing hostnames, user names, and paths where those are sensitive.
If a client configuration is involved, ask the client to show its resolved settings instead of guessing which Host stanza won. OpenSSH documents ssh -G as configuration-dump mode.
ssh -G -p <ssh-port> <server-name> | sort
This is especially useful with Include, Match, proxy jumps, hardware-backed keys, and site-wide crypto policy. Treat the output as a local client view. It does not prove that the server will accept the connection, but it makes an unexpected port, identity file, proxy command, or algorithm preference visible before the server changes.
Inspect configuration without editing it
On the server, identify the package version and the configuration files the distribution owns. The package command varies, so use the one appropriate to the host.
ssh -V
rpm -q openssh-server # RPM-based distributions
# or
apt-cache policy openssh-server # Debian-family distributions
sudo find /etc/ssh -maxdepth 2 -type f -name '*.conf' -o -name 'sshd_config'
The find command is an inventory aid, not a promise that every listed file is included. Modern distributions often place local policy in /etc/ssh/sshd_config.d/. Check the main configuration for Include directives and preserve the package’s file ordering. A broad replacement of sshd_config can quietly discard vendor defaults or configuration supplied by a management system.
First, parse the configuration without restarting the daemon.
sudo sshd -t
A zero exit status means the daemon accepted the configuration syntax and can read the referenced files with its current privileges. It does not prove that a particular administrator can log in. In particular, a configuration can pass this check while AllowUsers, AllowGroups, DenyUsers, AuthenticationMethods, Match, or an address-specific ListenAddress excludes the intended connection.
Next, dump the effective configuration. OpenSSH 10.4 changed the sshd -G output so directives are written one per line, which makes the result more reliable to inspect or compare. Use -C to supply the connection facts that matter to a Match rule.
sudo sshd -T | sort
sudo sshd -T -C user=<admin-user>,addr=<admin-client-ip>,host=<server-name>,laddr=<server-ip>,lport=<ssh-port> | sort
-T checks and prints the effective server configuration. The second form asks sshd to evaluate conditional rules as though the named user connected from the stated client address to the listed local address and port. Some portable OpenSSH builds use the same options but may differ in their vendor defaults; use the local sshd(8) manual page as the final reference.
Review the values that define access rather than trying to read every default: port, listenaddress, passwordauthentication, kbdinteractiveauthentication, pubkeyauthentication, authenticationmethods, permitrootlogin, allowusers, allowgroups, denygroups, authorizedkeysfile, and usepam. Also record hostkey, hostkeyalgorithms, pubkeyacceptedalgorithms, kexalgorithms, ciphers, and macs if the site has explicit cryptographic policy.
Do not add legacy algorithms merely because an old client may fail later. First identify the device or software that needs an exception and test it against a non-production host when possible. OpenSSH can list algorithms supported by the installed client:
ssh -Q key
ssh -Q key-sig
ssh -Q KexAlgorithms
ssh -Q cipher
ssh -Q mac
The output is a capability list, not a negotiated result and not necessarily the distribution’s system crypto policy. A system-wide policy layer can remove or constrain algorithms even when the binary knows about them. Keep compatibility exceptions narrow, time-limited, and documented; an exception for one old device should not weaken every inbound administrative connection.
Capture a safe pre-update state
Make a privileged backup of the SSH configuration and record its checksum. Do not copy private host keys into a ticket, source repository, or shared chat channel.
stamp=$(date +%F-%H%M%S)
sudo install -d -m 0700 /root/ssh-preupgrade
sudo tar -C /etc -czf "/root/ssh-preupgrade/ssh-$stamp.tgz" ssh
sudo sha256sum "/root/ssh-preupgrade/ssh-$stamp.tgz" \
> "/root/ssh-preupgrade/ssh-$stamp.tgz.sha256"
sudo systemctl status --no-pager sshd || sudo systemctl status --no-pager ssh
The archive is a configuration recovery aid, not a replacement for a host backup. Store it under the host’s protected backup policy if the maintenance standard requires that. Check the actual service unit before planning a restart: RPM-based systems commonly use sshd.service; Debian-family systems commonly use ssh.service.
Also capture the current listener and process state:
sudo ss -ltnp | grep -E ':(22|<ssh-port>)\b'
ps -ef | grep '[s]shd'
If SSH listens on a non-default port, replace 22 in the expression or remove that alternative. The expected result is a listener on the intended local address and port, owned by sshd. If a firewall, load balancer, or bastion is in the path, its health check should be part of the maintenance plan too. A local listener alone cannot prove the path is reachable.
Update one service, then prove the path
Read the distribution’s update advisory and package transaction before applying it. In a managed fleet, use the approved package repository and orchestration process rather than downloading a portable OpenSSH archive to an individual host. Package scripts may restart the service automatically, so schedule the change accordingly.
On an RPM-based host, a controlled update might be:
sudo dnf upgrade openssh openssh-server
sudo sshd -t
sudo systemctl restart sshd
sudo systemctl status --no-pager sshd
On a Debian-family host, use the equivalent approved package transaction and service unit:
sudo apt-get update
sudo apt-get install --only-upgrade openssh-client openssh-server
sudo sshd -t
sudo systemctl restart ssh
sudo systemctl status --no-pager ssh
Do not close the original session after the restart. From the separate administrator terminal, make a new verbose login through the normal route. Confirm that the host key matches the expected known-hosts entry and that the intended key, certificate, MFA, or other required factor succeeds. Then run a simple command that proves the expected account and host were reached.
ssh -vvv -p <ssh-port> <admin-user>@<server-name> 'id; hostnamectl --static'
Compare the new negotiation lines with the saved pre-update log. A changed algorithm is not automatically a failure, but an unexpected fallback, a host-key warning, repeated authentication prompt, or a disconnect during key exchange needs investigation before the window closes. Inspect the service journal for configuration and authentication errors:
sudo journalctl -u sshd --since '15 minutes ago' --no-pager
# or
sudo journalctl -u ssh --since '15 minutes ago' --no-pager
If the new daemon fails its syntax check or a new administrative connection cannot be made, use the retained session or console to restore the known-good configuration, run sshd -t again, and restart the correct unit. Do not repeatedly restart a daemon whose error has not been read. If a package-level rollback is required, follow the distribution’s documented procedure and the local change policy; configuration restoration alone cannot fix a defective package transaction.
Finish with evidence
OpenSSH 10.4’s security fixes and stricter protocol handling make patching worthwhile, but a successful package install is not the success condition. The useful result is a service with a validated effective configuration, a preserved recovery route, and a new connection through the same path administrators use during an incident. Keep the version, configuration checksum, client negotiation evidence, service status, and any compatibility exception with the change record.