天天看点

Ansible批量化自动化管理工具及ssh安全策略1. 概述2.生产环境下ssh登录及用户权限策略3.安装ansible4. 基础应用模块5. 使用ansible-playbook6. roles标准化playbook

文章目录

  • 1. 概述
  • 2.生产环境下ssh登录及用户权限策略
    • 2.1 安全策略
    • 2.2 具体配置
    • 2.3 配置ansible管理服务器sudo审计日志
  • 3.安装ansible
    • 3.1 实验环境配置
    • 3.2 安装ansible及配置
      • 3.2.1 安装ansible
      • 3.2.2 配置主机清单
      • 3.2.3 设置ssh免密码登录
    • 3.3 Ansible服务器简单的综合安全管理策略
  • 4. 基础应用模块
    • 4.1 命令基本语法:
    • 4.2 ping模块
    • 4.3 command模块
    • 4.4 shell模块
    • 4.5 cron模块
    • 4.6 copy模块
    • 4.7 script模块
    • 4.8 yum模块
    • 4.9 service模块
    • 4.10 user模块
    • 4.11 setup模块
    • 4.12 fetch模块
    • 4.13 查看CPU,mem,IO的命令
  • 5. 使用ansible-playbook
    • 5.1 执行脚本的格式:
    • 5.2 Python的数据格式
  • 6. roles标准化playbook
    • 6.1 roles原型目录结构
    • 6.2 入口触发配置文件
    • 6.3 roles中,tasks下各ansible模块的使用

1. 概述

  • 基于Python开发的一款的批量管理工具,实现了批量运行命令,部署程序,配置系统等功能
  • 默认通过ssh协议,以root用户登录目标服务器,通过各种模块实现不同的功能
  • ansible及其他自动化工具有:

    管理工具|管理服务器数量|优缺点

    -|

    ansible|<500台|

    saltstack|1000~4w台|

    puppet|

2.生产环境下ssh登录及用户权限策略

2.1 安全策略

  • 禁止密码登录:

    工作环境中,通常禁止用户使用密码登录,所以在ansible管理机中,需要生成秘钥(ssh-keygen),给所有被管理的服务器分发公钥,使ansible连接被管理服务器时,采用秘钥登录不留下键盘输入,增强安全性

  • 禁止root用户远程登录:

    防止恶意破坏主机,可以指定一个普通用户,通过visudo授权ALL权限,使普通用户通过提权来获得高权限,这样防止root用户远程登录,又保证了对服务器所拥有的高权限

  • 普通用户密钥登录:

    在该用户家目录下,放公钥,配置xshell以密钥登录

  • 关闭GSSAPI认证
  • 修改ssh连接端口,通常设定在1w以上,避免nmap命令扫描出来
  • 注意.ssh目录权限是700,属主属组是该家目录用户,公钥文件权限是600

2.2 具体配置

  • 修改配置文件为以下状态
cat -n /etc/ssh/sshd_config | sed -n '17p;38p;43p;47p;65p;79p;115p'
Port 22221                  #修改端口,切记配置好密钥后再进行
PermitRootLogin yes         #yes表示开启root远程登录,非大规模服务器可以图方便开启,关闭改成no
PubkeyAuthentication yes    #开启公钥连接认证,默认是注释的
AuthorizedKeysFile .ssh/authorized_keys         #指定公钥存放位置
PasswordAuthentication no   #允许密码认证方式,no代表关闭,默认是yes
GSSAPIAuthentication no     #关闭GSSAPI认证,提高ssh连接速度
UseDNS no                   #关闭DNS反向解析,提高ssh连接速度
           

2.3 配置ansible管理服务器sudo审计日志

开启sudo日志,rsyslog服务时所有日志记录的服务进程

echo "local1.debug /var/log/sudo.log" >> /etc/rsyslog.conf
echo "Defaults logfile=/var/log/sudo.log" >> /etc/sudoers
visudo -c       #手动检测visudo语法是否正确 
systemctl restart rsyslog
#执行一次sudo提权,sudo su -,再查看sudo日志
cat /var/log/sudo.log
           

