短版:
paramiko.Packetizer.need_rekey()
,然后在数据传输线程返回True时阻塞或休眠我的问题:
paramiko.SSHClient()
对象时,如何访问paramiko.Packetizer.need_rekey()
的任何参考或示例?长版:
现代SSH会话需要在经过一定时间或数据后重新键入。如果对重新密钥的请求没有足够快地采取行动,其中“足够快”意味着自请求重新密钥以来已经过了太多时间或过多的数据,则连接将作为安全保护机制中止。在
Paramiko过去在重新密钥请求和重新密钥更新之间有一个非常狭窄的限制:20个数据包。This patch2012年起
Increase(d) the limit of received packets between re-key request & completion from 20 packets to 2**29 packets.
在我的应用程序中,我使用paramiko.transport.open_channel
在转发端口上传输大(10-30gb)的数据流。如果我在同一LAN上的两个主机之间执行此操作,则成功率为100%。如果主机在不同的局域网上,并且延迟时间越来越长,它就会开始出现故障,比如50%的情况,但可能不止这些。在
不用说,丢失25 GB的SSH连接到30 GB的数据传输会令人沮丧。在
使用OpenSSH作为客户机,我没有这个问题,这与我读到的报告一致,即重新键入互操作性是有问题的。据报道,OpenSSH与自身无缝地重新加密;与其他无缝地重新加密。。。不是这样。但是我已经在使用Paramiko登录到远程主机并运行必要的命令来启动数据传输;必须打开一个单独的OpenSSH会话来转发数据的端口是很麻烦的。在
正确的解决方法似乎是,Paramiko应该阻止或延迟不需要重新密钥的数据包,而这似乎是OpenSSH处理它的方式,尽管我还没有看到权威的证实。但这可能是一个雄心勃勃的改变,会影响到很多人,需要时间。在
作为一种临时措施,最简单的解决办法就是让我的剧本自我调节。我很乐意插入sleep
调用,或者在处理重新键入时完全阻止数据传输。如果没有在后台进行大量的数据传输,重新键入应该很容易在最后期限内完成。在
Paramiko提供了一种查看是否已请求重新密钥的方法-paramiko.Packetizer.need_rekey()
。但是我不知道如何在现有的SSHClient()
对象的上下文中调用它。对于paramiko.transport.*
方法,我可以使用paramiko.SSHClient().get_transport()
创建一个用于调用它们的对象。似乎没有一个paramiko.SSHClient().get_packetizer()
等价物来获得对Packetizer方法的访问权。在demo/
代码中没有Packetizer的示例,tests/
下的test_packetizer.py
文件表明它被设计成用作原始接口,而不是{
所以-重申上面简短版本中的问题-
paramiko.Packetizer.need_rekey()
为真时,我想我可以通过sleep()
来解决这个问题,但是我不知道如何从拥有SSHClient
对象的上下文中访问need_rekey()
方法。有什么想法吗?在感谢任何帮助!在
版本信息仅供参考:
$ python
Python 2.7.5 (default, Apr 9 2015, 11:03:32)
[GCC 4.8.3 20140911 (Red Hat 4.8.3-9)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import paramiko
>>> paramiko.__version__
'1.15.2'
>>>
我还是很想听听Š2。。。在
我通过黑客攻击和斜杠找到了#1的答案:
get_transport
返回的transport
对象包括一个packetizer
对象,可用于解决need_rekey()
方法:我更新了我的“数据读取”循环来检查
^{pr2}$transport.packetizer.need_rekey()
是否被设置,如果设置了,则使用time.sleep(1)
来休眠。以下代码每数据传输进度的1/80打印“.”,并且每当由于请求重新密钥而暂停时,将打印“Z”:这就产生了这种输出
这告诉我,重新密钥是定期发生的(很好,考虑到正在传输的数据量),并且我在更改后的10多次运行中都无法重现会话中止失败。在
相关问题 更多 >
编程相关推荐