简介

paramiko 是python的一个实现SSHv2协议的一个库,使用paramiko我们可以很方便使用python ssh连接到其它主机.

核心组件

client: 入口组件,主要用于创建ssh连接,执行命令等入口

transport: 核心功能组件,控制ssh连接,管理channel,处理ssh server返回数据,发送数据

channel: 用于执行ssh命令以及interactive 交互方式shell处理

packet: 解析数据包和压缩数据包

client

SSHClient作为client里面主要类,是作为paramiko一个主要入口类,起到一个门面的作用

简单使用

import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(*args, **kwargs)
stdin, stdout, stderr = ssh.exec_command('ls -a')
print(stdout.read().decode('utf-8'))
ssh.close()

首先初始化一个SSHClient,后面connect和exec_command都是通过transport来执行,下面会具体讲transport

transport

最重要的一个核心类Transport,整个库核心功能都集中到这个类里面,在client.connect方法里面会初始化一个Transport对象,设置一下Transport对象的SSH相关的属性,然后进行相关的认证工作

    def _auth(self,username,password,pkey,key_filenames,allow_agent,look_for_keys,gss_auth,gss_kex,gss_deleg_creds,gss_host,passphrase,):"""Try, in order:- The key(s) passed in, if one was passed in.- Any key we can find through an SSH agent (if allowed).- Any "id_rsa", "id_dsa" or "id_ecdsa" key discoverable in ~/.ssh/(if allowed).- Plain username/password auth, if a password was given.(The password might be needed to unlock a private key [if 'passphrase'isn't also given], or for two-factor authentication [for which it isrequired].)"""saved_exception = Nonetwo_factor = Falseallowed_types = set()two_factor_types = {"keyboard-interactive", "password"}if passphrase is None and password is not None:passphrase = password# If GSS-API support and GSS-PI Key Exchange was performed, we attempt# authentication with gssapi-keyex.if gss_kex and self._transport.gss_kex_used:try:self._transport.auth_gssapi_keyex(username)returnexcept Exception as e:saved_exception = e# Try GSS-API authentication (gssapi-with-mic) only if GSS-API Key# Exchange is not performed, because if we use GSS-API for the key# exchange, there is already a fully established GSS-API context, so# why should we do that again?if gss_auth:try:return self._transport.auth_gssapi_with_mic(username, gss_host, gss_deleg_creds)except Exception as e:saved_exception = eif pkey is not None:try:self._log(DEBUG,"Trying SSH key {}".format(hexlify(pkey.get_fingerprint())),)allowed_types = set(self._transport.auth_publickey(username, pkey))two_factor = allowed_types & two_factor_typesif not two_factor:returnexcept SSHException as e:saved_exception = eif not two_factor:for key_filename in key_filenames:for pkey_class in (RSAKey, DSSKey, ECDSAKey, Ed25519Key):try:key = self._key_from_filepath(key_filename, pkey_class, passphrase)allowed_types = set(self._transport.auth_publickey(username, key))two_factor = allowed_types & two_factor_typesif not two_factor:returnbreakexcept SSHException as e:saved_exception = eif not two_factor and allow_agent:if self._agent is None:self._agent = Agent()for key in self._agent.get_keys():try:id_ = hexlify(key.get_fingerprint())self._log(DEBUG, "Trying SSH agent key {}".format(id_))# for 2-factor auth a successfully auth'd key password# will return an allowed 2fac auth methodallowed_types = set(self._transport.auth_publickey(username, key))two_factor = allowed_types & two_factor_typesif not two_factor:returnbreakexcept SSHException as e:saved_exception = eif not two_factor:keyfiles = []for keytype, name in [(RSAKey, "rsa"),(DSSKey, "dsa"),(ECDSAKey, "ecdsa"),(Ed25519Key, "ed25519"),]:# ~/ssh/ is for windowsfor directory in [".ssh", "ssh"]:full_path = os.path.expanduser("~/{}/id_{}".format(directory, name))if os.path.isfile(full_path):# TODO: only do this append if below did not runkeyfiles.append((keytype, full_path))if os.path.isfile(full_path + "-cert.pub"):keyfiles.append((keytype, full_path + "-cert.pub"))if not look_for_keys:keyfiles = []for pkey_class, filename in keyfiles:try:key = self._key_from_filepath(filename, pkey_class, passphrase)# for 2-factor auth a successfully auth'd key will result# in ['password']allowed_types = set(self._transport.auth_publickey(username, key))two_factor = allowed_types & two_factor_typesif not two_factor:returnbreakexcept (SSHException, IOError) as e:saved_exception = eif password is not None:try:self._transport.auth_password(username, password)returnexcept SSHException as e:saved_exception = eelif two_factor:try:self._transport.auth_interactive_dumb(username)returnexcept SSHException as e:saved_exception = e# if we got an auth-failed exception earlier, re-raise itif saved_exception is not None:raise saved_exceptionraise SSHException("No authentication methods available")

