openssh版本升级通常在各种安全扫描、漏洞修复,三级等保等需求场景下会用到,本文将介绍基于centos环境下编译升级安装openssh的步骤。

安装包下载准备

openssh下载

http://www.openssh.com/portable.html

http://mirror.aarnet.edu.au/pub/OpenBSD/OpenSSH/portable/

openssl下载

http://www.openssl.org/

http://www.openssl.org/source/

zlib下载

http://www.zlib.net/

查看系统当前软件版本

1
2
3
rpm -q zlib
openssl version
ssh -V
1
2
3
4
5
6
7
[root@VM_100_51_centos installSofts]# rpm -q zlib
zlib-1.2.7-15.el7.x86_64
zlib-1.2.7-15.el7.i686
[root@VM_100_51_centos installSofts]# openssl version
OpenSSL 1.0.2k-fips  26 Jan 2017
[root@VM_100_51_centos installSofts]# ssh -V
OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 11 Feb 2013

安装telnet-server

安装telnet-server不是必须的,但是为了避免openssh卸载安装过程中出现问题导致无法登录,所以安装telnet以备万一。

先查看安装情况

1
2
[root@host39 xinetd.d]# rpm -qa | grep telnet
telnet-0.17-47.el6.x86_64

安装telnet-server

1
yum install telnet-server

再先查看安装情况

1
2
3
[root@host39 xinetd.d]# rpm -qa | grep telnet
telnet-server-0.17-47.el6.x86_64
telnet-0.17-47.el6.x86_64

安装xinetd

1
2
3
4
[root@VM_100_51_centos xinetd.d]# yum list |grep xinetd
xinetd.x86_64                             2:2.3.15-13.el7              os       
[root@VM_100_51_centos xinetd.d]# rpm -qa | grep xinetd
[root@VM_100_51_centos xinetd.d]# yum install xinetd.x86_64
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
安装完成后,将xinetd服务加入开机自启动:
systemctl enable xinetd.service
将telnet服务加入开机自启动:
systemctl enable telnet.socket

最后,启动以上两个服务即可:
由于telnet服务也是由xinetd守护的,所以安装完telnet-server,要启动telnet服务就必须重新启动xinetd 。
systemctl start telnet.socket
systemctl start xinetd
(或service xinetd start)

查看telnet-server启动情况

1
2
[root@VM_100_51_centos xinetd.d]# netstat -tnlp | grep :23
tcp        0      0 0.0.0.0:23              0.0.0.0:*               LISTEN      1/systemd

注意:telnet登陆需以普通用户登录 后切换root

安装需要的依赖包

1
2
3
rpm -qa gcc pam-devel zlib-devel

yum install pam-devel zlib-devel

升级ZLIB

解压zlib_1.2.11源码并编译

1
2
3
4
5
6
7
tar -zxvf zlib-1.2.11.tar.gz
cd zlib-1.2.11

tar zxvf zlib-1.2.12.tar.gz
cd zlib-1.2.12
./configure --prefix=/usr
make

卸载当前zlib

注意:此步骤必须在步骤A执行完毕后再执行,否则先卸载zlib后,/lib64/目录下的zlib相关库文件会被删除,步骤A编译zlib会失败。(补救措施:从其他相同系统的服务器上复制/lib64、/usr/lib和/usr/lib64目录下的libcrypto.so.10、libssl.so.10、libz.so.1、libz.so.1.2.3四个文件到相应目录即可。可通过whereis、locate或find命令找到这些文件的位置) rpm -e –nodeps zlib

1
2
3
4
5
6
[root@VM_100_80_centos zlib-1.2.11]# rpm -e --nodeps zlib
error: "zlib" specifies multiple packages:
zlib-1.2.7-18.el7.x86_64
zlib-1.2.7-18.el7.i686
[root@VM_100_80_centos zlib-1.2.11]# rpm -e --nodeps zlib-1.2.7-18.el7.i686
[root@VM_100_80_centos zlib-1.2.11]# rpm -e --nodeps zlib-1.2.7-18.el7.x86_64

安装之前编译好的zlib

在zlib编译目录执行如下命令

1
make install

共享库注册

zlib安装完成后,会在/usr/lib目录中生产zlib相关库文件,需要将这些共享库文件注册到系统中。

1
2
echo '/usr/lib' >> /etc/ld.so.conf
ldconfig        #更新共享库cache

或者采用如下方式也可:

1
2
3
4
ln -s  /usr/lib/libz.so.1 libz.so.1.2.11
ln -s  /usr/lib/libz.so libz.so.1.2.11
ln -s  /usr/lib/libz.so.1 /lib/libz.so.1
ldconfig

