Mark blog

知行合一 划水归档

运维自动化发展历程及技术应用

企业实际应用场景分析

Dev开发环境

使用者:程序员

功能:程序员开发软件,测试BUG的环境

管理者:程序员

测试环境

使用者:QA测试工程师

功能:测试经过Dev环境测试通过的软件的功能

管理者:运维

说明:测试环境往往有多套,测试环境满足测试功能即可,不宜过多

1、测试人员希望测试环境有多套,公司的产品多产品线并发,即多个版本,意味着多个版本同步测试

2、通常测试环境有多少套和产品线数量保持一样

发布环境:代码发布机,有些公司为堡垒机(安全屏障)

使用者:运维

功能:发布代码至生产环境

管理者:运维(有经验)

发布机:往往需要有2台(主备)

生产环境

使用者:运维,少数情况开放权限给核心开发人员,极少数公司将权限完全开放给开发人员并其维护

功能:对用户提供公司产品的服务

管理者:只能是运维

生产环境服务器数量:一般比较多,且应用非常重要。往往需要自动工具协助部署配置应用
灰度环境(生产环境的一部分)

使用者:运维

功能:在全量发布代码前将代码的功能面向少量精准用户发布的环境,可基于主机或用户执行灰度发布

案例:共100台生产服务器,先发布其中的10台服务器,这10台服务器就是灰度服务器

管理者:运维

灰度环境:往往该版本功能变更较大,为保险起见特意先让一部分用户优化体验该功能,待这部分用户使用没有重大问题的时候,再全量发布至所有服务器

程序发布

程序发布要求:

不能导致系统故障或造成系统完全不可用

不能影响用户体验

预发布验证:

新版本的代码先发布到服务器(跟线上环境配置完全相同,只是未接入到调度器)

灰度发布:

基于主机,用户,业务

发布路径:

/webapp/markupzh 

/webapp/markupzh-1.1 

/webapp/markupzh-1.2

发布过程:

在调度器上下线一批主机(标记为maintanance状态) –> 关闭服务 –> 部署新版本的应用程序 –> 启动服务 –> 在调度器上启用这一批服务器

自动化灰度发布:

脚本、发布平台

自动化运维应用场景

文件传输

应用部署

配置管理

任务流编排

常用自动化运维工具
Ansible:python,Agentless,中小型应用环境

Saltstack:python,一般需部署agent,执行效率更高

Puppet:ruby, 功能强大,配置复杂,重型,适合大型环境

Fabric:python,agentless

Chef: ruby,国内应用少

Cfengine

func

企业级自动化运维工具应用实战ansible

公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备。公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运维老大为了在年底有所表现,要求运维部门同学尽快实现,接到这个任务时,有没有更快的解决方案?

特性

模块化:调用特定的模块,完成特定任务

有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块

支持自定义模块

基于Python语言实现

部署简单,基于python和SSH(默认已安装),agentless

安全,基于OpenSSH

支持playbook编排任务

幂等性:一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况

无需代理不依赖PKI(无需ssl)

可使用任何编程语言写模块

YAML格式,编排任务,支持丰富的数据结构

较强大的多层解决方案

Ansible主要组成部分

ANSIBLE PLAYBOOKS:任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件

INVENTORY:Ansible管理主机的清单/etc/anaible/hosts

MODULES:Ansible执行命令的功能模块,多数为内置核心模块,也可自定义

PLUGINS:模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用

API:供第三方程序调用的应用程序编程接口

ANSIBLE:组合INVENTORY、API、MODULES、PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具

Ansible命令执行来源:

USER,普通用户,即SYSTEM ADMINISTRATOR

CMDB(配置管理数据库) API 调用

PUBLIC/PRIVATE CLOUD API调用

USER-> Ansible Playbook -> Ansibile

利用ansible实现管理的方式:

Ad-Hoc 即ansible命令,主要用于临时命令使用场景

Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前提的规划

Ansible-playbook(剧本)执行过程:

将已有编排好的任务集写入Ansible-Playbook

通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行

Ansible主要操作对象:

HOSTS主机

NETWORKING网络设备

注意事项

执行ansible的主机一般称为主控端,中控,master或堡垒机

主控端Python版本需要2.6或以上

被控端Python版本小于2.4需要安装python-simplejson

被控端如开启SELinux需要安装libselinux-python

windows不能做为主控端

安装

rpm包安装: EPEL源

yum install ansible

编译安装:

1
2
3
4
5
6
7
# yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
# tar xf ansible-1.5.4.tar.gz
# cd ansible-1.5.4
# python setup.py build
# python setup.py install
# mkdir /etc/ansible
# cp -r examples/* /etc/ansible
Git方式:
1
2
# git clone git://github.com/ansible/ansible.git --recursive cd ./ansible
# source ./hacking/env-setup
pip安装:

pip是安装Python包的管理器,类似yum

1
2
3
# yum install python-pip python-devel
# yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel pip install --upgrade pip
# pip install ansible --upgrade
确认安装:

ansible --version

相关文件

配置文件
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性                     

/etc/ansible/hosts 主机清单

/etc/ansible/roles/ 存放角色的目录
程序
/usr/bin/ansible 主程序,临时命令执行工具 

/usr/bin/ansible-doc 查看配置文档,模块功能查看工具 

/usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台

/usr/bin/ansible-playbook 定制自动化任务,编排剧本工具

/usr/bin/ansible-pull 远程执行命令的工具

/usr/bin/ansible-vault 文件加密工具 

/usr/bin/ansible-console 基于Console界面与用户交互的执行工具
主机清单inventory

Inventory 主机清单

ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名

默认的inventory file为/etc/ansible/hosts

inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成

/etc/ansible/hosts文件格式

inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中;此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明

1
2
3
4
5
6
7
8
ntp.markupzh.com
[webservers]
www1.markupzh.com:2222
www2.markupzh.com
[dbservers]
db1.markupzh.com
db2.markupzh.com
db3.markupzh.com

如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机

示例:

1
2
3
4
[websrvs]
www[01:100].example.com
[dbsrvs]
db-[a:f].example.com
ansible 配置文件

Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认)

1
2
3
4
5
6
7
8
9
10
11
[defaults]
#inventory = /etc/ansible/hosts # 主机列表配置文件
#library = /usr/share/my_modules/ # 库文件存放目录
#remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录
#local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
#forks = 5 # 默认并发数
#sudo_user = root # 默认sudo 用户
#ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
#ask_pass = True
#remote_port = 22
#host_key_checking = False # 检查对应服务器的host_key,建议取消注释 #log_path=/var/log/ansible.log #日志文件

ansible系列命令

ansible ansible-doc

ansible-playbook

ansible-vault

ansible-console

ansible-galaxy

ansible-pull

ansible-doc: 显示模块帮助

1
2
3
4
ansible-doc options
-a 显示所有模块的文档
-l, --list 列出可用模块
-s, --snippet显示指定模块的playbook片段
示例:

ansible-doc –l 列出所有模块
ansible-doc ping 查看指定模块帮助用法
ansible-doc –s ping 查看指定模块帮助用法

ansible通过ssh实现配置管理、应用部署、任务执行等功能,建议配置ansible端能基于密钥认证的方式联系各被管理节点

1
2
3
4
5
6
7
8
9
10
11
ansible <host-pattern> -m module_name
--version 显示版本
-m module 指定模块,默认为command
-v 详细过程 –vv -vvv更详细
--list-hosts 显示主机列表,可简写 --list
-k, --ask-pass 提示输入ssh连接密码,默认Key验证
-K, --ask-become-pass 提示输入sudo时的口令
-C, --check 检查,并不执行
-T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
-u, --user=REMOTE_USER 执行远程执行的用户
-b, --become 代替旧版的sudo 切换
ansible的Host-pattern

匹配主机的列表

All :表示所有Inventory中的所有主机

ansible all –m ping

*:通配符

1
2
3
ansible "*" -m ping
ansible 192.168.1.* -m ping
ansible "*srvs" -m ping

或关系

1
2
ansible "websrvs:appsrvs" -m ping
ansible "192.168.1.10:192.168.1.20" -m ping

逻辑与

ansible "websrvs:&dbsrvs" –m ping

在websrvs组并且在dbsrvs组中的主机

逻辑非

ansible 'websrvs:!dbsrvs' –m ping

在websrvs组,但不在dbsrvs组中的主机注意:此处为单引号

综合逻辑

ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping

正则表达式

ansible "websrvs:&dbsrvs" –m ping

ansible "~(web|db).*\.markupzh\.com" –m ping

ansible命令执行过程

1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg

2. 加载自己对应的模块文件,如command

3. 通过ansible将模块或命令生成对应的临时py文件,并将该 文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件

4. 给文件+x执行

5. 执行并返回结果

6. 删除临时py文件,sleep 0退出

执行状态:

    绿色:执行成功并且不需要做改变的操作

    黄色:执行成功并且对目标主机做变更

    红色:执行失败

ansible使用示例

以mark用户执行ping存活检测

ansible all -m ping -u mark -k

以mark sudo至root执行ping存活检测

ansible all -m ping -u mark –b -k

以mark sudo至markupzh用户执行ping存活检测

ansible all -m ping -u mark –b -k --become-user markupzh

以mark sudo至root用户执行ls

ansible all -m command -u mark --become-user=root -a 'ls /root' -b –k -K

ansible常用模块

Command:在远程主机执行命令,默认模块,可忽略-m选项

ansible srvs -m command -a 'service vsftpd start'

ansible srvs -m command -a 'echo markupzh |passwd --stdin mark'不成功

