# openssh-rpms: backporting upstream OpenSSH to CentOS and the RHEL family

> This repository builds RPM packages of upstream OpenSSH for CentOS, RHEL and the distributions that clone it, from spec files derived from the OpenSSH project's own spec and three template directories for the older init systems. It publishes ready-made zips per platform and architecture, and the readme explains why the config backup step is not optional.

**boypt/openssh-rpms** — A script to backport openssh rpm package from upstream.

- Repository: https://github.com/boypt/openssh-rpms
- Stars: 533 · Forks: 179
- Language: Shell
- License: not declared
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/boypt-openssh-rpms

## The gap the project fills

The openssh-rpms repository is a script to backport the OpenSSH RPM package from upstream, and the readme describes it as a script to backport upstream OpenSSH for CentOS and RHEL-like distributions.

That problem is specific and well known. Enterprise Linux platforms ship OpenSSH in their own package repositories, and those packages move slowly because they are tied to the platform's long support lifecycle. When an OpenSSH release fixes a security issue, an administrator on an older platform has to wait for the platform vendor, or take matters into their own hands.

This project is the second option, and it is a well-trodden path. The readme notes a similar project for Debian and Ubuntu distributions, so the approach is familiar to anyone who has dealt with a stale SSH package on an old distribution.

The primary language is Shell, and the build is driven by two scripts rather than by a build system. pullsrc.sh downloads the source packages and compile.sh builds the RPMs, with a version.env file holding the version definitions, the release number and the OpenSSL mode. The build script reads version.env for its version definitions, so changing the version you are building against is an edit to one file.

The current versions are given in the readme: OpenSSH 10.6p1 and OpenSSL 3.5.9, and OpenSSL is not needed when using WITH_OPENSSL=0, which is set in version.env.

The recent releases follow the upstream version scheme with a build counter, v10.6p1_b2 from 2026-10-06, v10.5p1_b5 from 2026-08-26 and v10.5p1_b2 from 2026-08-11. The last push was on 2026-10-06, so the releases follow the upstream cadence closely rather than lagging it.

## The spec files and the three template directories

The build recipes come from upstream rather than being written from scratch, and that is the key decision in the project.

The readme says the directory el5, el6 and el7 serve as functional templates for different environment types, and that the openssh.spec files are modified based on the shipped spec file from the OpenSSH project.

So the spec is upstream's, adjusted for the platform. That matters more than it sounds, because an OpenSSH spec file is a large piece of configuration that encodes the build flags, the file layout, the service integration and the subpackages. Rewriting it from scratch for each platform would be a large and error-prone job, and the result would drift from upstream with every release. Starting from upstream's file and modifying it means the backport tracks the upstream design.

The three template directories split on the init system and the toolchain, which is the real compatibility boundary.

The el5 directory is designed for legacy environments, with toolchains such as Perl to support the build process. The el6 directory is the one with SysVinit startup. The el7 directory uses a systemd service.

And there is an important note about the newest platforms: the systemd units in el7 are applicable not only to EL7 but also to EL8, EL9 and other modern distributions that rely on systemd. That is why three directories cover more than three releases, and it means a modern platform build does not need its own template.

The repository layout at the top level is consistent with that: el5/, el6/, el7/, plus the two scripts, version.env, a docker/ directory, a downloads/ directory for source files, and an AGENTS.md.

## Which platforms are covered, and how the tags map

The supported distro table is long and it is the most useful page in the repository, because it tells you which build to download for a given machine.

CentOS is covered from version 5 through 8 and CentOS Stream 8 and 9. Rocky Linux and AlmaLinux are covered at 8 and 9. Oracle Linux at 7, 8 and 9. Amazon Linux at 1, 2 and 2023. UnionTech UOS at V20. openEuler at 20.03, 22.03 and 24.03. AnolisOS at 7, 8 and 2023.