认证会按一定顺序尝试认证,直到认证或者所有方式尝试完,大致流程如下

里面还会有two-factor这个用的不多.

Transport继承自Thread对象,所以它本身就是一个线程,connect方法会通过start启动Transport线程,Transport run方法会不断从建立的通道读取数据,通过packetizer解码,判断数据类型,然后找具体handler进行处理

run 方法里处理message代码断:

                while self.active:if self.packetizer.need_rekey() and not self.in_kex:self._send_kex_init()try:ptype, m = self.packetizer.read_message()except NeedRekeyException:continueif ptype == MSG_IGNORE:continueelif ptype == MSG_DISCONNECT:self._parse_disconnect(m)breakelif ptype == MSG_DEBUG:self._parse_debug(m)continueif len(self._expected_packet) > 0:if ptype not in self._expected_packet:raise SSHException("Expecting packet from {!r}, got {:d}".format(self._expected_packet, ptype))  # noqaself._expected_packet = tuple()if (ptype >= 30) and (ptype <= 41):self.kex_engine.parse_next(ptype, m)continueif ptype in self._handler_table:error_msg = self._ensure_authed(ptype, m)if error_msg:self._send_message(error_msg)else:self._handler_table[ptype](self, m)elif ptype in self._channel_handler_table:chanid = m.get_int()chan = self._channels.get(chanid)if chan is not None:self._channel_handler_table[ptype](chan, m)elif chanid in self.channels_seen:self._log(DEBUG,"Ignoring message for dead channel {:d}".format(  # noqachanid),)else:self._log(ERROR,"Channel request for unknown channel {:d}".format(  # noqachanid),)breakelif (self.auth_handler is not Noneand ptype in self.auth_handler._handler_table):handler = self.auth_handler._handler_table[ptype]handler(self.auth_handler, m)if len(self._expected_packet) > 0:continueelse:# Respond with "I don't implement this particular# message type" message (unless the message type was# itself literally MSG_UNIMPLEMENTED, in which case, we# just shut up to avoid causing a useless loop).name = MSG_NAMES[ptype]warning = "Oops, unhandled type {} ({!r})".format(ptype, name)self._log(WARNING, warning)if ptype != MSG_UNIMPLEMENTED:msg = Message()msg.add_byte(cMSG_UNIMPLEMENTED)msg.add_int(m.seqno)self._send_message(msg)self.packetizer.complete_handshake()

Channel

channel是具体执行ssh命令的组件,每次执行命令或者创建interactive shell都是创建一个channel这个channel对应ssh协议里的channel,创建channel会请求ssh server开启一个channel.

执行命令大致流程,Transport创建一个channel, channel通过transport发送cMSG_CHANNEL_REQUEST消息到服务端,通过transport后台线程获取到数据,然后调用相应channel的进行后续处理,返回给调用者

