Stay on the latest OpenSSH without upgrading your entire distro.
This project rebuilds the official Debian Sid OpenSSH source package for older Debian and Ubuntu releases. You get the newest security fixes and features as native .deb packages — with Debian's patches, systemd integration, and packaging intact — so you can keep long-term-stable systems secure without a full OS upgrade.
Similar project: openssh-rpms — Backport OpenSSH RPM for CentOS
Prebuilt packages are tested and published via GitHub Actions. Other architectures can be built from source.
| Distribution | Codename | Architectures | Notes |
|---|---|---|---|
| Ubuntu 24.04 LTS | noble |
amd64 / arm64 |
✅ Fully supported |
| Ubuntu 22.04 LTS | jammy |
amd64 / arm64 |
✅ Fully supported |
| Ubuntu 20.04 LTS | focal |
amd64 / arm64 |
✅ Fully supported |
| Ubuntu 18.04 LTS | bionic |
amd64 / arm64 |
✅ Fully supported |
| Debian 13 | trixie |
amd64 / arm64 |
✅ Fully supported |
| Debian 12 | bookworm |
amd64 / arm64 |
✅ Fully supported |
| Debian 11 | bullseye |
amd64 / arm64 |
✅ Fully supported |
| Debian 10 | buster |
amd64 / arm64 |
✅ Fully supported |
| UnionTech OS Desktop 20 Home | based on buster / glibc 2.28 | — | |
| Kylin V10 SP1 | based on focal / glibc 2.31 | — |
Need another architecture? Any Debian/Ubuntu derivative with a compatible glibc can build from source — see Build from Source.
Versions are pinned in version.env. When OPENSSH_SIDPKG is empty, the build automatically picks the latest version from Debian Sid.
| Component | Version | Source |
|---|---|---|
| OpenSSH | 10.5p1-1 |
Debian Sid — auto-tracked |
| OpenSSL | 3.5.8 |
Static link on older distros, dynamic link on newer ones |
The built package version is suffixed with the target codename (e.g. 10.5p1-1~noble) so it is clearly distinguishable from the distro's official package and won't be silently overwritten.
If your OS is in the table above, the fastest way is to install the CI-built .debs:
sudo bash -c "$(curl -L https://github.com/boypt/openssh-deb/raw/master/lazy_install.sh)"Behind a firewall or need a GitHub proxy?
sudo bash -c "$(curl -L https://gh-proxy.com/github.com/boypt/openssh-deb/raw/master/lazy_install.sh)" @ gh-proxy.comThe script detects your codename and architecture, downloads the matching release tarball from the latest GitHub Release, and installs it with apt.
To revert to the distro-provided OpenSSH later, see Rolling Back to the Distro Default.
The build must run in three steps in order:
# 1. Fetch OpenSSH sources from Debian Sid + sid debhelper debs for old distros
./pullsrc.sh
# 2. Fix apt sources for EOL releases and install build dependencies
./install_deps.sh
# 3. Compile — output goes to output/
./compile.shUseful environment variables:
| Variable | Effect |
|---|---|
FORCESSL=1 |
Force static OpenSSL even when libssl-dev >= 3.0 is available |
APT_MIRROR=mirrors.ustc.edu.cn |
Use a custom apt mirror (also applied when switching EOL Debian sources to archive.debian.org) |
Build artefacts:
| Directory | Contents |
|---|---|
downloads/ |
Fetched source tarballs (gitignored) |
build/ |
Ephemeral build tree (gitignored) |
builddep/ |
Sid debhelper .debs downloaded by pullsrc.sh (gitignored) |
output/ |
Final .deb packages |
Install the result:
ls -l output/*.deb
sudo apt install -y output/*.debBuild without polluting your host, or target a different distro than your host:
# Fetch sources on the host first (host has a current CA store; old containers may not)
./pullsrc.sh
# Build for e.g. Ubuntu 20.04
docker run --rm -v "$(pwd):/work" -w /work ubuntu:20.04 bash -c "./install_deps.sh && ./compile.sh"
docker builder pruneWith a mirror or proxy inside the container:
docker run --rm -v "$(pwd):/work" -w /work \
-e APT_MIRROR=mirrors.ustc.edu.cn \
-e http_proxy=http://proxy.example.com:8080 \
-e https_proxy=http://proxy.example.com:8080 \
ubuntu:20.04 bash -c "./install_deps.sh && ./compile.sh"Why fetch sources on the host? Minimal or EOL images often ship outdated
ca-certificatesand cannot verify GitHub's TLS chain. The release CI uses the same pattern: run./pullsrc.shon the host runner, then mount the repo into the container.pullsrc.shalso populatesbuilddep/with the Siddebhelperdebs thatinstall_deps.shneeds on distros withdebhelper < 13.12.
Dockerfile.deps for CI
For reproducible CI images:
./pullsrc.sh debhelper # populate builddep/ only
docker build --build-arg BASE_IMAGE=ubuntu:noble -f docker/Dockerfile.deps -t <tag> .docker/Dockerfile.deps uses BuildKit --mount=type=bind for install_deps.sh and builddep/, so they don't end up in image layers. BuildKit is required (default on modern Docker).
sudo apt update
V=$(apt-cache madison ssh | awk 'NR==1 {print $3}')
sudo apt install --allow-downgrades -y \
ssh=$V openssh-client=$V openssh-server=$V openssh-sftp-server=$VSince OpenSSH 9.8, the per-connection daemon was renamed from sshd to sshd-session. Tools that match on the process name will miss new sessions unless updated.
Affected software: fail2ban, sshguard, and similar log monitors.
In filter.d/sshd.conf, change:
_daemon = sshdto:
_daemon = sshd(?:-session)?Then restart fail2ban. sshguard and other tools need analogous updates — check their docs for OpenSSH 9.8+ compatibility.
Debian glibc 2.28-21-1+deepin-1
- Exclude
libfido2-devfrom the build-dependency install — it is not available. - Manually install from
bullseye:
Ubuntu glibc 2.31-0kylin9.2k0.1
Run ./compile.sh from a desktop terminal (mate-terminal), not over SSH. Installing builddep/*.deb triggers a kysec_auth authorization dialog that requires a manual click — it will fail silently in a headless SSH session.
The build starts from the unmodified Debian Sid source package and applies only the minimal compatibility shims needed for older toolchains:
- No test or udeb packages —
openssh-testsis excluded (BUILD_PACKAGES += -Nopenssh-tests),DEB_BUILD_PROFILES="noudeb pkg.openssh.nognome"andDEB_BUILD_OPTIONS="noddebs nocheck"skip udebs, GNOME askpass, and the build-time test suite. - Codename suffix —
~${BUILD_CODENAME}is appended to the version indebian/changelog. - OpenSSL linkage (decided at build time from the installed
libssl-dev):- Dynamic — if
libssl-dev >= 3.0.0andFORCESSLis unset: links against the system OpenSSL, no extra compilation. - Static — if
libssl-dev < 3.0.0orFORCESSL=1: builds OpenSSL${OPENSSLVER}from source, removeslibssl-devfromdebian/control, and injects--with-ssl-dirplusLD_LIBRARY_PATHintodebian/rules.
- Dynamic — if
- Security-key / FIDO2 — if
libfido2-dev < 1.5.0, removes it from build deps and flipswith-security-key-builtintodisable-security-key. - wtmpdb — if
libwtmpdb-devis unavailable, strips it and--with-wtmpdb. - init-system-helpers — relaxes the versioned dependency from
1.66to1.50when the installed version is older. - EOL apt sources —
install_deps.shautomatically rewrites EOL Debian sources toarchive.debian.org(including-backports), unconditionally for bothbusterandbullseye; bullseye-security is commented out as archive.debian.org does not carry it yet. The retiredswitch_archive_sources.shis no longer needed. - Additional portability shims in
compile.sh— handleslibcrypt-dev,dh-runit/runit-helper,systemdsysusers, and non-merged-/usrlayouts as needed.
- Find the latest Sid version:
wget -qO- http://deb.debian.org/debian/pool/main/o/openssh/ \ | grep -oP 'openssh_\K[0-9]+\.[0-9]+p[0-9]+-[0-9]+(?:~bpo[0-9]+(?:\+[0-9]+)?)?' \ | sort -V | tail -n 1
- Update
OPENSSH_SIDPKGinversion.envand the version table inREADME.md. - Commit:
git add README.md version.env && git commit -m "bump version to <new-version>" - Tag:
git tag v<new-version>_b1(_b1= build 1; increment on rebuilds) - Push:
git push && git push --tags