技术存在的终级意义,是为了解决问题。

最完善的更新 Openssh 步骤(附自动执行脚本)

概述

Openssh 和 openssl 经常会报出高危漏洞,并且更新起来万一操作不当还容易出现远程断开的问题,处理起来确实比较棘手。

我之前查好多网上的教程,大部分是互相 copy。按照他们的步骤来操作,基本都是更新完之后,使用 ssh -V 命令测试版本显示是最新了,但是实际用另一台 PC 或者服务器测试(telnet 被测试服务器的 22 端口查看返回信息)发现还是原先的低版本。

本教程中,我可以保证按照我的操作步骤不会存在上述问题。

那么下面开始,我将结合脚本来详细说明。

环境及注意事项

  • 下述所有文件的存放目录皆为 /data/tools/ssh_update,如有修改需自行调整脚本,否则会报错
  • 确保已下载 openssh 和 openssl 的最新安装包,并注意调整脚本中的软件路径与下载的保持一致,否则会报错
  • 完成后要记得关闭 xinetd 服务(即 telnet 服务),telnet 服务长期开启很危险

脚本及说明

下面以 CentOS 7 的脚本举例,后面也会放上 CentOS 5 和 6 的脚本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/bin/bash
#安装完毕后需关闭telnet服务:
#systemctl stop telnet.socket
#chkconfig telnet off
#systemctl stop xinetd
#chkconfig xinetd off

yum update openssh -y
#更新openssh到可自动更新的最新版

########安装 telnet########

yum install xinetd telnet-server -y
#安装telnet服务,避免万一ssh断开后远程不到服务器

sed -i 's/yes/no/g' /etc/xinetd.d/telnet
echo 'pts/0
pts/1
pts/2
pts/3' >> /etc/securetty
#修改telnet配置文件,允许远程服务器

systemctl start telnet.socket
systemctl start xinetd
#重启telnet服务

yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel pcre-devel pam-devel
yum install -y pam* zlib*
yum install -y basename
#安装依赖包和依赖软件


########准备工作########

work_dir=/data/tools/ssh_update
backup_dir=$work_dir/backup
mkdir -p $backup_dir/ssh

cd $work_dir
wget -nd -r -l1 -nc -R index.html -e robots=off --no-parent https://www.linken404.com/tools/ssh_update/packages/
#自动下载我已经上传到网站上的最新版本的安装包(仅为了便于我自己批量部署)

#-nd 不创建目录, wget默认会创建一个目录
#-r 递归下载
#-l1 (L one) 递归一层,只下载指定文件夹中的内容, 不下载下一级目录中的.
#–no-parent 不下载父目录中的文件
#-nc:下载时跳过已经存在的文件
#-e robots=off 忽略robots
#-R index.html : 不下载 index.html 文件


########安装 openssl########
#这里注意的是,不支持1.1.0之上版本的openssl,目前只能选择1.0.x版本

cd $work_dir
openssl_version=`ls |grep -Eiw 'openssl.*.gz' | sort -rV | head -n 1`
openssl_dir=`basename $openssl_version .tar.gz`
#设置变量,CentOS5不支持sort命令的-V选项

tar zxvf $openssl_version
cd $work_dir/$openssl_dir
#解压并进入

mv /usr/bin/openssl $backup_dir/usr_bin_openssl_bak
mv /usr/include/openssl $backup_dir/usr_include_openssl_bak
#备份旧的openssl目录

./config shared && make && make install
#编译并安装,不要设置安装路径

ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl
echo "/usr/local/ssl/lib" >> /etc/ld.so.conf
/sbin/ldconfig
#为新安装的openssl创建软连接,写入配置文件并加载


########安装 openssh########

cd $work_dir
openssh_version=`ls |grep -Eiw 'openssh.*.gz' | sort -rV | head -n 1`
openssh_dir=`basename $openssh_version .tar.gz`
#解压并进入

chown -R root.root $work_dir/$openssh_dir
#增加权限,理论上不做也可以,但是做了保险一些

\cp -a /etc/ssh/* $backup_dir/ssh/
rm -rf /etc/ssh/*
#备份,然后删除旧文件
#这步是关键,openssh需要安装到原先的位置才能保证真正生效,所以必须先把旧文件清空

./configure --prefix=/usr/ --sysconfdir=/etc/ssh --with-openssl-includes=/usr/local/ssl/include \
--with-ssl-dir=/usr/local/ssl --with-zlib --with-md5-passwords --with-pam \
&& make && make install
#编译并安装,上面的路径切记要注意

echo "PermitRootLogin yes
UseDNS no" >> /etc/ssh/sshd_config
#调整配置文件中的部分项,支持远程登录

\cp -a contrib/redhat/sshd.init /etc/init.d/sshd
\cp -a contrib/redhat/sshd.pam /etc/pam.d/sshd.pam
chmod +x /etc/init.d/sshd
chkconfig --add sshd
#添加到init.d服务

systemctl enable sshd
rm -f /usr/lib/systemd/system/sshd.service
chkconfig sshd on
systemctl restart sshd
#设置开机启动,并重启sshd服务

测试的话,ssh -V 命令显示最新版本只是保证更新软件成功,至于最新版本的 openssh 是否真正生效则还是需要用 telnet [ip] [port] 来测试。返回版本号是最新更新的版本才证明更新彻底成功。

附:CentOS 5 和 6 的更新脚本(暂未更新至最新)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#!/bin/bash
#CentOS 5、6通用
yum update openssh -y
yum install xinetd telnet-server -y
sed -i 's/yes/no/g' /etc/xinetd.d/telnet
echo 'pts/0
pts/1
pts/2
pts/3' >> /etc/securetty
service xinetd restart
yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel pcre-devel pam-devel
yum install -y pam* zlib*

#install openssl
cd /data/tools/
tar zxvf openssl-1.0.2s.tar.gz
cd /data/tools/openssl-1.0.2s
mv /usr/bin/openssl /usr/bin/openssl_bak
mv /usr/include/openssl /usr/include/openssl_bak
./config shared && make && make install
ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/ssl/include/openssl /usr/include/openssl
echo "/usr/local/ssl/lib" >> /etc/ld.so.conf
/sbin/ldconfig



#install openssh
cd /data/tools/
tar zxvf openssh-8.0p1.tar.gz
cd /data/tools/openssh-8.0p1
chown -R root.root /data/tools/openssh-8.0p1
mv /etc/ssh/* /data/tools/
rm -rf /etc/ssh/*
./configure --prefix=/usr/ --sysconfdir=/etc/ssh --with-openssl-includes=/usr/local/ssl/include \
--with-ssl-dir=/usr/local/ssl --with-zlib --with-md5-passwords --with-pam \
&& make && make install
echo "PermitRootLogin yes
UseDNS no" >> /etc/ssh/sshd_config
\cp -a contrib/redhat/sshd.init /etc/init.d/sshd
\cp -a contrib/redhat/sshd.pam /etc/pam.d/sshd.pam
chmod +x /etc/init.d/sshd
chkconfig --add sshd
chkconfig sshd on
service sshd restart

参考文章

升级操作系统 OpenSSH 及其 OpenSSL 的正确姿势

打赏猫粮!!!