由于全网安全检查需要,要对项目中1280台Linux系统升级SSH及openssl,其中:
OPENSSH 升级为 openssh 7.9p
下载地址:
openssl 升级为 1.0.2o
下载地址:
涉及的系统版本为:
rhel5 32 位、64位
rhel6 32 位、64位
rhel7 64位
openssl下对应的两个关键库文件(用多了就知道,这两个东西出问题了就该找谁):
libssl.so
libcrypto.so
准备工具:
1. openssl 编译安装包
2. ssh 安装包(已经被改造成公司自用版)
3. ansible (批量操作软件)
前期工作:
1. 根据不同系统版本,打包为不同的 openssl 及 ssh 升级包,内部包含升级脚本
openssl 升级命令为 :
# tar -zxf openssl-1.0.2o.tar.gz
# cd openssl-1.0.2o
# make clean
# ./config --prefix=/home/caya/openssh --shared /*默认路径为 /usr ,为避免远古脚本无法执行,此处修改为 /home/caya/openssh */
(32位加上参数 -m32)
# make && make install
/*新测试,可不需要 -m32 ,包本身必须干净,别用编译过的再打包给别人编译!!!*/
openssh 升级命令为:
# tar -zxf openssh-7.9p1.tar.gz
# cd openssh-7.9p1
# mv /etc/ssh /etc/ssh.bak 备份配置文件
# vi version.h /* 修改成你喜欢的版本号,此处可忽略*/
# ./configure /* 请写到一行 */
--prefix=/home/caya/openssh /*安装目录,默认为 /usr*/
--sysconfdir=/home/caya/openssh/etc/ssh /*配置文件目录,默认为 /ect/ssh */
--with-md5-passwords /*这个随便吧*/
--with-ssl-dir=/home/caya/openssl /*此处是关键!要与前面ssl安装的路径一致!*/
# make && make install
2. 编写脚本根据系统版本分发安装包
检测系统版本指指令为:
dis=$(uname -a|awk '{print $3}'|awk -F 'el' '{print $2}'|awk -F '.' '{print $1}')
bites=$(uname -a|grep x86_64|wc -l)
([[ $dis = 7 ]]&&[[ $bites = 1 ]] && wget ...)||
([[ $dis = 6 ]]&&[[ $bites = 1 ]] && wget ...)||
([[ $dis = 6 ]]&&[[ $bites = 0 ]] && wget ...)||
([[ $dis = 5 ]]&&[[ $bites = 1 ]] && wget ...)||
([[ $dis = 5 ]]&&[[ $bites = 0 ]] && wget ...)||
(echo unknown system)
3. 通过 ansible 分发脚本并执行
ansible 本身实际上是逐个通过ssh执行操作的, 一旦下载文件的地址不通的话就会让后面的操作一直阻塞,
最好下载文件的位置与ansible是同一IP 这样就能有效避免阻塞导致升级失败(顶多就是超时连不上跳到下一台机)
升级过程出现的问题:
1. ansible 直接多条命令执行运行效果不好,特别是对变量无法有效赋值, 最后通过 copy 模块把脚本分发到服务器解决
2. 由于ansible执行方式是根据hosts逐条通过ssh登录系统,目标系统内如果wget 无法连接源仓库的话,该主机会一直尝试连接,最终会导致后面所有主机一直等待
3. 部分主机会提示插件问题,待后期处理
4. ssh 编译时提示: configure: error: OpenSSL version header not found
分析:不知道,反正装了下面那个就可以,旧版也可以不影响升级
解决方法:yum -y install openssl-devel
升级后出现的问题:
1. 32位系统全部升级失败,编译过程中有冗余文件提示
解决方法:
a. 可能是原升级包被编译过再进行打包, 执行指令 make clean 清理冗余文件
b. 生成库文件版本不对, ./config 后添加 -m32 强制所有库文件为32位文件
2. 升级后提示缺失 libcrypto.so 库文件
解决方法:
去别的同类型系统复制一个库文件并做好软连接即可
3. 提示 openssl 版本不对
分析: 实际上还是库文件目录问题,根据其环境变量优先使用就近库文件,导致库文件不匹配
解决方法:
1. ldd /usr/sbin/sshd 检查库文件目录:
linux-vdso.so.1 => (0x00007fff56a7d000)
libcrypto.so.1.0.0 => /usr/local/ssl/lib/libcrypto.so.1.0.0 (0x00002b876b7ef000)
librt.so.1 => /lib64/librt.so.1 (0x00002b876bbb5000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b876bdbf000)
libutil.so.1 => /lib64/libutil.so.1 (0x00002b876bfc3000)
libz.so.1 => /lib64/libz.so.1 (0x00002b876c1c6000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00002b876c3db000)
2. 明显 libcrypto.so.1.0.0 位置与其他库文件不同,环境变量的锅
mv /usr/local/ssl/lib /usr/local/ssl/lib.bak 封了那个搞事的库
3. service sshd restart 提示成功!
4. ssh 重启提示: /usr/lib64/libcrypto.so.10: no version information available
分析: /usr/lib64/libcrypto.so.10 软连接到不合适的 libcrypto.so.1.0.0文件去了
解决方法: 重新编译openssh
总结:
单独升级openssh或者openssl出现问题会比较多,这一般是早期配置环境的人使用非默认位置导致的
最好的解决方法是两个一起编译安装,熟悉了目录规则之后就知道怎么在不重新编译的情况下解决库的问题了。
熟用ldd是非常好的。
更新:
动态库库的管理工具为: ldconfig, 及其配置文件:/etc/ld.so.conf
ldconfig //更新动态库
ldconfig -p //打印出所有关联库的位置
因此,如果不想多余的动态库被连接,可以通过修改/etc/ld.so.conf解决