此命令不支持 $VARNAME < > | ; & 等,用shell模块实现

Shell:和command相似,用shell执行命令

ansible srv -m shell -a 'echo markupzh |passwd –stdin mark'

调用bash执行命令 类似 cat /tmp/stanley.md | awk -F’|’ ‘{print $1,$2}’ &> /tmp/example.txt 这些复杂命令,即使使用shell也可能会失败,解决办法:写到脚本时,copy到远程,执行,再把需要的结果拉回执行命令的机器

Script:运行脚本

-a "/PATH/TO/SCRIPT_FILE"

snsible websrvs -m script -a f1.sh

Copy:从服务器复制文件到客户端

ansible srv -m copy -a "src=/root/f1.sh dest=/tmp/f2.sh owner=mark mode=600 backup=yes"

如目标存在,默认覆盖,此处指定先备份

ansible srv -m copy -a "content='test content\n' dest=/tmp/f1.txt"

利用内容,直接生成目标文件

Fetch:从客户端取文件至服务器端,copy相反,目录可先tar

ansible srv -m fetch -a 'src=/root/a.sh dest=/data/scripts'

File:设置文件属性

ansible srv -m file -a "path=/root/a.sh owner=mark mode=755"

ansible web -m file -a 'src=/app/testfile dest=/app/testfile-link state=link'

Hostname:管理主机名

ansible node1 -m hostname -a "name=websrv"

Cron:计划任务

支持时间:minute,hour,day,month,weekday

ansible srv -m cron -a "minute=*/5 job='/usr/sbin/ntpdate

172.16.0.1 &>/dev/null' name=Synctime"创建任务

ansible srv -m cron -a 'state=absent name=Synctime' 删除任务

Yum:管理包

ansible srv -m yum -a 'name=httpd state=latest' 安装

ansible srv -m yum -a 'name=httpd state=absent' 删除

Service:管理服务

ansible srv -m service -a 'name=httpd state=stopped'

ansible srv -m service -a 'name=httpd state=started'

ansible srv –m service –a 'name=httpd state=reloaded'

ansible srv -m service -a 'name=httpd state=restarted'

User:管理用户

ansible srv -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'

ansible srv -m user -a 'name=sysuser1 system=yes home=/app/sysuser1 '

ansible srv -m user -a 'name=user1 state=absent remove=yes'删除用户及家目录等数据

Group:管理组

ansible srv -m group -a "name=testgroup system=yes"

ansible srv -m group -a "name=testgroup state=absent"

ansible系列命令

ansible-galaxy

连接 https://galaxy.ansible.com 下载相应的roles

列出所有已安装的galaxy

ansible-galaxy list

安装galaxy

ansible-galaxy install geerlingguy.redis

删除galaxy

ansible-galaxy remove geerlingguy.redis

ansible-pull

推送命令至远程,效率无限提升,对运维要求较高

Ansible-playbook

ansible-playbook hello.yml

1
2
3
4
5
6
7
cat hello.yml
#hello world yml file
-hosts: websrvs
remote_user: root
tasks:
-name: hello world
command: /usr/bin/wall hello world
Ansible-vault
1
2
3
4
5
6
7
8
功能:管理加密解密yml文件
ansible-vault [create|decrypt|edit|encrypt|rekey|view]
ansible-vault encrypt hello.yml 加密
ansible-vault decrypt hello.yml 解密
ansible-vault view hello.yml 查看
ansible-vault edit hello.yml 编辑加密文件
ansible-vault rekey hello.yml 修改口令
ansible-vault create new.yml 创建新文件
Ansible-console

Ansible-console:2.0+新增,可交互执行命令,支持tab

root@test (2)[f:10] $

执行用户@当前操作的主机组 (当前组的主机数量)[f:并发数]$

设置并发数: forks n 例如: forks 10

切换组: cd 主机组 例如: cd web

列出当前组主机列表: list

列出所有的内置命令: ?或help

示例:

1
2
3
4
5
root@all (2)[f:5]$ list 
root@all (2)[f:5]$ cd appsrvs
root@appsrvs (2)[f:5]$ list
root@appsrvs (2)[f:5]$ yum name=httpd state=present
root@appsrvs (2)[f:5]$ service name=httpd state=started
playbook

playbook是由一个或多个”play”组成的列表

play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏

Playbook采用YAML语言编写

YAML介绍

YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822等。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者

YAML Ain’t Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是:”Yet Another Markup Language”(仍是一种标记语言)

特性

YAML的可读性好

YAML和脚本语言的交互性好

YAML使用实现语言的数据类型

YAML有一个一致的信息模型

YAML易于实现

YAML可以基于流来处理

YAML表达能力强,扩展性好

更多的内容及规范参见http://www.yaml.org

YAML语法简介

在单一档案中,可用连续三个连字号(——)区分多个档案。另外,还有选择性的连续三个点号( … )用来表示档案结尾

次行开始正常写Playbook的内容,一般建议写明该Playbook的功能

使用#号注释代码

缩进必须是统一的,不能空格和tab混用

缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的

YAML文件内容是区别大小写的,k/v的值均需大小写敏感

k/v的值可同行写也可换行写。同行使用:分隔

v可是个字符串,也可是另一个列表

一个完整的代码块功能需最少元素需包括 name: task

一个name只能包括一个task

YAML文件扩展名通常为yml或yaml

List:列表,其所有元素均使用”-“打头

示例:
1
2
3
4
5
A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango

Dictionary:字典,通常由多个key与value构成

1
2
3
4
5
---
An employee record
name: Example Developer
job: Developer
skill: Elite

也可以将key:value放置于{}中进行表示,用,分隔多个key:value

1
2
3
---
An employee record
{name: Example Developer, job: Developer, skill: Elite}

YAML语法

YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用”-“来代表,Map里的键值对用”:”分隔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
name: John Smith
age: 41
gender: Male
spouse:
name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female

Playbook核心元素

Hosts 执行的远程主机列表
Tasks 任务集
Varniables 内置变量或自定义变量在playbook中调用
Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers 和notity结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
ansible-playbook –t tagsname useradd.yml

playbook基础组件

Hosts:
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中
可以是如下形式:
​ one.example.com
​ one.example.com:two.example.com
​ 192.168.1.50
​ 192.168.1.*

Websrvs:dbsrvs 两个组的并集

Websrvs:&dbsrvs 两个组的交集

webservers:!phoenix 在websrvs组,但不在dbsrvs组

示例: - hosts: websrvs:dbsrvs

remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

1
2
3
4
5
6
7
8
- hosts: websrvs
remote_user: root
tasks:
-name: test connection
ping:
remote_user: markupzh
sudo: yes 默认sudo为root
sudo_user:mark sudo为mark

task列表和action
play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后,再开始第二个任务

task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致

每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出

playbook基础组件
tasks:任务列表

格式:
(1) action: module arguments

(2) module: arguments 建议使用

注意:shell和command模块后面跟命令,而非key=value

某任务的状态在运行后为changed时,可通过”notify”通知给相应的 handlers

任务可以通过”tags”打标签,而后可在ansible-playbook命令上使用-t指定进行调用

示例:

1
2
3
tasks:
- name: disable selinux
command: /sbin/setenforce 0

如果命令或脚本的退出码不为零,可以使用如下方式替代

1
2
3
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true

或者使用ignore_errors来忽略错误信息:

1
2
3
4
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True

运行playbook

运行playbook的方式

ansible-playbook <filename.yml> ... [options]

常见选项

–check 只检测可能会发生的改变,但不真正执行操作

–list-hosts 列出运行任务的主机

–limit 主机列表 只针对主机列表中的主机执行

-v 显示过程 -vv -vvv 更详细

示例

ansible-playbook file.yml --check 只检测

ansible-playbook file.yml

ansible-playbook file.yml --limit websrvs

Playbook与ShellScripts相比较

SHELL脚本

1
2
3
4
5
6
7
8
9
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp /tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
service httpd start
chkconfig httpd on

Playbook定义

1
2
3
4
5
6
7
8
9
10
11
---
- hosts: all
tasks:
- name: "安装Apache"
yum: name=httpd
- name: "复制配置文件"
copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
- name: "复制配置文件"
copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.cd/
- name: "启动Apache,并设置开机启动"
service: name=httpd state=started enabled=yes

Playbook示例

示例:sysuser.yml创建mysql用户

1
2
3
4
5
6
7
8
---
- hosts: all
remote_user: root
tasks:
- name: create mysql user
user: name=mysql system=yes uid=36
- name: create a group
group: name=httpd system=yes

示例:httpd.yml安装httpd

1
2
3
4
5
6
7
8
9
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
- name: start service
service: name=httpd state=started enabled=yes

handlers和notify结合使用触发条件

Handlers

是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作

Notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

Playbook中handlers使用

1
2
3
4
5
6
7
8
9
10
11
12
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present
- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd
- name: ensure apache is running
service: name=httpd state=started enabled=yes handlers:
- name: restart httpd
service: name=httpd status=restarted

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- hosts: websrvs
remote_user: root

tasks:
- name: add group nginx
tags: user
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: config
copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
notify:
- Restart Nginx
- Check Nginx Process
handlers:
- name: Restart Nginx
service: name=nginx state=restarted enabled=yes
- name: Check Nginx process
shell: killall -0 nginx > /tmp/nginx.log

Playbook中tags使用

示例:httpd.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- hosts: websrvs
remote_user: root
tasks:
- name: Install httpd
yum: name=httpd state=present

- name: Install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: conf

- name: start httpd service
tags: service
service: name=httpd state=started enabled=yes
ansible-playbook –t conf httpd.yml

