G
N
I
D
A
O
L
W
e
l
c
o
m
e
: )

Centos、银河麒麟x86、arm升级openssh安装包

OpenSSH RPM打包方案

根据您提供的两个链接(腾讯云文章和GitHub项目),我整理了详细的OpenSSH RPM打包方案。这个方案适用于CentOS/RHEL类系统,特别适合需要升级OpenSSH的环境。

一、准备工作

1. 环境准备

安装必要的构建依赖:

安装开发工具组

yum groupinstall -y "Development Tools"

安装构建OpenSSH所需的依赖

yum install -y imake rpm-build pam-devel krb5-devel zlib-devel libXt-devel libX11-devel gtk2-devel perl perl-IPC-Cmd perl-Time-Piece

CentOS 7及以上系统需要安装

yum install -y systemd-devel

CentOS 5系统需要安装

yum install -y gcc44

2. 下载打包脚本

克隆GitHub项目

git clone https://github.com/boypt/openssh-rpms.git
cd openssh-rpms

或者直接下载压缩包

wget https://github.com/boypt/openssh-rpms/archive/refs/heads/main.zip
unzip main.zip
cd openssh-rpms-main

二、配置版本

##1. 编辑版本配置文件

vi version.env
根据需要修改版本信息,例如升级到OpenSSH 9.8p1:

OPENSSLSRC=openssl-3.0.14.tar.gz
OPENSSLSRC=openssl-1.1.1v.tar.gz  # 选择合适的OpenSSL版本
OPENSSHSRC=openssh-9.8p1.tar.gz
ASKPASSSRC=x11-ssh-askpass-1.2.4.1.tar.gz
PERLSRC=perl-5.38.2.tar.gz
PKGREL=1

注意:如果系统已安装OpenSSL 1.1.1v,建议保持这个版本以避免兼容性问题。
三、获取源码

1. 下载源码包

./pullsrc.sh
如果下载过程中出现错误,可以手动下载源码文件并放入downloads目录:

例如,手动下载OpenSSH 9.8p1

wget https://mirrors.aliyun.com/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz -P downloads/

手动下载OpenSSL 1.1.1v

wget https://www.openssl.org/source/openssl-1.1.1v.tar.gz -P downloads/

2. 验证下载

ls downloads/

应该看到类似以下文件:

# openssh-9.8p1.tar.gz
# openssl-1.1.1v.tar.gz
# x11-ssh-askpass-1.2.4.1.tar.gz

四、构建RPM包

1. 运行构建脚本

./compile.sh
构建过程会生成RPM包,结果存放在el7/RPMS/x86_64/目录(根据系统版本,可能是el5、el6、el7等)。

2. 查看生成的RPM包

ls el7/RPMS/x86_64/

应该看到类似以下文件:


# openssh-9.8p1-1.el7.x86_64.rpm
# openssh-clients-9.8p1-1.el7.x86_64.rpm
# openssh-debuginfo-9.8p1-1.el7.x86_64.rpm
# openssh-server-9.8p1-1.el7.x86_64.rpm

重要提示:升级OpenSSH时,只需使用以下3个文件,不需要debuginfo:
● openssh-9.8p1-1.el7.x86_64.rpm
● openssh-clients-9.8p1-1.el7.x86_64.rpm
● openssh-server-9.8p1-1.el7.x86_64.rpm

五、安装RPM包

1. 备份现有配置

备份sshd配置

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.date +%Y%m%d

备份PAM配置

cp /etc/pam.d/sshd /etc/pam.d/sshd.date +%Y%m%d
cp /etc/pam.d/system-auth /etc/pam.d/system-auth.date +%Y%m%d

2. 卸载旧的OpenSSH相关包(如果需要)

如果有冲突,先卸载旧的包

yum erase openssh-askpass openssh-keycat openssh-cavs openssh-askpass openssh-askpass-gnome openssh-debuginfo

3. 安装新RPM包

进入生成的RPM目录

cd el7/RPMS/x86_64/

安装RPM包

yum --disablerepo=* localinstall -y openssh*.rpm

检查安装的版本
ssh -V

应该显示:OpenSSH_9.8p1, OpenSSL 1.1.1v 1 Aug 2023

4. 处理可能的权限问题

如果出现以下错误:
Permissions 0640 for '/etc/ssh/ssh_host_ed25519_key' are too open.
修复权限:
chmod 0600 /etc/ssh/ssh_host_rsa_key
chmod 0600 /etc/ssh/ssh_host_ecdsa_key
chmod 0600 /etc/ssh/ssh_host_ed25519_key
5. 重启SSH服务
systemctl enable sshd
systemctl restart sshd
六、验证和测试

  1. 检查SSH版本
    ssh -V
  2. 测试SSH连接
    ssh localhost

