1、背景
安全整改过程中针对服务器共性问题的修复,SSH弱密钥交换算法漏洞为例,以上篇中的《Centos7修复ssh弱密钥交换算法漏洞》为场景结合优化处理。ansible环境搭建可以参考《win10系统下ansible环境的搭建》
2、目的
批量修复服务器的SSH弱密钥交换算法漏洞
3、环境说明
名称 | 型号 | 备注 |
window10 | 教育版64位 | 主操作系统 |
WSL | 1.0 | 介质 |
Linux | ubuntu18.04LTS | 子操作系统 |
ansible | 2.9.10 | 运维工具 |
Centos7 | 7.9.2009 | 远程主机操作系统 |
4、工具选型
本次以ansible工具为例进行操作。
5、问题说明
安全扫描厂家提供如下信息
漏洞名称 | 漏洞描述 | 等级 | 安全建议 |
SSH Weak Key Exchange Algorithms Enabled SSH 弱密钥交换算法已启用 | 远程 SSH 服务器配置为允许被认为是弱的密钥交换算法。这是基于 IETF 草案文档 Key Exchange (KEX) Method Updates and Recommendations for Secure Shell (SSH) draft-ietf-curdle-ssh-kex-sha2-20。第 4 节列出了关于不应和不得启用的密钥交换算法的指南。这包括:diffie-hellman-group-exchange-sha1、diffie-hellman-group1-sha1、gss-gex-sha1-、gss-group1-sha1-、gss-group14-sha1-*、rsa1024-sha1 | 低危 | 联系供应商或查阅产品文档以禁用弱算法。 |
6、处理说明
6.1、方案选型
两种处理方案:
方案一 通过调整配置文件,规避此安全漏洞,
方案二 升级ssh程序,修复此安全漏洞
本文选取方案二
项目名称 | 原版本号 | 升级后版本号 |
OpenSSL | 1.0.2k-fips | 3.0.0 |
OpenSSH | 7.4p1 | 8.8p1 |
6.2、处理思路
6.2.1、漏洞原因:
该漏洞是由于操作系统自带软件版本过旧,导致的漏洞,Centos7.x及以前版本会存在此漏洞。
6.2.2、风险点分析
远程登陆使用的是ssh服务进行,修复过程中会产生服务启停操作,即时会有远程登陆无法登陆的情况,故在处理过程中需要考虑到此风险,
6.2.3、风险应对
针对此风险应对措施如下:
1、服务器开启telnet服务,保证ssh启停过程中可以通过telnet登陆服务器操作系统
2、使用显示器接入服务器,即使远程登陆无法使用,可以直接操作服务器
本次使用措施1进行风险应对。
6.3、处理过程
针对以上的考虑出具如下解决步骤:
1、开启服务器telnet
2、升级软件
由于是多台服务器,使用自动化运维工具ansible工具进行批量操作。
6.3.1、准备工作
6.3.1.1、查看服务
ansible语法
ansible host/ip -m 模块 -a '参数' -i host文件
#常用到的模块
command 远程主机上执行命令,默认模块
shell 远程主机上执行命令,可以支持管道符
setup 收集远程主机的一些信息
copy 本地文件复制到远程主机上
file 设置文件属性
yum 管理安装相关程序包
service 管理服务
group 管理用户组模块
user 管理用户模块
lineinfile 管理远程文件中的内容
查看服务使用到ansible的command模块,command模块为默认模块。
$ ansible jgxt3 -a "rpm -qa telnet-server" # 查看telnet-server服务
$ ansible jgxt3 -a "rpm -qa xinetd" # 查看xinetd服务
$ ansible jgxt3 -a "systemctl status telnet" # 查看telnet服务状态
ansible中command相关参数
chdir 进入到指定目录下,执行命令
creates 指定文件存在时,不执行
removes 指定文件不存在时,不执行
6.3.1.2、创建用户
默认root账号没有telnet权限,使用普通账户relnet远程登陆,如果需要提权,登陆后切换root权限。
创建用户使用到ansible的group和user模块
创建组
创建jgxt用户组
$ ansible jgxt3 -m group -a "name=jgxt state=present"
ansible的group参数
name 组名称
gid 指定组的GID
state 指定组的状态,present-创建组 absent-删除组
system
创建用户
创建jgxt用户
$ ansible jgxt3 -m user -a "name=jgxt state=present groups=jgxt,jgxt shell=/bin/bash append=yes"
ansible-user参数
name 用户名
password 为用户设置密码
update_password always-只有当密码不相同时才会更新密码,on_create-为新用户设置密码
shell 用户shell设定
groups 用户组设定
home 指定用户家目录
state 状态,present-创建用户,absent-删除用户
append 追加,yes-增量添加group,no-全量变更group,只设置groups指定的group组(默认)
remove 配合state=absent使用,删除用户的家目录-remove=yes
expires 设置用户的过期时间,值是一个时间戳
6.3.1.3、下载软件
创建目录
$ ansible jgxt3 -m file -a "path=/home/tools/telnet owner=jgxt group=jgxt state=directory mode=0644"
ansible-file模块参数
path 必选。用于指定要操作的文件或者目录。
src 当state设置为link或者hard的时候,此参数为链接文件的源文件。
dest 当state设置为link或者hard的时候,此参数为链接文件路径。
force 当state为link的时候,force设置为yes,则就算文件不存在,依旧创建链接文件。
group 设定远程主机目录的组名
mode 设定远程主机文件及目录的权限
owner 设定远程主机目录的用户名
recurse 被操作的文件为目录,将其设置为yes,可递归修改属性。
state
=directory 如果目录不存在,创建目录
=file 即使文件不存在,也不会被创建
=link 创建软链接
=hard 创建硬链接
=touch 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
=absent 删除目录、文件或者取消链接文件
下载软件
软件下载这块为下载到本地,然后通过ansible分发到被控主机
下载本地
创建存储目录
# mkdir -p /home/tools/telnet
# mkdir -p /home/tools/openssl
# mkdir -p /home/tools/openssh
# 下载telnet软件
# cd /home/tools/telnet
# yum -y install telnet-server --downloadonly --downloaddir ./
# yum -y install xinetd --downloadonly --downloaddir ./
# 下载openssl软件
# cd /home/tools/
# wegt https://ftp.openssl.org/source/openssl-3.0.0.tar.gz
# 下载openssh软件
# wegt https://openbsd.hk/pub/OpenBSD/OpenSSH/portable/openssh-8.8p1.tar.gz
拷贝软件
拷贝软件为主控电脑讲下载的软件批量分发到被控主机上。
$ ansible -m copy -a "src=/home/tools/telnet/xinetd-2.3.15-14.el7.x86_64.rpm dest=/home/tools/telnet/"
$ ansible -m copy -a "src=/home/tools/telnet/telnet-server-0.17-66.el7.x86_64.rpm dest=/home/tools/telnet/"
$ ansible -m copy -a "src=/home/tools/openssl-3.0.0.tar.gz dest=/home/tools/"
$ ansible -m copy -a "src=/home/tools/openssh-8.8p1.tar.gz dest=/home/tools/"
ansible-copy模块
src 与content其一必选。源文件/目录,如果以"/"结尾,复制内容,否则,复制包括目录在内的所有内容。
content 与src其一必选。直接设定目的文件的值,此时dest必须是文件。
dest 必选。远端路径,可以是文件/目录。
backup 覆盖之前备份源文件。yes/no
directory_mode 递归设定目标目录的权限。
follow 支持link文件复制
force 覆盖远程主机不一致的内容
group 设定远程主机目录的组名
mode 设定远程主机文件及目录的权限
owner 设定远程主机目录的用户名
安装依赖库
安装依赖库主要为openssl和openssh依赖库。
新增端口
新增telnet服务使用的端口23
$ ansible jgxt3 -a "systemctl status firewalld" # 查看防火墙状态
$ ansible jgxt3 -a "firewall-cmd --list-all" # 查看防火墙开放端口
$ ansible jgxt3 -a "firewall-cmd --zone=public --add-port=23/tcp --permanent" # 添加23端口
$ ansible jgxt3 -a "firewall-cmd --complete-reload" # 重新加载防火墙
$ ansible jgxt3 -a "firewall-cmd --query-port=23/tcp" # 查看23端口状态
6.3.2、开启telnet服务
安装telnet和xinetd程序
$ ansible jgxt3 -m shell -a "chdir=/home/tools/telnet/ rpm -ivh xinetd-2.3.15-14.el7.x86_64.rpm"
$ ansible jgxt3 -m shell -a "chdir=/home/tools/telnet/ rpm -ivh telnet-server-0.17-66.el7.x86_64.rpm"
启动服务
远程启动被控端主机的服务使用到是ansible中的service模块
$ ansible jgxt -m service -a "name=xinetd state=started enabled=yes" -i /etc/ansible/hosts
$ ansible jgxt -m service -a "name=telnet state=started enabled=yes" -i /etc/ansible/hosts
service模块参数
name 服务名称
state 服务状态,startd-启动,stop-停止,restarted-重启,reloaded-重新加载
enabled 服务设置为开机启动项,yes-开机启动,no-开机不启动
查看服务状态
$ ansible jgxt3 -a "systemctl status telnet"
$ ansible jgxt3 -a "systemctl status xinetd"
验证服务
telnet 远程登陆
telnet IP地址
输入创建的账号密码正常登陆即为验证通过。
6.3.3、升级软件版本
本次升级主要包括openssl和openssh两个软件。注意安装顺序,先安装openssl,后升级openssh,后者安装需要加载前者的目录程序。
6.3.3.1、备份文件
$ ansible jgxt3 -a 'mv /usr/bin/openssl /usr/bin/openssl_bak' # 备份openssl文件
$ ansible jgxt3 -a 'rm -rf /etc/ssh/*' # 删除openssh文件
6.3.3.2、安装openssl
1 安装
配置、编译、安装
$ ansible jgxt3 -m shell -a 'chdir=/home/Downloads/openssl-3.0.0 ./config shared --prefix=/opt/openssl && make && make install'
2 验证安装
$ ansible jgxt3 -a 'echo $?'
输出0表示验证通过
3 创建链接
$ ansible jgxt3 -a 'ln -s /opt/openssl/bin/openssl /usr/bin/openssl'
$ ansible jgxt3 -a 'ln -s /opt/openssl/include/openssl /usr/include/openssl'
4 加载配置
$ ansible jgxt3 -m shell -a 'echo "/opt/openssl/lib64" >> /etc/ld.so.conf'
$ ansible jgxt3 -m shell -a '/sbin/ldconfig'
5 验证安装
$ ansible jgxt3 -a "openssl version"
6.3.3.3、安装openssh
1 安装
配置、编译、安装
$ ansible jgxt3 -m shell -a 'mv /usr/lib/systemd/system/sshd.service /home/service/'
$ ansible jgxt1 -m shell -a './configure --prefix=/opt/openssh --sysconfdir=/etc/ssh --with-openssl-includes=/opt/openssl/include --with-ssl-dir=/opt/openssl --with-zlib --with-md5-passwords --with-pam && make && make install'
2 验证安装
$ ansible jgxt3 -a "echo $?"
输出0表示验证通过
3 修改配置
# vim /etc/ssh/sshd_config
$ ansible jgxt3 -m lineinfile -a 'path=/etc/ssh/sshd_config regexp="^#PermitRootLogin yes" line="PermitRootLogin yes" backrefs=yes backup=yes'
$ ansible jgxt3 -m lineinfile -a 'path=/etc/ssh/sshd_config regexp="^#UseDNS yes" line="UseDNS no" backrefs=yes backup=yes'
ansible-lineinfile参数
path 指定文件,必填
line 文本内容
regexp 正则表达式匹配
state 状态,absent-删除,present-操作
backrefs 配合regexp使用,yes-匹配到数据后处理,no-没有匹配到不进行处理
insertafter 文本插入到指定行之后
insertbefore文本插入到指定行之前
backup 是否在修改文件前对文件进行备份
create 操作文件时,文件不存在,是否创建,yes-创建,no-不创建
4 配置文件迁移
# cd /home/tools/openssh-8.8p1
# cp -a contrib/redhat/sshd.init /etc/init.d/sshd
# cp -a contrib/redhat/sshd.pam /etc/pam.d/sshd.pam
# cp /run/systemd/generator.late/sshd.service /usr/lib/systemd/system/sshd.service
# chmod +x /etc/init.d/sshd # 赋权限
# chkconfig --add sshd # 添加系统服务
# systemctl enable sshd # 设置开机启动
# /etc/init.d/sshd start # 启动服务
# firewall-cmd --reload # 重启防火墙
5 验证
重启服务器,登陆查看版本
6 关闭telnet服务
# systemctl disable xinetd.servicef # 禁止xinetd服务
# systemctl stop xinetd.service # 关闭xinetd服务
# systemctl disable telnet.socket # 禁止telnet服务
# systemctl stop telnet.socket # 关闭xinetd服务
# netstat -nltp # 验证23端口是否关闭
# firewall-cmd --zone=public --remove-port=23/tcp --permanent # 防火墙移除23端口
# firewall-cmd --reload # 重新加载防火墙
telnet远程登陆验证