Playbook中变量使用

变量名:

仅能由字母、数字和下划线组成,且只能以字母开头

变量来源:

1 ansible setup facts 远程主机的所有变量都可直接调用

2 在/etc/ansible/hosts中定义

普通变量:主机组中主机单独定义,优先级高于公共变量公共(组)变量:针对主机组中所有主机定义统一变量

3 通过命令行指定变量,优先级最高

ansible-playbook –e varname=value

4 在playbook中定义
vars:
​ - var1: value1
​ - var2: value2

5 在独立的变量YAML文件中定义

6 在role中定义
变量命名
变量名仅能由字母、数字和下划线组成,且只能以字母开头

变量定义:key=value
示例:http_port=80

变量调用方式:

通过 调用变量,且变量名前后必须有空格,有时用”“才生效

ansible-playbook –e 选项指定
ansible-playbook test.yml -e "hosts=www user=markupzh"

示例:使用setup变量

var.yml

1
2
3
4
5
6
7
8
- hosts: websrvs
remote_user: root

tasks:
- name: create log file
file: name=/var/log/ {{ ansible_fqdn }} state=touch

ansible-playbook var.yml

示例:变量

var.yml

1
2
3
4
5
6
7
- hosts: websrvs
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }} state=present

ansible-playbook –e pkname=httpd var.yml

示例:变量

var.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
- hosts: websrvs
remote_user: root
vars:
- username: user1
- groupname: group1
tasks:
- name: create group
group: name={{ groupname }} state=present
- name: create user
user: name={{ username }} state=present

ansible-playbook var.yml
ansible-playbook -e "username=user2 groupname=group2" var2.yml

主机变量

可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用

示例:

1
2
[websrvs]
www1.markupzh.com http_port=80 maxRequestsPerChild=808 www2.markupzh.com http_port=8080 maxRequestsPerChild=909

组变量

组变量是指赋予给指定组内所有主机上的在playbook中可用的变量

示例:

1
2
3
4
5
[websrvs]
www1.markupzh.com
www2.markupzh.com
[websrvs:vars]
ntp_server=ntp.markupzh.com nfs_server=nfs.markupzh.com

普通变量

1
2
3
[websrvs]
192.168.99.101 http_port=8080 hname=www1
192.168.99.102 http_port=80 hname=www2

公共(组)变量

1
2
3
4
5
6
7
8
9
[websvrs:vars] 
http_port=808
mark="_"

[websrvs]
192.168.99.101 http_port=8080 hname=www1
192.168.99.102 http_port=80 hname=www2

ansible websvrs –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'

命令行指定变量:

1
ansible websvrs –e http_port=8000 –m hostname –a 'name={{ hname }}{{ mark }}{{ http_port }}'

使用变量文件

1
2
3
4
cat vars.yml 

var1: httpd
var2: nginx
1
2
3
4
5
6
7
8
9
10
11
cat var.yml

- hosts: web
remote_user: root
vars_files:
- vars.yml
tasks:
- name: create httpd log
file: name=/app/{{ var1 }}.log state=touch
- name: create nginx log
file: name=/app/{{ var2 }}.log state=touch

模板templates

文本文件,嵌套有脚本(使用模板编程语言编写)

Jinja2语言,使用字面量,有下面形式字符串:使用单引号或双引号

数字:整数,浮点数

列表:[item1, item2, …]

元组:(item1, item2, …)

字典:{key1:value1, key2:value2, …}

布尔型:true/false

算术运算:+, -, , /, //, %, *

比较操作:==, !=, >, >=, <, <=

逻辑运算:and, or, not

流表达式:For If When

templates

templates功能:根据模块文件动态生成对应的配置文件

templates文件必须存放于templates目录下,且命名为 .j2 结尾

yaml/yml 文件需和templates目录平级,目录结构如下:

1
2
3
4
./
├── temnginx.yml
└── templates
└── nginx.conf.j2

Templates示例

示例:利用templates 同步nginx配置文件准备templates/nginx.conf.j2文件

1
2
3
4
5
6
7
8
9
10
vim temnginx.yml

- hosts: websrvs
remote_user: root

tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

ansible-playbook temnginx.yml

Playbook中template变更替换

修改文件nginx.conf.j2 下面行为

worker_processes ;

1
2
3
4
5
6
7
8
9
10
cat temnginx2.yml

- hosts: websrvs
remote_user: root

tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

ansible-playbook temnginx2.yml

Playbook中template算术运算

算法运算:

示例:

1
2
3
4
vim nginx.conf.j2

worker_processes {{ ansible_processor_vcpus**2 }};
worker_processes {{ ansible_processor_vcpus+2 }};

when

条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过when语句实现,在task中使用,jinja2的语法格式

when语句

在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法

示例:

1
2
3
4
tasks:
- name: "shutdown RedHat flavored systems"
command: /sbin/shutdown -h now
when: ansible_os_family == "RedHat"

示例:when条件判断

1
2
3
4
5
6
7
8
9
10
11
12
13
- hosts: websrvs
remote_user: root
tasks:
- name: add group nginx
tags: user
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: restart Nginx
service: name=nginx state=restarted
when: ansible_distribution_major_version == "6"

示例:when条件判断

示例:

1
2
3
4
5
6
7
tasks:
- name: install conf file to centos7
template: src=nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"

迭代:with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制

对迭代项的引用,固定变量名为”item”

要在task中使用with_items给定要迭代的元素列表

列表格式:

字符串

字典

示例:

1
2
3
4
5
- name: add several users
user: name={{ item }} state=present groups=wheel
with_items:
- testuser1
- testuser2

上面语句的功能等同于下面的语句:

1
2
3
4
- name: add user testuser1
user: name=testuser1 state=present groups=wheel
- name: add user testuser2
user: name=testuser2 state=present groups=wheel

示例:迭代

将多个文件进行copy到被控端

1
2
3
4
5
6
7
8
9
10
---

- hosts: testsrv
remote_user: root

tasks
- name: Create rsyncd config
copy: src={{ item }} dest=/etc/{{ item }} with_items:
- rsyncd.secrets
- rsyncd.conf

示例:迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- hosts: websrvs
remote_user: root
tasks:
- name: copy file
copy: src={{ item }} dest=/tmp/{{ item }}
with_items:
- file1
- file2
- file3
- name: yum install httpd
yum: name={{ item }} state=present
with_items:
- apr
- apr-util
- httpd

示例:迭代

1
2
3
4
5
6
7
8
9
10
- hosts:websrvs 
remote_user: root

tasks
- name: install some packages
yum: name={{ item }} state=present
with_items:
- nginx
- memcached
- php-fpm

示例:迭代嵌套子变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- hosts:websrvs
remote_user: root
tasks:
- name: add some groups
group: name={{ item }} state=present
with_items:
- group1
- group2
- group3
- name: add some users
user: name={{ item.name }} group={{ item.group }} state=present with_items:
- { name: 'user1', group: 'group1' }
- { name: 'user2', group: 'group2' }
- { name: 'user3', group: 'group3' }

roles

ansilbe自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中

复杂场景:建议使用roles,代码复用度高

变更指定主机或主机组

如命名不规范维护和传承成本大

某些功能需多个Playbook,通过Includes即可实现

角色(roles):角色集合

roles/

mysql/

httpd/

nginx/

memcached/

roles目录结构

每个角色,以特定的层级目录结构进行组织

roles目录结构:

playbook.yml

roles/
​ project/
​ tasks/
​ files/
​ vars/
​ templates/
​ handlers/
​ default/ 不常用
​ meta/ 不常用

Roles各目录作用:

/roles/project/ :项目名称,有以下子目录

files/ :存放由copy或script模块等调用的文件

templates/:template模块查找所需要模板文件的目录

tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含

handlers/:至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含

vars/:定义变量,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含

meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含

default/:设定默认变量时使用此目录中的main.yml文件

创建role:

创建role的步骤

(1) 创建以roles命名的目录

(2) 在roles目录中分别创建以各角色名称命名的目录,如webservers等

(3) 在每个角色命名的目录中分别创建files、handlers、meta、tasks、templates和vars目录;用不到的目录可以创建为空目录,也可以不创建

(4) 在playbook文件中,调用各角色

playbook调用角色

调用角色方法1:

1
2
3
4
5
6
- hosts: websrvs
remote_user: root
roles:
- mysql
- memcached
- nginx

调用角色方法2:传递变量给角色

1
2
3
4
5
- hosts:
remote_user:
roles:
- mysql
- { role: nginx, username: nginx }

键role用于指定角色名称

后续的k/v用于传递变量给角色

调用角色方法3:还可基于条件测试实现角色调用 roles:

1
- { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }

推荐资料

http://galaxy.ansible.com
https://galaxy.ansible.com/explore#/
http://github.com/
http://ansible.com.cn/
https://github.com/ansible/ansible
https://github.com/ansible/ansible-examples

无论在本地搭建实验环境还是在生产环境中,多节点并行计算设置中,建立Linux主机间的SSH互信是非常重要的环节.常见的互信机制包括RSH和SSH两种,其中SSH互信较常用到,下面介绍SSH的原理及其配置方法.

首先,我们先了解下配置ssh互信的原理,ssh互信,说白了,就是在目标机器上,预先设置好经过认证的key文件,当需要访问目标机器时,目标机器通过key文件,对访问者进行自动认证,从而实现互信.

了解了ssh互信的原理,我们把配置ssh互信的步骤,进行有效的分割:

1.首先,在要配置互信的机器上,生成各自的经过认证的key文件;

2.其次,将所有的key文件汇总到一个总的认证文件中;

