为了达到更高的安全标准,常常需要升级Linux中的OpenSSH和OpenSSL至更新版本,本文讲述在CentOS系统下的更新方法,并附自动升级的shell脚本。
安装前建议先备份原openssl和openssh,步骤略。
部署openssl
点击此处访问OpenSSL官方下载页面查看是否有新版本,否则无需更新。
安装依赖包
yum -y install gcc gcc-c++ autoconf automake make perl zlib zlib-devel openssl-devel
安装openssl
cd /opt/installation wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz # 备份旧版openssl cp -f /usr/bin/openssl /opt/installation/bak/usr.bin.openssl.bak cp -f /usr/include/openssl /opt/installation/bak/usr.include.openssl.bak # 如果以前在/usr/local安装过openssl # mv /usr/local/openssl /opt/installation/bak/usr.local.openssl.bak # 开始更新openssl tar zxvf openssl-1.1.1k.tar.gz cd openssl-1.1.1k ./config --shared --openssldir=/usr/local/openssl --prefix=/usr/local/openssl make && make install ln -sf /usr/local/openssl/bin/openssl /usr/bin/openssl ln -sf /usr/local/openssl/include/openssl /usr/include/openssl echo '/usr/local/openssl/lib/' >> /etc/ld.so.conf ldconfig -v # Linux8版本不需要执行:ldconfig -v
查看openssl版本
openssl version
部署openssh
升级openssl后,继续升级openssh。点击此处访问OpenSSH官方下载页面查看是否有新版本,否则无需更新。
安装依赖包
yum install -y pam pam-devel pcre-devel perl rpm-build
安装openssh
# 备份旧版openssh cp -f /etc/init.d/sshd /opt/installation/bak/etc.init.d.sshd.bak cp -f /etc/pam.d/sshd.pam /opt/installation/bak/etc.pam.d.sshd.pam.bak cp -f /etc/ssh/sshd_config /opt/installation/bak/sshd_config.bak cp -f /usr/bin/ssh-keygen /opt/installation/bak/usr.bin.ssh-keygen.bak cp -f /usr/sbin/sshd /opt/installation/bak/usr.sbin.sshd.bak # 如果以前在/usr/local安装过openssh # mv /usr/local/openssh /opt/installation/bak/usr.local.openssh.bak # 卸载旧版openssh rpm -e `rpm -qa openssh openssh-server` --nodeps # 开始更新openssh cd /opt/installation wget https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.6p1.tar.gz tar zxvf openssh-8.6p1.tar.gz cd openssh-8.6p1 # 若没有编译部署openssl则必须去掉参数--with-openssl-dir=/usr/local/openssl ./configure --prefix=/usr/local/openssh --sysconfdir=/etc/ssh --with-openssl-dir=/usr/local/openssl --with-pam --with-zlib --with-md5-passwords make && make install cp -f contrib/redhat/sshd.init /etc/init.d/sshd cp -f contrib/redhat/sshd.pam /etc/pam.d/ chmod 600 /etc/ssh/ssh_host_ed25519_key # 配置openssh开机启动 systemctl enable sshd # CentOS6设置开机启动 # chkconfig --add sshd # chkconfig sshd on ln -sf /usr/local/openssh/bin/ssh-keygen /usr/bin/ssh-keygen ln -sf /usr/local/openssh/sbin/sshd /usr/sbin/sshd # 配置允许Root远程登录 echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config # 重新启动sshd systemctl restart sshd
常见问题分析
如果编译遇到如下报错“configure: error: OpenSSL library not found.”,尝试在./configure时添加如下参数:
# openssh ./configure --with-openssl-includes=/usr/local/openssl/include --with-openssl-libraries=/usr/local/openssl/lib
如果执行ssh时提示“-bash: /usr/local/openssh/bin/ssh: Permission denied”,可以通过以下方案修复:
chmod 755 /usr/local/openssh chmod 755 /usr/local/openssl
更新后系统报错“sshd: no hostkeys available — exiting”,重新生成密钥即可:
# 以下命令按默认执行即可 ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
配置openssh
修改配置/etc/ssh/sshd_config:
# 允许root登录 PermitRootLogin yes # 不允许空密码登录 PermitEmptyPasswords no # 设置是否使用口令验证 PasswordAuthentication yes # 配置认证文件 AuthorizedKeysFile .ssh/authorized_keys # 默认禁用pam验证登录 # UsePAM no # 配置sftp子系统 Subsystem sftp /usr/local/openssh/libexec/sftp-server
启动openssh
service sshd start # 查看SSH版本 ssh -V
自动部署脚本
该脚本已在CentOS6/7/8中进行测试。
#!/bin/bash # 初始化安装目录 inspath="/opt/installation" bakpath="${inspath}/bak" rpmpath="${inspath}/rpm" exelogs="${inspath}/install.log" errlogs="${inspath}/error.log" # OpenSSL下载地址【请修改为最新地址】 soft1dl="https://www.openssl.org/source/openssl-1.1.1k.tar.gz" # OpenSSL安装包名称 soft1=${soft1dl##*/} # OpenSSL解压文件夹 soft1dr=${soft1%%.tar*} # OpenSSL当前版本高于此版本时不升级 # soft1uv="1.1.1k" soft1uv=${soft1dr#*-} # OpenSSL安装目录 soft1pt="/usr/local/openssl" # OpenSSH下载地址【请修改为最新地址】 soft2dl="https://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.6p1.tar.gz" # OpenSSH安装包名称 soft2=${soft2dl##*/} # OpenSSH解压文件夹 soft2dr=${soft2%%.tar*} # OpenSSH当前版本高于此版本时不升级 # soft2uv="8.6p1" soft2uv=${soft2dr#*-} # OpenSSH安装目录 soft2pt="/usr/local/openssh" # OpenSSH配置文件 soft2cf="/etc/ssh/sshd_config" ##### 准备工作 ##### # 检查操作系统版本 osversion=`cat /etc/redhat-release | sed 's/[^0-9]//g'` # Redhat8/CentOS8不升级 [ "${osversion:0:1}" -ge 8 ] && echo "########当前操作系统版本已经很新了,不需升级########" > upgrade-openssh.log && exit 0 # Redhat6/CentOS6不升级 [ "${osversion}" -eq 6 ] && echo "########当前操作系统版本已经太旧了,不敢升级########" > upgrade-openssh.log && exit 0 # 检查OPENSSL版本 CHKSSLVER () { opensslv=`openssl version | awk -F'[ -]' '{print $2}'` } # 检查OPENSSH版本 CHKSSHVER () { opensshv=`ssh -V 2>&1 | awk -F'[_,]' '{print $2}'` } # 检查基本命令和目录 [ -z "`rpm -qa wget`" ] && yum -y install wget # 检查安装目录 [ ! -d "${inspath}" ] && mkdir -p "${inspath}" && echo -e "########----升级OPENSSL/OPENSSH----########\n`date "+%Y%m%d%H%M%S"` 成功创建安装目录" > ${exelogs} || echo -e "########----升级OPENSSL/OPENSSH----########\n`date "+%Y%m%d%H%M%S"` 安装目录已存在" > ${exelogs} # 检查备份目录 [ -d "${bakpath}" ] && tar -czvf ${inspath}/bak.`date "+%Y%m%d%H%M%S"`.tar.gz ${bakpath} --remove-files && echo "`date "+%Y%m%d%H%M%S"` 已打包原备份目录" >> ${exelogs} mkdir -p "${bakpath}" echo "`date "+%Y%m%d%H%M%S"` 成功创建备份目录" >> ${exelogs} #检查依赖包 CHKPACKS () { [ -d "${rpmpath}" ] && cd ${rpmpath} || exit 1 for pack in ${deppacks[@]} do if [ -z "`rpm -qa "${pack}"`" ] then yum -y install "${pack}" echo "`date "+%Y%m%d%H%M%S"` 安装依赖包${pack}" >> ${exelogs} else yum -y update "${pack}" echo "`date "+%Y%m%d%H%M%S"` 升级依赖包${pack}" >> ${exelogs} fi done } # 检查configure CHKCONFIG () { if [ -e "${errlogs}" ] then errstatus=`grep -E ": error|终止|not found" ${errlogs}` [ -n "${errstatus}" ] && echo "`date "+%Y%m%d%H%M%S"` 编译环境未通过检查,终止升级" >> ${exelogs} && echo "编译环境未通过检查,请重新执行安装程序" && exit 0 echo "`date "+%Y%m%d%H%M%S"` 编译环境没有问题,开始编译" >> ${exelogs} rm -f ${errlogs} fi } ##### 安装OpenSSL ##### UPOPENSSL () { deppacks=(gcc gcc-c++ autoconf automake make perl zlib zlib-devel openssl-devel) CHKPACKS sleep 3 cd $inspath # 检查安装包 [ ! -e "${soft1}" ] && echo "`date "+%Y%m%d%H%M%S"` 下载${soft1}" >> ${exelogs} && wget ${soft1dl} || echo "`date "+%Y%m%d%H%M%S"` 已有${soft1}" >> ${exelogs} # 备份旧版openssl chgfile1="/usr/bin/openssl" chgfile2="/usr/include/openssl" [ -d "${soft1pt}" ] && mv "${soft1pt}" "${bakpath}/" && echo "`date "+%Y%m%d%H%M%S"` 备份${soft1pt}" >> ${exelogs} if [ -e "${chgfile1}" ] || [ -L "${chgfile1}" ] then mv "${chgfile1}" "${bakpath}/usr.bin.openssl.bak" echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile1}" >> ${exelogs} fi if [ -e "${chgfile2}" ] || [ -L "${chgfile2}" ] then mv "${chgfile2}" "${bakpath}/user.include.openssl.bak" echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile2}" >> ${exelogs} fi # 开始安装 tar zxvf "${soft1}" if [ -d "${soft1dr}" ] then cd "${soft1dr}" echo "`date "+%Y%m%d%H%M%S"` 开始配置openssl编译环境" >> ${exelogs} ./config --shared --openssldir=${soft1pt} --prefix=${soft1pt} > ${errlogs} else echo "`date "+%Y%m%d%H%M%S"` 目录${soft1dr}不存在,终止升级" >> ${exelogs} exit 0 fi CHKCONFIG sleep 1 echo "`date "+%Y%m%d%H%M%S"` 完成配置,开始make安装文件" >> ${exelogs} make depend make echo "`date "+%Y%m%d%H%M%S"` 完成make,开始编译openssl" >> ${exelogs} make install sleep 3 ln -sf /usr/local/openssl/bin/openssl "${chgfile1}" ln -sf /usr/local/openssl/include/openssl "${chgfile2}" chkldcfg=`grep "/usr/local/openssl/lib/" /etc/ld.so.conf` [ -z "${chkldcfg}" ] && echo '/usr/local/openssl/lib/' >> /etc/ld.so.conf && echo "`date "+%Y%m%d%H%M%S"` 已修改配置文件ld.so.conf" >> ${exelogs} || echo "`date "+%Y%m%d%H%M%S"` 参数已存在,无需修改ld.so.conf" >> ${exelogs} sleep 1 ldconfig -v sleep 3 CHKSSLVER if [ "${opensslv}" != “”${soft1uv}“” ] || [ !-d "${soft1pt}" ] then echo "`date "+%Y%m%d%H%M%S"` 完成OPENSSL升级" >> ${exelogs} else echo "`date "+%Y%m%d%H%M%S"` 成功升级OPENSSL" >> ${exelogs} fi } ##### 安装OpenSSH ##### UPOPENSSH () { deppacks=(pam pam-devel pcre-devel perl rpm-build) CHKPACKS sleep 3 cd ${inspath} # 检查安装包 [ ! -e "${soft2}" ] && echo "`date "+%Y%m%d%H%M%S"` 下载${soft2}" >> ${exelogs} && wget ${soft2dl} || echo "`date "+%Y%m%d%H%M%S"` 已有${soft2}" >> ${exelogs} # 备份旧版openssh chgfile5="/usr/bin/ssh" chgfile6="/usr/sbin/sshd" chgfile7="/usr/bin/ssh-keygen" chgfile8="/etc/init.d/sshd" chgfile9="/etc/pam.d/sshd.pam" [ -d "${soft2pt}" ] && mv "${soft2pt}" "${bakpath}/" && echo "`date "+%Y%m%d%H%M%S"` 备份${soft2pt}" >> ${exelogs} [ -e "${soft2cf}" ] && cp -rf "${soft2cf}" "${bakpath}/etc.ssh.sshd_config" && echo "`date "+%Y%m%d%H%M%S"` 备份${soft2cf}" >> ${exelogs} [ -e "${chgfile8}" ] && cp -rf "${chgfile8}" "${bakpath}/etc.init_d.sshd.bak" && echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile8}" >> ${exelogs} [ -e "${chgfile9}" ] && cp -rf "${chgfile9}" "${bakpath}/etc.pam_d.sshd_pam.bak" && echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile9}" >> ${exelogs} if [ -e "${chgfile7}" ] || [ -L "${chgfile7}" ] then mv "${chgfile7}" "${bakpath}/user.bin.ssh-keygen.bak" echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile7}" >> ${exelogs} fi if [ -e "${chgfile6}" ] || [ -L "${chgfile6}" ] then mv "${chgfile6}" "${bakpath}/usr.sbin.sshd.bak" echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile6}" >> ${exelogs} fi if [ -e "${chgfile5}" ] || [ -L "${chgfile5}" ] then mv "${chgfile5}" "${bakpath}/usr.bin.ssh.bak" echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile5}" >> ${exelogs} fi # 开始安装 tar zxvf "${soft2}" if [ -d "${soft2dr}" ] then [ -n "`rpm -qa openssh`" ] && rpm -e `rpm -qa openssh` --nodeps && echo "`date "+%Y%m%d%H%M%S"` 卸载旧版openssh" >> ${exelogs} [ -n "`rpm -qa openssh-server`" ] && rpm -e `rpm -qa openssh-server` --nodeps && echo "`date "+%Y%m%d%H%M%S"` 卸载旧版openssh-server" >> ${exelogs} cd "${soft2dr}" echo "`date "+%Y%m%d%H%M%S"` 开始配置openssh编译环境" >> ${exelogs} ./configure --prefix=${soft2pt} --sysconfdir=/etc/ssh --with-ssl-dir=${soft1pt} --with-pam --with-zlib --with-md5-passwords > $errlogs else echo "`date "+%Y%m%d%H%M%S"` 目录${soft2dr}不存在,终止升级" >> ${exelogs} exit 0 fi CHKCONFIG echo "`date "+%Y%m%d%H%M%S"` 完成配置,开始make安装文件" >> ${exelogs} make echo "`date "+%Y%m%d%H%M%S"` 完成make,开始编译openssh" >> ${exelogs} make install sleep 1 cp -f "${inspath}/${soft2dr}/contrib/redhat/sshd.init" "${chgfile8}" cp -f "${inspath}/${soft2dr}/contrib/redhat/sshd.pam" "${chgfile9}" echo "`date "+%Y%m%d%H%M%S"` 复制新sshd/sshd.pam至系统" >> ${exelogs} chmod 600 /etc/ssh/ssh_host_rsa_key chmod 600 /etc/ssh/ssh_host_ecdsa_key chmod 600 /etc/ssh/ssh_host_ed25519_key echo "`date "+%Y%m%d%H%M%S"` 修改ssh_key文件属性" >> ${exelogs} if [ "${osversion}" -ge 7 ] then chkcfgsshd=`systemctl list-unit-files | grep sshd.service | grep enabled` [ -z "${chkcfgsshd}" ] && systemctl enable sshd else chkcfgsshd=`/sbin/chkconfig --list sshd` [ -z "${chkcfgsshd}" ] && /sbin/chkconfig --add sshd /sbin/chkconfig sshd on fi echo "`date "+%Y%m%d%H%M%S"` 配置sshd开机启动" >> ${exelogs} ln -sf /usr/local/openssh/bin/ssh-keygen "${chgfile7}" ln -sf /usr/local/openssh/sbin/sshd "${chgfile6}" ln -sf /usr/local/openssh/bin/ssh "${chgfile5}" } ##### 开始执行升级程序 ##### CHKSSLVER if [ -z "${opensslv}" ] || [ ${soft1uv} \> ${opensslv} ] then echo -e "############----升级OPENSSL----############\n`date "+%Y%m%d%H%M%S"` 当前版本${opensslv},升级到${soft1uv}" >> ${exelogs} UPOPENSSL else echo -e "############----升级OPENSSL----############\n`date "+%Y%m%d%H%M%S"` 当前版本${opensslv},不需要升级" >> ${exelogs} fi sleep 3 CHKSSLVER [ "${soft1uv}" != "${opensslv}" ] && echo -e "`date "+%Y%m%d%H%M%S"` 版本差异,请重新执行升级程序" >> ${exelogs} && exit 1 || echo -e "`date "+%Y%m%d%H%M%S"` 版本匹配,继续升级OPENSSH" >> ${exelogs} CHKSSHVER if [ -z "${opensshv}" ] || [ "${soft2uv}" \> "${opensshv}" ] then echo -e "############----升级OPENSSH----############\n`date "+%Y%m%d%H%M%S"` 当前版本${opensshv},升级到${soft2uv}" >> ${exelogs} UPOPENSSH echo 'PermitRootLogin yes' >> ${soft2cf} echo "`date "+%Y%m%d%H%M%S"` 已经配置为允许root登录" >> ${exelogs} egrep -v "^$|^#" ${soft2cf} echo "`date "+%Y%m%d%H%M%S"` 重新重启sshd" >> ${exelogs} service sshd restart sleep 3 systemctl status sshd [ $? -eq 0 ] && echo "`date "+%Y%m%d%H%M%S"` 大功告成,完成openssh升级" >> ${exelogs} && echo ">>>>>大功告成,完成openssh升级<<<<<" || echo "`date "+%Y%m%d%H%M%S"` 重启OPENSSH失败,请检查配置文件" >> ${exelogs} else echo -e '############----升级OPENSSH----############\n`date "+%Y%m%d%H%M%S"` 当前openssh版本是${opensshv},不需要升级' >> ${exelogs} fi
原创文章禁止转载:技术学堂 » Linux升级OpenSSH/OpenSSL步骤(附自动部署脚本)