或者连接其他服务器

ssh 192.168.0.117

七、注意事项

1. 不要断开当前SSH连接:在安装新版本后,先在新终端中测试SSH连接,确保正常工作后再断开原连接。

2. 兼容性:构建的RPM包在兼容的glibc版本上可跨系统使用,例如在CentOS 8上构建的RPM可以安装在Rocky Linux 8、AlmaLinux 8等系统上。

  1. OpenSSL版本:如果系统已经安装了较新版本的OpenSSL,可以修改version.env文件中的OPENSSLSRC,或使用WITH_OPENSSL=0来禁用OpenSSL,但这样会失去对ssh-rsa密钥的支持。
  2. UnionTech OS 20:在UOS上安装时,需要先移除冲突包:
    sudo rpm --nodeps -e openssh-help
    sudo yum --disablerepo=* install -y ./openssh*.rpm
    八、高级选项
  3. 使用Docker构建
    按照GitHub项目中的说明,可以使用Docker来构建RPM包:

查看Docker构建说明

cat docker/README.md
2. 构建无OpenSSL版本
如果希望RPM包更小且构建更快,可以在version.env中设置:
WITH_OPENSSL=0
然后重新运行构建脚本。
九、常见问题解决

  1. 依赖问题:如果安装时提示依赖缺失,先安装缺失的依赖包。
  2. 配置冲突:如果配置文件冲突,可以使用--replacefiles选项强制安装:
    rpm -ivh --force --nodeps --replacepkgs --replacefiles openssh-*.rpm
  3. SSH连接失败:检查/var/log/secure日志,查看具体错误原因。
    通过以上步骤,您可以成功打包并安装OpenSSH的RPM包,确保系统安全性和最新功能。
    这三个 RPM 包是 OpenSSH 9.8p1 在 RHEL/CentOS 7 系统上的标准模块化拆分,各司其职、缺一不可。以下是精准解析:

🔑 三包功能详解(基于 boypt 打包方案 & RHEL 标准)

RPM 包	核心作用	关键文件示例	安装场景
openssh-9.8p1-1.el7.x86_64.rpm	基础支撑包
• 提供客户端/服务端共享资源
• 不包含ssh
/sshd
 可执行文件	/etc/ssh/ssh_config
(客户端模板)
/etc/pam.d/sshd
(PAM认证配置)
/usr/share/doc/openssh-9.8p1/
(文档)
/etc/ssh/moduli
(DH参数)	✅ 必须安装
clients/server 的依赖基础
openssh-clients-9.8p1-1.el7.x86_64.rpm	客户端工具集
• 用于本机发起 SSH 连接	/usr/bin/ssh
/usr/bin/scp
/usr/bin/sftp
/usr/bin/ssh-keygen
/usr/bin/ssh-copy-id
/usr/bin/ssh-agent	🖥️ 需要连接其他服务器时安装(如跳板机、开发机)
openssh-server-9.8p1-1.el7.x86_64.rpm	服务端守护进程
• 用于本机提供 SSH 服务	/usr/sbin/sshd
/usr/lib/systemd/system/sshd.service
/etc/sysconfig/sshd
/usr/bin/sshd-keygen-wrapper	🌐 需要被远程登录时安装(如服务器、云主机)

⚠️ 关键注意事项(生产环境必读)

  1. 版本强一致性
    三包版本号必须完全一致(9.8p1-1.el7),混用会导致:
    ○ sshd 启动失败(配置解析错误)
    ○ 客户端与服务端协议不兼容
    ○ PAM 模块加载异常
  2. 依赖关系

安装 clients 时自动依赖 openssh

rpm -qpR openssh-clients-9.8p1-1.el7.x86_64.rpm | grep openssh

输出:openssh = 9.8p1-1.el7

安装 server 时同样依赖 openssh

rpm -qpR openssh-server-9.8p1-1.el7.x86_64.rpm | grep openssh
  1. 升级操作规范

1. 备份关键配置(升级前必做!)

cp -r /etc/ssh /etc/ssh.backup.$(date +%Y%m%d)

2. 一次性安装三包(避免依赖断裂)

yum localinstall -y openssh-9.8p1-1.el7.x86_64.rpm \
                   openssh-clients-9.8p1-1.el7.x86_64.rpm \
                   openssh-server-9.8p1-1.el7.x86_64.rpm

3. 检查配置冲突(.rpmnew 文件)