3.将这个包含了所有互信机器认证key的认证文件,分发到各个机器中去;

4.验证互信;

实例演示:CentOS 7.5系统的两台电脑,IP分别为192.168.0.100和192.168.0.101,主机名(hostname)分别为node0和node1,默认都已安装SSH服务,要实现两个名称相同的账号root间的互信连接.

备注:主机名可以通过root用户修改/etc/sysconfig/network中的hostname变量名,重启设定生效,而hostname命令只修改当前显示的主机名,重启后即失效.

1.节点node1上,以root身份修改/etc/hosts文件,以建立主机IP和主机名(hostname)间的映射,其文件格式如下:

1
2
3
4
5
6
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
192.168.100.100 node1.localdomain node1
192.168.100.101 node2.localdomain node2

IP hostname.domainname hostname,其中各项以Tab键隔开.

注意:修改该文件不是必须步骤,但方便以后用主机名直接访问各主机,省去了输入IP地址的麻烦.在节点node2上进行相同操作.

2.用户root身份,在node1上生成认证RSA密钥(这里有个细节,就是ssh互信的认证文件,需要放在用户的home目录下的.ssh目录中,因此我们要首先建立这个目录,并且保证这个目录的权限是700):

1
2
3
4
5
6
7
8
9
10
11
12
# cd
# mkdir .ssh
# chmod 700 .ssh
# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/deven/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/deven/.ssh/id_rsa.
Your public key has been saved in /home/deven/.ssh/id_rsa.pub.
The key fingerprint is:
89:56:d6:4a:b2:6c:4a:05:86:ae:cd:7d:80:dd:3c:f1 deven@node1

中间过程直接3个回车.在~/.ssh/目录下,生成了两个文件:id_rsa(私钥文件放在本地) 和 id_rsa.pub(公钥文件放在信任服务器).

在node2上,以用户root身份进行相同操作.

3.将所有的公钥文件 id_rsa.pub汇总到一个总的认证文件authorized-keys中:

1
2
3

# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# ssh root@node2 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

4.经过1,2两步,目前node1上存在一份完整的认证key文件,这时候,把她拷到node2主机的对应目录下

1
# scp ~/.ssh/authorized_keys root@node2:~/.ssh/authorized_keys

5.大功告成,这时候,再互相用ssh命令连接,看看是否配置成功.

vmware为我们提供了3种网络工作模式,分别是:Bridge(桥接模式),NAT(网络地址转换模式),Host-Only(仅主机模式).

首先在说到VMware的网络模型前,先说一下VMware的几个虚拟设备:

VMnet0:这是VMware用于虚拟机桥接网络下的虚拟交换机

VMnet1:这是VMware用于Host-Only网络下的虚拟交换机

VMnet8:这是VMware用于虚拟NAT网络下的虚拟交换机

VMware Network Adapter VMnet1:这是Host用于Host-Only虚拟网络进行通信的虚拟网卡

VMware Network Adapter VMnet8:这是Host用于NAT虚拟网络进行通信的虚拟网卡

那么如何查看这些网卡的信息呢?

在windows主机命令行提示符环境中输入 ipconfig 便可以查询到VMware Network Adapter VMnet1,VMware Network Adapter VMnet8的ip地址.

Bridge(桥接模式)

桥接模式就是将主机网卡与虚拟机网卡利用虚拟网桥进行通信,在桥接的作用下,类似把主机虚拟为一个交换机,所有桥接设置的虚拟机连接到这个交换机的一个接口上,物理主机也同样连接到这个交换机中,所以所有桥接下的网卡与网卡都是交换模式的,相互可以访问而不干扰,在桥接模式下,虚拟机的ip地址需要与主机在同一个网段,如果需要联网,则网关与DNS需要与主机网卡一致.

在桥接模式下,VMware虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问该类网段内任何一台机器.

桥接网络环境下需要做到:

1.手动为虚拟机系统配置ip地址,子网掩码

2.在桥接的模式下虚拟机必须与物理机处于同一网段,(举个例子,物理机ip:192.168.1.2 虚拟机ip:192.168.1.3)这样虚拟系统才能和真实主机进行通信.

当我们想利用VMware在局域网内新建一个虚拟服务器,为局域网用户提供网络服务,就应该选择桥接模式,便可将虚拟机模拟接入主机所在的局域网,桥接网络相当于虚拟机与主机在一台交换机上,同时上网,虚拟机对物理机的直接影响较小.

但是桥接模式也有一定的问题,如果网络环境很缺少,或者对ip的管理比较严格的话,那桥接模式就不太适用了.如果解决这个问题就引入了vmware的另一种网络模式:NAT模式

NAT(地址转换模式)

在NAT网络中,会使用到VMnet8虚拟交换机,物理机上的VMware Network Adapter VMnet8 虚拟网卡将会和VMnet8交换机相连,来实现物理机与虚拟机之间的通信.

注意:VMware Network Adapter VMnet8虚拟网卡仅仅是用于和VMnet8网段通信用的,它并不为VMnet8网段提供路由功能,处于虚拟NAT网络下的Guest是使用虚拟的NAT服务器连接的Internet的.

VMware Network Adapter VMnet8 虚拟网卡它仅仅是为Host和NAT虚拟网络下的Guest通信提供一个接口,所以,即便去掉这块网卡,虚拟机仍然是可以上网的,只是物理机无法再访问到VMnet8网段而已.

1.主机需要开启vmdhcp和vmnat服务.

2.NAT模式下的虚拟机的TCP/IP配置信息将由VMnet8(NAT)虚拟网络的DHCP服务器自动分配,需要开启DHCP功能.

使用NAT模式,就是让虚拟系统借助NAT功能,通过物理机所在的网络来访问外网,也就是说,使用NAT模式可以实现在虚拟机里访问到互联网,NAT模式下的虚拟机的TCP/IP配置信息是由VMnet8(NAT)虚拟网络的DHCP服务器提供的,无法进行手动修改,因此虚拟系统也就无法和本局域网中的其他真实主机进行通讯,采用NAT模式最大的优势就是虚拟系统接入互联网非常简单,不需要进行任何其他的配置,只需要宿主机能访问互联网即可.

NAT模式下的网络,相当于说虚拟机是通过物理机连接上的网络,等于物理机是个路由器,申请到一个上网的名额,带着隐藏在它下下面的虚拟机上网,自然所有的虚拟机使用的网络总和都限制在实体机的一个网络通道内,虚拟机会抢占物理机的网络,对物理机上网会有很大的影响.

Host-Only(仅主机模式)

Host-Only模式其实就是NAT模式去除了虚拟NAT设备,然后使用VMware Network Adapter VMnet1 虚拟网卡连接VMnet1虚拟交换机来与虚拟机通信的,Host-Only模式将虚拟机与外网隔开,是虚拟机成为一个独立的系统,只与主机相互通讯.

使用cobbler

Cobbler:
快速网络安装linux操作系统的服务,支持众多的Linux发行版:Red Hat、Fedora、CentOS、Debian、Ubuntu和SuSE,也可以支持网络安装windows
PXE的二次封装,将多种安装参数封装到一个菜单
Python编写
提供了CLI和Web的管理形式

cobbler 工作流程

client裸机配置了从网络启动后,开机后会广播包请求DHCP服务器(cobbler server)发送其分配好的一个IP
DHCP服务器(cobbler server)收到请求后发送responese,包括其ip地址
client裸机拿到ip后再向cobbler server发送请求OS引导文件的请求
cobbler server告诉裸机OS引导文件的名字和TFTP server的ip和port
client裸机通过上面告知的TFTP server地址通信,下载引导文件
client裸机执行执行该引导文件,确定加载信息,选择要安装的os,期间会再向 cobbler server请求kickstart文件和os image
cobbler server发送请求的kickstart和os iamge
client裸机加载kickstart文件
client裸机接收os image,安装该os image

cobbler 介绍

安装包
cobbler 基于EPEL源
cobbler 服务集成
PXE
DHCP
rsync
Http
DNS
Kickstart
IPMI 电源管理
检查cobbler环境
cobbler check

cobbler 相关术语
发行版:
表示一个操作系统版本,它承载了内核和 initrd 的信息,以及内核参数等其他数据
配置文件:
包含一个发行版、一个 kickstart 文件以及可能的存储库,还包含更多特定的内核参数等其他数据
系统:
表示要配置的主机,它包含一个配置文件或一个镜像,还包含 IP 和 MAC 地址、电源管理(地址、凭据、类型)以及更为专业的数据等信息
存储库:
保存一个 yum 或 rsync 存储库的镜像信息

cobbler 各种配置目录说明

安装:yum install cobbler dhcp
配置文件目录 /etc/cobbler
    /etc/cobbler/settings : cobbler 主配置文件
    /etc/cobbler/iso/: iso模板配置文件
    /etc/cobbler/pxe: pxe模板文件
    /etc/cobbler/power: 电源配置文件
    /etc/cobbler/user.conf: web服务授权配置文件
    /etc/cobbler/users.digest: web访问的用户名密码配置文件
    /etc/cobbler/dhcp.template : dhcp服务器的的配置末班
    /etc/cobbler/dnsmasq.template : dns服务器的配置模板
    /etc/cobbler/tftpd.template : tftp服务的配置模板
    /etc/cobbler/modules.conf : 模块的配置文件

cobbler 目录介绍

数据目录
/var/lib/cobbler/config/: 用于存放distros,system,profiles 等信息配置文件
/var/lib/cobbler/triggers/: 用于存放用户定义的cobbler命令
/var/lib/cobbler/kickstart/: 默认存放kickstart文件
/var/lib/cobbler/loaders/: 存放各种引导程序

