文章目录
一、项目介绍
1.项目介绍
本项目基于Django实现后台管理,nmap 识别网络上的主机、使用telnet命令探测主机SSH端口存活扫描、使用paramiko对远程服务器进行命令或文件操作。最终实现Web形式的自动化资产扫描系统,可以通过IP来扫描到所对应主机的详细信息。项目基于HTTP实现自动化任务接受和响应接口设计,基于MySQL用作的关系型数据存取。本次项目实战就是用最短的时间、手把手地完成运维开发系统的开发实战。
二、项目环境搭建
- 创建Django项目devops,查看本地django版本,远程服务器的虚拟环境django版本也需要为2.2
连接并配置远程服务器
- 连接并配置远程服务器 [Tools] -> [Deployment]
- 配置本地目录和远程服务器目录的映射(Mapping), 上述操作完成, 本地文件修改, 远程服务器文件也同时修改.
远程服务器虚拟环境的配置
- 连接远程服务器命令行bash
- 创建虚拟环境并激活虚拟环境
- `cd /data/www/devops
- virtualenv -p /usr/bin/python3 env
遇到的问题:换了一个云服务器后,虚拟环境没有安装,因此需要先pip3 install virtualenv- source env/bin/active
- pip install django==2.2 -i https://pypi.douban.com/simple` 安装虚拟环境需要的django
远程服务器解释器和目录映射的配置
- 项目在远程创建,因此本地虚拟环境应该修改为远程python虚拟环境 settings中设置
- 虚拟环境使用项目下的虚拟环境
- 上传项目:把本地项目和远程服务器关联
三、MySQL数据库配置
- 远程服务器虚拟环境下安装数据库:
- 用户授权:让任意主机的指定用户可以访问
- ` create database if not exists devopsProject default charset utf8;
- MariaDB [(none)]> create user devops@’%’ identified by ‘123’;
- MariaDB [(none)]> grant all on devpsProject.* to devops@’%’;
- 测试:mysql -udevops -p123`
- 测试用户授权是否成功
- 遇到的问题:阿里云 数据库无法登录
- 报错信息:Access denied for user ‘root’@‘localhost’ (using password: YES)
- 1)修改密码 mysql–> use mysql; --> update user set authentication_string=password(‘新密码’) where user=‘root’;—>flush privilage;(不建议使用)
- 2)阿里云安全组对于mysql端口3306的设置
- 3) 终端关闭防火墙
- 经过分析最终解决方法:
解决方法:本次的问题呢,mysql 可以登录,但是mysql -uroot -p123不能登录 说明是一开始安装mysql设置密码的问题,默认情况下-h不指定是连接本机的数据库,如果连接远程主机数据库要通过-hIP指定;
mysql设置密码:mysql_secure_installation来初始化设置密码。修改密码才能进入mysql数据库中设置。
Django数据库配置
- 修改配置文件的信息:Settings 数据库设置为mysql 、中文汉字时区的设置
注意:settings中allowhost中必须加入外网ip 47.92.233.236,或者直接ALLOWED_HOSTS = [’*’]
- 中文汉字时区的设置:
LANGUAGE_CODE = 'zh-hans' TIME_ZONE = 'Asia/Shanghai'
- 生成数据库表
操作中遇到的问题:django2.2/mysql ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3
报错环境 python=3.6,django=2.2,PyMySQL=0.9.3原因分析: Django连接MySQL时默认使用MySQLdb驱动,但MySQLdb不支持Python3,因此这里将MySQL驱动设置为pymysql,:django2.2和pymysql版本不匹配。使用 pip install pymysql 进行安装,然后在工程文件__init__.py添加以下代码即可。
具体做法:
#init.py
import pymysql
pymysql.install_as_MySQLdb()
django降到2.1.4版本就OK了
- 测试数据表是否创建?数据信息是否写入?
连接mariadb数据库> 配置数据库信息
- 访问数据库表和数据内容
初次运行项目:查看后台管理页面
django后台创建超级用户
python manage.py createsuperuser
一切都设置好后,运行项目进入django后台:
-
python manage.py runserver 0.0.0.0:8000
问题:网页输入外网ip:8000无法访问是因为公网ip的安全组端口没有设置8000
页面展示:
四、Django工程多配置文件
- base.py文件: 基本的配置文件,将原先seetings.py文件的内容拷贝进来
- development.py文件: 开发环境的配置文件
from .base import *
DEBUG = True- production.py文件: 生产环境的配置文件
from .base import *
# 开发环境一定要关闭调试模式
DEBUG = False
# 允许所有主机访问
ALLOWED_HOSTS = [’*’]- 修改manage.py文件, 默认寻找的设置文件是当前项目中的settings文件, 如果是开发环境, 修改如下:
def main():
os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’,
'devops.settings.development’)
#…此处省略代码
if name == ‘main’:
main()- 如果项目将来需要上线, 修改启动项目访问的配置文件为生产环境的配置文件即可, 如下:
def main():
os.environ.setdefault(‘DJANGO_SETTINGS_MODULE’,
‘devops.settings.production’)
# …此处省略代码
if name == ‘main’:
main()- 启动项目的后台展示
五、Django工程应用与模块加载
为了方便在一个大的Django项目中,管理实现不同的业务功能, 我们会在项目中创建多个APP实现功能。为了更加方便管理APP, 项目结构更加清晰。可以专门创建apps目录存储项目应用, 专门创建extra_apps存储项目第三方APP, 项目结构如下所示:
- 但项目运行时, 不会自动寻找apps和extra_apps子目录中创建的APP, 创建子应用方法如下:
远程服务器创建好后download到本地
鼠标先选择要从远程服务器下载的文件,tools的development中选择download from devops 就可以啦
- 子应用的加载
base下:
六、主机存活探测模块和工具
Nmap探测工具
Nmap,也就是Network Mapper,最早是Linux下的网络扫描和嗅探工具包。是一款用于网络发现和安全审计的网络安全工具。
功能:
- 主机发现 - 识别网络上的主机。例如,列出响应TCP和/或ICMP请求或打开特定端口的主机。
nmap -n -sP 172.25.254.197 扫描某一个IP是否存活
nmap -n -sP 172.25.254.0/24 扫描某一个局域网下哪些主机存活
- 端口扫描 - 枚举目标主机上的开放端口。(不常用)
$ 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检测 - 确定网络设备的操作系统和硬件特性。
# -O是检测操作系统交换机
$ nmap -O 172.25.254.197
Nmap的Python操作接口: python-nmap
python-nmap是一个使用nmap进行端口扫描的python库,它可以很轻易的生成nmap扫描报告,并且可以帮助系统管理员进行自动化扫描任务和生成报告。同时,它也支持nmap脚本输出。
- 具体的代码调用如下:
import nmap
# 实例化对象, portScanner()类用于实现对指定主机进行端口扫描
nm = nmap.PortScanner()
# 以指定方式扫描指定主机或网段的指定端口
result = nm.scan(hosts='172.25.254.0/24', arguments='-n -sP')
print("扫描结果: ", result)
# 返回的扫描具体的nmap命令行
print("nmap命令行: ", nm.command_line())
# 返回nmap扫描的主机清单,格式为列表类型
print("主机清单: ", nm.all_hosts())
# 查看指定主机信息
print('172.25.254.197的主机信息: ', nm['172.25.254.197'])
代码执行效果如下图所示:
扫描结果:
{'nmap': {'command_line': 'nmap -oX - -n -sP 172.25.254.0/24', 'scaninfo': {},
'scanstats': {'timestr': 'Wed Dec 25 16:14:47 2019', 'elapsed': '6.06',
'uphosts': '2', 'downhosts': '254', 'totalhosts': '256'}}, 'scan':
{'172.25.254.197': {'hostnames': [{'name': '', 'type': ''}], 'addresses':
{'ipv4': '172.25.254.197'}, 'vendor': {}, 'status': {'state': 'up', 'reason':
'syn-ack'}}, '172.25.254.250': {'hostnames': [{'name': '', 'type': ''}],
'addresses': {'ipv4': '172.25.254.250'}, 'vendor': {}, 'status': {'state': 'up',
'reason': 'syn-ack'}}}}
nmap命令行: nmap -oX - -n -sP 172.25.254.0/24
主机清单: ['172.25.254.197', '172.25.254.250']
172.25.254.197的主机信息:
{'hostnames': [{'name': '', 'type': ''}], 'addresses': {'ipv4':
'172.25.254.197'}, 'vendor': {}, 'status': {'state': 'up', 'reason': 'syn-ack'}}
操作中的报错总结:
一、
- 云服务器虚拟环境下:pip install python-nmap 报错:
- 报错信息: pip: command not found…
- 解决方法:
$ wget https://bootstrap.pypa.io/get-pip.py
$ python get-pip.py
二、
云服务器虚拟环境下:pip install python-nmap
之后pycharm文件中import nmap
无法导入时:查看解释器环境是否正确
七、SSH端口存活扫描
使用telnet命令探测主机列表是否属于Linux服务器。
- telnetlib模块探测 telnetlib模块提供的Telnet类实现了Telnet协议。
telnetlib模块提供的Telnet类实现了Telnet协议。
import telnetlib
import re
# 实例化对象
tn = telnetlib.Telnet(host='172.25.254.197', port=22, timeout=5)
# read_until读取直到遇到了换行符或超时秒数。默认返回bytes类型,通过decode方法解码为字符
串。
tn_result = tn.read_until(b"\n", timeout=5).decode('utf-8')
# 通过正则匹配且忽略大小写, 寻找是否ssh服务开启。
ssh_result = re.search(pattern=r'ssh', string=tn_result, flags=re.I)
# 如果能匹配到内容, 说明ssh服务开启, 是Linux服务器.
if ssh_result:
print("Linux服务器存活")
else:
print("其他服务器存活")
代码执行结果如下:
Linux服务器存活
扫描探测小结
八、Python的SSH登录模块paramiko
-
什么是主机登录探测?
用一系列的验证方式循环进行SSH登录, 得到争取的登录方式。 -
主机SSH登录验证方式
SSH常用来远程登录到远程机器,有两种常用的方法:
第一种便是账号密码登录。
第二种就是公钥私钥无密码登录。(如何实现无密码登录?) -
什么是paramiko?
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接。 -
如何安装paramiko?
# 使用豆瓣的镜像源, 安装paramiko模块并指定安装版本为2.6.0.
$ pip install -i https://pypi.douban.com/simple paramiko==2.6.0
-
paramiko核心组件
paramiko包含两个核心组件:SSHClient和SFTPClient。
SSHClient的作用类似于Linux的ssh命令,是对SSH会话的封装,该类封装了传输(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通常用于执行远程命令。
SFTPClient的作用类似与Linux的sftp命令,是对SFTP客户端的封装,用以实现远程文件操作,如文件上传、下载、修改文件权限等操作。 -
项目代码: 基于paramiko实现ssh客户端密钥远程登录
- 客户端连接服务端公钥私钥:
- 测试之前生成公钥和私钥进行测试 :
- 本次测试将公钥分发给本机的root用户,
ssh-copy-id -i ~/.ssh/id_rsa.pub root@localhost
分发公钥时需要输入密码,此密码为root用户可以登录本机的密码,也就是root可以登录47.92.233.236的密码;- 测试:
[root@docker .ssh]# ssh root@localhost
可以实现无密码登录
pyhon代码实现公钥和私钥的无密码连接 :
def login_ssh_key( hostname='172.25.254.197', keyfile='./id_rsa',
username='root', port=22, command='df -h'):
"""
基于paramiko实现ssh的自动化密钥管理
"""
# 配置私人密钥文件位置
private = paramiko.RSAKey.from_private_key_file(keyfile)
# 实例化SSHClient
with paramiko.SSHClient() as client:
# 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不再本地
know_hosts文件中记录的主机将无法连接
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接SSH服务端,以用户名和密码进行认证
client.connect(hostname=hostname, port=port, username=username,
pkey=private)
# 打开一个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')
login_ssh_key(hostname='127.0.0.1', command='hostname')
运行结果:foundation0.ilt.example.com
九、系统信息获取
- 通过系统获取哪些信息
- 获取信息的Linux命令介绍
获取主机名的命令(选择通用方式): hostname、uname -a、cat /etc/sysconfig/network(主 要针对Centos)
获取系统版本: cat /etc/issue(可能为空)、cat /etc/redhat-release、uname、 lsb_release
获取MAC地址: cat /sys/class/net/ [^vtlsb] */address、ifconfig ens33
获取服务器硬件机型: dmidecode -s system-manufacturer、dmidecode -s systemproduct-name
十、项目的大体规划
前面说了这么多,现在就真正进入布局阶段了,Django数据库模型设计、配置文件设置、视图函数、路由配置、后台admin管理请看代码链接:Django_CMDB_code
- 最后的测试阶段:运行项目
python manage.py runserver 0.0.0.0:8000
- 访问网址http://ip:port/scan 查看扫描结果
- 访问网址http://ip:port/admin 查看后台管理
- 测试遇到的疑惑:
- 在云服务器下的虚拟环境中输入 python manage.py runserver 0.0.0.0:8000可以访问,只输入python manage.py runserver浏览器页面无法访问原因:
- 目前8000端口只和127.0.0.1这个IP绑定,只能通过127.0.0.1:8000在浏览器访问,用其他的ip:8000访问是失败的,因为其他ip与8000端口没有关联起来;因此用公网IP:port访问浏览器不可能成功
- 而0.0.0.0:8000的意思:如果希望通过任意一个IP访问8000端口,每一台主机都会有多个IP,让8000端口和当前主机的任意一个IP(0.0.0.0)绑定在一起, 包含公网IP,因此公网IP:8000才可以从浏览器访问。
- 本机测试不指定 生产环境需要指定为0.0.0.0