Linux升级OpenSSH/OpenSSL步骤(附自动部署脚本)

为了达到更高的安全标准,常常需要升级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'`
osversion=${osversion:0:1}
# Redhat8/CentOS8不升级
if [ "${osversion}" -ge 8 ]
then
  echo "########当前操作系统版本已经很新了,不需升级########" > upgrade-openssh.log
  exit 0
fi
# Redhat6/CentOS6不升级
if [ "${osversion}" -eq 6 ]
then
  echo "########当前操作系统版本已经太旧了,不敢升级########" > upgrade-openssh.log
  exit 0
fi

# 检查OPENSSL版本
CHKSSLVER () {
opensslv=`openssl version | awk -F'[ -]' '{print $2}'` 
}

# 检查OPENSSH版本
CHKSSHVER () {
opensshv=`ssh -V 2>&1 | awk -F'[_,]' '{print $2}'`
}

# 检查基本命令和目录
chkwget=`rpm -qa wget`
if [ -z "${chkwget}" ]
then
  yum -y install wget
fi
# 检查安装目录
if [ -d "${inspath}" ]
then
  echo -e "########----升级OPENSSL/OPENSSH----########\n`date "+%Y%m%d%H%M%S"` 安装目录已存在" > ${exelogs}
else
  mkdir -p "${inspath}"
  echo -e "########----升级OPENSSL/OPENSSH----########\n`date "+%Y%m%d%H%M%S"` 成功创建安装目录" > ${exelogs}
fi
# 检查备份目录
if [ -d "${bakpath}" ]
then
  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}
fi
mkdir -p "${bakpath}"
echo "`date "+%Y%m%d%H%M%S"` 成功创建备份目录" >> ${exelogs}

#检查依赖包
CHKPACKS () {
if [ -d "${rpmpath}" ]
then
  cd ${rpmpath}
fi
for pack in ${deppacks[@]}
do
  packson=`rpm -qa "${pack}"`
  if [ -z "${packson}" ]
  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}`
  if [ -n "${errstatus}" ]
  then
    echo "`date "+%Y%m%d%H%M%S"` 编译环境未通过检查,终止升级" >> ${exelogs}
    echo "编译环境未通过检查,请重新执行安装程序"
    exit 0
  else
    echo "`date "+%Y%m%d%H%M%S"` 编译环境没有问题,开始编译" >> ${exelogs}
  fi
  rm -f ${errlogs}
fi
}

##### 安装OpenSSL #####

UPOPENSSL () {
deppacks=(gcc gcc-c++ autoconf automake make perl zlib zlib-devel openssl-devel)
CHKPACKS
sleep 3
cd $inspath
# 检查安装包
if [ -e "${soft1}" ]
then
  echo "`date "+%Y%m%d%H%M%S"` 已有${soft1}" >> ${exelogs}
else
  echo "`date "+%Y%m%d%H%M%S"` 下载${soft1}" >> ${exelogs}
  wget ${soft1dl}
fi
# 备份旧版openssl
chgfile1="/usr/bin/openssl"
chgfile2="/usr/include/openssl"
if [ -d "${soft1pt}" ]
then
  mv "${soft1pt}" "${bakpath}/"
  echo "`date "+%Y%m%d%H%M%S"` 备份${soft1pt}" >> ${exelogs}
fi
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`
if [ -z "${chkldcfg}" ]
then
  echo '/usr/local/openssl/lib/' >> /etc/ld.so.conf
  echo "`date "+%Y%m%d%H%M%S"` 已修改配置文件ld.so.conf" >> ${exelogs}
else
  echo "`date "+%Y%m%d%H%M%S"` 参数已存在,无需修改ld.so.conf" >> ${exelogs}
fi
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}
# 检查安装包
if [ -e "${soft2}" ]
then
  echo "`date "+%Y%m%d%H%M%S"` 已有${soft2}" >> ${exelogs}
else
  echo "`date "+%Y%m%d%H%M%S"` 下载${soft2}" >> ${exelogs}
  wget ${soft2dl}
fi
# 备份旧版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"
if [ -d "${soft2pt}" ]
then
 mv "${soft2pt}" "${bakpath}/"
 echo "`date "+%Y%m%d%H%M%S"` 备份${soft2pt}" >> ${exelogs}
fi
if [ -e "${soft2cf}" ]
then
  \cp -f "${soft2cf}" "${bakpath}/etc.ssh.sshd_config"
   echo "`date "+%Y%m%d%H%M%S"` 备份${soft2cf}" >> ${exelogs}
fi
if [ -e "${chgfile8}" ]
then
  \cp -f "${chgfile8}" "${bakpath}/etc.init_d.sshd.bak"
  echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile8}" >> ${exelogs}
fi
if [ -e "${chgfile9}" ]
then
  \cp -f "${chgfile9}" "${bakpath}/etc.pam_d.sshd_pam.bak"
  echo "`date "+%Y%m%d%H%M%S"` 备份${chgfile9}" >> ${exelogs}
fi
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
  rmsoft1=`rpm -qa openssh`
  if [ -n "${rmsoft1}" ]
  then
    rpm -e `rpm -qa openssh` --nodeps
    echo "`date "+%Y%m%d%H%M%S"` 卸载旧版openssh" >> ${exelogs}
  fi
  rmsoft2=`rpm -qa openssh-server`
  if [ -n "${rmsoft2}" ]
  then
    rpm -e `rpm -qa openssh-server` --nodeps
    echo "`date "+%Y%m%d%H%M%S"` 卸载旧版openssh-server" >> ${exelogs}
  fi
  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`
  if [ -z "${chkcfgsshd}" ]
  then
    systemctl enable sshd
  fi
else
  chkcfgsshd=`/sbin/chkconfig --list sshd`
  if [ -z "${chkcfgsshd}" ]
  then
    /sbin/chkconfig --add sshd
  fi
  /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
if [ "${soft1uv}" != "${opensslv}" ]
then
  echo -e "`date "+%Y%m%d%H%M%S"` 版本差异,请重新执行升级程序" >> ${exelogs}
  exit 1
else
  echo -e "`date "+%Y%m%d%H%M%S"` 版本匹配,继续升级OPENSSH" >> ${exelogs}
fi
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
  if [ $? -eq 0 ]
  then
    echo "`date "+%Y%m%d%H%M%S"` 大功告成,完成openssh升级" >> ${exelogs}
    echo ">>>>>大功告成,完成openssh升级<<<<<"
  else
    echo "`date "+%Y%m%d%H%M%S"` 重启OPENSSH失败,请检查配置文件" >> ${exelogs}
  fi
else
  echo -e '############----升级OPENSSH----############\n`date "+%Y%m%d%H%M%S"` 当前openssh版本是${opensshv},不需要升级' >> ${exelogs}
fi

原创文章禁止转载:技术学堂 » Linux升级OpenSSH/OpenSSL步骤(附自动部署脚本)

赞 (0) 打赏

精彩评论

5+2=

感谢您的支持与鼓励

支付宝扫一扫打赏

微信扫一扫打赏