文章目录
代码参考:https://gitee.com/half-summer/cmdb.git
1.文件差异性对比
import difflib
def diff(fn1, fn2):
"""对比两个文件内容的不同并以html的格式返回"""
with open(fn1) as f1: content1 = f1.readlines()
with open(fn2) as f2: content2 = f2.readlines()
df = difflib.HtmlDiff()
return df.make_file(content1, content2)
# 这句python代码实现了什么功能?
if __name__ == '__main__':
fn1 = 'doc/passwd'
fn2 = 'doc/passwd.bak'
res = diff(fn1, fn2)
print(res)
2.CMDB自动化资产扫描项目
"""
hashlib摘要算法详情:
https://www.liaoxuefeng.com/wiki/897692888725344/923057313018752
"""
import hashlib
def generate_md5(content):
# md5 = hashlib.md5()
# md5.update(content)
md5 = hashlib.md5(content.encode('utf-8'))
return md5.hexdigest()
if __name__ == '__main__':
fn1 = 'doc/passwd'
fn2 = 'doc/passwd.bak'
with open(fn1) as f1: content1 = f1.read()
with open(fn2) as f2: content2 = f2.read()
print(generate_md5(content1))
print(generate_md5(content2))
if generate_md5(content1) == generate_md5(content2):
print("文件未被篡改")
else:
print("文件已被篡改")
#Terminal命令行执行
python 01_文件差异性对比.py > doc/result.html
任选一个网址打开,查看结果:
3.搭建项目环境
- 新建project->Django项目,选择虚拟环境:是个隔离的环境,与python无关
- 创建app
#Terminal命令行执行
python manage.py startapp cmdbhost
- 设置时区和语言
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'cmdbhost',
]
# 编辑文件 loginRegister/settings.py
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'
- 数据库表生成、创建用户
#Terminal命令行执行
python manage.py makemigrations
python manage.py migrate # 将迁移脚本的内容写入数据库并创建数据库表
python manage.py createsuperuser # 创建后台登录的超级用户和密码
- 启动开发服务器
#Terminal命令行执行
python manage.py runserver
- git
安装.ignore插件
新建.ignore文件
git init
git add *
git commit -m "cmdb"
git remote add origin 远程仓库#关联仓库
git push
git push --set-upstream origin master -f
#新建readme.cm和requirements.txt
pip freeze > requirements.txt
4.资产管理
资产管理探测流程
#cmdb/settings/__init__.py
import os
env = os.environ.get('PROJECT_ENV', 'dev')
if env == 'dev':
from .dev import *
elif env == 'prod':
from .prod import *
else:
from .dev import *
#cmdb/settings/base.py
#与settings相同
#cmdb/settings/dev.py
from .base import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
#cmdb/settings/prod.py
from .base import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'cmdb',
'USER': 'devops',
'PASSWORD': 'devopspassword',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
DEBUG = False # debug调试在生产环境一定要关闭
# ALLOWED_HOSTS = ['192.168.0.0/16'] # 允许访问服务器的客户端网段信息
ALLOWED_HOSTS = ['*'] # 允许访问服务器的客户端网段信息
#Terminal命令行执行
pip install python-nmap
python manage.py makemigrations
python manage.py migrate # 将迁移脚本的内容写入数据库并创建数据库表
#Terminal命令行执行
git add *
git commit -m "add dev and prod settings"
git push
5.Pycharm远程部署
1)安装VMware,新建虚拟机
#打开VMware,新建虚拟机server1
#打开Git bash,链接server:$ ssh root@192.168.16.129
[root@localhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# ls
CentOS-Base.repo
[root@localhost yum.repos.d]# vim CentOS-Base.repo
%s/$.../7/g
[root@localhost yum.repos.d]# yum install python3
[root@localhost ~]# yum install git -y
[root@localhost ~]# git clone https://gitee.com/half-summer/cmdb.git#git clone项目到远程主机
[root@localhost ~]# ls
anaconda-ks.cfg cmdb original-ks.cfg
6.远程代码调试
1)远程服务器安装虚拟环境
yum install python3 -y
[root@localhost ~]# pip3 install virtualenv -i https://pypi.douban.com/simple
[root@localhost ~]# virtualenv -p /usr/bin/python3 venv
[root@localhost ~]# source venv/bin/activate
[root@localhost ~]# pip install -r requirments.txt
(venv) [root@localhost ~]# ls
(venv) [root@localhost cmdb]# cd cmdb/
(venv) [root@localhost cmdb]# ls
(venv) [root@localhost cmdb]# pip install -r requirements.txt -i https://pypi.douban.com/simple
2)配置pycharm的解释器为远程服务器解释器
3)运行远程服务器项目
7.配置项目数据库为mysql
1)安装mysql
(venv) [root@localhost cmdb]# yum install mariadb-server -y
(venv) [root@localhost cmdb]# systemctl start mariadb
(venv) [root@localhost cmdb]# systemctl enable mariadb
(venv) [root@localhost cmdb]# mysql
MariaDB [(none)]> create database cmdb default charset='utf8';
MariaDB [(none)]> create user cmdb@'%' identified by "cmdb";
MariaDB [(none)]> grant all on cmdb.* to cmdb@'%';
(venv) [root@localhost cmdb]# mysql_secure_installation #MySQL安全配置向导
(venv) [root@localhost cmdb]# mysql -ucmdb -pcmdb -h192.168.63.130
(venv) [root@localhost cmdb]# yum install mariadb-devel.x86_64 -y
(venv) [root@localhost cmdb]# yum install python3-devel -y
(venv) [root@localhost cmdb]# pip3 install mysqlclient -i https://pypi.douban.com/simple
2)修改settings配置信息
3)关闭远程服务器防火墙和selinux
(venv) [root@localhost cmdb]# systemctl stop firewalld.service
(venv) [root@localhost cmdb]# systemctl disable firewalld.service
(venv) [root@localhost cmdb]# setenforce 0
4)运行并查看
#Terminal命令行执行
python manage.py makemigrations
python manage.py migrate # 将迁移脚本的内容写入数据库并创建数据库表
python manage.py createsuperuser # 创建后台登录的超级用户和密码
8.资产管理探测流程
1)主机存活探测模块和工具
扫描指定网段所有存活的主机:
- Nmap也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包。是一款用于网络发现和安全审计的网络安全工具。
-
python-nmap是一个使用nmap进行端口扫描的python库,它可以很轻易的生成nmap扫描报告,并且
可以帮助系统管理员进行自动化扫描任务和生成报告。同时,它也支持nmap脚本输出。
import nmap
def scan_active_hosts(subnet):
"""扫描指定网段所有存活的主机"""
# 实例化对象, portScanner()类用于实现对指定主机进行端口扫描
nm = nmap.PortScanner()
# 以指定方式扫描指定主机或网段的指定端口
result = nm.scan(hosts=subnet, arguments='-n -sP')
# 返回nmap扫描的主机清单,格式为列表类型
return nm.all_hosts()
if __name__ == '__main__':
hosts=scan_active_hosts('192.168.16.0/24')
print(hosts)
2)ssh端口存活扫描,扫描存活的linux主机
#虚拟机虚拟环境
(venv) [root@localhost cmdb]# yum install telnet
(venv) [root@localhost cmdb]# telnet 192.168.16.129 22
import nmap
import telnetlib
import re
def scan_active_hosts(subnet):
"""扫描指定网段所有存活的主机"""
# 实例化对象, portScanner()类用于实现对指定主机进行端口扫描
nm = nmap.PortScanner()
# 以指定方式扫描指定主机或网段的指定端口
result = nm.scan(hosts=subnet, arguments='-n -sP')
# 返回nmap扫描的主机清单,格式为列表类型
return nm.all_hosts()
def is_ssh_open(ip):
"""判断ssh的22端口是否打开"""
try:
# 实例化对象
tn = telnetlib.Telnet(host=ip, port=22, timeout=5)
# read_until读取直到遇到了换行符或超时秒数。默认返回bytes类型,通过decode方法解码为字符 串。
tn_result = tn.read_until(b"\n", timeout=5).decode('utf-8').lower()
except Exception as e: #捕获异常
tn_result = ''
return True if re.findall('ssh', tn_result) else False
if __name__ == '__main__':
hosts = scan_active_hosts('192.168.16.0/24')
print(hosts)
for host in hosts:
if is_ssh_open(host):
print(f'{host}的22端口打开')
3)python的ssh登录模块paraniko
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操
作,paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。
- 安装paramiko模块
(venv) [root@localhost cmdb]# pip install -i https://pypi.douban.com/simple paramiko==2.6.0
#安装完后需要重启pycharm才能使用
-
paramiko核心组件
paramiko包含两个核心组件:SSHClient和SFTPClient(sftp=ssh file transfer protocol)。 SSHClient的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用于执行远程命令。SFTPClient的作用类似与Linux的sftp命令,是对SFTP客户端的封装,用以实现远程文件操作,如文件上传、下载、修改文件权限等操作。 - 项目代码: 基于paramiko实现ssh客户端密码远程登录
#免密给本地主机
[root@localhost ~]# ssh-keygen
[root@localhost ~]# cd .ssh/
[root@localhost .ssh]# ls
id_rsa id_rsa.pub
[root@localhost .ssh]# ssh-copy-id -i id_rsa.pub root@localhost
[root@localhost .ssh]# ssh root@localhost#能够免密连接
Last login: Mon Mar 15 21:25:54 2021 from 192.168.16.1
[root@localhost ~]# logout
Connection to localhost closed.
[root@localhost .ssh]# ls
authorized_keys id_rsa id_rsa.pub known_hosts
[root@localhost .ssh]# cat id_rsa#查看秘钥内容,并储存在pycharm中
#scanhost/utils.py
import nmap
import telnetlib
import re
def scan_active_hosts(subnet):
"""扫描指定网段所有存活的主机"""
# 实例化对象, portScanner()类用于实现对指定主机进行端口扫描
nm = nmap.PortScanner()
# 以指定方式扫描指定主机或网段的指定端口
result = nm.scan(hosts=subnet, arguments='-n -sP')
# 返回nmap扫描的主机清单,格式为列表类型
return nm.all_hosts()
def is_ssh_open(ip):
"""判断ssh的22端口是否打开"""
try:
# 实例化对象
tn = telnetlib.Telnet(host=ip, port=22, timeout=5)
# read_until读取直到遇到了换行符或超时秒数。默认返回bytes类型,通过decode方法解码为字符 串。
tn_result = tn.read_until(b"\n", timeout=5).decode('utf-8').lower()
except Exception as e: #捕获异常
tn_result = ''
return True if re.findall('ssh', tn_result) else False
import paramiko
def login_ssh(host, user, passwd=None, pkey=None, cmd='hostname'):#passwd密码;pkey密码文件
client = paramiko.SSHClient()#实例化
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())#跳过连接询问YES
if pkey:
private = paramiko.RSAKey.from_private_key_file(pkey)
client.connect(host, 22, user, pkey=private)
if passwd:
client.connect(host, 22, user, passwd)
stdin, stdout, stderr = client.exec_command(cmd)
return stdout.read().decode('utf-8')
if __name__ == '__main__':
# hosts = scan_active_hosts('192.168.16.0/24')
# print(hosts)
# for host in hosts:
# if is_ssh_open(host):
# print(f'{host}的22端口打开')
pkey = '/root/cmdb/scanhost/id_rsa'
res = login_ssh('192.168.16.129', 'root', pkey=pkey, cmd='free -m')
print(res)
9.Django数据库模型设计
#scanhost/models.py
from django.db import models
# Create your models here.
class Server(models.Model):
"""服务器设备"""
sub_asset_type_choice = (
(0, 'PC服务器'),
(1, '刀片机'),
(2, '小型机'),
)
created_by_choice = (
('auto', '自动添加'),
('manual', '手工录入'),
)
sub_asset_type = models.SmallIntegerField(choices=sub_asset_type_choice, default=0, verbose_name="服务器类型")
created_by = models.CharField(choices=created_by_choice, max_length=32, default='auto', verbose_name="添加方式")
IP = models.CharField('IP地址', max_length=30, default='')
MAC = models.CharField('Mac地址', max_length=200, default='')
model = models.CharField(max_length=128, null=True, blank=True, verbose_name='服务器型号')
hostname = models.CharField(max_length=128, null=True, blank=True, verbose_name="主机名")
os_type = models.CharField('操作系统类型', max_length=64, blank=True, null=True)
os_distribution = models.CharField('发行商', max_length=64, blank=True, null=True)
os_release = models.CharField('操作系统版本', max_length=64, blank=True, null=True)
def __str__(self):
return '%s-%s' % (self.id, self.hostname)
class Meta:
verbose_name = '服务器'
verbose_name_plural = "服务器"
#虚拟机虚拟环境创建数据库
[root@localhost ~]# cd cmdb/
[root@localhost cmdb]# source venv/bin/activate
(venv) [root@localhost cmdb]# ls
(venv) [root@localhost cmdb]# python manage.py makemigrations
(venv) [root@localhost cmdb]# python manage.py migrate
#cmdb/settings/base.py最后添加
scanhosts = [
# '127.0.0.1',
# '172.25.254.0/24',
'192.168.16.0/24']
commands = {
'hostname': 'hostname',
'os_type': 'uname',
'os_distribution': 'dmidecode -s system-manufacturer',
'os_release': 'cat /etc/redhat-release',
'MAC': 'cat /sys/class/net/`[^vtlsb]`*/address',
}
#新建cmdb/settings/tasks.py
from cmdb.settings import *
from scanhost.utils import *
from scanhost.models import Server
# 定时任务,定时扫描
def scan_hosts():
# 访问所有要扫描的网段/IP
for host in scanhosts:
print("正在扫描%s......" %(host))
# 获取所有可以ping通的主机IP
active_hosts = scan_active_hosts(host)
# 一次遍历判断ssh服务是否开启
for active_host in active_hosts:
if is_ssh_open(active_host):
server = Server()
# 设置IP地址
server.IP = active_host
# 执行指令
for attr, command in commands.items():
# attr ='hostname' , command = 'hostname'
# 存储主机名、操作系统.....指令执行的结果
result = login_ssh(active_host, 'root', 'westos', cmd =command)
setattr(server, attr, result)
server.save()