准备工作
操作系统:CentOS 7
制作RPM包,需要依赖以下命令,因此需要安装对应的包
- gcc(yum install -y gcc)
- rpmbuild(yum install -y rpmdevtools rpmlint)
- rpmlint(可选,执行上面的命令,则rpmlint一并安装)
题外话,如果遇到yum命令报错,则检查环境变量,yum依赖的python的版本是否为2.x,如果默认是3.x,则会导致yum报错。当 python2 和 python3 同时存在时,最简单的做法就是直接修改/usr/bin/python的软连接为python2。
OpenSSH官网信息
下文是基于10.0之前的版本写的,经测试,在10.0上依然有效,所以就不更新内容里面的版本号了。
制作RPM包
- 将openssh-9.7p1.tar.gz放在rpmbuild对应的工作目录下。比如,rpmbuild默认安装后,工作目录如下:
/root/rpmbuild/
├── BUILD
├── RPMS
├── SOURCES
├── SPECS
└── SRPMS
如果没有该目录,则执行以下命令进行创建:
rpmdev-setuptree
然后,将openssh-9.7p1.tar.gz放在SOURCES目录下。
- 提取openssh的spec文件,这个文件就是用来制作rpm包的配置文件。命令如下:
cd /
tar -xzvf /root/rpmbuild/SOURCES/openssh-9.7p1.tar.gz /openssh-9.7p1/contrib/redhat/openssh.spec
cp /openssh-9.7p1/contrib/redhat/openssh.spec /root/rpmbuild/SPECS/
- 执行打包命令:
rpmbuild -bb /root/rpmbuild/SPECS/openssh.spec
- 打包过程中可能遇到的问题:
关注上图中的error部分:no acceptable C compiler found in $PATH,这个问题,其实在文章的开头的准备工作中提到了,需要先安装gcc,如果未安装,则会报这个错误,安装命令如下:
yum install -y gcc
重新执行打包命令,可能遇到如下错误:缺少glibc-devel和krb5-devel依赖
同上面一样,安装这两个包:
yum install -y glibc-devel krb5-devel
重新打包,可能会遇到cannot run C compiled programs错误:
上面的错误信息不够详细,看不出来是什么原因导致的,根据上图的提示,可以查看 /root/rpmbuild/BUILD/openssh-9.7p1/config.log文件,里面记录了更详细的错误信息,如下图所示:
上图提示:stdio.h: No such file or directory,所以,我们需要安装glibc-headers,命令如下:
yum install glibc-headers
安装完成之后,stdio.h文件将保存在/usr/include中,可通过命令
`find / -name stdio.h`
进行确认,如果该文件不在/usr/include下,执行打包命令还是会报错。
继续执行打包命令:
[root@localhost rpmbuild]# rpmbuild -bb SPECS/openssh.spec
error: Failed build dependencies:
openssl-devel < 1.1 is needed by openssh-9.0p1-1.el7.centos.x86_64
查看系统是否安装了openssl-devel,以及版本是否符合条件。openssh.specs文件中明确了openssl-devel的版本:
BuildRequires: openssl-devel >= 1.0.1
BuildRequires: openssl-devel < 1.1
不存在则安装相应的版本:
yum install -y openssl-devel
但实际情况可能是即使安装了正确的版本,还是报上面那个错误。可以直接修改openssh.specs文件,将BuildRequires: openssl-devel < 1.1 删除或者在这行的起始位置加#进行注释。
#BuildRequires: openssl-devel < 1.1
另外,还需要修改openssh.specs文件中的两个变量值:
# Do we want to disable building of x11-askpass? (1=yes 0=no)
%global no_x11_askpass 1
# Do we want to disable building of gnome-askpass? (1=yes 0=no)
%global no_gnome_askpass 1
将no_x11_askpass 和no_gnome_askpass的值都改为1,不编译这两个模块。
为了避免修改的文件有误导致编译再次失败,可用rpmlint命令对修改的配置文件进行校验。
rpmlint /root/rpmbuild/SPECS/openssh.spec
如果遇到找不到zlib.h的问题,则安装zlib库,安装命令如下:
yum install -y zlib-devel
如果还是报错,则查找zlib.h文件在哪里:
find / -name zlib.h
然后将找到的文件,复制到/usr/include下。
如果遇到如下问题:
configure: error: PAM headers not found
error: Bad exit status from /var/tmp/rpm-tmp.c0SmcP (%build)
RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.c0SmcP (%build)
则需要安装pam-devel,devel就是包含头文件的包:
yum install -y pam-devel
如果遇到如下错误:
Obsoletes: ssh-server
Processing files: openssh-debuginfo-10.0p1-1.el7.centos.x86_64
Provides: openssh-debuginfo = 10.0p1-1.el7.centos openssh-debuginfo(x86-64) = 10.0p1-1.el7.centos
Requires(rpmlib): rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(CompressedFileNames) <= 3.0.4-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files /root/rpmbuild/BUILDROOT/openssh-10.0p1-1.el7.centos.x86_64
error: Installed (but unpackaged) file(s) found:
/usr/libexec/openssh/sshd-auth
RPM build errors:
Installed (but unpackaged) file(s) found:
/usr/libexec/openssh/sshd-auth
那就编辑文件,然后找到这部分内容:
%files server
...
...
在里面添加一条:
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-auth
最终效果如下:
%files server
%defattr(-,root,root)
%dir %attr(0111,root,root) %{_var}/empty/sshd
%attr(0755,root,root) %{_sbindir}/sshd
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-auth
%attr(0755,root,root) %{_libexecdir}/openssh/sshd-session
%attr(0755,root,root) %{_libexecdir}/openssh/sftp-server
%attr(0644,root,root) %{_mandir}/man8/sshd.8*
%attr(0644,root,root) %{_mandir}/man5/moduli.5*
最后重新编译:
rpmbuild -bb /root/rpmbuild/SPECS/openssh.spec
应该就能打包成功了,打包好的rpm文件在以下目录:
[root@localhost x86_64]# pwd
/root/rpmbuild/RPMS/x86_64
[root@localhost x86_64]# ll | grep ssh
-rw-r--r-- 1 root root 665872 May 24 16:13 openssh-9.7p1-1.el7.centos.x86_64.rpm
-rw-r--r-- 1 root root 655388 May 24 16:13 openssh-clients-9.7p1-1.el7.centos.x86_64.rpm
-rw-r--r-- 1 root root 3108720 May 24 16:13 openssh-debuginfo-9.7p1-1.el7.centos.x86_64.rpm
-rw-r--r-- 1 root root 465228 May 24 16:13 openssh-server-9.7p1-1.el7.centos.x86_64.rpm
安装或者升级
目前openssh最新版是9.7,该版本需要使用openssl 1.1.1的版本,所以,我们需要同时升级openssl。
- 查询openssl的版本:
openssl version
- 如果openssl的版本不是1.1.1,则需要升级到1.1.1版本,查看已安装的openssl:
rpm -qa|grep openssl
注意,卸载openssl-1.x.x容易导致系统crash,可以采用强制升级的方式。
- 安装openssl的新版本:
rpm -i openssl-1.1.1t-1.el7.centos.x86_64.rpm --nodeps --force
- 检查是否已安装openssh,执行以下命令:
rpm -qa | grep openssh
如果未安装,则进行安装:
rpm -i openssh*.rpm
注意,这里是用的openssh*,因为有依赖,所以除了debuginfo那个包,其他的都需要安装上。
- 已安装,则直接升级,如果升级之前,需要备份配置文件,则备份如下配置即可:
/etc/ssh/ssh_config
/etc/ssh/sshd_config
/etc/pam.d/sshd
- 备份完成,执行以下命令进行升级:
rpm -U openssh*.rpm
检查是否升级成功:
rpm -qa | grep openssh
- 升级成功之后,需要检查前面备份的三个配置文件是否需要还原。如果是小版本升级,可复用之前的配置,然后重启。如果是大版本升级,可能涉及到配置文件的重要变化,所以需要将升级之后的新配置文件,一般名为sshd_config.rpmnew,重命名为sshd_config,然后重启sshd服务:
systemctl restart sshd
如果涉及到安全加固,那就参考备份文件,重新进行配置即可。
重启可能会失败,使用以下命令查看失败原因:
systemctl status sshd
输出信息如下:
May 25 13:21:52 localhost.localdomain sshd[13077]: Unable to load host key "/etc/ssh/ssh_host_ed25519_key": bad permissions
May 25 13:21:52 localhost.localdomain sshd[13077]: Unable to load host key: /etc/ssh/ssh_host_ed25519_key
May 25 13:21:52 localhost.localdomain sshd[13077]: sshd: no hostkeys available -- exiting.
May 25 13:21:52 localhost.localdomain sshd[13077]: [FAILED]
进入/etc/ssh/目录,将key相关的文件都删掉:
[root@localhost ssh]# rm -rf *key*
再次重启sshd服务,并查看sshd的运行状态是否正常:
systemctl restart sshd
systemctl status sshd
如果启动正常,但通过ssh无法登录服务器,则需要查看系统日志,命令如下:
[root@localhost pam.d]# cat /var/log/secure
......
May 25 13:28:39 localhost sshd[30480]: PAM unable to dlopen(/usr/lib64/security/pam_stack.so): /usr/lib64/security/pam_stack.so: cannot open shared object file: No such file or directory
May 25 13:28:39 localhost sshd[30480]: PAM adding faulty module: /usr/lib64/security/pam_stack.so
如果出现上述的错误信息,提示找不到pam_stack.so模块,则说明/etc/pam.d/sshd文件没有被恢复为之前的备份文件。
如果还是无法使用ssh登录,则继续查看系统日志:
[root@localhost pam.d]# cat /var/log/secure
......
May 25 13:40:41 localhost sshd[28873]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=10.10.10.10 user=root
May 25 13:40:41 localhost sshd[28873]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
May 25 13:40:43 localhost sshd[28873]: Failed password for root from 10.10.10.10 port 59430 ssh2
May 25 13:40:46 localhost sshd[28873]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
May 25 13:40:49 localhost sshd[28873]: Failed password for root from 10.10.10.10 port 59430 ssh2
提示requirement “uid >= 1000” not met by user “root”,则需要修改/etc/ssh/sshd_config下的配置:
PermitRootLogin yes
该参数表示允许root用户使用ssh方式登录。修改完成后,需要重启sshd服务。