镜像目录
/var/www/cobbler/ks_mirror/: 导入的发行版系统的所有数据
/var/www/cobbler/images/ : 导入发行版的kernel和initrd镜像用于远程网络启动
/var/www/cobbler/repo_mirror/: yum 仓库存储目录

日志目录
/var/log/cobbler/installing: 客户端安装日志
/var/log/cobbler/cobbler.log : cobbler日志

cobbler 命令介绍

cobbler check 核对当前设置是否有问题
cobbler list 列出所有的cobbler元素
cobbler report 列出元素的详细信息
cobbler sync 同步配置到数据目录,更改配置最好都要执行下
cobbler reposync 同步yum仓库
cobbler distro 查看导入的发行版系统信息
cobbler system 查看添加的系统信息
cobbler profile 查看配置信息

cobbler 重要的参数

/etc/cobbler/settings中重要的参数设置
default_password_crypted: "$1$gEc7ilpP$pg5iSOj/mlxTxEslhRvyp/"
manage_dhcp:1
manage_tftpd:1
pxe_just_once:1
next_server:< tftp服务器的 IP 地址>
server:<cobbler服务器的 IP 地址>

cobbler 环境检查

执行Cobbler check命令会报如下异常

1
2
3
4
5
6
7
8
9
1 : The ‘server’ field in /etc/cobbler/settings must be set to something other than localhost, or kickstarting features will not work. This should be a resolvable hostname or IP for the boot server as reachable by all machines that will use it.
2 : For PXE to be functional, the ‘next_server’ field in /etc/cobbler/settings must be set to something other than 127.0.0.1, and should match the IP of the boot server on the PXE network.
3 : some network boot-loaders are missing from /var/lib/cobbler/loaders, you may run ‘cobbler get-loaders’ to download them, or, if you only want to handle x86/x86_64 netbooting, you may ensure that you have installed a recent version of the syslinux package installed and can ignore this message entirely. Files in this directory, should you want to support all architectures, should include pxelinux.0, menu.c32, elilo.efi, and yaboot. The ‘cobbler get-loaders’ command is the easiest way to resolve these requirements.
4 : change ‘disable’ to ‘no’ in /etc/xinetd.d/rsync
5 : comment ‘dists’ on /etc/debmirror.conf for proper debian support
6 : comment ‘arches’ on /etc/debmirror.conf for proper debian support
7 : The default password used by the sample templates for newly installed machines (default_password_crypted in /etc/cobbler/settings)
is still set to ‘cobbler’ and should be changed, try: “openssl passwd -1 -salt ‘random-phrase-here’ ‘your-password-here’” to generate new one
8 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them

cobbler 报错解决

执行Cobbler check报错解决方式
修改/etc/cobbler/settings文件中的server参数的值为提供cobbler服务的主机相应的IP地址或主机名
修改/etc/cobbler/settings文件中的next_server参数的值为提供PXE服务的主机相应的IP地址
如果当前节点可以访问互联网,执行“cobbler get-loaders”命令即可;否则,需要安装syslinux程序包,而后复制/usr/share/syslinux/{pxelinux.0,memu.c32}等文件至/var/lib/cobbler/loaders/目录中
执行“chkconfig rsync on”命令即可
执行“openssl passwd -1 生成密码,并用其替换/etc/cobbler/settings文件中default_password_crypted参数的值

cobbler 相关管理

下载启动菜单:
    联网:cobbler get-loaders
    不联网:cp /usr/share/syslinux/{pxelinux.0,menu.c32}  /var/lib/tftpboot

管理distro
    cobbler import --name=centos-7.5-x86_64 --path=/media/cdrom --arch=x86_64

管理profile
    cobbler profile add --name=centos-7.5-x86_64-basic --distro=centos-7.5-x86_64 --kickstart= /var/lib/cobbler/kickstarts/centos7_x86_64.cfg

cobbler 命令

查看profiles
    cobbler profile list
查看引导文件
    cat /var/lib/tftpboot/pxelinux.cfg/default
同步cobbler配置
    cobbler sync
多系统引导方案
    cobbler import --name=CentOS-7-x86_64 --path=/media/cdrom 
    cobbler distro list
    cobbler profile list 
    cobbler sync

cobbler 实现步骤

安装包,并设置服务
检查配置
根据上面提示修改配置
下载启动相关文件菜单
配置DHCP服务
分别导入centos的安装源,并查看
准备kickstart文件并导入cobbler
测试

cobbler的web管理实现

cobbler-web

提供cobbler的基于web管理界面,epel源 yum install cobbler-web

认证方式
    认证方法配置文件:/etc/cobbler/modules.conf
    支持多种认证方法:
        authn_configfile
        authn_pam

使用authn_configfile模块认证cobbler_web用户
vim /etc/cobbler/modules.conf
[authentication]
module=authn_configfile

创建其认证文件/etc/cobbler/users.digest,并添加所需的用户 htdigest -c /etc/cobbler/users.digest Cobbler admin
注意:添加第一个用户时,使用“-c”选项,后续添加其他用户时不要再使用,cobbler_web的realm只能为Cobbler

使用authn_pam模块认证cobbler_web用户
    vim /etc/cobbler/modules.conf 
    [authentication]
    module = authn_pam
创建cobbler用户:useradd cobbler
    vim /etc/cobbler/users.conf
    [admins]
    admin = "cobbler“

Web访问cobbler
    重启cobblerd服务
    通过https://cobblerserver/cobbler_web访问

安装Linux系统

CentOS系统安装系统启动流程:
bootloader–>kernel(initramfs)–>rootfs–>/sbin/init

anaconda: 系统安装程序
gui:图形窗口
tui: 基于图形库curses的文本窗口

安装程序启动过程

MBR:isolinux/boot.cat
stage2: isolinux/isolinux.bin
配置文件:isolinux/isolinux.cfg
每个对应的菜单选项:
加载内核:isolinuz/vmlinuz
向内核传递参数:append initrd=initrd.img …
装载根文件系统,并启动anaconda
默认启动GUI接口
若是显式指定使用TUI接口:向内核传递text参数即可
(1)按tab键,在后面增加text
(2)按ESC键:boot: linux text

anaconda工作过程

Anaconda安装系统分成三个阶段:
安装前配置阶段
安装过程使用的语言键盘类型
安装目标存储设备
Basic Storage:本地磁盘
特殊设备:iSCSI
设定主机名
配置网络接口时区
管理员密码
设定分区方式及MBR的安装位置
创建一个普通用户
选定要安装的程序包

安装阶段
在目标磁盘创建分区,执行格式化操作等
将选定的程序包安装至目标位置
安装bootloader和initramfs

图形模式首次启动
iptables
selinux
core dump

系统安装

启动安装过程一般应位于引导设备;后续的anaconda及其安装用到的程序包等可来自下面几种方式:
本地光盘
本地硬盘
NFS
URL:
ftp server: yum repository
http server: yum repostory
如果想手动指定安装源:
boot: linux askmethod

指定安装源

centos6
DVD drive repo=cdrom :device
Hard Drive repo=hd:device/path
HTTP Server repo=http://host/path
HTTPS Server repo=https://host/path
FTP Server repo=ftp://username:password@ host/path
NFS Server repo=nfs:server:/path
ISO images on an NFS Server repo=nfsiso:server:/path

centos7
Any CD/DVD drive inst.repo=cdrom
Hard Drive inst.repo=hd:device:/path
HTTP Server inst.repo=http://host/path
HTTPS Server inst.repo=https://host/path
FTP Server inst.repo=ftp://username:password@ host/path
NFS Server inst.repo=nfs:[options:]server:/path

系统安装

anaconda的配置方式:
(1) 交互式配置方式
(2) 通过读取事先给定的配置文件自动完成配置按特定语法给出的配置选项kickstart文件

安装boot引导选项:boot:
text: 文本安装方式
askmethod: 手动指定使用的安装方法

与网络相关的引导选项:
ip=IPADDR
netmask=MASK
gateway=GW
dns=DNS_SERVER_IP
ifname=NAME:MAC_ADDR

与远程访问功能相关的引导选项:
vnc
vncpassword=’PASSWORD’

指明kickstart文件的位置: ks=
DVD drive: ks=cdrom:/PATH/TO/KICKSTART_FILE
Hard drive: ks=hd:device:/directory/KICKSTART_FILE
HTTP server: ks=http://host:port/path/to/KICKSTART_FILE
FTP server: ks=ftp://host:port/path/to/KICKSTART_FILE
HTTPS server: ks=https://host:port/path/to/KICKSTART_FILE
NFS server:ks=nfs:host:/path/to/KICKSTART_FILE

启动紧急救援模式:
rescue

官方文档:《Installation Guide》

kickstart文件的格式

命令段:指明各种安装前配置,如键盘类型等
程序包段:指明要安装的程序包组或程序包,不安装的程序包等
%packages
@group_name
package
-package
%end

脚本段:
%pre: 安装前脚本
运行环境:运行于安装介质上的微型Linux环境

%post: 安装后脚本
运行环境:安装完成的系统

命令段中的命令:
必备命令
authconfig: 认证方式配置
authconfig –useshadow –passalgo=sha512
bootloader:bootloader的安装位置及相关配置
bootloader –location=mbr –driveorder=sda – append=”crashkernel=auto rhgb quiet”
keyboard: 设定键盘类型
lang: 语言类型
part: 创建分区
rootpw: 指明root的密码
timezone: 时区