可通过yum list命令验证是否更新成功(更新失败yum不可用),另外redhat和centos的5.*版本不支持高于1.2.3的zlib版本。

升级OpenSSL

官方升级文档:http://www.linuxfromscratch.org/blfs/view/cvs/postlfs/openssl.html

A、备份当前openssl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
find / -name openssl

rm -rf /usr/lib64/openssl.old
rm -rf /usr/bin/openssl.old
rm -rf /etc/pki/ca-trust/extracted/openssl.old


mv /usr/lib64/openssl /usr/lib64/openssl.old
mv /usr/bin/openssl /usr/bin/openssl.old
mv /etc/pki/ca-trust/extracted/openssl /etc/pki/ca-trust/extracted/openssl.old

/usr/include/openssl 这个目录不要重命名

1
2
3
如下两个库文件必须先备份,因系统内部分工具(如yum、wget等)依赖此库,而新版OpenSSL不包含这两个库
cp  /usr/lib64/libcrypto.so.10  /usr/lib64/libcrypto.so.10.old
cp  /usr/lib64/libssl.so.10  /usr/lib64/libssl.so.10.old

B、卸载当前openssl

1
2
3
4
5
6
7
rpm -qa | grep openssl

rpm -e --nodeps openssl-1.0.2k-25.el7_9.x86_64
rpm -e --nodeps openssl-libs-1.0.2k-25.el7_9.x86_64
rpm -e --nodeps openssl-devel-1.0.2k-25.el7_9.x86_64
rpm -qa | grep openssl
或者直接执行此命令:rpm -qa |grep openssl|xargs -i rpm -e --nodeps {}

C、解压openssl源码并编译安装

1
2
3
4
5
tar -zxvf openssl-1.1.1p.tar.gz
cd openssl-1.1.1p
./config --prefix=/usr --openssldir=/etc/ssl --shared zlib    #必须加上--shared,否则编译时会找不到新安装的openssl的库而报错
make
make test                            #必须执行这一步结果为pass才能继续,否则即使安装完成,ssh也无法使用

如遇到Parse errors: No plan found in TAP output 报错解决方法:

1
yum install perl-Test-Simple

所有通过后

1
2
make install
openssl version -a                   #查看是否升级成功

D、恢复共享库(新版本此步骤好像不用)

由于OpenSSL_1.0.2k不提供libcrypto.so.10和libssl.so.10这两个库,而yum、wget等工具又依赖此库,因此需要将先前备份的这两个库进行恢复,其他的可视情况考虑是否恢复。

1
2
mv  /usr/lib64/libcrypto.so.10.old  /usr/lib64/libcrypto.so.10
mv  /usr/lib64/libssl.so.10.old  /usr/lib64/libssl.so.10

升级OpenSSH

官方升级文档:http://www.linuxfromscratch.org/blfs/view/svn/postlfs/openssh.html

A、备份当前openssh

1
mv /etc/ssh /etc/ssh.old

B、卸载当前openssh

1
2
3
4
5
6
rpm -qa | grep openssh

rpm -e --nodeps openssh-server-7.4p1-21.el7.x86_64
rpm -e --nodeps openssh-7.4p1-21.el7.x86_64
rpm -e --nodeps openssh-clients-7.4p1-21.el7.x86_64
rpm -qa | grep openssh
1
2
3
4
5
6
7
8
或者直接执行此命令:rpm -qa |grep openssh|xargs -i rpm -e --nodeps {}

[root@sl-app-test ~]# rpm -qa |grep openssh|xargs -i rpm -e --nodeps {}
warning: file /etc/ssh/moduli: remove failed: No such file or directory
warning: file /etc/ssh: remove failed: No such file or directory
warning: file /etc/ssh/ssh_config: remove failed: No such file or directory
warning: file /etc/ssh/sshd_config: remove failed: No such file or directory
warning: /etc/pam.d/sshd saved as /etc/pam.d/sshd.rpmsave

C、openssh安装前环境配置

1
2
3
4
install  -v -m700 -d /var/lib/sshd
chown  -v root:sys /var/lib/sshd
groupadd -g 50 sshd
useradd  -c 'sshd PrivSep' -d /var/lib/sshd -g sshd -s /bin/false -u 50 sshd

D、解压openssh_8.1p1源码并编译安装

1
2
3
4
5
6
tar -zxvf openssh-8.1p1.tar.gz
cd openssh-8.1p1

