项目实战: CMDB自动化资产扫描——3、视图层、前端及路由整合

news/2024/11/19 21:30:07/

资产管理探测流程

在这里插入图片描述

  • 存活探测: 获取局域网内存活的IP列表
  • 主机探测: 获取系统版本(SN、版本、MAC地址)
  • 主机关系探测: 识别宿主主机和虚拟机的关系
    在这里插入图片描述

1、主机存货探测模块视图层的实现

Nmap探测工具

Nmap,也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包。是一款用于网络发现和安
全审计的网络安全工具。

  • 主机发现 - 识别网络上的主机。例如,列出响应TCP和/或ICMP请求或打开特定端口的主机。
nmap -n -sP 172.25.254.197
nmap -n -sP 172.25.254.0/24
  • 端口扫描 - 枚举目标主机上的开放端口。
# Nmap默认端口的扫描范围1-10000
nmap -n -p 172.25.254.197
# 具体指定要扫描的端口为50-80
nmap -n -p50-80 172.25.254.197
# 具体指定要扫描的端口为22和80
nmap -n -p22,80 172.25.254.197
  • 版本检测 - 询问远程设备上的网络服务以确定应用程序名称和版本号。
  • OS检测 - 确定网络设备的操作系统和硬件特性。
nmap -O 172.25.254.197
  • 可与脚本进行脚本交互 - 使用Nmap脚本引擎(NSE)和Lua编程语言。
    查看172.25.254.197这台主机是否开启?
    在这里插入图片描述
    查看172.25.254.0/24局域网内存活的主机信息及存活主机个数
    在这里插入图片描述

Nmap的Python操作接口: python-nmap

python-nmap是一个使用nmap进行端口扫描的python库,它可以很轻易的生成nmap扫描报告,并且
可以帮助系统管理员进行自动化扫描任务和生成报告。同时,它也支持nmap脚本输出。

  • 安装nmap的第三方模块
pip3 install python-nmap
  • 视图层的实现
    代码全部卸载views.py过于冗余,这里新建utils.py代码用于存放调用
#utils.py
import nmapdef get_active_hosts(host='172.25.254.250'):# 实例化对象, portScanner()类用于实现对指定主机进行端口扫描nm = nmap.PortScanner()# 以指定方式扫描指定主机或网段的指定端口result = nm.scan(hosts=host, arguments='-n -sP')# print("扫描结果: ", result)# 返回的扫描具体的nmap命令行# print("nmap命令行: ", nm.command_line())# 返回nmap扫描的主机清单,格式为列表类型# print("主机清单: ", nm.all_hosts())return nm.all_hosts()
##测试:
if __name__ == '__main__':get_active_hosts()

代码执行效果如下图所示:
在这里插入图片描述
主机存活探测模块完成

2、SSH端口存活扫描基础和实现

  • 使用telnet命令探测主机列表是否属于Linux服务器
  • telnet命令探测
telnet 172.25.254.197 22

在这里插入图片描述

SSH端口存货python实现:telnetlib模块

telnetlib模块提供的Telnet类实现了Telnet协议。
#utils.py补充

import telnetlib
import re
def get_active_hosts(host='172.25.254.250'):#省略代码def is_ssh_up(host='172.25.254.250', port=22, timeout=5):try:# 实例化对象tn = telnetlib.Telnet(host=host, port=port, timeout=timeout)# read_until读取直到遇到了换行符或超时秒数。默认返回bytes类型,通过decode方法解码为字符串。tn_result = tn.read_until(b"\n", timeout=timeout).decode('utf-8')# 通过正则匹配且忽略大小写, 寻找是否ssh服务开启。ssh_result = re.search(pattern=r'ssh', string=tn_result, flags=re.I)except Exception as e:print("%s ssh is down, Beacuse %s" % (host, str(e)))return Falseelse:# 如果能匹配到内容, 说明ssh服务开启, 是Linux服务器.return True if ssh_result else False
#测试
if __name__ == '__main__':# get_active_hosts()print(is_ssh_up(host='172.25.254.100'))

3、主机登录探测

  • 用一系列的验证方式循环进行SSH登录, 得到争取的登录方式。
  • 主机SSH登录验证方式
    SSH常用来远程登录到远程机器,有两种常用的方法:
    第一种便是账号密码登录。
    第二种就是公钥私钥无密码登录。(如何实现无密码登录?)