可选命令
install OR upgrade
text: 文本安装界面
network
firewall
selinux
halt
poweroff
reboot
repo
user:安装完成后为系统创建新用户
url: 指明安装源
key –skip 跳过安装号码,适用于rhel版本

创建kickstart文件的方式
直接手动编辑
依据某模板修改
可使用创建工具:system-config-kickstart
依据某模板修改并生成新配置
/root/anaconda-ks.cfg
检查ks文件的语法错误:ksvalidator
ksvalidator /PATH/TO/KICKSTART_FILE

系统光盘中isolinux目录列表
solinux.bin:光盘引导程序,在mkisofs的选项中需要明确给出文件路径,这个文件属于SYSLINUX项目
isolinux.cfg:isolinux.bin的配置文件,当光盘启动后(即运行isolinux.bin),会自动去找isolinux.cfg文件
vesamenu.c32:是光盘启动后的安装图形界面,也属于SYSLINUX项目,menu.c32版本是纯文本的菜单
Memtest:内存检测,这是一个独立的程序
splash.jgp:光盘启动界面的背景图
vmlinuz是内核映像
initrd.img是ramfs (先cpio,再gzip压缩)

制作引导光盘和U盘

创建引导光盘:
mkdir –pv /app/myiso
cp -r /misc/cd/isolinux/ /app/myiso/
vim /app/myiso/isolinux/isolinux.cfg initrd=initrd.img text ks=cdrom:/myks.cfg
cp /root/myks.cfg /app/myiso/
mkisofs -R -J -T -v –no-emul-boot –boot-load-size 4 –boot-info-table -V “CentOS 6.9 x86_64 boot” -b isolinux/isolinux.bin -c isolinux/boot.cat -o /root/boot.iso /app/myiso/
注意:以上相对路径都是相对于光盘的根,和工作目录无关

创建U盘启动盘
dd if=/dev/sr0 of=/dev/sdb

mkisofs选项
-o 指定映像文件的名称。
-b 指定在制作可开机光盘时所需的开机映像文件。
-c 制作可开机光盘时,会将开机映像文件中的 no-eltorito-catalog 全部内容作成一个文件。
-no-emul-boot 非模拟模式启动。
-boot-load-size 4 设置载入部分的数量
-boot-info-table 在启动的图像中现实信息
-R 或 -rock   使用 Rock RidgeExtensions
-J 或 -joliet   使用 Joliet 格式的目录与文件名称
-v 或 -verbose   执行时显示详细的信息
-T 或 -translation-table 建立文件名的转换表,适用于不支持 Rock Ridge Extensions 的系统上

DHCP服务

网络配置
静态指定
动态获取: bootp:boot protocol MAC与IP一一静态对应dhcp:增强的bootp,动态

DHCP: (Dynamic Host Configuration Protocol)
动态主机配置协议
局域网协议,UDP协议

主要用途:
用于内部网络和网络服务供应商自动分配IP地址给用户
用于内部网络管理员作为对所有电脑作集中管理的手段

使用场景
自动化安装系统
解决IPV4资源不足问题

DHCP共有八种报文
DHCP DISCOVER:客户端到服务器
DHCP OFFER :服务器到客户端
DHCP REQUEST:客户端到服务器
DHCP ACK :服务器到客户端
DHCP NAK:服务器到客户端,通知用户无法分配合适的IP地址
DHCP DECLINE :客户端到服务器,指示地址已被使用
DHCP RELEASE:客户端到服务器,放弃网络地址和取消剩余的租约时间
DHCP INFORM:客户端到服务器, 客户端如果需要从DHCP服务器端获取更为详细的配置信息,则发送Inform报文向服务器进行请求,极少用到

续租
50% :租赁时间达到50%时来续租,刚向DHCP服务器发向新的DHCPREQUEST请求。如果dhcp服务没有拒绝的理由,则回应DHCPACK信息。当DHCP客户端收到该应答信息后,就重新开始新的租用周期
87.5%:如果之前DHCP Server没有回应续租请求,等到租约期的7/8时,主机会再发送一次广播请求

DHCP服务简介

同网段多DHCP服务
DHCP服务必须基于本地
先到先得的原则

跨网段
RFC 1542 Compliant Routers
dhcrelay: 中继

相关协议
Arp
rarp

DHCP实现

Linux DHCP协议的实现程序:dhcp, dnsmasq(dhcp,dns)

Dhcp Server
/usr/sbin/dhcpd
/etc/dhcp/dhcpd.conf –> /etc/rc.d/init.d/dhcpd
/etc/dhcp/dhcpd6.conf–> /etc/rc.d/init.d/dhcpd6
/usr/sbin/dhcrelay
/etc/rc.d/init.d/dhcrelay
dhcp server:67/udp
dhcp client: 68/udp
dhcpv6 client:546/udp

Dhcp client
dhclient
自动获取的IP信息: /var/lib/dhclient

DHCP配置文件

dhcpd.conf:
帮助参考:man 5 dhcpd.conf
全局配置
subnet {

}
host {

​ }

地址分配记录
/var/lib/dhcpd/dhcpd.leases

dhcpd.conf示例

option domain-name “magedu.com”;
option domain-name-servers 192.168.0.1,8.8.8.8;
default-lease-time 86400;
max-lease-time 86400;
subnet 192.168.100.0 netmask 255.255.255.0 {
range 192.168.100.1 192.168.100.200;
option routers 192.168.100.1;
}

其它配置选项:
filename: 指明引导文件名称
next-server:提供引导文件的服务器IP地址
示例:
filename “pxelinux.0”;
next-server 192.168.100.100;
检查语法
service dhcpd configtest

PXE介绍

PXE:
Preboot Excution Environment 预启动执行环境
Intel公司研发
基于Client/Server的网络模式,支持远程主机通过网络从远端服务器下载映像,并由此支持通过网络启动操作系统
PXE可以引导和安装Windows,linux等多种操作系统

PXE工作原理
Client向PXE Server上的DHCP发送IP地址请求消息,DHCP检测Client是否合法(主要是检测Client的网卡MAC地址),如果合法则返回Client的IP地址,同时将启动文件pxelinux.0的位置信息一并传送给Client
Client向PXE Server上的TFTP发送获取pxelinux.0请求消息,TFTP接收到消息之后再向Client
发送pxelinux.0大小信息,试探Client是否满意,当TFTP收到Client发回的同意大小信息之后,正式向Client发送pxelinux.0
Client执行接收到的pxelinux.0文件
Client向TFTP Server发送针对本机的配置信息文件(在TFTP 服务的pxelinux.cfg目录下),
TFTP将配置文件发回Client,继而Client根据配置文件执行后续操作。
Client向TFTP发送Linux内核请求信息,TFTP接收到消息之后将内核文件发送给Client
Client向TFTP发送根文件请求信息,TFTP接收到消息之后返回Linux根文件系统
Client启动Linux内核
Client下载安装源文件,读取自动化安装脚本

PXE自动化安装CentOS 7

安装前准备:关闭防火墙和SELINUX,DHCP服务器静态IP
安装软件包
httpd tftp-server dhcp syslinux system-config-kickstart
配置文件共享服务:
systemctl enable httpd
systemctl start httpd
mkdir /var/www/html/centos/7
mount /dev/sr0 /var/www/html/centos/7
准备kickstart文件
/var/www/html/ks/centos7.cfg 注意:权限
配置tftp服务
systemctl enable tftp.socket
systemctl start tftp.socket
配置DHCP服务
vim /etc/dhcp/dhcpd.conf
option domain-name “example.com”;
default-lease-time 600;
max-lease-time 7200;
subnet 192.168.100.0 netmask 255.255.255.0 {
range 192.168.100.1 192.168.100.200;
filename “pxelinux.0”;
next-server 192.168.100.100;
}
systemctl enable dhcpd
systemctl start dhcpd

准备相关文件
mkdir /var/lib/tftpboot/pxelinux.cfg/
cp /usr/share/syslinux/{pxelinux.0,menu.c32} /var/lib/tftpboot/
cp /misc/cd/isolinux/{vmlinuz,initrd.img} /var/lib/tftpboot/
cp /misc/cd/isolinux/isolinux.cfg /var/lib/tftpboot/pxelinux.cfg/default

文件列表如下:

/var/lib/tftpboot/
├── initrd.img
├── menu.c32
├── pxelinux.0
├── pxelinux.cfg
│ └── default
└── vmlinuz

准备启动菜单
Vim /var/lib/tftpboot/pxelinux.cfg/default
default menu.c32
timeout 600
menu title PXE INSTALL MENU
label auto
menu label Auto Install CentOS 7
kernel vmlinuz
append initrd=initrd.img ks=http://192.168.100.100/ks/centos7.cfg
label manual
menu label Manual Install CentOS 7
kernel vmlinuz
append initrd=initrd.img inst.repo=http://192.168.100.100/centos/7
label local
menu default
menu label ^Boot from local drive
localboot 0xffff

安装前准备:关闭防火墙和SELINUX,DHCP服务器静态IP

1 安装相应软件包
yum install dhcp httpd tftp-server syslinux chkconfig tftp on
chkconfig xinetd on 
chkconfig httpd on 
chkconfig dhcpd on 
service httpd start 
service xneted start
2 准备Yum 源和相关目录
mkdir -pv /var/www/html/centos/{6,ks} 
mount /dev/sr0 /var/www/html/centos/6
3 准备kickstart文件
/var/www/html/centos/ks/centos6.cfg

注意权限:
chmod 644 /var/www/html/centos/ks/centos6.cfg