3.安装ansible

3.1 实验环境配置

  • linux及内核版本

    CentOS Linux release 7.5.1804

    3.10.0-862.3.3.e17.x86_64

  • ansible版本

    ansible 2.8.1

  • 配置好epel源yum

3.2 安装ansible及配置

3.2.1 安装ansible

#通过yum方式安装:
yum -y install ansible
#通过Python的pip方式安装ansible(pip是一个Python包管理工具,查找Python相关的包)
yum -y install python2-pip
pip install ansible

#我们用yum安装ansible
ansible --version
#查看ansible版本
           

3.2.2 配置主机清单

vim /etc/ansible/hosts
#添加模块,模块中添加主机
[nginx]
web01 ansible_ssh_host=192.168.200.172
web02 ansible_ssh_host=192.168.200.173
           
  • 参数说明:

    ansible_ssh_host:被管理主机IP

    ansible_ssh_user:指定登录用户

    ansible_ssh_pass:指定登录用户的密码

    ansible_sudo_pass:被管理主机用户sudo时的密码

3.2.3 设置ssh免密码登录

使用ssh-keygen产生密钥对,通过ssh-copy-id发送公钥给被管理的主机

ssh-copy-id 192.168.200.172

ssh-copy-id 192.168.200.173

3.3 Ansible服务器简单的综合安全管理策略

禁止非root用户查看ansible管理服务器端/etc/hosts文件,和主机清单文件

chmod 600 /etc/hosts

chmod 600 /etc/ansible/hosts

4. 基础应用模块

4.1 命令基本语法:

ansible <被操控的主机|主机组|all>[-m 模块名][-a ‘具体命令’]

4.2 ping模块

检测指定主机的连通性

ansible webA -m ping

#或者指定[nginx],webB

4.3 command模块

在远程主机执行命令,不支持管道符和重定向

ansible webA -m command -a ‘uptime’

4.4 shell模块

也是远程执行命令,并支持管道符和重定向等复杂命令

ansible all -m shell -a ‘echo “ansible 192.168.200.170” >> /etc/hosts’

4.5 cron模块

  • 定义定时任务,包含两种状态:

    crontab时间周期(不设定默认为*):

    minute:分钟

    hour:小时

    day:日期

    month:月份

    weekday:周期

  • job:指定运行的命令
  • name:定时任务描述,不可缺少,是清除时的依据
  • state状态:

    present:添加定时任务,不写状态默认添加

    absent:移除定时任务,移除时,只需要指定name描述

  • user:指定定时任务以哪个用户身份执行,不指定默认root

    ansible all -m cron -a ‘minute="*/10" job="/bin/echo hello" name=“test cron job” state=present’

4.6 copy模块

  • 批量分发文件
  • src=:文件路径
  • dest=:目标路径,加文件名可改名
  • backup=yes:有同名文件时,先备份再覆盖
  • owner:分发文件时,指定文件的属主
  • mode:指定权限
  • 等,使用该模块时,可查看所有参数

    ansible all -m copy -a ‘src=/etc/hosts dest=/tmp/yun owner=yunjisuan mode=640 backup=yes’

4.7 script模块

  • 将本地脚本复制到被管理主机的内存中并执行,不会在被管理主机中留下脚本文件

    ansible all -m script -a ‘/tmp/test.sh’

  • 也可以使用copy模块先将脚本文件复制到目标服务器,然后执行:

    ansible all -m copy -a ‘src=/tmp/test.sh dest=/tmp/test.sh’

    ansible all -m script -a '/bin/bash /tmp/test.sh

4.8 yum模块

  • 利用yum安装软件包,能用shell替代
  • name:指定软件包名
  • state状态

    present:安装软件包,不指定则默认安装

    absent:卸载软件包

    #卸载webA上的namp

    ansible webA -m yum -a ‘name=namp state=absent’

