前言:升级OpenSSH是一个危险系数比较高的操作,一旦出现意外情况,会导致无法ssh登录设备。一定要确保除ssh外 要有其他登录方式能够连接到设备。
我这里升级ssh是因为漏扫 扫出来很多openssh相关漏洞,一共73台设备,分为CentOS-8.2、CentOS-7.9。其中7.9系统又包含x86_64架构和ARM(aarch64)架构的系统,环境比较复杂。
升级OpenSSH这里有两种方法,一是构建SSH RPM包升级,另一种就是源码编译升级。更推荐使用RPM升级的方式,因为RPM升级耗时短,效率高,安全性也相对较高。源码升级耗时长,如果使用ansible等工具批量升级,由于环境不同,在编译和安装时高概率会出错。
一、RPM升级OpenSSH_9.3p2
说明:CentOS-7或8、x86_64或ARM架构 构建rpm包方法基本一样,只是环境不同所需安装的依赖包不同。但需要在不同的系统中单独构建。按照我这里的话要构建三个(8.2_x86_64、7.9_x86_64、7.9_aarch64)。下面以7.9_x86_64操作
1、环境准备
1)官网下载安装包,上传到服务器
https://www.openssh.com/releasenotes.html openssh-9.3p2.tar.gz(SHA256)
https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/ openssh另一个下载地址
https://src.fedoraproject.org/repo/pkgs/openssh/ x11-ssh-askpass-1.2.4.1.tar.gz
2)生成构建目录,将所需.spec文件和源码包放到指定路径
shell> yum install -y rpmdevtools (如果已安装,忽略)
shell> rpmdev-setuptree 生成的默认路径在:/root/rpmbuild/
shell> tar -zxvf openssh-9.3p2.tar.gz 解压ssh,拿取.spec文件
shell> cp openssh-9.3p2/contrib/redhat/openssh.spec /root/rpmbuild/SPECS/
shell> mv openssh-9.3p2.tar.gz /root/rpmbuild/SOURCES/
shell> mv x11-ssh-askpass-1.2.4.1.tar.gz /root/rpmbuild/SOURCES/
2、构建OpenSSH RPM包
1)编译RPM包
shell> yum install -y rpm-build (如果已安装,忽略)
shell> rpmbuild -ba /root/rpmbuild/SPECS/openssh.spec
构建失败,需要安装依赖环境。
shell> yum install -y openssl-devel.x86_64 libXt-devel.x86_64 imake.x86_64 gtk2-devel.x86_64 krb5-devel.x86_64
说明:openssl-devel需要1.1.1版本,yum源里是1.0.2版本,不满足需要。我这里选择跳过openssl-devel环境检查
shell> vim /root/rpmbuild/SPECS/openssh.spec
shell> rpmbuild -ba /root/rpmbuild/SPECS/openssh.spec
如果遇到报错:configure: error: PAM headers not found
yum install -y pam-devel.x86_64
构建的rpm包在:/root/rpmbuild/RPMS/x86_64/
2)打包RPM包
shell> cd /root/rpmbuild/RPMS/
shell> tar -zcvf OpenSSH_9.3p2-el7-x86_64.tar.gz x86_64/*
打包好以后可以使用ansible等自动化工具分发给所有7.9_x86_64需要升级的主机。
shell> ansible 主机群组 -m copy -a "src=/path/OpenSSH_9.3p2-el7-x86_64.tar.gz dest=/path/"(路径根据各自情况为准)
说明:条件允许的情况下,建议在虚拟机上安装测试一下,在操作线上环境。要稳~
3、安装telnet
1)安装telnet
注意:一定要安装好telnet服务,一定要确保除ssh外 要有其他方式能够连接到设备,比如ipmi带外界面等。出现问题时 要有救急通道,否则就得端着电脑进机房了(我就进去了)
shell> yum install -y telnet-server.x86_64 telnet.x86_64 xinetd.x86_64
shell> vim /etc/xinetd.d/telnet 手动创建配置文件
service telnet
{
disable = no
flags = REUSE
socket_type = stream
wait = no
user = root
server =/usr/sbin/in.telnetd
log_on_failure += USERID
}
shell> systemctl restart telnet.socket xinetd.service
shell> netstat -anput | grep -Ew "telnet|xinetd|23" 检查23端口是否运行
2)SElinux和Firewalld设置
说明:selinux要设置为宽容模式,firewalld如果不用可以关掉,或者放行23端口。否则telnet登不上设备。
SElinux设置:
shell> setenforce 0 临时生效,重启失效
shell> getenforce 查看状态,状态要为Permissive或Disabled
shell> sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config 永久生效(需要重启设备)
Firewalld设置:
shell> systemctl stop firewalld.service 关闭firewalld
shell> systemctl disable firewalld.service 移除开机自启(选择性操作)
或者
shell> firewall-cmd --zone=public --add-port=23/tcp --permanent 开放23端口(--permanent参数为永久生效)
shell> firewall-cmd --reload 更新规则
shell> firewall-cmd --zone=public --query-port=23/tcp 查看放行状态,yes说明OK
3)连接测试
打开一个新终端
telnet root@IP地址
登录失败,检查原因
shell> tail -f /var/log/secure 查看系统日志
提示pts/1不安全,访问被拒绝
shell> echo "pts/1" >> /etc/securetty
注意:并不是每台主机都是pts/*,有的可能是npts/*。建议把pts/1~pts/10或者npts/1~npts/10加入到/etc/securetty,方便批量处理。
telnet root@IP地址 重新测试
SUCCESS!
4、安装OpenSSH_9.3p2
1)安装SSH
shell> ssh -V
当前版本为7.4p1
shell> tar -zxvf OpenSSH_9.3p2-el7-x86_64.tar.gz 解压构建好的rpm包
shell> cp /etc/ssh/sshd_config /etc/ssh/sshd_config_7.4p1_bak 备份老配置文件
shell> cp /etc/pam.d/sshd /etc/pam.d/sshd_bak 该文件一定要备份,如果缺少该文件 ssh运行正常也登不上设备。(更新时也会生成新的sshd,但缺少配置参数)
shell> rpm -Uivh /root/x86_64/openssh-*
安装完成。可自行看一下新、老sshd文件区别(/etc/pam.d/sshd、/etc/pam.d/sshd_bak)
shell> mv /etc/pam.d/sshd /etc/pam.d/sshd_rpmnew 将新生成的sshd改名备份
shell> mv /etc/pam.d/sshd_bak /etc/pam.d/sshd 将原来的sshd文件还原
shell> vim /etc/ssh/sshd_config 修改ssh配置文件
我这里只改了基本的参数,其他配置项或参数根据各自情况修改(也可以用老的配置文件)
shell> cd /etc/ssh/
shell> chmod 600 ssh_host_rsa_key ssh_host_ecdsa_key ssh_host_ed25519_key (需要修改这三个文件的权限,否则ssh起不来)
shell> systemctl restart sshd.service
shell> systemctl enable sshd.service && /sbin/chkconfig sshd on (一定要加入开机自启)
shell> ssh -V
升级完成。建议多试几次ssh登录,确保没问题
2)卸载telnet
说明:考虑到避免扫出telnet相关漏洞,telnet与ssh共存一段时间,ssh没问题了在卸载。
shell> systemctl stop telnet.socket xinetd.service
shell> rpm -qa | grep -E "telnet|xinetd"
shell> rpm -e $(rpm -qa | grep -E "telnet|xinetd") 卸载
RPM包从构建到升级,完成。
二、源码升级OpenSSH_9.3p2
说明:安装telnet和一些环境配置和上面一样,以下直接从编译开始。
注意:源码编译升级出现问题概率较高,尤其是批量操作,一定要安装好telnet服务。我的16台8.2系统就是采用源码批量升级,没有用rpm,结果9台有问题。主要的原因是 我用了ansible工具,它是基于ssh服务的,在升级ssh时中断了,导致playbook脚本没有执行完成,最后一台一台恢复的。
源码升级推荐编写一个本地shell升级脚本,测试好,没问题后在分发给所有需要升级的主机,然后通过ansible等自动化工具调度执行本地脚本,这样就可以规避ssh中断而导致后面的代码没有执行。(方法总比困难多)
1、源码编译
shell> tar -zxvf openssh-9.3p2.tar.gz -C /usr/src/
shell> cd /usr/src/openssh-9.3p2/
shell> yum install -y zlib-devel.x86_64 openssl-devel.x86_64 pam-devel.x86_64 gcc
shell> ./configure --prefix=/usr --sysconfdir=/etc/ssh --with-pam --with-md5-passwords
shell> make -j4
这里先只执行到make,打开一个新终端,接下列操作。(我选择这样操作是为了减少ssh中断时间)
2、卸载旧版本SSH
说明:考虑到下次漏扫时 担心还能扫出老版本的漏洞,我这里选择卸载老版本(危险!一定要安装好telnet。选择性操作)
shell> ssh -V
当前为7.4p1
shell> systemctl stop sshd.service 关闭SSH
shell> cp /etc/pam.d/sshd /etc/pam.d/sshd_bak 该文件一定要备份,缺少它一样无法ssh登录
shell> mv /etc/ssh /etc/ssh_7.4p1_bak 备份老文件,要改名,否则在安装9.3时会报错,意思就是该文件或目录已经存在
shell> rpm -qa | grep openssh
shell> rpm -e $(rpm -qa | grep openssh) --nodeps 卸载ssh,卸载时/etc/pam.d/sshd文件也会被移除掉
3、安装新版本SSH
回到之前的终端
shell> make install
shell> mv /etc/pam.d/sshd_bak /etc/pam.d/sshd 还原pam文件
shell> cp /usr/src/openssh-9.3p2/contrib/redhat/sshd.init /etc/init.d/sshd 复制控制脚本
shell> chmod +x /etc/init.d/sshd
shell> vim /etc/ssh/sshd_config 修改配置文件
我这里只修改了最基本配置项,其他配置项或参数根据各自情况配置。
shell> /etc/init.d/sshd restart 启动ssh
或者
shell> systemctl restart sshd.service
shell> systemctl enable sshd.service && /sbin/chkconfig sshd on && chkconfig --add sshd && systemctl restart sshd.service 一定要加入开机自启
shell> ssh -V
SUCCESS!
升级完成。建议多试几次ssh登录,确保没问题