zoukankan      html  css  js  c++  java
  • 来一个堡垒机

    第十三章   堡垒机

      1.堡垒机的概念

     2.堡垒机的实现

    概念:

       背景,公司为了主机系统的管理和安全,更有效的工作,产生的一种工作模式,往往一个公司有很多台服务器,这些服务器又有许多人需要去操作,运维、开发、测试等。人多

    手杂,谁操作了什么,导致了什么问题,用户的管理。主机的管理,都需要高效的实现,堡垒机实现了这些管理上的方便。

      直接说事

    堡垒机执行流程:

    1、管理员为用户在服务器上创建帐号(将公钥放置服务器,或者使用用户名密码)

    2、用户登录堡垒机,输入堡垒机用户名密码,现实当前用户管理的服务器列表

    3、用户选择服务器,并自动登录

    4、执行操作并同时将用户操作记录 

     注:配置.brashrc实现ssh登录后自动执行脚本,如:/usr/bin/python /home/wulaoer/menu.py

    实现过程

    步骤一,使用用户登录

     1 #!/usr/bin/env  python
     2 # --*--coding:utf-8 --*--
     3 import getpass
     4 
     5 user = raw_input('username:')
     6 pwd = getpass.getpass('password:')
     7 if user == 'wulaoer' and pwd == '123':
     8     print '登陆成功'
     9 else:
    10     print '登陆失败'

     步骤二,根据用户获取相关服务器列表

     1 dic = {
     2     'laowu': [
     3         '172.16.103.189',
     4         'c10.puppet.com',
     5         'c11.puppet.com',
     6     ],
     7     'wu': [
     8         'c100.puppet.com',
     9     ]
    10 }
    11 
    12 host_list = dic['laowu']
    13 #用户可以连接的主机IP
    14 print 'please select:'
    15 for index, item in enumerate(host_list, 1):
    16     print index, item
    17 #循环可以连接的主机
    18 inp = raw_input('your select (No):')#选择要连接的IP
    19 inp = int(inp)
    20 hostname = host_list[inp-1]#连接的主机IP
    21 port = 22

     步骤三,根据用户名、私钥登录服务器

     1 tran = paramiko.Transport((hostname, port,))
     2 #连接服务器的端口和IP
     3 tran.start_client()
     4 default_path = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
     5 #连接方式,使用密钥
     6 key = paramiko.RSAKey.from_private_key_file(default_path)
     7 #密钥默认路径
     8 tran.auth_publickey('wulaoer', key)
     9 #连接用户名和密钥
    10  
    11 # 打开一个通道
    12 chan = tran.open_session()
    13 # 获取一个终端
    14 chan.get_pty()
    15 # 激活器
    16 chan.invoke_shell()
    17  
    18 #########
    19 # 利用sys.stdin,肆意妄为执行操作
    20 # 用户在终端输入内容,并将内容发送至远程服务器
    21 # 远程服务器执行命令,并将结果返回
    22 # 用户终端显示内容
    23 #########

    用户监控日志:

     1 while True:
     2     # 监视用户输入和服务器返回数据
     3     # sys.stdin 处理用户输入
     4     # chan 是之前创建的通道,用于接收服务器返回信息
     5     readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
     6     if chan in readable:
     7         try:
     8             x = chan.recv(1024)
     9             if len(x) == 0:
    10                 print '
    *** EOF
    ',
    11                 break
    12             sys.stdout.write(x)
    13             sys.stdout.flush()
    14         except socket.timeout:
    15             pass
    16     if sys.stdin in readable:
    17         inp = sys.stdin.readline()
    18         chan.sendall(inp)
     1 # 获取原tty属性
     2 oldtty = termios.tcgetattr(sys.stdin)
     3 try:
     4     # 为tty设置新属性
     5     # 默认当前tty设备属性:
     6     #   输入一行回车,执行
     7     #   CTRL+C 进程退出,遇到特殊字符,特殊处理。
     8 
     9     # 这是为原始模式,不认识所有特殊符号
    10     # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
    11     tty.setraw(sys.stdin.fileno())
    12     chan.settimeout(0.0)
    13 
    14     while True:
    15         # 监视 用户输入 和 远程服务器返回数据(socket)
    16         # 阻塞,直到句柄可读
    17         r, w, e = select.select([chan, sys.stdin], [], [], 1)
    18         if chan in r:
    19             try:
    20                 x = chan.recv(1024)
    21                 if len(x) == 0:
    22                     print '
    *** EOF
    ',
    23                     break
    24                 sys.stdout.write(x)
    25                 sys.stdout.flush()
    26             except socket.timeout:
    27                 pass
    28         if sys.stdin in r:
    29             x = sys.stdin.read(1)
    30             if len(x) == 0:
    31                 break
    32             chan.send(x)
    33 
    34 finally:
    35     # 重新设置终端属性
    36     termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
     1 def windows_shell(chan):
     2     import threading
     3 
     4     sys.stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.
    
    ")
     5 
     6     def writeall(sock):
     7         while True:
     8             data = sock.recv(256)
     9             if not data:
    10                 sys.stdout.write('
    *** EOF ***
    
    ')
    11                 sys.stdout.flush()
    12                 break
    13             sys.stdout.write(data)
    14             sys.stdout.flush()
    15 
    16     writer = threading.Thread(target=writeall, args=(chan,))
    17     writer.start()
    18 
    19     try:
    20         while True:
    21             d = sys.stdin.read(1)
    22             if not d:
    23                 break
    24             chan.send(d)
    25     except EOFError:
    26         # user hit ^Z or F6
    27         pass

    注:密码验证t.auth_password(username,pw)

     详见:paramiko源码demo

    A wise man thinks all that he says, a fool says all that he thinks.
  • 相关阅读:
    python中kafka生产者和消费者实现
    bzip2压缩
    gzip压缩
    对目录、文件操作需要的权限
    Linux文件查找
    Linux文件种类与扩展名
    centos 文件权限与目录权限
    centos关机命令
    私有方法私有属性继承问题
    python3 中类的__del__方法
  • 原文地址:https://www.cnblogs.com/BernieChen/p/6021230.html
Copyright © 2011-2022 走看看