本篇将主要描述在腾讯云平台如何构建Ansible自动化运维管理工具平台/环境,如何批量管理云上服务器,批量分发配置等设置,同时这里将引入某客户真实的案例进行整体的阐述。将从Ansible的基础、架构、常见功能模块,案例解决示例方法进行展开。
Ansible 是一款开源自动化平台,基于Python开发,无需客户端,轻量级,配置语言采用YAML,可以管理强大的自动化任务,提高工作效率。
Ansible 架构存在两种计算类型,即控制节点和受控主机/被管主机。
这里为了更直观看到效果,采用3台centos7.6 + 1台ubuntu进行自动运维环境的构建,如果需要覆盖更多被管主机,则通过下面的方法扩展即可。
[root@master]# yum -y install ansible
[root@master ~]# hostnamectl set-hostname master.example.com
[root@master ~]# cat /etc/hosts
127.0.0.1 VM-6-10-centos VM-6-10-centos
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
::1 VM-6-10-centos VM-6-10-centos
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
10.0.6.10 master.example.com master
10.0.6.4 node1.example.com node1
10.0.6.13 node2.example.com node2
10.0.6.8 node3.example.com node3
备注: node1 – node3 均像master 节点一样设置
[root@master ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:afVk9vExWqYP3sxC0Pj1+kIaLFpKiUr8slNea3gxPPI root@master.example.com
The key's randomart image is:
+---[RSA 2048]----+
| |
| o |
| .o+..* |
| o =o.*o+|
| . oS. ..*. o|
| o +.O o = B. |
| . = * O . *.= |
| + + E . o. |
| .+ o ..|
+----[SHA256]-----+
[root@master ~]# ssh-copy-id root@node1.example.com 输入node1 密码, node2, node3类似,机器多则可通过for脚本批量实现。
[root@master ~]# tail /etc/ansible/hosts
[nodes]
node1
node2
node3
node4
[root@master ~]# ansible all -m ping
node2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node4 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@master ~]#
[root@master ~]# rpm -ql ansible |less
/etc/ansible/ansible.cfg //ansible 主配置文件
/etc/ansible/hosts //主机清单文件
/etc/ansible/roles //角色目录
/usr/bin/ansible //主程序,临时命令执行工具
/usr/bin/ansible-config //查看ansible配置
/usr/bin/ansible-connection //基于Console界面与用户交互的执行工具
/usr/bin/ansible-doc //查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy //下载/上传Roles模块的官网
/usr/bin/ansible-inventory // 查看inventory信息
/usr/bin/ansible-playbook //定制自动化任务,编排剧本工具
/usr/bin/ansible-vault //文件加密工具
/usr/share/ansible/roles //角色目录
Ansible默认配置文件: /etc/ansible/ansible.cfg
#forks = 5 并发执行数量,默认5
#poll_interval = 15 拉取数据间隔时间,默认15秒
#sudo_user = root sudo命令默认用户
#remote_port = 22 连接远程端口号
#host_key_checking = False 检查对应服务器的host_key,建议取消注释
#log_path=/var/log/ansible.log 日志文件,建议取消注释
ansible配置文件以及读取优先级,如下顺序:
1) ANSIBLE_CONFIG变量
2) 当前目录 ansible.cfg
3) 家目录下 ansible.cfg
4) 默认配置文件 /etc/ansible/ansible.cfg
本篇采用系统默认的配置,若生产环境且涉及多人协作,使用普通用户选择2)或3)方法去配置Ansible环境。
[root@master ansible]# ansible-doc yum //查看模块帮助
[root@master ansible]# ansible-doc -s yum //显示模块简要说明
[root@master ansible]# ansible-doc -l //列出ansible模块
功能:默认模块,在远程主机执行命令,可忽略-m选项
[root@master ansible]# ansible all -m command -a "touch /tmp/test.txt"
[root@master ansible]# ansible all -m command -a 'systemctl restart httpd'
功能:和command相似,用shell执行命令
[root@master ansible]# ansible node1 -m shell -a 'useradd user01'
[root@master ansible]# ansible node1 -m shell -a "echo 123456 |passwd --stdin user01“
功能:运行脚本,不需要将脚本复制到被控端
[root@master ansible]#ansible node1-m script -a test.sh
[root@master ansible]# ansible all -m script -a ./test.sh
[root@master ansible]# ansible all -m command -a 'ls -l /tmp'
[root@master ansible]# ansible node1 -m script -a ./host-name.sh
功能:通过yum 安装软件包
安装vsftpd软件包
[root@master ansible]# ansible node1 -m yum -a "name=vsftpd state=present"
卸载vsftpd软件包
[root@master ansible]# ansible all -m yum -a "name=vsftpd state=absent"
安装Development Tools (软件包组)
[root@master ansible]# ansible node1 -m yum -a "name='@Development Tools'"
功能:设置文件属性,创建/删除等操作
创建新文件:
[root@master ansible]# ansible node1 -m file -a 'name=/tmp/file1 state=touch'
删除文件:
[root@master ansible]# ansible node1 -m file -a 'name=/tmp/file1 state=absent'
创建目录:
[root@master ansible]# ansible node1 -m file -a 'name=/tmp/dir state=directory'
删除目录:
[root@master ansible]# ansible node1 -m file -a 'name=/tmp/dir state=absent'
功能:从服务器复制文件到客户端,
[root@master ansible]# ansible node1 -m copy -a 'src=/etc/hostname dest=/opt' //将控制主机的hosname
文件拷贝到被控主机的/opt下
功能:管理服务
停止httpd服务:
[root@master ansible]# ansible node1 -m service -a "name=httpd state=stopped"
开启httpd服务:
[root@master ansible]# ansible node1 -m service -a "name=httpd state=started"
重新加载httod服务:
[root@master ansible]# ansible node1 -m service -a "name=httpd state=reloaded"
重启httpd服务:
[root@master ansible]# ansible node1 -m service -a "name=httpd state=restarted"
开启ftp服务,同时设置开机自动启动:
[root@master ansible]# ansible node1 -m service -a "name=vsftpd state=started enabled=yes"
重启ftp服务:
[root@master ansible]# ansible node1 -m service -a "name=vsftpd state=restarted"
功能:管理用户
添加用户,指定uid、家目录、主组及注释:
[root@master ansible]# ansible node1 -m user -a 'name=user1 comment="test user" uid=2000 home=/home/user1'
功能:管理主机名,生效同时更改文件永久生效
[root@master ansible]# ansible node1 -m hostname -a "name=node1.example.com"
由于ansible支持的模块是非常丰富的,上面仅列出了常用的一些模块,还有其他模块可通过ansible-doc 命令来获取。
近期某客户基于腾讯云镜(主机安全)进行等保安全基线扫描,发现有上百台云服务器的安全基线不符合客户安全部门的安全需求,需要进行整改,涉及的机器量也比较大,而客户侧人员较少,日常运维常用采用简单脚本方式进行云上运维管理。一开始比较倾向云上的产品进行批量或自动修复,发现比较难找到合适的产品完全吻合,因此这里推荐采用Ansible自动化运维的方式进行批量修复云服务器的安全隐患问题,这里简单列举几项高危风险示例:
序号 | 风险项 | 威胁等级 | 描述 | 处理建议 |
---|---|---|---|---|
1 | 确保已配置SSH空闲超时间隔 | 高危 | 这两个选项ClientAliveInterval和ClientAliveCountMax控制SSH会话超时。当ClientAliveInterval变量被设置,对指定的时间长度没有活动的SSH会话被终止。当ClientAliveCountMax变量被设置,sshd将在每一个客户端发送活动消息ClientAliveInterval的时间间隔。当连续发送的客户端活动消息数没有客户端响应时,ssh会话将终止。 | 编辑/etc/ssh/sshd_config文件以设置参数: ClientAliveInterval 300 ClientAliveCountMax 0 |
2 | 确保SSH MaxAuthTries设置为4或更低 | 高危 | MaxAuthTries参数指定每个连接允许的最大身份验证尝试次数。登录失败次数达到设置参数一半时,错误消息将写入syslog文件,详细说明登录失败。 | 编辑/etc/ssh/sshd_config文件以设置参数,如下所示: MaxAuthTries 4 |
3 | 确保默认用户umask限制为027或更高 | 高危 | umask默认值确定用户创建的文件的权限。创建文件的用户可以通过chmod命令自行决定使其他人可以读取其文件和目录 | 编辑/etc/bash.bashrc,/etc/profile文件(以及系统上支持的任何其他Shell的适当文件),并添加或编辑umask参数,如下所示: umask 027 |
4 | 确保默认用户shell超时为900秒或更短 | 高危 | 默认值TMOUT确定用户的shell超时时间。TMOUT值以秒为单位。 | 编辑/etc/bashrc,/etc/profile和/etc/profile.d/*.sh文件(以及系统上支持的任何其他Shell的适当文件),并根据站点策略添加或编辑任何TMOUT参数: TMOUT=900 |
由于客户侧使用操作系统为:RedHat/CentOS、Ubuntu, 这里采用不同操作系统的yml文件进行。
[root@master method1]# cat ubuntu.yml-m1
---
- name: repair system security issue
hosts: node4
tasks:
- name: session timeout
lineinfile:
path: /etc/profile
regexp: '^export TMOUT=600'
line: export TMOUT=300
- name: set MaxAuthTries
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#MaxAuthTries 6'
line: MaxAuthTries 4
- name: set ClientAliveInterval
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveInterval 0'
line: ClientAliveInterval 300
- name: set ClientAliveCountMax
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveCountMax 3'
line: ClientAliveCountMax 0
- name: reloaded service
service:
name: sshd
state: reloaded
- name: set umask1
lineinfile:
path: /etc/profile
regexp: '002'
line: "umask 027"
- name: set umask2
lineinfile:
path: /etc/bash.bashrc
regexp: '002'
line: "umask 027"
[root@master method1]# cat centos.yml
---
- name: repair system security issue
hosts: node1
tasks:
- name: session timeout
lineinfile:
path: /etc/profile
regexp: '^export TMOUT=600'
line: export TMOUT=300
- name: set MaxAuthTries
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#MaxAuthTries 6'
line: MaxAuthTries 4
- name: set ClientAliveInterval
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveInterval 0'
line: ClientAliveInterval 300
- name: set ClientAliveCountMax
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveCountMax 3'
line: ClientAliveCountMax 0
- name: reloaded service
service:
name: sshd
state: reloaded
[root@master ansible]# ansible-playbook ubuntu.yml-m1
[root@master ansible]# ansible-playbook centos.yml
root@node4:~# grep MaxAuthTries /etc/ssh/sshd_config
MaxAuthTries 4
#简单查一下修复情况,符合预期
第一种实现的方法相对简单与直接,临时用下还不错。针对云上机器量大,第一种方式就不是适用管理大型的项目,第二种方法则采用导入外部文件方式管理playbook
这里采用import_tasks 功能将任务文件静态导入playbook中。
[root@master ansible]# cat fixsec.yml
---
- name: fix security issue
hosts: node1,node4
tasks:
- name: Centos/RedHat System
import_tasks: centos.yml
when: ansible_distribution == "CentOS" or ansible_distribution == "RedHat"
- name: Centos/RedHat System
import_tasks: ubuntu.yml
when: ansible_distribution == "Ubuntu"
[root@master ansible]#
########### centos/rhel #################
[root@master method2]# cat centos.yml
---
- name: set MaxAuthTries
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#MaxAuthTries 6'
line: MaxAuthTries 4
- name: set ClientAliveInterval
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveInterval 0'
line: ClientAliveInterval 300
- name: set ClientAliveCountMax
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveCountMax 3'
line: ClientAliveCountMax 0
- name: reloaded service
service:
name: sshd
state: reloaded
########### Ubuntu #################
[root@master method2]# cat ubuntu.yml
---
- name: session timeout
lineinfile:
path: /etc/profile
regexp: '^export TMOUT=600'
line: export TMOUT=300
- name: set MaxAuthTries
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#MaxAuthTries 6'
line: MaxAuthTries 4
- name: set ClientAliveInterval
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveInterval 0'
line: ClientAliveInterval 300
- name: set ClientAliveCountMax
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#ClientAliveCountMax 3'
line: ClientAliveCountMax 0
- name: reloaded service
service:
name: sshd
state: reloaded
- name: set umask
lineinfile:
path: /etc/{{item}}
regexp: '002'
line: "umask 027"
loop:
- profile
- bash.bashrc
[root@master ansible]# ansible-playbook fixsec.yml
案例实现方法3采用通过roles方式进行解决。因在生成环境中, 为了实现不同的功能, 需要编写大量的playbook文件,而且每个playbook还可能会调用其他文件(如变量文件),对于海量的、无规律的文件,管理起来非常痛苦。Roles是管理ansible文件的一种规范(目录结构),roles会按照标准的规范, 自动到特定的目录和文件中读取数据,从而达到实现重复使用。
Ansible galaxy是官方提供的一个共享roles的平台,这里采用ansible-galaxy初始化角色,让其创建规范的目录结构。Roles目录结构说明
[root@master ansible]# ansible-galaxy init roles/ossec
- Role roles/ossec was created successfully
[root@master ansible]# tree roles/ossec/
roles/ossec/
|-- defaults
| `-- main.yml
|-- files
|-- handlers
| `-- main.yml
|-- meta
| `-- main.yml
|-- README.md
|-- tasks
| `-- main.yml
|-- templates
|-- tests
| |-- inventory
| `-- test.yml
`-- vars
`-- main.yml
本次高危安全隐患主要是sshd配置不符合等保的安全需求,这里直接将对应不同系统类的sshd_config 制定模板,让其通过roles规范目录结构进行分发,同时也方便后续的灵活改动与复用。
[root@master ansible]# tree roles/ossec/
roles/ossec/
|-- defaults
| `-- main.yml
|-- files
|-- handlers
| `-- main.yml
|-- meta
| `-- main.yml
|-- README.md
|-- tasks
| |-- main.yml
| `-- main.yml-bak
|-- templates
| |-- sshd_config_centos.j2 # ssh模板文件
| `-- sshd_config_ubuntu.j2 # sshd模板文件
|-- tests
| |-- inventory
| `-- test.yml
`-- vars
`-- main.yml
[root@master ansible]# cat roles/ossec/tasks/main.yml
---
# tasks file for ossec
- name: deploy ssh_config file on ubuntu
template:
src: sshd_config_ubuntu.j2
dest: /etc/ssh/sshd_config
when: ansible_distribution == "Ubuntu"
- name: deploy ssh_config file on centos
template:
src: sshd_config_centos.j2
dest: /etc/ssh/sshd_config
when: ansible_distribution == "CentOS" or ansible_distribution == "RedHat"
- name: reload sshd service based on new config info
service:
name: sshd
state: reloaded
[root@master ansible]# cat ossec.yml
---
- name: fix ossec by roles
hosts: node1,node4 # 如果执行所有被管主机,写被管主机组名即可
roles:
- ossec
案例方法3实现起来更简洁,更直接,playbook目录结构清晰,可结合生产环境需求对其目录进行相关设定,如4.3.1目录功能说明。
本篇从Ansible定义、功能特点、架构、环境部署、常用模块等,以及结合了真实的案例进行实践说明。关于生产环境的引用,建议根据需求及生产环境的差异进行调整,测试与验证后再大规模的投入使用。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。