ls /etc/ssh/*.rpmnew # 如有,需手动合并

4. 重启服务(保留备用连接!)

systemctl daemon-reload
systemctl restart sshd
4. 安全验证
ssh -V # 验证客户端版本:OpenSSH_9.8p1
/usr/sbin/sshd -V # 验证服务端版本
journalctl -u sshd -f # 实时监控服务日志

💡 场景化建议

使用场景	需安装包	说明
普通服务器(需被远程登录)	三包全装	标准配置
跳板机/堡垒机	三包全装	既提供服务又需连接下游
纯客户端机器(如开发机)	openssh
 + openssh-clients	无需安装 server 包
容器/最小化环境	按需选择	节省空间,但需确认依赖
✅ 权威依据:此拆分方案符合 RHEL 官方打包规范 及 boypt 项目实践,确保与系统生态兼容。
🔒 安全提示:OpenSSH 9.8p1 修复了 CVE-2024-6387 等高危漏洞,建议在测试验证后及时升级生产环境。
问题根源在于脚本的 GUESS_DIST 函数无法识别麒麟系统返回的 dist 值 ky10,导致进入 TOPDIR_SELECT 的默认分支并报错退出。
✅ 解决方案(推荐修改 GUESS_DIST 函数)
1. 编辑 compile.sh,定位到 GUESS_DIST() 函数内:
local dist=$(rpm --eval '%{?dist}' | tr -d '.')

在其后、[[ -n $dist ]] && echo $dist && return 0之前,添加以下映射规则:

映射国产系统到兼容的 RHEL 系列版本

[[ $dist == "ky10" ]] && dist="el7"      # 麒麟 V10 (Lance) 通常基于 CentOS 7
[[ $dist == "uel20" ]] && dist="el8"     # 可选:统信 UOS 20+
[[ $dist == "an8" ]] && dist="el8"       # Anolis OS 8(已有,保留)
[[ $dist == "an7" ]] && dist="el7"       # Anolis OS 7(已有,保留)

2. 验证目录结构

确保项目根目录存在 el7 构建目录(含 SPECS/, SOURCES/ 等):
ls -la /root/openssh-rpms-main/el7
若缺失,可复制现有模板:
cp -r /root/openssh-rpms-main/el7_template /root/openssh-rpms-main/el7

3. (可选)临时绕过方案

若急需构建且确认系统兼容 CentOS 7,可直接指定构建目录:
./compile.sh
🔍 补充建议
● 确认基础系统:执行 rpm -q glibc,若版本为 2.17 则确属 CentOS 7 系,映射 el7 安全;若为 2.28+ 则应映射 el8。
● 增强健壮性:在 TOPDIR_SELECT 的 *) 分支末尾添加:
echo "Tip: For Kylin V10, ensure 'ky10' is mapped to 'el7' in GUESS_DIST function."
● 长期维护:建议在项目文档中补充国产系统适配说明,并考虑将 dist 映射逻辑外置为配置文件。
修改后重新运行 sh -x compile.sh,脚本应能正确识别为 el7 并继续构建流程。此修改精准匹配当前系统特征,且符合麒麟 V10 与 CentOS 7 的兼容事实,无需改动构建逻辑主体。

打包代码内容


[root@localhost openssh-rpms-main]# cat compile.sh 
#!/usr/bin/env bash
# Bash3 Boilerplate. Copyright (c) 2014, kvz.io

set -o errexit
set -o pipefail
set -o nounset
# set -o xtrace

trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; exit 1' ERR

# Set magic variables for current file & dir
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
__root="$(cd "$(dirname "${__dir}")" && pwd)" # <-- change this as it depends on your app

arg1="${1:-}"
rpmtopdir=

# WITH_OPENSSL=
# Control openssl dependency
# 0: build without openssl
# 1: use system openssl
# 2: build openssl statically

CHECKEXISTS() {
  if [[ ! -f $__dir/downloads/$1 ]];then
    echo "$1 not found, run 'pullsrc.sh', or manually put it in the downloads dir."
    exit 1
  fi
}


GUESS_DIST() {
    # will not work if rpm cmd not exists
    if ! type -p rpm > /dev/null;then
      echo 'unknown' && return 0
    fi

    local dist=$(rpm --eval '%{?dist}' | tr -d '.')

    # fallback to el7
    [[ $dist == "el9" ]] && dist="el8"
    [[ $dist == "el8" ]] && dist="el8"
    [[ $dist == "an8" ]] && dist="el8" # Anolis 8
    [[ $dist == "an7" ]] && dist="el7" # Anolis 7
    [[ $dist == uel* ]] && dist="el8"  # UOS20+
    [[ $dist == "ky10" ]] && dist="el7"

    [[ -n $dist ]] && echo $dist && return 0

    local glibcver=$(ldd --version | head -n1 | grep -Eo '[0-9]+' | tr -d '\n')

    # centos 5 uses glibc 2.5
    [[ $glibcver -eq 25 ]] && echo 'el5' && return 0

    # centos 6 uses glibc 2.12
    [[ $glibcver -eq 212 ]] && echo 'el6' && return 0

    # centos 7 uses glibc 2.17
    [[ $glibcver -eq 217 ]] && echo 'el7' && return 0

    # centos 8 uses glibc 2.28, not yet to be in a seprate dir
    [[ $glibcver -eq 228 ]] && echo 'el8' && return 0

    # some centos-like dists ships higher version of glibc, fallback to el7
    [[ $glibcver -gt 217 ]] && echo 'el8' && return 0
}

TOPDIR_SELECT() {
    local DISTVER=$(GUESS_DIST)
    case $DISTVER in
        el8)
            rpmtopdir=el7
            WITH_OPENSSL=${WITH_OPENSSL:-1}
            ;;
        el7)
            rpmtopdir=el7
            WITH_OPENSSL=${WITH_OPENSSL:-2}
            ;;
        el6)
            rpmtopdir=el6
            WITH_OPENSSL=${WITH_OPENSSL:-2}
            ;;
        el5)
            rpmtopdir=el5
            WITH_OPENSSL=${WITH_OPENSSL:-2}
            # on centos5, it's prefered to use gcc44
            rpm -q gcc44 2>&1 >/dev/null && export CC=gcc44
            ;;
        *)
            echo "Distro undefined, please specify manually: el5 el6 el7"
            echo -e "\nCurrent OS:"
            [[ -f /etc/os-release ]] && cat /etc/os-release
            [[ -f /etc/redhat-release ]] && cat /etc/redhat-release 
            [[ -f /etc/system-release ]] && cat /etc/system-release
            echo -e "Current OS vendor: $(rpm --eval '%{?_vendor}') \n"
            return 1
            ;;
    esac
}

BUILD_RPM() {

    source version.env
    [[ -f version-local.env ]] && source version-local.env

    local SOURCES=( $OPENSSHSRC \
          $OPENSSLSRC \
          $ASKPASSSRC \
        )
    local RPMBUILDOPTS=( \
        --define "with_openssl ${WITH_OPENSSL}" \
        --define "opensslver ${OPENSSLVER}" \
        --define "opensshver ${OPENSSHVER}" \
        --define "opensshpkgrel ${PKGREL}" \
        --define 'debug_package %{nil}' \
        --define 'no_gtk2 1' \
        --define 'skip_gnome_askpass 1' \
        --define 'skip_x11_askpass 1' \
        )

    # only on EL5, perl source is needed.
    [[ $rpmtopdir == "el5" ]] && \
        SOURCES+=($PERLSRC) && \
        RPMBUILDOPTS+=('--define' "perlver ${PERLVER}"
                   '--define' 'dist .el5')

    # add dist variable if not defined
    [[ $rpmtopdir == "el7" ]] && \
        [[ -z $(rpm --eval '%{?dist}') ]] && \
         RPMBUILDOPTS+=('--define' "dist .$(rpm -q glibc | rev | cut -d. -f2 | rev)")

    pushd $rpmtopdir
    RPMBUILDOPTS+=('--define' "_topdir $PWD")
    for fn in ${SOURCES[@]}; do
      CHECKEXISTS $fn && \
        install -v -m666 $__dir/downloads/$fn ./SOURCES/
    done
    rpmbuild -ba ./SPECS/openssh.spec "${RPMBUILDOPTS[@]}"
    popd
}

LIST_RPMDIR(){
    local RPMDIR=$__dir/${rpmtopdir}/RPMS/$(rpm --eval '%{_arch}')
    [[ -d $RPMDIR ]] && echo $RPMDIR
}

LIST_RPMS() {
    local RPMDIR=$(LIST_RPMDIR)
    [[ -d $RPMDIR ]] && find $RPMDIR -type f -name '*.rpm'
}

# sub cmds
case $arg1 in
    GETEL)
        GUESS_DIST
        exit 0
        ;;
    GETRPM)
        TOPDIR_SELECT
        LIST_RPMS
        exit 0
        ;;
    RPMDIR)
        TOPDIR_SELECT
        LIST_RPMDIR
        exit 0
        ;;
    *)
        [[ -n $arg1 ]] && \
        echo -e "Subcmd: $arg1 not found.\n GETEL, GETRPM, RPMDIR" && \
        exit 1
        ;;
esac

# manual specified dist
[[ -n $arg1 && -d $__dir/$arg1 ]] && rpmtopdir=$arg1 && BUILD_RPM && exit 0
TOPDIR_SELECT

if [[ ! -d $rpmtopdir ]]; then 
  echo "This script works only in el5/el6/el7"
  echo "eg: ${0} el7"
  exit 1
fi

[[ -d $rpmtopdir ]] && BUILD_RPM

参考链接:https://github.com/boypt/openssh-rpms/archive/refs/heads/main.zip

posted @ 2026-02-05 17:00  狸猫大侠  阅读(179)  评论(0)    收藏  举报