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
六、验证和测试
- 检查SSH版本
ssh -V - 测试SSH连接
ssh localhost
或者连接其他服务器
ssh 192.168.0.117
七、注意事项
1. 不要断开当前SSH连接:在安装新版本后,先在新终端中测试SSH连接,确保正常工作后再断开原连接。
2. 兼容性:构建的RPM包在兼容的glibc版本上可跨系统使用,例如在CentOS 8上构建的RPM可以安装在Rocky Linux 8、AlmaLinux 8等系统上。
- OpenSSL版本:如果系统已经安装了较新版本的OpenSSL,可以修改version.env文件中的OPENSSLSRC,或使用WITH_OPENSSL=0来禁用OpenSSL,但这样会失去对ssh-rsa密钥的支持。
- UnionTech OS 20:在UOS上安装时,需要先移除冲突包:
sudo rpm --nodeps -e openssh-help
sudo yum --disablerepo=* install -y ./openssh*.rpm
八、高级选项 - 使用Docker构建
按照GitHub项目中的说明,可以使用Docker来构建RPM包:
查看Docker构建说明
cat docker/README.md
2. 构建无OpenSSL版本
如果希望RPM包更小且构建更快,可以在version.env中设置:
WITH_OPENSSL=0
然后重新运行构建脚本。
九、常见问题解决
- 依赖问题:如果安装时提示依赖缺失,先安装缺失的依赖包。
- 配置冲突:如果配置文件冲突,可以使用--replacefiles选项强制安装:
rpm -ivh --force --nodeps --replacepkgs --replacefiles openssh-*.rpm - 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 🌐 需要被远程登录时安装(如服务器、云主机)
⚠️ 关键注意事项(生产环境必读)
- 版本强一致性
三包版本号必须完全一致(9.8p1-1.el7),混用会导致:
○ sshd 启动失败(配置解析错误)
○ 客户端与服务端协议不兼容
○ PAM 模块加载异常 - 依赖关系
安装 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. 备份关键配置(升级前必做!)
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

浙公网安备 33010602011771号