python paramiko 解析相关推荐

  1. 了解女友的心还不如了解Python之在Python中解析和修改XML

    2021年12月15日 10:14 ·  阅读 30 摘要: 工作中我们时常需要解析用不同语言编写的数据.Python 提供了许多库来解析或拆分用其他语言编写的数据.在这篇 Python XML 解析 ...

  2. python列表解析的新方法

    python 列表解析我感觉是python非常灵活的一个地方,一开始接触它的时候,特别是之前学过其它的语言, 你会感觉很不习惯,怎么看怎么不对劲,老是觉的哪个地方怪怪的,这就是列表解析的魔力所在. p ...

  3. 如何在Python中解析YAML文件

    如何在Python中解析YAML文件? #1楼 不依赖C标头的最简单,最纯净的方法是PyYaml( 文档 ): #!/usr/bin/env pythonimport yamlwith open(&q ...

  4. python dpkt解析ssl流

    用法:python extract_tls_flow.py -vr  white_pcap/11/2018-01-10_13-05-09_2.pcap  -o pcap_ssl_flow.txt  & ...

  5. 用Python提取解析pdf文档中内容

    用Python提取解析pdf文档中内容 文章目录: 参考: 1.https://blog.csdn.net/tmaczt/article/details/82876018 # Tika库 2.http ...

  6. 【Android 逆向】使用 Python 代码解析 ELF 文件 ( PyCharm 中进行断点调试 | ELFFile 实例对象分析 )

    文章目录 一.PyCharm 中进行断点调试 二.ELFFile 实例对象分析 一.PyCharm 中进行断点调试 在上一篇博客 [Android 逆向]使用 Python 代码解析 ELF 文件 ( ...

  7. 密码算法中iv值是什么_?标检测中的?极?值抑制算法(nms):python代码解析

    ⾮极⼤值抑制(Non-Maximum Suppression)原理 ⾮极⼤值抑制,顾名思义,找出极⼤值,抑制⾮极⼤值.这种思路和算法在各个领域中应⽤⼴泛,⽐如边缘检测算法canny算⼦中就使⽤了该⽅法 ...

  8. python简介pdf_PDFMiner首页、文档和下载 - Python PDF 解析器 - OSCHINA - 中文开源技术交流社区...

    PDFMiner 是一个 Python 的 PDF 解析器,可以从 PDF 文档中提取信息.与其他 PDF 相关的工具不同,它侧重的是获取和分析文本数据.PDFMiner 允许获取某一页中文本的准确位 ...

  9. python paramiko安装_Python Paramiko模块的安装与使用详解

    一.前言 常见的解决方法都会需要对远程服务器必要的配置,如果远程服务器只有一两台还好说,如果有N台,还需要逐台进行配置,或者需要使用代码进行以上操作时,上面的办法就不太方便了.而使用paramiko可 ...

最新文章

  1. break 和continue在循环中起到的作用
  2. jQuery对象和DOM对象互转的问题、jQuery文件引入问题、DOM版本的网页开关灯
  3. protobuf入门教程(五):枚举(enum)、包(package)
  4. 浙江科技学院c语言考试试卷,浙江科技学院c语言C试卷A.doc
  5. Waymo研发经理:《自动驾驶感知前沿技术介绍》
  6. python输入三个商品_用python3采集shopify站点商品
  7. vim 编辑演示_改变我生活的7个Vim技巧(含演示)
  8. linq 动态拼接where条件 类似 T_SQL And Or
  9. 降低关系型数据库的逻辑复杂
  10. 10.26 第二次面试小感
  11. CSS中的Position、Float属性的一些深入探讨
  12. 世界各国国家代码简称 - 备用
  13. R-CNN解读+代码梳理
  14. pycharm社区免费版如何创建Django项目
  15. 经纬度转换器_FME应用小实例:线面经纬度集合快速转几何图形
  16. 第19章 项目收尾管理
  17. 微软最走运、最倒霉的十个瞬间
  18. 网站推广的一百种方法
  19. office使用问题和解决方法总结
  20. 国开大学计算机应用基础 (本科)终结性考试试题以及答案.zip 内含word和ppt答案 下载即可使用

热门文章

  1. 在ArrayList中根据自定义类的一个属性找某个对象
  2. v-slot的用法(代替slot和slot-scope)
  3. 如何在Excel表中使用Power BI的功能?
  4. Java项目:SSH羽毛球馆管理系统
  5. DCHP 中继,攻击防范配置
  6. 财神爷商训---范蠡
  7. printk 使用方法
  8. 国内各地图API坐标系统比较
  9. 明日方舟统计寻访工具【附下载链接】
  10. 企业微信开发实战(五、自建应用-审批流程引擎之配置可信任域名、创建审批模版、发起审批)