-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transfer fails at 1GB: rekey window too small, hard-coded #49
Comments
Exception info, if helpful: Backtrace on logger: Backtrace on exception: |
Chris, ironically, I ran into this issue today as well. What value did you end up picking instead of 20 packets? |
The value is entirely dependent on your situation, but basically, it goes like this:
|
I was looking for a ball park. I don't have the luxury of doing this calculation. I am using paramiko on the server-side, so my clients will all have different optimal values. I am using paramiko as an SSH server to expose access to rsync. The client I am using is OpenSSH. First I tried 120, I got to 3GB transferred before dying. Now I am trying 1024. We will see how that works. I reviewed the code of dropbear SSH server. It disallows sending of packets during kex rekeying. During rekeying, it enqueues packets to a linked list. No limit is enforced (except by available memory). The relevant code is in packet.c see: enqueue_reply_packet() The queue is activated when ses.dataallowed == 0. kex.c handles rekeying and sets the dataallowed member to 0 after sending/receiving a rekey request. The OpenSSH implementation is similar. packet.c enqueues outbound packets in packet_send2() when active_state->rekeying == 1. My thoughts are that the 20 packet receiving limit should simply disappear. I don't see any similar limits on receiving packets in either implementation. I also don't see any queuing of outbound packets in paramiko, just a difference, not sure if that is a problem or not. |
New version of duplicity (http://duplicity.nongnu.org/) uses paramiko as a transport backend and seem to suffer from this bug also. It will normally crash at some moment during the full backup with a following stacktrace:
Any ideas for a real fix to this (instead of enlarging the number of packets allowed to receive)? |
The problem boils down to a sort of timeout (measured in packets received, not seconds) that is too short. The options are then to remove the timeout or make it longer, perhaps by some fancy algorithm. Rekeying is part of the ssh protocol and is there for security reasons. So any "real fix" necessarily involves enlarging the number of packets allowed. That's not to say we can't do better than a hard coded limit. Something that auto-tunes based on the formula above is probably a decent idea. I'd also be curious what the openssl codebase does since it does not suffer from this issue as far as I can tell. |
One way to fix this, without disabling transmission during re-keying and without the need for a complex (and possibly error-prone) time-based algorithm, would be to initiate the re-keying really early (at 500 MB, for example) and then raise the exception after 1 GB has been received like we do now. This weekend, I'll see if I can put together a patch that does this. |
This patch seems to work: #63 Anyone want to try it out? |
Works for me; with it, my duplicity backups manage to get past 1GB without throwing an exception. |
I think that this is related to this Twisted Conch bug http://twistedmatrix.com/trac/ticket/4395 |
So what's the process for getting this merged to master? |
When Paramiko initiates a re-key request over a high-bandwidth, medium-latency connection, it erroneously terminates the connection with the error, "SSHException: Remote transport is ignoring rekey requests". This is due to the hard-coded limit of 20 packets that may be received after a re-key request has been sent. See, for example, this bug report: "Transfer fails at 1GB: rekey window too small, hard-coded" paramiko#49 This patch changes paramiko's behaviour as follows: - Decrease the threshold for starting re-keying from 2**30 to 2**29 bytes. - Decrease the threshold for starting re-keying from 2**30 to 2**29 packets. - Increase the limit of received packets between re-key request & completion from 20 packets to 2**29 packets. - Add a limit of 2**29 received bytes between re-key request & completion. In other words, we re-key more often in order to allow more data to be in-transit during re-keying. NOTE: It looks like Paramiko disables the keep-alive mechanism during re-keying. This patch does not change that behaviour.
When backing up assets and Whitehall using Duplicity, I originally used SCP which makes use of the Paramiko back-end (as it's all Python) for SSH access. Due to paramiko/paramiko#49 and paramiko/paramiko#63, we can't use Paramiko. Changing the SSH backend in the version of Duplicity we run (0.6.18) isn't supported. It is in later versions, but they aren't available from Ubuntu for Precise machines. As a result, we need to ensure that rSSH allows access for Rsync. This does that.
Is this still an issue with the latest release v1.15.2? |
Given the age, it's at least a little likely, @simon-online - though I know there are still outstanding issues re: "large" file transfers (also with their own PRs, though...). Not sure if same or different. Overall, we really need a thorough cleaning of the ticket queue (even if it is simply "close anything w/o activity in the last year" on the assumption that critical issues will get re-upped). Something I hope to find time for in the mid term. |
For what it's worth I can confirm that I was regularly having this issue with v1.7.7.1 but since I updated to v1.15.2 over a month ago this issue has stopped. |
Thanks a lot for double checking, @simon-online! |
kex: fix server-side of kex-group-14-sha256 and kex-group16-sha512
For what it's worth, i'm on 2.12.0 and the problem is (still?) present. The workaround provided here #151 (comment) worked wonders for me. |
If you're still observing this problem, @fthiery, then likely your root cause is different from that discussed in this ticket, at least to some degree. Please test also on the most recent 3.x release, and if you're seeing the problem there open a new ticket to report as such. Thanks! |
First off, thanks for the great work with paramiko.
At 1GB of data transferred over sftp, paramiko initiates a ssh rekey request and then sets a limit on the number of packets exchanged before the remote side answers the rekey request. This limit is hard-coded to 20. If you have fat, long pipes, it's pretty easy to consistently exceed this threshold. As a consequence in this context, paramiko is not able to transfer files larger than 1GB in size. OpenSSH does not exhibit this behavior. I manually patched the source to change the 20 to something that was more reasonable based on our RTT and bandwidth. The exceptions immediately went away.
The text was updated successfully, but these errors were encountered: