为了达到更高的安全标准,常常需要升级Linux中的OpenSSH和OpenSSL至更新版本,本文讲述在CentOS系统下的更新方法,并附自动升级的shell脚本。
安装前建议先备份原openssl和openssh,步骤略。
部署openssl
点击此处访问OpenSSL官方下载页面查看是否有新版本,否则无需更新。
安装依赖包
1 |
yum -y install gcc gcc-c++ autoconf automake make perl zlib zlib-devel openssl-devel |
安装openssl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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版本
1 |
openssl version |
部署openssh
升级openssl后,继续升级openssh。点击此处访问OpenSSH官方下载页面查看是否有新版本,否则无需更新。
安装依赖包
1 |
yum install -y pam pam-devel pcre-devel perl rpm-build |
安装openssh
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 |
# 备份旧版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时添加如下参数:
1 2 |
# 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”,可以通过以下方案修复:
1 2 |
chmod 755 /usr/local/openssh chmod 755 /usr/local/openssl |
更新后系统报错“sshd: no hostkeys available — exiting”,重新生成密钥即可:
1 2 3 |
# 以下命令按默认执行即可 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 允许root登录 PermitRootLogin yes # 不允许空密码登录 PermitEmptyPasswords no # 设置是否使用口令验证 PasswordAuthentication yes # 配置认证文件 AuthorizedKeysFile .ssh/authorized_keys # 默认禁用pam验证登录 # UsePAM no # 配置sftp子系统 Subsystem sftp /usr/local/openssh/libexec/sftp-server |
启动openssh
1 2 3 4 |
service sshd start # 查看SSH版本 ssh -V |
自动部署脚本
该脚本已在CentOS6/7/8中进行测试。
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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
#!/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步骤(附自动部署脚本)