4.9 service模块

  • 管理服务程序,能被shell替代
  • name:指定服务名
  • state状态:

    started:启动

    stopped:停止

    restarted:重启

    reloaded:平缓重载

  • enabled开机自启动:

    true:设置开机自启

    false:设置开机不启动

    #示例:

    ansible webA -m service -a ‘name=firewalld state=started enabled=true’

4.10 user模块

  • 管理用户账号
  • name:指定用户名
  • comment:用户描述,可以不用
  • createhome:是否创建家目录
  • uid:指定uid
  • groups:指定gid,不指定默认创建同uid的组
  • password:指定密码
  • update_password:更新用户密码
  • shell:指定用户登录方式

    /bin/bash

    /sbin/nologin

  • home:指定家目录路径

    -state状态:

    present:创建,不指定默认创建

    absent:删除

  • remove:删除是,确认是否删除家目录

    =true或=false

  • 需要注意这样创建用户,密码是明文,无法使用,所以需要通过一些操作来获得想要的密文

    #安装Python2的pip工具,通过pip工具安装python的加密模块来给密码加密

    yum -y install python2-pip

    pip install passlib

    python -c “from passlib.hash import sha512_crypt;import getpass;print sha512_crypt.encrypt(getpass.getpass())”

    #然后输入想加密的密码,系统会输出加密后的密码,然后复制到password参数后面,这样创建用户就是密文了

4.11 setup模块

收集,查看被管理主机的facts(ansible采集被管理主机设备信息的一个功能),每个被管理主机在接收并运行管理命令之前,都会将自己相关信息(操作系统版本,IP地址等)发送给控制主机

ansible webA -m setup | less

#输出信息会非常多,也可以指定127.0.0.1查看本机内置参数

4.12 fetch模块

从远程主机拉取文件到ansible机器上,会保留远程主机的目录结构

  • src:要复制的远程主机的文件路径
  • dest:拉取到本地此路径下

4.13 查看CPU,mem,IO的命令

  • top 可查看当前CPU占用率,MEN剩余量,由于该命令占用内存大,可以重定向到某个文件再查看
  • iostat 查看系统分区的IO使用情况,也可以查看CPU的平均负荷,通过安装sysstat安装iostat命令
  • iotop,动态显示各个进程的IO情况,可以定位IO操作重的进程

5. 使用ansible-playbook

5.1 执行脚本的格式:

1. 执行剧本文件:

ansible-playbook test_shell.yaml

2. 具体格式范例:

cat test_shell.yaml     #剧本文件固定以.yaml结尾
#内容为:
---                     #固定三个 - 顶格写
- hosts: web1           #执行范围,hosts前有两个占位
  gather_facts: True    #使用ansible内置变量
  vars:                 #启用自定义变量
  - AGE: 3              #用大写避免和内置变量冲突
    PORT: 100
  tasks:                #具体任务
  #调用shell模块
  - name: shell         #任务名,相对于tasks,多缩进两格
    shell: echo "welcome" >> /tmp/yun.txt   
  #copy模块
  - name: copy
    copy: src=/tmp/nginx.j2 dest=/usr/local/nginx/conf/nginx.conf backup=yes
  #利用template下发可变配置文件,文件内容看下文
  - name: template    
    template: src=/tmp/test.j2 dest=/tmp/test222
    notify:
    - reload nginx          #触发notify后执行的动作
  handlers:                 #定义动作,和tasks同级
  - name: reload nginx      #动作名
    shell: /usr/local/nginx/sbin/nginx -s reload
  #利用notify通知,当前面的命令执行成功,文件发生改变后,执行reload nginx

    #测试变量,引用变量需要在双引号中引用,并且用两对大括号引用,变量名两头空格
  - name: vars             
    shell: echo "myage {{ AGE }},ip {{ ansible_all_ipv4_addresses[0] }}"
    
    #利用register模块将检测nginx配置文件的结果保存在自定义变量print_result中,在debug中输出变量的值,- debug:var= 是固定格式,需要注意的是debug只输出当前name任务命令的结果
  - name: register
    shell: /usr/local/nginx/sbin/nginx -t
  register: print_result
  - debug: var=print_result
           