SSH登录模块Python实现:paramiko

  • 安装paramiko
    pip install -i https://pypi.douban.com/simple paramiko==2.6.0
  • paramiko核心组件
    SSHClient和SFTPClient(sftp=ssh file transfer protocol)。
    SSHClient的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输
    (Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用于执行远程命令。
    SFTPClient的作用类似与Linux的sftp命令,是对SFTP客户端的封装,用以实现远程文件操
    作,如文件上传、下载、修改文件权限等操作。

第一种:基于paramiko实现ssh客户端密码远程登录

代码实现:

import paramiko
def login_ssh_passwd(hostname='172.25.254.197', port=22,username='root', password='westos', command='df -h'):# 实例化SSHClientwith paramiko.SSHClient() as client:# 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不再本地know_hosts文件中记录的主机将无法连接client.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 连接SSH服务端,以用户名和密码进行认证client.connect(hostname=hostname, port=port, username=username,password=password)# 打开一个Channel并执行命令。 stdout 为正确输出,stderr为错误输出,同时是有1个变量有值stdin, stdout, stderr = client.exec_command(command)# 打印执行结果print(stdout.read().decode('utf-8'))
if __name__ == '__main__':login_ssh_passwd(hostname='127.0.0.1', command='hostname')

第二种: 基于paramiko实现ssh客户端密钥远程登录(推荐)
测试之前生成公钥和私钥进行测试:

# 生成公钥和私钥, 默认存储在 ~/.ssh/目录下. id_rsa私钥, id_rsa.pub公钥
ssh-keygen
#生成的若不是有效的RSA密钥文件。则用命令ssh-keygen -m PEM -t rsa代替
# 希望我的主机可以无密码连接其他主机(需要将公钥分发给其他主机)
ssh-copy-id -i ~/.ssh/id_rsa.pub user@ip
# 测试无密码连接是否成功
ssh user@ip
ssh -i 私钥位置 user@ip

测试成功后将生成的私钥id_rsa复制到项目中备用
代码实现:

#utils.py
def login_ssh_key(hostname='172.25.254.250', port=22, username='root',private_key='doc/id_rsa', command='df -h'):# 0. 读取私钥文件pkey = paramiko.RSAKey.from_private_key_file(private_key)# 1. 实例化client = paramiko.SSHClient()# 5.自动应答client.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 2. 连接client.connect(hostname, port, username, pkey=pkey)# 3.执行命令stdin, stdout, stderr = client.exec_command(command)# 4. 输出staout结果return stdout.read().decode('utf-8')
#测试
if __name__ == '__main__':print(login_ssh_key())

运行效果如下:
在这里插入图片描述

整合三步代码,至此完成utils.py

补充:STFClient实战代码:实现上传和下载文件
SFTPCLient作为一个sftp的客户端对象,根据ssh传输协议的sftp会话,实现远程文件操作,如上
传、下载、权限、状态。

def paramiko_sftp(hostname='localhost',port=22,username='root',password='lee',localpath="/etc/passwd",remotepath="/mnt/passwd"):#获取Transport实例with paramiko.Transport(hostname,port) as tran:#连接SSH服务端,使用password,也可以用私钥连接tran.connect(username=username,password=password)##获取SFTP实例sftp = paramiko.SFTPClient.from_transport(tran)#执行上传动作sftp.put(localpath,remotepath)#执行下载动作#sftp.get(remotepath,localpath)print('file upload success')

4. 视图函数实现上述功能的整合并实现scanhost扫描

#views.py

需求:
1. 用户访问http://ip/hostscan/返回一个html页面
表单填写的是需要扫描的主机IP或者网段,用逗号分隔开
2. 用户填写好网段/IP之后,将填写的信息提交给服务器路由处理(/hostscan/)
POST方法;

from django.shortcuts import render
from django.http import HttpResponse
from hostinfo.models import Server
from hostinfo.utils import get_active_hosts, is_ssh_up, login_ssh_key  ##把utils.py中的方法引入
from CMDB.settings import commands# Create your views here.def hostscan(request):# print(request.method)if request.method == 'POST':# POST方法获取网页传来的scanhosts['172.25.254.250', '172.25.34.0/24']# print(request.POST)#得到scanhosts并以,号分割scanhosts = request.POST.get('scanhosts').split(',')servers = []for scanhost in scanhosts:print("正在扫描%s......" % (scanhost))# 获取所有可以ping通的主机IPactive_hosts = get_active_hosts(scanhost)for host in active_hosts:#获取ssh端口开通的主机if is_ssh_up(host):# Instance Server(ORM)===> MySQL# If ip exists ,How to manage?server = Server()server.IP = host#command是个字典,在第6部分setting中定义"""for command_name, command in commands.items():# 登录主机result = login_ssh_key(hostname=host, command=command)# 获取属性值setattr(server, command_name, result)# 保存到数据库server.save()# 保存到servers用于指向第5部分html文件servers.append(server)return render(request, "hostscan.html", {'servers': servers})return render(request, 'hostscan.html')

5. html前端页面配置hostscan.html

hostscan.html存放在项目templates文件夹

<!DOCTYPE html>
<html>
<head><title>Scan Host</title><meta name="viewport" content="width=device-width, initial-scale=1.0"><!-- 引入 Bootstrap --><!-- 新 Bootstrap 核心 CSS 文件 --><link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"><!-- HTML5 Shiv 和 Respond.js 用于让 IE8 支持 HTML5元素和媒体查询 -->
</head>
<body>
<nav class="navbar navbar-inverse" role="navigation"><div class="container-fluid"><div class="navbar-header"><a class="navbar-brand" href="/">CMDB</a></div><div><ul class="nav navbar-nav"><li class="active"><a href="/hostscan/">Scanhost</a></li></ul></div></div>
</nav>
<div class="container"><div class="row"><div class="col-sm-6 col-sm-offset-3"><h1>Scan Host</h1><form action="/hostscan/" method="post">{% csrf_token %}<input type="text" name="scanhosts"width="800px"placeholder="eg:172.25.254.0/24,192.168.0.0/24"><input type="submit" value="submit"></form><br/>#处理第5部分的传来的参数{% if servers %}<table class="table table-striped table-hover"><tr><td>ID</td><td>IP</td><td>hostname</td><td>os_distribution</td></tr>{% for server in servers %}<tr><td>{{ server.id }}</td><td>{{ server.IP }}</td><td>{{ server.hostname }}</td><td>{{ server.os_distribution }}</td></tr>{% endfor %}</table>{% endif %}</div></div>
</div>
<!-- jQuery (Bootstrap 的 JavaScript 插件需要引入 jQuery) -->
<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
</body>
</html>

6.配置文件配置setting.py

# devops\settings\base.py
scanhosts = [# '127.0.0.1',# '172.25.254.0/24','47.92.255.98']
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',
}

6. 路由配置urls.py

主路由
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('', include('hostinfo.urls')),
]
APP路由
from django.urls import path
from hostinfo import viewsurlpatterns = [path('hostscan/', views.hostscan, name='hostscan'),  ##这里指向的即view文件中定义的方法path('', views.hostscan, name='hostscan'),  ##输入ip即可浏览
]

