3212ed 发表于 2016-1-12 09:08:49

Python堡垒机实现之基础知识

一般堡垒机都具有5个基本功能:

    1、权限控制

    2、执行命令

    3、上传下载文件

    4、远程登录

    5、记录操作



权限控制:
    说明:根据不同的登录用户分配不同的可管理的主机组。(再细分的权限就是根据不同的用户控制可在主机上执行的命令,一般不会限制的这么严格)

    思路:使用数据库创建用户表,表字段有ID、用户名、密码、所属组,再创建主机表,表字段有ID,主机IP,所属组。其中用户表中的所属组和主机表中的所属组相对应,这样就能把两张表关联起来。当用户登录的时候就可以根据用户名去获取可管理的主机列表。

    例子:(这里只写出关于python连接MySQL数据库的例子)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import MySQLdb

def con_mysql(mhost,muser,mpasswd,mdb):    #连接数据库需要的参数
   try:
      con = MySQLdb.connect(host=mhost,user=muser,passwd=mpasswd,db=mdb)
      cur = con.cursor()
   except MySQLdb.Error,err_msg:
      print 'Mysql Error Msg:',err_msg
      sys.exit()

   try:
      cur.execute('select * from host_list')    #执行SQL语句
      info = cur.fetchall()   #获取主机列表
      return info                #返回获取到的主机列表
   except MySQLdb.Error,err_msg:
      print 'Mysql Error Msg:',err_msg
      cur.close()
      con.close()
      sys.exit()





执行命令:
    说明:这里的执行命令一般是指批量执行命令,比如需要同时获取N台主机的主机名。

    思路:使用paramiko模块来实现远程登录服务器并执行命令。使用multiprocessing来实现批量并发执行。
    例子:(这里只写出paramiko模块远程密码登录服务器并执行命令的例子)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import paramiko

class Paramiko_Manage():
    def __init__(self,host,port,user,passwd):    #初始化连接服务器所需要的参数
      self.host = host
      self.port = port
      self.user = user
      self.passwd = passwd    #使用密码认证

    def connect(self):      #连接方法,用来建立与服务器的连接
      self.transport = paramiko.Transport((self.host,self.port))
      self.transport.connect(username=self.user,password=self.passwd)
      print 'connect'

    def close(self):      #关闭方法,用来关闭与服务器的连接
      self.transport.close()
      print 'close'

    def cmd(self,command):      #执行命令的方法,接收需要执行的命令作为参数
      ssh = paramiko.SSHClient()
      ssh._transport = self.transport
      stdin, stdout, stderr = ssh.exec_command(command,timeout=3)
      print 'command resluat: ',stdout.read()

    def run(self,command):
      self.connect()      #建立连接
      self.cmd(command)   #执行命令
      self.close()          #关闭连接

p = Paramiko_Manage('192.168.100.211',22,'test','123')
p.run('hostname')

执行结果:
connect
command resluat:Test1

close






上传、下载文件:
    说明:批量上传文件相对比较简单,如果是批量下载文件还需要考虑到多台服务器文件重名的问题。
            还需要考虑到文件上传后比较大小以确认是否上传下载成功。

    思路:使用paramiko模块来实现远程上传下载文件。使用multiprocessing来实现批量并发执行。   

    例子:(这里只写出paramiko模块远程秘钥认证登录服务器并执行命令的例子)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import paramiko
import os

class Paramiko_Manage():
    def __init__(self,host,port,user,key):
      self.host = host
      self.port = port
      self.user = user
      keyfile = os.path.expanduser(key)    #使用秘钥认证
      self.key = paramiko.RSAKey.from_private_key_file(keyfile)

    def connect(self):
      self.transport = paramiko.Transport((self.host,self.port))
      self.transport.connect(username=self.user,pkey=self.key)
      print 'connect'

    def close(self):
      self.transport.close()
      print 'close'

    def trans(self,file1,file2):    #传输文件的方法
      sftp = paramiko.SFTPClient.from_transport(self.transport)
      file1 = '%s_%s' % (file1, self.host)   #修改下载文件的保存文件名
      sftp.get(file2,file1)
      file1_size = os.path.getsize(file1)    #获取下载文件的大小
      file2_size = int(str(sftp.stat(file2)).split()) #获取远程文件的大小
      if file1_size == file2_size:    #比较两个文件大小
            print 'File trans done'

    def run(self,file1,file2):
      self.connect()      #建立连接
      self.trans(file1,file2)#传输文件
      self.close()               #关闭连接

p = Paramiko_Manage('192.168.100.211',22,'test2','~/.ssh/id_rsa')
p.run('/root/hosts','/etc/hosts')

执行结果:
connect
File trans done
close





远程登录和记录操作:

    说明:通过堡垒机ssh远程连接到服务器,并执行操作,和在终端执行操作的效果一样。

    思路:使用paramiko实现远程连接服务器的功能,使用sys.stdin和select处理用户输入和接受返回结果。

    例子:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import paramiko
import select
import sys
import socket
import os

tran = paramiko.Transport((host,port))    #连接服务器,host和port自定义
tran.start_client()
default_path = os.path.join(os.environ['HOME'],'.ssh','id_rsa')
key = paramiko.RSAKey.from_private_key_file(default_path)
tran.auth_publickey('root',key)
chan = tran.open_session()    #打开一个通道
chan.get_pty()                #获取一个终端
chan.invoke_shell()         #激活器

f = open('log.log','a')       #打开一个文件用于写入执行的操作
while True:
    # 监视用户输入和服务器返回数据
    # sys.stdin 处理用户输入
    # chan 是之前创建的通道,用于接收服务器返回信息
    readable,writeable,error = select.select(,[],[],1)
    if chan in readable:      #接受命令的返回结果
      try:
            x = chan.recv(1024)
            if len(x) == 0:
                print '\r\n*** EOF\r\n',
                f.close()    #退出时关闭记录文件
                break
            sys.stdout.write(x)
            sys.stdout.flush()
      except socket.timeout:
            pass
    if sys.stdin in readable:    #处理用户输入发送到服务器执行
      inp = sys.stdin.readline()
      f.write(inp)    #记录用户输入
      chan.sendall(inp)

chan.close()
tran.close()






   

页: [1]
查看完整版本: Python堡垒机实现之基础知识