堡垒机--paramiko模块

做堡垒机之前,来了解一下paramiko模块.

实际上底层封装的SSH.

SSHclient(1)

import paramiko

#实例化一个ssh
ssh = paramiko.SSHClient()

#设置主机不在khost_key中也能连接
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#创建连接
ssh.connect(hostname=‘192.168.12.100‘,port=22,username=‘root‘,password=‘123456‘)
#执行命令
stdin,stdout,stderror =  ssh.exec_command(‘df -Th‘)
#打印输出
print(stdout.read())
#关闭连接
ssh.close()

如果去看paramiko模块中,会有一个transport部分

所以SSHclient会有第二种连接方式

SSHclient(2)

import paramiko

transport = paramiko.Transport((‘hostname‘, 22))
transport.connect(username=‘zcq‘, password=‘123‘)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command(‘df‘)
print(stdout.read())

transport.close()

既然是ssh连接,那还有用公钥的方式来连接

基于公钥的连接方式(1)

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(‘/home/auto/.ssh/id_rsa‘)

# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接服务器
ssh.connect(hostname=‘c1.salt.com‘, port=22, username=‘zcq‘, key=private_key)

# 执行命令
stdin, stdout, stderr = ssh.exec_command(‘df‘)
# 获取命令结果
result = stdout.read()

# 关闭连接
ssh.close()

基于公钥的连接(2)

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(‘/home/auto/.ssh/id_rsa‘)