Each row gives the architecture and a recommended tag, and the pattern in the recommended column is worth understanding. A CentOS 5 machine gets the EL 5 tag, a CentOS 6 machine gets EL 6, and a Rocky 8 machine gets EL 8. The tag names are rpm-el5-x86_64, rpm-el6-x86_64 and so on, with aarch64 variants where the platform supports it.

The reason for the EL mapping is glibc compatibility, which the readme explains later in the usage section: it is unnecessary to build on each system, as most RPM-based Linux distributions are glibc compatible. That is, RPMs built on CentOS 8 can be installed and run on Rocky Linux 8, AlmaLinux 8, Oracle Linux 8 and similar.

So the EL level is the compatibility target, and the many distributions in the table are simply the ones that share a glibc generation. Amazon Linux 1 is the outlier, mapping to EL 6, and Amazon Linux 2 maps to EL 7.

UnionTech UOS is the one genuinely different entry. It is bolded in the table and its recommended tag is UOS20, with rpm-uos20-x86_64 and rpm-uos20-aarch64, so it has its own template rather than reusing an EL one.

There is also a note about the aarch64 builds, which is a detail that catches people out. aarch64 RPMs are built from the same el7/ spec via aarch64_el7/8/9 Docker tags, for example ghcr.io/boypt/openssh-rpms:aarch64_el7, and they are QEMU-built with per-arch tags, not multi-arch manifests. That last clause matters if you are pulling images, because a per-arch tag is not something a multi-arch aware runtime can resolve for you.

## Downloading rather than building

The primary route is to download a prebuilt zip, and the readme is explicit that no script or GitHub API is needed.

Go to the releases page and download the zip file that matches your system. Each release provides one zip per tag, named openssh_<version>_<tag>.zip, for example openssh_v10.5p1_b1_rpm-el8-x86_64.zip.

The three steps are: find your distro in the supported table and note the tag in the recommended column, download the zip whose name ends with that tag, and unzip it.

```bash
unzip openssh*.zip
```

That is a deliberately boring workflow, and it is the right one for the audience. The people who need this are system administrators updating an SSH package on a production machine, and the fewer moving parts the better.

The build route exists for people who need to go further. The steps are to install the build requirements, edit version.env if necessary, download the source packages with the pullsrc.sh script, and run compile.sh. The generated RPM files are then copied to the output directory.

```bash
    ./pullsrc.sh
```

```bash
    ./compile.sh
```

If any error comes up during the source download, the readme says to manually download the source files into the downloads directory, which tells you the directory is where the script expects to find them.

The build requirements are a yum line, and the comments in it are the interesting part:

```bash
yum install -y autoconf automake gcc make rpm-build pam-devel krb5-devel zlib-devel libXt-devel libX11-devel gtk2-devel perl perl-IPC-Cmd perl-Time-Piece

# For CentOS7 and above:
yum install -y systemd-devel

# For CentOS5 only:
yum install -y gcc44
```

The last line is the one that explains the EL5 template. CentOS 5 needs a specific gcc, gcc44, and the el5 directory mentions Perl toolchains for the same reason: these are old platform build environments with old compilers.

The X11 and GTK libraries have a narrower purpose, and the readme explains that libXt-devel, libX11-devel and gtk2-devel are only relevant to the EL6 and EL7 era askpass subpackages, that the EL8 and later spec skips them because compile.sh passes no_gtk2, skip_gnome_askpass and skip_x11_askpass set to 1, and that the CentOS Stream Dockerfile does not install them either.

## Installing, and why the config backup is not optional

The install section is where the readme does something worth reading carefully, because it explains a consequence of the package design that would otherwise surprise you.

```bash
ls output
# you will find multiple RPM files in this directory.
# you may copy them to other machines, and continue following steps there.

# Backup current SSH config by moving it away — the new package then
# lays down a fresh stock config, which also avoids breakage from old
# directives (notably the GSSAPI* series) removed upstream.
[[ -f /etc/ssh/sshd_config ]] && mv /etc/ssh/sshd_config /etc/ssh/sshd_config.$(date +%Y%m%d)

# Install rpm packages (`dnf` works the same on EL8/EL9).
sudo yum --disablerepo=* localinstall -y ./openssh*.rpm

# Check Installed version:
ssh -V && /usr/sbin/sshd -V
```