3. 自定可变配置文件

cat /tmp/test.j2
#内容为下,加入了if判断
{% if PORT %}
ip=0.0.0.0:{{ PORT }}
{% else %}
ip=0.0.0.0:80
{% else %}

my age is {{ AGE }}
my ip is {{ ansible_all_ipv4_addresses[0] }}
           

5.2 Python的数据格式

  • 输入python进入Python环境
  • 变量赋值:

    num = “yunjisuan” 或

    num = 123

    等号两边空格,字母需要双引号赋值会变成字符串,用数字识别为整性int

  • 列表取值:

    num = [1,3,5]

    类型为list,根据索引取值,从0开始输入name[0]结果为1,name[2]这里和name[-1]一样,取最后的值

  • 字典/键值型:

    num = {“user1”:123,“user2”:“abc”,“user3”:[1,2,3]}

    键需要用双引号,值可以使用列表,取值方式为

    num[“user1”]=123

    num[“user3”][0]=1

6. roles标准化playbook

6.1 roles原型目录结构

/myroles/
├── nginx.yaml              #入口触发配置文件
└── roles                   #playbook的原型配置目录
    └── nginx               #nginx相关模组配置目录
        ├── files           #copy模快,script模块文件的源路径
        │   ├── test
        │   └── test.sh
        ├── handlers        #notify通知调用的配置文件
        │   └── main.yaml   #文件内容包含了可调用的动作
        ├── tasks           #存放ansible主任务文件
        │   └── main.yaml   #写了所有执行的任务name
        ├── templates       #存放可变配置文件的
        │   └── test.j2     #内容中引用变量
        └── vars            #存放变量文件
            └── main.yaml   #自定义变量的赋值
           

6.2 入口触发配置文件

指定调用执行roles下的某个模组

cat /myroles/nginx.yaml
#内容为
---
- hosts: all            #执行的主机范围
  gather_facts: True    #开启系统内置变量
  roles:                #启用roles原型配置
  - nginx               #执行nginx原型模组
           

6.3 roles中,tasks下各ansible模块的使用

  • roles的本质,就是将tasks任务单独写了,前文指定的nginx,就相当于整个tasks集合
  • 自定义变量vars模组的配置文件,格式如下
cat roles/nginx/vars/main.yaml
---
my_name: yunjisuan
phone: 12345
           
  • copy模块需要推送的文件
cat roles/nginx/files/test
welcone to yunjisuan
           
  • script模块执行的脚本
cat roles/nginx/files/test.sh
echo "aaa" >> /tmp/test
           
  • template可变配置文件的使用,通常文件名以.j2结尾
cat roles/nginx/template/test.j2
#内容为
my name is {{ my_name }},my phone is {{ phone }}
my ipaddress is {{ ansible_all_ipv4_addresses[0] }}
           
  • notify通知模块的配置文件格式如下
cat roles/nginx/handlers/main.yaml
#内容为
---
- name: start_nginx
  shell: /usr/local/nginx/sbin/nginx
- name: stop_nginx
  shell: /usr/local/nginx/sbin/nginx
- name: reload_nginx
  shell: /usr/local/nginx/sbin/nginx
           
  • tasks文件范例:
cat roles/nginx/tasks/main.yaml
#内容为
---
- name:
  ping:
- name:
  shell: ls /
  register: ls_result
- debug: var=ls_result
- name:
  shell: echo my phone is {{ phone }}
  register: echo_result
- debug: var=echo_result
- name:
  copy: src=test dest=/root/
- name:
  script: test.sh
- name:
  template: src=test.j2 dest=/root/test2
  notify: start_nginx
           

继续阅读