transport = paramiko.Transport((‘hostname‘, 22))
transport.connect(username=‘zcq‘, pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command(‘df‘)

transport.close()

上诉是远程执行命令,,既然有执行命令的方式,那就有上传下载的功能

SFTPClient

基于用户名密码上传下载:

import paramiko

transport = paramiko.Transport((‘hostname‘,22))
transport.connect(username=‘zcq‘,password=‘123‘)

sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(‘/tmp/location.py‘, ‘/tmp/test.py‘)
# 将remove_path 下载到本地 local_path
sftp.get(‘remove_path‘, ‘local_path‘)

transport.close()

基于公钥密钥上传下载:

import paramiko

private_key = paramiko.RSAKey.from_private_key_file(‘/home/auto/.ssh/id_rsa‘)

transport = paramiko.Transport((‘hostname‘, 22))
transport.connect(username=‘zcq‘, pkey=private_key )

sftp = paramiko.SFTPClient.from_transport(transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(‘/tmp/location.py‘, ‘/tmp/test.py‘)
# 将remove_path 下载到本地 local_path
sftp.get(‘remove_path‘, ‘local_path‘)

transport.close()

前戏铺垫完了。那就开始用类的方式,来封装一个基于paraimko的长连接方式

import paramiko

class SSH(object):
    def __init__(self,ip,port,user,passwd):
        self.ip = ip
        self.port = port
        self.user = user
        self.passwd = passwd

        self.transport = None
    def connect(self):
        self.transport = paramiko.Transport((self.ip,self.port))
        self.transport.connect(username=self.user,password=self.passwd)

    def cmd(self,cmd):
        ssh = paramiko.SSHClient()
        ssh._transport = self.transport
        stdin,stdout,stderr = ssh.exec_command(cmd)
        #print(stdout.read())
        return stdout.read()

    def put(self,server_path,local_path):
        sftp = paramiko.SFTPClient.from_transport(self.transport)
        sftp.put(local_path,server_path)
    def get(self,server_path,local_path):
        sftp = paramiko.SFTPClient.from_transport(self.transport)
        sftp.get(server_path,local_path)

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

obj = SSH(‘192.168.12.100‘,22,‘root‘,‘123456‘)
obj.connect()
#obj.cmd(‘df -Th‘)
print(obj.cmd(‘df -Th‘))
#obj.put()
obj.close()

堡垒机---

堡垒机执行流程:

  1. 管理员为用户在服务器上创建账号(将公钥放置服务器,或者使用用户名密码)
  2. 用户登陆堡垒机,输入堡垒机用户名密码,现实当前用户管理的服务器列表
  3. 用户选择服务器,并自动登陆
  4. 执行操作并同时将用户操作记录

实现过程(用transport来实现)

初级版

import paramiko
import sys
import os
import socket
import select
import getpass

tran = paramiko.Transport((‘10.211.55.4‘, 22,))
tran.start_client()
tran.auth_password(‘wupeiqi‘, ‘123‘)

# 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell()

#########
# 利用sys.stdin,肆意妄为执行操作
# 用户在终端输入内容,并将内容发送至远程服务器
# 远程服务器执行命令,并将结果返回
# 用户终端显示内容
#########

chan.close()
tran.close()

进阶版

import paramiko
import sys
import os
import socket
import select
import getpass
from paramiko.py3compat import u

tran = paramiko.Transport((‘10.211.55.4‘, 22,))
tran.start_client()
tran.auth_password(‘wupeiqi‘, ‘123‘)

# 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell()

while True:
    # 监视用户输入和服务器返回数据
    # sys.stdin 处理用户输入
    # chan 是之前创建的通道,用于接收服务器返回信息
    readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
    if chan in readable:
        try:
            x = u(chan.recv(1024))
            if len(x) == 0:
                print(‘\r\n*** EOF\r\n‘)
                break
            sys.stdout.write(x)
            sys.stdout.flush()
        except socket.timeout:
            pass
    if sys.stdin in readable:
        inp = sys.stdin.readline()
        chan.sendall(inp)

chan.close()
tran.close()

高级版(1)

import paramiko
import sys
import os
import socket
import select
import getpass
from paramiko.py3compat import u

default_username = getpass.getuser()
username = input(‘Username [%s]: ‘ % default_username)
if len(username) == 0:
    username = default_username

hostname = input(‘Hostname: ‘)
if len(hostname) == 0:
    print(‘*** Hostname required.‘)
    sys.exit(1)

tran = paramiko.Transport((hostname, 22,))
tran.start_client()

default_auth = "p"
auth = input(‘Auth by (p)assword or (r)sa key[%s] ‘ % default_auth)
if len(auth) == 0:
    auth = default_auth

if auth == ‘r‘:
    default_path = os.path.join(os.environ[‘HOME‘], ‘.ssh‘, ‘id_rsa‘)
    path = input(‘RSA key [%s]: ‘ % default_path)
    if len(path) == 0:
        path = default_path
    try:
        key = paramiko.RSAKey.from_private_key_file(path)
    except paramiko.PasswordRequiredException:
        password = getpass.getpass(‘RSA key password: ‘)
        key = paramiko.RSAKey.from_private_key_file(path, password)
    tran.auth_publickey(username, key)
else:
    pw = getpass.getpass(‘Password for %[email protected]%s: ‘ % (username, hostname))
    tran.auth_password(username, pw)

# 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell()

while True:
    # 监视用户输入和服务器返回数据
    # sys.stdin 处理用户输入
    # chan 是之前创建的通道,用于接收服务器返回信息
    readable, writeable, error = select.select([chan, sys.stdin, ],[],[],1)
    if chan in readable:
        try:
            x = u(chan.recv(1024))
            if len(x) == 0:
                print(‘\r\n*** EOF\r\n‘)
                break
            sys.stdout.write(x)
            sys.stdout.flush()
        except socket.timeout:
            pass
    if sys.stdin in readable:
        inp = sys.stdin.readline()
        chan.sendall(inp)

chan.close()
tran.close()

高级版(2)

import paramiko
import sys
import os
import socket
import select
import getpass
import termios
import tty
from paramiko.py3compat import u

tran = paramiko.Transport((‘10.211.55.4‘, 22,))
tran.start_client()
tran.auth_password(‘wupeiqi‘, ‘123‘)

# 打开一个通道
chan = tran.open_session()
# 获取一个终端
chan.get_pty()
# 激活器
chan.invoke_shell()

# 获取原tty属性
oldtty = termios.tcgetattr(sys.stdin)
try:
    # 为tty设置新属性
    # 默认当前tty设备属性:
    #   输入一行回车,执行
    #   CTRL+C 进程退出,遇到特殊字符,特殊处理。

    # 这是为原始模式,不认识所有特殊符号
    # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
    tty.setraw(sys.stdin.fileno())
    chan.settimeout(0.0)

    while True:
        # 监视 用户输入 和 远程服务器返回数据(socket)
        # 阻塞,直到句柄可读
        r, w, e = select.select([chan, sys.stdin], [], [], 1)
        if chan in r:
            try:
                x = u(chan.recv(1024))
                if len(x) == 0:
                    print(‘\r\n*** EOF\r\n‘)
                    break
                sys.stdout.write(x)
                sys.stdout.flush()
            except socket.timeout:
                pass
        if sys.stdin in r:
            x = sys.stdin.read(1)
            if len(x) == 0:
                break
            chan.send(x)

finally:
    # 重新设置终端属性
    termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

chan.close()
tran.close()

基于Passwd或者RSA进行登录操作

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
import sys
import os
import socket
import getpass
import termios
import tty
import select
from paramiko.py3compat import u

def interactive_shell(chan):
    # 获取原tty属性
    oldtty = termios.tcgetattr(sys.stdin)
    try:
        # 为tty设置新属性
        # 默认当前tty设备属性:
        #   输入一行回车,执行
        #   CTRL+C 进程退出,遇到特殊字符,特殊处理。

        # 这是为原始模式,不认识所有特殊符号
        # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
        tty.setraw(sys.stdin.fileno())
        tty.setcbreak(sys.stdin.fileno())
        chan.settimeout(0.0)
        while True:
            r, w, e = select.select([chan, sys.stdin], [], [])
            if chan in r:
                try:
                    x = u(chan.recv(1024))
                    if len(x) == 0:
                        sys.stdout.write(‘\r\n*** EOF\r\n‘)
                        break
                    sys.stdout.write(x)
                    sys.stdout.flush()
                except socket.timeout:
                    pass
            if sys.stdin in r:
                x = sys.stdin.read(1)
                if len(x) == 0:
                    break
                chan.send(x)

    finally:
        # 重新设置终端属性
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

def run():
    hostname = input(‘请输入主机名: ‘)
    tran = paramiko.Transport((hostname, 22,))
    tran.start_client()

    username = input(‘请输入用户名: ‘)
    auth = input(‘请输入密码进行验证(p) 或 (r)sa Key进行验证?‘)
    if auth == ‘r‘:
        path = input(‘请输入RSA key 路径: ‘)
        try:
            key = paramiko.RSAKey.from_private_key_file(path)
        except paramiko.PasswordRequiredException:
            password = getpass.getpass(‘RSA key password: ‘)
            key = paramiko.RSAKey.from_private_key_file(path, password)
        tran.auth_publickey(username, key)
    else:
        pw = getpass.getpass(‘请输入密码 %[email protected]%s: ‘ % (username, hostname))
        tran.auth_password(username, pw)

    # 打开一个通道
    chan = tran.open_session()
    # 获取一个终端
    chan.get_pty()
    # 激活器
    chan.invoke_shell()

    interactive_shell(chan)

    chan.close()
    tran.close()

if __name__ == ‘__main__‘:
    run()

提示用户选择主机和用户

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
import sys
import os
import socket
import getpass
import termios
import tty
import select
from paramiko.py3compat import u

def interactive_shell(chan):
    # 获取原tty属性
    oldtty = termios.tcgetattr(sys.stdin)
    try:
        # 为tty设置新属性
        # 默认当前tty设备属性:
        # 输入一行回车,执行
        # CTRL+C 进程退出,遇到特殊字符,特殊处理。

        # 这是为原始模式,不认识所有特殊符号
        # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
        tty.setraw(sys.stdin.fileno())
        tty.setcbreak(sys.stdin.fileno())
        chan.settimeout(0.0)
        while True:
            r, w, e = select.select([chan, sys.stdin], [], [])
            if chan in r:
                try:
                    x = u(chan.recv(1024))
                    if len(x) == 0:
                        sys.stdout.write(‘\r\n*** EOF\r\n‘)
                        break
                    sys.stdout.write(x)
                    sys.stdout.flush()
                except socket.timeout:
                    pass
            if sys.stdin in r:
                x = sys.stdin.read(1)
                if len(x) == 0:
                    break
                chan.send(x)

    finally:
        # 重新设置终端属性
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

def run():
    db_dict = {
        ‘c1.salt.com‘: {
            ‘root‘: {‘user‘: ‘root‘, ‘auth‘: ‘r‘, "cert": ‘key路径‘},
            ‘alex‘: {‘user‘: ‘alex‘, ‘auth‘: ‘p‘, "cert": ‘密码‘},
        },
        ‘c2.salt.com‘: {
            ‘alex‘: {‘user‘: ‘alex‘, ‘auth‘: ‘p‘, "cert": ‘密码‘},
        },

    }

    for row in db_dict.keys():
        print(row)

    hostname = input(‘请选择主机: ‘)
    tran = paramiko.Transport((hostname, 22,))
    tran.start_client()

    for item in db_dict[hostname].keys():
        print(item)

    username = input(‘请输入用户: ‘)

    user_dict = db_dict[hostname][username]
    if username[‘auth‘] == ‘r‘:
        key = paramiko.RSAKey.from_private_key_file(user_dict[‘cert‘])
        tran.auth_publickey(username, key)
    else:
        pw = user_dict[‘cert‘]
        tran.auth_password(username, pw)

    # 打开一个通道
    chan = tran.open_session()
    # 获取一个终端
    chan.get_pty()
    # 激活器
    chan.invoke_shell()

    interactive_shell(chan)

    chan.close()
    tran.close()

if __name__ == ‘__main__‘:
    run()

提供用户选择主机和用户(记录操作日志)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
import sys
import os
import socket
import getpass
import termios
import tty
import select
from paramiko.py3compat import u

def interactive_shell(chan):
    # 获取原tty属性
    oldtty = termios.tcgetattr(sys.stdin)
    try:
        # 为tty设置新属性
        # 默认当前tty设备属性:
        # 输入一行回车,执行
        # CTRL+C 进程退出,遇到特殊字符,特殊处理。

        # 这是为原始模式,不认识所有特殊符号
        # 放置特殊字符应用在当前终端,如此设置,将所有的用户输入均发送到远程服务器
        tty.setraw(sys.stdin.fileno())
        tty.setcbreak(sys.stdin.fileno())
        chan.settimeout(0.0)

        log = open(‘handle.log‘, ‘a+‘, encoding=‘utf-8‘)
        flag = False
        temp_list = []

        while True:
            r, w, e = select.select([chan, sys.stdin], [], [])
            if chan in r:
                try:
                    x = u(chan.recv(1024))
                    if len(x) == 0:
                        sys.stdout.write(‘\r\n*** EOF\r\n‘)
                        break
                    # 如果用户上一次点击的是tab键,则获取返回的内容写入在记录中
                    if flag:
                        if x.startswith(‘\r\n‘):
                            pass
                        else:
                            temp_list.append(x)
                        flag = False
                    sys.stdout.write(x)
                    sys.stdout.flush()
                except socket.timeout:
                    pass
            if sys.stdin in r:
                # 读取用户在终端数据每一个字符
                x = sys.stdin.read(1)
                if len(x) == 0:
                    break
                # 如果用户点击TAB键
                if x == ‘\t‘:
                    flag = True
                else:
                    # 未点击TAB键,则将每个操作字符记录添加到列表中,以便之后写入文件
                    temp_list.append(x)

                # 如果用户敲回车,则将操作记录写入文件
                if x == ‘\r‘:
                    log.write(‘‘.join(temp_list))
                    log.flush()
                    temp_list.clear()
                chan.send(x)

    finally:
        # 重新设置终端属性
        termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)

def run():
    db_dict = {
        ‘c1.salt.com‘: {
            ‘root‘: {‘user‘: ‘root‘, ‘auth‘: ‘r‘, "cert": ‘key路径‘},
            ‘alex‘: {‘user‘: ‘alex‘, ‘auth‘: ‘p‘, "cert": ‘密码‘},
        },
        ‘c2.salt.com‘: {
            ‘root‘: {‘user‘: ‘root‘, ‘auth‘: ‘r‘, "cert": ‘key路径‘},
            ‘alex‘: {‘user‘: ‘alex‘, ‘auth‘: ‘p‘, "cert": ‘密码‘},
        },

    }

    for row in db_dict.keys():
        print(row)

    hostname = input(‘请选择主机: ‘)
    tran = paramiko.Transport((hostname, 22,))
    tran.start_client()

    for item in db_dict[hostname].keys():
        print(item)

    username = input(‘请输入用户: ‘)

    user_dict = db_dict[hostname][username]
    if username[‘auth‘] == ‘r‘:
        key = paramiko.RSAKey.from_private_key_file(user_dict[‘cert‘])
        tran.auth_publickey(username, key)
    else:
        pw = user_dict[‘cert‘]
        tran.auth_password(username, pw)

    # 打开一个通道
    chan = tran.open_session()
    # 获取一个终端
    chan.get_pty()
    # 激活器
    chan.invoke_shell()

    interactive_shell(chan)

    chan.close()
    tran.close()

if __name__ == ‘__main__‘:
    run()

#转载于http://www.cnblogs.com/wupeiqi/articles/5699254.html 博客

时间: 2024-10-29 10:48:35

堡垒机--paramiko模块的相关文章

堡垒机 Paramiko 模块

Paramiko 模块 引用源:http://www.cnblogs.com/wupeiqi/articles/5095821.html 前言:Paramiko模块封装了SSH协议,在连接服务器这方面广泛使用,是python连接Linux的重要模块.此模块封装了很多方法和类,可以根据需要合理使用. 一.连接服务器 1.用户名密码连接(不安全).这里介绍两种方法: 第一: 1 import paramiko 2 3 # 创建SSH对象 4 ssh = paramiko.SSHClient() 5

python之路 堡垒机paramiko

paramiko 1.安装 pip3 install paramiko 二.使用 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='c1.sa

堡垒机 paramiko 自动登陆代码

#!/usr/bin/env python # Copyright (C) 2003-2007 Robey Pointer <[email protected]> # # This file is part of paramiko. # # Paramiko is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License a

堡垒机的简单应用

堡垒机的定义: 即在一个特定的网络环境下,为了保障网络和数据不受来自外部和内部用户的入侵和破坏,而运用各种技术手段实时收集和监控网络环境中每一个组成部分的系统状态.安全事件.网络活动,以便集中报警.及时处理及审计定责. 堡垒机的功能: 账号管理 设备支持统一账户管理策略,能够实现对所有服务器.网络设备.安全设备等账号进行集中管理 完成对账号整个生命周期的监控 对设备进行特殊角色设置如:审计巡检员.运维操作员.设备管理员等自定义设置,以满足审计需求 账号登陆 支持对X11.linux.unix.数

运维堡垒机---基于paramiko模块

话不多说,有图为证,主要是表达能力问题,呵呵.... 简单描述: 堡垒机一般都独立出来,单独部署,通俗点说就是跳板机,中控机. 须通过堡垒机才能连接到远程目的ip. 堡垒机将某用户的所有操作都记录在案----堡垒机的意义 一,流程图描述的功能已经非常清楚了 用户须先登陆堡垒机,然后能完成下面3个功能 1,单台机器登陆--->所有操作入库 2,批量机器执行命令--->所有操作入库 3,查看操作记录 二,堡垒机的意义(自己理解): 1,操作简单化,运维人员再也不用记服务器的username/pas

python2.0 s12 day8 _ 堡垒机前戏paramiko模块

堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 paramiko模块是做主机管理的,他模拟了一个ssh. 有两种形式连接形式, 一种通过用户名密码: ssh -p 22 [email protected] 一种是通过密钥的方式: ssh -p 22 -i ~/.ssh/dongjing-shanghai.pem [email protected]_pro01 再连接的的语法上,有两种: 一种是直接将连接的主机地址和端口直接

python-----堡垒机前戏paramiko模块

堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.con

Python修改paramiko模块开发运维审计保垒机

需求: 1.保垒机有一个公共账号,所有人都是用这个账号登陆保垒机,root用户只能由堡垒机管理员有权限可以登陆 2.公共账号登陆保垒机->选择主机组->选择主机->选择你的普通用户->输入你的后端服务器的密码登陆 3.登陆的后端服务器所操作过的命令要记录到文件 拓扑图: 第三方模块paramiko下载 paramiko-1.10.1.tar.gz http://pan.baidu.com/s/1hrWzg7y paramiko源码包远程演示(未修改源码) 修改parpakio源码

python 学习第十一课 上下文管理 paramiko 堡垒机 mysql操作

Rlock 与 Lock 这两种琐的主要区别是:RLock允许在同一线程中被多次acquire.而Lock却不允许这种情况.注意:如果使用RLock,那么acquire和release必须成对出现,即调用了n次acquire,必须调用n次的release才能真正释放所占用的琐 >>> help(threading.RLock) RLock(*args, **kwargs) Factory function that returns a new reentrant lock. A reen