测试:运行项目python manage.py runserver 0.0.0.0:8000

  • 访问网址http://ip:port/scan
  • 访问网址http://ip:port/admin
    在这里插入图片描述
    在这里插入图片描述

http://www.ppmy.cn/news/379450.html

相关文章

2、前端总线FSB和南桥与北桥

什么叫前端总线&#xff1a;FSB 前端总线——Front Side Bus&#xff08;FSB&#xff09;&#xff0c;是将CPU连接到北桥芯片的总线。选购主板和CPU时&#xff0c;要注意两者搭配问题&#xff0c;一般来说&#xff0c;前端总线是由CPU决定的&#xff0c;如果主板不支持CPU所需要…

【附源码】计算机毕业设计SSM码码科技公司招投标管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

什么是前端总线,后端总线,内部总线、系统总线,外部总线,地址总线,数据总线,控制总线

文章 部分内容来自于 电子发烧友 内部总线、系统总线和外部总线汇总 部分内容来自于 知乎 前端总线&#xff0c;系统总线&#xff0c;内部总线&#xff0c;外部总线 本文是在两篇文章的基础上进行了二次加工&#xff0c;对两篇文章的精华内容进行了提炼&#xff0c;删掉了对理解…

计算机毕业设计JAVA旧物置换网站mybatis+源码+调试部署+系统+数据库+lw

计算机毕业设计JAVA旧物置换网站mybatis源码调试部署系统数据库lw 计算机毕业设计JAVA旧物置换网站mybatis源码调试部署系统数据库lw 本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;idea eclipse 前端技术&…

设计用户模块的schema

schema 在计算机科学中&#xff0c;schema通常指的是 数据结构的定义和约束。 关系型数据库 在关系型数据库中&#xff0c;schema指的是数据库中所有表格的定义和表格之间的关系约束&#xff0c;包括每个表格的列名、数据类型、主键、外键等等。 如果要对一个关系型数据库进行…

前后端如何进行数据传输问题(结合电商后台管理系统具体代码)

v-bind和v-model 和 :model 和&#xff1a;参数如何调用后端接口使用axios获取数据El渲染表格数据添加商品的数据问题搜索框按照输入搜索功能添加用户&#xff08;商品问题&#xff09;弹窗的使用 使用作用域插槽渲染dialog1、分配权限操作——dialog的内容的渲染(作用域插层sc…

Flink面试题二十道

问题 1&#xff1a;什么是Apache Flink&#xff1f; 答案&#xff1a;Apache Flink是一个开源的流处理和批处理框架&#xff0c;它提供了高吞吐量、低延迟和容错性等特性。Flink支持事件驱动的流处理和批处理&#xff0c;可以处理有界和无界的数据集&#xff0c;并具有灵活的编…

微信小程序开发中用自己的appid,发布时用公司appid的可行吗?

可以。 小程序文件project.config.json 修改对应的 appid:xxxxxxxx’即可&#xff1b; uniapp在manifest.json的微信小程序配置中修改对应的appid即可&#xff1b; 前期开发可用测试号&#xff1a;也可以用测试号&#xff1a;https://developers.weixin.qq.com/sandbox 参考&…