前言
漏洞扫描总是扫出openssh版本过低存在高危风险的情况,所以干脆直接编译安装新版本,发现网上的教程都是存在一些问题的,比如centos6适用,到了centos7再用相同方法就会出现sshd服务开机无法自启的问题,但是你用systemctl命令又可以让sshd服务启动起来,sshd服务在生产环境是非常重要的,不可能每次服务器重启都要VNC连上去启动一次服务,找了很久发现是openssh官方源代码的问题,具体参考以下文章,测试升级openssl-1.1.1i + openssh-8.4p1该方法依然有效,最后提供的懒人脚本支持centos6和centos7自动判断安装,并支持回退到系统自带版本,不会存在sshd服务挂掉的问题。
准备工作
远程ssh连接最好先安装Telnet服务防止SSH无法启动导致无法连接服务器,如果SSH挂掉,就只能VNC连接服务器。
CentOS安装Telnet服务可以看这篇文章 CentOS安装Telnet服务
# 依赖库安装
yum -y install gcc gcc-c++ glibc make autoconf pcre-devel pam-devel openssl-devel zlib-devel
# 注意安装升级openssh时需要关闭SELinux,否则退出后无法登陆
setenforce 0
sed -i 's/enforcing/disabled/g' /etc/sysconfig/selinux
Zlib安装
wget http://www.zlib.net/zlib-1.2.11.tar.gz
tar -zxf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure --prefix=/usr/local/zlib
make && make install
echo "/usr/local/zlib/lib" >> /etc/ld.so.conf.d/zlib.conf
ldconfig
Open SSL安装
# 下载解压软件包
wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz
tar -zxf openssl-1.1.1i.tar.gz
cd openssl-1.1.1i
# 编译安装
./config --prefix=/usr/local/openssl -d shared
make && make install
# 备份老版本
mv /usr/bin/openssl /usr/bin/openssl_bak
# 新版本添加软连接
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/openssl/include/openssl /usr/include/openssl
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1 #解决so文件报错
ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
#添加新函数库
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf.d/openssl.conf
ldconfig
# 检查安装的版本
openssl version
Open SSH安装
cd ~
wget https://openbsd.hk/pub/OpenBSD/OpenSSH/portable/openssh-8.4p1.tar.gz
tar -zxf openssh-8.4p1.tar.gz
cd openssh-8.4p1
chown -R root.root * # 修改权限,防止出错
# 备份老配置(改名后不能退出当前终端,若退出,只能通过telnet连了)
mv /etc/ssh /etc/ssh_bak
# 配置编译安装
./configure --prefix=/usr/local/openssh --sysconfdir=/etc/ssh --with-pam --with-ssl-dir=/usr/local/openssl --with-md5-passwords --mandir=/usr/share/man --with-zlib=/usr/local/zlib --without-hardening
# 以下四条命令是解决centos7无法用systemctl控制sshd服务用的,centos6跳过
yum -y -q install systemd-devel #解决centos7无法使用systemctl控制
sed -i '44a\\#include <systemd/sd-daemon.h>' sshd.c #添加头文件
sed -i '2070a\ sd_notify(0, "READY=1");' sshd.c # 修改sshd.c文件添加信号
sed -i 's/LIBS=-lcrypto -ldl -lutil -lz -lcrypt -lresolv/LIBS=-lcrypto -ldl -lutil -lz -lcrypt -lresolv -lsystemd/' Makefile
make && make install
# 拷贝启动脚本
cp ./contrib/redhat/sshd.init /etc/init.d/sshd
chmod +x /etc/init.d/sshd
# 修改sshd配置文件/etc/ssh/sshd_config(重要!)
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
echo 'PubkeyAuthentication yes' >> /etc/ssh/sshd_config
echo 'X11Forwarding yes' >> /etc/ssh/sshd_config
echo "UsePAM yes" >>/etc/ssh/sshd_config
# 替换相关命令,并重启sshd服务(询问覆盖全输入y)
cp /usr/local/openssh/bin/* /usr/bin/
mv /usr/sbin/sshd /usr/sbin/sshd_bak
cp /usr/local/openssh/sbin/sshd /usr/sbin/sshd #直接替换sshd文件就不需要修改/etc/init.d/sshd中的路径了
# 添加sshd服务到自启
chkconfig --add sshd
chkconfig --level 2345 sshd on
systemctl enable sshd
systemctl enable sshd.socket
/etc/init.d/sshd restart
# 查看22端口ssh服务是否正常
netstat -lntp
# 查看ssh和ssl版本
ssh -V
PS:升级全程请不要关闭当前的SSH连接,否则配置错误会导致SSH连不上,只能从面板VNC进去
懒人脚本
首先用wget下载软件包,或者手动上传到~/ssh文件夹
mkdir ssh
cd ssh
wget http://www.zlib.net/zlib-1.2.11.tar.gz
wget https://www.openssl.org/source/openssl-1.1.1i.tar.gz
wget https://openbsd.hk/pub/OpenBSD/OpenSSH/portable/openssh-8.4p1.tar.gz
运行脚本方法:
添加执行权限 chmod u+x ssh.sh,运行脚本,后面带update参数更新openssh,带restore参数则回退版本
#!/bin/bash
#openssl&openssh update script
#author Millet
#version 1.0
#chmod u+x ssh.sh && ./ssh.sh update|restore
path="/root"
zlib="zlib-1.2.11"
ssl="openssl-1.1.1i"
ssh="openssh-8.4p1"
format=".tar.gz"
os=`cat /etc/redhat-release|sed -r 's/.* ([0-9]+)\..*/\1/'`
update(){
yum -y install gcc gcc-c++ glibc make autoconf pcre-devel pam-devel openssl-devel zlib-devel
#安装zlib
cd $path/ssh
tar -zxf $zlib$format
cd $zlib
./configure --prefix=/usr/local/zlib
make -j2 -s && make install
echo "/usr/local/zlib/lib" >> /etc/ld.so.conf.d/zlib.conf
ldconfig
# 升级openssl
if [ $? -eq 0 ]; then
echo "start install openssl "
cd $path/ssh
tar -zxf $ssl$format
cd $ssl
./config --prefix=/usr/local/openssl -d shared
sleep 1
make -j2 -s && make install
if [ $? -eq 0 ]; then
echo "make success"
mv /usr/bin/openssl /usr/bin/openssl_bak
ln -s /usr/local/openssl/bin/openssl /usr/bin/openssl
ln -s /usr/local/openssl/include/openssl /usr/include/openssl
ln -s /usr/local/openssl/lib/libssl.so.1.1 /usr/lib64/libssl.so.1.1 #解决so文件报错
ln -s /usr/local/openssl/lib/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
echo "/usr/local/openssl/lib" >> /etc/ld.so.conf.d/openssl.conf
ldconfig
openssl version
sleep 3
else
echo "make fail"
fi
else
echo "yum install fail"
fi
#升级openssh
if [ $? -eq 0 ]; then
echo "start install openssh"
cd $path/ssh
tar -zxf $ssh$format
chown -R root.root $ssh
cd $ssh
mv /etc/ssh /etc/ssh_bak #备份配置文件
./configure --prefix=/usr/local/openssh --sysconfdir=/etc/ssh --with-pam --with-ssl-dir=/usr/local/openssl --with-md5-passwords --mandir=/usr/share/man --with-zlib=/usr/local/zlib --without-hardening
case $os in
6)
mv /etc/rc.d/init.d/sshd /etc/rc.d/init.d/sshd_bak #备份centos6服务启动文件
;;
7)
yum -y -q install systemd-devel #解决centos7无法使用systemctl控制
sed -i '44a\\#include <systemd/sd-daemon.h>' sshd.c #添加头文件
sed -i '2070a\ sd_notify(0, "READY=1");' sshd.c # 修改sshd.c文件添加信号
sed -i 's/LIBS=-lcrypto -ldl -lutil -lz -lcrypt -lresolv/LIBS=-lcrypto -ldl -lutil -lz -lcrypt -lresolv -lsystemd/' Makefile
;;
esac
if [ $? -eq 0 ]; then
echo "configure success"
make -j2 -s && make install
if [ $? -eq 0 ]; then
echo "make success"
cp ./contrib/redhat/sshd.init /etc/init.d/sshd
chmod +x /etc/init.d/sshd
echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
echo 'PubkeyAuthentication yes' >> /etc/ssh/sshd_config
echo 'X11Forwarding yes' >> /etc/ssh/sshd_config
echo "UsePAM yes" >>/etc/ssh/sshd_config
#备份替换命令文件
cd /usr/bin/
tar -zcf ssh_bak.tar.gz scp sftp ssh ssh-add ssh-agent ssh-keygen ssh-keyscan
rm -rf scp sftp ssh ssh-add ssh-agent ssh-keygen ssh-keyscan #备份后删除旧命令文件
cp /usr/local/openssh/bin/* /usr/bin/
mv /usr/sbin/sshd /usr/sbin/sshd_bak
cp /usr/local/openssh/sbin/sshd /usr/sbin/sshd #直接替换sshd就不需要修改/etc/init.d/sshd中的路径了
sshd -t -f /etc/ssh/sshd_config
case $os in
6)
chkconfig --add sshd
chkconfig --level 2345 sshd on
;;
7)
systemctl disable sshd #移除旧开机启动项(不移除可能无法开机自启)
systemctl enable sshd
;;
esac
/etc/init.d/sshd restart
netstat -lntp
ssh -V
else
echo "make fail"
fi
else
echo "configure fail"
fi
else
echo "openssl install fail"
fi
}
recover(){
# 卸载zlib
cd $path/ssh
cd $zlib
make uninstall
rm -rf /etc/ld.so.conf.d/zlib.conf
ldconfig
# 卸载openssl
cd $path/ssh
cd $ssl
make uninstall
if [ $? -eq 0 ]; then
echo "uninstall openssl success"
rm -rf /usr/bin/openssl
rm -rf /usr/include/openssl
mv /usr/bin/openssl_bak /usr/bin/openssl
rm -rf /usr/lib64/libssl.so.1.1
rm -rf /usr/lib64/libcrypto.so.1.1
rm -rf /etc/ld.so.conf.d/openssl.conf
ldconfig
openssl version
sleep 3
else
echo "uninstall openssl fail"
fi
#卸载openssh
if [ $? -eq 0 ]; then
echo "uninstall openssh"
cd $path/ssh
cd $ssh
make uninstall
rm -rf /etc/ssh
mv /etc/ssh_bak /etc/ssh
rm -f /etc/init.d/sshd
mv /etc/rc.d/init.d/sshd_bak /etc/rc.d/init.d/sshd #还原centos6服务启动文件
cd /usr/bin/
rm -rf scp sftp ssh ssh-add ssh-agent ssh-keygen ssh-keyscan
tar -zxf ssh_bak.tar.gz
rm -rf /usr/sbin/sshd
mv /usr/sbin/sshd_bak /usr/sbin/sshd
sshd -t -f /etc/ssh/sshd_config
case $os in
6)
chkconfig --add sshd
chkconfig --level 2345 sshd on
service sshd restart
;;
7)
systemctl enable sshd
systemctl restart sshd
;;
esac
netstat -lntp
ssh -V
else
echo "uninstall openssh fail"
fi
}
case $1 in
update)
update
;;
restore)
recover
;;
esac