4 准备相关的启动文件
mkdir /var/lib/tftpboot/pxelinux.cfg/
cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/ 
cd /misc/cd/images/pxeboot/
cp vmlinuz initrd.img /var/lib/tftpboot 
cd /misc/cd/isolinux/
cp boot.msg vesamenu.c32 splash.jpg /var/lib/tftpboot
5 准备启动菜单文件
cp /misc/cd/isolinux/isolinux.cfg /var/lib/tftpboot/pxelinux.cfg/default
vim /var/lib/tftpboot/pxelinux.cfg/default 
default vesamenu.c32 指定菜单风格 
#prompt 1
timeout 600 
display boot.msg
menu background splash.jpg
menu title Welcome to wang CentOS 6 
menu color border 0 #ffffffff #00000000 
menu color sel 7 #ffffffff #ff000000 
menu color title 0 #ffffffff #00000000 
menu color tabmsg 0 #ffffffff #00000000 
menu color unsel 0 #ffffffff #00000000 
menu color hotsel 0 #ff000000 #ffffffff 
menu color hotkey 7 #ffffffff #ff000000 
menu color scrollbar 0 #ffffffff #00000000
label auto
    menu label ^Automatic Install Centos6
    kernel vmlinuz
    append initrd=initrd.img ks=http://192.168.100.100/centos/ks/centos6.cfg
label manual
    menu label ^Manual Install Centos
    kernel vmlinuz
    append initrd=initrd.img inst.repo=http://192.168.100.100/centos/6
label local
    menu default
    menu label Boot from ^local drive
    localboot 0xffff

目录结构如下:
tree /var/lib/tftpboot/
/var/lib/tftpboot/
├── boot.msg
├── initrd.img
├── pxelinux.0
├── pxelinux.cfg
│ └── default
├── splash.jpg
├── vesamenu.c32
└── vmlinuz

​ 1 directory, 7 files

6 配置dhcp服务

​ cp /usr/share/doc/dhcp-4.1.1/dhcpd.conf.sample /etc/dhcp/dhcpd.conf
vim /etc/dhcp/dhcpd.conf
option domain-name “magedu.com”;
option domain-name-servers 192.168.100.1;
subnet 192.168.100.0 netmask 255.255.255.0 {
range 192.168.100.1 192.168.100.200;
option routers 192.168.100.1;
filename “pxelinux.0”;
next-server 192.168.100.100;
}

​ service dhcpd start

PAM认证机制

PAM:Pluggable Authentication Modules
认证库:文本文件,MySQL,NIS,LDAP等
Sun公司于1995 年开发的一种与认证相关的通用框架机制
PAM 是关注如何为服务验证用户的 API,通过提供一些动态链接库和一套统一的API,将系统提供的服务和该服务的认证方式分开
使得系统管理员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序
一种认证框架,自身不做认证

