• 第二部分用户交互程序开发,通过paramiko记录ssh会话记录


    需求及任务:实现一个给用户登录的界面(通过ssh登到堡垒机上,然后给它展现一个命令行的页面,然后他选择登哪台机器,一选择就连上去且把日志也记录下来)。

     先在admin创建几条组数据并与用户关联如下图:

    一.用户交互程序开发

       分析:等用户一连上我的堡垒机就启动我的程序,我这个程序是脚本的形式,脚本界面,跟用户交互,让它去连。

      真正交互的程序我把放在manage.py同级的bakend包下---我专放所有后端程序。

    (1)和manage.py同级目录新建crazyeye_manager.py---这是程序的入口:

      导入backend中的main模块并实例化我在main.py中自定的ArgvHandler(object)"""接收用户参数,并调用相应的功能"""的类,并且直接传入参数后此实例就自己调用相应参数--我在main.py中自定的call方法。

    import sys,os
    
    if __name__ == "__main__":
        #让脚本能访问django数据库环境需要如下三条命令:
        ##设置环境变量
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "s3CrazyEye.settings")
        #把django相关联的app都加载一遍
        import django
        django.setup()
    
    
        from  backend import main  #导入
        interactive_obj = main.ArgvHandler(sys.argv)#交互程序可能需要很多参数
        interactive_obj.call() #调用call方法

    (2)backend/main.py:

      argvhandler类(接收用户参数,并调用相应的功能)--只负责处理/调用参数即它只是一个入口

        help_msg方法(打印帮助):列出可用功能如提示run方法就是启动用户交互程序

        call方法(根据用户参数,调用对应的方法)

        run方法(启动用户交互程序)

    class ArgvHandler(object):
        """接收用户参数,并调用相应的功能"""
        def __init__(self,sys_args):#初始化类
            self.sys_args = sys_args  #给类传sys_args参数
        def help_msg(self,error_msg=''):
            """打印帮助"""
            msgs = """
            %s
            run    此方法启动用户交互程序
            """ % error_msg
    
            exit(msgs)
        def call(self):
            """根据用户参数,调用对应的方法"""
            if len(self.sys_args) == 1:  #如果等于1则代表什么也没输
                self.help_msg()
            #让call法后面跟的第一个参数就是run函数名
            if hasattr(self,self.sys_args[1]):#如果类参数中有run方法则拿到此方法并调用执行它(1就是方法,因为0是此脚本本身)
                func = getattr(self,self.sys_args[1])
                func()
            else:
                self.help_msg("没有方法:%s"% self.sys_args[1])
    
    
        def run(self):
            """启动用户交互程序"""
            from  backend.ssh_interactive import SshHandler
            obj = SshHandler(self)  #把自己传给这个类方法
            obj.interactive()  #启动交互脚本

     (3)backend/ssh_interactive.py:--启动堡垒机交互脚本

      它需要有办法拿到main.py中argvhandler类中的参数(但它俩是完全不同的一种类,没法继承),

    所以把argv_handler类实例传给它即可。

      auth方法(认证程序):

      interactive方法(启动交互脚本):一进来打印他可以访问的组,他一选择组就把组里列出来他能访问哪些机器,

    from django.contrib.auth import authenticate  #导入djnago的认证模块
    from web import models
    class SshHandler(object):
        """堡垒机交互脚本"""
        #初始化,并把argv_handler类实例传给它
        def __init__(self,argv_handler_instance):
            self.argv_handler_instance = argv_handler_instance
            # self.models = models
    
        def auth(self):
            """认证程序"""
            count = 0
            while count < 3:#输三次
                username = input("堡垒机账号:").strip()
                password = input("Password:").strip()
                user = authenticate(username=username,password=password) #拿到数据库中认证信息
                if user:#有这个用户则认证成功
                    self.user = user  #把这个认证成功的用户存到实例中,因为后面要用
                    return True
                else:#否则
                    count +=1
    
        def interactive(self):
            """启动交互脚本"""
            if self.auth():#先登录--返回的是true,则认证成功
                print("Ready to print all the authorized hosts...to this user ...")
                while True:#大循环让用户去选择主机组
                    host_group_list = self.user.host_groups.all()#拿到当前用户关联的所有主机组
                    #列出来:左边打印组右边打印所关联的主机
                    for index,host_group_obj in enumerate(host_group_list):
                        print("%s.	%s[%s]"%(index,host_group_obj.name, host_group_obj.host_to_remote_users.count()))
                    print("z.	未分组主机[%s]" % (self.user.host_to_remote_users.count()))
    
                    choice = input("请选择主机组>>:").strip()
                    if choice.isdigit():#判断是数字
                        choice = int(choice)
                        #取出组中所有主机
                        selected_host_group  = host_group_list[choice]
                    elif choice == 'z':#选择z则打印未分组的
                        selected_host_group = self.user
    
                    while True:#选出组中主机并把未分组的他选的主机加到他选的组中
                        for index,host_to_user_obj in enumerate(selected_host_group.host_to_remote_users.all()):
                            print("%s.	%s" % (index, host_to_user_obj))
    
                        choice = input("请选择主机>>:").strip()
                        if choice.isdigit():
                            choice = int(choice)
                            selected_host_to_user_obj = selected_host_group.host_to_remote_users.all()[choice]
                            print("going to logon  %s" % selected_host_to_user_obj )
    
                        if choice == "b":  #如果选择b则回到上一级
                            break  

    .如下图执行程序:若报错

      

       会报如下错:说请求的settigs中的认证后端,但是settings中没有配置

      

      因为之前是一直在django的环境中去调数据库,但现在相当脱离了django环境,自己写了个脚本调它,而django的数据库不是想调就能调---必须配置好相应环境才能允许你调,所以在脚本中要加三条命令:配置环境变量以及加载django所有的app

    4.最终如下图:执行程序会出现如下图效果了

     二.通过paramiko记录ssh会话记录

    root@ubuntu:~# pip install paramiko -i https://pypi.douban.com/simple     --安装 paramiko模块

    1

    2

  • 相关阅读:
    tcp/ip的通俗讲述(转)
    linux中的read_link
    浅拷贝和深拷贝
    JAVA的动态代理Jdk实现方式
    友元函数
    孤儿进程、僵尸进程
    waitpid()函数
    wait()函数
    dup2函数
    exec族函数
  • 原文地址:https://www.cnblogs.com/dbslinux/p/12848810.html
Copyright © 2020-2023  润新知