So the instruction is to move the existing config aside rather than back it up, and the reason given is in the comment. The new package lays down a fresh stock configuration, which also avoids breakage from old directives, notably the GSSAPI series, removed upstream.

That is a real consequence of the spec being derived from upstream's. A spec that ships a stock sshd_config will replace yours on upgrade unless the file is marked as a config with noreplace. The readme then explains what happens if you skip the backup step: rpm kept your old config and saved the package defaults as sshd_config.rpmnew, because the spec marks it as %config(noreplace).

So there are two paths and both are documented. Move the file aside and you get the fresh upstream configuration. Leave it and you keep your old configuration with any directives that upstream has since removed still in place, which is where breakage comes from.

The install command itself disables all repositories with --disablerepo=* and installs from the local files, which avoids the package manager pulling a different OpenSSH from the configured repositories as a dependency. The note that dnf works the same on EL8 and EL9 confirms the command is not yum-specific in behaviour.

The verification step runs both ssh -V and /usr/sbin/sshd -V, so you can check both the client and the server versions, which matters because a package that updates one and not the other is a different problem from a package that updates neither.

## Conclusion

Adopt openssh-rpms if you run an Enterprise Linux platform and need current OpenSSH without waiting for your distribution's own packages, since the project exists to close exactly that gap. Do not adopt it if your distribution already ships a recent OpenSSH, because the value here is entirely in the backport. Before you commit, back up your existing sshd_config as the readme shows, and read the config file notes in full, because moving the config aside is how you get the fresh stock configuration the package ships.

## FAQ

### What does the openssh-rpms project do?

It is a script to backport upstream OpenSSH for CentOS and RHEL-like distributions, building RPM packages from spec files modified from the spec file shipped by the OpenSSH project. The current versions listed in the readme are OpenSSH 10.6p1 and OpenSSL 3.5.9.

### Which Linux distributions does openssh-rpms support?

CentOS 5 through 8 and CentOS Stream 8 and 9, Rocky Linux 8 and 9, AlmaLinux 8 and 9, Oracle Linux 7, 8 and 9, Amazon Linux 1, 2 and 2023, UnionTech UOS V20, openEuler 20.03, 22.03 and 24.03, and AnolisOS 7, 8 and 2023, on x86_64 and aarch64 where the platform supports them.

### How do I install the backported OpenSSH RPMs?

Download the zip from the releases page whose name ends with the tag recommended for your distro in the supported table, unzip it, move your existing sshd_config aside, and run sudo yum --disablerepo=* localinstall -y on the RPM files. Verify with ssh -V and /usr/sbin/sshd -V.

### Why do I need to back up sshd_config before installing?

Because the package ships a fresh stock configuration, which also avoids breakage from old directives, notably the GSSAPI series, that were removed upstream. If you skip the backup step, rpm keeps your old config and saves the package defaults as sshd_config.rpmnew, since the spec marks the file as %config(noreplace).

### Can I use one build of the RPMs across different RHEL-like distributions?

Yes. The readme notes it is unnecessary to build on each system, as most RPM-based Linux distributions are glibc compatible, so RPMs built on CentOS 8 can be installed and run on Rocky Linux 8, AlmaLinux 8 or Oracle Linux 8. The recommended tag column in the table shows which Enterprise Linux level to pick for each distribution.

## Sources

- [boypt/openssh-rpms on GitHub](https://github.com/boypt/openssh-rpms)
- [Issues](https://github.com/boypt/openssh-rpms/issues)
- [README](https://github.com/boypt/openssh-rpms/blob/main/README.md)
- [Releases](https://github.com/boypt/openssh-rpms/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/boypt-openssh-rpms