它提供了对所有服务进行认证的中央机制,适用于login,远程登录(telnet,rlogin,fsh,ftp,点对点协议 (PPP)),su等应用程序中.系统管理员通过PAM配置文件来制定不同应用程序的不同认证策略;应用程序开发者通过在服务程序中使用PAM API(pam_xxxx( ))来实现对认证方法的调用;而PAM服务模块的开发者则利用PAM SPI来编写模块(主要调用函数pam_sm_xxxx( )供PAM接口库调用,将不同的认证机制加入到系统中;PAM接口库(libpam)则读取配置文件,将应用程序和相应的PAM服务模块联系起来

图解PAM架构

PAM认证原理

PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→pam_*.so
PAM认证首先要确定那一项服务,然后加载相应的PAM的配置文件(位于/etc/pam.d下),最后调用认证文件(位于/lib/security下)进行安全认证

PAM认证机制

PAM相关文件

模块文件目录:/lib64/security/*.so
环境相关的设置:/etc/security/
主配置文件:/etc/pam.conf,默认不存在
为每种应用模块提供一个专用的配置文 件:/etc/pam.d/APP_NAME
注意:如/etc/pam.d存在,/etc/pam.conf将失效

PAM认证过程:

1.使用者执行/usr/bin/passwd 程序,并输入密码
2.passwd开始调用PAM模块,PAM模块会搜寻passwd程序的PAM相关设置文件,这个设置文件一般是在/etc/pam.d/里边的与程序同名的文件,即PAM会搜寻/etc/pam.d/passwd此设置文件
3.经由/etc/pam.d/passwd设定文件的数据,取用PAM所提供的相关模块来进行验证
4.将验证结果回传给passwd这个程序,而passwd这个程序会根据PAM回传的结果决定下一个动作(重新输入密码或者通过验证)

PAM认证文件:

通用配置文件/etc/pam.conf格式
application type control module-path arguments
专用配置文件/etc/pam.d/* 格式
type control module-path arguments
说明:
服务名(application)
telnet、login、ftp等,服务名字“OTHER”代表所有没有在该文件中明确配置的其它服务
模块类型(module-type)
control PAM库该如何处理与该服务相关的PAM模块的成功或失败情况
module-path 用来指明本模块对应的程序文件的路径名
Arguments 用来传递给该模块的参数

PAM模块类型(module-type)

Auth 账号的认证和授权
Account 与账号管理相关的非认证类的功能,如:用来限制/允许用户对某个服务的访问时间,当前有效的系统资源(最多可以有多少个用户),限制用户的位置(例如:root用户只能从控制台登录)
Password 用户修改密码时密码复杂度检查机制等功能
Session 用户获取到服务之前或使用服务完成之后需要进行一些附加的操作,如:记录打开/关闭数据的信息,监视目录等
-type 表示因为缺失而不能加载的模块将不记录到系统日志,对于那些不总是安装在系统上的模块有用

PAM参数

Control:
PAM库如何处理与该服务相关的PAM模块成功或失败情况
两种方式实现:
简单和复杂
简单方式实现:一个关健词实现
required :一票否决,表示本模块必须返回成功才能通过认证,但是如果该模块返回失败,失败结果也不会立即通知用户,而是要等到同一type中的所有模块全部执行完毕再将失败结果返回给应用程序.即为必要条件

requisite :一票否决,该模块必须返回成功才能通过认证,但是一旦该模块返回失败,将不再执行同一type内的任何模块,而是直接将控制权返回给应用程序.是一个必要条件
sufficient :一票通过,表明本模块返回成功则通过身份认证的要求,不必再执行同一type内的其它模块,但如果本模块返回失败可忽略,即为充分条件
optional :表明本模块是可选的,它的成功与否不会对身份认证起关键作用,其返回值一般被忽略
include: 调用其他的配置文件中定义的配置信息

复杂详细实现:使用一个或多个“status=action”
[status1=action1 status2=action …]
Status:检查结果的返回状态
Action:采取行为 ok,done,die,bad,ignore,reset
ok 模块通过,继续检查
done 模块通过,返回最后结果给应用
bad 结果失败,继续检查
die 结果失败,返回失败结果给应用
ignore 结果忽略,不影响最后结果
reset 忽略已经得到的结果

module-path: 模块路径
相对路径:
/lib64/security目录下的模块可使用相对路径
如:pam_shells.so、pam_limits.so
绝对路径:
模块通过读取配置文件完成用户对系统资源的使用控制
/etc/security/*.conf
注意:修改PAM配置文件将马上生效
建议:编辑pam规则时,保持至少打开一个root会话,以防止root身份验证错误
Arguments 用来传递给该模块的参数

PAM文档说明

/user/share/doc/pam-*
rpm -qd pam
man –k pam_
man 模块名 如man rootok
《The Linux-PAM System Administrators’ Guide》

PAM模块示例
模块:pam_shells

功能:检查有效shell
man pam_shells
示例:不允许使用/bin/csh的用户本地登录
vim /etc/pam.d/login
auth required pam_shells.so
vim /etc/shells
去掉 /bin/csh
useradd –s /bin/csh testuser
testuser将不可登录
tail /var/log/secure

模块:pam_securetty.so

功能:只允许root用户在/etc/securetty列出的安全终端上登陆
示例:允许root在telnet登陆
vi /etc/pam.d/remote
#auth required pam_securetty.so #将这一行加上注释

或者/etc/securetty文件中加入
pts/0,pts/1…pts/n

模块:pam_nologin.so

功能:
如果/etc/nologin文件存在,将导致非root用户不能登陆
如果用户shell是/sbin/nologin 时,当该用户登陆时,会显示/etc/nologin文件内容,并拒绝登陆

模块:pam_limits.so

功能:在用户级别实现对其可使用的资源的限制,例如:可打开的文件数量,可运行的进程数量,可用内存空间
修改限制的实现方式:
(1) ulimit命令,立即生效,但无法保存
-n 最多的打开的文件描述符个数
-u 最大用户进程数
-S 使用 soft(软)资源限制
-H 使用 hard(硬)资源限制
(2) 配置文件:/etc/security/limits.conf, /etc/security/limits.d/*.conf
配置文件:每行一个定义;

1
\<domain\>    \<type\>      \<item\>       \<value>
PAM图解

pam_limits.so

<domain>应用于哪些对象
Username 单个用户
@group 组内所有用户
* 所有用户
<type>限制的类型
Soft 软限制,普通用户自己可以修改
Hard 硬限制,由root用户设定,且通过kernel强制生效
- 二者同时限定
<item>限制的资源
nofile 所能够同时打开的最大文件数量,默认为1024
nproc 所能够同时运行的进程的最大数量,默认为1024
<value>指定具体值

pam_limits.so

限制用户最多打开的文件数和运行进程数
/etc/pam.d/system-auth
session required pam_limits.so
vim /etc/security/limits.conf
apache – nofile 10240 用户apache可打开10240个文件
student hard nproc 20 用户student不能运行超过20个进程

AIDE

AIDE简介

当一个入侵者进入了你的系统并且种植了木马,通常会想办法来隐蔽这个木马(除了木马自身的一些隐蔽特性外,他会尽量给你检查系统的过程设置障碍),通常入侵者会修改一些文件,比如管理员通常用ps -aux来查看系统进程,那么入侵者很可能用自己经过修改的ps程序来替换掉你系统上的ps程序,以使用ps命令查不到正在运行的木马程序.如果入侵者发现管理员正在运行crontab作业,也有可能替换掉crontab程序等等.所以由此可以看出对于系统文件或是关键文件的检查是很必要的.目前就系统完整性检查的工具用的比较多的有两款:Tripwire和AIDE,前者是一款商业软件,后者是一款免费的但功能也很强大的工具

AIDE(Advanced Intrusion Detection Environment)
• 高级入侵检测环境)是一个入侵检测工具,主要用途是检查文件的完整性,审计计算机上的那些文件被更改过了.
• AIDE能够构造一个指定文件的数据库,它使用aide.conf作为其配置文件.AIDE数据库能够保存文件的各种属性,包括:权限(permission)、索引节点序号(inode number)、所属用户(user)、所属用户组(group)、文件大小、最后修改时间(mtime)、创建时间(ctime)、最后访问时间(atime)、增加的大小以及连接数.AIDE还能够使用下列算法:sha1、md5、rmd160、tiger,以密文形式建立每个文件的校验码或散列号.
• 这个数据库不应该保存那些经常变动的文件信息,例如:日志文件、邮件、/proc文件系统、用户起始目录以及临时目录.

安装AIDE
1
yum install aide
修改配置文件

vim /etc/aide.conf (指定对哪些文件进行检测)
/test/chameleon R
/bin/ps R+a
/usr/bin/crontab R+a
/etc PERMS
!/etc/mtab #“!”表示忽略这个文件的检查
R=p+i+n+u+g+s+m+c+md5 权限+索引节点+链接数+用户+组+大小+最后一次修改时间+创建时间+md5校验 值
NORMAL = R+rmd60+sha256

初始化默认的AIDE的库:
1
/usr/local/bin/aide --init
生成检查数据库(建议初始数据库存放到安全的地方)

cd /var/lib/aide
mv aide.db.new.gz aide.db.gz

检测:
1
/usr/local/bin/aide --check
更新数据库
1
aide --update

sudo更改身份

su 切换身份:su –l username –c ‘command’
sudo
• 来自sudo包,man 5 sudoers
• sudo能够授权指定用户在指定主机上运行某些命令.如果未授权用户尝试使用 sudo,会提示联系管理员
• sudo可以提供日志,记录每个用户使用sudo操作
• sudo为系统管理员提供配置文件,允许系统管理员集中地管理用户的使用权限和使用的主机
• sudo使用时间戳文件来完成类似“检票”的系统,默认存活期为5分钟的“入场券”
• 通过visudo命令编辑配置文件,具有语法检查功能
visudo –c 检查语法
visudo -f /etc/sudoers.d/test

sudo

配置文件:/etc/sudoers, /etc/sudoers.d/
时间戳文件:/var/db/sudo
日志文件:/var/log/secure
配置文件支持使用通配符glob:
?:任意单一字符

* :匹配任意长度字符

[wxc]:匹配其中一个字符

[!wxc]:除了这三个字符的其它字符

\x : 转义

[[alpha]] :字母 示例: /bin/ls [[alpha]]*

配置文件规则有两类;
1、别名定义:不是必须的
2、授权规则:必须的

sudoers

授权规则格式:
用户 登入主机=(代表用户) 命令
示例:
root ALL=(ALL) ALL
格式说明:
user: 运行命令者的身份
host: 通过哪些主机
(runas):以哪个用户的身份
command: 运行哪些命令

别名

Users和runas:
username
#uid
%group_name
%#gid
user_alias|runas_alias
host:
ip或hostname
network(/netmask)
host_alias
command:
command name
directory
sudoedit
Cmnd_Alias

sudo别名和示例

别名有四种类型:User_Alias, Runas_Alias, Host_Alias ,Cmnd_Alias
别名格式:[A-Z]([A-Z][0-9]_)*

别名定义:
Alias_Type NAME1 = item1, item2, item3 : NAME2 = item4, item5

示例1:

Student ALL=(ALL) ALL
%wheel ALL=(ALL) ALL

示例2:

student ALL=(root) /sbin/pidof,/sbin/ifconfig
%wheel ALL=(ALL) NOPASSWD: ALL

示例3:

User_Alias NETADMIN= netuser1,netuser2
Cmnd_Alias NETCMD = /usr/sbin/ip
NETADMIN ALL=(root) NETCMD

示例4:

User_Alias SYSADER=mark,jack,%admins
User_Alias DISKADER=tom
Host_Alias SERS=www.google.com,172.16.0.0/24
Runas_Alias OP=root
Cmnd_Alias SYDCMD=/bin/chown,/bin/chmod
Cmnd_Alias DSKCMD=/sbin/parted,/sbin/fdisk
SYSADER SERS= SYDCMD,DSKCMD
DISKADER ALL=(OP) DSKCMD

User_Alias ADMINUSER = adminuser1,adminuser2
Cmnd_Alias ADMINCMD = /usr/sbin/useradd,/usr/sbin/usermod,
/usr/bin/passwd [a-zA-Z]*, !/usr/bin/passwd root ADMINUSER ALL=(root) NOPASSWD:ADMINCMD,
PASSWD:/usr/sbin/userdel

示例5:

Defaults:mark runas_default=tom
mark ALL=(tom,jerry) ALL

示例6:

mark 192.168.1.6,192.168.1.8=(root) /usr/sbin/,!/usr/sbin/useradd

示例7:

mark ALL=(ALL) /bin/cat /var/log/messages*

sudo命令

ls -l /usr/bin/sudo
sudo –i –u mark 切换身份
sudo [-u user] COMMAND
-V 显示版本信息等配置信息
-u user 默认为root
-l,ll 列出用户在主机上可用的和被禁止的命令
-v 再延长密码有效期限5分钟,更新时间戳
-k 清除时间戳(1970-01-01),下次需要重新输密码
-K 与-k类似,还要删除时间戳文件
-b 在后台执行指令
-p 改变询问密码的提示符号
示例:-p “password on %h for user %p:”

TCP_Wrappers

作者:Wieste Venema,IBM,Google
工作在第四层(传输层)的TCP协议
对有状态连接的特定服务进行安全检测并实现访问控制
以库文件形式实现
某进程是否接受libwrap的控制取决于发起此进程的程序在编译时是否针对libwrap进行编译的
判断服务程序是否能够由tcp_wrapper进行访问控制的方法:
ldd /PATH/TO/PROGRAM|grep libwrap.so
strings PATH/TO/PROGRAM|grep libwrap.so

TCP_Wrappers的使用

配置文件:/etc/hosts.allow, /etc/hosts.deny
帮助参考:man 5 hosts_access,man 5 hosts_options
检查顺序:hosts.allow,hosts.deny(默认允许)
注意:一旦前面规则匹配,直接生效,将不再继续
基本语法:
daemon_list@host: client_list [ :options :option… ]
Daemon_list@host格式
单个应用程序的二进制文件名,而非服务名,例如vsftpd
以逗号或空格分隔的应用程序文件名列表,如:sshd,vsftpd
ALL表示所有接受tcp_wrapper控制的服务程序
主机有多个IP,可用@hostIP来实现控制如:in.telnetd@192.168.0.254

客户端Client_list格式
以逗号或空格分隔的客户端列表
基于IP地址:192.168.10.1 192.168.1.
基于主机名:www.google.com .google.com 较少用
基于网络/掩码:192.168.0.0/255.255.255.0
基于net/prefixlen: 192.168.1.0/24(CentOS7)
基于网络组(NIS 域):@mynetwork
内置ACL:ALL,LOCAL,KNOWN,UNKNOWN,PARANOID
EXCEPT用法:
示例:
vsftpd: 172.16. EXCEPT 172.16.100.0/24 EXCEPT 172.16.100.1

[:options]选项:
帮助:man 5 hosts_options
deny 主要用在/etc/hosts.allow定义“拒绝”规则
如:vsftpd: 172.16. :deny
allow 主要用在/etc/hosts.deny定义“允许”规则
如:vsftpd:172.16. :allow
spawn 启动一个外部程序完成执行的操作
twist 实际动作是拒绝访问,使用指定的操作替换当前服务,标准I/O和ERROR发送到客户端,默认至/dev/null
测试工具:
tcpdmatch [-d] daemon[@host] client
-d 测试当前目录下的hosts.allow和hosts.deny

示例1:

只允许192.168.1.0/24的主机访问sshd

/etc/hosts.allow
sshd: 192.168.1.
/etc/hosts.deny
sshd :ALL

示例2:

只允许192.168.1.0/24的主机访问telnet和vsftpd服务

/etc/hosts.allow
vsftpd,in.telnetd: 192.168.1.
/etc/host.deny
vsftpd,in.telnetd: ALL

示例3:

sshd: ALL :spawn echo “$(date +%%F) login attempt from %c to
%s,%d” >>/var/log/sshd.log
说明:
在/etc/hosts.allow中添加,允许登录,并记录日志
在/etc/hosts.deny中添加,拒绝登录,并记录日志
%c 客户端信息
%s 服务器端信息
%d 服务名
%p 守护进程的PID
%% 表示%
vsftpd: 172.16. :twist /bin/echo “connection prohibited”