tar -zxvf openssh-9.0p1.tar.gz
cd openssh-9.0p1
./configure --prefix=/usr  --sysconfdir=/etc/ssh  --with-md5-passwords  --with-pam  --with-zlib --with-openssl-includes=/usr --with-privsep-path=/var/lib/sshd

如遇到configure: error: PAM headers not found错误解决方法:

1
yum install pam-devel

执行编译和安装

1
2
make
make install

错误解决 PAM is enabled. You may need to install a PAM control file for sshd, otherwise password authentication may fail. Example PAM control files can be found in the contrib/ subdirectory

解决方法: 若在sshd_config启用UsePAM yes 若没有 /etc/pam.d/sshd,则添加文件,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[root@host47 openssh-6.6p1]# cat /etc/pam.d/sshd
#%PAM-1.0
auth       include      system-auth
account    required     pam_nologin.so
account    include      system-auth
password   include      system-auth
session    optional     pam_keyinit.so force revoke
session    include      system-auth
session    required     pam_loginuid.so

session required pam_selinux.so close
session required pam_selinux.so open env_params

如果使用selinux,最后两行是需要

E、openssh安装后环境配置

在openssh编译目录执行如下命令

1
2
3
4
5
install -v -m755    contrib/ssh-copy-id /usr/bin
install -v -m644    contrib/ssh-copy-id.1 /usr/share/man/man1
install -v -m755 -d /usr/share/doc/openssh-9.0p1
install -v -m644    INSTALL LICENCE OVERVIEW README* /usr/share/doc/openssh-9.0p1
ssh -V              #验证是否升级成功

F、启用OpenSSH服务

在openssh编译目录执行如下目录

1
2
3
4
5
6
7
cp -p contrib/redhat/sshd.init /etc/init.d/sshd
chmod +x /etc/init.d/sshd
chkconfig  --add  sshd
chkconfig  sshd  on
chkconfig  --list  sshd
service sshd restart
注意:如果升级操作一直是在ssh远程会话中进行的,上述sshd服务重启命令可能导致会话断开并无法使用ssh再行登入(即ssh未能成功重启),此时需要通过telnet登入再执行sshd服务重启命令。

修改/etc/ssh/sshd_config,在文件底部添加内容:

三级等保的openssh的推荐配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
X11Forwarding yes
X11UseLocalhost no
PermitRootLogin yes
Port 22
UsePAM yes
Protocol 2
MaxAuthTries 4
LogLevel INFO
ClientAliveInterval 600
ClientAliveCountMax 2

问题解决: sshd登陆时发现/var/log/message打印错误: sshd[12222]: error: Failed to allocate internet-domain X11 display socket.

/etc/ssh/sshd_config 配置了

1
2
X11Forwarding yes
X11UseLocalhost no

主要是X11UseLocalhost no配置解决该问题。

善后工作

新开启远程终端以ssh [ip]登录系统,确认一切正常升级成功后,只需关闭telnet服务以保证系统安全性即可。

关闭telnet服务 查看进程

1
2
3
4
5
6
7
netstat -tnlp | grep :23

取消开机启动及关闭程序
systemctl disable telnet.socket
systemctl stop telnet.socket
systemctl disable xinetd.service
systemctl stop xinetd

查看版本

1
2
3
4
[root@VM_100_51_centos ~]# openssl version
OpenSSL 1.0.2q  20 Nov 2018
[root@VM_100_51_centos ~]# ssh -V
OpenSSH_7.9p1, OpenSSL 1.0.2q  20 Nov 2018

配置SELinux

查看是否启用了selinux

1
getenforce

方案1,直接禁用

1
2
3
setenforce 0
vi /etc/selinux/config
修改为SELINUX = permissive

方案2,需要启动的情况

修改SELinux端口: 检查SELinux是否启用

1
sestatus -v |grep SELinux

SELinux status: enabled #表示启用

检查semanage是否安装

1
 rpm -qa |grep policycoreutils-python

若未安装,请先安装工具包

1
 yum install policycoreutils-python

查看当前selinux允许的端口 [test@aa ~]# semanage port -l |grep ssh ssh_port_t tcp 22 添加新端口,假设ssh端口修改为10022

1
semanage port -a -t ssh_port_t -p tcp 10022

检查是否添加成功

1
semanage port -l |grep ssh

重启SSH服务

1
2
3
4
systemctl restart sshd.service

[hgq@izwz9c5lg1thld35vbi1v9z ~]# semanage port -l |grep ssh
ssh_port_t                     tcp      10022, 22

确保/etc/pam.d/sshd包含以下内容

1
2
session required pam_selinux.so close
session required pam_selinux.so open env_params